  /* ============================================================
     DESIGN TOKENS
     ============================================================ */
  :root {
    --accent: #6c5ce7;
    --accent-press: #5a4bd4;
    --accent-soft: rgba(108, 92, 231, 0.14);
    --radius-lg: 20px;
    --radius-md: 14px;
    --radius-sm: 10px;
    --ease: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
    --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color-scheme: light dark;
  }

  html[data-theme="light"] {
    /* Read by the timer card and the note colour swatch but never defined, so
       they resolved to nothing — which is why the timer bleached out whenever
       the theme or skin changed. They follow the theme like everything else. */
    --text-soft: #59627a;
    --panel: #ffffff;
    --accent-warn: #c77700;
    --bg-grad: radial-gradient(1200px 800px at 80% -10%, #eef1f8 0%, #e3e8f1 55%, #dde3ee 100%);
    --surface: rgba(255, 255, 255, 0.72);
    --surface-solid: #ffffff;
    --text: #1d2230;
    --muted: #626b7b;
    --border: rgba(20, 28, 46, 0.09);
    --border-strong: rgba(20, 28, 46, 0.14);
    --hover: rgba(20, 28, 46, 0.05);
    --shadow: 0 18px 50px -12px rgba(23, 31, 56, 0.22), 0 4px 14px -6px rgba(23, 31, 56, 0.14);
    --shadow-sm: 0 4px 14px -4px rgba(23, 31, 56, 0.18);
  }
  html[data-theme="dark"] {
    --text-soft: #a7b0c2;
    --panel: #1b1f28;
    --accent-warn: #f5a524;
    --bg-grad: radial-gradient(1200px 800px at 80% -10%, #1a1f2b 0%, #12151d 55%, #0c0e14 100%);
    --surface: rgba(26, 30, 41, 0.66);
    --surface-solid: #1b1f29;
    --text: #eef1f6;
    --muted: #9aa3b4;
    --border: rgba(255, 255, 255, 0.08);
    --border-strong: rgba(255, 255, 255, 0.14);
    --hover: rgba(255, 255, 255, 0.06);
    --shadow: 0 24px 60px -16px rgba(0, 0, 0, 0.65), 0 6px 18px -8px rgba(0, 0, 0, 0.5);
    --shadow-sm: 0 6px 18px -6px rgba(0, 0, 0, 0.55);
  }

  * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
  html, body { margin: 0; height: 100%; overflow: hidden; font-family: var(--font);
    color: var(--text); background: var(--sk-bg, var(--bg-grad));
    background-attachment: fixed;
    -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; overscroll-behavior: none;
    transition: background-color 0.4s var(--ease), color 0.4s var(--ease); }

  @media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
  }

  .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

  /* ---------- canvas ---------- */
  #stage { position: fixed; inset: 0; touch-action: none; }
  #board { position: absolute; inset: 0; display: block; width: 100%; height: 100%; cursor: crosshair;
    touch-action: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
  #board.tool-select { cursor: default; }
  #board.tool-text { cursor: text; }
  #board.tool-eraser { cursor: none; }
  /* Only created when ?debug is in the address; safe to delete with its script. */
  #slate-debug { position: fixed; left: 8px; bottom: 8px; z-index: 400; font: 500 10.5px/1.35 var(--font); }
  #dbg-head { appearance: none; border: 1px solid var(--border-strong); background: rgba(12,14,20,0.86);
    color: #cfd6e4; border-radius: 8px; padding: 5px 9px; cursor: pointer; font: 700 10.5px/1 var(--font); }
  #dbg-body { margin-top: 5px; max-width: 260px; max-height: 46vh; overflow-y: auto;
    background: rgba(12,14,20,0.93); border: 1px solid var(--border-strong); border-radius: 9px;
    padding: 7px 9px; color: #cfd6e4; }
  #dbg-body table { border-collapse: collapse; width: 100%; }
  #dbg-body td { padding: 1px 0; }
  #dbg-body td:first-child { color: #8e97a8; padding-right: 10px; }
  #dbg-body .dbg-log { margin-top: 6px; border-top: 1px solid rgba(255,255,255,0.14); padding-top: 5px;
    font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 9.5px; color: #a7b0c2; }
  #dbg-body .dbg-log b { color: #e8edf6; }
  #dbg-tools { display: flex; gap: 5px; margin-bottom: 6px; }
  #dbg-tools button { flex: 1; appearance: none; border: 1px solid var(--border-strong);
    background: transparent; color: #cfd6e4; border-radius: 6px; padding: 4px 0; cursor: pointer;
    font: 600 10px/1 var(--font); }
  #dbg-tools button:hover { background: rgba(255,255,255,0.08); }
  #dbg-tools button.rec-on { background: #b3261e; border-color: #b3261e; color: #fff;
    animation: dbg-rec-pulse 1.1s ease-in-out infinite; }
  @keyframes dbg-rec-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } }
  #dbg-dump { width: 100%; height: 120px; margin-top: 6px; font: 400 9px/1.3 ui-monospace, monospace;
    background: #05070b; color: #cfd6e4; border: 1px solid var(--border-strong); border-radius: 6px; }
  #board.hand { cursor: grab; }
  #board.grabbing { cursor: grabbing; }

  /* ---------- text editor overlay ---------- */
  /* white-space was "pre": no wrap at all, so a single long line just grew the
     box wider forever, straight past the board and often past the viewport
     itself. pre-wrap keeps the sticky-note editor's exact behaviour (it sets
     its own fixed width already) while giving the free-text editor somewhere
     to actually wrap to now that it has a bounded width of its own. */
  #text-editor, #note-editor { position: fixed; z-index: 40; display: none; margin: 0; padding: 0 2px;
    border: none; outline: none; resize: none; background: transparent; overflow-y: auto; overflow-x: hidden;
    white-space: pre-wrap; overflow-wrap: break-word; caret-color: var(--accent); min-width: 10px;
    -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; }
  /* The text editor is a rich box (v280), so parts of the words can be bold,
     coloured or highlighted while typing. It shows exactly what the board will
     draw; the sticky-note editor stays a plain box. */
  #text-editor { word-break: normal; cursor: text; box-sizing: content-box; }
  #text-editor:focus { outline: none; }
  #text-editor span { white-space: pre-wrap; }
  #ts-hl { position: relative; }
  #ts-hl .ts-hl-bar { position: absolute; left: 6px; right: 6px; bottom: 3px; height: 3px; border-radius: 2px; background: rgba(255, 214, 10, 0.85); pointer-events: none; }
  #ts-hl-pop { padding: 10px; min-width: 0; width: max-content; max-width: 260px; }
  #ts-hl-pop .ts-hl-row { display: flex; gap: 6px; }
  #ts-hl-pop .ts-hl-row button { width: 30px; height: 30px; border-radius: 8px; border: 2px solid rgba(255,255,255,.18); cursor: pointer; padding: 0; }
  #ts-hl-pop .ts-hl-row button:hover { border-color: var(--accent); }
  #ts-hl-pop .ts-hl-row button.none { background: linear-gradient(135deg,transparent 45%,#e5484d 45%,#e5484d 55%,transparent 55%), rgba(255,255,255,.06); }
  #ts-hl-pop .ts-hl-lab { font: 700 10.5px/1 var(--font); letter-spacing: .07em; text-transform: uppercase; color: var(--muted); margin: 2px 0 6px; }
#ts-hl-pop .ts-hl-row + .ts-hl-lab { margin-top: 10px; }
#ts-hl-pop .ts-hl-row { flex-wrap: wrap; }
#ts-hl-pop .ts-hl-any { display: flex; align-items: center; gap: 8px; margin-top: 10px; cursor: pointer; font-size: 12.5px; font-weight: 600; }
#ts-hl-pop .ts-hl-any input { width: 30px; height: 30px; padding: 0; border: 2px solid rgba(255,255,255,.18); border-radius: 8px; background: none; cursor: pointer; }
#ts-hl-pop .ts-hl-tip { font-size: 11.5px; line-height: 1.35; color: var(--muted); margin-top: 8px; max-width: 220px; }

  /* The number box for a part of a region. Sits on the board over the part it
     belongs to, so what is being numbered is never in doubt. */
  #rgn-num { position: fixed; z-index: 42; display: none; width: 62px; margin: 0;
    padding: 5px 6px; text-align: center; font: 700 17px/1.1 var(--font);
    color: #fff; background: rgba(18, 20, 28, 0.94); border: 2px solid var(--accent);
    border-radius: 10px; outline: none; box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45);
    -moz-appearance: textfield; }
  #rgn-num::-webkit-inner-spin-button, #rgn-num::-webkit-outer-spin-button {
    -webkit-appearance: none; margin: 0; }
  body.region-mode.region-slicing #board { cursor: crosshair }
  body.region-mode.region-freecut #board { cursor: crosshair }
  body.region-mode.region-numbering #board { cursor: pointer }
  /* The cut tools, beside the presets they compose with. */
  .rgn-tool[aria-pressed="true"] { background: var(--accent); color: #fff; border-color: var(--accent) }

  /* ==================== a table, edited on the board ====================
     The layer the cells live in while a table is open. It sits in screen
     coordinates over the place the table occupies on the board, and the baked
     picture underneath is hidden, so what the teacher types is what they see.
     Everything here is themed from the table's own colours at runtime — the
     look belongs to the table, not to this stylesheet. */
  #tbl-live { position: fixed; z-index: 44; }
  #tbl-live[hidden] { display: none }
  #tbl-live-grid { position: relative }
  #tbl-live table { border-collapse: separate; border-spacing: 0; table-layout: fixed }
  #tbl-live td { vertical-align: middle; position: relative; padding: 0 }
  /* The editable area fills its cell, padding and all: a press on the padding
     used to focus nothing, and the next keystroke was read as a board shortcut. */
  #tbl-live .tc { outline: none; min-height: 1.2em; white-space: pre-wrap;
    overflow-wrap: break-word; cursor: text; -webkit-user-select: text; user-select: text;
    width: 100%; box-sizing: border-box }
  #tbl-live td.sel::after { content: ""; position: absolute; inset: 0; pointer-events: none;
    background: rgba(108, 92, 231, 0.20) }
  #tbl-live td.anchor::after { content: ""; position: absolute; inset: 0; pointer-events: none;
    box-shadow: inset 0 0 0 2px var(--accent) }
  /* The handles: a bar along the top for columns, one down the left for rows.
     A tap selects that column or row and opens what can be done to it. */
  #tbl-live .hbar { position: absolute; left: 0; right: 0; top: -22px; height: 16px }
  #tbl-live .vbar { position: absolute; left: -22px; top: 0; bottom: 0; width: 16px }
  #tbl-live .hh, #tbl-live .vh { position: absolute; display: grid; place-items: center;
    cursor: pointer; border-radius: 6px; background: rgba(140, 146, 170, 0.28);
    color: #fff; font: 600 10px/1 var(--font); transition: background .12s }
  #tbl-live .hh { top: 0; height: 12px }
  #tbl-live .vh { left: 0; width: 12px }
  #tbl-live .hh:hover, #tbl-live .vh:hover { background: rgba(108, 92, 231, 0.55) }
  #tbl-live .hh.on, #tbl-live .vh.on { background: var(--accent); color: #fff }
  /* The insert dots between columns and rows: a small dot that becomes a plus,
     with a line showing where the new column or row will land. */
  #tbl-live .ins { position: absolute; width: 17px; height: 17px; margin: -8.5px 0 0 -8.5px;
    border-radius: 50%; display: grid; place-items: center; cursor: pointer; z-index: 3;
    color: transparent; font: 700 12px/1 var(--font) }
  #tbl-live .ins::before { content: ""; grid-area: 1/1; width: 5px; height: 5px;
    border-radius: 50%; background: rgba(190, 195, 215, 0.85) }
  #tbl-live .ins:hover { background: var(--accent); color: #fff;
    box-shadow: 0 2px 7px rgba(108, 92, 231, 0.55) }
  #tbl-live .ins:hover::before { display: none }
  #tbl-live .ins.c { top: 8px } #tbl-live .ins.r { left: 8px }
  #tbl-live .ins.c:hover::after { content: ""; position: absolute; left: 7.5px; top: 18px;
    width: 2px; height: var(--th); background: var(--accent); pointer-events: none }
  #tbl-live .ins.r:hover::after { content: ""; position: absolute; top: 7.5px; left: 18px;
    height: 2px; width: var(--tw); background: var(--accent); pointer-events: none }
  /* The grip between two columns, for dragging a column's width. */
  #tbl-live .cw { position: absolute; top: 0; bottom: 0; width: 11px; margin-left: -5.5px;
    cursor: col-resize; z-index: 2 }
  #tbl-live .cw:hover { background: linear-gradient(var(--accent), var(--accent)) center/2px 100% no-repeat }
  /* Add a column on the right, a row at the bottom, and size the whole table. */
  #tbl-live .addc, #tbl-live .addr { position: absolute; display: grid; place-items: center;
    border-radius: 7px; background: var(--accent); color: #fff; cursor: pointer;
    font: 700 13px/1 var(--font) }
  #tbl-live .addc { top: 0; bottom: 0; left: calc(100% + 10px); width: 16px }
  #tbl-live .addr { left: 0; right: 0; top: calc(100% + 10px); height: 16px }
  #tbl-live .addc:hover, #tbl-live .addr:hover { background: var(--accent); color: #fff }
  #tbl-live .grip { position: absolute; left: -24px; top: -24px; width: 18px; height: 18px;
    border-radius: 6px; display: grid; place-items: center; cursor: grab;
    background: rgba(24, 27, 36, 0.92); color: #fff; font: 700 11px/1 var(--font);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4) }
  #tbl-live .grip:hover { color: #fff }
  #tbl-live .corner { position: absolute; right: -7px; bottom: -7px; width: 12px; height: 12px;
    border-radius: 4px; background: #fff; border: 2px solid var(--accent); cursor: nwse-resize; z-index: 4 }

  /* The toolbar, which floats above the table it belongs to. Slate's own panel
     shape and spacing, so it reads as part of the app rather than a guest. */
  #tbl-bar { position: fixed; z-index: 46; display: flex; align-items: center; gap: 2px;
    padding: 5px; border-radius: 13px; background: var(--surface-solid);
    border: 1px solid var(--border);
    box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5); white-space: nowrap;
    backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px) }
  /* On a phone the bar is wider than the screen; it scrolls sideways rather
     than running off the edge with Colours and Done out of reach. */
  #tbl-bar { max-width: calc(100vw - 16px); overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin; }
  #tbl-bar > * { flex: none; }
  #tbl-bar[hidden] { display: none }
  #tbl-bar .tbl-b { border: 0; background: transparent; color: var(--text);
    height: 31px; min-width: 31px; padding: 0 8px; border-radius: 9px; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: 5px;
    font: 500 13px/1 var(--font) }
  #tbl-bar .tbl-b:hover { background: var(--hover) }
  #tbl-bar .tbl-b[aria-pressed="true"] { background: var(--accent); color: #fff }
  #tbl-bar .tbl-b.tbl-done { background: var(--accent); color: #fff; font-weight: 600; padding: 0 12px }
  #tbl-bar .tbl-scope { border: 0; background: var(--accent); color: #fff;
    font: 600 12px/1 var(--font); height: 28px; padding: 0 10px; border-radius: 8px;
    cursor: pointer; margin-right: 3px }
  #tbl-bar .tbl-sep { width: 1px; height: 20px; background: var(--border); margin: 0 4px }
  #tbl-bar .tbl-chev { opacity: .55; font-size: 10px }
  #tbl-bar .tbl-step { display: inline-flex; align-items: center; height: 29px;
    background: var(--hover); border-radius: 9px }
  #tbl-bar .tbl-step input { width: 34px; border: 0; background: transparent; text-align: center;
    color: var(--text); font: 600 13px var(--font); outline: none;
    -moz-appearance: textfield }
  #tbl-bar .tbl-step input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0 }
  #tbl-bar .tbl-swatch { display: block; width: 14px; height: 3.5px; border-radius: 2px;
    background: currentColor; box-shadow: 0 0 0 1px rgba(0, 0, 0, .35) }

  /* The popovers the styling lives in, now the dialog is gone. */
  #tbl-pop { position: fixed; z-index: 47; min-width: 226px; max-width: 360px;
    max-height: calc(100vh - 24px); overflow: auto; padding: 11px;
    border-radius: 14px; background: var(--surface-solid);
    border: 1px solid var(--border);
    box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px) }
  #tbl-pop[hidden] { display: none }
  #tbl-pop .ph { font: 700 10.5px/1 var(--font); letter-spacing: .07em;
    text-transform: uppercase; color: var(--muted); margin: 12px 2px 7px }
  #tbl-pop .ph:first-child { margin-top: 1px }
  #tbl-pop .pre { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px }
  #tbl-pop .pre button { border: 0; background: none; padding: 5px 2px; border-radius: 9px;
    cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 4px;
    font: 500 10.5px/1 var(--font); color: var(--muted) }
  #tbl-pop .pre button:hover { background: var(--hover) }
  #tbl-pop .pre button[aria-pressed="true"] { background: var(--accent); color: #fff }
  #tbl-pop .thumb { width: 52px; height: 36px; border-radius: 5px; overflow: hidden;
    display: flex; flex-direction: column; border: 1px solid rgba(255, 255, 255, 0.18) }
  #tbl-pop .thumb i { display: block; height: 11px }
  #tbl-pop .thumb u { display: block; flex: 1 }
  #tbl-pop .sw { display: flex; align-items: center; gap: 9px; padding: 6px 4px;
    cursor: pointer; border-radius: 8px; font: 500 13px/1 var(--font); color: var(--text) }
  #tbl-pop .sw:hover { background: var(--hover) }
  #tbl-pop .sw input { display: none }
  #tbl-pop .sw i { flex: none; width: 29px; height: 17px; border-radius: 9px;
    background: rgba(255, 255, 255, 0.17); position: relative; transition: background .15s }
  #tbl-pop .sw i::after { content: ""; position: absolute; top: 2px; left: 2px; width: 13px;
    height: 13px; border-radius: 50%; background: #fff; transition: left .15s }
  #tbl-pop .sw input:checked + i { background: var(--accent) }
  #tbl-pop .sw input:checked + i::after { left: 14px }
  #tbl-pop .swatches { display: grid; grid-template-columns: repeat(8, 1fr); gap: 5px }
  #tbl-pop .swatches button { width: 100%; aspect-ratio: 1; border-radius: 6px;
    border: 1px solid rgba(0, 0, 0, 0.35); cursor: pointer; padding: 0 }
  #tbl-pop .swatches button[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--surface-solid), 0 0 0 4px var(--accent) }
  /* The dot of colour beside each entry in the Colours list, so the list says
     what it holds without six sets of swatches being open at once. */
  #tbl-pop .tbl-dot { flex: none; width: 15px; height: 15px; border-radius: 5px;
    border: 1px solid var(--border-strong); background: var(--hover) }
  #tbl-pop .tbl-dot.none { background:
    linear-gradient(135deg, transparent 44%, #e5484d 44%, #e5484d 56%, transparent 56%) }
  #tbl-pop .rows button { display: flex; align-items: center; gap: 9px; width: 100%;
    border: 0; background: none; padding: 7px 9px; border-radius: 8px; cursor: pointer;
    text-align: left; font: 500 13px/1 var(--font); color: var(--text) }
  #tbl-pop .rows button:hover { background: var(--hover) }
  #tbl-pop .rows button[aria-pressed="true"] { background: var(--accent); color: #fff }
  #tbl-pop .rows button.danger { color: #ff8a8a }
  #tbl-pop .rows button.danger:hover { background: rgba(255, 90, 90, 0.13) }
  #tbl-pop .rows hr { border: 0; border-top: 1px solid var(--border); margin: 6px 0 }
  #tbl-pop .rows button:disabled { opacity: .38; cursor: default; background: none }
  #tbl-pop .ph.tbl-tip { text-transform: none; letter-spacing: 0; font-weight: 500; font-size: 12px; line-height: 1.35; margin-bottom: 2px }
  #tbl-live td.merged .tc { min-height: 100% }
  #tbl-pop .num { display: flex; align-items: center; gap: 8px; padding: 4px 2px;
    font: 500 12.5px/1 var(--font); color: var(--muted) }
  #tbl-pop .num input[type="range"] { flex: 1; accent-color: var(--accent) }
  #tbl-pop .num b { color: var(--text); min-width: 30px; text-align: right; font-weight: 600 }
  #tbl-pop .cust { display: flex; align-items: center; gap: 8px; margin-top: 8px;
    font: 500 12.5px/1 var(--font); color: var(--muted) }
  #tbl-pop input[type="color"] { width: 26px; height: 26px; border: 0; padding: 0;
    background: none; cursor: pointer }
  /* The size picker's grid: one cell per row-and-column count, swept across.
     Themed, because a white-on-white picker is no picker at all. */
  #tbl-pop .tbl-pkgrid { display: grid; gap: 3px; padding: 1px }
  /* The note wraps to the grid above it rather than deciding how wide the panel
     is: a line of help text longer than twelve columns left a band of empty
     panel beside the grid. */
  #tbl-pop .tbl-pknote { margin-top: 10px; font: 500 11.5px/1.4 var(--font);
    color: var(--muted); width: 264px; max-width: 100% }
  #tbl-pop .tbl-pknote b { color: var(--text); font-weight: 700 }
  #tbl-pop .tbl-pk { display: block; width: 19px; height: 19px; border-radius: 4px;
    border: 1px solid var(--border-strong); background: var(--hover); cursor: pointer }
  #tbl-pop .tbl-pk.on { background: var(--accent); border-color: var(--accent) }
  #tbl-pop .num { color: var(--muted) }

  /* Drawing a table: the ghost that shows its size and its rows and columns
     before a single cell exists. */
  #tbl-ghost { position: fixed; z-index: 43; pointer-events: none;
    border: 2px dashed var(--accent); border-radius: 8px;
    background-color: rgba(108, 92, 231, 0.07) }
  #tbl-ghost[hidden] { display: none }
  #tbl-ghost b { position: absolute; right: -2px; bottom: -27px; background: var(--accent);
    color: #fff; font: 600 12px/1 var(--font); padding: 4px 8px; border-radius: 6px }
  body.tbl-drawing #board { cursor: crosshair }

  /* ---------- eraser cursor ---------- */
  #erase-cursor { position: fixed; z-index: 35; display: none; pointer-events: none;
    border-radius: 50%; transform: translate(-50%, -50%);
    border: 2px solid rgba(255, 255, 255, 0.9);
    box-shadow: 0 0 0 1.5px rgba(0, 0, 0, 0.45), inset 0 0 0 1.5px rgba(0, 0, 0, 0.3); }
  /* Dot pointer for pen / pencil / highlighter: the stroke's own colour, filled
     so it reads as the mark about to be made rather than a hole to erase. */
  #erase-cursor.dot { border-width: 1.5px; background: currentColor;
    box-shadow: 0 0 0 1.5px rgba(0,0,0,0.5), 0 0 0 3px rgba(255,255,255,0.35); opacity: 0.85; }
  /* #board is an id, so a plain "canvas.dot-pointer" rule loses to every
     cursor rule above and the tool pointer stayed on screen beside the dot.
     Matching the id, the way #board.tool-eraser does, is what actually wins. */
  #board.dot-pointer { cursor: none; }

  /* ---------- glass ---------- */
  /* Every toolbar, popup and dialog in Slate is this one class, so dressing the
     chrome happens here and nowhere else. The gloss is a second background
     layer rather than a ::before, because several panels already use their own
     pseudo-elements and stacking another one would fight them.
     Each variable falls back to today's value, so with no skin chosen nothing
     about the appearance changes. */
  .glass { background: var(--sk-gloss, linear-gradient(transparent, transparent)), var(--sk-panel, var(--surface));
    backdrop-filter: blur(var(--sk-blur, 20px)) saturate(var(--sk-sat, 160%));
    -webkit-backdrop-filter: blur(var(--sk-blur, 20px)) saturate(var(--sk-sat, 160%));
    border: var(--sk-border-w, 1px) solid var(--sk-border, var(--border));
    box-shadow: var(--sk-shadow, var(--shadow)); }
  /* Buttons in the chrome pick up the skin's edge treatment too. */
  .ctrl, .tool { border-color: var(--sk-btn-border, var(--border)); }

  /* ---------- top bar ---------- */
  .topbar { position: fixed; top: 16px; left: 16px; right: 16px; display: flex;
    align-items: center; justify-content: space-between; gap: 12px; pointer-events: none; z-index: 30; }
  .topbar > * { pointer-events: auto; }
  /* Boards now live in #boards-pop; the topbar only carries a fixed-width button. */
  .ctrl-badge { position: absolute; right: 3px; bottom: 3px; min-width: 15px; height: 15px; padding: 0 3px;
    border-radius: 8px; background: var(--accent); color: #fff; font: 700 10px/15px var(--font);
    text-align: center; pointer-events: none; box-shadow: 0 0 0 2px var(--surface-solid); }
  /* Starts hidden in the markup too. A deck of one needs no badge, and painting
     it before app.js could add .solo made a "1" flash on every load. */
  .ctrl-badge.solo { display: none; }
  .bd-row { display: flex; align-items: center; gap: 4px; border-radius: var(--radius-sm); }
  .bd-row:hover { background: var(--hover); }
  .bd-row.active { background: var(--accent-soft); }
  .bd-open { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 11px;
    padding: 9px 10px; border: none; background: transparent; color: var(--text);
    border-radius: var(--radius-sm); cursor: pointer; text-align: left; font: 550 13.5px/1.2 var(--font); }
  .bd-row.active .bd-open { color: var(--accent); }
  .bd-num { flex: none; width: 24px; height: 24px; border-radius: 7px; border: 1px solid var(--border-strong);
    display: inline-flex; align-items: center; justify-content: center; font: 700 12px/1 var(--font); }
  .bd-row.active .bd-num { background: var(--accent); border-color: var(--accent); color: #fff; }
  .bd-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .bd-meta { margin-left: auto; font-size: 11px; color: var(--muted); }
  .bd-acts { display: flex; align-items: center; gap: 2px; flex: none; padding-right: 4px; }
  .bd-act { appearance: none; border: none; background: transparent; color: var(--muted);
    width: 30px; height: 30px; border-radius: 8px; cursor: pointer; font: 600 15px/1 var(--font);
    display: inline-flex; align-items: center; justify-content: center;
    transition: background-color 0.16s var(--ease), color 0.16s var(--ease); }
  .bd-act:hover { background: var(--hover); color: var(--text); }
  .bd-act.danger:hover { background: var(--danger-soft, rgba(220,60,60,0.14)); color: var(--danger, #d94040); }
  .bd-act:disabled { opacity: 0.3; cursor: default; }
  @media (pointer: coarse) { .bd-act { width: 36px; height: 36px; } }

  .brand { display: flex; align-items: center; gap: 11px; margin: 0; padding: 9px 16px 9px 11px;
    border-radius: 999px; font-weight: 650; letter-spacing: -0.01em; font-size: 15px; user-select: none; }
  .brand .mark { width: 26px; height: 26px; border-radius: 8px;
    background: linear-gradient(140deg, #8b7bff, #6c5ce7 55%, #4f8cff);
    box-shadow: 0 4px 12px -2px rgba(108, 92, 231, 0.6), inset 0 1px 0 rgba(255,255,255,0.35); position: relative; }
  .brand .mark::after { content: ""; position: absolute; inset: 6px 6px auto 6px; height: 3px;
    border-radius: 3px; background: rgba(255,255,255,0.85);
    box-shadow: 0 6px 0 rgba(255,255,255,0.55), 0 12px 0 rgba(255,255,255,0.3); }
  .brand small { color: var(--muted); font-weight: 500; font-size: 12px; margin-left: 2px; }

  .controls { display: flex; align-items: center; gap: 6px; padding: 6px; border-radius: 16px;
    min-width: 0; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .controls::-webkit-scrollbar { display: none; }
  .controls > * { flex: 0 0 auto; }
  .ctrl { appearance: none; border: none; background: transparent; color: var(--text);
    width: 40px; height: 40px; border-radius: 11px; display: inline-flex; align-items: center;
    justify-content: center; cursor: pointer; position: relative;
    transition: background-color 0.18s var(--ease), transform 0.18s var(--ease-spring), color 0.18s var(--ease); }
  .ctrl:hover { background: var(--hover); }
  .ctrl:active { transform: scale(0.9); }
  .ctrl:disabled { opacity: 0.35; cursor: default; }
  .ctrl:disabled:hover { background: transparent; }
  .ctrl.active { background: var(--accent); color: #fff; }
  .ctrl svg { width: 19px; height: 19px; }
  .ctrl.danger:hover { background: rgba(232, 90, 90, 0.14); color: #e85a5a; }
  .divider { width: 1px; height: 24px; background: var(--border-strong); margin: 0 3px; flex: none; }

  .ctrl-label { appearance: none; border: none; cursor: pointer; height: 40px; padding: 0 14px;
    border-radius: 11px; background: var(--accent); color: #fff; font: 600 13.5px/1 var(--font);
    letter-spacing: 0.01em; display: inline-flex; align-items: center; gap: 7px;
    box-shadow: 0 6px 16px -6px var(--accent);
    transition: transform 0.18s var(--ease-spring), background-color 0.18s var(--ease); }
  .ctrl-label:hover { background: var(--accent-press); }
  .ctrl-label:active { transform: scale(0.94); }
  .ctrl-label svg { width: 17px; height: 17px; }

  /* ---------- tool rail ---------- */
  /* top:50%/translateY(-50%) centred the rail purely on viewport height, with
     no regard for the topbar sitting at the very top of that same space. On a
     short window — a small laptop, a browser only half-snapped to the screen
     — a rail with several tools centred that way had its top edge rise
     above the topbar’s bottom edge, and the brand mark there (z-index 30,
     above the rail’s 25) painted over the first tool button and buried it.
     top+bottom instead reserve a zone that starts clear of the topbar and
     ends clear of the bottom of the screen; the tools then centre THEMSELVES
     within that safe zone via flex, and if there are ever more of them than
     the zone has room for, the rail scrolls internally rather than spilling
     back out into the topbar. */
  /* The box hugs its tools again, so there is no empty glass above or below
     them. It is still kept clear of the topbar, but by capping how tall it can
     get rather than by reserving a full-height zone: a centred box of height
     h spans [50vh - h/2, 50vh + h/2], so limiting h to 100vh-176px keeps it
     inside 88px..(100vh-88px) by construction. Below that, the tools shrink
     (see the short-viewport rule further down) rather than the rail clipping
     — clipping would erase the tooltips, which render outside this box. */
  .rail { position: fixed; left: 16px; top: 50%; transform: translateY(-50%); display: flex;
    flex-direction: column; align-items: center; gap: 4px; padding: 8px;
    max-height: calc(100vh - 176px);
    border-radius: var(--radius-lg); z-index: 25;
    opacity: 0; }
  /* This block sits ABOVE the short-window media queries on purpose. It and
     those queries have identical specificity (0,2,0), so whichever comes last
     wins \u2014 and while it sat below them the rail shrank to 32px tools while the
     pill stayed 46px, a highlight bleeding 14px past the icon and 9px out of
     the rail itself. Same cascade-order trap as the [hidden] notes below. */
  /* top:8px is explicit on purpose. The pill had no top at all and relied on
     its static position, which for an absolutely-positioned flex child is
     decided by the container's justify-content — so adding
     justify-content:center to the rail silently moved the pill's origin to
     the middle of the rail. movePill() then applies translateY(offsetTop-8)
     on top of that, landing the highlight several tools further down: Slate
     opened in Select but the pill sat on the Text tool. Pinning the origin
     to the padding corner restores the coordinate space movePill() has
     always assumed, whatever the rail's alignment does later. */
  .rail .pill { position: absolute; left: 8px; top: 8px; width: 46px; height: 46px; border-radius: var(--radius-md);
    background: var(--accent-soft); border: 1px solid rgba(108,92,231,0.35); z-index: 0;
    transition: transform 0.34s var(--ease-spring); pointer-events: none; }
  /* Ten tools at 46px plus gaps need ~512px. On a short window that exceeds
     the safe height, so the tools themselves get smaller instead of the rail
     clipping them or climbing back under the topbar. The pill follows the
     same sizes so the highlight keeps lining up. */
  @media (max-height: 720px) {
    .rail .tool { width: 38px; height: 38px; }
    .rail .pill { width: 38px; height: 38px; }
    .rail { gap: 2px; }
  }
  @media (max-height: 600px) {
    .rail .tool { width: 32px; height: 32px; }
    .rail .pill { width: 32px; height: 32px; }
    .rail { gap: 1px; padding: 6px; }
    .rail .pill { left: 6px; top: 6px; }
  }
  .rail.ready { opacity: 1; transition: opacity 0.25s var(--ease); }
  /* A class setting `display` beats the browser's own [hidden] rule, so hiding
     a tool with the hidden attribute did nothing at all — the Move tool stayed
     on screen and clickable on a board with nowhere to pan. Same trap already
     noted for #sel-tools, #timer-card and #calc-card. */
  .tool[hidden] { display: none !important; }
  .tool { appearance: none; border: none; background: transparent; width: 46px; height: 46px;
    border-radius: var(--radius-md); color: var(--muted); display: inline-flex; align-items: center;
    justify-content: center; cursor: pointer; position: relative; z-index: 1;
    transition: color 0.18s var(--ease), transform 0.18s var(--ease-spring), background-color 0.18s var(--ease); }
  .tool:hover { color: var(--text); background: var(--hover); }
  .tool:active { transform: scale(0.88); }
  .tool.active { color: var(--accent); background: transparent; }
  .tool.active:hover { background: transparent; }
  .tool svg { width: 22px; height: 22px; }

  .tool[data-tip]::after, .ctrl[data-tip]::after { content: attr(data-tip); position: absolute;
    left: calc(100% + 12px); top: 50%; transform: translateY(-50%) translateX(-4px);
    background: var(--surface-solid); color: var(--text); border: 1px solid var(--border);
    box-shadow: var(--shadow-sm); padding: 5px 9px; border-radius: 8px; font-size: 12px; font-weight: 550;
    white-space: nowrap; opacity: 0; pointer-events: none;
    transition: opacity 0.16s var(--ease), transform 0.16s var(--ease); z-index: 50; }
  .ctrl[data-tip]::after { left: 50%; top: calc(100% + 10px); transform: translateX(-50%) translateY(-4px); }
  .tool[data-tip]:hover::after { opacity: 1; transform: translateY(-50%) translateX(0); }
  .ctrl[data-tip]:hover::after { opacity: 1; transform: translateX(-50%) translateY(0); }

  /* ---------- style bar ---------- */
  .stylebar { position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%) translateY(0);
    display: flex; align-items: center; gap: 14px; padding: 10px 14px; border-radius: var(--radius-lg);
    max-width: calc(100vw - 40px); overflow-x: auto; scrollbar-width: none;
    z-index: 25; transition: opacity 0.28s var(--ease), transform 0.28s var(--ease-spring); }
  .stylebar::-webkit-scrollbar { display: none; }
  .stylebar.hidden { opacity: 0; transform: translateX(-50%) translateY(20px); pointer-events: none; }
  .swatches { display: flex; align-items: center; gap: 7px; }
  .swatches.collapsed, #picker-swatch.collapsed, .sb-colbtn.collapsed { display: none; }
  #picker-swatch.collapsed ~ input[type="color"] { display: none; }
  .swatch { width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--border-strong);
    cursor: pointer; padding: 0; position: relative;
    transition: transform 0.18s var(--ease-spring), box-shadow 0.18s var(--ease); }
  .swatch:hover { transform: scale(1.12); }
  .swatch.active { transform: scale(1.12);
    box-shadow: 0 0 0 2px var(--surface-solid), 0 0 0 4px var(--accent); border-color: transparent; }
  .swatch.picker { background: conic-gradient(from 0deg, #ff5b5b, #ffb35b, #ffe95b, #5bff8f, #5bd8ff, #5b7bff, #c95bff, #ff5bd8, #ff5b5b);
    overflow: hidden; display: grid; place-items: center; }
  .swatch.picker svg { width: 13px; height: 13px; color: #fff; filter: drop-shadow(0 1px 1px rgba(0,0,0,0.4)); }
  .picker-wrap { position: relative; display: inline-flex; }
  .picker-wrap input[type="color"] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border: 0; padding: 0; background: none; }

  .font-toggle { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--text); height: 30px; padding: 0 12px; border-radius: 9px; font: 600 12.5px/1 var(--font);
    cursor: pointer; display: none; align-items: center; gap: 6px; white-space: nowrap;
    transition: background-color 0.16s var(--ease); }
  .font-toggle.show { display: inline-flex; }
  /* Box | Lasso under Select & move. Hidden like the other context controls
     until its tool is in hand. */
  .sel-mode { display: none; gap: 2px; padding: 2px; border-radius: 10px;
    border: 1px solid var(--border-strong); flex: none; }
  .sel-mode.show { display: inline-flex; }
  .sel-mode button { display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
    padding: 5px 10px; border-radius: 8px; border: none; background: transparent;
    color: var(--text-soft); font: 600 12px/1 var(--font); }
  .sel-mode button svg { width: 16px; height: 16px; }
  .sel-mode button:hover { background: var(--hover); color: var(--text); }
  .sel-mode button.active { background: var(--accent); color: #fff; }
  .font-toggle:hover { background: var(--hover); }

  .sizefield { display: flex; align-items: center; gap: 10px; }
  .sizefield .preview { width: 30px; display: grid; place-items: center; flex: none; }
  .sizefield .dot { border-radius: 50%; background: currentColor; transition: width 0.18s var(--ease), height 0.18s var(--ease); }
  .step-btn { appearance: none; border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    width: 24px; height: 24px; border-radius: 7px; font: 700 16px/1 var(--font); cursor: pointer; flex: none;
    display: grid; place-items: center; padding: 0; transition: background-color 0.12s var(--ease); }
  .step-btn:hover { background: var(--hover); }
  .step-btn:active { transform: scale(0.92); }
  #hl-opacity-field { display: none; }
  #hl-opacity-field.show { display: flex; }
  .textstyle { display: none; gap: 4px; }
  .textstyle.show { display: flex; }
  .ts-btn { appearance: none; border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    width: 28px; height: 28px; border-radius: 7px; font-size: 14px; cursor: pointer; flex: none;
    display: grid; place-items: center; padding: 0; transition: background-color 0.12s var(--ease); }
  .ts-btn:hover { background: var(--hover); }
  .ts-btn.active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
  .presets { display: flex; align-items: center; gap: 6px; }
  .preset { position: relative; width: 26px; height: 26px; border-radius: 8px; border: 2px solid var(--border-strong);
    cursor: pointer; padding: 0; display: grid; place-items: center; flex: none;
    transition: transform 0.16s var(--ease-spring); }
  .preset:hover { transform: translateY(-1px) scale(1.06); }
  .preset .pdot { border-radius: 50%; background: #fff; }
  /* highlighter preset: its chisel tip, a rounded rectangle, not a dot */
  .preset .pdot.pdot-hl { border-radius: 3px; }
  /* eraser preset: the footprint it leaves, a ring */
  .preset .pdot.pdot-er { border-radius: 50%; border: 2px solid currentColor; box-sizing: border-box; }
  .preset .pdel { position: absolute; top: -6px; right: -6px; width: 14px; height: 14px; border-radius: 50%;
    border: none; background: var(--danger, #e1564b); color: #fff; font-size: 11px; line-height: 12px; cursor: pointer;
    display: none; place-items: center; padding: 0; }
  .preset:hover .pdel { display: grid; }
  .preset-tool { position: absolute; bottom: -3px; right: -3px; font-size: 7px; font-weight: 800;
    background: var(--surface-solid); color: var(--muted); border-radius: 3px; padding: 0 1px; line-height: 1.4; }
  .preset-add { height: 26px; padding: 0 9px 0 7px; border-radius: 8px; flex: none; cursor: pointer; gap: 4px;
    border: 1px dashed var(--border-strong); background: transparent; color: var(--muted); display: inline-flex; align-items: center;
    font: 600 11.5px/1 var(--font); white-space: nowrap;
    transition: background-color 0.14s var(--ease), color 0.14s var(--ease); }
  .preset-add:hover { background: var(--hover); color: var(--text); }
  .preset-add svg { width: 13px; height: 13px; flex: none; }
  .presets.collapsed, .preset-add.collapsed, #sb-div2.collapsed { display: none; }
  input[type="range"] { -webkit-appearance: none; appearance: none; width: 124px; height: 4px;
    border-radius: 4px; background: var(--border-strong); outline: none; cursor: pointer; }
  input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 16px;
    height: 16px; border-radius: 50%; background: var(--accent); border: 2px solid var(--surface-solid);
    box-shadow: var(--shadow-sm); transition: transform 0.16s var(--ease-spring); }
  input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.18); }
  input[type="range"]::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%;
    border: 2px solid var(--surface-solid); background: var(--accent); cursor: pointer; }
  .sb-divider { width: 1px; height: 26px; background: var(--border-strong); }
  .sb-meta { font-size: 12.5px; font-weight: 600; color: var(--muted); min-width: 46px; text-align: right; }

  /* ---------- popovers ---------- */
  .pop { position: fixed; border-radius: var(--radius-md); padding: 7px; min-width: 224px;
    max-height: min(78vh, 580px); overflow-y: auto; z-index: 60; opacity: 0;
    transform: translateY(-8px) scale(0.97); transform-origin: top right; pointer-events: none;
    transition: opacity 0.2s var(--ease), transform 0.22s var(--ease-spring), visibility 0s linear 0.22s;
    /* v278: a closed menu is invisible but was still being painted, each into
       its own composited layer — some twenty menus, about 30 MB of a fresh
       load for nothing. Hidden once its fade-out has finished, it costs
       nothing; opening shows it at once, so the fade-in is unchanged. */
    visibility: hidden; }
  .pop.open { opacity: 1; transform: translateY(0) scale(1); pointer-events: auto;
    visibility: visible; transition: opacity 0.2s var(--ease), transform 0.22s var(--ease-spring), visibility 0s; }
  .pop h4 { margin: 6px 8px 8px; font-size: 11px; font-weight: 700; letter-spacing: 0.07em;
    text-transform: uppercase; color: var(--muted); }
  .pop-sep { height: 1px; background: var(--border); margin: 8px 6px; }

  /* ---------- presenter mode ----------
     Only the board and the tools. The topbar and board strip go; the tool rail
     and style bar stay, because annotating during a show is the point. */
  /* Chrome out of the way, once, for anything on the stage — a show or a
     replay. Both used to hide the top bar through their own selector, so a new
     control had to be remembered in two places or it leaked into one of them. */
  body.stage .topbar { display: none !important; }
  body.presenting #genie-launcher { display: none !important; }

  #present-bar { position: fixed; left: 50%; bottom: calc(18px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%) translateY(14px);
    display: none; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 999px; z-index: 46;
    background: linear-gradient(135deg, rgba(30,27,75,0.96), rgba(46,16,101,0.96));
    border: 1px solid rgba(255,255,255,0.22); box-shadow: 0 16px 40px rgba(0,0,0,0.42);
    color: #fff; font: 700 12.5px/1 var(--font); opacity: 0;
    transition: opacity .2s var(--ease), transform .2s var(--ease); }
  #present-bar.show { display: flex; opacity: 1; transform: translateX(-50%) translateY(0); }
  #present-bar button { display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
    background: rgba(255,255,255,0.14); border: 1px solid rgba(255,255,255,0.22); color: #fff;
    border-radius: 999px; padding: 7px 12px; font: 700 12px/1 var(--font); }
  #present-bar button:hover { background: rgba(255,255,255,0.26); }
  #present-bar button:disabled { opacity: 0.35; cursor: default; }
  #present-bar button svg { width: 15px; height: 15px; }
  #present-bar #present-laser.active { background: #ff3b30; border-color: #ff3b30; }
  #present-count { min-width: 54px; text-align: center; opacity: 0.9; }
  .present-sep { width: 1px; height: 16px; background: rgba(255,255,255,0.28); }
  /* The laser is the pointer while it is on \u2014 no pen cursor beside it. */
  body.lasering #board { cursor: crosshair !important; }

  /* REPORTED: on a phone or an iPad the style bar landed in the MIDDLE of the
     board during a show. The cause was a specificity collision, not a layout
     mistake. The narrow-screen rule moves the bar to the top with
     "bottom: auto; top: 76px", but `body.presenting .stylebar` is two classes
     to that rule's one, so its `bottom` won and `bottom: auto` never applied.
     A fixed box with top AND bottom set and height auto stretches to fill the
     gap between them — so the pill became nearly screen-tall, invisible, with
     its buttons centred in the middle of the board.

     The fix is to stop expressing "above the presenter bar" as a bare bottom
     that fights the layout. One variable carries the offset; a narrow screen
     overrides the VARIABLE, not the property, so the pair can never both be
     set. `top: auto` is stated alongside as a belt to that brace. */
  /* REPORTED: the pen and pencil controls ran over the bottom edge of the
     frame during a show, and the presenter bar was down there competing for
     the same strip. The top of the screen is empty while presenting, so the
     presenter bar moves up there and opens its menus downwards, and the style
     bar takes the gap UNDER THE BOARD — measured from the board itself, not
     from the window, because the board is centred and that gap moves. */
  body.presenting .stylebar {
    top: calc(var(--board-bot, 60vh) + 10px);
    bottom: auto;
    gap: 10px; padding: 7px 12px;
    max-width: calc(100vw - 32px);
  }
  body.presenting .stylebar .seg button,
  body.presenting .stylebar button { padding-top: 5px; padding-bottom: 5px; }
  /* Docked above the board, opening downwards. max() keeps it on screen when a
     board is tall enough to reach the top of the window. */
  body.presenting #present-bar {
    top: max(10px, calc(var(--board-top, 70px) - 56px));
    bottom: auto;
    transform: translateX(-50%) translateY(0);
  }
  body.presenting #present-bar.show { transform: translateX(-50%) translateY(0); }
  /* The recording bar lived at the top of the screen, which is where the
     presenter bar now is. It joins the stack under the board instead, below
     the style bar, so nothing on screen overlaps anything else during a show. */
  body.presenting #rec-bar { top: calc(var(--board-bot, 60vh) + 58px); }
  /* .seg sets display:flex, which beats the browser's [hidden] rule \u2014 the same
     trap as .tool and #sel-tools. The spotlight shape picker only belongs on
     screen while the spotlight is on. */
  #spot-shape[hidden] { display: none !important; }

  /* ---------- performance settings ---------- */
  #opts-pop { width: 300px; max-height: 84vh; overflow-y: auto; }
  .opts-tabs { display: flex; gap: 3px; margin: 6px 4px 8px; }
  .opts-tabs button { flex: 1; padding: 7px 4px; border-radius: 8px; cursor: pointer;
    border: 1px solid transparent; background: transparent; color: var(--text-soft);
    font: 700 11.5px/1 var(--font); }
  .opts-tabs button:hover { background: var(--hover); }
  .opts-tabs button.active { background: var(--accent); color: #fff; }
  .opts-pane[hidden] { display: none; }
  #opts-pop select:disabled, #opts-pop input:disabled + span { opacity: 0.5; }
  .perf-presets { display: flex; flex-direction: column; gap: 5px; padding: 2px 4px 4px; }
  .perf-presets button { display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
    padding: 9px 12px; border-radius: 11px; cursor: pointer; text-align: left;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text); }
  .perf-presets button b { font: 700 13px/1.1 var(--font); }
  .perf-presets button small { font: 500 11px/1.2 var(--font); color: var(--muted); }
  .perf-presets button:hover { border-color: var(--accent); }
  .perf-presets button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
  .perf-presets button.active small { color: rgba(255,255,255,0.8); }
  .perf-hint:empty { display: none; }
  .perf-hint { color: var(--accent); font-weight: 600; }
  .perf-adv { margin: 4px 4px 2px; border-top: 1px solid var(--border); padding-top: 6px; }
  .perf-adv summary { cursor: pointer; padding: 5px 2px; font: 700 11px/1 var(--font);
    letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
  #perf-current { text-transform: none; letter-spacing: 0; color: var(--accent); margin-left: 6px; }
  .perf-row { display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 5px 2px; font: 600 12px/1.2 var(--font); color: var(--text-soft); }
  /* REPORTED: the Undo steps dropdown came out bleached. --hover is a
     TRANSLUCENT token (5% ink on light, 6% white on dark), which is right for
     a hover wash over a panel but wrong for a control: the browser paints the
     native dropdown list in that same colour, so the list composited to
     near-white and its text with it. A select needs an opaque surface, and
     its options need to be told their colours explicitly — they do not
     inherit from the select on every platform. */
  .perf-row select, .mmd-f select, .frm-row select {
    min-width: 118px; padding: 5px 7px; border-radius: 8px;
    border: 1px solid var(--border-strong);
    background: var(--surface-solid); color: var(--text);
    font: 600 12px/1.2 var(--font); }
  .perf-row select option, .mmd-f select option, .frm-row select option {
    background: var(--surface-solid); color: var(--text); }
  .perf-check { justify-content: flex-start; }
  .perf-check input { width: 16px; height: 16px; accent-color: var(--accent); }
  .perf-check input:disabled + span { opacity: 0.5; }
  .perf-pen { margin: 4px 4px 2px; padding: 8px 10px 4px; border-radius: 11px;
    background: var(--accent-soft); border: 1px solid var(--border); }
  .perf-pen h5 { margin: 0 0 2px; font: 700 10.5px/1 var(--font); letter-spacing: .07em;
    text-transform: uppercase; color: var(--accent); }
  #perf-pen-status:empty { display: none; }
  .perf-help { display: block; margin: 6px 6px 4px; font: 600 12px/1.3 var(--font);
    color: var(--accent); text-decoration: none; }
  .perf-help:hover { text-decoration: underline; }

  /* Glass off. The frosted blur behind every panel is one of the most expensive
     effects on a weak graphics chip, redrawn whenever anything behind a panel
     moves. Without it a translucent panel would be hard to read, so panels go
     to the solid surface colour at the same time. */
  body.perf-noglass *, body.perf-noglass *::before, body.perf-noglass *::after {
    backdrop-filter: none !important; -webkit-backdrop-filter: none !important; }
  body.perf-noglass .glass { background: var(--surface-solid) !important; }

  /* Reduced motion. Durations go to near zero rather than animation:none, so
     every element still lands on its final keyframe \u2014 nothing is left stuck
     half-way. No script listens for transition or animation end events, so
     nothing depends on them running. */
  body.perf-reduced-motion *, body.perf-reduced-motion *::before, body.perf-reduced-motion *::after {
    animation-duration: 0.001ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important; scroll-behavior: auto !important; }

  /* ---------- containers (shrink zones) ----------
     The bar that appears while a container is open. It has to read as "you are
     somewhere else now", because the surface deliberately looks like the board
     it came from. */
  /* Attached to the main menu, not floating between it and the brand. As the
     middle child of a space-between row it was pushed to the centre with a
     wide gap either side; margin-left:auto instead hands all the free space to
     its LEFT, so it sits flush against the controls and the two read as one
     bar. Both take the open container's own colour (--zone-c, set from the
     marker), so it is obvious at a glance that this is not the ordinary board. */
  #zone-bar { display: none; align-items: center; gap: 10px; padding: 6px 14px 6px 6px;
    margin-left: auto; margin-right: -6px;
    border-radius: 999px; min-width: 0; flex: 0 1 auto;
    background: var(--zone-c, #6c5ce7);
    border: 1px solid rgba(255,255,255,0.28); box-shadow: 0 10px 26px rgba(0,0,0,0.28);
    color: #fff; font: 600 13px/1 var(--font); }
  #zone-bar.show { display: flex; }
  body.zone-open .controls { box-shadow: 0 0 0 2px var(--zone-c, #6c5ce7), 0 10px 26px rgba(0,0,0,0.22); }
  #zone-name { max-width: 22vw; }
  /* The export panel's container option: one short line, no hint beneath it,
     so the panel stays the size it was before containers existed. */
  .pop-toggle.exp-compact { padding: 4px 10px; font-size: 12px; }
  .zone-swatches { display: grid; grid-template-columns: repeat(5, 30px); gap: 7px; padding: 4px 6px 6px; }
  .zone-sw { width: 30px; height: 30px; border-radius: 9px; cursor: pointer;
    border: 2px solid transparent; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.18); }
  .zone-sw:hover { transform: scale(1.08); }
  .zone-sw.active { border-color: var(--text); box-shadow: 0 0 0 2px var(--surface-solid) inset; }
  #zone-bar button { display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
    background: rgba(255,255,255,0.16); border: 1px solid rgba(255,255,255,0.25);
    color: #fff; border-radius: 999px; padding: 6px 12px 6px 8px; font: 700 12px/1 var(--font); }
  #zone-bar button:hover { background: rgba(255,255,255,0.28); }
  #zone-bar button svg { width: 15px; height: 15px; }
  .zone-sep { width: 1px; height: 16px; background: rgba(255,255,255,0.3); }
  #zone-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* While a container is open the deck itself is out of reach: its pages are
     not this board's pages, and recording a container is not a thing. */
  body.zone-open .board-strip,
  body.zone-open #rec-btn,
  body.zone-open #boards-btn { opacity: 0.35; pointer-events: none; }
  /* "Repeat on every new board" block inside the Lesson header dialog. */
  .hdr-auto { margin: 10px 0 12px; padding: 10px 8px 4px; border-radius: 10px;
    background: var(--hover); border: 1px solid var(--border); }
  .hdr-auto h5 { margin: 0 4px 6px; font: 700 10.5px/1 var(--font); letter-spacing: .07em;
    text-transform: uppercase; color: var(--muted); }
  .hdr-auto .ins-hint { margin: 4px 4px 6px; }
  /* The move-tool availability note: muted while unavailable, green once the
     board is big enough and the tool has actually appeared. */
  #grow-hand-note.on { color: #2e9e63; font-weight: 600; }
  /* REPORTED: the export panel and the collab menu "looking a bit oversized...
     I think you can condense it", and the presentation options "menu is still a
     bit longer". Every one of those is a list of these, so they are trimmed
     here: a little less padding, a slightly smaller label, a tighter gap. Enough
     to take a row off a long menu without making anything hard to hit — the row
     is still 30px tall, which is above the comfortable minimum. */
  .pop-item { display: flex; align-items: center; gap: 9px; width: 100%; padding: 7px 9px;
    border: none; background: transparent; color: var(--text); border-radius: var(--radius-sm);
    cursor: pointer; text-align: left; font: 550 13px/1.2 var(--font);
    transition: background-color 0.16s var(--ease); }
  .pop-item:hover { background: var(--hover); }
  .pop-item.active { background: var(--accent-soft); color: var(--accent); }
  .pop-item .chip { width: 24px; height: 24px; border-radius: 7px; flex: none;
    border: 1px solid var(--border-strong); box-shadow: inset 0 1px 2px rgba(0,0,0,0.18); }
  .pop-item svg { width: 18px; height: 18px; flex: none; }
  .pop-item .meta { margin-left: auto; font-size: 11px; color: var(--muted); }
  .pop-custom { display: flex; align-items: center; gap: 11px; padding: 9px 10px; border-radius: var(--radius-sm); }
  .pop-custom label { font: 550 13.5px/1.2 var(--font); display: flex; align-items: center; gap: 11px; cursor: pointer; flex: 1; }
  .pop-custom input[type="color"] { width: 30px; height: 30px; padding: 0; border: 1px solid var(--border-strong);
    border-radius: 8px; background: none; cursor: pointer; }
  .pop-custom input[type="color"]::-webkit-color-swatch-wrapper { padding: 2px; }
  .pop-custom input[type="color"]::-webkit-color-swatch { border: none; border-radius: 5px; }
  .pop-slider { display: flex; align-items: center; gap: 10px; padding: 6px 10px; font: 550 13px/1 var(--font); }
  .pop.sizing { opacity: 0.15; transition: opacity 0.1s var(--ease); }
  .pop-action { width: calc(100% - 20px); margin: 8px 10px 4px; padding: 9px; border-radius: 9px; border: 1px solid var(--border-strong);
    background: transparent; color: var(--text); font: 600 12.5px/1 var(--font); cursor: pointer; transition: background-color 0.12s var(--ease), border-color 0.12s var(--ease), color 0.12s var(--ease); }
  .pop-action:hover { background: var(--hover); border-color: var(--accent); color: var(--accent); }
  .pop-slider > span:first-child { width: 48px; color: var(--muted); }
  .pop-slider input[type="range"] { flex: 1; width: auto; }
  .pop-slider .pct { width: 40px; text-align: right; color: var(--muted); font-variant-numeric: tabular-nums; }
  .tex-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; padding: 2px 6px 4px; }
  .tex-grid button { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--text); padding: 7px 4px; border-radius: 8px; font: 600 11.5px/1 var(--font); cursor: pointer;
    transition: background-color 0.14s var(--ease); }
  .tex-grid button:hover { background: var(--hover); }
  .tex-grid button.active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
  .tex-upload { appearance: none; border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    padding: 6px 11px; border-radius: 8px; font: 600 12px/1 var(--font); cursor: pointer; flex: none; }
  .tex-upload:hover { background: var(--hover); }
  /* A label that wraps makes its whole row taller and leaves every button in
     it padded out with empty space. Keep them on one line; if a set really is
     too wide for the panel, it wraps as a set rather than inside a button. */
  .seg { display: flex; gap: 4px; padding: 4px 6px 2px; flex-wrap: wrap; }
  .seg button { white-space: nowrap; min-width: 0; }
  /* Four choices in one row: the labels wrap onto two short lines rather than
     being clipped inside their boxes. */
  #amb-when-seg { flex-wrap: wrap; }
  #amb-when-seg button { flex: 1 1 calc(50% - 4px); white-space: normal; line-height: 1.25;
    padding: 6px 6px; }
  /* REPORTED: the Scene row was stuffed. It held four buttons when it was
     written out by hand; it now holds six or seven, built from whichever
     scenes suit the theme — and the .seg rule further down the sheet sets no
     wrap, so they were squeezed until the labels collided and clipped. Three
     to a row, wrapping, which fits both the six-scene and seven-scene case
     without the panel changing width. */
  #amb-scene-seg, #amb-seg { flex-wrap: wrap; }
  #amb-scene-seg button, #amb-seg button {
    flex: 1 1 calc(33.333% - 6px); min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    padding: 6px 4px; }
  #amb-note.amb-why { color: var(--accent-warn, #f5a524) }
  .seg button { flex: 1; appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--muted); padding: 6px 4px; border-radius: 8px; font: 600 11.5px/1 var(--font); cursor: pointer;
    transition: background-color 0.12s var(--ease); }
  .seg button:hover { background: var(--hover); }
  .seg button.active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
  .pop-toggle { display: flex; align-items: center; gap: 9px; padding: 8px 10px; cursor: pointer;
    font: 550 13px/1.3 var(--font); }
  .pop-toggle input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
  .ins-tabs { display: flex; gap: 4px; padding: 2px 4px 8px; }
  .ins-tabs button { flex: 1; appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--muted); padding: 6px 4px; border-radius: 8px; font: 600 11.5px/1 var(--font); cursor: pointer; }
  .ins-tabs button.active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
  .ins-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; max-height: 220px; overflow-y: auto;
    padding: 2px; scrollbar-width: thin; }
  .ins-grid button { appearance: none; border: none; background: transparent; cursor: pointer; border-radius: 8px;
    color: var(--text); height: 34px; font-size: 21px; line-height: 1; display: grid; place-items: center; transition: background-color 0.12s var(--ease); }
  .ins-grid button:hover { background: var(--hover); }
  .ins-hint { margin: 8px 6px 2px; font: 500 11px/1.4 var(--font); color: var(--muted); }
  .pop-label { font: 600 10.5px/1 var(--font); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin: 4px 4px 5px; }
  .pop-label:first-child { margin-top: 0; }
  #fill-pop .pop-label + .seg, #fill-pop .pop-label + .brush-grid { margin-bottom: 4px; }
  .brush-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; margin-bottom: 4px; }
  .brush-grid button { font: 600 12px var(--font); padding: 8px 4px; border-radius: 9px; border: 1px solid var(--border); background: var(--surface); color: var(--text); cursor: pointer; transition: background .15s, border-color .15s, color .15s; }
  .brush-grid button:hover { background: var(--hover); }
  .brush-grid button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
  #brush-size-row label { font: 600 12px var(--font); color: var(--text); }
  #brush-size-row input[type=range] { flex: 1; }
  #brush-size-meta { min-width: 22px; text-align: right; }
  .shape-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 3px; padding: 3px; max-height: 260px; overflow-y: auto; }
  .shape-grid button { appearance: none; border: 1px solid transparent; background: transparent; color: var(--text);
    cursor: pointer; border-radius: 9px; height: 40px; display: grid; place-items: center;
    transition: background-color 0.12s var(--ease); }
  .shape-grid button:hover { background: var(--hover); }
  .shape-grid button.active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
  .shape-grid button svg { width: 22px; height: 22px; }

  /* ---------- export panel ---------- */
  #export-pop { min-width: 258px; }
  #exp-trim-seg button { padding: 8px 2px; font-size: 11.5px; }
  #exp-trim-seg button small { font-size: 9.5px; }
  .seg { display: flex; gap: 6px; padding: 2px 6px 8px; }
  .seg button { flex: 1; appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--text); border-radius: 10px; padding: 9px 6px; font: 600 13px/1.1 var(--font); cursor: pointer;
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    transition: background-color 0.16s var(--ease), border-color 0.16s var(--ease), color 0.16s var(--ease); }
  .seg button small { font-weight: 500; font-size: 10px; color: var(--muted); }
  .seg button:hover { background: var(--hover); }
  .seg button.active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
  .seg button.active small { color: var(--accent); }
  .seg-wrap { flex-wrap: wrap; }
  .seg-wrap button { flex: 1 0 28%; padding: 8px 6px; }
  .exp-dims { font-size: 11.5px; color: var(--muted); text-align: center; padding: 2px 6px 9px; }
  .exp-download { width: calc(100% - 12px); margin: 0 6px 4px; appearance: none; border: none; cursor: pointer;
    background: var(--accent); color: #fff; border-radius: 11px; padding: 11px; font: 600 13.5px/1 var(--font);
    display: flex; align-items: center; justify-content: center; gap: 8px;
    box-shadow: 0 6px 16px -6px var(--accent); transition: background-color 0.16s var(--ease); }
  .exp-download:hover { background: var(--accent-press); }
  .exp-download:active { transform: scale(0.97); }
  .exp-download svg { width: 16px; height: 16px; }
  .exp-copy { width: calc(100% - 12px); margin: 6px 6px 4px; appearance: none; cursor: pointer;
    border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    border-radius: 10px; padding: 9px; font: 600 13px/1 var(--font); display: flex; align-items: center;
    justify-content: center; gap: 8px; transition: background-color 0.16s var(--ease), transform 0.1s var(--ease); }
  .exp-copy:hover { background: var(--hover); }
  .exp-copy:active { transform: scale(0.97); }
  .exp-copy svg { width: 16px; height: 16px; }
  /* Compact 3-across rows (Share/Copy/Print, Save/Open/Player) — the panel
     used to be one long single-file column and barely fitted a laptop. */
  .exp-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 6px 6px 4px; }
  /* Two mini buttons across, same row height — the beats manager moved to the
     Presentation menu and left this row a cell short. */
  .exp-row.exp-row-2 { grid-template-columns: repeat(2, 1fr); }
  /* The GIF's beat count and warning, where the resolution rows would be —
     the panel keeps its height whichever format is chosen. */
  .exp-note { margin: 2px 6px 4px; min-height: 17px; }
  .exp-mini { appearance: none; cursor: pointer; border: 1px solid var(--border-strong); background: transparent;
    color: var(--text); border-radius: 10px; padding: 8px 4px 7px; font: 600 11.5px/1.15 var(--font);
    display: flex; flex-direction: column; align-items: center; gap: 5px;
    transition: background-color 0.16s var(--ease), transform 0.1s var(--ease); }
  .exp-mini:hover { background: var(--hover); }
  .exp-mini:active { transform: scale(0.96); }
  .exp-mini svg { width: 16px; height: 16px; }

  /* ---------- offline overlay ---------- */
  .offline { position: fixed; inset: 0; z-index: 200; display: none; align-items: center; justify-content: center;
    padding: 24px; background: rgba(8, 10, 16, 0.55);
    backdrop-filter: blur(9px) saturate(140%); -webkit-backdrop-filter: blur(9px) saturate(140%); }
  .offline.show { display: flex; animation: offin 0.26s var(--ease); }
  @keyframes offin { from { opacity: 0; } to { opacity: 1; } }
  .offline-card { max-width: 360px; text-align: center; padding: 30px 28px; border-radius: var(--radius-lg);
    animation: offcard 0.32s var(--ease-spring); }
  @keyframes offcard { from { transform: translateY(10px) scale(0.97); } to { transform: none; } }
  .offline-icon { width: 60px; height: 60px; margin: 0 auto 16px; border-radius: 18px; display: grid;
    place-items: center; background: var(--accent-soft); color: var(--accent); }
  .offline-icon svg { width: 30px; height: 30px; }
  .offline-card h3 { margin: 0 0 8px; font-size: 19px; font-weight: 650; letter-spacing: -0.01em; }
  .offline-card p { margin: 0 0 18px; font-size: 13.5px; line-height: 1.55; color: var(--muted); }
  .offline-status { font-size: 12.5px; font-weight: 600; color: var(--accent);
    display: inline-flex; align-items: center; gap: 8px; }
  .offline-status::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor;
    animation: pulse 1.4s ease-in-out infinite; }
  @keyframes pulse { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } }

  /* ---------- toast ---------- */
  #toast { position: fixed; bottom: 92px; left: 50%; transform: translateX(-50%) translateY(16px);
    background: var(--surface-solid); border: 1px solid var(--border); box-shadow: var(--shadow);
    color: var(--text); padding: 10px 16px; border-radius: 999px; font-size: 13px; font-weight: 550;
    display: flex; align-items: center; gap: 9px; opacity: 0; pointer-events: none;
    transition: opacity 0.3s var(--ease), transform 0.32s var(--ease-spring); z-index: 70; }
  #toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
  #toast svg { width: 16px; height: 16px; color: var(--accent); }

  /* ---------- Slate Player ---------- */
  /* The top bar is hidden by body.stage, above, for a show and a replay alike.
     What is left here is the difference between the two: a show keeps the
     tools, because annotating while you teach is the point; a replay has
     nothing to draw with. */
  body.player-mode .rail,
  body.player-mode .stylebar { display: none !important; }
  body.player-mode #board { cursor: default !important; }
  #player-title { position: fixed; top: 18px; left: 50%; transform: translateX(-50%);
    background: var(--surface-solid); border: 1px solid var(--border); box-shadow: var(--shadow);
    color: var(--text); padding: 9px 18px; border-radius: 999px; font: 600 14px/1.2 var(--font);
    max-width: min(90vw, 520px); text-align: center; z-index: 71; display: none; }
  #player-bar { position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%);
    display: none; flex-direction: column; align-items: stretch; gap: 8px; z-index: 72;
    background: var(--surface-solid); border: 1px solid var(--border); box-shadow: var(--shadow);
    padding: 9px 13px 11px; border-radius: 18px;
    width: max-content; max-width: calc(100vw - 20px); }
  .pl-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: center; }
  /* A cluster of controls that belong together. Twenty loose buttons in one
     wrapping row scattered across three lines in no particular arrangement;
     grouped, a row that has to wrap moves whole clusters and the shape of the
     bar still reads. */
  .pl-group { display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }
  .pl-view { padding-left: 8px; border-left: 1px solid var(--border); }
  /* Saving, exporting and leaving: the things you do at the end, kept together
     and set apart from what you touch while teaching. */
  .pl-finish { padding-left: 10px; border-left: 1px solid var(--border); gap: 6px; }
  .pl-out { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--text); padding: 8px 12px; border-radius: 10px;
    font: 600 12.5px/1 var(--font); cursor: pointer; white-space: nowrap; }
  .pl-out:hover { border-color: var(--accent); color: var(--accent); }
  .pl-btn { appearance: none; border: none; background: transparent; color: var(--text);
    width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center; cursor: pointer;
    transition: background-color 0.12s var(--ease); }
  .pl-btn:hover { background: var(--hover); }
  .pl-btn svg { width: 20px; height: 20px; }
  .pl-main { background: var(--accent); color: #fff; width: 44px; height: 44px; }
  .pl-main:hover { background: var(--accent); filter: brightness(1.08); }
  .pl-main svg { width: 24px; height: 24px; }
  .pl-toggle.on { background: var(--accent); color: #fff; }
  .pl-boards { display: flex; align-items: center; gap: 4px; padding-right: 4px; margin-right: 2px; border-right: 1px solid var(--border);
    min-width: 0; max-width: min(56vw, 430px); overflow-x: auto; overflow-y: hidden;
    scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .pl-boards::-webkit-scrollbar { display: none; }
  .pl-boards > * { flex: 0 0 auto; }
  .pl-boards-lbl { font: 600 11px/1 var(--font); color: var(--muted); margin-right: 2px; }
  .pl-board-tab { appearance: none; border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    min-width: 26px; height: 28px; border-radius: 8px; font: 600 12.5px/1 var(--font); cursor: pointer; }
  .pl-board-tab:hover { background: var(--hover); }
  .pl-board-tab.active { background: var(--accent); border-color: var(--accent); color: #fff; }
  .pl-board-tab.empty { opacity: 0.45; }
  #fx-canvas { position: fixed; inset: 0; pointer-events: none; z-index: 200; }
  /* REPORTED: ambience dimmed the tool rail and the style bar along with the
     room. It sat at z-index 30 — above the rail (26) and the style bar (25) —
     so the controls were behind the scrim and the scrim was doing its job on
     them. It belongs just above the board canvas and below every piece of
     chrome, so the room darkens and the things you work with do not. */
  #theatre-canvas { position: fixed; inset: 0; pointer-events: none; z-index: 3; display: none; }
  /* REPORTED: ambience did nothing at all during a show. The canvas was gated
     on body.player-mode — the beats manager's class — so while presenting it
     was drawn to on every frame and never displayed. body.stage covers both.

     REPORTED AGAIN, for "On the board": body.stage is set only while
     presenting or replaying, which is exactly the two cases ambOnStage()
     already covers — so the two WHEN settings added afterwards, "On the
     board" and "When idle", drew fifteen frames a second into a canvas CSS
     kept hidden. Nothing on screen, and the Room panel cheerfully reported
     "Running now", because it was. The gate is now the `on` class alone,
     which startTheatre and stopTheatre already put on and take off from
     ambienceRunning() — the one function that knows when the room should be
     alive. z-index 3 still keeps it above the board and below every control,
     so showing it off-stage dims the room and not the tools. */
  #theatre-canvas.on { display: block; }
  /* floating selection toolbar (front / back / lock / delete) */
  #sel-tools { position: fixed; display: none; align-items: center; gap: 2px; z-index: 60;
    padding: 4px; border-radius: 13px; border: 1px solid var(--border); background: var(--surface-solid);
    box-shadow: var(--shadow); }
  #sel-tools.show { display: inline-flex; }
  body.player-mode #sel-tools { display: none !important; }
  #sel-tools button { width: 34px; height: 34px; border-radius: 9px; border: none; background: transparent;
    color: var(--text); cursor: pointer; padding: 0; display: inline-flex; align-items: center; justify-content: center;
    transition: background 0.15s, transform 0.12s, color 0.15s; }
  /* `display: inline-flex` above beats the hidden attribute, so every
     conditional button in this bar was showing at all times — including two
     different "detach" buttons at once. Restore what hidden is supposed to do. */
  #sel-tools button[hidden] { display: none !important; }
  #sel-tools button:hover { background: var(--hover); }
  #sel-tools button:active { transform: scale(0.92); }
  #sel-tools button svg { width: 18px; height: 18px; }
  #sel-tools .sel-sep { width: 1px; height: 22px; background: var(--border); margin: 0 2px; }
  #sel-delete { color: #e5484d; }
  #sel-delete:hover { background: #e5484d; color: #fff; }
  #sel-lock.locked { color: #fff; background: var(--accent); }
  #sel-lock.locked:hover { background: var(--accent); }

  /* classroom timer */
  /* The format painter is a mode, and the cursor is the only thing on the page
     that can say so while the pointer is over the board. */
  body.painter-on #board { cursor: copy; }

  /* ---------- time machine ----------
     Same card as the timer and the region panel, for the same reason: it belongs
     on the board rather than announcing itself. `display:none` on the id so the
     UA [hidden] rule is never what decides. */
  #tm-card { position: fixed; display: none; z-index: 121; left: 22px; bottom: 92px; width: 258px;
    border-radius: 18px; border: 1px solid var(--border); background: var(--surface-solid);
    box-shadow: 0 24px 60px -18px rgba(0,0,0,0.45); padding: 11px 13px 13px;
    user-select: none; touch-action: none;
    max-height: calc(100vh - 120px); overflow-y: auto; overscroll-behavior: contain; }
  #tm-card.show { display: block; animation: timerPop 0.28s var(--ease-spring); }
  #tm-head { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; cursor: grab; }
  #tm-title { font: 800 12.5px/1 var(--font); color: var(--text); }
  #tm-close { margin-left: auto; appearance: none; border: none; background: transparent; color: var(--muted);
    font-size: 19px; line-height: 1; cursor: pointer; padding: 0 2px; }
  #tm-close:hover { color: var(--text); }
  #tm-note { font: 500 11.5px/1.35 var(--font); color: var(--muted); margin: 0 0 9px; min-height: 2.2em; }
  .tm-row { display: flex; align-items: center; gap: 6px; margin-bottom: 7px; }
  .tm-slider-row input[type="range"] { flex: 1 1 auto; min-width: 0; margin: 0; }
  .tm-val { flex: none; min-width: 42px; text-align: right;
    font: 700 11px/1 var(--font); color: var(--text); font-variant-numeric: tabular-nums; }
  .tm-btn { appearance: none; flex: 1 1 auto; padding: 7px 6px; border-radius: 10px;
    border: 1px solid var(--border-strong); background: var(--surface-solid); color: var(--text);
    font: 700 11.5px/1 var(--font); cursor: pointer; }
  .tm-btn:hover:not(:disabled) { background: var(--hover); }
  .tm-btn:disabled { opacity: 0.45; cursor: default; }
  .tm-warn { border-color: rgba(229,72,77,0.45); color: #e5484d; }
  #tm-list { display: flex; flex-direction: column; gap: 5px; margin-top: 4px; }
  #tm-list:empty { display: none; }
  .tm-cap { display: flex; align-items: center; gap: 7px; padding: 5px 6px; border-radius: 9px;
    border: 1px solid var(--border); background: var(--hover); cursor: pointer; text-align: left; }
  .tm-cap:hover { border-color: var(--accent); }
  .tm-cap img { width: 34px; height: 24px; object-fit: cover; border-radius: 4px; flex: none;
    background: rgba(0,0,0,0.25); }
  .tm-cap .tm-pin { width: 34px; height: 24px; flex: none; display: grid; place-items: center;
    border-radius: 4px; background: var(--accent-soft); color: var(--accent); font: 800 10px/1 var(--font); }
  .tm-cap .tm-cap-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; font: 700 11.5px/1.25 var(--font); color: var(--text); }
  .tm-cap .tm-cap-when { flex: none; font: 500 10px/1 var(--font); color: var(--muted); }
  /* A preview is not the board. The window says so, so a scrubbed-back board can
     never be mistaken for the live one. */
  body.tm-preview #board { outline: 3px solid #f5a524; outline-offset: -3px; }
  body.tm-preview::after { content: "Preview \2014 not the live board"; position: fixed; z-index: 122;
    left: 50%; top: 10px; transform: translateX(-50%); pointer-events: none;
    padding: 5px 12px; border-radius: 999px; background: #f5a524; color: #1a1205;
    font: 800 11.5px/1 var(--font); box-shadow: 0 8px 22px rgba(0,0,0,0.3); }

  /* ---------- region playback ----------
     Built from the same parts as the timer card so it belongs on the board
     rather than announcing itself: a class to show it, a header to drag it by,
     and nothing that needs its own rendering. `display:none` sits on the id so
     the UA [hidden] rule is never the thing deciding \u2014 the trap noted for
     .tool, #sel-tools and #calc-card. */
  /* REPORTED: "the button seems to be all over the place... the text is flowing
     outside the panel." Six more buttons had gone into a 226px card. It is a
     little wider now, and it only ever shows the controls for the one way the
     region is being used, so there is room for a label to be read. */
  #rgn-card { position: fixed; display: none; z-index: 120; right: 22px; bottom: 92px; width: 252px;
    border-radius: 18px; border: 1px solid var(--border); background: var(--surface-solid);
    box-shadow: 0 24px 60px -18px rgba(0,0,0,0.45); padding: 11px 13px 13px;
    user-select: none; touch-action: none; }
  #rgn-card.show { display: block; animation: timerPop 0.28s var(--ease-spring); }
  #rgn-head { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; cursor: grab; }
  #rgn-title { font: 800 12.5px/1 var(--font); color: var(--text); letter-spacing: 0.01em; }
  #rgn-close { margin-left: auto; appearance: none; border: none; background: transparent; color: var(--muted);
    font-size: 19px; line-height: 1; cursor: pointer; padding: 0 2px; }
  #rgn-close:hover { color: var(--text); }
  #rgn-note { font: 500 11.5px/1.35 var(--font); color: var(--muted); margin: 0 0 9px; min-height: 2.2em; }
  .rgn-row { display: flex; align-items: center; gap: 7px; margin-bottom: 8px; }
  .rgn-row:last-child { margin-bottom: 0; }
  .rgn-btn { appearance: none; flex: 1 1 auto; padding: 7px 8px; border-radius: 10px;
    border: 1px solid var(--border-strong); background: var(--surface-solid); color: var(--text);
    font: 700 12px/1 var(--font); cursor: pointer; }
  .rgn-btn:hover:not(:disabled) { background: var(--hover); }
  .rgn-btn:disabled { opacity: 0.45; cursor: default; }
  .rgn-go { background: var(--accent-soft); border-color: rgba(108,92,231,0.4); }
  .rgn-lbl { font: 600 11.5px/1 var(--font); color: var(--muted); flex: none; }
  /* Sliders rather than four fixed steps: a speed is a preference, not a set of
     four opinions, and the same row shape carries the dim control. */
  .rgn-slider-row input[type="range"] { flex: 1 1 auto; min-width: 0; margin: 0; }
  .rgn-val { flex: none; min-width: 34px; text-align: right;
    font: 700 11px/1 var(--font); color: var(--text); font-variant-numeric: tabular-nums; }
  .rgn-check { display: flex; align-items: center; gap: 7px; margin: 0 0 8px;
    font: 600 11.5px/1.3 var(--font); color: var(--muted); cursor: pointer; }
  .rgn-check input { flex: none; }
  .rgn-export-row { gap: 5px; }
  .rgn-mini { flex: 1 1 auto; padding: 6px 4px; font-size: 11px; }
  .rgn-step-row, .rgn-save-row, .rgn-cover-row, .rgn-split-row { gap: 5px; }
  .rgn-split-row .rgn-lbl { flex: none; }
  .rgn-split-row .rgn-mini { flex: 0 0 auto; min-width: 26px; padding: 6px 6px; }
  /* A pressed control is the accent, solid, with white on it. The soft wash
     with accent-coloured text measures under 3:1 on a dark panel, which is the
     "grey on white, not readable" that was reported. */
  .rgn-cover[aria-pressed="true"], .rgn-axis[aria-pressed="true"], .rgn-cut[aria-pressed="true"],
  .rgn-tool[aria-pressed="true"], .rgn-wayb[aria-pressed="true"] {
    background: var(--accent); border-color: var(--accent); color: #fff; }
  /* The four ways of using a region, one of which is always in use. */
  .rgn-modes { gap: 4px; margin-bottom: 9px; }
  .rgn-modes .rgn-wayb { flex: 1 1 0; min-width: 0; padding: 7px 2px; font-size: 10.5px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .rgn-row[data-way] { display: none; }
  .rgn-row[data-way].on { display: flex; }
  .rgn-cutrow { gap: 4px; }
  .rgn-cutrow .rgn-tool { flex: 1 1 0; min-width: 0; padding: 6px 3px; font-size: 10.5px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .rgn-cutrow2 { gap: 5px; }
  /* The status line gets a row of its own and wraps inside it, so it can never
     run past the edge of the card however many parts there are. */
  .rgn-inforow { margin-bottom: 8px; }
  .rgn-cutinfo { flex: 1 1 auto; min-width: 0; white-space: normal;
    line-height: 1.35; font-weight: 600; color: var(--muted); }
  .rgn-cutinfo.rgn-loose { color: var(--accent-warn, #f5a524); }
  /* While a cover is up, a press inside the region rubs it clear rather than
     starting a rectangle, so the cursor says so. */
  body.region-mode.region-cover #board { cursor: cell; }
  /* While cutting, the pointer is a blade: a tap lands a line. */
  body.region-mode.region-cutting #board { cursor: crosshair; }
  .rgn-mode[aria-pressed="true"] { background: var(--accent-soft, rgba(108,92,231,0.16));
    border-color: rgba(108,92,231,0.55); color: var(--accent, #6c5ce7); }
  /* The steps, as numbered chips in the order they play. Wraps rather than
     scrolls: a teacher should see the whole sequence at a glance. */
  .rgn-chips { display: flex; flex-wrap: wrap; gap: 4px; margin: 0 0 8px; }
  .rgn-chip { appearance: none; display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 5px 3px 7px; border-radius: 8px; border: 1px solid var(--border);
    background: var(--surface-solid); color: var(--muted);
    font: 700 10.5px/1 var(--font); cursor: pointer; }
  .rgn-chip:hover { background: var(--hover); }
  .rgn-chip.now { border-color: rgba(108,92,231,0.6); color: var(--accent, #6c5ce7);
    background: rgba(108,92,231,0.12); }
  .rgn-chip.done { opacity: 0.55; }
  .rgn-chip .x { font-size: 12px; line-height: 1; opacity: 0.5; padding: 0 1px; }
  .rgn-chip .x:hover { opacity: 1; }
  .rgn-saved-lbl { flex: 1 1 auto; text-align: right; }
  .rgn-saved { display: flex; flex-direction: column; gap: 3px; margin: 0 0 8px;
    max-height: 132px; overflow-y: auto; overscroll-behavior: contain; }
  .rgn-item { display: flex; align-items: center; gap: 4px; }
  /* A kept region whose work has gone: it still lists, so it can be renamed or
     removed, but it says plainly that there is nothing left inside. */
  .rgn-item.gone .nm { opacity: 0.5; text-decoration: line-through }
  .rgn-item .nm { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; font: 600 11.5px/1.3 var(--font); color: var(--text);
    padding: 3px 4px; border-radius: 7px; cursor: pointer; }
  .rgn-item .nm:hover { background: var(--hover); }
  .rgn-item .nm .ct { color: var(--muted); font-weight: 500; }
  .rgn-item button { appearance: none; flex: none; width: 22px; height: 22px; padding: 0;
    border-radius: 7px; border: 1px solid var(--border); background: var(--surface-solid);
    color: var(--muted); font-size: 11px; line-height: 1; cursor: pointer; }
  .rgn-item button:hover { background: var(--hover); color: var(--text); }
  /* The rectangle is drawn on the canvas, so the cursor is the only hint the
     DOM has to give that a press will start one. */
  body.region-mode #board { cursor: crosshair; }
  #timer-card { position: fixed; display: none; z-index: 120; right: 22px; bottom: 92px; width: 244px;
    border-radius: 20px; border: 1px solid var(--border); background: var(--surface-solid);
    box-shadow: 0 24px 60px -18px rgba(0,0,0,0.45); padding: 12px 14px 14px; user-select: none; touch-action: none;
    /* A long agenda must never grow taller than the window. Cap it and let the
       inside scroll, so the header and its close button always stay reachable. */
    max-height: calc(100vh - 24px); overflow-y: auto; overscroll-behavior: contain; }
  #timer-card.show { display: block; animation: timerPop 0.28s var(--ease-spring); }
  @keyframes timerPop { from { opacity: 0; transform: translateY(10px) scale(0.96); } to { opacity: 1; transform: none; } }
  #timer-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
  #timer-grip { display: flex; flex-direction: column; gap: 3px; cursor: grab; padding: 4px 2px; }
  #timer-grip i { display: block; width: 16px; height: 2px; border-radius: 2px; background: var(--text-soft); opacity: 0.5; }
  #timer-title { font-weight: 700; font-size: 14px; letter-spacing: 0.01em; flex: 1; }
  #timer-close { width: 26px; height: 26px; border-radius: 8px; border: none; background: transparent; color: var(--text-soft); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
  #timer-close:hover { background: var(--hover); color: var(--text); }
  #timer-close svg { width: 15px; height: 15px; }
  #timer-min { width: 26px; height: 26px; border-radius: 8px; border: none; background: transparent; color: var(--text-soft); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
  #timer-min:hover { background: var(--hover); color: var(--text); }
  #timer-min svg { width: 16px; height: 16px; }
  /* minimised corner pill */
  #timer-label { flex: 1; min-width: 0; background: transparent; border: 1px solid transparent;
    color: var(--text); font: 700 14px/1.2 var(--font); border-radius: 7px; padding: 3px 6px; }
  /* A heading, not a field. It read as editable and invited a click that did
     nothing useful. */
  #timer-label { pointer-events: none; cursor: default; }
  #timer-label:hover { border-color: transparent; }
  #timer-label:focus { outline: none; border-color: var(--accent); background: var(--hover); }
  #timer-tabs { margin: 2px 0 8px; }
  #timer-tabs button { padding: 4px 10px; font-size: 11px; }
  #tz-picker { margin-top: 10px; border-top: 1px solid var(--border-strong); padding-top: 9px; }
  #tz-search { width: 100%; box-sizing: border-box; margin-bottom: 6px; padding: 6px 9px;
    border-radius: 8px; border: 1px solid var(--border-strong); background: var(--hover);
    color: var(--text); font: 500 12.5px/1.3 var(--font); }
  #tz-list { max-height: 152px; overflow-y: auto; border: 1px solid var(--border-strong); border-radius: 9px; }
  #tz-list button { display: flex; width: 100%; align-items: center; gap: 8px; appearance: none;
    border: 0; background: transparent; color: var(--text); cursor: pointer; text-align: left;
    padding: 6px 9px; font: 500 12px/1.3 var(--font); }
  #tz-list button:hover { background: var(--hover); }
  #tz-list button.active { background: var(--accent); color: #fff; }
  #tz-list .now { margin-left: auto; font-variant-numeric: tabular-nums; color: var(--text-soft); font-weight: 600; }
  #tz-list button.active .now { color: #fff; }
  #tz-face { margin-top: 7px; }
  #timer-alarm { margin-top: 8px; }
  #timer-alarm .frm-row > span { width: 54px; }
  #timer-alarm input[type=time] { flex: 1; padding: 6px 9px; border-radius: 8px;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text);
    font: 600 13px/1.3 var(--font); }
  #timer-at-note { margin: 6px 0 0; }
  #timer-agenda { margin-top: 8px; }
  #timer-seg-now { font: 700 12.5px/1.4 var(--font); color: var(--text); margin-bottom: 6px; min-height: 18px; }
  #timer-seg-now small { display: block; font: 500 11px/1.4 var(--font); color: var(--text-soft); }
  #timer-seg-list { max-height: 116px; overflow-y: auto; }
  .tseg { display: grid; grid-template-columns: 14px 1fr 46px auto auto auto; gap: 4px;
    align-items: center; margin-bottom: 4px; }
  .tseg .n { font: 700 10px/1 var(--font); color: var(--text-soft); text-align: center; }
  .tseg.now .n { color: var(--accent); }
  .tseg input { min-width: 0; padding: 4px 6px; border-radius: 6px; border: 1px solid var(--border-strong);
    background: var(--hover); color: var(--text); font: 500 11.5px/1.3 var(--font); }
  .tseg button { border: 1px solid var(--border-strong); background: transparent; color: var(--text-soft);
    width: 20px; height: 22px; border-radius: 5px; cursor: pointer; font: 700 10px/1 var(--font); padding: 0; }
  .tseg button:hover { background: var(--hover); color: var(--text); }
  .tseg.done input { opacity: .55; }
  .timer-ag-opts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 7px;
    font: 500 11px/1.3 var(--font); color: var(--text-soft); }
  .timer-ag-opts label { display: flex; align-items: center; gap: 4px; }
  .timer-ag-opts input[type=number] { width: 40px; padding: 3px 5px; border-radius: 6px;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text); font-size: 11px; }
  .timer-ag-opts select { flex: 1; min-width: 0; padding: 3px 6px; border-radius: 6px;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text); font-size: 11px; }
  #timer-laps { margin-top: 8px; }
  #timer-lap-list { max-height: 74px; overflow-y: auto; font: 600 11.5px/1.6 var(--font); color: var(--text-soft); }
  #timer-lap-list b { color: var(--text); font-variant-numeric: tabular-nums; }
  #timer-lap-list .fast { color: #4caf7d; }
  #timer-lap-list .slow { color: var(--accent-warn); }
  .timer-lap-row { display: flex; gap: 6px; margin-top: 6px; }
  .timer-lap-row button { flex: 1; padding: 6px; border-radius: 9px; border: 1px solid var(--border-strong);
    background: transparent; color: var(--text); font: 600 12px/1 var(--font); cursor: pointer; }
  .timer-lap-row button:hover { background: var(--hover); }
  #timer-opts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 9px;
    font: 500 11.5px/1.3 var(--font); color: var(--text-soft); }
  #timer-opts label { display: flex; align-items: center; gap: 5px; cursor: pointer; }
  #timer-opts button { margin-left: auto; padding: 5px 10px; border-radius: 8px;
    border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    font: 600 11.5px/1 var(--font); cursor: pointer; }
  #timer-opts button:hover { background: var(--hover); }
  /* Overtime: the ring stays full and the digits go red with a leading plus. */
  #timer-card.over #timer-time { color: var(--danger, #ff8a80); }
  #timer-card.over #timer-ring .tr-prog { stroke: var(--danger, #ff8a80); }
  @keyframes timerFlash { 0%,100% { background: var(--surface-solid); } 50% { background: var(--accent-warn, #f5a524); } }
  #timer-card.flashing { animation: timerFlash 0.45s ease-in-out 3; }
  #timer-mini { display: none; align-items: center; gap: 9px; padding: 2px 4px; }
  #timer-card.mini { width: auto; right: 18px; bottom: 18px; left: auto; top: auto; padding: 7px 9px; border-radius: 14px; }
  #timer-card.mini > :not(#timer-mini) { display: none; }
  #timer-card.mini > #timer-mini { display: flex; }
  #timer-mini button { width: 34px; height: 34px; border-radius: 10px; border: 1px solid var(--border); background: var(--surface); color: var(--text); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
  #timer-mini-toggle { background: var(--accent) !important; border-color: var(--accent) !important; color: #fff !important; }
  #timer-card.mini.running #timer-mini-toggle { background: #e5484d !important; border-color: #e5484d !important; }
  #timer-mini button svg { width: 16px; height: 16px; }
  #timer-mini-time { font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; min-width: 64px; text-align: center; }
  #timer-card.mini.warn #timer-mini-time { color: #f5a524; }
  #timer-card.mini.done #timer-mini-time { color: #e5484d; }
  #timer-dial { position: relative; width: 168px; height: 168px; margin: 4px auto 8px; }
  /* Agenda stacks a segment list under the dial, so the dial gives height
     back — on a laptop the card used to fill the whole window and scroll. */
  #timer-card.mode-agenda #timer-dial { width: 118px; height: 118px; margin: 2px auto 6px; }
  #timer-card.mode-agenda #timer-time { font-size: 26px; }
  #timer-card.mode-agenda #timer-edit { width: 92px; font-size: 24px; }
  #timer-card.mode-agenda #timer-state { font-size: 10px; letter-spacing: 0.1em; }
  /* Laptop screens are short: shave the dial a little in every mode. */
  @media (max-height: 820px) {
    #timer-dial { width: 140px; height: 140px; }
    #timer-time { font-size: 32px; }
    #timer-card { padding: 10px 12px 12px; }
    #timer-card.mode-agenda #timer-dial { width: 112px; height: 112px; }
  }
  #timer-ring { width: 100%; height: 100%; }
  #timer-ring .tr-track { fill: none; stroke: var(--hover); stroke-width: 9; }
  #timer-ring .tr-prog { fill: none; stroke: var(--accent); stroke-width: 9; stroke-linecap: round;
    stroke-dasharray: 326.7; stroke-dashoffset: 0; transition: stroke-dashoffset 0.3s linear, stroke 0.3s; }
  #timer-readout { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; pointer-events: none; }
  #timer-time { font-size: 38px; font-weight: 800; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; line-height: 1; pointer-events: auto; cursor: pointer; border-radius: 8px; padding: 0 4px; }
  #timer-time:hover { background: var(--hover); }
  #timer-edit { display: none; width: 118px; text-align: center; font-size: 34px; font-weight: 800; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; background: var(--surface); color: var(--text); border: 2px solid var(--accent); border-radius: 10px; padding: 2px 0; pointer-events: auto; outline: none; }
  #timer-card.editing #timer-time, #timer-card.editing #timer-state { display: none; }
  #timer-card.editing #timer-edit { display: block; }
  #timer-state { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: var(--text-soft); }
  /* last-15s warning */
  #timer-card.warn #timer-ring .tr-prog { stroke: var(--accent-warn, #f5a524); }
  #timer-card.warn #timer-time { color: #f5a524; animation: timerPulse 1s ease-in-out infinite; }
  @keyframes timerPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.45; } }
  /* done */
  #timer-card.done #timer-ring .tr-prog { stroke: #e5484d; }
  #timer-card.done #timer-time { color: #e5484d; }
  #timer-card.done #timer-dial { animation: timerDone 0.6s ease-in-out 4; }
  @keyframes timerDone { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.06); opacity: 0.4; } }
  #timer-presets, #timer-adjust { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; margin-bottom: 7px; }
  /* An id selector setting `display` beats the browser's own [hidden] rule, so
     hiding these from script did nothing at all — the preset buttons stayed
     live in Alarm mode and quietly overwrote the ring-at time. */
  #timer-card [hidden] { display: none !important; }
  #timer-presets .tp, #timer-adjust .tadj { font-size: 12px; font-weight: 600; padding: 7px 0; border-radius: 9px;
    border: 1px solid var(--border); background: var(--surface); color: var(--text); cursor: pointer; font-variant-numeric: tabular-nums; transition: background 0.15s, border-color 0.15s; }
  #timer-presets .tp:hover, #timer-adjust .tadj:hover { background: var(--hover); }
  #timer-presets .tp.active { background: var(--accent); color: #fff; border-color: var(--accent); }
  #timer-adjust .tadj { color: var(--text-soft); }
  #timer-controls { display: flex; align-items: center; gap: 7px; }
  #timer-controls button { height: 40px; border-radius: 11px; border: 1px solid var(--border); background: var(--surface); color: var(--text); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
  #timer-reset, #timer-sound { width: 40px; flex: none; }
  #timer-reset svg, #timer-sound svg { width: 18px; height: 18px; }
  #timer-toggle { flex: 1; font-size: 15px; font-weight: 700; }
  #timer-toggle.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
  #timer-toggle.running { background: #e5484d; border-color: #e5484d; color: #fff; }
  #timer-sound { color: var(--text-soft); }
  #timer-sound.on { color: var(--accent); }
  #timer-sound.off svg { opacity: 0.6; }

  /* temporary-ink toggle (in style bar) */
  #temp-toggle { display: none; align-items: center; gap: 6px; height: 32px; padding: 0 11px; border-radius: 10px;
    border: 1px solid var(--border); background: var(--surface); color: var(--text-soft); cursor: pointer; font-size: 12.5px; font-weight: 600; white-space: nowrap; }
  #temp-toggle.show { display: inline-flex; }
  #temp-toggle svg { width: 15px; height: 15px; }
  #temp-toggle.active { background: var(--accent); border-color: var(--accent); color: #fff; }
  #fade-hold { display: none; align-items: center; gap: 2px; height: 32px; padding: 0 4px; border-radius: 10px; border: 1px solid var(--border); background: var(--surface); }
  #fade-hold.show { display: inline-flex; }
  #fade-hold button { width: 24px; height: 24px; border: none; background: transparent; color: var(--text); font-size: 17px; font-weight: 700; line-height: 1; cursor: pointer; border-radius: 7px; display: inline-flex; align-items: center; justify-content: center; }
  #fade-hold button:hover { background: var(--hover); }
  #fade-hold-val { min-width: 26px; text-align: center; font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text); }
  #print-area { display: none; }
  @media print {
    body > *:not(#print-area) { display: none !important; }
    #print-area { display: block !important; position: static; background: #fff; }
    /* the app shell pins html/body to 100% with overflow:hidden — that clips the
       printed document to a single page, so release it for print only */
    html, body { margin: 0; padding: 0; background: #fff;
      height: auto !important; min-height: 0 !important; overflow: visible !important; }
    #print-area { height: auto; overflow: visible; }
    /* one board per sheet: the page box fills the sheet, the board is centred
       inside it and scaled down to fit. calc() shaves a rounding hair off the
       height so a full 100vh box can't tip into a spurious blank page. */
    /* Trim on: a standard sheet turned to match the board, with its margins
       removed, so the board area reaches the paper's edge and nothing else is
       printed beside it.

       REPORTED twice — white space below the board on an iPad, and a board that
       never reached the paper at all on a small laptop. Both were the same
       cause: setPrintOrientation used to redefine the PAPER as the board's own
       shape in millimetres. AirPrint substitutes the printer's real paper and
       ignored it; a 1121x342 board asked for a 305mm-wide sheet no printer
       has. The sheet is a real sheet now, and the picture is fitted to it.

       So the image is bounded on BOTH axes and never asked to be 100% wide:
       a wide board binds on width, a tall one on height, and neither can
       overflow into a second sheet.

       Centring it on the sheet is done in the CANVAS, not here \u2014 see the
       padding step in printBoardsNow. Nothing in a print stylesheet knows how
       tall the paper is: the one lever CSS offers is viewport units, and the
       iPad report above is what those are worth under a print reflow. A picture
       already cut to the sheet's shape needs no centring box, so this stays a
       plain full-width image and there is no page box sized from the window. */
    /* REPORTED, twice: "Trim to board area is broken at print, plenty of white
       space." This rule is v238's, restored character for character, because v238
       is what worked.

       What it does: the picture fills the page WIDTH and its height follows. With
       the sheet asked to be the board's own shape (see setPrintOrientation) that
       fills the paper exactly, which is the whole point of Board area.

       What v248 tried instead, and why it is gone: width:auto with a page box of
       height:100%, to centre the board on a sheet a printer had substituted. It
       made the image stop filling the width, which is the reported fault. Fitting
       a substituted sheet nicely is worth less than Board area working, so the
       fill wins and any slack falls below the board as it did in v238. */
    #print-area.exact .print-page { display: flex; align-items: center; justify-content: center;
      width: 100%; overflow: hidden; }
    #print-area.exact .print-page img { width: 100%; height: auto;
      max-width: 100%; max-height: 100%; object-fit: contain;
      display: block; border-radius: 0; box-shadow: none; }

  /* A stacked sheet is a column of whole boards: the sheet was asked for at
     exactly this many boards tall, so each one at full width lands flush with
     the next and the paper is covered. */
  #print-area.exact .print-page.stack { flex-direction: column; align-items: center;
    justify-content: center; height: 100vh; }
  /* An equal share of the sheet each, and the board fitted inside its share. The
     sheet was asked for at exactly this many boards tall, so the share is the
     board's own shape to within the millimetre the page size rounds to \u2014 and
     sharing the height rather than stacking natural heights is what keeps a
     rounded-up millimetre from spilling the last board onto a page of its own. */
  #print-area.exact .print-page.stack img { flex: 1 1 0; min-height: 0;
    width: 100%; height: 100%; max-height: 100%; object-fit: contain; }
    /* The page box used to be calc(100vh - 2px). Viewport units under a print
       reflow are not the paper's height — on iOS in particular they are
       whatever the layout engine had at the time — which is the same family of
       bug as the one above. A page is one sheet by declaration instead, and
       its height comes from the sheet. */
    #print-area .print-page { display: flex; align-items: center; justify-content: center;
      width: 100%; min-height: 0; overflow: hidden;
      break-inside: avoid; page-break-inside: avoid; }
    #print-area .print-page img { max-height: 96vh; }
    #print-area .print-page + .print-page { break-before: page; page-break-before: always; }
    #print-area img { max-width: 100%; max-height: 100%; width: auto; height: auto;
      object-fit: contain; display: block; margin: 0; }
  }
  .react-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
  .magnify-bar { display: none; align-items: center; gap: 10px; }
  .magnify-bar.show { display: flex; }
  .lens-zoomfield { display: inline-flex; align-items: center; gap: 4px; }
  .lens-zoomfield .sb-meta { min-width: 36px; text-align: center; }
  #lens-shape-seg button { min-width: 32px; font-size: 14px; line-height: 1; }
  .decor-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; margin-bottom: 8px; }
  .decor-grid button { appearance: none; border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    border-radius: 9px; padding: 8px 6px; font-size: 12.5px; font-weight: 600; cursor: pointer; display: flex; align-items: center; gap: 6px; }
  .decor-grid button:hover { background: var(--hover); border-color: var(--accent); }
  .decor-grid button .dico { font-size: 15px; }
  .decor-done { width: 100%; margin-top: 4px; appearance: none; border: none; border-radius: 9px; padding: 9px;
    background: var(--accent); color: #fff; font-weight: 700; font-size: 13px; cursor: pointer; }
  .decor-done:hover { filter: brightness(1.05); }
  .react-grid button { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    border-radius: 10px; padding: 9px 6px; font-size: 22px; line-height: 1; cursor: pointer; transition: background-color 0.12s var(--ease), border-color 0.12s var(--ease); }
  .react-grid button:hover { background: var(--hover); border-color: var(--accent); }
  .note-bar { position: fixed; bottom: 18px; left: 50%; transform: translateX(-50%);
    display: none; align-items: center; gap: 9px; padding: 9px 13px; border-radius: var(--radius-lg);
    max-width: calc(100vw - 32px); overflow-x: auto; scrollbar-width: none; z-index: 26; }
  .note-bar.show { display: flex; }
  .note-bar::-webkit-scrollbar { display: none; }
  .nb-colors { display: flex; gap: 6px; }
  /* narration recording bar */
  #rec-bar { position: fixed; top: 70px; left: 50%; transform: translateX(-50%) translateY(-8px);
    display: none; align-items: center; gap: 10px; z-index: 60; padding: 8px 10px 8px 14px;
    background: var(--panel, #1b1b22); border: 1px solid var(--border-strong, #3a3a44); border-radius: 14px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.35); opacity: 0; transition: opacity .18s ease, transform .18s ease; pointer-events: none; }
  #rec-bar.show { display: flex; opacity: 1; transform: translateX(-50%) translateY(0); pointer-events: auto; }
  #rec-bar.paused { border-color: #d9a441; }
  .rec-dot { width: 11px; height: 11px; border-radius: 50%; background: #e5484d; box-shadow: 0 0 0 0 rgba(229,72,77,0.6); animation: recpulse 1.2s infinite; flex: 0 0 auto; }
  #rec-bar.paused .rec-dot { background: #d9a441; animation: none; }
  @keyframes recpulse { 0% { box-shadow: 0 0 0 0 rgba(229,72,77,0.55);} 70% { box-shadow: 0 0 0 7px rgba(229,72,77,0);} 100% { box-shadow: 0 0 0 0 rgba(229,72,77,0);} }
  .rec-time { font: 600 14px/1 var(--font); color: var(--text); min-width: 40px; font-variant-numeric: tabular-nums; }
  .rec-state { font: 600 12px/1 var(--font); color: var(--muted); }
  .rec-act { appearance: none; border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    font: 600 12.5px/1 var(--font); padding: 7px 11px; border-radius: 9px; cursor: pointer; }
  .rec-act:hover { background: var(--hover); }
  .rec-act.primary { background: var(--accent, #6c5ce7); border-color: transparent; color: #fff; }
  .rec-act.ghost { color: var(--muted); border-color: transparent; }
  .rec-act.ghost:hover { color: #ff6b6b; background: transparent; }
  #rec-btn.recording { color: #e5484d; }
  #stylus-btn.on { color: var(--accent, #6c5ce7); background: var(--hover); }
  #timer-sound.off, #timer-music.off { opacity: 0.4; }
  #timer-music.on { color: var(--accent, #6c5ce7); opacity: 1; }
  /* understanding pulse */
  .collab-understanding { display: flex; gap: 8px; margin-top: 10px; }
  .cu-chip { flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px; background: var(--cp-raised); border-radius: 9px; padding: 8px; font: 600 13px/1 var(--font); color: var(--cp-text); }
  .cu-chip b { font-weight: 800; }
  .collab-pulse-row { display: flex; gap: 8px; }
  .cu-btn { flex: 1; appearance: none; border: 2px solid transparent; background: var(--cp-raised); color: var(--cp-text); font: 700 12.5px/1.2 var(--font); padding: 12px 6px; border-radius: 11px; cursor: pointer; }
  .cu-btn.cu-green.sel { border-color: #3fb950; background: rgba(63,185,80,0.16); }
  .cu-btn.cu-amber.sel { border-color: #d9a441; background: rgba(217,164,65,0.16); }
  .cu-btn.cu-red.sel { border-color: #e5484d; background: rgba(229,72,77,0.16); }
  #collab-laser.on { background: var(--accent, #6c5ce7); color: #fff; }
  /* laser pointer dot */
  #laser-dot { position: fixed; left: 0; top: 0; width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%; z-index: 88; display: none; pointer-events: none;
    background: radial-gradient(circle, rgba(255,60,60,0.95) 0%, rgba(255,60,60,0.6) 35%, rgba(255,60,60,0) 70%);
    box-shadow: 0 0 14px 6px rgba(255,40,40,0.55); }
  #laser-dot.show { display: block; }
  /* eyes up flash */
  #eyesup-flash { position: fixed; inset: 0; z-index: 95; display: none; pointer-events: none; background: var(--accent, #6c5ce7);
    align-items: center; justify-content: center; color: #fff; font: 800 34px/1 var(--font, sans-serif); letter-spacing: 0.02em; }
  #eyesup-flash.show { display: flex; animation: eyesup 1.4s ease; }
  @keyframes eyesup { 0% { opacity: 0; } 15% { opacity: 0.92; } 70% { opacity: 0.92; } 100% { opacity: 0; } }
  /* best-participant award: fireworks canvas + banner */
  #award-fx { position: fixed; left: 0; top: 0; width: 100%; height: 100%; z-index: 96; display: none; pointer-events: none; }
  #award-fx.show { display: block; }
  #award-banner { position: fixed; inset: 0; z-index: 97; display: none; align-items: center; justify-content: center; pointer-events: none; }
  #award-banner.show { display: flex; }
  /* Solid panel, no backdrop blur: the text stays crisp and it costs less GPU
     while the fireworks are animating over it. */
  #award-banner .aw-inner { text-align: center; padding: 30px 42px; border-radius: 24px;
    background: #12151d; border: 1px solid rgba(255,255,255,0.22);
    box-shadow: 0 30px 90px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,215,94,0.25) inset;
    animation: awpop 0.5s cubic-bezier(.2,.9,.3,1.35); }
  @keyframes awpop { from { transform: scale(0.72); opacity: 0; } to { transform: none; opacity: 1; } }
  #award-banner .aw-trophy { font-size: 58px; line-height: 1; animation: awbob 1.6s ease-in-out infinite; }
  @keyframes awbob { 50% { transform: translateY(-9px) rotate(-4deg); } }
  #award-banner .aw-title { margin-top: 8px; font: 800 13px/1 var(--font, sans-serif); letter-spacing: 0.18em; text-transform: uppercase; color: #ffd75e; }
  #award-banner .aw-names { margin-top: 10px; font: 800 30px/1.25 var(--font, sans-serif); color: #fff; text-shadow: 0 3px 18px rgba(0,0,0,0.5); }
  /* picker */
  #seq-dlg { position: fixed; inset: 0; z-index: 92; display: none; align-items: center; justify-content: center;
    padding: 20px; background: rgba(8,10,16,0.55); backdrop-filter: blur(3px); }
  #seq-dlg.show { display: flex; }
  #seq-src { width: 100%; box-sizing: border-box; margin-bottom: 8px; padding: 11px 12px; border-radius: 10px;
    border: 1px solid var(--border-strong); background: var(--surface-solid); color: var(--text);
    font: 500 13px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; resize: vertical; }
  .pop-row { display: flex; align-items: center; gap: 9px; padding: 7px 4px; font: 500 13px/1.3 var(--font); color: var(--text); }
  .pop-row select { margin-left: auto; padding: 5px 8px; border-radius: 8px; border: 1px solid var(--border-strong);
    background: var(--surface-solid); color: var(--text); font: 500 12.5px var(--font); }
  .pop-row input[type=checkbox] { flex: none; width: 16px; height: 16px; accent-color: var(--accent); }
  #mmd-dlg { position: fixed; inset: 0; z-index: 93; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(8,10,16,0.6); backdrop-filter: blur(3px); }
  #mmd-dlg.show { display: flex; }
  .mmd-inner { width: 100%; max-width: 940px; max-height: 92vh; overflow-y: auto; overflow-x: hidden;
    display: flex; flex-direction: column; padding: 16px 18px 14px;
    border-radius: 18px; background: var(--surface-solid); border: 1px solid var(--border); box-shadow: var(--shadow); }
  .mmd-body { display: flex; gap: 14px; align-items: stretch; min-height: 0; flex: 1 1 auto; }
  .mmd-left, .mmd-right { max-height: 74vh; overflow-y: auto; overflow-x: hidden; }
  .mmd-left { flex: 1 1 46%; min-width: 0; display: flex; flex-direction: column; }
  .mmd-right { flex: 1 1 54%; min-width: 0; }
  /* The "which panel should I use?" link is guidance, not another thing to
     insert. Sitting in the list it read as an eighth maker, so it moves below a
     hairline and drops to the muted, smaller treatment of a footnote. */
  .pop-foot { margin-top: 6px; padding-top: 7px; border-top: 1px solid var(--border-strong); }
  .pop-help { display: flex; align-items: center; gap: 7px; width: 100%;
    appearance: none; background: transparent; border: 0; cursor: pointer;
    padding: 5px 8px; border-radius: 8px; color: var(--muted);
    font: 500 11.5px/1.3 var(--font); text-align: left; }
  .pop-help:hover { background: var(--hover); color: var(--text); }
  .pop-help svg { width: 14px; height: 14px; flex: none; opacity: 0.85; }
  .pop-help span { text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
  /* Thirteen shapes will not sit on one line on a laptop, let alone a tablet. */
  /* Add image and Sticky note give their choices straight away — a sub-panel
     for two buttons is a click that buys nothing. */
  .pop-inline { display: flex; align-items: center; gap: 6px; padding: 5px 8px; border-radius: 9px; }
  .pop-inline:hover { background: var(--hover); }
  .pop-inline-label { display: flex; align-items: center; gap: 9px; margin-right: auto;
    font: 500 13px/1.3 var(--font); color: var(--text); }
  .pop-inline-label svg { width: 17px; height: 17px; flex: none; opacity: .9; }
  .pop-inline .tex-upload { flex: none; }
  /* Thirteen shapes will not fit on one line on a laptop, and a wrapping strip
     just made the note bar tall. A pull-up keeps the bar one line and gives the
     shapes room to be read. */
  /* Surface, Template, Frame, Texture and Size stacked into one very long
     dropdown. One at a time, chosen from a tab strip, keeps it to a screenful. */
  /* Cancel was the same muted chip as everything else, which on a light board
     read as disabled. Give it a definite edge and a red that holds up on both
     themes — light mode needs the darker one to carry against white. */
  /* Three digits plus the spinner does not fit the shared number width. */
  .mmd-f input[type=number].num-wide { width: 78px; }
  /* Sixteen icons wrapped past the panel; let the row scroll instead. */
  .lab-icons.stk-icons { max-height: 108px; overflow-y: auto; padding-right: 2px; }
  /* Cancel follows the PANEL, not the page: a dark skin chosen in light mode
     needs the light red, or it disappears into the panel it sits on. */
  /* Every Cancel now matches End session: solid, so the way out of a panel looks
     the same everywhere rather than an outline here and a fill there. */
  /* Any Cancel, not only the chip-shaped ones — one of them is a texture button
     and was left looking different from the rest. */
  .is-cancel { background: #e5484d !important; border-color: #e5484d !important;
    color: #fff !important; font-weight: 700; }
  .is-cancel:hover { background: #d13c41 !important; border-color: #d13c41 !important; }
  .is-cancel:focus-visible { outline: 2px solid #e5484d; outline-offset: 2px; }
  html[data-theme="dark"] { --danger: #ff8a80; --danger-edge: rgba(255,138,128,0.5); --danger-soft: rgba(255,138,128,0.14); }
  /* Programmer mode adds a base list, a bit pattern and a third keypad, which
     made the card tall enough to run off the top of the screen and take the
     close button with it. Capping the height and letting the body scroll keeps
     the header — and its close button — reachable in every mode.
     display:flex with the header as flex:none is what pins the header while
     only the content below it scrolls. */
  #calc-card { position: fixed; right: 22px; bottom: 92px; width: 268px; z-index: 121;
    max-height: calc(100vh - 120px);
    display: flex; flex-direction: column;
    border-radius: 18px; border: 1px solid var(--border); background: var(--surface-solid);
    box-shadow: 0 24px 60px -18px rgba(0,0,0,0.45); padding: 10px 12px 12px;
    user-select: none; touch-action: none; }
  #calc-card > .calc-head, #calc-card > .calc-tabs { flex: none; }
  #calc-card > .calc-pane { overflow-y: auto; min-height: 0; }
  #calc-card[hidden] { display: none; }
  .calc-head { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; }
  .calc-grip { cursor: grab; color: var(--text-soft); font-size: 13px; }
  .calc-title { flex: 1; font: 700 13px/1.2 var(--font); color: var(--text); }
  .calc-x { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--text-soft); border-radius: 7px; padding: 3px 7px; cursor: pointer;
    font: 700 10px/1.2 var(--font); }
  .calc-x:hover { background: var(--hover); color: var(--text); }
  .calc-x.on { background: var(--accent); color: #fff; border-color: var(--accent); }

  /* highlight shape picker — five options, each one tap away */
  .hl-shape-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; padding: 2px; }
  .hl-shape-grid button { display: flex; flex-direction: column; align-items: center; gap: 4px;
    padding: 9px 4px; border-radius: 10px; cursor: pointer;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text-soft);
    font: 600 10px/1 var(--font); }
  .hl-shape-grid button svg { width: 22px; height: 22px; }
  .hl-shape-grid button:hover { background: var(--accent-soft); color: var(--text); }
  .hl-shape-grid button.active { background: var(--accent); color: #fff; border-color: var(--accent); }
  /* The card lifts itself clear of the on-screen keyboard; animate that so it
     does not jump. */
  #calc-card { transition: transform .18s var(--ease); }
  .calc-tape { min-height: 15px; max-height: 120px; overflow-y: auto;
    font: 500 11px/1.45 var(--font); color: var(--text-soft);
    background: var(--hover); border: 1px solid var(--border-strong);
    border-radius: 9px; padding: 5px 7px; }
  html[data-theme="dark"] .calc-tape { background: rgba(255,255,255,0.04); }
  .calc-hrow { display: flex; align-items: center; gap: 6px; padding: 2px 0; }
  .calc-hrow span { flex: 1; min-width: 0; overflow-x: auto; white-space: nowrap; text-align: right; }
  .calc-hsend { flex: none; width: 20px; height: 20px; border-radius: 6px; cursor: pointer;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text-soft);
    font: 700 11px/1 var(--font); }
  .calc-hsend:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
  .calc-hist-head { display: flex; align-items: center; gap: 6px; margin: 8px 0 4px;
    font: 700 10px/1 var(--font); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
  .calc-hist-head span { flex: 1; }
  .calc-mini { border-radius: 7px; padding: 4px 8px; cursor: pointer;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text-soft);
    font: 700 9.5px/1 var(--font); letter-spacing: .03em; text-transform: none; }
  .calc-mini:hover { background: var(--accent); color: #fff; border-color: var(--accent); }

  /* mode tabs */
  /* Five tabs at a readable size do not fit across a 268px card, and the last
     one ("Convert") was overflowing past the edge. Wrapping keeps every tab
     inside the panel at whatever width it happens to be. */
  .calc-tabs { display: flex; flex-wrap: wrap; gap: 3px; margin: 6px 0 4px; }
  /* One rule, not two: a separate "flex: 1 1 30%" rule above this one was
     simply overridden by the "flex: 1" here, so the tabs never actually
     wrapped and the last one still spilled past the card. */
  .calc-tabs button { flex: 1 1 30%; min-width: 0; padding: 7px 3px; border-radius: 8px;
    cursor: pointer; border: 1px solid transparent; background: transparent;
    color: var(--text-soft); font: 700 11.5px/1 var(--font); }
  .calc-tabs button:hover { background: var(--hover); }
  .calc-tabs button.active { background: var(--accent); color: #fff; }

  /* programmer: base list + bit pattern */
  .calc-seg-sm { display: flex; gap: 2px; margin-bottom: 5px; }
  .calc-seg-sm button { flex: 1; padding: 4px 2px; border-radius: 6px; cursor: pointer;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text-soft);
    font: 700 9px/1 var(--font); }
  .calc-seg-sm button.active { background: var(--accent); color: #fff; border-color: var(--accent); }
  .calc-baselist { margin-bottom: 4px; }
  .calc-baserow { display: flex; justify-content: space-between; gap: 8px; padding: 1px 2px;
    font: 500 10.5px/1.5 ui-monospace, Menlo, Consolas, monospace; color: var(--text-soft); }
  .calc-baserow.on { color: var(--text); font-weight: 700; }
  .calc-baserow span:last-child { overflow-x: auto; white-space: nowrap; }
  .calc-bits { font: 500 9.5px/1.5 ui-monospace, Menlo, Consolas, monospace;
    color: var(--muted); word-break: break-all; margin-bottom: 5px; }

  /* date + convert forms */
  .calc-f { display: flex; align-items: center; gap: 6px; margin-bottom: 5px;
    font: 600 10.5px/1 var(--font); color: var(--text-soft); }
  .calc-f span { flex: none; width: 58px; }
  .calc-f input, .calc-f select { flex: 1; min-width: 0; box-sizing: border-box; padding: 5px 7px;
    border-radius: 7px; border: 1px solid var(--border-strong); background: var(--hover);
    color: var(--text); font: 600 11.5px/1.2 var(--font); }
  .calc-ymd { display: flex; gap: 4px; }
  .calc-ymd .calc-f { flex: 1; flex-direction: column; align-items: stretch; gap: 2px; }
  .calc-ymd .calc-f span { width: auto; }
  .calc-result { margin-top: 6px; padding: 8px; border-radius: 9px; background: var(--hover);
    font: 500 11px/1.4 var(--font); color: var(--text-soft); text-align: center; }
  .calc-result-main { font: 800 17px/1.25 ui-monospace, Menlo, Consolas, monospace; color: var(--text);
    overflow-x: auto; white-space: nowrap; }
  .calc-result-sub { font: 500 10px/1.4 var(--font); color: var(--muted); margin-top: 2px; }
  #calc-in { width: 100%; box-sizing: border-box; margin-top: 4px; padding: 7px 9px;
    border-radius: 9px; border: 1px solid var(--border-strong); background: var(--hover);
    color: var(--text); font: 600 16px/1.3 ui-monospace, Menlo, Consolas, monospace; text-align: right; }
  .calc-out { text-align: right; padding: 5px 2px 8px; min-height: 26px;
    font: 800 22px/1.2 ui-monospace, Menlo, Consolas, monospace; color: var(--text);
    overflow-x: auto; white-space: nowrap; }
  .calc-out.err { font-size: 12px; font-weight: 600; color: var(--danger, #b3261e); white-space: normal; }
  /* Green, not the accent purple the "=" key uses — pressing "=" works the sum
     out, pressing this puts it on the board, and two same-coloured buttons
     stacked together made that far too easy to confuse. The top margin is what
     stops it touching the keypad above it. */
  #calc-place { display: block; width: 100%; margin: 12px 0 4px; padding: 10px 10px;
    border-radius: 10px; border: 1px solid #1f7a4d; cursor: pointer;
    background: #2e9e63; color: #fff; font: 800 12.5px/1 var(--font);
    box-shadow: 0 2px 8px rgba(46,158,99,0.3); }
  #calc-place:hover { background: #278954; }
  #calc-place:active { background: #1f7a4d; }
  .calc-keys { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; }
  /* A class setting `display` beats the browser's own [hidden] rule, so hiding
     the scientific row from script did nothing — both keypads looked the same. */
  #calc-card [hidden] { display: none !important; }
  #calc-mem { display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; margin-bottom: 5px; }
  #calc-mem button { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--text-soft); border-radius: 8px; padding: 6px 0; cursor: pointer;
    font: 700 10.5px/1 var(--font); }
  #calc-mem button:hover { background: var(--hover); color: var(--text); }
  #calc-mem button.held { border-color: var(--accent); color: var(--accent); }
  #calc-sci-keys { grid-template-columns: repeat(5, 1fr); margin-bottom: 5px; }
  .calc-keys button { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--text); border-radius: 9px; padding: 9px 0; cursor: pointer;
    font: 600 14px/1 var(--font); }
  #calc-sci-keys button { padding: 7px 0; font-size: 11.5px; }
  .calc-keys button:hover { background: var(--hover); }
  .calc-keys button.op { color: var(--accent); }
  .calc-keys button.eq { background: var(--accent); border-color: var(--accent); color: #fff; }
  .calc-keys button.clr { color: var(--danger, #b3261e); }
  .ctxm { position: fixed; z-index: 140; min-width: 196px; max-width: 264px; padding: 5px;
    border-radius: 13px; max-height: 78vh; overflow-y: auto; }
  .ctxm[hidden] { display: none; }
  .ctxm button { display: flex; width: 100%; align-items: center; gap: 9px; appearance: none;
    border: 0; background: transparent; color: var(--text); text-align: left; cursor: pointer;
    padding: 7px 9px; border-radius: 8px; font: 500 13px/1.25 var(--font); }
  .ctxm button:hover { background: var(--hover); }
  .ctxm button[disabled] { opacity: .4; cursor: default; }
  .ctxm button:hover[disabled] { background: transparent; }
  .ctxm button svg { width: 15px; height: 15px; flex: none; opacity: .85; }
  .ctxm button .k { margin-left: auto; font: 600 10.5px/1 var(--font); color: var(--text-soft); }
  .ctxm .ctxm-sep { height: 1px; margin: 4px 6px; background: var(--border-strong); }
  .ctxm .ctxm-head { font: 700 9.5px/1 var(--font); letter-spacing: .06em; text-transform: uppercase;
    color: var(--text-soft); padding: 7px 9px 4px; }
  .ctxm .ctxm-row { display: flex; flex-wrap: wrap; gap: 3px; padding: 1px 6px 5px; }
  .ctxm .ctxm-row button { width: 30px; height: 30px; padding: 0; justify-content: center;
    font-size: 17px; border: 1px solid transparent; }
  .ctxm .ctxm-row button:hover { border-color: var(--border-strong); }
  .ctxm .ctxm-row .sw { width: 24px; height: 24px; border-radius: 7px; border: 1px solid var(--border-strong); }
  .ctxm .ctxm-row .chip { width: auto; padding: 0 9px; height: 24px; border-radius: 999px;
    font: 700 11px/1 var(--font); color: #fff; }
  /* Two rows in one grid rather than two flex rows plus labels — the panel was
     taller than it needed to be on a laptop. */
  .grow-grid { display: grid; grid-template-columns: auto 26px 1fr 26px; gap: 4px 6px;
    align-items: center; margin: 4px 0 2px; }
  .grow-row { display: flex; align-items: center; gap: 8px; margin: 5px 0; }
  .grow-lab { width: auto; font: 700 10px/1 var(--font); letter-spacing: .06em;
    text-transform: uppercase; color: var(--muted); }
  .grow-val { flex: 1; text-align: center; font: 700 12.5px/1 var(--font); color: var(--text);
    font-variant-numeric: tabular-nums; }
  .grow-btn { appearance: none; width: 26px; height: 24px; border-radius: 8px;
    border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    cursor: pointer; font: 700 15px/1 var(--font); }
  .grow-btn:hover { background: var(--hover); }
  .grow-btn[disabled] { opacity: .35; cursor: default; }
  #tools-pop { width: 288px; }
  #tools-pop .seg { width: 100%; margin-bottom: 4px; }
  #curtain-dir[hidden] { display: none !important; }
  #tools-pop .seg button { flex: 1; padding: 6px 4px; font-size: 11.5px; }
  #tools-pop .frm-row > span { width: 42px; }
  #tools-pop input[type=range] { flex: 1; min-width: 0; }
  #theme-pop { width: 268px; }
  /* The name used to sit BELOW each swatch, which put row one's labels on top
     of row two's swatches. It goes inside now, on a scrim so it reads against
     any colour the swatch happens to be. */
  .skin-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; margin-bottom: 4px; }
  .skin-grid button { appearance: none; height: 32px; border-radius: 9px; cursor: pointer;
    border: 2px solid transparent; padding: 0; position: relative; overflow: hidden; }
  .skin-grid button.active { border-color: var(--text); }
  .skin-grid button span { position: absolute; left: 0; right: 0; bottom: 0; padding: 3px 2px 4px;
    font: 700 8.5px/1 var(--font); color: #fff; text-align: center;
    background: rgba(0,0,0,0.55); text-shadow: 0 1px 2px rgba(0,0,0,0.6); }
  .skin-badge { margin: 6px 0 0; font: 600 11px/1.4 var(--font); color: var(--danger, #b3261e); }
  .skin-custom .frm-row .tex-upload { flex: 0 0 auto; }
  .skin-custom .seg { flex: 1; }
  .skin-custom { margin-top: 6px; border-top: 1px solid var(--border-strong); padding-top: 8px; }
  .skin-custom > summary { cursor: pointer; font: 600 11.5px/1.3 var(--font); color: var(--muted);
    padding: 3px 0; user-select: none; }
  .skin-custom > summary:hover { color: var(--text); }
  .skin-custom .frm-row > span { width: 62px; }
  .skin-custom input[type=range] { flex: 1; min-width: 0; }
  .fn-group { font: 700 10px/1 var(--font); letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted); padding: 9px 4px 5px; }
  .fn-group:first-child { padding-top: 2px; }
  .font-list { max-height: 340px; overflow-y: auto; }
  .fill-tol { display: flex; align-items: center; gap: 8px; margin: 8px 0 2px;
    font: 700 10px/1 var(--font); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
  .fill-tol input[type=range] { flex: 1; min-width: 0; }
  .fill-tol output { min-width: 26px; text-align: right; font-weight: 600; }
  #fill-tol-hint { margin: 2px 0 6px; }
  .bp-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 10px; }
  .bp-tabs button { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--muted); padding: 5px 11px; border-radius: 999px; cursor: pointer;
    font: 600 11.5px/1 var(--font); }
  .bp-tabs button:hover { background: var(--hover); color: var(--text); }
  .bp-tabs button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
  .bp-sec[hidden] { display: none; }
  .nb-shape-btn { display: inline-flex; align-items: center; gap: 6px; appearance: none;
    border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    padding: 5px 9px; border-radius: 9px; cursor: pointer; font: 600 12px/1 var(--font); }
  .nb-shape-btn:hover { background: var(--hover); }
  .nb-shape-btn svg { width: 13px; height: 13px; opacity: .8; }
  .nb-shape-pop { width: 250px; }
  .nb-shape-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; }
  .nb-shape-grid button { appearance: none; border: 1px solid var(--border-strong);
    background: transparent; color: var(--muted); padding: 8px 6px; border-radius: 9px;
    cursor: pointer; font: 600 11.5px/1.2 var(--font); }
  .nb-shape-grid button:hover { background: var(--hover); color: var(--text); }
  .nb-shape-grid button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
  #ifg-dlg { position: fixed; inset: 0; z-index: 93; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(8,10,16,0.6); backdrop-filter: blur(3px); }
  #ifg-dlg.show { display: flex; }
  .ifg-head { display: flex; align-items: center; gap: 8px; font: 700 10px/1 var(--font);
    letter-spacing: .06em; text-transform: uppercase; color: var(--muted); margin: 10px 0 6px; }
  .ifg-count { font-weight: 600; opacity: .8; }
  .ifg-head .collab-chip { margin-left: auto; }
  .ifg-items { max-height: 190px; overflow-y: auto; border: 1px solid var(--border-strong);
    border-radius: 10px; padding: 6px; }
  .ifg-item { display: grid; grid-template-columns: 18px 1fr 1fr 54px auto auto auto;
    gap: 4px; align-items: center; margin-bottom: 5px; }
  .ifg-item:last-child { margin-bottom: 0; }
  .ifg-item .n { font: 700 10px/1 var(--font); color: var(--muted); text-align: center; }
  .ifg-item input, .ifg-item select { min-width: 0; padding: 5px 7px; border-radius: 7px;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text);
    font: 500 12px/1.3 var(--font); }
  .ifg-item button { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--muted); width: 22px; height: 24px; border-radius: 6px; cursor: pointer;
    font: 700 11px/1 var(--font); padding: 0; }
  .ifg-item button:hover { background: var(--hover); color: var(--text); }
  #ifg-search { width: 100%; box-sizing: border-box; margin-bottom: 6px; padding: 6px 10px;
    border-radius: 9px; border: 1px solid var(--border-strong); background: var(--hover);
    color: var(--text); font: 500 12.5px/1.3 var(--font); }
  #ifg-layouts { max-height: 150px; }
  #stk-dlg { position: fixed; inset: 0; z-index: 93; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(8,10,16,0.6); backdrop-filter: blur(3px); }
  #stk-dlg.show { display: flex; }
  .stk-head { font: 700 10px/1 var(--font); letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted); margin: 10px 0 6px; }
  .stk-head:first-child { margin-top: 0; }
  .stk-presets { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 9px; }
  .stk-presets button { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--muted); padding: 5px 10px; border-radius: 999px; cursor: pointer;
    font: 600 11.5px/1 var(--font); }
  .stk-presets button:hover { background: var(--hover); color: var(--text); }
  .stk-designs { display: flex; flex-wrap: wrap; gap: 5px; max-height: 96px; overflow-y: auto; }
  .stk-designs button { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--muted); padding: 5px 9px; border-radius: 8px; cursor: pointer;
    font: 600 11.5px/1 var(--font); }
  .stk-designs button:hover { background: var(--hover); color: var(--text); }
  .stk-designs button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
  .stk-pals { display: flex; flex-wrap: wrap; gap: 6px; }
  .stk-pals button { appearance: none; width: 30px; height: 22px; border-radius: 7px; cursor: pointer;
    border: 2px solid transparent; padding: 0; }
  .stk-pals button.active { border-color: var(--text); }
  .stk-icons { max-height: 76px; overflow-y: auto; }
  #stk-preview img { max-height: 300px; }
  #stk-preview { position: relative; }
  /* The animation preview runs the board's own drawing code on a canvas laid
     exactly over the still preview, which is hidden while it plays. */
  #stk-preview canvas.stk-anim-cv { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
  .stk-anim-hint { font-style: normal; font-size: 12px; color: var(--muted, #889); }
  #cal-dlg, #lab-dlg, #rub-dlg { position: fixed; inset: 0; z-index: 93; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(8,10,16,0.6); backdrop-filter: blur(3px); }
  #cal-dlg.show, #lab-dlg.show, #rub-dlg.show { display: flex; }
  .mmd-inner.mmd-narrow { max-width: 880px; }
  #lab-text { flex: 1; min-width: 140px; padding: 6px 9px; border-radius: 8px;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text);
    font: 600 13px/1.3 var(--font); }
  .lab-icons { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 10px; }
  .lab-icons button { appearance: none; width: 32px; height: 32px; padding: 5px;
    border: 1px solid var(--border-strong); background: transparent; border-radius: 8px;
    color: var(--muted); cursor: pointer; }
  .lab-icons button svg { width: 100%; height: 100%; display: block; }
  .lab-icons button:hover { background: var(--hover); color: var(--text); }
  .lab-icons button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
  .lab-presets-wrap { margin-top: 10px; border-top: 1px solid var(--border-strong); padding-top: 9px; }
  .lab-presets-head { display: flex; align-items: center; justify-content: space-between; gap: 8px;
    font: 700 10px/1 var(--font); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
  .lab-presets { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; min-height: 24px; }
  .lab-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 4px 3px 8px;
    border-radius: 999px; font: 700 11.5px/1.4 var(--font); color: #fff; border: 0; cursor: pointer; }
  .lab-chip .lab-x { display: inline-flex; width: 15px; height: 15px; align-items: center;
    justify-content: center; border-radius: 50%; background: rgba(0,0,0,0.25); font-size: 10px; }
  .lab-empty { color: var(--muted); font: 500 11.5px/1.4 var(--font); }
  #tbl-dlg { position: fixed; inset: 0; z-index: 93; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(8,10,16,0.6); backdrop-filter: blur(3px); }
  #tbl-dlg.show { display: flex; }
  .tbl-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 8px; }
  .tbl-sep { width: 1px; height: 18px; background: var(--border-strong); margin: 0 2px; }
  .tbl-gridwrap { max-height: 210px; overflow: auto; border: 1px solid var(--border-strong);
    border-radius: 10px; background: var(--hover); }
  table.tbl-grid { border-collapse: collapse; width: 100%; }
  table.tbl-grid td { border: 1px solid var(--border-strong); padding: 0; vertical-align: top; }
  table.tbl-grid td > div { min-width: 74px; min-height: 20px; padding: 6px 8px; outline: none;
    font: 500 12.5px/1.4 var(--font); color: var(--text); white-space: pre-wrap; word-break: break-word; }
  table.tbl-grid td > div:focus { background: rgba(108, 92, 231, 0.18); }
  @supports (color: color-mix(in srgb, red 50%, blue)) { table.tbl-grid td > div:focus { background: color-mix(in srgb, var(--accent) 18%, transparent); } }
  table.tbl-grid tr.is-head td > div { font-weight: 700; }
  /* The alignment control lives on the column it affects, so there is no
     separate "which column?" step. */
  table.tbl-grid th { padding: 3px 4px; border: 1px solid var(--border-strong);
    background: var(--hover); position: sticky; top: 0; z-index: 1; }
  .tbl-align { display: flex; gap: 2px; justify-content: center; }
  .tbl-align button { appearance: none; border: 1px solid transparent; background: transparent;
    color: var(--muted); width: 22px; height: 20px; border-radius: 5px; cursor: pointer; padding: 0;
    font: 700 11px/1 var(--font); }
  .tbl-align button:hover { background: var(--hover); color: var(--text); }
  .tbl-align button.active { background: var(--accent); color: #fff; }
  #ins-search { width: 100%; box-sizing: border-box; margin: 0 0 7px; padding: 7px 10px;
    border-radius: 9px; border: 1px solid var(--border-strong); background: var(--hover);
    color: var(--text); font: 500 12.5px/1.3 var(--font); }
  #ins-search::placeholder { color: var(--muted); }
  .ins-tabs { flex-wrap: wrap; }
  .ins-tabs.muted { opacity: 0.45; }
  /* The grid is eight fixed columns, so a paragraph dropped in as a grid item
     stretched column one to fit its text and blew the whole panel out. Make it
     span the full width instead. */
  .ins-empty { grid-column: 1 / -1; color: var(--muted); font: 500 12px/1.4 var(--font);
    padding: 10px 4px; margin: 0; }
  .ts-sep { width: 1px; align-self: stretch; margin: 3px 3px; background: var(--border-strong); }
  .textstyle .ts-btn svg { width: 15px; height: 15px; display: block; }
  /* A four-digit year needs room; the shared number-field width clipped it. */
  #cal-year { width: 74px; }
  /* One line per thing being adjusted, so "Delete" is never ambiguous about
     what it deletes and the checkboxes stop dangling off the end of a wrap. */
  .tbl-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 6px; }
  .tbl-line:last-child { margin-bottom: 0; }
  .tbl-line .tbl-grp { width: 58px; flex: none; }
  .tbl-line .spacer { flex: 1 1 auto; }
  /* Undo and Redo are a pair; letting a wrap split them looked like two
     unrelated controls on two lines. */
  .tbl-pair { display: inline-flex; flex-wrap: nowrap; gap: 6px; }
  .tbl-grp { font: 700 10px/1 var(--font); letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted); margin-right: 1px; }
  .tbl-tools .collab-chip:disabled { opacity: 0.38; cursor: default; }
  .tbl-tools .collab-chip:disabled:hover { background: transparent; }
  /* The structural buttons act on the cell you last touched, so that cell has
     to be visibly the one they mean. */
  table.tbl-grid td.is-current { outline: 2px solid var(--accent); outline-offset: -2px; }
  .tbl-hint { color: var(--muted); font: 500 11.5px/1.45 var(--font); margin: 7px 0 2px; }
  /* Each maker dialog carries its own overlay rule; there is no shared
     selector, so a new panel is invisible only once this exists. Without it
     #frm-dlg laid out as an ordinary block in the page flow and sat on top of
     the board. */
  #frm-dlg { position: fixed; inset: 0; z-index: 93; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(8,10,16,0.6); backdrop-filter: blur(3px); }
  #frm-dlg.show { display: flex; }
  /* Frame picker. Fifty-odd frames is too many for the flat pill row the chart
     panel uses, so they are grouped under their category and the list scrolls,
     with a search box above for people who already know what they want. */
  /* A frame has no code to write — just a title and some headings — so it gets
     fields, not an editor. The source is still the storage format and still
     reachable, but folded away where it belongs. */
  .frm-fields { margin-bottom: 9px; }
  .frm-row { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; }
  /* A read-out at the end of a slider row — fixed width so the row does not
     shuffle as the number changes. */
  .frm-val { flex: none; min-width: 30px; text-align: right; font: 600 11.5px/1 var(--font);
    color: var(--muted); font-variant-numeric: tabular-nums; }
  /* Curtain, spotlight and laser are one idea now, so they are rows inside
     Pointer options rather than three headings of their own. */
  /* A line of state under a menu item — how long the take is, how much of the
     deck it has covered. Quiet, and it never moves the items around it. */
  .pop-note { margin: 2px 12px 6px; min-height: 15px; font: 500 11.5px/1.3 var(--font);
    color: var(--muted); }
  .pop-sub { margin: 9px 10px 3px; font: 700 10px/1 var(--font); letter-spacing: .06em;
    text-transform: uppercase; color: var(--muted); }
  .frm-row > span { flex: none; width: 54px; font: 700 10px/1 var(--font); letter-spacing: .06em;
    text-transform: uppercase; color: var(--muted); }
  .frm-row input { flex: 1; min-width: 0; padding: 6px 9px; border-radius: 8px;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text);
    font: 500 13px/1.3 var(--font); }
  .frm-areas-head { font: 700 10px/1 var(--font); letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted); margin: 10px 0 6px; }
  .frm-areas { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; }
  .frm-areas input { padding: 6px 9px; border-radius: 8px; border: 1px solid var(--border-strong);
    background: var(--hover); color: var(--text); font: 500 12.5px/1.3 var(--font); min-width: 0; }
  .frm-counts { display: flex; flex-wrap: wrap; gap: 10px; }
  .frm-counts label { display: flex; align-items: center; gap: 6px;
    font: 700 10px/1 var(--font); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
  .frm-counts input { width: 58px; padding: 5px 7px; border-radius: 7px;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text);
    font: 500 12.5px/1.3 var(--font); }
  .frm-src-wrap { margin-bottom: 9px; }
  .frm-src-wrap > summary { cursor: pointer; font: 600 11px/1.3 var(--font); color: var(--muted);
    padding: 3px 0; user-select: none; }
  .frm-src-wrap > summary:hover { color: var(--text); }
  .mmd-editor-small { margin-top: 6px; }
  /* Ninety-nine frames in one scrolling list is a haystack. Collapse the
     categories, show a count, and open only what you are looking at. */
  .frm-cat { display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none;
    padding: 3px 2px; border-radius: 6px; }
  .frm-cat:hover { background: var(--hover); color: var(--text); }
  .frm-cat .caret { transition: transform 0.15s var(--ease); font-size: 9px; }
  .frm-cat.open .caret { transform: rotate(90deg); }
  .frm-cat .count { margin-left: auto; opacity: 0.65; font-weight: 600; }
  .frm-types { max-height: 236px; }
  .frm-pickwrap { margin-bottom: 9px; }
  #frm-search { width: 100%; box-sizing: border-box; margin-bottom: 7px; padding: 7px 10px;
    border-radius: 9px; border: 1px solid var(--border-strong); background: var(--hover);
    color: var(--text); font: 500 12.5px/1.3 var(--font); }
  #frm-search::placeholder { color: var(--muted); }
  .frm-types { max-height: 172px; overflow-y: auto; padding-right: 4px;
    border: 1px solid var(--border-strong); border-radius: 10px; padding: 8px 8px 4px; }
  .frm-cat { font: 700 10px/1 var(--font); letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted); margin: 8px 0 5px; }
  .frm-cat:first-child { margin-top: 0; }
  .frm-pills { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 3px; }
  .frm-pills button { appearance: none; border: 1px solid var(--border-strong); background: transparent;
    color: var(--muted); padding: 5px 10px; border-radius: 999px; cursor: pointer;
    font: 600 11.5px/1 var(--font); }
  .frm-pills button:hover { background: var(--hover); color: var(--text); }
  .frm-pills button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
  .frm-empty { color: var(--muted); font: 500 12px/1.4 var(--font); padding: 6px 2px; }
  #frm-cell-alpha { width: 84px; }
  .mmd-types { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 9px; }
  .mmd-types button { appearance: none; border: 1px solid var(--border-strong); background: transparent; color: var(--muted);
    padding: 5px 10px; border-radius: 999px; cursor: pointer; font: 600 11.5px/1 var(--font); }
  .mmd-types button:hover { background: var(--hover); color: var(--text); }
  .mmd-types button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
  #mmd-src { flex: 1 1 auto; min-height: 190px; padding: 11px 12px; border-radius: 10px;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text);
    font: 500 12.5px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace; resize: vertical; }
  /* The preview shows light-inked artwork, so it needs a dark backdrop of its
     own — against the panel it was barely readable. A checker underneath makes
     transparent areas obvious rather than looking like a blank render. */
  .mmd-preview { height: 100%; min-height: 300px; border-radius: 12px; border: 1px solid var(--border-strong);
    display: flex; align-items: center; justify-content: center; overflow: auto; padding: 10px;
    background-color: #1b1f29;
    background-image: linear-gradient(45deg, rgba(255,255,255,0.045) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.045) 75%),
                      linear-gradient(45deg, rgba(255,255,255,0.045) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.045) 75%);
    background-size: 18px 18px; background-position: 0 0, 9px 9px; }
  .mmd-preview.pv-light { background-color: #f4f2ea; }
  .pv-bg { display: flex; align-items: center; gap: 5px; }
  .pv-bg button { width: 22px; height: 22px; border-radius: 6px; border: 2px solid transparent; cursor: pointer; padding: 0; }
  .pv-bg button.active { border-color: var(--accent); }
  .mmd-preview img { max-width: 100%; max-height: 62vh; display: block; }
  .mmd-hint { color: var(--muted); font: 500 12.5px var(--font); }
  .mmd-swatches { display: flex; gap: 5px; }
  .mmd-swatches button { width: 20px; height: 20px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; padding: 0; }
  .mmd-swatches button.active { border-color: var(--accent); }
  @media (max-width: 780px) {
    .mmd-body { flex-direction: column; }
    .mmd-preview { min-height: 180px; }
  }
  .air-btn.on { background: var(--accent); border-color: var(--accent); color: #fff; }
  .air-btn.on svg { color: #fff; }
  #air-pop { min-width: 260px; }
  /* The highlighted copy sits behind a transparent textarea. Every metric that
     affects glyph position must match exactly or the two drift apart. */
  .mmd-editor { position: relative; flex: 1 1 auto; min-height: 210px; border-radius: 10px;
    border: 1px solid var(--border-strong); background: var(--hover); overflow: hidden; }
  .mmd-editor > .mmd-hl, .mmd-editor > textarea {
    margin: 0; padding: 11px 12px; border: 0; width: 100%; height: 100%; box-sizing: border-box;
    font: 500 12.5px/1.55 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    letter-spacing: 0; word-spacing: 0; tab-size: 2; text-indent: 0; text-transform: none;
    white-space: pre-wrap; overflow-wrap: break-word; word-break: normal; font-kerning: none;
    font-variant-ligatures: none; font-feature-settings: normal;
  }
  .mmd-hl { position: absolute; inset: 0; overflow: auto; pointer-events: none; color: var(--text); }
  .mmd-editor > textarea { position: relative; background: transparent; color: transparent;
    /* WebKit paints textarea text with -webkit-text-fill-color, which ignores
       `color: transparent` — the visible text was the textarea's own copy
       sitting a hair off the highlighted one underneath, which reads as fuzzy
       or doubled. Both properties must be cleared. */
    -webkit-text-fill-color: transparent;
    caret-color: var(--text); resize: none; outline: none;
    /* the two layers must rasterise identically or the glyphs will not align */
    -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
  .mmd-hl { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
  .mmd-editor > textarea::selection { background: rgba(108,92,231,0.35); }
  .mmd-hl .t-kw  { color: #c792ea; font-weight: 700; }
  .mmd-hl .t-str { color: #a3e635; }
  .mmd-hl .t-arw { color: #4cc9f0; font-weight: 700; }
  .mmd-hl .t-num { color: #f7b955; }
  .mmd-hl .t-com { color: var(--muted); font-style: italic; }
  html[data-theme="light"] .mmd-hl .t-kw  { color: #7c3aed; }
  html[data-theme="light"] .mmd-hl .t-str { color: #15803d; }
  html[data-theme="light"] .mmd-hl .t-arw { color: #0369a1; }
  html[data-theme="light"] .mmd-hl .t-num { color: #b45309; }
  .mmd-theme { display: flex; flex-wrap: wrap; align-items: center; gap: 7px 10px; margin: 9px 0 4px; }
  .mmd-f { display: flex; align-items: center; gap: 5px; font: 600 11.5px/1 var(--font); color: var(--muted); }
  .mmd-f input[type=color] { width: 26px; height: 22px; padding: 0; border: 1px solid var(--border-strong);
    border-radius: 6px; background: transparent; cursor: pointer; }
  .mmd-f input[type=number] { width: 48px; padding: 4px 6px; border-radius: 7px; border: 1px solid var(--border-strong);
    background: var(--surface-solid); color: var(--text); font: 600 12px var(--font); }
  .mmd-f select { padding: 4px 7px; border-radius: 7px; border: 1px solid var(--border-strong);
    background: var(--surface-solid); color: var(--text); font: 600 12px var(--font); }
  .mmd-f input[type=checkbox] { width: 15px; height: 15px; accent-color: var(--accent); }
  #hdr-dlg { position: fixed; inset: 0; z-index: 93; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(8,10,16,0.58); backdrop-filter: blur(3px); }
  #hdr-dlg.show { display: flex; }
  .hdr-row { display: flex; align-items: center; gap: 8px; margin-bottom: 7px;
    font: 600 12.5px/1 var(--font); color: var(--text); }
  .hdr-row > span:first-of-type { min-width: 52px; color: var(--muted); }
  .hdr-row input[type=checkbox] { width: 15px; height: 15px; accent-color: var(--accent); flex: none; }
  .hdr-row select, .hdr-in, .hdr-num { padding: 6px 8px; border-radius: 8px; border: 1px solid var(--border-strong);
    background: var(--surface-solid); color: var(--text); font: 500 12.5px var(--font); }
  .hdr-in { width: 100%; box-sizing: border-box; margin: 0 0 8px 0; }
  .hdr-inline { flex: 1 1 auto; margin: 0; }
  .hdr-num { width: 62px; }
  .hdr-sub { color: var(--muted); font-weight: 500; }
  /* the composed line, shown the way it will look on the board */
  #hdr-preview { margin: 12px 0 14px; padding: 14px 16px 16px; border-radius: 12px;
    background: rgba(0,0,0,0.22); border: 1px solid var(--border-strong);
    color: var(--text); font: 650 15px/1.5 var(--font); text-align: center;
    letter-spacing: 0.01em; min-height: 22px; }
  #hdr-preview::after { content: ""; display: block; width: 58%; height: 2px; margin: 9px auto 0;
    border-radius: 2px; background: linear-gradient(90deg, transparent, var(--hdr-rule, var(--accent)), transparent); }
  #hdr-preview.empty { color: var(--muted); font-weight: 500; font-style: italic; }
  #hdr-preview.empty::after { display: none; }
  #cht-dlg { position: fixed; inset: 0; z-index: 93; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(8,10,16,0.6); backdrop-filter: blur(3px); }
  #cht-dlg.show { display: flex; }
  .cht-pal { display: flex; gap: 5px; }
  .cht-pal button { width: 22px; height: 22px; border-radius: 6px; border: 2px solid transparent; cursor: pointer; padding: 0; }
  .cht-pal button.active { border-color: var(--text); }
  #eqn-dlg { position: fixed; inset: 0; z-index: 93; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(8,10,16,0.6); backdrop-filter: blur(3px); }
  #eqn-dlg.show { display: flex; }
  #eqn-src { width: 100%; box-sizing: border-box; min-height: 92px; padding: 11px 12px; border-radius: 10px;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text);
    font: 500 13px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; resize: vertical; }
  #eqn-preview img { max-width: 100%; max-height: 40vh; }
  #seq-dlg { position: fixed; inset: 0; z-index: 93; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(8,10,16,0.6); backdrop-filter: blur(3px); }
  #seq-dlg.show { display: flex; }
  .help-link { appearance: none; width: 20px; height: 20px; margin-left: 8px; border-radius: 50%;
    border: 1px solid var(--border-strong); background: transparent; color: var(--muted);
    font: 700 12px/1 var(--font); cursor: pointer; vertical-align: middle; }
  .help-link:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
  /* Its own box: the highlighted editors deliberately render their text
     transparent behind an overlay, and reusing that class here made the JSON
     invisible. This one is a plain, visible textarea. */
  .json-editor { margin: 8px 0 0; border-radius: 10px; border: 1px solid var(--border-strong);
    background: var(--hover); overflow: hidden; }
  .json-editor textarea { display: block; width: 100%; box-sizing: border-box;
    max-height: 34vh; min-height: 150px; padding: 11px 12px; margin: 0;
    border: 0; outline: none; resize: vertical; background: transparent; color: var(--text);
    font: 500 12px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
  .is-disabled { opacity: 0.4; pointer-events: none; filter: grayscale(0.4); }
  #print-range { position: fixed; inset: 0; z-index: 92; display: none; align-items: center; justify-content: center;
    padding: 20px; background: rgba(8,10,16,0.55); backdrop-filter: blur(3px); }
  #print-range.show { display: flex; }
  .pr-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
  .pr-row label { flex: none; width: 44px; font: 600 13px/1 var(--font); color: var(--muted); }
  .pr-row select { flex: 1 1 auto; min-width: 0; padding: 10px 11px; border-radius: 10px;
    border: 1px solid var(--border-strong); background: var(--hover, rgba(255,255,255,0.06));
    color: var(--text); font: 600 14px/1.2 var(--font); }
  .pr-note { margin: 2px 0 14px; font: 500 12px/1.45 var(--font); color: var(--muted); min-height: 17px; }
  /* While the view is held, the presenter gets a quiet reminder that the class
     is not seeing what they are. */
  #collab-freeze.on { border-color: var(--accent); color: var(--accent); }
  #collab-shape-hint.warn { color: var(--accent-warn, #c77700); }
  body.collab-frozen #board { outline: 2px dashed var(--accent); outline-offset: -4px; }
  /* A long deck made this panel taller than the window on a laptop. */
  #boards-list { max-height: 46vh; overflow-y: auto; }
  #boards-pop { max-height: 84vh; overflow-y: auto; }
  #board-pop { max-height: 84vh; overflow-y: auto; }
  /* board rename, inside #boards-pop */
  .bd-name-input { flex: 1 1 auto; min-width: 0; margin: 5px 0 5px 9px; padding: 7px 9px; border-radius: 8px;
    border: 1px solid var(--accent); background: var(--surface-solid); color: var(--text);
    font: 550 13.5px/1.2 var(--font); }
  .bd-label { color: var(--muted); font-weight: 500; }
  .bd-row.active .bd-label { color: inherit; }
  #award-pick { position: fixed; inset: 0; z-index: 92; display: none; align-items: center; justify-content: center; padding: 20px; background: rgba(8,10,16,0.55); backdrop-filter: blur(3px); }
  #award-pick.show { display: flex; }
  /* A dialog taller than the window used to overflow it equally top and bottom,
     because the wrapper centres it: on a 551px-high laptop the Lesson header
     stood 694px tall, putting 72px behind the top bar, 72px behind the style
     bar, and its Add button 13px off the bottom of the screen \u2014 unreachable.
     Cap it to the window and let the inside scroll, the same way the timer card
     and the agenda already do. */
  .awp-inner { width: 100%; max-width: 380px; background: var(--surface-solid, #1b1f29); color: var(--text, #eef1f6);
    border: 1px solid var(--border-strong, rgba(255,255,255,0.14)); border-radius: 18px; padding: 20px; box-shadow: 0 26px 70px rgba(0,0,0,0.5);
    max-height: calc(100vh - 36px); overflow-y: auto; overscroll-behavior: contain; }
  @supports (max-height: 100dvh) { .awp-inner { max-height: calc(100dvh - 36px); } }
  /* On a short window, give the content room rather than spending it on padding
     so there is less to scroll through in the first place. */
  @media (max-height: 640px) {
    #hdr-dlg { padding: 8px; }
    #hdr-dlg .awp-inner { padding: 13px 14px; max-height: calc(100vh - 16px); }
    #hdr-dlg .awp-title { margin-bottom: 8px; }
    #hdr-dlg .hdr-row { margin-bottom: 5px; }
    #hdr-dlg #hdr-preview { margin: 7px 0 8px; padding: 9px 11px 10px; }
  }
  @supports (max-height: 100dvh) {
    @media (max-height: 640px) { #hdr-dlg .awp-inner { max-height: calc(100dvh - 16px); } }
  }
  .awp-title { font: 800 15px/1 var(--font); margin-bottom: 14px; }
  .awp-list { list-style: none; margin: 0 0 16px; padding: 0; display: flex; flex-direction: column; gap: 7px; max-height: 46vh; overflow-y: auto; }
  .awp-list li { display: flex; align-items: center; gap: 10px; background: var(--hover, rgba(255,255,255,0.06)); border: 2px solid transparent; border-radius: 11px; padding: 12px 13px; font: 600 14px/1 var(--font); cursor: pointer; }
  .awp-list li.sel { border-color: #ffd75e; background: rgba(255,215,94,0.14); }
  .awp-list li .awp-tick { margin-left: auto; opacity: 0; }
  .awp-list li.sel .awp-tick { opacity: 1; }
  .awp-row { display: flex; gap: 8px; align-items: center; }
  .collab-mini.mute { background: var(--cp-raised-2); color: var(--cp-text); }
  .collab-mini.mute.on { background: #e5484d; color: #fff; }
  /* collaboration panel — self-contained palette so contrast holds in both themes */
  #collab-panel { --cp-bg: #ffffff; --cp-raised: #eef1f6; --cp-raised-2: #e4e8f0; --cp-line: rgba(20,28,46,0.16); --cp-text: #1d2230; --cp-muted: #5b6472;
    /* Sized to what is in it, not the full height of the window. A first visit
       shows only the start options, and a full-height drawer made that a short
       list floating in a tall empty panel. It now grows as sessions, people and
       polls appear, up to the screen height, and scrolls inside after that. */
    position: fixed; top: 16px; right: 16px; width: 340px; max-width: calc(92vw - 16px);
    height: auto; max-height: calc(100vh - 32px);
    background: var(--cp-bg); border: 1px solid var(--cp-line); border-radius: 18px; z-index: 70; color: var(--cp-text);
    display: flex; flex-direction: column; transform: translateX(calc(100% + 24px)); transition: transform 0.24s var(--ease);
    box-shadow: -18px 0 44px rgba(0,0,0,0.28); overflow: hidden; }
  html[data-theme="dark"] #collab-panel { --cp-bg: #1c2029; --cp-raised: #2a2f3b; --cp-raised-2: #343a48; --cp-line: rgba(255,255,255,0.16); --cp-text: #eef1f6; --cp-muted: #9aa3b4; }
  /* Sliding off with a transform leaves the panel focusable off-screen, so a
     keyboard user tabs into controls nobody can see. visibility removes it from
     the tab order and still animates. */
  /* Off-screen until tabbed to, which is the first thing a keyboard user hits. */
  .skip-link { position: fixed; left: 8px; top: -60px; z-index: 300; padding: 9px 14px;
    border-radius: 9px; background: var(--accent); color: #fff; text-decoration: none;
    font: 600 13px/1 var(--font); transition: top .16s var(--ease); }
  .skip-link:focus { top: 8px; outline: 2px solid #fff; outline-offset: 2px; }
  /* The panel had grown past a laptop screen: scroll its body rather than the
     page, and tighten the ghost buttons and hints. */
  #collab-panel .collab-body { overflow-y: auto; min-height: 0; flex: 0 1 auto; }
  /* Groups are put in order with flexbox rather than moved in the markup, and
     the ones you rarely reach for start folded — the panel had grown taller
     than a laptop screen. */
  #collab-panel section.cp-ordered { display: flex; flex-direction: column; }
  #collab-panel .cg-toggle { cursor: pointer; user-select: none; display: flex;
    align-items: center; gap: 6px; }
  /* Was a caret character, which some tablet fonts do not carry — it drew as an
     empty rectangle. A triangle made from borders always renders. */
  #collab-panel .cg-toggle::before { content: ""; flex: none; width: 0; height: 0;
    border-left: 4.5px solid transparent; border-right: 4.5px solid transparent;
    border-top: 5px solid currentColor; opacity: .55;
    transition: transform .16s var(--ease); }
  #collab-panel .collab-group.folded .cg-toggle::before { transform: rotate(-90deg); }
  /* The action buttons were full width and loosely stacked, pushing everything
     else off a laptop screen. Tighter, and two across where they pair. */
  #collab-panel .collab-btn-ghost { width: 100%; margin: 0; padding: 8px 10px;
    font: 600 12.5px/1.15 var(--font); border-radius: 9px; }
  #collab-panel .cp-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin: 8px 0 0; }
  #collab-panel .cp-actions .wide { grid-column: 1 / -1; }
  #collab-panel .collab-btn-danger { margin-top: 10px; padding: 9px; font-size: 12.5px; }
  #collab-panel .cg-toggle:hover { color: var(--cp-text); }
  #collab-panel .cg-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 5px; }
  /* Fold everything in the group except its title. */
  #collab-panel .collab-group.folded > *:not(.cg-toggle) { display: none !important; }
  #collab-panel .collab-group { margin-bottom: 8px; }
  /* Two across, so a list of actions is half the height it was. */
  #collab-panel .collab-group .collab-btn-ghost { padding: 7px 9px; font-size: 12px; }

  #collab-panel .ins-hint { margin: 5px 0; font-size: 11.5px; line-height: 1.45; }
  .collab-btn-ghost { padding: 7px 10px; font-size: 12.5px; }
  #collab-panel h4 { margin: 10px 0 5px; }
  #collab-panel { visibility: hidden; transition: transform 0.24s var(--ease), visibility 0s linear 0.24s; }
  #collab-panel.show { transform: translateX(0); visibility: visible; transition: transform 0.24s var(--ease), visibility 0s; }
  .collab-head { display: flex; align-items: center; justify-content: space-between; padding: 16px 18px 12px; border-bottom: 1px solid var(--cp-line); }
  .collab-title { font: 700 16px/1 var(--font); color: var(--cp-text); }
  .collab-x { appearance: none; background: transparent; border: 0; color: var(--cp-muted); font-size: 16px; cursor: pointer; padding: 4px 8px; border-radius: 8px; }
  .collab-x:hover { background: var(--cp-raised); color: var(--cp-text); }
  .collab-scroll { flex: 1; overflow-y: auto; padding: 16px 18px; }
  .collab-tabs { display: flex; gap: 4px; background: var(--cp-raised); border-radius: 10px; padding: 4px; margin-bottom: 16px; }
  .collab-tab { flex: 1; appearance: none; border: 0; background: transparent; color: var(--cp-muted); font: 600 13px/1 var(--font); padding: 9px; border-radius: 8px; cursor: pointer; }
  .collab-tab.active { background: var(--accent, #6c5ce7); color: #fff; }
  .collab-hint { font: 400 12.5px/1.5 var(--font); color: var(--cp-muted); margin: 0 0 14px; }
  .collab-hint a { color: var(--accent); }
  #collab-present-form .collab-hint:last-child { margin: 10px 0 0; }
  .collab-label { display: block; font: 700 11px/1 var(--font); color: var(--cp-muted); text-transform: uppercase; letter-spacing: 0.05em; margin: 12px 0 6px; }
  .collab-input { width: 100%; box-sizing: border-box; background: var(--cp-raised); border: 1.5px solid var(--cp-line); color: var(--cp-text);
    font: 500 14px/1 var(--font); padding: 11px 12px; border-radius: 9px; outline: none; }
  .collab-input::placeholder { color: var(--cp-muted); opacity: 0.75; }
  select.collab-input { cursor: pointer; line-height: 1.2; }
  select.collab-input option { background: var(--surface-solid, #fff); color: var(--text, #1d2433); }
  /* Presenter-only marker: this student is on the relay. Dimmed while it connects. */
  .collab-net-tag { font: 700 10px/1 var(--font); letter-spacing: .02em; text-transform: uppercase;
    padding: 3px 6px; border-radius: 5px; margin-left: 4px; flex: 0 0 auto;
    color: var(--cp-muted); border: 1px solid var(--cp-line); }
  .collab-net-tag.wait { opacity: 0.5; }
  .collab-input:focus { border-color: var(--accent, #6c5ce7); background: var(--cp-bg); }
  .collab-btn-primary { width: 100%; margin-top: 16px; appearance: none; border: 0; background: var(--accent, #6c5ce7); color: #fff;
    font: 700 14px/1 var(--font); padding: 12px; border-radius: 10px; cursor: pointer; }
  .collab-btn-primary:hover { filter: brightness(1.08); }
  .collab-btn-primary:disabled { opacity: 0.55; cursor: default; }
  .collab-btn-danger { width: 100%; margin-top: 18px; appearance: none; border: 0; background: #c43439; color: #fff; font: 700 13.5px/1 var(--font); padding: 11px; border-radius: 10px; cursor: pointer; }
  .collab-btn-ghost { width: 100%; margin-top: 18px; appearance: none; border: 1.5px solid var(--cp-line); background: transparent; color: var(--cp-text); font: 600 13.5px/1 var(--font); padding: 11px; border-radius: 10px; cursor: pointer; }
  .collab-btn-ghost:hover { background: var(--cp-raised); }
  .collab-error { color: #ff5d62; font: 600 12.5px/1.4 var(--font); margin: 12px 0 0; }
  .collab-room { display: flex; align-items: center; gap: 8px; background: var(--cp-raised); border: 1px solid var(--cp-line); border-radius: 12px; padding: 12px 14px; }
  .collab-room-label { font: 700 11px/1 var(--font); color: var(--cp-muted); text-transform: uppercase; letter-spacing: 0.04em; }
  .collab-room-code { font: 800 20px/1 var(--font); letter-spacing: 0.16em; color: var(--cp-text); margin-left: auto; }
  .collab-copy { appearance: none; border: 1px solid var(--cp-line); background: var(--cp-bg); color: var(--cp-text); font: 600 11px/1 var(--font); padding: 6px 9px; border-radius: 7px; cursor: pointer; }
  .collab-meta { display: flex; align-items: center; gap: 7px; font: 600 12.5px/1 var(--font); color: var(--cp-muted); margin: 14px 2px; }
  .collab-dot { width: 9px; height: 9px; border-radius: 50%; background: #d9a441; flex: 0 0 auto; }
  .collab-dot.ok { background: #3fb950; }
  .collab-group { margin-top: 14px; }
  .collab-group-title { font: 700 11px/1 var(--font); color: var(--cp-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 8px; }
  .collab-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
  .collab-list li { display: flex; align-items: center; gap: 8px; background: var(--cp-raised); border-radius: 9px; padding: 9px 11px; font: 500 13px/1.2 var(--font); color: var(--cp-text); }
  .collab-list .collab-empty { color: var(--cp-muted); font-weight: 400; background: transparent; padding: 4px 2px; }
  .collab-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .collab-mini { appearance: none; border: 0; font: 700 11.5px/1 var(--font); padding: 7px 11px; border-radius: 7px; cursor: pointer; }
  .collab-mini.admit { background: var(--accent, #6c5ce7); color: #fff; }
  .collab-mini.deny { background: var(--cp-raised-2); color: var(--cp-text); }
  .collab-foot { font: 400 11px/1.4 var(--font); color: var(--cp-muted); padding: 10px 18px 14px; margin: 0; border-top: 1px solid var(--cp-line); }
  .collab-foot a { color: var(--accent); }
  /* ── polished panel: consistent rhythm + glossy controls ── */
  #collab-panel .collab-group { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--cp-line); }
  #collab-panel .collab-group:first-of-type { border-top: 0; padding-top: 0; }
  #collab-panel .collab-group-title { font-size: 11.5px; letter-spacing: 0.07em; margin-bottom: 10px; }
  .collab-btn-primary, .collab-chip, .collab-btn-ghost, .collab-btn-danger, .collab-mini, .cu-btn {
    position: relative; overflow: hidden;
    box-shadow: 0 1px 0 rgba(255,255,255,0.16) inset, 0 -1px 0 rgba(0,0,0,0.13) inset, 0 2px 6px rgba(0,0,0,0.16);
    transition: transform .07s ease, filter .12s ease, box-shadow .12s ease; }
  .collab-btn-primary::after, .collab-chip::after, .collab-btn-danger::after {
    content: ""; position: absolute; inset: 0 0 55% 0; background: linear-gradient(180deg, rgba(255,255,255,0.22), rgba(255,255,255,0)); pointer-events: none; }
  /* REPORTED: Join and Raise hand came out bleached (white on white) on iPad
     in light mode. These gradients mix colours with color-mix(), which iPad
     Safari before iOS 16.2 does not know — and a background holding var() that
     fails is not skipped back to the previous rule, it becomes TRANSPARENT.
     So every mixed colour now sits inside @supports, with a plain colour
     outside it that any browser draws. */
  .collab-btn-primary { background: linear-gradient(180deg, #7e70ea 0%, var(--accent,#6c5ce7) 55%, #5d4fc7 100%); }
  @supports (color: color-mix(in srgb, red 50%, blue)) {
  .collab-btn-primary { background: linear-gradient(180deg, color-mix(in srgb, var(--accent,#6c5ce7) 88%, #fff) 0%, var(--accent,#6c5ce7) 55%, color-mix(in srgb, var(--accent,#6c5ce7) 86%, #000) 100%); }
  }
  /* Darkened from #e5484d: white on that red was 3.9:1, short of the 4.5:1
     text needs. Still unmistakably a stop button. */
  .collab-btn-danger { background: linear-gradient(180deg, #d9454a 0%, #c43439 55%, #a92b30 100%); }
  .collab-chip { background: linear-gradient(180deg, var(--cp-raised) 0%, var(--cp-raised) 60%, var(--cp-raised-2) 100%); border: 1px solid var(--cp-line); }
  @supports (color: color-mix(in srgb, red 50%, blue)) {
  .collab-chip { background: linear-gradient(180deg, color-mix(in srgb, var(--cp-raised) 60%, #fff 12%) 0%, var(--cp-raised) 60%, var(--cp-raised-2) 100%); }
  }
  .collab-btn-primary:active, .collab-chip:active, .collab-btn-ghost:active, .collab-btn-danger:active, .collab-mini:active, .cu-btn:active { transform: translateY(1px); }
  .collab-btn-primary:hover, .collab-chip:hover, .collab-btn-danger:hover { filter: brightness(1.07); }
  .collab-chip.on, #collab-annotate.on, #collab-vmic.on, #collab-mic.on {
    background: linear-gradient(180deg, #7e70ea 0%, var(--accent,#6c5ce7) 60%, #5d4fc7 100%); color: #fff; border-color: transparent; }
  @supports (color: color-mix(in srgb, red 50%, blue)) {
  .collab-chip.on, #collab-annotate.on, #collab-vmic.on, #collab-mic.on {
    background: linear-gradient(180deg, color-mix(in srgb, var(--accent,#6c5ce7) 88%, #fff) 0%, var(--accent,#6c5ce7) 60%, color-mix(in srgb, var(--accent,#6c5ce7) 85%, #000) 100%); }
  }
  .cu-btn { background: linear-gradient(180deg, var(--cp-raised), var(--cp-raised-2)); }
  @supports (color: color-mix(in srgb, red 50%, blue)) {
  .cu-btn { background: linear-gradient(180deg, color-mix(in srgb, var(--cp-raised) 60%, #fff 12%), var(--cp-raised-2)); }
  }
  .collab-mini { box-shadow: 0 1px 0 rgba(255,255,255,0.14) inset, 0 2px 5px rgba(0,0,0,0.16); }
  /* quiz prompt images */
  .qz-images { display: flex; flex-direction: column; gap: 10px; margin: -6px 0 16px; }
  .qz-images img { width: 100%; max-height: 42vh; object-fit: contain; border-radius: 12px; background: rgba(255,255,255,0.05); }
  .qz-img { display: block; max-width: 100%; max-height: 30vh; object-fit: contain; border-radius: 10px; margin: 8px 0; background: rgba(255,255,255,0.05); }
  .qz-math { font-family: "KaTeX_Main", Georgia, serif; }
  .qz-math-block { display: block; margin: 10px 0; text-align: center; }
  .qz-optbody { flex: 1; min-width: 0; }
  .qz-textarea { resize: vertical; min-height: 96px; font: 500 15px/1.5 var(--font); }
  .qz-scale { display: flex; gap: 8px; }
  .qz-scalebtn { flex: 1; appearance: none; border: 2px solid transparent; background: var(--hover, rgba(255,255,255,0.06)); color: var(--text); font: 700 17px/1 var(--font); padding: 16px 0; border-radius: 12px; cursor: pointer; }
  .qz-scalebtn.sel { border-color: var(--accent, #6c5ce7); background: rgba(108, 92, 231, 0.2); }
  @supports (color: color-mix(in srgb, red 50%, blue)) { .qz-scalebtn.sel { background: color-mix(in srgb, var(--accent,#6c5ce7) 20%, transparent); } }
  .qz-blankrow, .qz-matchrow, .qz-orderrow { display: flex; align-items: center; gap: 10px; margin-bottom: 9px; }
  .qz-order { display: flex; flex-direction: column; }
  .qz-orderrow { background: var(--hover, rgba(255,255,255,0.06)); border-radius: 11px; padding: 11px 12px; }
  .qz-move { appearance: none; border: 0; background: rgba(255,255,255,0.12); color: var(--text); width: 30px; height: 30px; border-radius: 8px; cursor: pointer; font-size: 14px; }
  .qz-move:hover { background: rgba(255,255,255,0.2); }
  .qz-select { flex: 0 0 45%; background: var(--hover, rgba(255,255,255,0.06)); color: var(--text); border: 2px solid transparent; border-radius: 10px; padding: 11px; font: 500 14px/1 var(--font); }
  .qz-select:focus { outline: none; border-color: var(--accent, #6c5ce7); }
  .qz-hotspot { position: relative; display: block; }
  .qz-hotspot img { width: 100%; border-radius: 12px; display: block; cursor: crosshair; }
  .qz-hsdot { position: absolute; width: 20px; height: 20px; margin: -10px 0 0 -10px; border-radius: 50%; background: rgba(108,92,231,0.85); border: 2px solid #fff; pointer-events: none; }
  .collab-reacts { display: flex; flex-wrap: wrap; gap: 6px; }
  .collab-reacts button { appearance: none; border: 1px solid var(--cp-line); background: var(--cp-raised); border-radius: 9px; font-size: 20px; line-height: 1; padding: 7px 9px; cursor: pointer; }
  .collab-reacts button:hover { background: var(--cp-raised-2); }
  .collab-timerctl { display: flex; flex-wrap: wrap; gap: 6px; }
  .collab-chip { appearance: none; border: 1px solid var(--cp-line); background: var(--cp-raised); color: var(--cp-text); font: 700 12.5px/1 var(--font); padding: 8px 12px; border-radius: 8px; cursor: pointer; }
  .collab-chip:hover { background: var(--cp-raised-2); }
  .collab-chip.stop { margin-left: auto; color: #e5484d; }
  .collab-hand { margin-left: 4px; color: #f5a623; background: transparent; border: 0; font-size: 15px; cursor: pointer; padding: 2px 4px; border-radius: 6px; }
  .collab-hand:hover { background: var(--cp-raised-2); }
  .collab-photorow { display: flex; align-items: center; gap: 8px; }
  .collab-photocount { font: 700 13px/1 var(--font); color: var(--cp-muted); min-width: 18px; text-align: center; }
  .collab-mini.grant { background: var(--cp-raised-2); color: var(--cp-text); }
  .collab-mini.grant.on { background: #3fb950; color: #fff; }
  /* quiz builder option rows */
  .cq-optrow { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; }
  .cq-optrow input[type=text] { flex: 1; box-sizing: border-box; background: var(--cp-raised); border: 1.5px solid var(--cp-line); color: var(--cp-text); font: 500 13px/1 var(--font); padding: 9px 10px; border-radius: 8px; outline: none; }
  .cq-optrow input[type=text]:focus { border-color: var(--accent); }
  .cq-optrow .cq-correct { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; border: 1.5px solid var(--cp-line); background: var(--cp-raised); color: var(--cp-muted); cursor: pointer; font: 700 13px/1 var(--font); }
  .cq-optrow .cq-correct.on { background: #3fb950; border-color: #3fb950; color: #fff; }
  .cq-optrow .cq-del { flex: 0 0 auto; background: transparent; border: 0; color: var(--cp-muted); cursor: pointer; font-size: 15px; }
  /* participant quiz card — CX-first pop-in, blends with the board */
  /* The overlay scrolls and the card centres via auto margins: when the card is
     taller than the viewport it starts at the top and scrolls instead of
     overflowing off both edges, which was hiding the submit button. */
  #quiz-card { position: fixed; inset: 0; z-index: 90; display: none; align-items: flex-start; justify-content: center; padding: 20px;
    overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
    background: rgba(8,10,16,0.55); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
  #quiz-card.show { display: flex; animation: qzin 0.22s var(--ease, ease); }
  @keyframes qzin { from { opacity: 0; } to { opacity: 1; } }
  .qz-inner { width: 100%; max-width: 460px; margin: auto; background: var(--surface-solid, #1b1f29); color: var(--text, #eef1f6);
    border: 1px solid var(--border-strong, rgba(255,255,255,0.14)); border-radius: 20px; padding: 24px 24px 22px;
    box-shadow: 0 30px 80px rgba(0,0,0,0.5); animation: qzpop 0.26s cubic-bezier(.2,.9,.3,1.2); }
  @keyframes qzpop { from { transform: translateY(14px) scale(0.96); } to { transform: none; } }
  .qz-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
  .qz-badge { font: 700 11px/1 var(--font); text-transform: uppercase; letter-spacing: 0.08em; color: #fff; background: var(--accent, #6c5ce7); padding: 6px 11px; border-radius: 999px; }
  .qz-pts { font: 600 12px/1 var(--font); color: var(--muted, #9aa3b4); }
  .qz-prompt { font: 600 19px/1.35 var(--font); margin-bottom: 18px; }
  .qz-options { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
  .qz-opt { display: flex; align-items: center; gap: 12px; text-align: left; background: var(--hover, rgba(255,255,255,0.06)); border: 2px solid transparent; border-radius: 13px;
    padding: 15px 16px; font: 500 15px/1.3 var(--font); color: var(--text); cursor: pointer; transition: border-color .12s, background .12s, transform .08s; }
  .qz-opt:hover { background: rgba(255,255,255,0.1); }
  .qz-opt:active { transform: scale(0.99); }
  .qz-opt .qz-key { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 9px; background: rgba(255,255,255,0.12); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; }
  .qz-opt.sel { border-color: var(--accent, #6c5ce7); background: rgba(108, 92, 231, 0.18); }
  @supports (color: color-mix(in srgb, red 50%, blue)) { .qz-opt.sel { background: color-mix(in srgb, var(--accent, #6c5ce7) 18%, transparent); } }
  .qz-opt.sel .qz-key { background: var(--accent, #6c5ce7); color: #fff; }
  .qz-opt.correct { border-color: #3fb950; background: rgba(63,185,80,0.16); }
  .qz-opt.correct .qz-key { background: #3fb950; color: #fff; }
  .qz-opt.wrong { border-color: #e5484d; background: rgba(229,72,77,0.14); }
  .qz-opt.wrong .qz-key { background: #e5484d; color: #fff; }
  .qz-opt.locked { pointer-events: none; }
  .qz-input { width: 100%; box-sizing: border-box; background: var(--hover, rgba(255,255,255,0.06)); border: 2px solid transparent; border-radius: 13px; padding: 15px 16px; font: 500 16px/1.3 var(--font); color: var(--text); outline: none; }
  .qz-input:focus { border-color: var(--accent, #6c5ce7); }
  .qz-submit { width: 100%; appearance: none; border: 0; background: var(--accent, #6c5ce7); color: #fff; font: 700 15px/1 var(--font); padding: 15px; border-radius: 13px; cursor: pointer; }
  .qz-submit:hover { filter: brightness(1.08); }
  /* short viewports (phone landscape, iPad with browser chrome): tighten so the
     whole question and the submit button fit without scrolling at all */
  @media (max-height: 720px) {
    .qz-inner { padding: 16px 16px 14px; border-radius: 16px; }
    .qz-prompt { font-size: 17px; margin-bottom: 12px; }
    .qz-options { gap: 8px; margin-bottom: 12px; }
    .qz-opt { padding: 11px 13px; font-size: 14px; }
    .qz-opt .qz-key { width: 26px; height: 26px; font-size: 13px; }
    .qz-submit { padding: 12px; }
    .qz-head { margin-bottom: 10px; }
  }
  .qz-submit:disabled { opacity: 0.5; cursor: default; }
  .qz-submit.done { background: #3fb950; }
  .qz-result { margin-top: 16px; text-align: center; font: 700 17px/1.3 var(--font); }
  .qz-result.ok { color: #4fd06a; } .qz-result.no { color: #ff6b6b; }
  .qz-score { margin-top: 8px; text-align: center; font: 600 13px/1.3 var(--font); color: var(--muted, #9aa3b4); }
  /* make the hidden attribute reliable inside the panel (beats .collab-photorow display:flex) */
  #collab-panel [hidden] { display: none !important; }
  /* floating host quiz control bar — lets the panel collapse while a question is live */
  #cq-hostbar { position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 68; display: none; align-items: center; gap: 10px;
    background: var(--surface-solid, #1b1f29); color: var(--text, #eef1f6); border: 1px solid var(--border-strong, rgba(255,255,255,0.14));
    border-radius: 14px; padding: 10px 12px 10px 16px; box-shadow: 0 16px 40px rgba(0,0,0,0.4); font: 600 13px/1 var(--font); max-width: 94vw; }
  #cq-hostbar.show { display: flex; }
  #cq-hostbar .cq-hb-info { display: flex; flex-direction: column; gap: 3px; }
  #cq-hostbar .cq-hb-tally { font: 500 12px/1 var(--font); color: var(--muted, #9aa3b4); }
  #cq-hostbar button { appearance: none; border: 0; border-radius: 9px; font: 700 12.5px/1 var(--font); padding: 9px 13px; cursor: pointer; }
  #cq-hbreveal { background: var(--accent, #6c5ce7); color: #fff; }
  #cq-hbnext { background: rgba(255,255,255,0.1); color: var(--text, #eef1f6); }
  #cq-hbend { background: transparent; color: #e5484d; }
  body.collab-viewing .rail .tool:not([data-tool="magnify"]) { display: none; }
  body.collab-viewing #undo, body.collab-viewing #redo, body.collab-viewing #insert-btn,
  body.collab-viewing #clear-btn, body.collab-viewing #export-btn, body.collab-viewing #timer-btn,
  body.collab-viewing #react-btn, body.collab-viewing #decor-btn, body.collab-viewing #board-btn,
  body.collab-viewing #rec-btn, body.collab-viewing #stylus-btn, body.collab-viewing #tools-btn,
  body.collab-viewing #stylebar, body.collab-viewing #swatches, body.collab-viewing #note-bar,
  body.collab-viewing #sel-tools, body.collab-viewing #boards-btn { display: none !important; }
  /* The teaching-tools pop (shade, focus, calculator) stays presenter-only —
     the granted rule below re-shows the rail and style bar, deliberately not
     this. Theme stays available to viewers for their own colours. */
  body.collab-granted.collab-viewing .rail .tool { display: flex !important; }
  body.collab-granted.collab-viewing #stylebar, body.collab-granted.collab-viewing #swatches { display: flex !important; }
  body.collab-granted.collab-viewing::after { content: "You can draw — shared with the class"; background: #3fb950; }
  body.collab-viewing::after { content: "Viewing live session"; position: fixed; top: 12px; left: 50%; transform: translateX(-50%);
    background: var(--accent, #6c5ce7); color: #fff; font: 700 12px/1 var(--font, sans-serif); padding: 7px 14px; border-radius: 999px; z-index: 65; pointer-events: none; box-shadow: 0 6px 18px rgba(0,0,0,0.25); }
  .nb-chip { width: 24px; height: 24px; border-radius: 50%; border: 2px solid var(--border-strong); cursor: pointer; padding: 0; flex: 0 0 auto; }
  .nb-chip.active { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); }
  .nb-btn { appearance: none; border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    min-width: 32px; height: 32px; border-radius: 9px; font: 600 14px/1 var(--font); cursor: pointer; padding: 0 8px; flex: 0 0 auto; }
  .nb-btn:hover { background: var(--hover); }
  .nb-btn.active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
  .nb-div { width: 1px; height: 22px; background: var(--border); flex: 0 0 auto; }
  .nb-color-wrap { display: inline-flex; flex: 0 0 auto; }
  .nb-color { width: 32px; height: 32px; padding: 2px; border: 1px solid var(--border-strong); border-radius: 9px; background: var(--panel); cursor: pointer; }
  .nb-color::-webkit-color-swatch-wrapper { padding: 0; }
  .nb-color::-webkit-color-swatch { border: none; border-radius: 6px; }
  .nb-color::-moz-color-swatch { border: none; border-radius: 6px; }
  .font-list { display: flex; flex-direction: column; gap: 2px; max-height: min(340px, 60vh); overflow-y: auto; min-width: 184px; }
  .font-list button { appearance: none; border: 1px solid transparent; background: transparent; color: var(--text);
    text-align: left; padding: 9px 12px; border-radius: 9px; cursor: pointer; font-size: 17px; line-height: 1.1;
    display: flex; align-items: center; justify-content: space-between; gap: 12px; white-space: nowrap; }
  .font-list button:hover { background: var(--hover); }
  .font-list button.active { border-color: var(--accent); background: var(--accent-soft); }
  .font-list button .fn-name { font: 600 12px/1 var(--font); color: var(--muted); flex: 0 0 auto; }
  #player-scrub { width: clamp(120px, 26vw, 260px); accent-color: var(--accent); cursor: pointer; }
  .pl-count { font: 600 12px/1 var(--font); color: var(--muted); min-width: 56px; text-align: center; font-variant-numeric: tabular-nums; }
  .pl-speed { padding: 0; gap: 3px; }
  .pl-speed button { padding: 6px 8px; font-size: 11px; }
  .pl-speedwrap { display: flex; align-items: center; gap: 7px; padding: 0 6px; }
  #player-speed-range {
    writing-mode: vertical-lr; direction: rtl;   /* standardized vertical range; up = faster */
    width: 26px; height: 62px; accent-color: var(--accent); cursor: pointer;
  }
  #player-speed-range::-moz-range-thumb { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--surface-solid);
    background: var(--accent); cursor: grab; }
  .pl-speedval { font: 700 13px/1 var(--font); color: var(--text); min-width: 38px; text-align: left; font-variant-numeric: tabular-nums; }
  .pl-exit { appearance: none; border: 1px solid var(--accent); background: var(--accent-soft); color: var(--accent);
    padding: 9px 14px; border-radius: 10px; font: 600 12.5px/1 var(--font); cursor: pointer; white-space: nowrap; }
  .pl-exit:hover { background: var(--accent); color: #fff; }
  /* ---------- the beats panel ----------
     Shaping the replay is the work this panel is for, so the strip gets a line
     of its own at full width instead of being squeezed into a 360px slot
     between buttons, and what you can do to a beat sits underneath in named
     groups. The whole block folds away for when you are only showing the
     lesson. */
  .pl-beatpanel { border-top: 1px solid var(--border); padding-top: 9px; display: flex; flex-direction: column; gap: 8px; }
  .pl-beathead { display: flex; align-items: center; gap: 10px; }
  .pl-beats-toggle { appearance: none; display: inline-flex; align-items: center; gap: 6px;
    border: 0; background: transparent; cursor: pointer; padding: 2px 2px;
    color: var(--muted); font: 700 11px/1 var(--font); text-transform: uppercase; letter-spacing: 0.06em; }
  .pl-beats-toggle:hover { color: var(--text); }
  .pl-beats-toggle svg { width: 13px; height: 13px; transition: transform 0.15s var(--ease); }
  .pl-beats-toggle[aria-expanded="false"] svg { transform: rotate(-90deg); }
  .pl-beats-count { font: 600 11.5px/1 var(--font); color: var(--text); font-variant-numeric: tabular-nums; }
  .pl-beathint { font: 500 11px/1.3 var(--font); color: var(--muted); flex: 1 1 auto; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #beat-body { display: flex; flex-direction: column; gap: 9px; }
  #beat-body[hidden] { display: none !important; }
  #beats-strip { display: flex; align-items: stretch; gap: 6px;
    width: 100%; min-height: 46px; padding: 4px 2px;
    overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; }
  /* Big enough to hit with a finger, and wide enough to carry its caption. */
  .beat-chip { appearance: none; flex: 0 0 auto; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 2px;
    min-width: 42px; max-width: 132px; min-height: 40px; padding: 4px 9px; border-radius: 10px;
    border: 1px solid var(--border-strong); background: var(--hover); color: var(--text);
    font: 700 13px/1 var(--font); cursor: grab; font-variant-numeric: tabular-nums;
    transition: background-color 0.1s var(--ease), border-color 0.1s var(--ease); }
  .beat-chip:hover { border-color: var(--accent); }
  .beat-chip.sel { background: var(--accent); color: #fff; border-color: var(--accent); }
  .beat-chip .bc-n { display: block; }
  .beat-chip .bc-cap { display: block; max-width: 112px; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; font: 500 10px/1.2 var(--font); opacity: 0.75; }
  .beat-chip .bc-marks { font: 500 9.5px/1 var(--font); opacity: 0.6; }
  /* What you can do to a beat: three named groups, then the caption, then the
     destructive one on its own at the end. */
  .pl-beatops { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .pl-opgroup { display: flex; align-items: center; gap: 5px; flex: 0 0 auto;
    padding: 4px 8px 4px 7px; border-radius: 11px; background: var(--hover);
    border: 1px solid var(--border); }
  .pl-opgrow { flex: 1 1 200px; min-width: 150px; }
  .pl-oplbl { font: 700 9.5px/1 var(--font); color: var(--muted);
    text-transform: uppercase; letter-spacing: 0.06em; padding-right: 2px; }
  /* On a phone the bar is the width of the screen and the clusters stack. */
  @media (max-width: 720px) {
    #player-bar { width: auto; left: 10px; right: 10px; transform: none; bottom: 10px;
      max-width: none; padding: 8px 10px 10px; }
    .pl-row { gap: 8px; }
    .pl-finish, .pl-view { border-left: 0; padding-left: 0; }
    .pl-finish { width: 100%; justify-content: center; }
    #player-scrub { width: clamp(90px, 34vw, 200px); }
    .pl-beatops { gap: 6px; }
    .pl-opgroup { padding: 3px 7px; }
    .pl-opgrow { flex: 1 1 100%; }
  }
  .pl-beat-btn { appearance: none; border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    padding: 7px 11px; border-radius: 9px; font: 600 12px/1 var(--font); cursor: pointer; white-space: nowrap; }
  .pl-beat-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
  .pl-beat-btn:disabled { opacity: 0.4; cursor: default; }
  .pl-beat-del:hover:not(:disabled) { border-color: #ff6b6b; color: #ff6b6b; }
  .pl-sel-btn { padding: 7px 9px; opacity: 0.92; }
  .beat-chip.dragging { opacity: 0.4; cursor: grabbing; }
  .beat-chip.over { border-color: var(--accent); box-shadow: inset 3px 0 0 var(--accent); }
  .pl-sel-btn.armed { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
  .pl-estimate { font: 600 11.5px/1.2 var(--font); color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
  /* 16px, because anything smaller makes iOS zoom the page on focus. */
  .pl-caption { appearance: none; border: 1px solid var(--border-strong); background: var(--surface-solid); color: var(--text);
    padding: 7px 10px; border-radius: 9px; font: 500 16px/1 var(--font); min-width: 110px; flex: 1 1 auto; width: 100%; }
  .pl-caption:focus { outline: none; border-color: var(--accent); }
  .pl-caption:disabled { opacity: 0.5; }
  .pl-estimate.warn { color: var(--danger, #e2536a); }
  /* 3-way choice modal */
  #choice-modal { position: fixed; inset: 0; z-index: 95; display: none; align-items: center; justify-content: center;
    background: rgba(8,10,14,0.55); backdrop-filter: blur(3px); }
  #choice-modal.show { display: flex; }
  .choice-card { background: var(--surface-solid); border: 1px solid var(--border); box-shadow: var(--shadow);
    border-radius: 16px; padding: 22px 24px; width: min(88vw, 380px); }
  .choice-msg { font: 600 15px/1.4 var(--font); color: var(--text); margin-bottom: 16px; }
  .choice-btns { display: flex; flex-direction: column; gap: 8px; }
  .choice-btn { appearance: none; border: 1px solid var(--border-strong); background: transparent; color: var(--text);
    padding: 11px 14px; border-radius: 10px; font: 600 13.5px/1 var(--font); cursor: pointer; text-align: center; }
  .choice-btn:hover { border-color: var(--accent); color: var(--accent); }
  .choice-btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
  .choice-btn.primary:hover { filter: brightness(1.08); color: #fff; }
  #gif-progress { position: fixed; inset: 0; z-index: 90; display: none; align-items: center; justify-content: center;
    background: rgba(8,10,14,0.55); backdrop-filter: blur(3px); }
  .gp-card { background: var(--surface-solid); border: 1px solid var(--border); box-shadow: var(--shadow);
    border-radius: 16px; padding: 22px 26px; width: min(86vw, 340px); text-align: center; }
  .gp-label { font: 600 15px/1.3 var(--font); color: var(--text); margin-bottom: 12px; }
  .gp-bar { height: 8px; border-radius: 999px; background: var(--hover); overflow: hidden; }
  .gp-bar > i { display: block; height: 100%; width: 0; background: var(--accent); border-radius: 999px;
    transition: width 0.2s var(--ease); }
  .gp-hint { font: 500 12px/1.4 var(--font); color: var(--muted); margin-top: 10px; }

  /* ---------- responsive ---------- */
  @media (max-width: 860px) {
    .brand small { display: none; }
    .rail { flex-direction: row; left: 50%; top: auto; bottom: 84px; transform: translateX(-50%);
      padding: 7px; gap: 2px; max-width: calc(100vw - 24px); overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
    .rail::-webkit-scrollbar { display: none; }
    .rail .pill { left: 7px; top: 7px; width: 42px; height: 42px; }
    .tool { width: 42px; height: 42px; flex: none; }
    .tool[data-tip]::after, .ctrl[data-tip]::after { display: none; }
    .stylebar { bottom: auto; top: 76px; gap: 10px; padding: 8px 12px; max-width: calc(100vw - 24px);
      overflow-x: auto; scrollbar-width: none; }
    /* Presenting on a narrow screen: the presenter bar is at the top, the tool
       rail keeps the bottom edge, and the style bar docks under the board
       between them. Nothing sets both top and bottom, so nothing can stretch. */
    body.presenting .rail { bottom: calc(18px + env(safe-area-inset-bottom, 0px)); }
    body.presenting #toast { bottom: calc(96px + env(safe-area-inset-bottom, 0px)); }
    /* On this same layout the rail moves to a horizontal row at bottom:84px —
       and the genie card was still anchored at bottom:26px, sitting directly
       on top of it. "Click the pen" with the pen physically hidden under the
       instructions was a real deadlock, not just an eyesore: there was no way
       to complete the step at all. Docking the card above that row, and
       letting it use most of the width, keeps both readable at once. */
    #genie-overlay { left: 12px; right: 12px; bottom: 150px; }
    .genie-card { width: 100%; }
    .stylebar::-webkit-scrollbar { display: none; }
    .stylebar.hidden { transform: translateX(-50%) translateY(-20px); }
    input[type="range"] { width: 92px; }
    #toast { bottom: 150px; }
    .topbar { top: 12px; left: 12px; right: 12px; }
    .brand { display: none; }
  }
  @media (max-width: 600px) {
    /* the brand label is cosmetic; drop it so the controls always fit/reach */
    .brand { display: none; }
    .topbar { gap: 0; }
    /* justify-content:flex-end + overflow is a known Chromium bug: the overflow
       spills past the START edge, where it overlaps and cannot be scrolled to.
       Safari handles it, which is why iOS looked fine. Align right with an auto
       margin instead — identical when it fits, scrollable when it doesn't. */
    .controls { width: 100%; max-width: 100%; justify-content: flex-start;
      overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -webkit-overflow-scrolling: touch;
      touch-action: pan-x; }
    .controls > *:first-child { margin-left: auto; }
    .controls::-webkit-scrollbar { display: none; }
    .controls > * { flex: none; }
  }
  @media (max-width: 500px) {
    .controls .opt-hide { display: none; }
    .ctrl-label .lbl { display: none; }
    .ctrl-label { padding: 0; width: 40px; justify-content: center; }
  }
  :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 8px; }
  button:focus:not(:focus-visible) { outline: none; }
  .pl-img { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
  .pl-img img { width: 100%; max-height: 150px; object-fit: contain; border-radius: 10px; background: var(--cp-raised); border: 1px solid var(--cp-line); }
  .qz-bar { display: block; height: 12px; border-radius: 999px; background: rgba(255,255,255,0.12); overflow: hidden; margin: 4px 0 16px; }
  .qz-bar span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, #6c5ce7, #4fd06a); transition: width .6s ease; }
  .qz-board { display: flex; flex-direction: column; gap: 6px; }
  .qz-boardrow { display: flex; align-items: center; gap: 10px; background: var(--hover, rgba(255,255,255,0.06)); border-radius: 10px; padding: 10px 12px; font: 500 14px/1 var(--font); }
  .qz-boardrow b { margin-left: auto; font-weight: 800; }

  /* ============================================================
     HELPER GENIE — a real demonstration on a real, disposable board
     No curtain, no fake canvas: the demo runs on a real board the genie
     adds to the deck and deletes when help ends. This file only styles the
     launcher, the ask panel, and the small floating instruction card that
     narrates alongside whatever the real app is actually doing.
     ============================================================ */
  :root {
    --genie-purple: #7c3aed;
    --genie-purple-dark: #4c1d95;
    --genie-gold: #fbbf24;
    --genie-gold-deep: #f59e0b;
  }

  /* ---------- the floating launcher: bottom-right, the entry point ---------- */
  /* Above the collab panel (70) and anything else that can sit in that corner,
     and slid clear of the panel when it opens so the two never overlap —
     being merely on top of a 340px panel still buries it visually. */
  body:has(#collab-panel.show) #genie-launcher,
  body.collab-panel-open #genie-launcher { right: 366px; }
  #genie-launcher { position: fixed; right: 26px; bottom: 26px; z-index: 125;
    transition: right .24s var(--ease);
    width: 60px; height: 60px; border-radius: 50%; border: none; padding: 0; cursor: pointer;
    background: radial-gradient(circle at 30% 28%, var(--genie-purple), var(--genie-purple-dark));
    box-shadow: 0 12px 30px rgba(124,58,237,0.5); animation: genie-float 3s ease-in-out infinite; }
  #genie-launcher:hover { box-shadow: 0 14px 36px rgba(124,58,237,0.65); }
  #genie-launcher svg { width: 34px; height: 34px; }
  #genie-launcher .genie-spark { position: absolute; border-radius: 50%; background: var(--genie-gold);
    opacity: 0; pointer-events: none; }
  #genie-launcher .genie-spark:nth-child(1) { width: 5px; height: 5px; top: 8px; left: 4px;
    animation: genie-spark 2.6s ease-in-out infinite; }
  #genie-launcher .genie-spark:nth-child(2) { width: 4px; height: 4px; bottom: 10px; right: 6px;
    animation: genie-spark 2.6s ease-in-out infinite 1.1s; }
  @keyframes genie-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
  @keyframes genie-spark { 0% { opacity: 0; transform: scale(.4); } 40% { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(.4) translateY(-8px); } }

  /* ---------- the highlight: a class on the real element ----------
     Not an overlay positioned from coordinates. The browser already knows
     where the element is, on every device and at every zoom level, so the
     ring is drawn as the element's own outline and can never be in the wrong
     place. outline (rather than border) is used because it does not take up
     layout space, so highlighting something never nudges the surrounding
     controls around. */
  .genie-target {
    outline: 3px solid var(--genie-gold) !important;
    outline-offset: 3px;
    border-radius: 10px;
    animation: genie-target-pulse 1.1s ease-in-out infinite;
    /* Deliberately NO position or z-index here. Setting position:relative
       overrode the fixed positioning of anything already fixed — the style
       bar, the rail, the calculator — which dropped it out of its fixed spot
       and into normal document flow, sending it to the top of the page the
       moment it was highlighted. An outline needs no positioning to be drawn
       in the right place, so the class touches nothing about layout at all. */
  }
  @keyframes genie-target-pulse {
    0%, 100% { box-shadow: 0 0 0 3px rgba(251,191,36,0.20), 0 0 18px rgba(251,191,36,0.55); }
    50%      { box-shadow: 0 0 0 7px rgba(251,191,36,0.08), 0 0 26px rgba(251,191,36,0.75); }
  }

  /* Dim per container, not with one full-screen scrim: a scrim would need the
     target lifted above it, and a target inside the topbar, the rail or a
     popover is trapped in that container's stacking context and cannot be.
     :has() lets each container skip dimming when it is the one holding the
     target. Browsers without :has() simply show no dimming — the ring and the
     click-blocking still do their job. */
  body.genie-guiding .topbar:not(:has(.genie-target)),
  body.genie-guiding .rail:not(:has(.genie-target)),
  body.genie-guiding .stylebar:not(:has(.genie-target)),
  body.genie-guiding .pop.open:not(:has(.genie-target)),
  body.genie-guiding #calc-card:not(:has(.genie-target)) {
    opacity: 0.45;
    transition: opacity .2s var(--ease);
  }
  /* The board itself is never the thing being pointed at unless a step says
     so, so it dims with everything else. */
  body.genie-guiding #board:not(.genie-target) { opacity: 0.55; transition: opacity .2s var(--ease); }

  @media (prefers-reduced-motion: reduce) {
    .genie-target { animation: none; box-shadow: 0 0 0 4px rgba(251,191,36,0.25), 0 0 20px rgba(251,191,36,0.6); }
  }

  /* ---------- the ask panel ---------- */
  #genie-pop { background: linear-gradient(165deg, rgba(30,27,75,0.96), rgba(46,16,101,0.96));
    backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
    border: 1px solid rgba(255,255,255,0.14); box-shadow: 0 28px 70px rgba(30,27,75,0.55);
    min-width: 340px; max-width: 380px; padding: 16px; }
  #genie-pop h4 { color: rgba(255,255,255,0.55); display: flex; align-items: center; gap: 6px; font-size: 13px; margin: 4px 8px 10px; }
  #genie-pop h4::before { content: "\2728"; font-size: 12px; }
  #genie-pop .ins-hint { color: rgba(255,255,255,0.6); font-size: 12.5px; margin: 0 2px 10px; }
  .genie-ask { display: flex; flex-direction: column; align-items: stretch; gap: 8px; margin: 10px 4px 6px; }
  .genie-ask input { background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.16);
    color: #fff; height: 44px; padding: 0 14px; font-size: 14.5px; border-radius: 11px; }
  .genie-ask input::placeholder { color: rgba(255,255,255,0.4); }
  .genie-ask input:focus { outline: none; border-color: var(--genie-gold);
    box-shadow: 0 0 0 3px rgba(251,191,36,0.18); }
  .genie-ask .pop-action { height: 42px; width: auto; margin: 0;
    background: linear-gradient(135deg, var(--genie-gold), var(--genie-gold-deep));
    color: #3f2a02; font-weight: 800; border: none; }
  .genie-ask .pop-action:hover { filter: brightness(1.05); }
  #genie-suggest .ins-hint { color: rgba(255,255,255,0.65); margin: 4px 2px 8px; }
  #genie-suggest .genie-suggest-btn, #genie-switch-list .genie-suggest-btn {
    background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.1); color: #fff;
    border-radius: 12px; font-weight: 600; margin-bottom: 6px; text-align: left;
    transition: background .15s, border-color .15s; width: 100%; }
  #genie-suggest .genie-suggest-btn:hover, #genie-switch-list .genie-suggest-btn:hover {
    background: rgba(255,255,255,0.14); border-color: rgba(251,191,36,0.5); }

  /* ---------- the help overlay: just a small floating card now, positioned
     clear of the launcher so both stay reachable, and NOT covering the
     board — the real board is exactly what the person is meant to see. ---------- */
  /* z-index 95, not 90: every maker dialog (#mmd-dlg, #tbl-dlg, #lab-dlg...)
     has its own full-viewport blurring scrim at z-index 92/93 — at 90 the
     genie card was rendering BENEATH that scrim the instant a real dialog
     opened, which is exactly the "instructions blur and stop responding"
     bug: it wasn't a bug in the card at all, the real dialog's own backdrop
     was simply covering it. */
  /* 124 since v278: the floating tool cards (calculator, timer, region, time
     machine) sit at 120/121, and on a phone they covered the card's own Next
     and Exit. The card moves itself clear of whatever it points at, so it can
     safely be on top of them. Still under the launcher and context menus. */
  #genie-overlay { position: fixed; left: 26px; bottom: 26px; z-index: 124; display: none; }
  #genie-overlay.show { display: block; }

  .genie-card { width: min(360px, calc(100vw - 52px));
    background: linear-gradient(170deg, rgba(30,27,75,0.97), rgba(46,16,101,0.97));
    backdrop-filter: blur(6px); color: #fff;
    border-radius: 22px; border: 1px solid rgba(255,255,255,0.14);
    box-shadow: 0 30px 70px rgba(15,12,41,0.55), 0 0 0 1px rgba(124,58,237,0.15) inset;
    padding: 22px 22px 18px; position: relative;
    animation: genie-card-in .32s cubic-bezier(.2,.9,.3,1.2); }
  @keyframes genie-card-in { from { opacity: 0; transform: translateY(14px) scale(.97); } to { opacity: 1; transform: none; } }

  .genie-close { position: absolute; right: 12px; top: 12px; width: 30px; height: 30px;
    border-radius: 50%; border: none; background: rgba(255,255,255,0.08); color: rgba(255,255,255,0.7);
    font-size: 19px; line-height: 1; cursor: pointer; transition: background .15s, color .15s; }
  .genie-close:hover { background: rgba(255,255,255,0.16); color: #fff; }

  .genie-step-label { font: 800 10.5px/1 var(--font); letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--genie-gold); margin-bottom: 8px; }
  .genie-title { font: 800 17px/1.3 var(--font); margin-bottom: 8px; padding-right: 22px; color: #fff; }
  .genie-body { font: 500 13.5px/1.55 var(--font); color: rgba(255,255,255,0.72); }
  .genie-body b { color: #fff; font-weight: 700; }
  .genie-body code { background: rgba(255,255,255,0.1); padding: 1px 6px;
    border-radius: 5px; font: 500 12px/1 ui-monospace, Menlo, Consolas, monospace; color: #fde68a; }

  .genie-nav { display: flex; align-items: center; justify-content: space-between; margin-top: 14px; gap: 10px; }
  .genie-dots { display: flex; gap: 6px; }
  .genie-dot { width: 6px; height: 6px; border-radius: 50%; background: rgba(255,255,255,0.22); }
  .genie-dot.on { background: var(--genie-gold); box-shadow: 0 0 8px rgba(251,191,36,0.6); }
  .genie-nav-btns { display: flex; gap: 8px; }
  .genie-nav-btns .pop-action { width: auto; margin: 0; padding: 8px 14px; border: none;
    background: linear-gradient(135deg, var(--genie-gold), var(--genie-gold-deep));
    color: #3f2a02; font-weight: 800; }
  .genie-nav-btns .pop-action:hover { filter: brightness(1.05); }
  .genie-nav-btns .pop-action.ghost { background: rgba(255,255,255,0.08); color: rgba(255,255,255,0.75); }
  .genie-nav-btns .pop-action.ghost:hover { background: rgba(255,255,255,0.14); }
  .genie-nav-btns .pop-action:disabled { opacity: 0.3; cursor: default; pointer-events: none; filter: none; }

  .genie-switch input { width: 100%; height: 38px; padding: 0 12px; border-radius: 10px;
    background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.16); color: #fff;
    font-size: 13px; margin-bottom: 8px; }
  .genie-switch input:focus { outline: none; border-color: var(--genie-gold); }
  #genie-switch-list { max-height: 200px; overflow-y: auto; }

  .genie-card-links { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; }
  .genie-exit { display: block; width: 100%; padding: 7px 0;
    background: transparent; border: none; color: rgba(255,255,255,0.55);
    font: 600 11.5px/1.3 var(--font); text-align: center; text-decoration: underline;
    text-underline-offset: 3px; cursor: pointer; }
  .genie-exit:hover { color: #fff; }

  /* ============================================================
     IMAGE LAB
     A darkroom for pictures. Same shell as the makers (#mmd-dlg), with a
     big preview on the left and the settings on the right — the picture is
     what you are judging, so it gets the room.
     ============================================================ */
  #imglab-dlg { position: fixed; inset: 0; z-index: 94; display: none; align-items: center; justify-content: center;
    padding: 18px; background: rgba(8,10,16,0.6); backdrop-filter: blur(3px); }
  #imglab-dlg.show { display: flex; }
  #imglab-dlg .mmd-inner { max-width: 1120px; }
  /* Three goes at this, so the model in full. The two columns are unequal by
     nature: a picture on the left, a long list of settings on the right. Sizing
     the picture area from the ROW made it stretch to the settings column and
     left empty checkerboard around a small photo. Sizing it from the PICTURE
     made a small photo give a small panel. Leaving the columns to find their
     own heights left the short one ending early — a gap at the bottom left,
     above the buttons.

     So: both columns get the same height, and the picture area FILLS whatever
     the column has left after the toolbar under it. No gap, and the preview is
     as large as the panel allows whatever size the picture is. */
  #imglab-dlg .mmd-body { align-items: stretch; }
  #imglab-dlg .mmd-left, #imglab-dlg .mmd-right { max-height: 74vh; }
  #imglab-dlg .mmd-left { flex: 1 1 58%; display: flex; flex-direction: column;
    overflow-y: hidden; overflow-x: hidden; }
  #imglab-dlg .mmd-right { flex: 1 1 42%; }
  .imglab-stats { margin-left: auto; color: var(--muted); font: 500 11.5px/1.3 var(--font);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 45%; }
  #imglab-stage { position: relative; display: flex; align-items: center; justify-content: center;
    flex: 1 1 auto; min-height: 240px; padding: 10px; border-radius: 14px;
    border: 1px dashed var(--border-strong); background: var(--hover);
    /* A checkerboard, so a cut-out subject reads as transparent rather than white. */
    background-image:
      linear-gradient(45deg, rgba(128,128,128,0.10) 25%, transparent 25%, transparent 75%, rgba(128,128,128,0.10) 75%),
      linear-gradient(45deg, rgba(128,128,128,0.10) 25%, transparent 25%, transparent 75%, rgba(128,128,128,0.10) 75%);
    background-size: 18px 18px; background-position: 0 0, 9px 9px; }
  #imglab-stage.over { border-color: var(--accent); background-color: var(--accent-soft); }
  /* Fits the area it sits in. A viewport-relative ceiling of its own let the
     picture overflow the stage on a short window. */
  #imglab-canvas { max-width: 100%; max-height: 100%; border-radius: 8px;
    box-shadow: 0 2px 14px rgba(0,0,0,0.22); }
  /* [hidden] is a UA rule of the lowest possible specificity, so the two rules
     below — which set display on an ID — silently beat it. Without these
     guards the drop hint and the "Working…" spinner could never be turned off,
     which is exactly how they came to be on screen permanently. */
  #imglab-drop[hidden], #imglab-busy[hidden], .imglab-stagebar [hidden],
  #imglab-corners-row[hidden] { display: none !important; }
  #imglab-drop { position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 8px; text-align: center; padding: 20px;
    color: var(--muted); font: 500 13px/1.5 var(--font); pointer-events: none; }
  #imglab-drop b { color: var(--text); font: 700 14.5px/1.4 var(--font); }
  #imglab-drop button { pointer-events: auto; }
  #imglab-busy { position: absolute; top: 10px; right: 12px; display: flex; align-items: center; gap: 7px;
    padding: 5px 10px; border-radius: 999px; background: var(--surface-solid);
    border: 1px solid var(--border); color: var(--muted); font: 600 11.5px/1.3 var(--font); }
  .imglab-spin { width: 11px; height: 11px; flex: none; border-radius: 50%;
    border: 2px solid var(--border-strong); border-top-color: var(--accent);
    animation: imglab-spin 0.7s linear infinite; }
  @keyframes imglab-spin { to { transform: rotate(360deg); } }
  .imglab-h { margin: 12px 0 7px; color: var(--muted);
    font: 700 10.5px/1.2 var(--font); letter-spacing: 0.08em; text-transform: uppercase; }
  .imglab-h:first-child { margin-top: 0; }
  /* Starting points, as cards with a reason — "docscan" means nothing on its own. */
  /* The chips used to sit in this box directly, so it was a two-column grid.
     They are grouped by purpose now, which made each GROUP a grid cell: a
     heading in the left column and a whole block of chips in the right. The
     box just stacks its groups; .imglab-pgrid does the two columns. */
  .imglab-presets { display: block; }
  .imglab-preset { display: flex; flex-direction: column; gap: 1px; align-items: flex-start;
    padding: 7px 9px; border-radius: 10px; cursor: pointer; text-align: left;
    border: 1px solid var(--border-strong); background: var(--surface-solid); color: var(--text); }
  .imglab-preset b { font: 700 12.5px/1.3 var(--font); }
  .imglab-preset small { color: var(--muted); font: 500 10.5px/1.3 var(--font); }
  .imglab-preset:hover { background: var(--hover); border-color: var(--accent); }
  .imglab-preset.active { background: var(--accent-soft); border-color: var(--accent); }
  .imglab-preset.active b { color: var(--accent); }
  .imglab-panels { display: flex; flex-direction: column; gap: 5px; }
  .imglab-group { border: 1px solid var(--border-strong); border-radius: 11px; overflow: hidden;
    background: var(--surface-solid); }
  .imglab-group > summary { padding: 8px 11px; cursor: pointer; list-style: none;
    font: 700 12px/1.3 var(--font); color: var(--text); }
  .imglab-group > summary::-webkit-details-marker { display: none; }
  .imglab-group > summary::before { content: "\203A"; display: inline-block; width: 12px;
    color: var(--muted); transition: transform 0.15s ease; }
  .imglab-group[open] > summary::before { transform: rotate(90deg); }
  .imglab-group > summary:hover { background: var(--hover); }
  .imglab-row { display: flex; align-items: center; gap: 9px; padding: 5px 11px 5px 23px;
    font: 500 12px/1.3 var(--font); color: var(--text); }
  .imglab-row[hidden] { display: none; }
  .imglab-lab { flex: 0 0 40%; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .imglab-row input[type=range] { flex: 1 1 auto; min-width: 0; accent-color: var(--accent); }
  .imglab-row select { flex: 1 1 auto; min-width: 0; padding: 4px 7px; border-radius: 8px;
    border: 1px solid var(--border-strong); background: var(--surface-solid); color: var(--text);
    font: 500 12px var(--font); }
  .imglab-row input[type=checkbox] { flex: none; width: 15px; height: 15px; margin-left: auto; accent-color: var(--accent); }
  .imglab-row input[type=color] { flex: none; width: 34px; height: 24px; margin-left: auto;
    padding: 0; border: 1px solid var(--border-strong); border-radius: 6px; background: none; cursor: pointer; }
  .imglab-val { flex: 0 0 38px; text-align: right; color: var(--muted);
    font: 600 11px/1.3 ui-monospace, SFMono-Regular, Menlo, monospace; font-style: normal; }
  @media (max-width: 760px) {
    #imglab-dlg .mmd-inner { max-width: 100%; }
    #imglab-stage { min-height: 190px; }
    #imglab-dlg .mmd-left, #imglab-dlg .mmd-right { max-height: none; }
    .imglab-pgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .imglab-lab { flex: 0 0 46%; }
  }

  /* preset groups: three purposes, not one long undifferentiated wall */
  .imglab-pgroup { margin: 10px 0 5px; color: var(--muted);
    font: 700 10px/1.2 var(--font); letter-spacing: 0.07em; text-transform: uppercase; }
  .imglab-pgroup:first-child { margin-top: 0; }
  .imglab-pgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
  .imglab-stagebar { display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
  .imglab-cmp { display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
    padding: 5px 10px; border-radius: 999px; border: 1px solid var(--border-strong);
    background: var(--surface-solid); color: var(--text); font: 600 11.5px/1.3 var(--font); }
  .imglab-cmp input { width: 14px; height: 14px; accent-color: var(--accent); }
  .imglab-hint { color: var(--muted); font: 500 11px/1.4 var(--font); flex: 1 1 160px; min-width: 0;
    font-style: normal; }
  .imglab-splitwrap { display: inline-flex; align-items: center; gap: 8px; flex: 1 1 200px; min-width: 0; }
  .imglab-splitwrap[hidden] { display: none !important; }
  #imglab-split { flex: 1 1 auto; min-width: 90px; accent-color: var(--accent); }
  .imglab-splitwrap .imglab-hint { flex: 0 0 auto; }
  /* While the split is on, the picture itself is the handle. */
  #imglab-canvas.imglab-grab { cursor: ew-resize; touch-action: none; }

  /* ---------- pointer tools ----------
     The laser's styles as a grid of named swatches: a row of nine unlabelled
     dots would make you try each one to find out what it is. */
  .pnt-styles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 5px; padding: 2px 4px 6px; }
  .pnt-style { display: flex; flex-direction: column; align-items: center; gap: 4px;
    padding: 7px 4px; border-radius: 10px; cursor: pointer; text-align: center;
    border: 1px solid var(--border-strong); background: var(--surface-solid); color: var(--text);
    font: 600 10.5px/1.2 var(--font); }
  .pnt-style:hover { border-color: var(--accent); }
  .pnt-style.active { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
  .pnt-swatch { display: block; width: 26px; height: 18px; border-radius: 4px; position: relative;
    background: rgba(128,128,128,0.16); }
  /* A hint of each style, so the choice can be made by eye. */
  .pnt-swatch::after { content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
    width: 7px; height: 7px; border-radius: 50%; background: #ff3b30; box-shadow: 0 0 5px #ff3b30; }
  .pnt-sw-bigdot::after { width: 12px; height: 12px; }
  .pnt-sw-halo::after { width: 14px; height: 14px; background: radial-gradient(circle, #ff3b30 30%, rgba(255,59,48,0.25) 60%, transparent 72%); box-shadow: none; }
  .pnt-sw-target::after { width: 13px; height: 13px; border-radius: 50%; background: transparent;
    border: 1.5px solid #ff3b30; box-shadow: none; }
  .pnt-sw-arrow::after { width: 0; height: 0; border-radius: 0; background: transparent; box-shadow: none;
    border-left: 5px solid transparent; border-right: 5px solid transparent; border-bottom: 10px solid #ff3b30; }
  .pnt-sw-finger::after { width: 5px; height: 11px; border-radius: 3px; box-shadow: none; }
  .pnt-sw-trail::after { width: 18px; height: 4px; border-radius: 3px;
    background: linear-gradient(90deg, transparent, #ff3b30); box-shadow: none; }
  .pnt-sw-pulse::after { box-shadow: 0 0 0 4px rgba(255,59,48,0.32); }
  .pnt-sw-ripple::after { width: 14px; height: 14px; background: transparent; box-shadow: none;
    border: 1.5px solid rgba(255,59,48,0.9); border-radius: 50%;
    outline: 1.5px solid rgba(255,59,48,0.35); outline-offset: 3px; }
  /* Which inputs the pointer answers to. */
  .pnt-acts { display: flex; gap: 5px; padding: 0 4px 4px; }
  .pnt-act { flex: 1 1 0; display: flex; align-items: center; justify-content: center; gap: 5px;
    padding: 6px 4px; border-radius: 9px; cursor: pointer;
    border: 1px solid var(--border-strong); background: var(--surface-solid);
    font: 600 11px/1 var(--font); color: var(--text); }
  .pnt-act input { width: 14px; height: 14px; accent-color: var(--accent); }
  .pnt-act:hover { border-color: var(--accent); }
  /* While the laser is on, the board is for pointing at, not drawing on. */
  body.lasering #board { cursor: none; }
  /* The way out of a container, while presenting. Marked out from the rest of
     the bar, because it is the one control that changes where you are. */
  #present-bar #present-zone-back { background: rgba(255,255,255,0.30); border-color: rgba(255,255,255,0.5); }
  #present-bar #present-zone-back:hover { background: rgba(255,255,255,0.44); }
  #present-bar button[hidden] { display: none !important; }

  /* ================================================================
     RUBBER STAMPS

     The tray rests on the top frame ring, positioned from the frame's own
     geometry rather than the window's: computeFrame publishes --board-left,
     --board-right, --board-mid, --board-top and --frame-w, and every path
     that can move the frame goes through it.

     DOM rather than canvas, deliberately. On the canvas the tray would
     appear in every PNG, print, GIF and video export and would need its own
     hit-testing; here it inherits focus, keyboard and tooltips, and print
     already hides everything outside #print-area.
     ================================================================ */

  /* The tray is ENGRAVED INTO the frame, not laid on it. That is one rule:
     paint nothing frame-like. No panel, no blur, no backdrop — the real
     painted ring shows through, so a wood grain, a gradient, a photograph or
     a flat colour all line up perfectly underneath without the tray knowing
     anything about them. What the tray contributes is the cut: a shadow down
     the inside of the top-left edge, a lit lip on the bottom-right, and a
     floor slightly darker than the wood around it. Those three colours are
     SAMPLED off the painted frame in app.js and arrive as --rub-cut, --rub-lip,
     --rub-floor and --rub-ink, which is why a pale frame and a dark one both
     read. The left/top are set in pixels by rubTrayPlace. */
  #rub-tray {
    position: fixed;
    left: var(--board-mid, 50vw);
    top: calc(var(--board-top, 84px) + var(--frame-w, 20px) / 2);
    transform: translateY(-50%);
    display: flex; align-items: center; gap: 4px;
    padding: 0 3px;
    background: none; border: 0; box-shadow: none;
    /* Above the ambience surround (3) and below the rail and style bar (25),
       so a show still looks right and the tools still win. */
    z-index: 20;
    max-width: calc(100vw - 32px);
    /* The whole strip is only as tall as the ring it is cut into. */
    height: var(--frame-w, 20px);
    --rub-cut: rgba(0,0,0,0.42);
    --rub-lip: rgba(255,255,255,0.5);
    --rub-floor: rgba(0,0,0,0.16);
    --rub-ink: rgba(0,0,0,0.8);
    --rub-grip: rgba(0,0,0,0.32);
    /* The recess is the frame's own height less a lip top and bottom; the
       hit area is padded back out below, so a finger still lands. */
    --rub-h: max(16px, calc(var(--frame-w, 20px) - 7px));
  }
  /* REPORTED (iPad, Android, and a short desktop window): a white dot or line
     on the bottom frame. An empty tray is marked hidden, but the display:flex
     above beats the browser's own [hidden] rule, so it was always on screen —
     invisible only because it painted nothing. On a thin frame the panel
     fallback below gives it a white background and border, and there it was.
     No stamps means no tray, whatever the frame or any later rule says. */
  #rub-tray[hidden] { display: none !important; }
  /* A board that has not been painted yet, or a canvas the browser will not
     let us read. Rather than an invisible tray, fall back to the panel look. */
  #rub-tray.rub-noframe {
    padding: 4px 6px; border-radius: 12px;
    background: var(--panel, rgba(255,255,255,0.86));
    border: 1px solid var(--border, rgba(0,0,0,0.1));
    box-shadow: 0 3px 14px rgba(0,0,0,0.2);
    height: auto;
  }

  .rub-tile {
    min-width: 36px; height: var(--rub-h); padding: 0 8px;
    border: 0;
    border-radius: 7px;
    /* The floor of the recess, which is the frame itself one shade darker.
       A stamp WITH a shape paints its own colour over this; a "just the text"
       stamp does not, and must show the frame through the hole. It used to
       fall back to Slate's --surface here, which made a shapeless stamp a
       white chip stuck on the wood in light mode and a black one in dark. */
    background: var(--rub-floor);
    color: var(--rub-ink);
    font: 600 13px/1 var(--font, system-ui);
    display: inline-flex; align-items: center; justify-content: center;
    cursor: pointer;
    position: relative;
    /* Cut in. The far wall of the recess falls into shadow (inset, top-left),
       the near wall catches the light (inset, bottom-right), and OUTSIDE the
       hole a single lit line along the bottom is the lip of the cut where the
       frame picks the light back up. An outer ring was tried here and read as
       a drawn stroke — a border round a button — rather than as a hole. */
    box-shadow: inset 1.5px 1.5px 2.5px var(--rub-cut),
                inset -1px -1px 1.5px var(--rub-lip),
                0 1px 0 var(--rub-lip);
    transition: box-shadow 0.12s var(--ease, ease), filter 0.12s var(--ease, ease);
  }
  /* The touch target, pushed back out to a comfortable size without the
     engraving growing with it — the recess stays the width of the ring, the
     thing you can hit does not.

     It grows OUTWARD, away from the board, never symmetrically. A 44px target
     centred on a 27px ring reaches eight pixels onto the writing surface, and
     those eight pixels stop being board: a mark started just under the tray
     would land on an invisible button instead. Outside the frame there is
     only margin, so that is where the slack goes. */
  .rub-tile::after, .rub-grip::after, .rub-manage::after {
    content: ""; position: absolute; left: 0; right: 0;
    top: -26px; bottom: -3px;
  }
  #rub-tray[data-side="bottom"] .rub-tile::after,
  #rub-tray[data-side="bottom"] .rub-grip::after,
  #rub-tray[data-side="bottom"] .rub-manage::after {
    top: -3px; bottom: -26px;
  }
  .rub-tile:hover { filter: brightness(1.12); }
  .rub-tile:active {
    box-shadow: inset 2px 2px 4px var(--rub-cut),
                inset -1px -1px 1px var(--rub-lip);
    filter: brightness(0.94);
  }
  .rub-tile:focus-visible { outline: 2px solid var(--accent, #6c5ce7); outline-offset: 2px; }
  /* The stamp in your hand. It rises PROUD of the frame — the one thing in
     the tray that is not cut into it — which is the clearest possible way of
     saying this one is lifted out and in your hand. */
  .rub-tile.active {
    box-shadow: 0 0 0 2px var(--accent, #6c5ce7),
                0 2px 6px rgba(0,0,0,0.4),
                inset 0 1px 0 var(--rub-lip);
    filter: brightness(1.08);
  }

  /* The grip: three cut lines in the wood, and the only part of the tray you
     can drag — everything else is a stamp and a drag there would cost you a
     click you meant. */
  .rub-grip {
    width: 11px; height: var(--rub-h); padding: 0; border: 0;
    background: none; cursor: grab;
    display: inline-flex; flex-direction: column; justify-content: center;
    align-items: center; gap: 2px;
    position: relative; flex: 0 0 auto;
  }
  .rub-grip span {
    display: block; width: 9px; height: 1px;
    background: var(--rub-grip);
    box-shadow: 0 1px 0 var(--rub-lip);
  }
  .rub-grip:hover span { background: var(--rub-ink); }
  .rub-grip:focus-visible { outline: 2px solid var(--accent, #6c5ce7); outline-offset: 1px; }
  #rub-tray.rub-dragging { }
  #rub-tray.rub-dragging .rub-grip { cursor: grabbing; }
  /* No transition while dragging, or the tray lags the hand. */
  #rub-tray.rub-dragging .rub-tile { transition: none; }

  .rub-manage {
    min-width: 24px; height: var(--rub-h); padding: 0 6px;
    border: 0; border-radius: 6px; background: transparent;
    color: var(--rub-ink); opacity: 0.7;
    font: 700 12px/1 var(--font, system-ui);
    cursor: pointer;
    box-shadow: inset 1px 1px 2px var(--rub-cut), inset -1px -1px 1px var(--rub-lip);
    position: relative;
  }
  .rub-manage:hover { opacity: 1; background: var(--rub-floor); }
  .rub-manage.rub-full {
    color: var(--accent-warn, #e3a33a); opacity: 1; font-size: 10px;
  }

  /* Stamp mode. The cut tray cannot take a glow without becoming a panel
     again, so the sign is the lifted tile above plus the board's own cursor. */
  body.rub-mode #board { cursor: copy; }

  /* The tray must never be the one live control on a replay or for a viewer
     who cannot place anything. Player and print hide it; a viewer keeps it,
     because seeing which stamps the presenter has is the point. */
  body.player-mode #rub-tray,
  body.exporting #rub-tray { display: none; }

  /* REPORTED: on an iPad and on Android the tray came out as a white blob on
     the bottom frame instead of engraved into it. This fallback used to be a
     860px media query — and an iPad in portrait is 820 CSS pixels, so a
     tablet with a 25px ring got the phone layout while the same iPad in
     landscape did not. body.frame-thin is set from the ring's actual
     thickness instead (computeFrame), so the question asked here is the one
     that matters: is there enough frame to cut into? A 13px phone ring still
     gets the panel; every tablet now gets the engraving either way up. */
  body.frame-thin #rub-tray, body.rub-panel #rub-tray {
      left: 50% !important; top: auto !important;
      bottom: calc(142px + env(safe-area-inset-bottom, 0px));
      transform: translateX(-50%);
      height: auto; padding: 4px 7px; gap: 6px;
      border-radius: 13px;
      background: var(--panel, rgba(255,255,255,0.86));
      border: 1px solid var(--border, rgba(0,0,0,0.1));
      box-shadow: 0 3px 14px rgba(0,0,0,0.22);
      backdrop-filter: blur(9px) saturate(150%);
      --rub-h: 42px;
    }
    body.frame-thin .rub-grip, body.rub-panel .rub-grip { display: none; }
    body.frame-thin .rub-tile, body.rub-panel .rub-tile {
      min-width: 46px; font-size: 16px; border-radius: 10px;
      box-shadow: inset 0 -1px 0 rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.18);
    }
    body.frame-thin .rub-tile.active, body.rub-panel .rub-tile.active {
      box-shadow: 0 0 0 3px var(--accent, #6c5ce7), 0 3px 8px rgba(0,0,0,0.3);
    }
    body.frame-thin .rub-manage, body.rub-panel .rub-manage { box-shadow: none; border: 1px dashed var(--border-strong, rgba(0,0,0,0.22)); }
  @media (max-height: 620px) {
    body:not(.frame-thin):not(.rub-panel) .rub-tile { min-width: 32px; font-size: 12px; }
  }

  /* ---- where it sits, named ------------------------------------------- */
  .rub-place-row { display: flex; align-items: center; gap: 8px; margin-top: 9px; flex-wrap: wrap; }
  .rub-place-lab { font: 600 11.5px/1 var(--font, system-ui); color: var(--text-soft, #667); }
  .rub-place-hint { font: 500 11px/1 var(--font, system-ui); color: var(--muted, #889); }
  /* Six buttons drawn as the frame they stand for: a rectangle with a mark
     where the tray would go, so the choice is read rather than parsed. */
  .rub-place { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; }
  .rub-place-btn {
    width: 26px; height: 18px; padding: 0; cursor: pointer;
    border: 1px solid var(--border-strong, rgba(0,0,0,0.2));
    border-radius: 3px; background: var(--hover, rgba(0,0,0,0.04));
    position: relative;
  }
  .rub-place-btn::before {
    content: ""; position: absolute; width: 8px; height: 3px; border-radius: 1px;
    background: var(--text-soft, #667);
  }
  .rub-place-btn[data-rub-side="top"]::before { top: 1px; }
  .rub-place-btn[data-rub-side="bottom"]::before { bottom: 1px; }
  .rub-place-btn[data-rub-at="0"]::before { left: 2px; }
  .rub-place-btn[data-rub-at="0.5"]::before { left: 50%; transform: translateX(-50%); }
  .rub-place-btn[data-rub-at="1"]::before { right: 2px; }
  .rub-place-btn:hover { border-color: var(--accent, #6c5ce7); }
  .rub-place-btn.active {
    border-color: var(--accent, #6c5ce7); background: var(--accent-soft, rgba(108,92,231,0.18));
  }
  .rub-place-btn.active::before { background: var(--accent, #6c5ce7); }

  /* ---- the creator ---------------------------------------------------- */
  /* The right column is the preview and, under it, the run of values the next
     few clicks will stamp — the thing the spec asks for and the thing a
     teacher checks before committing. The panel took `height: 100%` from
     .mmd-preview, grew to the full column and pushed that run out of the
     scroll area, so it was there but never seen. The column is a flex stack
     now: the panel takes what is left, the run keeps its line. */
  #rub-dlg .mmd-right { display: flex; flex-direction: column; min-height: 0; }
  .rub-preview {
    display: flex; align-items: center; justify-content: center;
    min-height: 118px; height: auto; flex: 1 1 auto;
  }
  .rub-chip {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 2.1em; padding: 0.3em 0.5em; line-height: 1.05;
  }
  .rub-chip.rub-shape-circle { border-radius: 50%; aspect-ratio: 1; padding: 0.42em; }
  .rub-chip.rub-shape-round { border-radius: 0.34em; }
  .rub-chip.rub-shape-square { border-radius: 3px; }
  .rub-chip.rub-shape-none { background: transparent !important; }

  .rub-seq {
    margin: 8px 0 0; flex: 0 0 auto; text-align: center;
    font: 600 13px/1.5 var(--font, system-ui);
    color: var(--text-soft, #667); letter-spacing: 0.02em;
  }
  .rub-count { font: 600 11px/1 var(--font, system-ui); color: var(--text-soft, #667); }
  .rub-count.is-full { color: var(--accent-warn, #e3a33a); }

  .rub-manage-list { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
  .rub-row {
    display: flex; align-items: center; gap: 6px;
    padding: 4px 5px; border-radius: 9px;
    background: var(--hover, rgba(0,0,0,0.04));
  }
  .rub-row.active { box-shadow: inset 0 0 0 1.5px var(--accent, #6c5ce7); }
  .rub-row-chip {
    min-width: 32px; height: 26px; padding: 0 6px; border: none;
    border-radius: 7px; cursor: pointer;
    font: 700 12px/1 var(--font, system-ui);
    background: var(--surface, #fff);
  }
  .rub-row-chip.rub-shape-circle { border-radius: 50%; width: 26px; min-width: 26px; padding: 0; }
  .rub-row-chip.rub-shape-none { background: transparent; }
  .rub-row-name { flex: 1; font: 600 12px/1 var(--font, system-ui);
                  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .rub-row-next { font: 500 10px/1 var(--font, system-ui); color: var(--muted, #8a93a2); }
  .rub-row-btn {
    width: 24px; height: 24px; border: none; border-radius: 6px;
    background: transparent; color: var(--text-soft, #667);
    font: 600 12px/1 var(--font, system-ui); cursor: pointer;
  }
  .rub-row-btn:hover { background: var(--surface, #fff); color: var(--text, #222); }
  .rub-row-btn.is-del:hover { background: var(--accent-warn, #e3a33a); color: #fff; }
  label.is-off { opacity: 0.42; }
  #rub-make.is-off { opacity: 0.5; cursor: not-allowed; }

  /* ---- board navigation, cut into the side rings -----------------------
     Same wood, same cut, same sampling as the stamp tray — engraveVars()
     writes --rub-cut / --rub-lip / --rub-floor / --rub-ink onto each host
     from the ring it actually sits on, so a left ring and a right ring that
     are different browns get different engravings. Nothing here paints a
     panel: the frame shows through, which is what keeps it aligned when the
     frame texture changes. */
  .nav-ring {
    position: fixed;
    transform: translate(-50%, -50%);
    display: flex; flex-direction: column; align-items: center; gap: 5px;
    z-index: 20;
    --rub-cut: rgba(0,0,0,0.42);
    --rub-lip: rgba(255,255,255,0.5);
    --rub-floor: rgba(0,0,0,0.16);
    --rub-ink: rgba(0,0,0,0.8);
    --nav-w: 20px;
  }
  .nav-ring[hidden] { display: none; }
  .nav-ring.rub-noframe {
    padding: 4px; border-radius: 11px;
    background: var(--panel, rgba(255,255,255,0.86));
    border: 1px solid var(--border, rgba(0,0,0,0.1));
  }
  .nav-btn {
    width: var(--nav-w); height: calc(var(--nav-w) + 8px);
    padding: 0; border: 0; border-radius: 6px;
    background: var(--rub-floor); color: var(--rub-ink);
    cursor: pointer; position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    box-shadow: inset 1.5px 1.5px 2.5px var(--rub-cut),
                inset -1px -1px 1.5px var(--rub-lip),
                0 1px 0 var(--rub-lip);
    transition: filter 0.12s var(--ease, ease), box-shadow 0.12s var(--ease, ease);
  }
  .nav-btn svg { width: 68%; height: 68%; display: block; }
  /* The target grows OUTWARD, into the margin beside the board, never inward
     over the writing surface — the same rule the stamp tray follows. */
  .nav-btn::after {
    content: ""; position: absolute; top: 0; bottom: 0;
    left: -22px; right: -3px;
  }
  #nav-right .nav-btn::after { left: -3px; right: -22px; }
  .nav-btn:hover:not(:disabled) { filter: brightness(1.15); }
  .nav-btn:active:not(:disabled) {
    box-shadow: inset 2px 2px 4px var(--rub-cut), inset -1px -1px 1px var(--rub-lip);
    filter: brightness(0.94);
  }
  .nav-btn:focus-visible { outline: 2px solid var(--accent, #6c5ce7); outline-offset: 2px; }
  /* Greyed, not gone: a button that disappears at the first and last board is
     one you cannot learn the position of. */
  .nav-btn:disabled { opacity: 0.32; cursor: default; }
  body.player-mode .nav-ring, body.exporting .nav-ring { display: none; }
  /* Too thin to cut into — and the deck strip is already within thumb reach
     at that size. Keyed on the ring, not on the viewport, for the same reason
     as the tray above. */
  body.frame-thin .nav-ring { display: none !important; }


/* ---- live session heartbeat on the Collab button ----------------------
   Two quick beats then a rest, like a pulse: a ring that swells out of the
   button and fades. Green while live, amber while a student's link is
   reconnecting. Reduced-motion devices get a steady ring instead. */
body.collab-live #collab-btn { position: relative; }
body.collab-live #collab-btn::before {
  content: ""; position: absolute; inset: -2px; border-radius: inherit; pointer-events: none;
  box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.75);
  animation: collab-heartbeat 1.6s ease-out infinite;
}
body.collab-live.collab-weak #collab-btn::before { animation-name: collab-heartbeat-weak; }
@keyframes collab-heartbeat {
  0%   { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.75); }
  14%  { box-shadow: 0 0 0 7px rgba(34, 197, 94, 0); }
  28%  { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.6); }
  42%  { box-shadow: 0 0 0 8px rgba(34, 197, 94, 0); }
  100% { box-shadow: 0 0 0 8px rgba(34, 197, 94, 0); }
}
@keyframes collab-heartbeat-weak {
  0%   { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.8); }
  30%  { box-shadow: 0 0 0 8px rgba(245, 158, 11, 0); }
  100% { box-shadow: 0 0 0 8px rgba(245, 158, 11, 0); }
}
/* A live dot inside the button, beating with the ring. */
body.collab-live #collab-btn .lbl::before {
  content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: #22c55e; margin-right: 6px; vertical-align: 1px;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.85);
  animation: collab-dot 1.6s ease-in-out infinite;
}
body.collab-live.collab-weak #collab-btn .lbl::before { background: #f59e0b; }
@keyframes collab-dot { 0%, 28% { transform: scale(1); } 7%, 35% { transform: scale(1.35); } 50%, 100% { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) {
  body.collab-live #collab-btn::before { animation: none; box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.55); }
  body.collab-live.collab-weak #collab-btn::before { box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.6); }
  body.collab-live #collab-btn .lbl::before { animation: none; }
}
/* Waiting students (and questions) while the panel is closed. */
#collab-btn[data-count] { position: relative; }
#collab-btn[data-count]::after {
  content: attr(data-count); position: absolute; top: -6px; right: -6px;
  min-width: 18px; height: 18px; padding: 0 5px; box-sizing: border-box; border-radius: 9px;
  background: #c43439; color: #fff; font: 700 11px/18px var(--font, system-ui); text-align: center;
  box-shadow: 0 0 0 2px var(--surface-solid, #fff); pointer-events: none;
}


/* ---- Ask a Question ------------------------------------------------- */
body.aq-placing #board { cursor: crosshair; }
.aq-banner {
  position: fixed; left: 50%; top: calc(var(--board-top, 84px) + 14px); transform: translateX(-50%);
  z-index: 60; display: flex; align-items: center; gap: 12px;
  padding: 9px 10px 9px 16px; border-radius: 999px;
  background: #1f2433; color: #fff; font: 600 13.5px/1.2 var(--font, system-ui);
  box-shadow: 0 6px 22px rgba(0,0,0,0.28);
}
.aq-banner .aq-x { appearance: none; border: 0; border-radius: 999px; padding: 6px 12px; cursor: pointer;
  background: rgba(255,255,255,0.16); color: #fff; font: 700 12.5px/1 var(--font, system-ui); }
.aq-banner .aq-x:hover { background: rgba(255,255,255,0.26); }
.aq-card {
  position: fixed; z-index: 61; width: min(320px, calc(100vw - 24px)); box-sizing: border-box;
  padding: 14px; border-radius: 14px; background: var(--surface-solid, #fff); color: var(--text, #1d2433);
  border: 1px solid var(--border-strong, rgba(0,0,0,0.14)); box-shadow: 0 12px 34px rgba(0,0,0,0.28);
  display: grid; gap: 10px;
}
.aq-card[hidden], .aq-banner[hidden] { display: none !important; }
.aq-card-title { font: 700 14px/1.3 var(--font, system-ui); }
.aq-card-title .aq-opt { font-weight: 500; font-size: 12px; color: var(--text-soft, #556); margin-left: 4px; }
.aq-reasons { display: flex; flex-wrap: wrap; gap: 6px; }
.aq-reasons button { appearance: none; cursor: pointer; padding: 7px 10px; border-radius: 999px;
  border: 1px solid var(--border-strong, rgba(0,0,0,0.18)); background: transparent; color: inherit;
  font: 600 12.5px/1 var(--font, system-ui); }
.aq-reasons button.sel { background: var(--accent, #6c5ce7); border-color: transparent; color: #fff; }
.aq-card-row { display: flex; gap: 8px; align-items: stretch; }
.aq-card-row .collab-btn-primary { margin: 0; flex: 1; }
/* queue and the student's own list */
.aq-count { font-weight: 600; text-transform: none; letter-spacing: 0; color: #92400e; }
.aq-item { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.aq-item .aq-body { display: grid; flex: 1 1 120px; min-width: 0; }
.aq-item .aq-meta { font-size: 12px; color: var(--cp-muted, #667); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aq-st { font: 700 10.5px/1 var(--font, system-ui); letter-spacing: .03em; text-transform: uppercase;
  padding: 3px 6px; border-radius: 5px; border: 1px solid currentColor; }
.aq-item.st-pending .aq-st { color: #92400e; }
.aq-item.st-seen .aq-st { color: #1d4ed8; }
.aq-item.st-sending .aq-st { color: var(--cp-muted, #667); }
.aq-item.st-resolved { opacity: 0.6; }
.aq-item.st-resolved .aq-st { color: #15803d; }
.aq-mine { margin-top: 10px; }
/* Dark panel: the light-theme amber/blue/green are too dim on it. */
[data-theme="dark"] .aq-count, [data-theme="dark"] .aq-item.st-pending .aq-st { color: #fbbf24; }
[data-theme="dark"] .aq-item.st-seen .aq-st { color: #93c5fd; }
[data-theme="dark"] .aq-item.st-resolved .aq-st { color: #86efac; }

/* ---- Spot question -------------------------------------------------- */
.sq-sheet, .sq-gal { position: fixed; inset: 0; z-index: 70; display: flex; align-items: center; justify-content: center;
  background: rgba(15,18,26,0.45); padding: 12px; box-sizing: border-box; }
.sq-sheet[hidden], .sq-gal[hidden], .sq-card[hidden], .sq-pill[hidden], .sq-view[hidden], .sq-grid[hidden],
.sq-markbar[hidden], .sq-mark-view[hidden], .sq-pad-wrap[hidden], .sq-tools[hidden], .sq-text[hidden], .sq-tabs[hidden],
.sq-observe[hidden], .sq-timer[hidden], .sq-stop[hidden], .sq-typed-ans[hidden], #rgn-collect-row[hidden], #sq-lesson-open[hidden] { display: none !important; }
.sq-sheet-box, .sq-gal-box, .sq-card {
  background: var(--surface-solid, #fff); color: var(--text, #1d2433);
  border: 1px solid var(--border-strong, rgba(0,0,0,0.14)); border-radius: 16px; box-shadow: 0 18px 50px rgba(0,0,0,0.32);
  font: 500 14px/1.4 var(--font, system-ui); box-sizing: border-box; }
.sq-sheet-box { width: min(460px, 100%); max-height: calc(100vh - 24px); overflow: auto; padding: 16px; display: grid; gap: 12px; }
.sq-sheet-head, .sq-card-head { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 15px; }
.sq-sheet-head span, .sq-card-title { flex: 1; min-width: 0; }
.sq-x { appearance: none; border: 0; background: transparent; color: inherit; font: 700 22px/1 var(--font, system-ui);
  width: 36px; height: 36px; border-radius: 10px; cursor: pointer; }
.sq-x:hover { background: rgba(127,127,127,0.16); }
.sq-ask-prev { border: 1px solid var(--border-strong, rgba(0,0,0,0.14)); border-radius: 10px; background: #fff; min-height: 70px;
  display: flex; align-items: center; justify-content: center; overflow: hidden; }
.sq-ask-prev img { display: block; max-width: 100%; max-height: 220px; }
.sq-ask-prev span { color: #4b5563; padding: 14px; text-align: center; font-size: 13px; }
.sq-field { display: grid; gap: 4px; font-weight: 600; font-size: 13px; }
.sq-field input, .sq-field select, #sq-note { font: 500 14px/1.3 var(--font, system-ui); padding: 9px 10px; border-radius: 9px;
  border: 1px solid var(--border-strong, rgba(0,0,0,0.2)); background: var(--surface-solid, #fff); color: inherit; min-width: 0; }
.sq-inline { display: flex; align-items: center; gap: 10px; }
.sq-opts { display: grid; gap: 8px; }
.sq-check { display: flex; align-items: center; gap: 8px; font-size: 13.5px; cursor: pointer; }
.sq-check input { width: 18px; height: 18px; margin: 0; accent-color: var(--accent, #6c5ce7); }
.sq-check em { color: var(--text-soft, #4b5563); font-style: normal; }
.sq-row, .sq-mark-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.sq-row .collab-btn-primary, .sq-mark-row .collab-btn-primary, .sq-view-bar .collab-btn-primary, .sq-tools .collab-btn-primary { width: auto; margin: 0; padding: 10px 16px; }
.sq-row .collab-btn-primary { flex: 1; }
.sq-grow { flex: 1; }
/* presenter pill */
.sq-pill { position: fixed; z-index: 58; left: 50%; transform: translateX(-50%); bottom: 18px;
  appearance: none; border: 0; cursor: pointer; border-radius: 999px; padding: 10px 16px;
  background: #1f2433; color: #fff; font: 500 13.5px/1.2 var(--font, system-ui); box-shadow: 0 8px 24px rgba(0,0,0,0.3); }
.sq-pill b { font-weight: 700; margin-right: 4px; }
.sq-pill:hover { background: #2b3245; }
/* gallery */
.sq-gal-box { width: min(1180px, 100%); height: min(860px, calc(100vh - 24px)); display: flex; flex-direction: column; overflow: hidden; }
.sq-gal-head { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-bottom: 1px solid var(--border-strong, rgba(0,0,0,0.12)); flex-wrap: wrap; }
.sq-gal-title { flex: 1; min-width: 180px; display: grid; }
.sq-gal-title b { font-size: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sq-gal-title span { color: var(--text-soft, #4b5563); font-size: 13px; }
.sq-gal-acts { display: flex; gap: 8px; align-items: center; }
.sq-gal-acts .collab-btn-danger { width: auto; margin: 0; padding: 9px 14px; }
.sq-grid { flex: 1; overflow: auto; padding: 14px; display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); align-content: start; }
.sq-empty { color: var(--text-soft, #4b5563); }
.sq-gcard { appearance: none; text-align: left; cursor: pointer; display: grid; gap: 6px; padding: 8px; border-radius: 12px;
  border: 1px solid var(--border-strong, rgba(0,0,0,0.14)); background: transparent; color: inherit; font: inherit; align-content: start; }
.sq-gcard:hover { border-color: var(--accent, #6c5ce7); }
.sq-gcard canvas { width: 100%; height: auto; max-height: 260px; object-fit: contain; object-position: top; background: #fff; border-radius: 7px; border: 1px solid #e3e6ec; }
.sq-gcard.empty canvas { display: none; }
.sq-gcard.empty { min-height: 80px; opacity: 0.8; }
.sq-gname { font-weight: 700; }
.sq-state { font: 700 10.5px/1 var(--font, system-ui); letter-spacing: .03em; text-transform: uppercase; justify-self: start;
  padding: 3px 6px; border-radius: 5px; border: 1px solid currentColor; color: var(--text-soft, #4b5563); }
.sq-state.st-in { color: #15803d; }
.sq-state.st-working { color: #92400e; }
.sq-state.marked { color: #1d4ed8; }
.sq-view-bar .sq-state { text-transform: none; letter-spacing: 0; font-size: 12px; border: 0; padding: 0; }
[data-theme="dark"] .sq-state.st-in { color: #86efac; }
[data-theme="dark"] .sq-state.st-working { color: #fbbf24; }
[data-theme="dark"] .sq-state.marked { color: #93c5fd; }
.sq-view { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.sq-view-bar { display: flex; align-items: center; gap: 8px; padding: 10px 14px; flex-wrap: wrap; border-bottom: 1px solid var(--border-strong, rgba(0,0,0,0.1)); }
.sq-view-bar b { font-size: 15px; }
.sq-view-body { flex: 1; overflow: auto; padding: 12px; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.sq-view-body canvas { background: #fff; border-radius: 8px; border: 1px solid #e3e6ec; touch-action: none; flex: none; }
.sq-typed-ans { margin: 0; max-width: 900px; width: 100%; padding: 10px 12px; border-radius: 9px; background: rgba(127,127,127,0.12); }
.sq-markbar { border-top: 1px solid var(--border-strong, rgba(0,0,0,0.12)); padding: 10px 14px; display: grid; gap: 8px; }
.sq-markbar #sq-note { flex: 1; min-width: 160px; }
.sq-lbl { font-weight: 700; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-soft, #4b5563); min-width: 52px; }
.sq-hint { font-size: 12.5px; color: var(--text-soft, #4b5563); }
.sq-verdict { appearance: none; cursor: pointer; width: 40px; height: 36px; border-radius: 9px; font: 800 20px/1 var(--font, system-ui);
  border: 1px solid var(--border-strong, rgba(0,0,0,0.2)); background: transparent; color: inherit; }
.sq-verdict[data-v="tick"].on { background: #16a34a; color: #fff; border-color: transparent; }
.sq-verdict[data-v="cross"].on { background: #dc2626; color: #fff; border-color: transparent; }
.sq-verdict[data-v="star"].on { background: #b45309; color: #fff; border-color: transparent; }
.sq-reward { appearance: none; cursor: pointer; padding: 7px 11px; border-radius: 999px; font: 600 12.5px/1 var(--font, system-ui);
  border: 1px solid var(--border-strong, rgba(0,0,0,0.18)); background: transparent; color: inherit; }
.sq-reward.on { background: var(--accent, #6c5ce7); color: #fff; border-color: transparent; }
/* student card */
.sq-card { position: fixed; z-index: 62; right: 12px; top: calc(var(--board-top, 84px) + 8px); bottom: 12px;
  width: min(560px, calc(100vw - 24px)); display: flex; flex-direction: column; gap: 8px; padding: 12px; }
.sq-card-title span { font-weight: 500; color: var(--text-soft, #4b5563); }
.sq-timer { font: 700 14px/1 var(--font, system-ui); padding: 6px 9px; border-radius: 8px; background: rgba(127,127,127,0.14); font-variant-numeric: tabular-nums; }
.sq-timer.low { background: #b91c1c; color: #fff; }
.sq-observe { margin: 0; font-size: 12.5px; color: var(--text-soft, #4b5563); }
.sq-tabs { display: flex; gap: 6px; }
.sq-tab { appearance: none; cursor: pointer; padding: 7px 12px; border-radius: 999px; font: 600 13px/1 var(--font, system-ui);
  border: 1px solid var(--border-strong, rgba(0,0,0,0.18)); background: transparent; color: inherit; }
.sq-tab.on { background: var(--accent, #6c5ce7); color: #fff; border-color: transparent; }
.sq-pad-wrap, .sq-mark-view { flex: 1; min-height: 120px; overflow: auto; border-radius: 10px; border: 1px solid #d6dae2; background: #fff; overscroll-behavior: contain; }
.sq-pad-wrap canvas { display: block; touch-action: none; cursor: crosshair; }
.sq-card.locked .sq-pad-wrap canvas { cursor: default; }
.sq-mark-view canvas { display: block; }
.sq-mark-note { padding: 8px 12px; color: #1b2230; font-weight: 600; }
.sq-mark-note:empty { display: none; }
.sq-mark-view.sq-anim { animation: sq-markpop .5s ease-out; }
@keyframes sq-markpop { 0% { transform: scale(.96); opacity: .4; } 60% { transform: scale(1.02); opacity: 1; } 100% { transform: none; } }
@media (prefers-reduced-motion: reduce) { .sq-mark-view.sq-anim { animation: none; } }
.sq-text { font: 500 14px/1.35 var(--font, system-ui); padding: 8px 10px; border-radius: 9px; resize: vertical;
  border: 1px solid var(--border-strong, rgba(0,0,0,0.2)); background: var(--surface-solid, #fff); color: inherit; }
.sq-tools { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.sq-dots, .sq-sizes { display: flex; gap: 4px; }
.sq-dot { appearance: none; cursor: pointer; width: 26px; height: 26px; border-radius: 50%; border: 2px solid transparent; box-shadow: 0 0 0 1px rgba(0,0,0,0.2) inset; }
.sq-dot.on { border-color: var(--text, #1d2433); box-shadow: 0 0 0 2px var(--surface-solid, #fff) inset; }
.sq-size, .sq-tool { appearance: none; cursor: pointer; min-width: 32px; height: 32px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-strong, rgba(0,0,0,0.18)); background: transparent; color: inherit; font: 600 15px/1 var(--font, system-ui); padding: 0 6px; }
.sq-size i { display: block; border-radius: 50%; background: currentColor; }
.sq-size.on, .sq-tool.on { background: var(--accent, #6c5ce7); color: #fff; border-color: transparent; }
.sq-tool:disabled { opacity: .4; cursor: default; }
.sq-tool.sq-wide { font-size: 13px; padding: 0 10px; }
.sq-status { font-size: 12.5px; color: var(--text-soft, #4b5563); }
.sq-handin:disabled { opacity: .5; cursor: default; }
.sq-card.locked .sq-tools .sq-dot, .sq-card.locked .sq-tools .sq-size, .sq-card.locked .sq-tools .sq-tool { pointer-events: none; opacity: .4; }
.sq-pill-student { background: var(--accent, #6c5ce7); }
.sq-pill-student:hover { background: #5d4fc7; }
@media (max-width: 640px) {
  .sq-card { left: 8px; right: 8px; width: auto; top: calc(var(--board-top, 84px) + 4px); bottom: 8px; }
  .sq-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
}

/* ---- Break time ------------------------------------------------------ */
#brk-screen { position: fixed; inset: 0; z-index: 140; display: flex; align-items: center; justify-content: center;
  background: #172234; color: #fff; touch-action: none; user-select: none; -webkit-user-select: none; }
#brk-screen[hidden], .brk-pill[hidden], #brk-live[hidden], #brk-setup[hidden] { display: none !important; }
#brk-screen.in { animation: brk-in .45s ease-out both; }
#brk-screen.out { animation: brk-out .45s ease-in both; }
@keyframes brk-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes brk-out { from { opacity: 1; } to { opacity: 0; } }
#brk-cv { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.brk-card { position: relative; text-align: center; padding: 28px 40px 26px; border-radius: 28px; max-width: min(560px, calc(100vw - 32px));
  box-sizing: border-box; background: rgba(10, 16, 30, 0.38); border: 1px solid rgba(255,255,255,0.14);
  box-shadow: 0 20px 60px rgba(0,0,0,0.35); font-family: var(--font, system-ui); }
@supports ((-webkit-backdrop-filter: blur(4px)) or (backdrop-filter: blur(4px))) {
  .brk-card { -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
}
.brk-title { font-weight: 700; font-size: clamp(20px, 3.4vw, 30px); letter-spacing: .01em; opacity: .95; }
.brk-time { font-weight: 800; font-size: clamp(64px, 15vw, 150px); line-height: 1.02; margin: 6px 0 12px;
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em; text-shadow: 0 4px 24px rgba(0,0,0,0.35); }
.brk-ring { height: 6px; border-radius: 999px; background: rgba(255,255,255,0.16); overflow: hidden; margin: 0 auto 14px; width: min(320px, 70vw); }
.brk-ring i { display: block; height: 100%; width: 100%; border-radius: inherit; background: linear-gradient(90deg, #7dd3fc, #c4b5fd); transition: width .25s linear; }
.brk-sub { font-size: clamp(14px, 2vw, 17px); color: #e2e8f0; line-height: 1.4; }
@media (prefers-reduced-motion: reduce) { #brk-screen.in, #brk-screen.out { animation: none; } .brk-ring i { transition: none; } }
/* the teacher's reminder */
.brk-pill { position: fixed; z-index: 59; left: 50%; transform: translateX(-50%); bottom: 18px; display: flex; align-items: center; gap: 8px;
  padding: 6px 6px 6px 14px; border-radius: 999px; background: #1f2433; color: #fff; font: 500 13.5px/1.2 var(--font, system-ui);
  box-shadow: 0 8px 24px rgba(0,0,0,0.3); }
.brk-pill b { font-variant-numeric: tabular-nums; margin-left: 2px; }
.brk-pill button { appearance: none; border: 0; cursor: pointer; border-radius: 999px; padding: 7px 12px; font: 700 12.5px/1 var(--font, system-ui);
  background: rgba(255,255,255,0.14); color: #fff; }
.brk-pill button:hover { background: rgba(255,255,255,0.24); }
.brk-pill #brk-pill-end { background: #c43439; }
.brk-pill #brk-pill-end:hover { background: #a92b30; }
select.collab-input.brk-len { width: auto; flex: 0 0 auto; margin: 0; padding-right: 8px; }
.brk-left { flex: 1; font-weight: 700; font-variant-numeric: tabular-nums; }
body.brk-live .sq-pill { bottom: 70px; }             /* both running: stack, never overlap */

/* ---- More colours (palettes) and pick-from-board ------------------------ */
.sb-colbtn { appearance: none; width: 26px; height: 26px; border-radius: 50%; padding: 0; cursor: pointer; flex: none;
  display: inline-flex; align-items: center; justify-content: center; margin-left: 4px;
  border: 1.5px solid var(--border-strong); background: transparent; color: var(--text); }
.sb-colbtn svg { width: 14px; height: 14px; }
.sb-colbtn:hover { background: var(--hover); }
.sb-colbtn.on, .sb-colbtn[aria-expanded="true"] { background: var(--accent, #6c5ce7); border-color: transparent; color: #fff; }
/* REPORTED: "the icon changes for every menu item it passes over". While the
   dropper is on, every element shows the same eyedropper; its tip (bottom
   left, marked red) is the exact pixel taken. */
body.picking-colour, body.picking-colour * { cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M2.5 21.5l1.2-3.6 9.4-9.4 2.4 2.4-9.4 9.4z' fill='white' stroke='black' stroke-width='1.3' stroke-linejoin='round'/%3E%3Cpath d='M14.2 6.6l2-2a2.3 2.3 0 0 1 3.2 3.2l-2 2 .9.9-1.5 1.5-5.6-5.6 1.5-1.5z' fill='black'/%3E%3Ccircle cx='2.2' cy='21.8' r='1.1' fill='%23ff2d55' stroke='white' stroke-width='.6'/%3E%3C/svg%3E") 2 22, crosshair !important; }
#drop-loupe { position: fixed; z-index: 160; pointer-events: none; padding: 6px; border-radius: 12px;
  background: #111827; box-shadow: 0 8px 24px rgba(0,0,0,0.35); border: 1px solid rgba(255,255,255,0.15); }
#drop-loupe[hidden] { display: none !important; }
#drop-loupe-cv { display: block; width: 110px; height: 110px; border-radius: 8px; image-rendering: pixelated; }
.drop-loupe-row { display: flex; align-items: center; gap: 6px; margin-top: 6px; color: #fff; font: 700 12px/1 ui-monospace, Consolas, monospace; }
.drop-loupe-row i { width: 16px; height: 16px; border-radius: 4px; border: 1px solid rgba(255,255,255,0.6); display: inline-block; }
#pal-pop { padding: 10px 10px 8px; min-width: 240px; }
.pal-head { font-weight: 700; font-size: 12px; margin: 0 4px 8px; color: var(--text); }
.pal-head span { display: block; font-weight: 500; font-size: 11px; color: var(--muted, #667); margin-top: 2px; }
.pal-list { display: block; }
.pal-row { display: grid; grid-template-columns: 74px repeat(6, 24px) 20px; gap: 6px; align-items: center; padding: 3px 4px; border-radius: 9px; height: 30px; box-sizing: content-box; }
.pal-row.active { background: var(--hover); box-shadow: inset 0 0 0 1.5px var(--accent, #6c5ce7); }
.pal-name { appearance: none; border: 0; background: transparent; color: var(--text); font: 600 12px/1.2 var(--font, system-ui);
  text-align: left; cursor: pointer; padding: 4px 2px; border-radius: 6px; }
.pal-name:hover { text-decoration: underline; }
.pal-chip { appearance: none; width: 24px; height: 24px; border-radius: 50%; padding: 0; cursor: pointer;
  border: 2px solid var(--border-strong); transition: transform .15s; }
.pal-chip:hover { transform: scale(1.15); }
.pal-chip.active { box-shadow: 0 0 0 2px var(--surface-solid, #fff), 0 0 0 4px var(--accent, #6c5ce7); border-color: transparent; }

/* Spot question: drawing the region, and the student's own list */
body.sq-regioning #board { cursor: crosshair; }
#sq-region-box { position: fixed; z-index: 57; pointer-events: none; border: 2px dashed var(--accent, #6c5ce7);
  background: rgba(108, 92, 231, 0.10); border-radius: 4px; }
#sq-region-box[hidden], #sq-region-banner[hidden], #sq-mine-wrap[hidden] { display: none !important; }
.sq-mine { display: grid; gap: 4px; }
.sq-mine-open { appearance: none; width: 100%; text-align: left; cursor: pointer; display: grid; gap: 2px; position: relative;
  padding: 8px 26px 8px 10px; border-radius: 9px; border: 1px solid var(--cp-line, rgba(0,0,0,0.12)); background: transparent; color: inherit;
  font: 500 13px/1.3 var(--font, system-ui); }
.sq-mine-open:hover { background: var(--hover); }
.sq-mine-q { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sq-mine-st { font-size: 12px; color: var(--cp-muted, #556); }
.sq-mine-dot { position: absolute; right: 10px; top: 50%; width: 9px; height: 9px; margin-top: -4.5px; border-radius: 50%; background: #c43439; }
.sq-mine-item { list-style: none; }

/* The Spot question buttons on one line in the presenter panel */
#sq-wrap .collab-photorow { flex-wrap: nowrap; gap: 6px; }
#sq-wrap .collab-photorow .collab-chip { flex: 1 1 0; min-width: 0; white-space: nowrap; padding-left: 8px; padding-right: 8px; justify-content: center; text-align: center; }

/* ---- Random Pick ---------------------------------------------------- */
#rp-screen { --rp-ink: #f8fafc; --rp-soft: #cbd5e1; --rp-card: rgba(10, 16, 30, 0.42); --rp-line: rgba(255,255,255,0.16);
  --rp-band: rgba(255,255,255,0.10); --rp-accent: #ffd166; --rp-btn: rgba(255,255,255,0.12); --rp-btn-ink: #fff;
  position: fixed; inset: 0; z-index: 135; color: var(--rp-ink); font-family: var(--font, system-ui); background: #172234;
  display: grid; grid-template-rows: auto 1fr; overflow: hidden; touch-action: manipulation; }
#rp-screen.rp-light { --rp-ink: #1b2230; --rp-soft: #475569; --rp-card: rgba(255,255,255,0.62); --rp-line: rgba(27,34,48,0.14);
  --rp-band: rgba(108,92,231,0.10); --rp-accent: #6c5ce7; --rp-btn: rgba(27,34,48,0.07); --rp-btn-ink: #1b2230; background: #eef2ff; }
#rp-screen[hidden], #rp-screen [hidden] { display: none !important; }
#rp-screen.in { animation: brk-in .4s ease-out both; }
#rp-screen.out { animation: brk-out .4s ease-in both; }
#rp-cv, #rp-fx { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
#rp-fx { pointer-events: none; z-index: 3; }
.rp-top { position: relative; z-index: 2; display: flex; align-items: center; gap: 12px; padding: 16px clamp(14px, 3vw, 28px); }
.rp-titles { flex: 1; min-width: 0; }
.rp-titles h2 { margin: 0; font-size: clamp(20px, 2.6vw, 28px); font-weight: 800; letter-spacing: -0.01em; }
.rp-titles p { margin: 2px 0 0; color: var(--rp-soft); font-size: clamp(13px, 1.6vw, 16px); }
.rp-count { font-weight: 700; font-size: 14px; padding: 7px 12px; border-radius: 999px; background: var(--rp-btn); border: 1px solid var(--rp-line); white-space: nowrap; font-variant-numeric: tabular-nums; }
.rp-icon, .rp-exit, .rp-btn { appearance: none; cursor: pointer; border: 1px solid var(--rp-line); background: var(--rp-btn); color: var(--rp-btn-ink);
  border-radius: 999px; font: 700 14px/1 var(--font, system-ui); padding: 10px 16px; }
.rp-icon { width: 42px; height: 42px; padding: 0; font-size: 20px; }
.rp-icon[aria-expanded="true"] { background: var(--rp-accent); color: #1b2230; border-color: transparent; }
.rp-icon:hover, .rp-exit:hover, .rp-btn:hover:not(:disabled) { filter: brightness(1.15); }
.rp-btn:disabled { opacity: .45; cursor: default; }
.rp-btn.rp-hot { background: var(--rp-accent); color: #1b2230; border-color: transparent; }
.rp-stage { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(14px, 3vh, 28px); padding: 0 16px 6vh; min-height: 0; }
.rp-reel { --rp-row: clamp(52px, 10vh, 104px); position: relative; width: min(760px, 92vw); height: calc(var(--rp-row) * 5); overflow: hidden; border-radius: 26px;
  background: var(--rp-card); border: 1px solid var(--rp-line); box-shadow: 0 24px 70px rgba(0,0,0,0.30);
  -webkit-mask-image: linear-gradient(transparent, #000 22%, #000 78%, transparent); mask-image: linear-gradient(transparent, #000 22%, #000 78%, transparent); }
@supports ((-webkit-backdrop-filter: blur(4px)) or (backdrop-filter: blur(4px))) { .rp-reel, .rp-panel, .rp-result { -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); } }
.rp-track { will-change: transform; position: relative; z-index: 1; }
.rp-row { height: var(--rp-row); display: flex; align-items: center; justify-content: center; padding: 0 24px; box-sizing: border-box;
  font-weight: 800; font-size: clamp(26px, 5.4vh, 54px); letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--rp-soft); }
.rp-row.rp-mid { color: var(--rp-ink); opacity: .5; }
.rp-row.rp-hit { color: var(--rp-ink); animation: rp-hit .5s ease-out both; }
@keyframes rp-hit { 0% { transform: scale(1); } 45% { transform: scale(1.12); text-shadow: 0 0 28px var(--rp-accent); } 100% { transform: scale(1.06); text-shadow: 0 0 18px var(--rp-accent); } }
.rp-window { position: absolute; z-index: 0; left: 10px; right: 10px; top: calc(var(--rp-row) * 2); height: var(--rp-row); border-radius: 18px; pointer-events: none;
  background: var(--rp-band); box-shadow: inset 0 0 0 2px var(--rp-accent), 0 0 34px -6px var(--rp-accent); }
.rp-result { text-align: center; padding: clamp(20px, 4vh, 40px) clamp(24px, 5vw, 64px); border-radius: 30px; max-width: min(900px, 94vw); box-sizing: border-box;
  background: var(--rp-card); border: 1px solid var(--rp-line); box-shadow: 0 0 0 1px var(--rp-line), 0 30px 90px -10px rgba(0,0,0,0.35), 0 0 120px -30px var(--rp-accent); }
.rp-result.rp-pop { animation: rp-pop .6s cubic-bezier(.2,1.4,.4,1) both; }
@keyframes rp-pop { from { opacity: 0; transform: scale(.82) translateY(10px); } to { opacity: 1; transform: none; } }
.rp-up { font-weight: 700; font-size: clamp(16px, 2.4vh, 22px); color: var(--rp-soft); letter-spacing: .02em; }
.rp-name { font-weight: 900; font-size: clamp(48px, 11vh, 120px); line-height: 1.05; margin: 6px 0 4px; letter-spacing: -0.02em; overflow-wrap: anywhere;
  background: linear-gradient(90deg, #ffd166, #ff8fab, #9b8cff, #4cc9f0); -webkit-background-clip: text; background-clip: text; color: transparent; }
#rp-screen.rp-light .rp-name { background: linear-gradient(90deg, #c2410c, #be185d, #6c5ce7, #0369a1); -webkit-background-clip: text; background-clip: text; }
.rp-you { display: inline-block; margin: 6px 0 2px; padding: 6px 14px; border-radius: 999px; background: var(--rp-accent); color: #1b2230; font-weight: 800; font-size: clamp(14px, 2vh, 18px); }
.rp-prompt { margin-top: 12px; font-size: clamp(18px, 3vh, 28px); font-weight: 600; line-height: 1.3; }
.rp-msg { margin: 0; min-height: 1.3em; color: var(--rp-soft); font-weight: 600; font-size: clamp(14px, 2vh, 18px); text-align: center; }
.rp-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: center; }
.rp-spin { appearance: none; border: 0; cursor: pointer; border-radius: 999px; padding: clamp(14px, 2.2vh, 20px) clamp(42px, 6vw, 72px);
  font: 900 clamp(20px, 3vh, 28px)/1 var(--font, system-ui); letter-spacing: .02em; color: #1b2230;
  background: linear-gradient(180deg, #ffe08a, #ffc14d); box-shadow: 0 10px 30px -6px rgba(255,193,77,0.65), inset 0 -3px 0 rgba(0,0,0,0.12); transition: transform .12s; }
#rp-screen.rp-light .rp-spin { color: #fff; background: linear-gradient(180deg, #8b7cf6, #6c5ce7); box-shadow: 0 10px 30px -6px rgba(108,92,231,0.6), inset 0 -3px 0 rgba(0,0,0,0.15); }
.rp-spin:hover:not(:disabled) { transform: translateY(-1px) scale(1.03); }
.rp-spin:active:not(:disabled) { transform: scale(.97); }
.rp-spin:disabled { opacity: .5; cursor: default; box-shadow: none; }
.rp-spin:focus-visible, .rp-btn:focus-visible, .rp-exit:focus-visible, .rp-icon:focus-visible { outline: 3px solid var(--rp-accent); outline-offset: 3px; }
.rp-wait { margin: 0; color: var(--rp-soft); font-weight: 600; }
.rp-panel { position: absolute; z-index: 4; right: clamp(12px, 2.5vw, 24px); top: 78px; width: min(320px, calc(100vw - 24px)); max-height: calc(100% - 96px); overflow: auto;
  box-sizing: border-box; padding: 14px; border-radius: 18px; background: var(--rp-card); border: 1px solid var(--rp-line); box-shadow: 0 18px 50px rgba(0,0,0,0.3);
  display: grid; gap: 10px; color: var(--rp-ink); }
.rp-panel-h { font-weight: 700; font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--rp-soft); }
.rp-panel-h em { text-transform: none; font-style: normal; letter-spacing: 0; }
.rp-seg { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 3px; border-radius: 12px; background: var(--rp-btn); }
.rp-seg button { appearance: none; border: 0; cursor: pointer; border-radius: 9px; padding: 9px 6px; font: 700 13px/1.1 var(--font, system-ui); background: transparent; color: var(--rp-ink); }
.rp-seg button.on { background: var(--rp-accent); color: #1b2230; }
#rp-screen.rp-light .rp-seg button.on { color: #fff; }
#rp-list, #rp-prompt { width: 100%; box-sizing: border-box; font: 500 14px/1.4 var(--font, system-ui); padding: 9px 10px; border-radius: 10px;
  border: 1px solid var(--rp-line); background: rgba(0,0,0,0.18); color: var(--rp-ink); resize: vertical; }
#rp-screen.rp-light #rp-list, #rp-screen.rp-light #rp-prompt { background: #fff; }
.rp-note { margin: 4px 0 0; font-size: 12.5px; color: var(--rp-soft); }
.rp-check { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14px; cursor: pointer; }
.rp-check input { width: 18px; height: 18px; margin: 0; accent-color: var(--rp-accent); }
.rp-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.rp-chips button { appearance: none; cursor: pointer; border: 1px solid var(--rp-line); background: transparent; color: var(--rp-ink); border-radius: 999px; padding: 6px 10px; font: 600 12px/1.2 var(--font, system-ui); text-align: left; }
.rp-chips button:hover { background: var(--rp-btn); }
.rp-panel :disabled { opacity: .5; }
@media (max-width: 700px) {
  .rp-top { flex-wrap: wrap; }
  .rp-panel { left: 12px; right: 12px; width: auto; top: auto; bottom: 12px; max-height: 52%; }
  .rp-exit { padding: 9px 12px; }
}
@media (prefers-reduced-motion: reduce) {
  #rp-screen.in, #rp-screen.out, .rp-result.rp-pop, .rp-row.rp-hit { animation: none; }
  .rp-row.rp-hit { text-shadow: 0 0 18px var(--rp-accent); }
}
.rp-wheel-wrap { width: min(86vw, 62vh, 640px); height: min(86vw, 62vh, 640px); display: flex; align-items: center; justify-content: center; }
#rp-wheel { display: block; }
#rp-screen.rp-light .rp-you { color: #ffffff; }

/* Palettes: five rows in view at a time, the rest a scroll away (REQUESTED). */
#pal-pop .pal-list { max-height: calc(5 * 36px + 26px); overflow-y: auto; overscroll-behavior: contain; padding-right: 2px; }
#pal-pop .pal-list[hidden], #pal-pop .pal-editor[hidden], #pal-pop .pal-new[hidden] { display: none !important; }
.pal-sec { position: sticky; top: 0; z-index: 1; font: 700 10.5px/1 var(--font, system-ui); text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted, #667); padding: 7px 4px 5px; background: var(--surface-solid, #fff); }
.pal-del { appearance: none; border: 0; background: transparent; color: var(--muted, #667); cursor: pointer; font: 700 12px/1 var(--font, system-ui); padding: 4px; border-radius: 6px; }
.pal-del:hover { background: var(--hover); color: var(--text); }
.pal-new { appearance: none; width: 100%; margin-top: 8px; padding: 9px; border-radius: 9px; cursor: pointer; text-align: left;
  border: 1px dashed var(--border-strong); background: transparent; color: var(--text); font: 600 12.5px/1 var(--font, system-ui); }
.pal-new:hover:not(:disabled) { background: var(--hover); }
.pal-new:disabled { opacity: .5; cursor: default; }
.pal-editor { display: grid; gap: 8px; padding: 2px 4px; }
.pal-ed-l { font: 700 11px/1 var(--font, system-ui); text-transform: uppercase; letter-spacing: .05em; color: var(--muted, #667); }
#pal-ed-name { font: 500 13px/1.2 var(--font, system-ui); padding: 7px 9px; border-radius: 8px; border: 1px solid var(--border-strong); background: var(--surface-solid, #fff); color: var(--text); }
.pal-ed-cols { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
.pal-ed-cols input { width: 100%; height: 34px; padding: 0; border: 1px solid var(--border-strong); border-radius: 8px; background: transparent; cursor: pointer; }
.pal-ed-hint { margin: 0; font-size: 11.5px; color: var(--muted, #667); }
.pal-ed-row { display: flex; gap: 6px; }
.pal-ed-btn { appearance: none; flex: 1; padding: 8px; border-radius: 9px; cursor: pointer; border: 1px solid var(--border-strong); background: transparent; color: var(--text); font: 700 12.5px/1 var(--font, system-ui); }
.pal-ed-btn.primary { background: var(--accent, #6c5ce7); color: #fff; border-color: transparent; }

/* ---- Collab panel as a compact menu (REPORTED: too long on iPad) ---------- */
#collab-panel section.cp-ordered .collab-group { margin: 0; padding: 0; border-top: 1px solid var(--cp-line); }
#collab-panel section.cp-ordered .collab-group:last-of-type { border-bottom: 1px solid var(--cp-line); }
#collab-panel section.cp-ordered .collab-group-title.cg-toggle {
  margin: 0; padding: 11px 4px; gap: 10px; min-height: 22px; border-radius: 8px;
  font: 600 13.5px/1.2 var(--font); text-transform: none; letter-spacing: 0; color: var(--cp-text); }
#collab-panel section.cp-ordered .cg-toggle:hover { background: var(--hover); }
#collab-panel section.cp-ordered .cg-toggle::before { display: none; }
#collab-panel section.cp-ordered .cg-toggle::after { content: ""; margin-left: auto; flex: none; width: 7px; height: 7px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; opacity: .5;
  transform: rotate(45deg) translate(-2px, -2px); transition: transform .16s var(--ease); }
#collab-panel section.cp-ordered .collab-group.folded .cg-toggle::after { transform: rotate(-45deg); }
#collab-panel .cg-ic { flex: none; width: 22px; text-align: center; font-size: 15px; line-height: 1; }
#collab-panel section.cp-ordered .collab-group:not(.folded) { padding-bottom: 12px; }
#collab-panel section.cp-ordered .collab-group:not(.folded) > .cg-toggle { margin-bottom: 4px; }
#collab-panel section.cp-ordered .aq-count { margin-left: 2px; }
/* Hold view and End session share one row under the room code. */
#collab-panel section[data-view="presenter"] .cp-actions { margin: 8px 0 12px; }
#collab-panel section[data-view="presenter"] .cp-actions .collab-btn-danger { margin: 0; width: 100%; }
#collab-panel section[data-view="presenter"] > .collab-hint[hidden] { display: none; }

/* ---- Game Time (Dots and Boxes) -------------------------------------- */
#gt-screen { --gt-ink: #f8fafc; --gt-soft: #cbd5e1; --gt-card: rgba(15, 23, 42, 0.55); --gt-line: rgba(255,255,255,0.16);
  --gt-accent: #ffd166; --gt-btn: rgba(255,255,255,0.12); --gt-btn-ink: #fff; --gt-warn: #f59e0b;
  position: fixed; inset: 0; z-index: 135; color: var(--gt-ink); font-family: var(--font, system-ui);
  background: radial-gradient(1200px 700px at 20% 0%, #23324d 0%, #172234 60%, #121b2b 100%);
  display: grid; grid-template-rows: auto 1fr; overflow: hidden; touch-action: manipulation; }
#gt-screen.gt-light { --gt-ink: #1b2230; --gt-soft: #475569; --gt-card: rgba(255,255,255,0.72); --gt-line: rgba(27,34,48,0.14);
  --gt-accent: #6c5ce7; --gt-btn: rgba(27,34,48,0.07); --gt-btn-ink: #1b2230; --gt-warn: #b45309;
  background: radial-gradient(1200px 700px at 20% 0%, #ffffff 0%, #eef2ff 55%, #e6ebf7 100%); }
#gt-screen[hidden], #gt-screen [hidden] { display: none !important; }
#gt-screen.in { animation: brk-in .35s ease-out both; }
#gt-screen.out { animation: brk-out .35s ease-in both; }
#gt-fx { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 6; }
.gt-top { position: relative; z-index: 2; display: flex; align-items: center; gap: 12px; padding: 14px clamp(14px, 3vw, 28px); }
.gt-titles { flex: 0 1 auto; min-width: 0; }
.gt-titles h2 { margin: 0; font-size: clamp(19px, 2.4vw, 26px); font-weight: 800; letter-spacing: -0.01em; white-space: nowrap; }
.gt-titles p { margin: 2px 0 0; color: var(--gt-soft); font-size: 14px; }
.gt-status { flex: 1; min-width: 0; text-align: center; font-weight: 700; font-size: clamp(14px, 1.8vw, 18px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gt-exit, .gt-btn { appearance: none; cursor: pointer; border: 1px solid var(--gt-line); background: var(--gt-btn); color: var(--gt-btn-ink);
  border-radius: 999px; font: 700 14px/1 var(--font, system-ui); padding: 11px 16px; min-height: 44px; }
.gt-exit:hover, .gt-btn:hover:not(:disabled) { filter: brightness(1.15); }
.gt-btn:disabled { opacity: .45; cursor: default; }
.gt-btn.gt-warn { color: var(--gt-warn); }
.gt-go { appearance: none; border: 0; cursor: pointer; border-radius: 999px; padding: 13px 26px; min-height: 46px; font: 800 16px/1 var(--font, system-ui);
  color: #1b2230; background: linear-gradient(180deg, #ffe08a, #ffd166); box-shadow: 0 8px 24px -8px rgba(255,209,102,0.7); }
#gt-screen.gt-light .gt-go { color: #fff; background: linear-gradient(180deg, #8b7cf6, #6c5ce7); box-shadow: 0 8px 24px -8px rgba(108,92,231,0.6); }
.gt-go:disabled { opacity: .5; cursor: default; box-shadow: none; }
.gt-go:focus-visible, .gt-btn:focus-visible, .gt-exit:focus-visible, .gt-step:focus-visible, .gt-seg button:focus-visible, .gt-link:focus-visible { outline: 3px solid var(--gt-accent); outline-offset: 3px; }
.gt-body { position: relative; z-index: 2; min-height: 0; padding: 0 clamp(12px, 3vw, 28px) clamp(12px, 2.5vh, 24px); display: grid; }
.gt-note { margin: 0; font-size: 13px; color: var(--gt-soft); }
.gt-note.gt-err { color: var(--gt-warn); font-weight: 600; min-height: 1.2em; }
/* lobby */
.gt-lobby { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(280px, 380px); gap: clamp(14px, 2.5vw, 28px); align-items: start; overflow: auto; min-height: 0; }
.gt-lobby.gt-solo { grid-template-columns: minmax(0, 900px); justify-content: center; }
.gt-rules, .gt-setup { background: var(--gt-card); border: 1px solid var(--gt-line); border-radius: 22px; padding: clamp(14px, 2.4vw, 24px); }
@supports ((-webkit-backdrop-filter: blur(4px)) or (backdrop-filter: blur(4px))) { .gt-rules, .gt-setup, .gt-side, .gt-result { -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); } }
.gt-rules h3, .gt-setup h3 { margin: 0 0 12px; font-size: 18px; font-weight: 800; }
.gt-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; counter-reset: gt; }
.gt-steps li { counter-increment: gt; background: #ffffff; color: #1b2230; border-radius: 16px; padding: 12px; display: flex; flex-direction: column; gap: 4px; box-shadow: 0 6px 20px -12px rgba(0,0,0,.45); position: relative; }
.gt-steps li::before { content: counter(gt); position: absolute; top: 10px; left: 10px; width: 24px; height: 24px; border-radius: 50%; background: #6c5ce7; color: #fff; font: 800 13px/24px var(--font, system-ui); text-align: center; }
.gt-steps svg { width: 100%; max-width: 150px; aspect-ratio: 1; align-self: center; }
.gt-steps b { font-size: 15px; }
.gt-steps span { font-size: 13px; color: #475569; line-height: 1.35; }
.gt-d circle { fill: #1e293b; }
.gt-ln { fill: none; stroke: #0072B2; stroke-width: 7; stroke-linecap: round; stroke-linejoin: round; }
.gt-ln.gt-fixed { stroke: #94a3b8; }
.gt-bx { fill: rgba(0,114,178,.28); }
.gt-plus { font: 900 22px var(--font, system-ui); fill: #0072B2; text-anchor: middle; }
.gt-cup { font-size: 26px; text-anchor: middle; }
.gt-sc { font: 900 20px var(--font, system-ui); text-anchor: middle; }
.gt-hand circle { fill: rgba(108,92,231,.25); stroke: #6c5ce7; stroke-width: 3; }
.gt-a1 { stroke-dasharray: 60; animation: gt-draw1 2.8s ease-in-out infinite; }
.gt-a1h { animation: gt-hand1 2.8s ease-in-out infinite; }
.gt-a2 { stroke: #0072B2; stroke-dasharray: 60; animation: gt-draw1 3.2s ease-in-out infinite; }
.gt-a2b { animation: gt-fill 3.2s ease-in-out infinite; }
.gt-a3 { animation: gt-bob 2.4s ease-in-out infinite; transform-origin: 60px 26px; }
@keyframes gt-draw1 { 0%, 15% { stroke-dashoffset: 60; } 55%, 100% { stroke-dashoffset: 0; } }
@keyframes gt-hand1 { 0%, 15% { transform: translateX(-60px); opacity: 1; } 55% { transform: translateX(0); opacity: 1; } 75%, 100% { transform: translateX(0); opacity: 0; } }
@keyframes gt-fill { 0%, 55% { opacity: 0; } 70%, 100% { opacity: 1; } }
@keyframes gt-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
.gt-wait { margin: 14px 0 0; text-align: center; font-weight: 700; color: var(--gt-soft); }
.gt-setup { display: flex; flex-direction: column; gap: 10px; }
.gt-h { font-weight: 700; font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--gt-soft); margin-top: 4px; }
.gt-h em { text-transform: none; font-style: normal; letter-spacing: 0; }
#gt-players { display: flex; flex-direction: column; gap: 6px; max-height: 240px; overflow: auto; }
.gt-prow { display: flex; align-items: center; gap: 8px; min-height: 36px; font-weight: 600; font-size: 14px; }
.gt-prow input[type=checkbox] { width: 20px; height: 20px; margin: 0; accent-color: var(--gt-accent); }
.gt-prow input[type=text] { flex: 1; min-width: 0; }
.gt-chip { width: 22px; height: 22px; border-radius: 7px; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 12px; line-height: 1; }
.gt-chip.gt-none { background: transparent; border: 2px dashed var(--gt-line); }
#gt-screen input[type=text], #gt-screen input[type=number] { font: 600 15px var(--font, system-ui); padding: 9px 10px; border-radius: 10px; border: 1px solid var(--gt-line); background: rgba(255,255,255,0.08); color: var(--gt-ink); min-height: 40px; box-sizing: border-box; }
#gt-screen.gt-light input[type=text], #gt-screen.gt-light input[type=number] { background: #fff; }
.gt-size { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.gt-size input[type=number] { width: 56px; text-align: center; -moz-appearance: textfield; }
.gt-size input::-webkit-outer-spin-button, .gt-size input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.gt-step { appearance: none; cursor: pointer; width: 40px; height: 40px; border-radius: 10px; border: 1px solid var(--gt-line); background: var(--gt-btn); color: var(--gt-ink); font: 800 18px/1 var(--font, system-ui); }
.gt-x { padding: 0 4px; font-weight: 800; color: var(--gt-soft); }
.gt-link { appearance: none; border: 0; background: transparent; color: var(--gt-accent); font: 700 13px var(--font, system-ui); cursor: pointer; padding: 8px; margin-left: auto; text-decoration: underline; }
.gt-seg { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 3px; border-radius: 12px; background: var(--gt-btn); }
.gt-seg button { appearance: none; border: 0; cursor: pointer; border-radius: 9px; padding: 10px 6px; min-height: 40px; font: 700 14px/1 var(--font, system-ui); background: transparent; color: var(--gt-ink); }
.gt-seg button.on { background: var(--gt-accent); color: #1b2230; }
#gt-screen.gt-light .gt-seg button.on { color: #fff; }
.gt-check { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14px; cursor: pointer; min-height: 32px; }
.gt-check input { width: 20px; height: 20px; margin: 0; accent-color: var(--gt-accent); }
.gt-setup .gt-go { margin-top: 6px; width: 100%; }
/* game */
.gt-game { display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, 300px); gap: clamp(12px, 2vw, 22px); min-height: 0; }
.gt-boardwrap { position: relative; min-height: 0; min-width: 0; display: flex; align-items: center; justify-content: center; }
.gt-card { background: #ffffff; border-radius: 22px; box-shadow: 0 18px 50px -20px rgba(0,0,0,.55), 0 0 0 1px rgba(0,0,0,.04); line-height: 0; }
#gt-board { display: block; touch-action: none; border-radius: 22px; cursor: default; }
#gt-board.gt-can { cursor: pointer; }
#gt-board:focus-visible { outline: 3px solid var(--gt-accent); outline-offset: 4px; }
.gt-side { display: flex; flex-direction: column; gap: 12px; background: var(--gt-card); border: 1px solid var(--gt-line); border-radius: 22px; padding: 14px; min-height: 0; overflow: auto; align-self: start; max-height: 100%; box-sizing: border-box; }
.gt-turn { position: relative; display: flex; align-items: center; gap: 12px; }
.gt-ring { width: 52px; height: 52px; flex: 0 0 auto; transform: rotate(-90deg); }
.gt-ring-bg { fill: none; stroke: var(--gt-line); stroke-width: 4; }
.gt-ring-fg { fill: none; stroke: var(--gt-accent); stroke-width: 4; stroke-linecap: round; stroke-dasharray: 119.4; stroke-dashoffset: 0; transition: stroke-dashoffset .2s linear; }
.gt-secs { position: absolute; left: 0; top: 0; width: 52px; height: 52px; display: flex; align-items: center; justify-content: center; font: 800 17px var(--font, system-ui); font-variant-numeric: tabular-nums; }
.gt-turn.gt-low .gt-ring-fg { stroke: var(--gt-warn); }
.gt-turn.gt-low .gt-secs { color: var(--gt-warn); animation: gt-pulse 1s ease-in-out infinite; }
@keyframes gt-pulse { 50% { transform: scale(1.15); } }
.gt-turn-t { display: flex; flex-direction: column; min-width: 0; }
.gt-turn-t b { font-size: 17px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gt-turn-t span { font-size: 13px; color: var(--gt-soft); }
.gt-score { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.gt-pl { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 14px; border: 2px solid transparent; background: var(--gt-btn); }
.gt-pl.on { border-color: var(--pc); box-shadow: 0 0 0 3px color-mix(in srgb, var(--pc) 25%, transparent); }
.gt-pl .gt-chip { width: 26px; height: 26px; font-size: 14px; }
.gt-pl .nm { flex: 1; min-width: 0; font-weight: 700; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gt-pl .nm small { font-weight: 600; color: var(--gt-soft); margin-left: 4px; }
.gt-pl .sc { font: 900 22px var(--font, system-ui); font-variant-numeric: tabular-nums; min-width: 1.5em; text-align: right; }
.gt-pl .dot { width: 9px; height: 9px; border-radius: 50%; background: #22c55e; flex: 0 0 auto; }
.gt-pl .dot.off { background: #94a3b8; }
.gt-pl.gt-away { opacity: .6; }
.gt-ctl { display: flex; gap: 8px; }
.gt-ctl .gt-btn { flex: 1; }
.gt-result { position: absolute; z-index: 5; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(460px, 94%); max-height: 96%; overflow: auto; box-sizing: border-box;
  text-align: center; padding: clamp(18px, 3vh, 30px) clamp(18px, 3vw, 30px); border-radius: 26px; background: var(--gt-card); border: 1px solid var(--gt-line); box-shadow: 0 30px 80px -30px rgba(0,0,0,.6); }
#gt-screen:not(.gt-light) .gt-result { background: rgba(15, 23, 42, 0.86); }
#gt-screen.gt-light .gt-result { background: rgba(255,255,255,0.92); }
.gt-result.gt-pop { animation: gt-pop .55s cubic-bezier(.2,1.4,.4,1) both; }
@keyframes gt-pop { from { opacity: 0; transform: translate(-50%, -46%) scale(.86); } to { opacity: 1; transform: translate(-50%, -50%); } }
.gt-res-kicker { font-weight: 700; color: var(--gt-soft); font-size: 14px; letter-spacing: .03em; }
.gt-res-title { font-weight: 900; font-size: clamp(26px, 4.5vh, 40px); line-height: 1.1; margin: 6px 0 12px; overflow-wrap: anywhere; }
.gt-rank { list-style: none; margin: 0 0 14px; padding: 0; display: flex; flex-direction: column; gap: 6px; text-align: left; }
.gt-rank li { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-radius: 12px; background: var(--gt-btn); font-weight: 700; }
.gt-rank .pos { width: 2em; font-weight: 900; color: var(--gt-soft); }
.gt-rank .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gt-rank .bx { font-variant-numeric: tabular-nums; }
.gt-rank li.win .pos { color: var(--gt-accent); }
.gt-res-act { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.gt-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
@media (max-width: 860px), (orientation: portrait) and (max-width: 1100px) {
  .gt-game { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; }
  .gt-side { align-self: stretch; max-height: none; flex-direction: row; flex-wrap: wrap; align-items: center; padding: 10px; gap: 8px; }
  .gt-turn { flex: 1 1 100%; }
  .gt-score { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); flex: 1 1 100%; }
  .gt-pl { min-width: 0; padding: 6px 8px; }
  .gt-ctl { flex: 1 1 100%; }
  .gt-side .gt-note { flex: 1 1 100%; }
}
@media (max-width: 760px) {
  .gt-lobby { grid-template-columns: minmax(0, 1fr); }
  .gt-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .gt-steps li { padding: 8px; }
  .gt-steps span { display: none; }
  .gt-titles p { display: none; }
  .gt-top { flex-wrap: wrap; gap: 8px; padding: 10px 12px; }
  .gt-status { order: 3; flex: 1 1 100%; text-align: left; }
  .gt-exit { padding: 9px 12px; margin-left: auto; }
  .gt-turn { flex: 1 1 auto; }
  .gt-score { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .gt-pl { gap: 6px; }
  .gt-pl .gt-chip { width: 22px; height: 22px; font-size: 12px; }
  .gt-pl .nm { font-size: 14px; }
  .gt-pl .sc { font-size: 18px; min-width: 1.2em; }
}
@media (prefers-reduced-motion: reduce) {
  #gt-screen.in, #gt-screen.out, .gt-result.gt-pop, .gt-turn.gt-low .gt-secs, .gt-a1, .gt-a1h, .gt-a2, .gt-a2b, .gt-a3 { animation: none; }
  .gt-a1, .gt-a2 { stroke-dashoffset: 0; }
  .gt-a1h { opacity: 0; }
}
.gt-res-toggle { appearance: none; cursor: pointer; position: absolute; top: 10px; right: 12px; border: 1px solid var(--gt-line); background: var(--gt-btn); color: var(--gt-ink);
  border-radius: 999px; font: 700 12px/1 var(--font, system-ui); padding: 8px 11px; min-height: 32px; }
.gt-res-toggle:focus-visible { outline: 3px solid var(--gt-accent); outline-offset: 2px; }
.gt-result.gt-min { top: 10px; transform: translateX(-50%); width: auto; max-width: 94%; padding: 10px 14px 10px 18px; display: flex; align-items: center; gap: 12px; border-radius: 999px; animation: none; }
.gt-result.gt-min .gt-res-toggle { position: static; order: 2; }
.gt-result.gt-min .gt-res-title { font-size: 18px; margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gt-result.gt-min .gt-res-kicker, .gt-result.gt-min .gt-rank, .gt-result.gt-min .gt-res-act, .gt-result.gt-min .gt-note { display: none !important; }
.gt-result:not(.gt-min) .gt-res-kicker { padding: 0 90px; }
.gt-turn.gt-over .gt-ring, .gt-turn.gt-over .gt-secs { display: none; }

/* ---- Lesson recap ---------------------------------------------------- */
body.recap-on #rgn-card { display: none !important; }
.rc-modal { position: fixed; inset: 0; z-index: 140; display: none; align-items: center; justify-content: center; background: rgba(10, 14, 24, 0.42); padding: 16px; }
.rc-modal.show { display: flex; }
.rc-box { width: min(560px, 100%); max-height: calc(100vh - 32px); overflow: auto; box-sizing: border-box; background: var(--surface-solid); color: var(--text);
  border: 1px solid var(--border); border-radius: 22px; box-shadow: var(--shadow); padding: 20px 22px; font-family: var(--font); }
.rc-head { display: flex; align-items: center; gap: 10px; }
.rc-head h2 { margin: 0; font-size: 19px; font-weight: 800; }
.rc-count { font-size: 13px; color: var(--muted); font-weight: 600; }
.rc-x { margin-left: auto; appearance: none; border: 0; background: transparent; color: var(--muted); font-size: 24px; cursor: pointer; width: 40px; height: 40px; border-radius: 10px; }
.rc-x:hover { background: var(--hover); color: var(--text); }
.rc-sub { margin: 6px 0 12px; font-size: 13.5px; color: var(--text-soft); line-height: 1.4; }
.rc-list { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-direction: column; gap: 6px; max-height: 260px; overflow: auto; }
.rc-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 12px; background: var(--hover); }
.rc-row.off .rc-nm, .rc-row.off .rc-way { opacity: .45; text-decoration: line-through; }
.rc-lab { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; cursor: pointer; min-height: 32px; }
.rc-lab input { width: 18px; height: 18px; margin: 0; accent-color: var(--accent); flex: 0 0 auto; }
.rc-way { width: 22px; text-align: center; color: var(--accent); font-size: 14px; flex: 0 0 auto; }
.rc-nm { flex: 1; min-width: 0; font-weight: 650; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rc-bd { font-size: 12px; color: var(--muted); white-space: nowrap; }
.rc-mv { appearance: none; border: 1px solid var(--border-strong); background: var(--surface-solid); color: var(--text); width: 32px; height: 32px; border-radius: 9px; cursor: pointer; font-size: 15px; }
.rc-mv:disabled { opacity: .35; cursor: default; }
.rc-empty { font-size: 14px; color: var(--text-soft); background: var(--hover); padding: 12px 14px; border-radius: 12px; line-height: 1.45; }
.rc-opts { display: flex; flex-direction: column; gap: 8px; }
.rc-h { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin-top: 4px; }
.rc-seg { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 3px; border-radius: 12px; background: var(--hover); }
.rc-seg3 { grid-template-columns: repeat(3, 1fr); }
.rc-seg4 { grid-template-columns: repeat(4, 1fr); }
.rc-seg button { appearance: none; border: 0; cursor: pointer; border-radius: 9px; padding: 9px 6px; min-height: 38px; font: 700 13px/1.1 var(--font); background: transparent; color: var(--text); }
.rc-seg button.on { background: var(--accent); color: #fff; }
.rc-check { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; cursor: pointer; min-height: 32px; }
.rc-check input { width: 18px; height: 18px; margin: 0; accent-color: var(--accent); }
.rc-actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; margin-top: 14px; }
.rc-go, .rc-btn, .rc-bb { appearance: none; cursor: pointer; border-radius: 999px; font: 750 14px/1 var(--font); min-height: 44px; padding: 0 18px; }
.rc-go { border: 0; background: var(--accent); color: #fff; box-shadow: 0 8px 22px -10px rgba(108,92,231,.8); }
.rc-go:hover:not(:disabled) { background: var(--accent-press); }
.rc-btn, .rc-bb { border: 1px solid var(--border-strong); background: var(--surface-solid); color: var(--text); }
.rc-btn:hover:not(:disabled), .rc-bb:hover:not(:disabled) { background: var(--hover); }
.rc-go:disabled, .rc-btn:disabled, .rc-bb:disabled { opacity: .45; cursor: default; box-shadow: none; }
.rc-go:focus-visible, .rc-btn:focus-visible, .rc-bb:focus-visible, .rc-mv:focus-visible, .rc-seg button:focus-visible, .rc-x:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* while it runs */
.rc-cap { position: fixed; z-index: 118; left: 50%; top: 84px; transform: translateX(-50%); max-width: min(720px, calc(100vw - 32px)); box-sizing: border-box;
  background: var(--surface-solid); color: var(--text); border: 1px solid var(--border); border-radius: 18px; box-shadow: var(--shadow); padding: 10px 16px; font-family: var(--font); text-align: center; }
.rc-cap[hidden], .rc-bar[hidden], .rc-card[hidden] { display: none !important; }
.rc-cap-row { display: flex; align-items: center; gap: 10px; justify-content: center; }
.rc-step { font-size: 12px; font-weight: 800; color: #fff; background: var(--accent); border-radius: 999px; padding: 4px 9px; white-space: nowrap; }
.rc-name { font-size: 18px; font-weight: 800; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.rc-clock { position: relative; width: 36px; height: 36px; flex: 0 0 auto; }
.rc-clock svg { width: 36px; height: 36px; transform: rotate(-90deg); }
.rc-ring-bg { fill: none; stroke: var(--border-strong); stroke-width: 3.5; }
.rc-ring { fill: none; stroke: var(--accent); stroke-width: 3.5; stroke-linecap: round; stroke-dasharray: 100.5; transition: stroke-dashoffset .25s linear; }
.rc-clock b { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 13px; font-variant-numeric: tabular-nums; }
.rc-prompt { margin-top: 4px; font-size: 14.5px; color: var(--text-soft); font-weight: 600; }
.rc-whoname { margin-top: 6px; display: inline-block; font-size: 15px; font-weight: 800; padding: 5px 12px; border-radius: 999px; background: var(--accent-soft); color: var(--text); }
.rc-whoname.mine { background: #ffd166; color: #1b2230; }
.rc-bar { position: fixed; z-index: 119; left: 50%; bottom: 96px; transform: translateX(-50%); display: flex; align-items: center; gap: 8px; max-width: calc(100vw - 24px); box-sizing: border-box;
  background: var(--surface-solid); border: 1px solid var(--border); border-radius: 999px; box-shadow: var(--shadow); padding: 6px; font-family: var(--font); }
.rc-bb { width: 44px; padding: 0; font-size: 16px; }
.rc-bb.rc-who { width: auto; padding: 0 14px; font-size: 13.5px; white-space: nowrap; }
.rc-next { min-width: 132px; }
.rc-dots { display: flex; gap: 5px; padding: 0 6px; flex-wrap: wrap; max-width: 220px; }
.rc-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); }
.rc-dot.done { background: var(--accent); opacity: .5; }
.rc-dot.now { background: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.rc-card { position: fixed; z-index: 119; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(520px, calc(100vw - 32px)); max-height: calc(100vh - 200px); overflow: auto; box-sizing: border-box;
  background: var(--surface-solid); color: var(--text); border: 1px solid var(--border); border-radius: 26px; box-shadow: var(--shadow); padding: 26px 28px; font-family: var(--font); text-align: center; }
.rc-kicker { font-size: 13px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }
.rc-title { font-size: clamp(24px, 3.4vh, 32px); font-weight: 900; margin: 6px 0 14px; line-height: 1.15; }
.rc-names { margin: 0 auto 6px; padding: 0 0 0 1.4em; text-align: left; max-width: 380px; font-size: 16px; line-height: 1.7; font-weight: 600; }
.rc-note { margin: 8px 0 0; color: var(--muted); font-size: 14px; font-weight: 600; }
.rc-note:empty { display: none; }
.rc-card .rc-actions { justify-content: center; }
@media (max-width: 640px) {
  .rc-cap { top: 76px; padding: 8px 12px; }
  .rc-name { font-size: 15px; }
  .rc-bar { bottom: 88px; gap: 5px; }
  .rc-dots { display: none; }
  .rc-next { min-width: 104px; padding: 0 12px; }
  .rc-bb.rc-who { padding: 0 10px; font-size: 12.5px; }
  .rc-seg4 { grid-template-columns: repeat(2, 1fr); }
}
/* the recap sheet */
#print-area .rc-sheet { display: block; page-break-after: always; break-after: page; padding: 0; font-family: var(--font); color: #111; }
#print-area .rc-sheet:last-child { page-break-after: auto; break-after: auto; }
#print-area .rc-sheet-head { display: flex; justify-content: space-between; align-items: baseline; border-bottom: 2px solid #222; padding-bottom: 6px; margin-bottom: 10px; font-size: 12px; }
#print-area .rc-sheet-head b { font-size: 18px; }
#print-area .rc-panel { margin: 0 0 12px; break-inside: avoid; page-break-inside: avoid; text-align: center; }
#print-area .rc-panel figcaption { text-align: left; font-weight: 700; font-size: 14px; margin-bottom: 4px; }
#print-area .rc-panel img { max-width: 100%; max-height: 118mm; object-fit: contain; border: 1px solid #ddd; }
.rc-cap [hidden], .rc-card [hidden], .rc-bar [hidden] { display: none !important; }
#print-area .rc-panel img { width: auto; max-width: 100%; }
body.ea-arming #board, body.ea-arming canvas#board { cursor: crosshair !important; }
.pop-item .dbg-state { margin-left: auto; font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--hover); color: var(--muted); }
.pop-item.dbg-toggle[aria-pressed="true"] .dbg-state { background: #16a34a; color: #fff; }
#slate-debug[hidden] { display: none !important; }
#dbg-tools { flex-wrap: wrap; }

/* ---- UX audit fixes (v278) ------------------------------------------------ */
/* UX-01: on a phone the bar scrolls; Collab and Export come first, and a soft
   edge shows there is more to scroll to. */
@media (max-width: 600px) {
  .controls #collab-btn { order: -2; }
  .controls #export-btn { order: -1; }
}
.controls.ux-fade-r, .rail.ux-fade-r { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 34px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 34px), transparent); }
.controls.ux-fade-l, .rail.ux-fade-l { -webkit-mask-image: linear-gradient(90deg, transparent, #000 34px); mask-image: linear-gradient(90deg, transparent, #000 34px); }
.controls.ux-fade-l.ux-fade-r, .rail.ux-fade-l.ux-fade-r { -webkit-mask-image: linear-gradient(90deg, transparent, #000 34px, #000 calc(100% - 34px), transparent); mask-image: linear-gradient(90deg, transparent, #000 34px, #000 calc(100% - 34px), transparent); }
/* UX-03: the board can take focus, and shows it; the size slider shows focus. */
/* REPORTED: "a purple border appears around the whole window at times" — the
   board canvas fills the window, so its keyboard-focus ring ran round the
   browser's edges. The board is announced by its label instead. */
#board:focus-visible { outline: none; }
#size:focus-visible, input[type=range]:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 6px; }
/* UX-08: menus over the board are more opaque, so their small print reads
   against a busy or dark board; unselected choices use full-strength text. */
:root { --ux-pop-veil: rgba(255,255,255,0.62); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --ux-pop-veil: rgba(18,21,30,0.66); } }
:root[data-theme="dark"] { --ux-pop-veil: rgba(18,21,30,0.66); }
.pop.glass { background: var(--sk-gloss, linear-gradient(transparent, transparent)), linear-gradient(var(--ux-pop-veil), var(--ux-pop-veil)), var(--sk-panel, var(--surface)); }
.seg button { color: var(--text); }
.seg button small { color: var(--text-soft); }
.pop .ins-hint, .pop h4 { color: var(--text-soft); }
/* UX-09: board arrows are easier to hit (the target grows, the look does not). */
.nav-btn::after { top: -6px; bottom: -6px; }
/* UX-10: a toast can be tapped away — click-through, see uxWire (it used to block what was under it). */
/* UX-04: the name of a button on long-press (touch). */
#ux-tip { position: fixed; z-index: 500; max-width: min(320px, calc(100vw - 16px)); padding: 7px 11px; border-radius: 10px;
  background: rgba(20,23,32,0.94); color: #fff; font: 600 13px/1.3 var(--font); box-shadow: 0 8px 24px -8px rgba(0,0,0,.5); pointer-events: none; }
#ux-tip[hidden] { display: none; }
/* welcome, QR, shortcuts */
.ux-modal { z-index: 145; }
.ux-box h2 { margin: 0; font-size: 20px; font-weight: 800; }
.ux-choices { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 14px 0 10px; }
.ux-choice { appearance: none; cursor: pointer; text-align: left; border: 1px solid var(--border-strong); background: var(--surface-solid); color: var(--text);
  border-radius: 16px; padding: 14px; min-height: 84px; display: flex; flex-direction: column; gap: 4px; font-family: var(--font); }
.ux-choice b { font-size: 15px; }
.ux-choice span { font-size: 13px; color: var(--text-soft); line-height: 1.35; }
.ux-choice:hover { border-color: var(--accent); background: var(--hover); }
.ux-choice:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.ux-note { margin: 6px 0 0; font-size: 13px; color: var(--text-soft); }
.ux-qr-box { text-align: center; max-width: 420px; }
.ux-qr-img { width: min(300px, 70vw); aspect-ratio: 1; margin: 12px auto 8px; background: #fff; border-radius: 16px; padding: 10px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; }
.ux-qr-img svg { width: 100%; height: 100%; }
.ux-qr-img .ux-note { color: #475569; }
.ux-qr-code { font-size: 15px; color: var(--text-soft); }
.ux-qr-code b { font-size: 26px; letter-spacing: .14em; color: var(--text); margin-left: 6px; }
.ux-qr-link { margin-top: 6px; font-size: 12px; color: var(--muted); word-break: break-all; }
.ux-qr-box .rc-actions { justify-content: center; }
.ux-kbd-body { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; margin-top: 10px; }
.ux-kbd-body h3 { margin: 0 0 6px; font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.ux-kbd-body dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 5px 12px; font-size: 13.5px; }
.ux-kbd-body dt { font-weight: 800; font-family: ui-monospace, Menlo, Consolas, monospace; white-space: nowrap; }
.ux-kbd-body dd { margin: 0; color: var(--text-soft); }
.ux-invite-row { margin: 8px 0 4px; }
.ux-invite-row .collab-chip { flex: 1 1 0; justify-content: center; }
@media (max-width: 520px) { .ux-choices { grid-template-columns: 1fr; } .ux-choice { min-height: 0; } }
#print-area .ux-photo img { max-width: 100%; max-height: 96vh; }
.exp-row.exp-row-4 { grid-template-columns: repeat(4, 1fr); }

/* ---- Symbols: search, plain-only, names (v278) ------------------------------- */
.ins-search-row { display: flex; gap: 6px; align-items: stretch; }
.ins-search-row #ins-search { flex: 1; min-width: 0; }
.ins-plain { appearance: none; margin: 0 0 7px; padding: 0 10px; border-radius: 9px; border: 1px solid var(--border-strong);
  background: transparent; color: var(--muted); font: 600 11.5px/1 var(--font); cursor: pointer; white-space: nowrap; }
.ins-plain[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.ins-count { margin: 0 4px 4px; min-height: 0; font: 600 11px/1.3 var(--font); color: var(--muted); }
.ins-count:empty { display: none; }
.ins-grid button.plain { color: var(--text); }
.ins-grid button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ins-name { display: flex; align-items: center; gap: 8px; min-height: 22px; }
.ins-name.on { color: var(--text); }
.ins-name-g { font-size: 18px; line-height: 1; }
.ins-name-k { margin-left: auto; font-weight: 600; font-size: 10.5px; padding: 2px 7px; border-radius: 999px; white-space: nowrap; }
.ins-name-k.plain { background: var(--accent-soft); color: var(--accent); }
.ins-name-k.col { background: var(--hover); color: var(--muted); }
/* The Decor panel kept growing as sets were added: a fixed, comfortable width,
   accessories three across, the set tabs as one scrolling row. */
#decor-pop { width: 380px; max-width: calc(100vw - 16px); box-sizing: border-box; }
#decor-pop .decor-grid { grid-template-columns: repeat(3, 1fr); gap: 5px; margin-bottom: 6px; }
#decor-pop .decor-grid button { padding: 6px 6px; font-size: 12px; gap: 5px; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#decor-pop .decor-done { padding: 7px; margin-top: 2px; }
/* REPORTED: the set tabs "are not moving" — one sideways-scrolling row
   hid most of them with no way to reach them by mouse. They wrap instead:
   every set is always in view, in two short rows. */
#decor-pop .ins-tabs { flex-wrap: wrap; padding: 2px 2px 6px; gap: 4px; }
#decor-pop .ins-tabs button { flex: 0 0 auto; padding: 5px 8px; font-size: 11px; }
#decor-pop .ins-grid { grid-template-columns: repeat(9, 1fr); max-height: 176px; }
#decor-pop .ins-grid button { height: 32px; font-size: 20px; }
#decor-pop h4 { margin-top: 4px; }

/* ---- Class reactions (v278) ------------------------------------------------ */
.react-place { appearance: none; width: 100%; margin: 0 0 8px; padding: 7px 10px; border-radius: 9px; border: 1px dashed var(--border-strong);
  background: transparent; color: var(--text); font: 600 12.5px/1 var(--font); cursor: pointer; }
.react-place[aria-pressed="true"] { border-style: solid; border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
body.rx-arming #board { cursor: crosshair; }
.rx-dlg { position: fixed; inset: 0; z-index: 92; display: none; align-items: center; justify-content: center; padding: 20px; background: rgba(8,10,16,0.55); backdrop-filter: blur(3px); }
.rx-dlg.show { display: flex; }
.rx-lbl { display: block; font: 600 11.5px/1 var(--font); color: var(--muted); margin: 10px 0 5px; }
.rx-dlg .collab-input { width: 100%; box-sizing: border-box; }
.rx-presets { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 14px; }
.rx-mode { display: flex; }
.rx-mode button { flex: 1; }
.rx-tally { margin: 8px 2px 4px; font: 500 12px/1.4 var(--font); color: var(--muted); }
.rx-feed:empty { display: none; }
.rx-tray { position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 60; display: flex; align-items: center; gap: 4px;
  padding: 6px 8px; border-radius: 999px; background: var(--surface-solid, #1b1f29); border: 1px solid var(--border, rgba(255,255,255,.12));
  box-shadow: 0 10px 30px rgba(0,0,0,.3); }
.rx-tray[hidden] { display: none; }
.rx-tray-btns { display: flex; gap: 2px; }
.rx-tray button { appearance: none; border: 0; background: transparent; font-size: 24px; line-height: 1; width: 42px; height: 42px; border-radius: 50%; cursor: pointer;
  transition: transform .15s var(--ease, ease), background-color .15s; }
.rx-tray button:hover { background: var(--hover); transform: translateY(-2px) scale(1.08); }
.rx-tray button:active { transform: scale(.92); }
.rx-tray button:focus-visible { outline: 2px solid var(--accent); }
.rx-tray.rx-cool .rx-tray-btns button { opacity: .45; }
.rx-point { border-left: 1px solid var(--border-strong) !important; border-radius: 0 50% 50% 0 !important; font-size: 20px !important; }
.rx-point.on { background: var(--accent-soft) !important; }
.rx-tray-note { font: 600 11px/1.2 var(--font); color: var(--muted); padding: 0 6px; }
.rx-tray-note:empty { display: none; }
.rx-combo { position: fixed; top: 130px; left: 50%; transform: translateX(-50%); z-index: 201; pointer-events: none;
  padding: 8px 16px; border-radius: 999px; background: rgba(20,24,34,.88); color: #fff; font: 800 22px/1 system-ui, sans-serif; box-shadow: 0 10px 30px rgba(0,0,0,.35); }
.rx-combo[hidden] { display: none; }
.rx-combo.rx-bump { animation: rxBump .35s cubic-bezier(.34,1.56,.64,1); }
@keyframes rxBump { from { transform: translateX(-50%) scale(.6); } to { transform: translateX(-50%) scale(1); } }
.rx-hype { position: fixed; top: 92px; left: 50%; transform: translateX(-50%); z-index: 59; width: min(460px, calc(100vw - 32px)); height: 26px; border-radius: 999px;
  background: rgba(20,24,34,.82); overflow: hidden; box-shadow: 0 6px 20px rgba(0,0,0,.3); pointer-events: none; }
.rx-hype[hidden] { display: none; }
.rx-hype-fill { position: absolute; inset: 0 auto 0 0; width: 0; background: linear-gradient(90deg, #ff9f43, #ff6b6b, #ffd166); transition: width .35s ease; }
.rx-hype.done .rx-hype-fill { background: linear-gradient(90deg, #06d6a0, #4f8cff, #8b7bff); }
.rx-hype-txt { position: relative; display: block; text-align: center; font: 800 12.5px/26px system-ui, sans-serif; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.5); }
.rx-card { position: fixed; left: 50%; bottom: 84px; transform: translateX(-50%); z-index: 61; width: min(420px, calc(100vw - 24px)); box-sizing: border-box;
  padding: 14px; border-radius: 16px; background: var(--surface-solid, #1b1f29); color: var(--text, #eef1f6); border: 1px solid var(--border, rgba(255,255,255,.12));
  box-shadow: 0 14px 40px rgba(0,0,0,.35); font: 13px var(--font); }
.rx-card[hidden] { display: none; }
.rx-card.rx-host { left: auto; right: 16px; transform: none; bottom: 16px; width: min(340px, calc(100vw - 24px)); }
.rx-feel-head { font-weight: 800; margin-bottom: 10px; display: flex; justify-content: space-between; gap: 8px; }
.rx-feel-left { color: var(--muted); font-weight: 600; }
.rx-feel-btns { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.rx-feel-btns button { appearance: none; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 10px 4px; border-radius: 12px;
  border: 1px solid var(--border-strong); background: transparent; color: inherit; font: 600 12px/1.2 var(--font); cursor: pointer; }
.rx-feel-btns button span { font-size: 30px; line-height: 1; }
.rx-feel-btns button.on { border-color: var(--accent); background: var(--accent-soft); }
.rx-feel-note { margin: 8px 2px 0; font-size: 11px; color: var(--muted); }
.rx-bar { display: flex; height: 16px; border-radius: 999px; overflow: hidden; background: var(--hover); }
.rx-seg { min-width: 0; transition: flex .3s ease; }
.rx-up { background: #06d6a0; } .rx-mid { background: #ffd166; } .rx-down { background: #ff6b6b; }
.rx-legend { display: flex; justify-content: space-between; gap: 6px; margin-top: 8px; font-size: 12px; }
.rx-none { margin: 6px 0 0; font-size: 11px; color: var(--muted); }
.rx-feel-acts { display: flex; gap: 6px; justify-content: flex-end; margin-top: 10px; }
.rx-shout { position: fixed; top: 22%; left: 50%; transform: translateX(-50%); z-index: 199; pointer-events: none; text-align: center;
  padding: 20px 34px; border-radius: 22px; background: rgba(20,24,34,.9); color: #fff; box-shadow: 0 20px 60px rgba(0,0,0,.4); max-width: calc(100vw - 32px); }
.rx-shout[hidden] { display: none; }
.rx-shout.rx-in { animation: rxShout .5s cubic-bezier(.34,1.56,.64,1); }
@keyframes rxShout { from { transform: translateX(-50%) scale(.5); opacity: 0; } to { transform: translateX(-50%) scale(1); opacity: 1; } }
.rx-shout-star { font-size: 44px; line-height: 1; }
.rx-shout-name { font: 800 26px/1.2 system-ui, sans-serif; margin-top: 6px; }
.rx-shout-text { font: 600 16px/1.3 system-ui, sans-serif; color: #ffd166; margin-top: 4px; }
@media (prefers-reduced-motion: reduce) { .rx-combo.rx-bump, .rx-shout.rx-in { animation: none; } .rx-hype-fill { transition: none; } }
@media (max-width: 640px) { .rx-tray { bottom: 86px; } .rx-tray button { width: 38px; height: 38px; font-size: 22px; } .rx-card { bottom: 140px; } }
body.collab-granted .rx-tray { bottom: 94px; } body.collab-granted .rx-card { bottom: 158px; }
@media (max-width: 640px) { body.collab-granted .rx-tray { bottom: 150px; } body.collab-granted .rx-card { bottom: 204px; } }

/* ---------- v278: video on the board ---------- */
.vid-note { margin: 7px 2px 2px; font: 500 12px/1.4 var(--font); color: var(--muted); min-height: 17px; }
.vid-note.ok { color: var(--accent); }
.vid-note.bad { color: var(--danger, #e5484d); }
.vid-opt { font-weight: 500; opacity: .75; }
.vid-prev { margin: 10px 0 2px; border-radius: 10px; overflow: hidden; background: #000; aspect-ratio: 16 / 9; }
.vid-prev img { display: block; width: 100%; height: 100%; object-fit: cover; }
.vid-dlg .awp-row { margin-top: 14px; }
#vid-live { position: fixed; z-index: 90; display: flex; flex-direction: column; background: #000; border-radius: 12px; overflow: hidden;
  box-shadow: 0 18px 50px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.08); }
#vid-live[hidden] { display: none; }
#vid-live .vid-bar { flex: none; display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 6px 0 12px;
  background: #111318; color: #e9ecf2; font: 600 12.5px/1 var(--font); }
#vid-live .vid-bar-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#vid-live #vid-close { appearance: none; border: 0; width: 28px; height: 28px; border-radius: 8px; background: rgba(255,255,255,.08); color: #fff; font-size: 14px; cursor: pointer; }
#vid-live #vid-close:hover { background: rgba(255,255,255,.18); }
#vid-live .vid-frame { flex: 1; position: relative; }
#vid-live iframe, #vid-live video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: #000; }

.pop-note:empty { display: none; }   /* v278: an empty state line takes no room */

/* v278: the student's reactions — placed above the bottom menus by rxTrayPlace; toasts rise above them */
body.rx-tray-on #toast { bottom: var(--rx-toast-b, 92px) !important; }
.rx-tray { flex-wrap: wrap; justify-content: center; max-width: calc(100vw - 24px); transition: bottom .18s var(--ease, ease); }
.rx-tray .rx-more { width: 34px; height: 34px; font-size: 18px; color: var(--muted); border: 1px dashed var(--border-strong, rgba(127,127,127,.4)); }
.rx-tray .rx-more[aria-expanded="true"] { color: var(--accent); border-style: solid; }
.rx-tray-more { display: flex; flex-wrap: wrap; justify-content: center; gap: 2px; flex-basis: 100%; order: -1; padding-bottom: 4px; margin-bottom: 2px;
  border-bottom: 1px solid var(--border, rgba(127,127,127,.2)); }
.rx-tray-more[hidden] { display: none; }
.rx-tray:has(.rx-tray-more:not([hidden])) { border-radius: 26px; }
/* the React button on the presenter bar */
#present-bar #present-react .pr-emoji { font-size: 16px; line-height: 1; }
/* v278 (iPad): a double-tap anywhere outside the board zoomed the whole page, and with zoom
   otherwise locked there was no way back. Double-tap zoom is off everywhere; scrolling still works. */
html, body { touch-action: manipulation; }
.rx-tray:has(.rx-tray-more:not([hidden])) { max-width: min(440px, calc(100vw - 24px)); }

/* ==================== Game Time: Hit the Target (v279) ==================== */
#ht-screen { --gt-ink: #f8fafc; --gt-soft: #cbd5e1; --gt-card: rgba(15, 23, 42, 0.55); --gt-line: rgba(255,255,255,0.16);
  --gt-accent: #ffd166; --gt-btn: rgba(255,255,255,0.12); --gt-btn-ink: #fff; --gt-warn: #f59e0b; --ht-hit: #34d399; --ht-near: #fbbf24; --ht-bad: #fb7185;
  --ht-tile1: #8b7cf6; --ht-tile2: #6c5ce7;
  position: fixed; inset: 0; z-index: 135; color: var(--gt-ink); font-family: var(--font, system-ui);
  background: radial-gradient(1100px 650px at 80% -10%, #3b2a6b 0%, transparent 60%), radial-gradient(1200px 700px at 10% 0%, #23324d 0%, #172234 60%, #121b2b 100%);
  display: grid; grid-template-rows: auto 1fr; overflow: hidden; touch-action: manipulation; }
#ht-screen.gt-light { --gt-ink: #1b2230; --gt-soft: #475569; --gt-card: rgba(255,255,255,0.78); --gt-line: rgba(27,34,48,0.14);
  --gt-accent: #6c5ce7; --gt-btn: rgba(27,34,48,0.07); --gt-btn-ink: #1b2230; --gt-warn: #b45309; --ht-hit: #059669; --ht-near: #b45309; --ht-bad: #e11d48;
  background: radial-gradient(1100px 650px at 85% -10%, #e9e3ff 0%, transparent 60%), radial-gradient(1200px 700px at 20% 0%, #ffffff 0%, #eef2ff 55%, #e6ebf7 100%); }
#ht-screen[hidden], #ht-screen [hidden] { display: none !important; }
#ht-screen.in { animation: brk-in .35s ease-out both; }
#ht-screen.out { animation: brk-out .35s ease-in both; }
#ht-fx { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 6; }
#ht-screen .gt-go { color: #1b2230; }
#ht-screen.gt-light .gt-go { color: #fff; background: linear-gradient(180deg, #8b7cf6, #6c5ce7); box-shadow: 0 8px 24px -8px rgba(108,92,231,0.6); }
#ht-screen input[type=number] { font: 600 15px var(--font, system-ui); padding: 9px 10px; border-radius: 10px; border: 1px solid var(--gt-line); background: rgba(255,255,255,0.08); color: var(--gt-ink); width: 56px; text-align: center; -moz-appearance: textfield; }
#ht-screen.gt-light input[type=number] { background: #fff; }
#ht-screen input::-webkit-outer-spin-button, #ht-screen input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
#ht-screen .gt-seg button.on { color: #1b2230; }
#ht-screen.gt-light .gt-seg button.on { color: #fff; }
/* the game picker, shared with Dots and Boxes */
.gt-games { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px; border-radius: 14px; background: var(--gt-btn); margin-bottom: 4px; }
.gt-games button { appearance: none; border: 0; cursor: pointer; border-radius: 10px; padding: 10px 6px; min-height: 42px; font: 800 14px/1.1 var(--font, system-ui); background: transparent; color: var(--gt-ink); }
.gt-games button.on { background: var(--gt-card); box-shadow: 0 2px 10px -4px rgba(0,0,0,.4), inset 0 0 0 2px var(--gt-accent); }
.gt-games button:not(.on):hover { background: rgba(255,255,255,.08); }
.gt-games button:focus-visible { outline: 3px solid var(--gt-accent); outline-offset: 2px; }
/* lobby */
.ht-steps .ht-demo { height: 92px; display: flex; align-items: center; justify-content: center; gap: 4px; }
.ht-d1 .ht-dt { font: 900 44px/1 var(--font, system-ui); color: #6c5ce7; padding: 8px 18px; border-radius: 18px; background: #f1edff; box-shadow: 0 0 0 4px rgba(108,92,231,.18); animation: ht-glow 2.4s ease-in-out infinite; }
.ht-d2 i { font: 800 20px/1 var(--font, system-ui); font-style: normal; width: 34px; height: 40px; display: inline-flex; align-items: center; justify-content: center; border-radius: 9px; color: #fff; background: linear-gradient(160deg, #8b7cf6, #6c5ce7); }
.ht-d2 em { font: 800 20px/1 var(--font, system-ui); font-style: normal; color: #1b2230; }
.ht-d2 > * { animation: ht-pop-in 3s ease-out infinite both; }
.ht-d2 > :nth-child(2) { animation-delay: .25s; } .ht-d2 > :nth-child(3) { animation-delay: .5s; } .ht-d2 > :nth-child(4) { animation-delay: .75s; } .ht-d2 > :nth-child(5) { animation-delay: 1s; }
.ht-d3 span { font: 900 20px/1 var(--font, system-ui); padding: 8px 10px; border-radius: 12px; background: #ecfdf5; color: #059669; animation: gt-bob 2.4s ease-in-out infinite; }
.ht-d3 span:nth-child(2) { animation-delay: .3s; background: #fef3c7; color: #b45309; } .ht-d3 span:nth-child(3) { animation-delay: .6s; background: #fff; }
@keyframes ht-glow { 50% { box-shadow: 0 0 0 10px rgba(108,92,231,.08); } }
@keyframes ht-pop-in { 0%, 8% { opacity: 0; transform: translateY(8px) scale(.8); } 18%, 85% { opacity: 1; transform: none; } 100% { opacity: 0; } }
.ht-how { margin-top: 14px; background: var(--gt-btn); border-radius: 14px; padding: 10px 14px; font-size: 13.5px; line-height: 1.45; }
.ht-how summary { cursor: pointer; font-weight: 800; font-size: 14px; }
.ht-how ul { margin: 8px 0 2px; padding-left: 18px; color: var(--gt-soft); }
.ht-how b { color: var(--gt-ink); }
.ht-opsel { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.ht-opt { appearance: none; cursor: pointer; border: 2px solid var(--gt-line); background: var(--gt-btn); color: var(--gt-ink); border-radius: 14px; padding: 8px 4px 6px; display: flex; flex-direction: column; align-items: center; gap: 2px; min-height: 58px; transition: transform .12s, border-color .12s, background-color .12s; }
.ht-opt .s { font: 900 22px/1 var(--font, system-ui); }
.ht-opt .n { font: 700 10.5px/1.1 var(--font, system-ui); color: var(--gt-soft); }
.ht-opt.on { border-color: var(--gt-accent); background: color-mix(in srgb, var(--gt-accent) 18%, transparent); }
.ht-opt.on .n { color: var(--gt-ink); }
.ht-opt:not(.on) .s { opacity: .45; }
.ht-opt:active { transform: scale(.95); }
.ht-opt:focus-visible { outline: 3px solid var(--gt-accent); outline-offset: 2px; }
.ht-row2 { display: grid; grid-template-columns: auto 1fr; gap: 12px; align-items: end; }
.ht-row2b { grid-template-columns: 1fr 1fr; }
.ht-dur { grid-template-columns: repeat(4, 1fr); }
.ht-sample { display: grid; grid-template-columns: auto 1fr; grid-template-areas: "k k" "t tiles" "t n"; column-gap: 12px; align-items: center; min-height: 0;
  background: var(--gt-btn); border-radius: 14px; padding: 10px 12px; }
.ht-sample:empty { display: none; }
.ht-sk { grid-area: k; font: 700 11px var(--font, system-ui); text-transform: uppercase; letter-spacing: .05em; color: var(--gt-soft); margin-bottom: 4px; }
.ht-st { grid-area: t; font: 900 32px/1 var(--font, system-ui); color: var(--gt-accent); }
.ht-stiles { grid-area: tiles; display: flex; gap: 4px; flex-wrap: wrap; }
.ht-stiles i { font: 800 14px/1 var(--font, system-ui); font-style: normal; min-width: 26px; height: 28px; padding: 0 4px; display: inline-flex; align-items: center; justify-content: center; border-radius: 7px; background: linear-gradient(160deg, var(--ht-tile1), var(--ht-tile2)); color: #fff; }
.ht-sn { grid-area: n; font-size: 12px; color: var(--gt-soft); }
/* play */
.ht-play { display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, 300px); gap: clamp(12px, 2vw, 22px); min-height: 0; }
.ht-stage { min-height: 0; overflow: auto; display: flex; flex-direction: column; align-items: center; gap: clamp(10px, 2vh, 18px); padding: 4px 0 12px; }
.ht-head { width: min(760px, 100%); display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px; }
.ht-round { display: flex; flex-direction: column; font-size: 13px; color: var(--gt-soft); }
.ht-round b { font-size: 18px; color: var(--gt-ink); }
.ht-clock { justify-self: end; }
.ht-clock .gt-ring { width: 64px; height: 64px; }
.ht-clock .gt-secs { width: 64px; height: 64px; font-size: 20px; }
.ht-target { position: relative; display: flex; flex-direction: column; align-items: center; padding: 10px clamp(26px, 5vw, 46px) 12px; border-radius: 26px;
  background: linear-gradient(160deg, #ffe08a, #ffc145); color: #3b2a00; box-shadow: 0 18px 40px -16px rgba(255,193,69,.7), inset 0 -4px 0 rgba(0,0,0,.08); }
.ht-target::after { content: ""; position: absolute; inset: -8px; border-radius: 32px; border: 3px solid rgba(255,209,102,.35); animation: ht-ring 2.6s ease-in-out infinite; pointer-events: none; }
.ht-tk { font: 800 12px/1 var(--font, system-ui); text-transform: uppercase; letter-spacing: .12em; opacity: .75; }
.ht-target b { font: 900 clamp(48px, 9vh, 84px)/1 var(--font, system-ui); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.ht-target.ht-new { animation: ht-target-in .7s cubic-bezier(.2,1.5,.4,1) both; }
@keyframes ht-target-in { from { transform: scale(.4) rotate(-8deg); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes ht-ring { 50% { transform: scale(1.04); opacity: .4; } }
.ht-tiles { display: flex; flex-wrap: wrap; justify-content: center; gap: clamp(8px, 1.6vw, 14px); width: min(760px, 100%); }
.ht-tile { appearance: none; border: 0; cursor: pointer; width: clamp(62px, 10vw, 86px); height: clamp(68px, 11vw, 92px); border-radius: 18px; position: relative;
  background: linear-gradient(160deg, var(--ht-tile1), var(--ht-tile2)); color: #fff; font: 900 clamp(28px, 4.4vw, 38px)/1 var(--font, system-ui);
  box-shadow: 0 10px 22px -10px rgba(108,92,231,.8), inset 0 -5px 0 rgba(0,0,0,.18), inset 0 2px 0 rgba(255,255,255,.25);
  transition: transform .14s, opacity .2s, filter .2s; animation: ht-deal .45s cubic-bezier(.2,1.4,.4,1) var(--d, 0ms) both; }
.ht-tile.big { background: linear-gradient(160deg, #22d3ee, #0891b2); box-shadow: 0 10px 22px -10px rgba(8,145,178,.8), inset 0 -5px 0 rgba(0,0,0,.18), inset 0 2px 0 rgba(255,255,255,.25); }
.ht-tile:hover:not(:disabled) { transform: translateY(-3px); }
.ht-tile:active:not(:disabled) { transform: translateY(1px) scale(.96); }
.ht-tile.used { opacity: .28; filter: grayscale(.6); transform: scale(.9); cursor: default; }
.ht-tile.used::after { content: "\2714"; position: absolute; right: 6px; top: 4px; font-size: 14px; color: #fff; }
.ht-tile:disabled:not(.used) { cursor: default; opacity: .75; }
.ht-tile:focus-visible, .ht-op:focus-visible { outline: 3px solid var(--gt-accent); outline-offset: 3px; }
@keyframes ht-deal { from { opacity: 0; transform: translateY(18px) rotate(-6deg) scale(.7); } to { opacity: 1; transform: none; } }
.ht-build { width: min(760px, 100%); display: flex; align-items: center; gap: 10px; min-height: 66px; padding: 10px 14px; border-radius: 20px;
  background: var(--gt-card); border: 2px dashed var(--gt-line); box-sizing: border-box; }
.ht-expr { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.ht-ph { color: var(--gt-soft); font-weight: 600; }
.ht-tok { font: 800 22px/1 var(--font, system-ui); padding: 8px 10px; border-radius: 10px; background: var(--gt-btn); }
.ht-tok.n { background: linear-gradient(160deg, var(--ht-tile1), var(--ht-tile2)); color: #fff; }
.ht-tok.last { animation: ht-tok-in .22s ease-out both; }
@keyframes ht-tok-in { from { transform: scale(.6); opacity: 0; } }
.ht-val { font: 900 26px/1 var(--font, system-ui); font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--gt-soft); }
.ht-val.hit { color: var(--ht-hit); animation: gt-pulse 1s ease-in-out 2; }
.ht-val.near { color: var(--ht-near); }
.ht-val.bad { color: var(--ht-bad); }
.ht-msg { margin: -4px 0 0; min-height: 1.3em; font-weight: 700; font-size: 14px; color: var(--gt-soft); text-align: center; }
.ht-msg.good { color: var(--ht-hit); } .ht-msg.bad { color: var(--ht-bad); }
.ht-msg.flash.on { animation: ht-shake .35s ease-in-out; }
@keyframes ht-shake { 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }
.ht-tray { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; width: min(760px, 100%); }
.ht-op { appearance: none; cursor: pointer; min-width: 58px; height: 56px; padding: 0 12px; border-radius: 16px; border: 1px solid var(--gt-line); background: var(--gt-btn); color: var(--gt-ink);
  font: 900 26px/1 var(--font, system-ui); transition: transform .12s, background-color .12s; }
.ht-op:hover:not(:disabled) { background: color-mix(in srgb, var(--gt-accent) 22%, transparent); }
.ht-op:active:not(:disabled) { transform: scale(.94); }
.ht-op:disabled { opacity: .4; cursor: default; }
.ht-acts { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.ht-acts .gt-go { min-width: 160px; font-size: 18px; }
.ht-mine { width: min(760px, 100%); display: none; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 10px 14px; border-radius: 16px; background: var(--gt-card); border: 1px solid var(--gt-line); box-sizing: border-box; }
.ht-mine.on { display: flex; animation: ht-tok-in .3s ease-out both; }
.ht-badge { font: 900 15px/1 var(--font, system-ui); padding: 7px 10px; border-radius: 999px; background: var(--gt-btn); }
.ht-badge.hit { background: color-mix(in srgb, var(--ht-hit) 22%, transparent); color: var(--ht-hit); }
.ht-badge.near { background: color-mix(in srgb, var(--ht-near) 22%, transparent); color: var(--ht-near); }
.ht-mtext { font-weight: 600; } .ht-mnote { color: var(--gt-soft); font-size: 13px; flex: 1 1 100%; }
/* the presenter while a round runs */
.ht-hostview { width: min(760px, 100%); }
.ht-subs { background: var(--gt-card); border: 1px solid var(--gt-line); border-radius: 20px; padding: 14px; }
.ht-subs-h { font-size: 15px; margin-bottom: 10px; } .ht-subs-h b { font-size: 26px; color: var(--gt-accent); }
.ht-subs-grid { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.ht-sp { display: inline-flex; align-items: center; gap: 6px; padding: 7px 11px; border-radius: 999px; background: var(--gt-btn); font-weight: 700; font-size: 14px; transition: background-color .25s; }
.ht-sp i { font-style: normal; width: 18px; text-align: center; color: var(--gt-soft); }
.ht-sp.done { background: color-mix(in srgb, var(--ht-hit) 20%, transparent); }
.ht-sp.done i { color: var(--ht-hit); }
.ht-sp.away { opacity: .5; }
.ht-side-h { display: flex; justify-content: space-between; align-items: baseline; font-size: 15px; }
.ht-side-h span { font-size: 12.5px; color: var(--gt-soft); }
.ht-score .gt-pl { gap: 8px; }
.ht-pl.you { border-color: var(--gt-accent); }
.ht-rk { width: 1.4em; text-align: center; font-weight: 900; color: var(--gt-soft); }
.ht-dn { width: 18px; text-align: center; color: var(--ht-hit); font-weight: 900; }
.ht-ctl { flex-wrap: wrap; }
/* leaderboard and final */
.ht-board { min-height: 0; overflow: auto; display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(260px, 0.8fr); grid-template-rows: auto auto; gap: clamp(12px, 2vw, 22px); align-content: start; padding-bottom: 12px; }
.ht-lb, .ht-sols { background: var(--gt-card); border: 1px solid var(--gt-line); border-radius: 24px; padding: clamp(16px, 2.6vw, 26px); }
.ht-lb { text-align: center; }
.ht-lb.ht-in { animation: gt-pop-flat .5s cubic-bezier(.2,1.3,.4,1) both; }
@keyframes gt-pop-flat { from { opacity: 0; transform: translateY(14px) scale(.96); } }
.ht-lb-act, .ht-lb-wait { grid-column: 1 / -1; }
.ht-lb-wait { text-align: center; font-weight: 700; }
.ht-rows { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; text-align: left; }
.ht-row { display: grid; grid-template-columns: 2.4em minmax(0, 1fr) minmax(0, 1.3fr) 3em 3.4em; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 14px; background: var(--gt-btn);
  animation: ht-row-in .45s ease-out var(--d, 0ms) both; }
.ht-board.final .ht-row { grid-template-columns: 2.4em minmax(0, 1fr) minmax(0, 1fr) 3.4em; }
@keyframes ht-row-in { from { opacity: 0; transform: translateX(-16px); } }
.ht-row.win { background: color-mix(in srgb, var(--gt-accent) 20%, transparent); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--gt-accent) 70%, transparent); }
.ht-row.you .nm { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 4px; }
.ht-row .pos { font-weight: 900; font-size: 18px; color: var(--gt-soft); text-align: center; }
.ht-row.win .pos { color: var(--gt-accent); }
.ht-row .nm { font-weight: 800; font-size: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ht-row .nm small { font-weight: 600; color: var(--gt-soft); }
.ht-crown { display: inline-block; animation: gt-bob 1.8s ease-in-out infinite; }
.ht-row .ht-how { font: 700 14px/1.2 var(--font, system-ui); color: var(--gt-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ht-how em { font-style: normal; font-weight: 900; }
.ht-how em.hit { color: var(--ht-hit); } .ht-how em.near { color: var(--ht-near); }
.ht-rp { font: 900 16px var(--font, system-ui); color: var(--ht-hit); text-align: right; font-variant-numeric: tabular-nums; }
.ht-tot { font: 900 22px var(--font, system-ui); text-align: right; font-variant-numeric: tabular-nums; }
.ht-spark { display: flex; align-items: flex-end; gap: 3px; height: 26px; }
.ht-spark i { flex: 1; max-width: 14px; height: var(--h, 6%); border-radius: 3px 3px 0 0; background: linear-gradient(180deg, var(--gt-accent), color-mix(in srgb, var(--gt-accent) 50%, transparent)); }
.ht-podium { display: flex; justify-content: center; align-items: flex-end; gap: 10px; margin: 6px 0 8px; }
.ht-pd { width: clamp(92px, 16vw, 140px); display: flex; flex-direction: column; align-items: center; gap: 2px; animation: ht-rise .7s cubic-bezier(.2,1.3,.4,1) both; }
.ht-pd b { font-size: 15px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ht-pm { font-size: 34px; line-height: 1; }
.ht-pt { font-size: 13px; color: var(--gt-soft); font-weight: 700; }
.ht-pb { width: 100%; border-radius: 14px 14px 6px 6px; display: flex; align-items: flex-start; justify-content: center; padding-top: 8px; font: 900 20px var(--font, system-ui); color: #1b2230; }
.ht-pb i { font-style: normal; }
.ht-pd.p1 .ht-pb { height: 92px; background: linear-gradient(180deg, #ffe08a, #ffc145); }
.ht-pd.p2 .ht-pb { height: 66px; background: linear-gradient(180deg, #e2e8f0, #cbd5e1); }
.ht-pd.p3 .ht-pb { height: 48px; background: linear-gradient(180deg, #fcd5b5, #f0a875); }
.ht-pd.p1 { animation-delay: .25s; } .ht-pd.p3 { animation-delay: .1s; }
@keyframes ht-rise { from { opacity: 0; transform: translateY(40px); } }
.ht-sols h4 { margin: 0 0 10px; font-size: 16px; font-weight: 800; }
.ht-sols-list { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ht-sols-list li { display: flex; flex-direction: column; gap: 3px; padding: 10px 12px; border-radius: 14px; background: var(--gt-btn); animation: ht-row-in .4s ease-out both; }
.ht-sols-list li.pool { border: 1px dashed var(--gt-line); background: transparent; }
.ht-sx { font: 800 20px/1.2 var(--font, system-ui); font-variant-numeric: tabular-nums; }
.ht-sby { font-size: 12.5px; color: var(--gt-soft); font-weight: 600; }
@media (max-width: 860px), (orientation: portrait) and (max-width: 1100px) {
  .ht-play { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; }
  .ht-side { max-height: 30vh; }
  .ht-board { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  .ht-head { grid-template-columns: auto 1fr auto; }
  .ht-target { padding: 8px 18px 10px; }
  .ht-opsel { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .ht-row { grid-template-columns: 2em minmax(0, 1fr) 2.6em 3em; } .ht-row .ht-how { display: none; }
  .ht-board.final .ht-row { grid-template-columns: 2em minmax(0, 1fr) 3em; } .ht-board.final .ht-spark { display: none; }
  .ht-op { min-width: 50px; height: 50px; }
}
@media (prefers-reduced-motion: reduce) {
  #ht-screen *, #ht-screen *::after { animation: none !important; transition: none !important; }
}
.ht-parts { grid-column: 2 / -1; display: flex; flex-wrap: wrap; gap: 4px; margin-top: 2px; }
.ht-parts i { font-style: normal; font: 700 11.5px/1 var(--font, system-ui); padding: 5px 7px; border-radius: 999px; background: var(--gt-btn); color: var(--gt-soft); }
/* v279: the lobby demos on narrow screens (the Dots rule hides step captions; the demos must stay) */
@media (max-width: 860px), (orientation: portrait) and (max-width: 1100px) {
  .ht-steps .ht-demo span { display: inline-flex; }
  .ht-steps .ht-demo { height: 64px; gap: 3px; margin-top: 22px; }
  .ht-d3 span:nth-child(3) { display: none; }
  .ht-d1 .ht-dt { font-size: 32px; padding: 6px 12px; }
  .ht-d2 i { width: 24px; height: 32px; font-size: 16px; border-radius: 7px; }
  .ht-d2 em { font-size: 15px; }
  .ht-d3 { flex-wrap: wrap; }
  .ht-d3 span { font-size: 14px; padding: 5px 6px; color: #059669; }
  .ht-d3 span:nth-child(2) { color: #b45309; }
}
.ht-side-h { gap: 8px; }
/* v280: a student with several writing boxes — the count rides on the ▭ button */
#collab-admitted .collab-mini.ea { position: relative; }
/* REPORTED (v280): the box count hung off the button's corner and knocked the
   row out of line. It now sits inside the button, beside the ▭. */
#collab-admitted .collab-mini { height: 28px; display: inline-flex; align-items: center; justify-content: center; gap: 4px; flex: none; }
#collab-admitted .collab-mini.ea .ea-n { min-width: 15px; height: 15px; padding: 0 4px; border-radius: 8px; background: rgba(0,0,0,.22); color: #fff; font: 800 10px/15px system-ui, sans-serif; text-align: center; }
/* v280: the timer on a student's screen — a clock to watch, not a set of the host's controls */
#timer-card.tv #timer-tabs, #timer-card.tv #timer-presets, #timer-card.tv #timer-adjust, #timer-card.tv #timer-reset,
#timer-card.tv #timer-toggle, #timer-card.tv #timer-music, #timer-card.tv #timer-opts, #timer-card.tv .timer-lap-row,
#timer-card.tv .timer-ag-opts, #timer-card.tv #timer-seg-list, #timer-card.tv #timer-mini-toggle, #timer-card.tv #timer-alarm { display: none !important; }
#timer-card.tv #timer-time { pointer-events: none; }
#timer-card.tv #timer-controls { justify-content: center; }
/* v280 (reported): the Collab panel, when open, sits above the timer — for the host and for students */
body.collab-panel-open #timer-card { z-index: 69; }
/* v280: the access code is masked, with an eye to show it */
.collab-pw { position: relative; }
.collab-pw .collab-input { padding-right: 46px; }
.collab-pw-eye { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 34px; height: 34px; border: 0; border-radius: 9px;
  background: transparent; color: var(--cp-muted); display: grid; place-items: center; cursor: pointer; }
.collab-pw-eye:hover { background: var(--cp-raised-2); color: var(--cp-text); }
.collab-pw-eye:focus-visible { outline: 2px solid var(--accent, #6c5ce7); outline-offset: 1px; }
.collab-pw-eye svg { width: 18px; height: 18px; }
.collab-pw-eye .eye-shut { display: none; }
.collab-pw-eye[aria-pressed="true"] .eye-open { display: none; }
.collab-pw-eye[aria-pressed="true"] .eye-shut { display: block; }
/* ==================== v280: the helper genie's ask panel ====================
   Question first; walkthroughs and guide answers under it, cut to fit the
   room above the bubble rather than scrolled. */
#genie-pop { width: 420px; min-width: 0; max-width: calc(100vw - 16px); padding: 14px 14px 12px; overflow: hidden; display: flex; flex-direction: column;
  transform-origin: bottom right; }
#genie-pop.narrow { width: auto; }
#genie-pop .gp-head { display: flex; align-items: center; justify-content: space-between; margin: 0 2px 8px; }
#genie-pop .gp-head h4 { margin: 0; color: rgba(255,255,255,0.72); letter-spacing: .08em; }
#genie-pop .gp-x { appearance: none; border: 0; background: transparent; color: rgba(255,255,255,0.6); width: 30px; height: 30px; border-radius: 8px; font-size: 22px; line-height: 1; cursor: pointer; }
#genie-pop .gp-x:hover { background: rgba(255,255,255,0.1); color: #fff; }
#genie-pop .genie-ask { flex-direction: row; margin: 0 0 4px; gap: 8px; flex: none; }
#genie-pop .genie-ask input { flex: 1; min-width: 0; font-size: 15px; -webkit-appearance: none; appearance: none; }
#genie-pop .genie-ask input::-webkit-search-cancel-button { filter: invert(1); opacity: .6; }
#genie-pop .genie-ask .pop-action { height: 44px; padding: 0 18px; border-radius: 11px; flex: none; }
#genie-suggest { min-height: 0; }
#genie-suggest .gs-h { font: 700 11px/1 var(--font, system-ui); letter-spacing: .14em; text-transform: uppercase; color: rgba(251,191,36,0.85); margin: 12px 4px 7px; }
#genie-suggest .gs-list { display: flex; flex-direction: column; gap: 5px; }
#genie-suggest .genie-suggest-btn { display: flex; align-items: center; gap: 10px; margin: 0; padding: 9px 12px; min-height: 40px; }
#genie-suggest .genie-suggest-btn .gs-ic { flex: none; width: 22px; height: 22px; border-radius: 7px; display: grid; place-items: center; font-size: 9px;
  background: linear-gradient(135deg, var(--genie-gold), var(--genie-gold-deep)); color: #3f2a02; }
#genie-suggest .genie-suggest-btn .gs-t { flex: 1; min-width: 0; font-size: 13.5px; line-height: 1.3; }
#genie-suggest .genie-guide-hit { display: block; text-decoration: none; padding: 8px 12px; border-radius: 12px; background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.08); color: #fff; transition: background .15s, border-color .15s; }
#genie-suggest .genie-guide-hit:hover, #genie-suggest .genie-guide-hit:focus-visible { background: rgba(255,255,255,0.12); border-color: rgba(251,191,36,0.5); outline: none; }
#genie-suggest .gg-where { display: block; font: 700 13px/1.3 var(--font, system-ui); }
#genie-suggest .gg-where span { font-weight: 600; color: rgba(251,191,36,0.9); }
#genie-suggest .gg-where::after { content: " \2197"; color: rgba(255,255,255,0.45); font-weight: 400; }
#genie-suggest .gg-snip { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: 12.5px; line-height: 1.4; color: rgba(255,255,255,0.68); margin-top: 3px; }
#genie-suggest .gg-snip mark { background: rgba(251,191,36,0.28); color: #fff; border-radius: 3px; padding: 0 1px; }
#genie-suggest .gs-none, #genie-suggest .gs-more { color: rgba(255,255,255,0.62); font-size: 12.5px; margin: 12px 4px 2px; }
#genie-suggest .gs-none a { color: var(--genie-gold); }
#genie-suggest [hidden] { display: none !important; }
/* the bubble steps up out of the way of a minimised timer in the same corner */
body:has(#timer-card.show.mini) #genie-launcher { bottom: 84px; }
/* v280: the genie is on by default, so on a phone the bubble must sit clear of
   the tool rail along the bottom: smaller, tucked into the corner below it, and
   on the left when a minimised timer already holds the right-hand corner. */
@media (max-width: 560px) {
  #genie-launcher { width: 50px; height: 50px; right: 12px; bottom: 12px; }
  #genie-launcher svg { width: 28px; height: 28px; }
  body:has(#timer-card.show.mini) #genie-launcher { bottom: 12px; right: auto; left: 12px; }
  body:has(#collab-panel.show) #genie-launcher, body.collab-panel-open #genie-launcher { display: none; }
}
#genie-pop.open { z-index: 126; }
/* v280: the genie as a copilot — the "Do it" line, quick picks and follow-ups */
#genie-suggest .gd-card { margin: 10px 0 2px; }
#genie-suggest .gd-do { appearance: none; width: 100%; display: flex; align-items: center; gap: 10px; text-align: left; cursor: pointer;
  padding: 11px 12px; border-radius: 13px; border: 1px solid rgba(251,191,36,0.55);
  background: linear-gradient(135deg, rgba(251,191,36,0.22), rgba(245,158,11,0.12)); color: #fff; font: 600 14px/1.3 var(--font, system-ui); }
#genie-suggest .gd-do:hover, #genie-suggest .gd-do:focus-visible { background: linear-gradient(135deg, rgba(251,191,36,0.32), rgba(245,158,11,0.2)); outline: none; }
#genie-suggest .gd-do .gd-ic { flex: none; width: 28px; height: 28px; border-radius: 9px; display: grid; place-items: center; font-size: 15px;
  background: linear-gradient(135deg, var(--genie-gold), var(--genie-gold-deep)); }
#genie-suggest .gd-do .gd-say { flex: 1; min-width: 0; }
#genie-suggest .gd-do .gd-say b { color: var(--genie-gold); margin-right: 4px; }
#genie-suggest .gd-do kbd { flex: none; font: 600 10.5px/1 var(--font, system-ui); padding: 5px 7px; border-radius: 6px; background: rgba(255,255,255,0.12); color: rgba(255,255,255,0.75); }
#genie-suggest .gd-picks { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 8px 2px 0; }
#genie-suggest .gd-picks > span { color: rgba(255,255,255,0.7); font-size: 12.5px; margin-right: 2px; }
#genie-suggest .gd-chip { appearance: none; cursor: pointer; padding: 6px 11px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.18);
  background: rgba(255,255,255,0.08); color: #fff; font: 600 12.5px/1.2 var(--font, system-ui); }
#genie-suggest .gd-chip:hover, #genie-suggest .gd-chip:focus-visible { background: rgba(255,255,255,0.16); border-color: rgba(251,191,36,0.6); outline: none; }
#genie-suggest .gd-none p { color: rgba(255,255,255,0.8); font-size: 13px; margin: 0 2px 8px; }
#genie-suggest .gd-done { margin: 12px 2px 8px; padding: 9px 12px; border-radius: 12px; font: 600 13.5px/1.35 var(--font, system-ui); color: #fff;
  background: rgba(34,197,94,0.16); border: 1px solid rgba(34,197,94,0.4); }
#genie-suggest .gd-done.no { background: rgba(251,191,36,0.12); border-color: rgba(251,191,36,0.4); }
#genie-suggest .gd-done span { font-weight: 800; margin-right: 4px; }
#genie-suggest .gd-follow { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 0 2px; }
#genie-suggest .gd-sw { display: inline-flex; gap: 5px; margin-left: 2px; }
#genie-suggest .gd-swatch { appearance: none; width: 24px; height: 24px; border-radius: 50%; border: 2px solid rgba(255,255,255,0.7); cursor: pointer; padding: 0; }
#genie-suggest .gd-swatch:hover, #genie-suggest .gd-swatch:focus-visible { transform: scale(1.12); outline: none; border-color: var(--genie-gold); }
/* ==================== v280: the helper's face ====================
   The bubble takes its colours from the chosen mascot (mascots.js). Genie's
   own purple stays the fallback, so nothing changes for anyone who never picks. */
#genie-launcher { background: radial-gradient(circle at 30% 28%, var(--m-bg1, var(--genie-purple)), var(--m-bg2, var(--genie-purple-dark)));
  box-shadow: 0 12px 30px rgba(var(--m-glow, 124,58,237), 0.5); }
#genie-launcher:hover { box-shadow: 0 14px 36px rgba(var(--m-glow, 124,58,237), 0.65); }
#genie-launcher .genie-spark { background: var(--m-accent, var(--genie-gold)); }
#genie-launcher .mascot-svg { width: 46px; height: 46px; overflow: visible; }
@media (max-width: 560px) { #genie-launcher .mascot-svg { width: 38px; height: 38px; } }
/* Ready to animate: every part turns and scales about its own centre. */
.mascot-svg .m-body, .mascot-svg .m-head, .mascot-svg .m-eyes, .mascot-svg .m-eye, .mascot-svg .m-mouth,
.mascot-svg .m-arm-l, .mascot-svg .m-arm-r, .mascot-svg .m-ear-l, .mascot-svg .m-ear-r, .mascot-svg .m-acc { transform-box: fill-box; transform-origin: center; }
.mascot-svg .m-arm-l { transform-origin: right top; } .mascot-svg .m-arm-r { transform-origin: left top; }
.mascot-svg .m-ear-l, .mascot-svg .m-ear-r { transform-origin: center bottom; }
/* The only motion for now: an occasional blink, and a hello when a helper arrives. */
#genie-launcher .m-eye { animation: m-blink 6s infinite; }
#genie-launcher .m-eye + .m-eye { animation-delay: .04s; }
@keyframes m-blink { 0%, 95.5%, 100% { transform: scaleY(1); } 97% { transform: scaleY(.1); } }
#genie-launcher.m-hello .m-body { animation: m-hello .8s cubic-bezier(.34,1.56,.64,1); }
@keyframes m-hello { 0% { transform: scale(.4) rotate(-12deg); opacity: 0; } 60% { transform: scale(1.12) rotate(4deg); opacity: 1; } 100% { transform: none; } }
@media (prefers-reduced-motion: reduce) { #genie-launcher .m-eye, #genie-launcher.m-hello .m-body { animation: none; } }

/* the face in the ask panel's header: tap it to change helper */
#genie-pop .gp-head { justify-content: flex-start; gap: 9px; }
#genie-pop .gp-head h4 { flex: 1; }
#genie-pop .gp-face { appearance: none; flex: none; width: 30px; height: 30px; border-radius: 50%; border: 1.5px solid rgba(255,255,255,.35); padding: 0; cursor: pointer;
  display: grid; place-items: center; background: radial-gradient(circle at 30% 28%, var(--m-bg1, #7c3aed), var(--m-bg2, #4c1d95)); }
#genie-pop .gp-face .mascot-svg { width: 27px; height: 27px; }
#genie-pop .gp-face:hover, #genie-pop .gp-face:focus-visible { border-color: var(--genie-gold); outline: none; transform: scale(1.08); }
#genie-pop .gp-head h4::before { content: none; }

/* the chooser */
#mascot-pick { position: fixed; z-index: 127; width: 300px; max-width: calc(100vw - 16px); padding: 14px; border-radius: 18px;
  background: linear-gradient(165deg, rgba(30,27,75,0.97), rgba(46,16,101,0.97)); border: 1px solid rgba(255,255,255,0.14);
  box-shadow: 0 28px 70px rgba(30,27,75,0.55); color: #fff; backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); }
#mascot-pick[hidden] { display: none; }
#mascot-pick.in { animation: mp-in .22s cubic-bezier(.2,.9,.3,1.2); }
@keyframes mp-in { from { opacity: 0; transform: translateY(8px) scale(.96); } to { opacity: 1; transform: none; } }
#mascot-pick .mp-head { display: flex; align-items: center; justify-content: space-between; margin: 0 2px 10px; }
#mascot-pick .mp-head b { font: 800 13px/1 var(--font, system-ui); letter-spacing: .1em; text-transform: uppercase; color: rgba(255,255,255,.8); }
#mascot-pick .mp-x { appearance: none; border: 0; background: transparent; color: rgba(255,255,255,.6); width: 28px; height: 28px; border-radius: 8px; font-size: 20px; cursor: pointer; }
#mascot-pick .mp-x:hover { background: rgba(255,255,255,.1); color: #fff; }
#mascot-pick .mp-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
#mascot-pick .mp-tile { appearance: none; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 4px 8px;
  border-radius: 14px; border: 1.5px solid rgba(255,255,255,.1); background: rgba(255,255,255,.05); color: #fff; transition: transform .15s, background .15s, border-color .15s; }
#mascot-pick .mp-tile:hover, #mascot-pick .mp-tile:focus-visible { background: rgba(255,255,255,.12); outline: none; transform: translateY(-2px); }
#mascot-pick .mp-tile.on { border-color: var(--genie-gold); background: rgba(251,191,36,.12); }
#mascot-pick .mp-face { width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center;
  background: radial-gradient(circle at 30% 28%, var(--m-bg1), var(--m-bg2)); box-shadow: 0 8px 18px rgba(var(--m-glow), .45); }
#mascot-pick .mp-face .mascot-svg { width: 44px; height: 44px; overflow: visible; }
#mascot-pick .mp-tile:hover .mascot-svg .m-body { animation: m-wiggle .5s ease-in-out; }
@keyframes m-wiggle { 25% { transform: rotate(-6deg); } 75% { transform: rotate(6deg); } }
@media (prefers-reduced-motion: reduce) { #mascot-pick.in, #mascot-pick .mp-tile:hover .mascot-svg .m-body { animation: none; } }
#mascot-pick .mp-name { font: 700 13px/1 var(--font, system-ui); }
#mascot-pick .mp-tile.on .mp-name::after { content: " \2713"; color: var(--genie-gold); }
#mascot-pick .mp-line { min-height: 2.6em; margin: 10px 4px 2px; font-size: 13px; line-height: 1.35; color: rgba(255,255,255,.85); }
#mascot-pick .mp-hint { margin: 2px 4px 0; font-size: 11.5px; color: rgba(255,255,255,.5); }

/* v280: links for later (presenter) and waiting for the teacher (student). */
#collab-panel .collab-saved { margin-top: 12px; }
#collab-panel .collab-saved[hidden] { display: none; }
#collab-panel .collab-saved-head { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 13px; margin-bottom: 6px; }
#collab-panel .collab-saved-ok { margin-left: auto; font: 600 11px/1 var(--font); color: #34d399; }
#collab-panel [data-view="presenter"] .collab-saved { margin: 12px 0; }
#collab-panel .collab-saved-body { padding: 10px; border: 1px solid var(--cp-line); border-radius: 10px; }
#collab-panel .collab-saved-body .collab-hint { margin-top: 0; }
#collab-panel .collab-saved-list { list-style: none; margin: 0 0 8px; padding: 0; display: grid; gap: 8px; }
#collab-panel .collab-saved-item { padding: 9px 10px; border-radius: 10px; border: 1px solid var(--cp-line); background: var(--cp-raised); display: grid; gap: 7px; min-width: 0; }
#collab-panel .csl-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
#collab-panel .csl-name { font-weight: 700; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; }
#collab-panel .csl-live { font: 700 11px/1 var(--font); color: #34d399; white-space: nowrap; flex: none; }
/* line 2: the code, its two icon buttons, and Start on the right */
#collab-panel .csl-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
#collab-panel .csl-code { font: 700 14px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: .1em; white-space: nowrap; margin-right: 2px; }
#collab-panel .csl-row .collab-chip, #collab-panel .csl-acts .collab-chip { height: 28px; padding: 0 10px; font-size: 11.5px; display: inline-flex; align-items: center; justify-content: center; gap: 4px; white-space: nowrap; }
#collab-panel .csl-row .csl-icon { width: 28px; padding: 0; flex: none; }
#collab-panel .csl-row .csl-icon svg { width: 15px; height: 15px; display: block; }
#collab-panel .csl-row .csl-start { margin-left: auto; flex: none; background: var(--accent, #6c5ce7); border-color: var(--accent, #6c5ce7); color: #fff; }
/* line 3: Rename · Reset · Delete, one even row */
#collab-panel .csl-acts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
#collab-panel .csl-acts .collab-chip { width: 100%; min-width: 0; }
#collab-panel .csl-acts .collab-chip.danger { color: #e5484d; }
#collab-panel .collab-saved-item .collab-chip:disabled { opacity: .4; cursor: default; }
#collab-panel .collab-saved-new { display: flex; gap: 6px; }
#collab-panel .collab-saved-new .collab-input { flex: 1; min-width: 0; margin: 0; }
#collab-panel .collab-saved-new { align-items: stretch; }
#collab-panel .collab-saved-new .collab-chip { white-space: nowrap; flex: none; display: inline-flex; align-items: center; }
#collab-panel .collab-saved-msg { margin: 8px 0 0; }
#collab-panel .collab-wait { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; padding: 9px 11px; border-radius: 9px;
  border: 1px solid var(--cp-line); background: var(--cp-raised); font-size: 12.5px; line-height: 1.4; }
#collab-panel .collab-wait[hidden] { display: none; }
#collab-panel .collab-wait-dot { width: 9px; height: 9px; border-radius: 50%; background: #fbbf24; flex: none; animation: collabWaitPulse 1.6s ease-in-out infinite; }
#collab-panel #collab-wait-text { flex: 1; min-width: 160px; }
#collab-panel .collab-wait-stop { appearance: none; border: 0; background: none; color: var(--cp-text); text-decoration: underline; font: inherit; cursor: pointer; padding: 0; opacity: .8; }
@keyframes collabWaitPulse { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { #collab-panel .collab-wait-dot { animation: none; } }

/* v280: edit points */
#pt-bar { position: fixed; z-index: 46; display: flex; align-items: center; gap: 4px; padding: 5px 6px 5px 12px;
  border-radius: 12px; background: var(--surface-solid, #1f2230); border: 1px solid var(--border); box-shadow: 0 10px 30px rgba(0,0,0,.35);
  font: 600 12.5px/1 var(--font); color: var(--text); max-width: calc(100vw - 16px); flex-wrap: wrap; }
#pt-bar[hidden] { display: none; }
#pt-bar .pt-title { font-weight: 700; }
#pt-bar .pt-count { color: var(--muted); font-weight: 500; margin: 0 6px 0 2px; }
#pt-bar button { border: 0; background: transparent; color: var(--text); font: inherit; padding: 7px 10px; border-radius: 8px; cursor: pointer; }
#pt-bar button:hover:not(:disabled) { background: var(--hover); }
#pt-bar button:disabled { opacity: .4; cursor: default; }
#pt-bar button[aria-pressed="true"] { background: var(--accent); color: #fff; }
#pt-bar .pt-done { background: var(--accent); color: #fff; }
#sel-points[aria-pressed="true"] { background: var(--accent); color: #fff; }

/* v280: Present is a sign-in, then a presenter home. */
#collab-panel #collab-signin[hidden], #collab-panel #collab-home[hidden] { display: none; }
#collab-panel .collab-home-head { display: flex; align-items: center; gap: 8px; margin: 2px 0 6px; font-size: 13px; }
#collab-panel .collab-home-ok { font-weight: 700; color: #16a34a; }
#collab-panel .collab-signout { margin-left: auto; appearance: none; border: 1px solid var(--cp-line); background: transparent; color: var(--cp-text); border-radius: 8px; padding: 5px 10px; font: 600 12px/1 var(--font); cursor: pointer; }
#collab-panel .collab-signout:hover { border-color: var(--accent); }

/* v280: Links for later inside its fold row while presenting — the group row
   carries the title, so the list's own heading and frame step back. */
#collab-panel #collab-saved-slot .collab-saved { margin: 0 0 10px; }
#collab-saved-slot .collab-saved-head { display: none; }
#collab-panel .collab-group[hidden] { display: none !important; }
