2026-10-06 15:58:02 +02:00
<!doctype html>
< html lang = "en" >
< head >
< meta charset = "utf-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< title > Kokkoja</ title >
< link rel = "stylesheet" href = "kokkoja.css" >
< script type = "module" src = "js/main.js" ></ script >
</ head >
< body >
< main id = "start" hidden >
< h1 > Kokkoja</ h1 >
< label for = "name" > Your name, as others will see it</ label >
< input id = "name" type = "text" maxlength = "40" autocomplete = "off" >
< label for = "notebook" > Notebook for the pages of this session</ label >
2026-10-10 19:01:20 +02:00
< select id = "notebook" class = "notebook_pick"
data-help = "The notebook this session’ s pages are saved in. The last entry makes a new notebook." ></ select >
< input id = "notebook_name" type = "text" maxlength = "100" autocomplete = "off" spellcheck = "false"
placeholder = "Name of the new notebook" aria-label = "Name of the new notebook" hidden >
2026-10-06 15:58:02 +02:00
< p id = "notebook_note" class = "note notebook_directory" ></ p >
2026-10-10 19:01:20 +02:00
< section id = "start_choice" >
2026-10-06 15:58:02 +02:00
< h2 > Start a session</ h2 >
< p > You will be given an invitation to send to the others.</ p >
< button id = "start_session" type = "button" > Start a session</ button >
</ section >
2026-10-10 19:01:20 +02:00
< section id = "join_choice" >
2026-10-06 15:58:02 +02:00
< h2 > Join a session</ h2 >
< label for = "invitation_entry" > Invitation</ label >
< input id = "invitation_entry" type = "text" autocomplete = "off" spellcheck = "false" >
< button id = "join_session" type = "button" > Join</ button >
< p class = "note" >< a id = "open_installed" href = "#" hidden > Join with the Kokkoja program installed on this computer instead</ a ></ p >
</ section >
< p id = "start_message" class = "message" role = "alert" ></ p >
</ main >
< div id = "session" hidden >
< header class = "toolbar" >
< div class = "group" role = "radiogroup" aria-label = "Tool" >
< button type = "button" data-tool = "pen" aria-pressed = "true"
data-help = "Write on the page. Only your own writing can be erased." > Pen</ button >
< button type = "button" data-tool = "text" aria-pressed = "false"
2026-10-10 19:01:20 +02:00
data-help = "Type on the page. Tap where the text should begin, or drag open a rectangle: a red box, white inside, in which the text wraps and which grows downward as you type. Tap your own text to change it; rest the pen on it to move it, or near a corner of a box to resize it." > Text</ button >
2026-10-06 15:58:02 +02:00
< button type = "button" data-tool = "eraser" aria-pressed = "false"
2026-10-10 19:01:20 +02:00
data-help = "Erase your own strokes and text by moving over them. A tap on an image, or on a Hide rectangle, removes it, if you are the host or a co-host (or added the image yourself)." > Eraser</ button >
< button type = "button" data-tool = "hide" aria-pressed = "false" hidden
data-help = "Hide part of the page for everyone: drag open a rectangle, and what lies under it is covered in white, marked by blue corners. Rest the pen on it to move it, or near a corner to resize it; a tap of the eraser removes it." > Hide</ button >
2026-10-06 15:58:02 +02:00
</ div >
< div class = "group" id = "colors" role = "radiogroup" aria-label = "Color" >
< button id = "more_colors" type = "button" class = "swatch more"
data-help = "Choose another color. It is added here." > +</ button >
</ div >
< div id = "color_palette" class = "palette" hidden ></ div >
< div class = "group" id = "widths" role = "radiogroup" aria-label = "Line width" ></ div >
< div class = "group" id = "text_style" hidden >
< select id = "text_font" aria-label = "Font" data-help = "The font: a sans-serif, a serif or a monospaced one, as this computer has them." >
< option value = "sans-serif" style = "font-family: sans-serif" > Sans</ option >
< option value = "serif" style = "font-family: serif" > Serif</ option >
< option value = "monospace" style = "font-family: monospace" > Mono</ option >
</ select >
< input id = "text_size" type = "number" min = "6" max = "100" step = "1" value = "14"
aria-label = "Text size in points" data-help = "Text size in points." >
</ div >
2026-10-10 19:01:20 +02:00
< div class = "group" aria-label = "View" >
< button id = "zoom_fit" type = "button"
data-help = "Show the whole page in the window. Pressed by the host, it does so on every screen. Ctrl (Command on a Mac) with the scroll wheel, or with a pen stroke up or down, zooms about the pointer." > Fit</ button >
< button id = "zoom_sheet" type = "button"
data-help = "Show the page at the scale a new page has: one A4 sheet filling the window. A shrunk page is then seen at its size on the sheet. Pressed by the host, it does so on every screen." > A4</ button >
< button id = "zoom_widen" type = "button" hidden
data-help = "Make the page wider, for everyone, until it fills the window at this zoom. Nothing on it moves." > Widen</ button >
< button id = "zoom_shrink" type = "button" hidden
data-help = "Make the page, for everyone, just large enough for what is on it, with the margin around. Nothing on it moves." > Shrink</ button >
< label class = "toggle" data-help = "Let the page grow when your writing reaches an edge. Off, your writing stops at the edge. Images always get the room they need." >
Extend < input id = "extend" type = "checkbox" checked >
</ label >
2026-10-06 15:58:02 +02:00
</ div >
2026-10-10 19:01:20 +02:00
< div class = "toolbar_right" >
2026-10-06 15:58:02 +02:00
< div class = "group" id = "host_tools" hidden >
< button id = "new_page" type = "button"
data-help = "Start a new blank page for everyone. The current page is kept in each notebook." > New</ button >
< button id = "load_image" type = "button"
2026-10-10 19:01:20 +02:00
data-help = "Put an image file, such as a scanned exercise, on the page for everyone: below the images already there, centred, at its own size. Rest the pen on an image to move it, or near a corner to scale it; it comes to the front. A tap of the eraser on an image removes it; writing on it stays." > Image</ button >
2026-10-06 15:58:02 +02:00
< button id = "load_notebook_page" type = "button"
data-help = "Start a new page for everyone from a page kept in a notebook, with everything on it. The current page is kept in each notebook." > Notebook</ button >
</ div >
2026-10-10 19:01:20 +02:00
< div class = "group" aria-label = "Notebook" >
< select id = "session_notebook" class = "notebook_pick" aria-label = "Current notebook"
data-help = "The notebook the page is saved in. Choosing another continues the page there; the last entry makes a new notebook." ></ select >
< input id = "session_notebook_name" type = "text" maxlength = "100" autocomplete = "off" spellcheck = "false"
placeholder = "Name of the new notebook" aria-label = "Name of the new notebook" hidden >
< button id = "keep_page" type = "button"
data-help = "Keep a dated copy of the page as it is now. The page is also kept by itself whenever it is about to be replaced." > Keep</ button >
< button id = "export_page" type = "button"
data-help = "Save a picture of the page, as it is shown here, in a PNG file at a place you choose." > Export</ button >
</ div >
< button id = "session_button" type = "button"
data-help = "Who is here, and the invitation to send to others." > Session</ button >
2026-10-06 15:58:02 +02:00
</ div >
</ header >
2026-10-10 19:01:20 +02:00
< div id = "notice" class = "notice" hidden ></ div >
2026-10-06 15:58:02 +02:00
< div class = "workspace" >
< div id = "desk" class = "desk" >
< div id = "page" class = "page" ></ div >
</ div >
2026-10-10 19:01:20 +02:00
</ div >
</ div >
2026-10-06 15:58:02 +02:00
2026-10-10 19:01:20 +02:00
< dialog id = "session_dialog" class = "chooser session" >
< header >
< h2 > Session</ h2 >
< button id = "session_close" type = "button" aria-label = "Close" > × </ button >
</ header >
< div class = "session_body" >
< h3 > Participants</ h3 >
< ul id = "participants" ></ ul >
< h3 > Invitation</ h3 >
< div class = "invitation_line" >
2026-10-06 15:58:02 +02:00
< input id = "invitation" type = "text" readonly spellcheck = "false" >
< button id = "copy_invitation" type = "button"
data-help = "Copy the invitation, to send to the others by any means." > Copy</ button >
2026-10-10 19:01:20 +02:00
</ div >
< div id = "invitation_code" class = "invitation_code" hidden
data-help = "The invitation as a QR code. Point the camera of a phone or a tablet at it, and the link opens there." ></ div >
< p class = "note session_state" >
< span id = "page_number" class = "page_number" ></ span >
< span id = "status" class = "status" ></ span >
< span id = "save_status" class = "save_status" ></ span >
</ p >
< p class = "note notebook_directory" ></ p >
< h3 > Log</ h3 >
< div class = "log_line" >
< pre id = "event_log" class = "event_log" ></ pre >
< button id = "copy_log" type = "button"
data-help = "Copy the log: what happened in this session and every press and release of the pen, for finding a fault." > Copy</ button >
</ div >
2026-10-06 15:58:02 +02:00
</ div >
2026-10-10 19:01:20 +02:00
</ dialog >
2026-10-06 15:58:02 +02:00
< dialog id = "notebook_chooser" class = "chooser" >
< header >
< h2 > Notebooks</ h2 >
< button id = "chooser_close" type = "button" aria-label = "Close" > × </ button >
</ header >
< div class = "chooser_body" >
< nav id = "chooser_notebooks" class = "chooser_notebooks" ></ nav >
< div id = "chooser_pages" class = "chooser_pages" ></ div >
</ div >
< p id = "chooser_message" class = "note" ></ p >
</ dialog >
< dialog id = "file_chooser" class = "chooser" >
< header >
< h2 id = "files_title" > Image</ h2 >
< button id = "files_close" type = "button" aria-label = "Close" > × </ button >
</ header >
< div class = "files_place" >
< button id = "files_up" type = "button" > Up</ button >
< input id = "files_directory" type = "text" spellcheck = "false" autocomplete = "off"
aria-label = "Directory" >
</ div >
< div class = "files_body" >
< nav id = "files_directories" class = "files_directories" ></ nav >
< div id = "files_entries" class = "files_entries" ></ div >
</ div >
< div id = "files_save" class = "files_save" hidden >
< input id = "files_name" type = "text" spellcheck = "false" autocomplete = "off"
aria-label = "File name" >
< button id = "files_save_here" type = "button" > Export</ button >
</ div >
< p id = "files_message" class = "note" ></ p >
</ dialog >
</ body >
</ html >