    /* ============================================================
       DESIGN TOKENS
       Every accent color below was checked for >= 4.5:1 contrast
       against the text color placed on it. Gradients run dark -> mid
       (never dark -> bright) so white text stays legible across the
       whole sweep.
       ============================================================ */
    :root {
      color-scheme: light;

      /* Brand */
      --brand-1: #0F766E;          /* teal-700  */
      --brand-2: #0E7490;          /* cyan-700  */

      /* Stage identities — color + shape + text, never color alone */
      --stage-start-1: #3730A3;    /* indigo-800 */
      --stage-start-2: #4F46E5;    /* indigo-600 */
      --stage-half-1:  #9A3412;    /* orange-800 */
      --stage-half-2:  #C2410C;    /* orange-700 */
      --stage-finish-1:#065F46;    /* emerald-800 */
      --stage-finish-2:#047857;    /* emerald-700 */

      /* Semantic */
      --ok: #047857;
      --warn: #C2410C;

      /* Surfaces */
      --bg: #EEF2F7;
      --bg-tint-1: rgba(15, 118, 110, 0.10);
      --bg-tint-2: rgba(14, 116, 144, 0.08);
      --surface: #FFFFFF;
      --surface-2: #F8FAFC;
      --text: #0F172A;
      --muted: #475569;
      --outline: #0F172A;
      --border: #CBD5E1;
      --accent: var(--brand-1);
      --on-accent: #FFFFFF;

      --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.07);
      --shadow-md: 0 2px 6px rgba(15, 23, 42, 0.08), 0 10px 28px rgba(15, 23, 42, 0.10);
      --shadow-lg: 0 8px 20px rgba(15, 23, 42, 0.14), 0 24px 48px rgba(15, 23, 42, 0.16);

      --radius-sm: 12px;
      --radius: 18px;
      --radius-lg: 26px;

      --viewport-height: 100vh;
    }

    body[data-theme="light"] {
      color-scheme: light;
      --bg: #EEF2F7;
      --surface: #FFFFFF;
      --surface-2: #F8FAFC;
      --text: #0F172A;
      --muted: #475569;
      --outline: #0F172A;
      --border: #CBD5E1;
      --brand-1: #0F766E;
      --brand-2: #0E7490;
      --accent: #0F766E;
      --on-accent: #FFFFFF;
      --bg-tint-1: rgba(15, 118, 110, 0.10);
      --bg-tint-2: rgba(14, 116, 144, 0.08);
    }

    body[data-theme="dark"] {
      color-scheme: dark;
      --bg: #070C14;
      --surface: #131C2B;
      --surface-2: #1B2637;
      --text: #E8EEF7;
      --muted: #A8B6C8;
      --outline: #E8EEF7;
      --border: #2C3A4E;
      --brand-1: #2DD4BF;
      --brand-2: #38BDF8;
      --accent: #2DD4BF;
      /* Dark ink on the light teal accent (~10:1). White here was ~1.8:1. */
      --on-accent: #04141A;
      --ok: #34D399;
      --on-ok: #04141A;
      --warn: #FB923C;
      --bg-tint-1: rgba(45, 212, 191, 0.10);
      --bg-tint-2: rgba(56, 189, 248, 0.08);
      --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
      --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.5), 0 10px 28px rgba(0, 0, 0, 0.45);
      --shadow-lg: 0 8px 20px rgba(0, 0, 0, 0.55), 0 24px 48px rgba(0, 0, 0, 0.5);
    }

    body[data-theme="inverted"] {
      color-scheme: dark;
      --bg: #000000;
      --surface: #000000;
      --surface-2: #000000;
      --text: #FFFF00;
      --muted: #FFF176;
      --outline: #FFFF00;
      --border: #FFFF00;
      --brand-1: #00FFFF;
      --brand-2: #00FFFF;
      --accent: #00FFFF;
      /* Black on cyan; white on cyan fails contrast. */
      --on-accent: #000000;
      --ok: #00FF66;
      --on-ok: #000000;
      --warn: #FF8C00;
      --bg-tint-1: transparent;
      --bg-tint-2: transparent;
      --shadow-sm: none;
      --shadow-md: none;
      --shadow-lg: none;
    }

    body.high-contrast {
      --bg: #FFFFFF;
      --surface: #FFFFFF;
      --surface-2: #FFFFFF;
      --text: #000000;
      --muted: #1A1A1A;
      --outline: #000000;
      --border: #000000;
      --brand-1: #000000;
      --brand-2: #000000;
      --accent: #000000;
      --on-accent: #FFFFFF;
      --ok: #000000;
      --warn: #000000;
      --bg-tint-1: transparent;
      --bg-tint-2: transparent;
      --shadow-sm: none;
      --shadow-md: none;
      --shadow-lg: none;
    }

    /* High contrast on a dark or inverted theme stays dark: white (or yellow)
       on black. It used to turn the screen white while the browser still drew
       its own controls dark, which hid the Settings title (white on white)
       and made an unselected radio button look selected (bug 26). */
    body.high-contrast[data-theme="dark"] {
      color-scheme: dark;
      --bg: #000000;
      --surface: #000000;
      --surface-2: #000000;
      --text: #FFFFFF;
      --muted: #F2F2F2;
      --outline: #FFFFFF;
      --border: #FFFFFF;
      --brand-1: #FFFFFF;
      --brand-2: #FFFFFF;
      --accent: #FFFFFF;
      --on-accent: #000000;
      --ok: #FFFFFF;
      --on-ok: #000000;
      --warn: #FFFFFF;
    }
    body.high-contrast[data-theme="inverted"] {
      color-scheme: dark;
      --bg: #000000;
      --surface: #000000;
      --surface-2: #000000;
      --text: #FFFF00;
      --muted: #FFF176;
      --outline: #FFFF00;
      --border: #FFFF00;
      --brand-1: #00FFFF;
      --brand-2: #00FFFF;
      --accent: #00FFFF;
      --on-accent: #000000;
      --ok: #00FF66;
      --on-ok: #000000;
      --warn: #FF8C00;
    }
    dialog { color: var(--text); }

    /* Input boundaries need 3:1 against what is around them; the card border
       colour was about 1.4:1 (bug 34, Oct 2026 review). Cards keep their light border. */
    :root, body[data-theme="light"] { --control-border: #64748B; }
    body[data-theme="dark"] { --control-border: #8A9BB2; }
    body[data-theme="inverted"] { --control-border: #FFFF00; }
    body.high-contrast { --control-border: #000000; }
    body.high-contrast[data-theme="dark"] { --control-border: #FFFFFF; }
    body.high-contrast[data-theme="inverted"] { --control-border: #FFFF00; }

    /* Flatten every gradient in the two "maximum legibility" themes. */
    body.high-contrast .action-btn,
    body.high-contrast .brand-mark,
    body[data-theme="inverted"] .action-btn,
    body[data-theme="inverted"] .brand-mark {
      background-image: none !important;
    }

    html { font-size: 18px; }

/* First paint on a dark-mode device, before JS sets body[data-theme].
   Without this the page flashes light for a frame on launch. */
@media (prefers-color-scheme: dark) {
  body:not([data-theme]) {
    color-scheme: dark;
    --bg: #070C14;
    --surface: #131C2B;
    --surface-2: #1B2637;
    --text: #E8EEF7;
    --muted: #A8B6C8;
    --outline: #E8EEF7;
    --border: #2C3A4E;
    --brand-1: #2DD4BF;
    --brand-2: #38BDF8;
    --accent: #2DD4BF;
    --on-accent: #04141A;
    --bg-tint-1: rgba(45, 212, 191, 0.10);
    --bg-tint-2: rgba(56, 189, 248, 0.08);
  }
}

/* Paint the canvas edge to edge (under the status bar and home indicator);
   .panel already pads for the safe areas. */
html { background: var(--bg); min-height: 100%; }


    *, *::before, *::after { box-sizing: border-box; }

    body {
      margin: 0;
      font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
      -webkit-text-size-adjust: 100%;
      text-size-adjust: 100%;
      -webkit-font-smoothing: antialiased;
      background-color: var(--bg);
      background-image:
        radial-gradient(120% 70% at 12% -8%, var(--bg-tint-1) 0%, transparent 60%),
        radial-gradient(110% 60% at 92% 4%, var(--bg-tint-2) 0%, transparent 55%);
      background-attachment: fixed;
      color: var(--text);
      font-size: 1rem;
      display: flex;
      min-height: var(--viewport-height);
      align-items: flex-start;
      justify-content: center;
      overflow-x: hidden;
      overscroll-behavior-y: none;
      /* Kill the iOS tap-highlight + text selection during rapid marking. */
      -webkit-tap-highlight-color: transparent;
    }

    body.dialog-open {
      position: fixed;
      inset: 0;
      width: 100%;
      overflow: hidden;
    }

    .panel {
      width: min(560px, 100vw);
      display: flex;
      flex-direction: column;
      gap: 18px;
      padding:
        calc(14px + env(safe-area-inset-top))
        18px
        calc(20px + env(safe-area-inset-bottom));
      min-width: 0;
    }

    .panel > * { min-width: 0; }

    /* ---------------- Header ---------------- */
    .app-header {
      position: sticky;
      top: 0;
      z-index: 20;
      display: flex;
      align-items: center;
      gap: 10px;
      min-width: 0;
      /* Escape the panel's padding so the bar runs edge to edge and sits
         behind the status bar; then pad for the safe area itself. */
      margin: calc(-1 * (14px + env(safe-area-inset-top))) -18px 0;
      padding: calc(8px + env(safe-area-inset-top)) 14px 8px;
      background: color-mix(in srgb, var(--surface) 82%, transparent);
      -webkit-backdrop-filter: saturate(160%) blur(18px);
      backdrop-filter: saturate(160%) blur(18px);
      border-bottom: 1px solid var(--border);
    }

    @supports not (background: color-mix(in srgb, red 50%, transparent)) {
      .app-header { background: var(--surface); }
    }

    .brand {
      display: flex;
      align-items: center;
      gap: 10px;
      min-width: 0;
      flex: 1 1 auto;
    }

    .brand-mark {
      width: 2.25rem;
      height: 2.25rem;
      flex: 0 0 auto;
      border-radius: 10px;
      background-image: linear-gradient(150deg, var(--brand-1), var(--brand-2));
      background-color: var(--brand-1);
      display: grid;
      place-items: center;
      border: 1px solid transparent;
    }

    .brand-mark svg {
      width: 66%;
      height: 66%;
      display: block;
      fill: none;
      stroke: var(--on-accent);
      stroke-width: 2.1;
      stroke-linecap: round;
      stroke-linejoin: round;
    }

    body.high-contrast .brand-mark,
    body[data-theme="inverted"] .brand-mark {
      background-color: var(--accent);
      border-color: var(--outline);
    }

    .brand-text { min-width: 0; }

    .app-title {
      margin: 0;
      font-size: 1.05rem;
      font-weight: 700;
      letter-spacing: -0.01em;
      line-height: 1.2;
      color: var(--text);
      overflow-wrap: anywhere;
    }

    .app-subtitle {
      margin: 1px 0 0;
      font-size: 0.68rem;
      font-weight: 600;
      letter-spacing: 0.09em;
      text-transform: uppercase;
      color: var(--muted);
      overflow-wrap: anywhere;
    }

    .header-actions {
      display: flex;
      gap: 2px;
      flex: 0 0 auto;
    }

    .icon-btn {
      width: 2.6rem;
      height: 2.6rem;
      border-radius: 12px;
      border: 1px solid transparent;
      background: transparent;
      color: var(--text);
      display: inline-grid;
      place-items: center;
      cursor: pointer;
      padding: 0;
      transition: background-color 120ms ease;
    }

    .icon-btn:hover { background: var(--surface-2); }
    .icon-btn:active { background: var(--border); }

    /* High-contrast and inverted themes keep an explicit outline on every control. */
    body.high-contrast .icon-btn,
    body[data-theme="inverted"] .icon-btn {
      border-color: var(--outline);
    }

    .icon-btn svg {
      width: 1.4rem;
      height: 1.4rem;
      display: block;
      fill: none;
      stroke: currentColor;
      stroke-width: 1.8;
      stroke-linecap: round;
      stroke-linejoin: round;
    }

    .icon-btn:disabled { opacity: 0.5; cursor: not-allowed; }

    /* ---------------- Cards ---------------- */
    .card {
      background: var(--surface);
      border: 1px solid var(--border);
      border-radius: var(--radius);
      padding: 14px;
      box-shadow: var(--shadow-sm);
      min-width: 0;
    }

    .card-label {
      margin: 0 0 10px;
      font-size: 0.78rem;
      line-height: 1.3;
      font-weight: 700;
      letter-spacing: 0.07em;
      text-transform: uppercase;
      color: var(--muted);
      overflow-wrap: anywhere;
    }

    /* ---------------- Mode selector ---------------- */
    .mode-toggle {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 8px;
      border: none;
      padding: 0;
      margin: 0;
      min-width: 0;
    }

    .mode-toggle label {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      gap: 4px;
      text-align: center;
      padding: 11px 8px;
      border-radius: 14px;
      border: 2px solid var(--border);
      background: var(--surface-2);
      color: var(--text);
      cursor: pointer;
      min-height: 3.4rem;
      font-size: 0.86rem;
      font-weight: 600;
      line-height: 1.2;
      min-width: 0;
      overflow-wrap: anywhere;
    }

    .mode-toggle input[type="radio"] {
      position: absolute;
      width: 1px; height: 1px;
      padding: 0; margin: -1px;
      overflow: hidden;
      clip: rect(0, 0, 0, 0);
      white-space: nowrap;
      border: 0;
    }

    .mode-toggle label:has(input:checked) {
      background: var(--accent);
      color: var(--on-accent);
      border-color: var(--accent);
      box-shadow: var(--shadow-sm);
    }

    .mode-toggle label:focus-within {
      outline: 4px solid var(--outline);
      outline-offset: 2px;
    }

    .mode-dots {
      display: flex;
      gap: 3px;
      font-size: 0.9rem;
      line-height: 1;
    }

    /* ---------------- Progress markers ---------------- */
    .markers {
      display: flex;
      justify-content: center;
      align-items: stretch;
      gap: 8px;
      min-width: 0;
    }

    .marker {
      flex: 1 1 0;
      min-width: 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 7px;
      padding: 11px 6px;
      border-radius: 14px;
      border: 2px solid var(--border);
      background: var(--surface);
      box-shadow: var(--shadow-sm);
    }

    .marker-shape {
      width: 2.2rem;
      height: 2.2rem;
      border-radius: 50%;
      border: 2.5px solid var(--border);
      display: grid;
      place-items: center;
      background: var(--surface-2);
      color: var(--muted);
      font-size: 1rem;
      font-weight: 900;
      line-height: 1;
      flex: 0 0 auto;
    }

    .marker-label {
      font-size: 0.76rem;
      font-weight: 700;
      letter-spacing: 0.05em;
      text-transform: uppercase;
      color: var(--muted);
      text-align: center;
      line-height: 1.15;
      overflow-wrap: anywhere;
    }

    .marker.complete { border-color: var(--ok); }
    .marker.complete .marker-shape {
      background: var(--ok);
      border-color: var(--ok);
      color: var(--on-ok, #FFFFFF);
    }
    .marker.complete .marker-label { color: var(--text); }

    .marker.current {
      border-color: var(--accent);
      border-style: dashed;
    }
    .marker.current .marker-shape {
      border-color: var(--accent);
      border-style: double;
      border-width: 4px;
      color: var(--text);
    }
    .marker.current .marker-label { color: var(--text); }

    body.high-contrast .marker.complete .marker-shape,
    body[data-theme="inverted"] .marker.complete .marker-shape {
      color: var(--on-accent);
      background: var(--accent);
      border-color: var(--outline);
    }

    /* ---------------- The action button ---------------- */
    .action-btn {
      width: 100%;
      min-height: 11rem;
      height: clamp(11rem, 32vh, 15rem);
      border-radius: var(--radius-lg);
      border: 3px solid var(--border);
      background-color: var(--surface);
      background-image: none;
      color: var(--text);
      font-size: clamp(1.15rem, 0.95rem + 1.3vw, 1.7rem);
      font-weight: 800;
      letter-spacing: 0.1em;
      text-transform: uppercase;
      cursor: pointer;
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-direction: column;
      gap: 10px;
      text-align: center;
      white-space: normal;
      box-shadow: var(--shadow-md);
      /* Prevent the double-tap-to-zoom delay from adding latency to a
         timing measurement. */
      touch-action: manipulation;
      -webkit-user-select: none;
      user-select: none;
      overflow-wrap: anywhere;
    }

    .action-btn-indicator {
      font-size: 2.5rem;
      line-height: 1;
      font-weight: 900;
      letter-spacing: 0;
    }

    .action-btn-hint {
      font-size: 0.8rem;
      font-weight: 700;
      letter-spacing: 0.09em;
      opacity: 1;
      text-transform: uppercase;
    }

    /* Idle: brand gradient. */
    .action-btn.idle {
      background-image: linear-gradient(150deg, var(--brand-1), var(--brand-2));
      background-color: var(--brand-1);
      color: var(--on-accent);
      border-color: transparent;
      box-shadow: var(--shadow-lg);
    }

    .action-btn.running {
      background-color: var(--accent);
      color: var(--on-accent);
      border-color: transparent;
      box-shadow: var(--shadow-lg);
    }

    /* Stage identities: distinct hue AND distinct corner radius AND distinct
       border style AND distinct indicator glyph. Four redundant channels. */
    .action-btn.running.stage-start {
      background-image: linear-gradient(150deg, var(--stage-start-1), var(--stage-start-2));
      background-color: var(--stage-start-1);
      color: #FFFFFF;
      border-radius: 10px;
      border: 3px solid rgba(255, 255, 255, 0.28);
    }

    .action-btn.running.stage-halfway {
      background-image: linear-gradient(150deg, var(--stage-half-1), var(--stage-half-2));
      background-color: var(--stage-half-1);
      color: #FFFFFF;
      border-radius: 999px;
      border: 3px dashed rgba(255, 255, 255, 0.55);
    }

    .action-btn.running.stage-finish {
      background-image: linear-gradient(150deg, var(--stage-finish-1), var(--stage-finish-2));
      background-color: var(--stage-finish-1);
      color: #FFFFFF;
      border-radius: 0;
      border: 3px double rgba(255, 255, 255, 0.75);
    }

    body.high-contrast .action-btn.running,
    body[data-theme="inverted"] .action-btn.running {
      background-color: var(--accent);
      color: var(--on-accent);
      border: 3px solid var(--outline);
    }

    .action-btn:disabled { opacity: 0.6; cursor: not-allowed; }
    .action-btn:active:not(:disabled) { transform: scale(0.985); }

    /* "Flash the action button on cue" accessibility option. */
    .action-btn.flash {
      box-shadow: 0 0 0 7px var(--accent), var(--shadow-lg);
    }

    @media (prefers-reduced-motion: reduce) {
      .action-btn:active:not(:disabled) { transform: none; }
      .action-btn.flash { box-shadow: var(--shadow-md); }
    }

    /* ---------------- Cue banner ---------------- */
    .cue-banner {
      border: 1px solid var(--border);
      border-left: 5px solid var(--accent);
      border-radius: var(--radius-sm);
      padding: 11px 13px;
      background: var(--surface);
      display: flex;
      align-items: center;
      gap: 10px;
      font-size: 0.95rem;
      font-weight: 600;
      line-height: 1.35;
      min-height: 2.6rem;
      box-shadow: var(--shadow-sm);
      overflow-wrap: anywhere;
    }

    .cue-banner[data-visible="false"] { display: none; }
    .cue-banner[data-tone="ok"] { border-left-color: var(--ok); }
    .cue-banner[data-tone="warn"] { border-left-color: var(--warn); }

    .cue-dot {
      width: 0.62rem;
      height: 0.62rem;
      border-radius: 50%;
      background: var(--accent);
      flex: 0 0 auto;
    }
    .cue-banner[data-tone="ok"] .cue-dot { background: var(--ok); }
    .cue-banner[data-tone="warn"] .cue-dot { background: var(--warn); }

    /* ---------------- Setup-required prompt ---------------- */
    .setup-required-prompt {
      border: 2px solid var(--warn);
      border-radius: var(--radius);
      background: var(--surface);
      color: var(--text);
      padding: 14px;
      display: grid;
      gap: 10px;
      text-align: left;
      min-width: 0;
      box-shadow: var(--shadow-sm);
    }

    .setup-required-prompt[hidden] { display: none; }

    .setup-required-prompt-title {
      margin: 0;
      font-size: 0.8rem;
      font-weight: 800;
      letter-spacing: 0.07em;
      text-transform: uppercase;
      color: var(--warn);
    }

    .setup-required-prompt p { margin: 0; line-height: 1.4; }
    .setup-required-prompt .settings-action { width: 100%; }

    /* ---------------- Forms / dialogs ---------------- */
    .field-help {
      margin: 0;
      font-size: 0.88rem;
      line-height: 1.35;
      color: var(--muted);
      text-align: left;
    }

    .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;
    }

    .debug {
      font-size: 0.9rem;
      color: var(--muted);
      text-align: center;
      font-variant-numeric: tabular-nums;
    }
    .debug:empty { display: none; }

    dialog {
      border: none;
      padding: 0;
      background: transparent;
      width: 100%;
      max-width: none;
      max-height: none;
    }

    dialog[open] {
      position: fixed;
      inset: 0;
      margin: 0;
      display: grid;
      place-items: center;
      padding:
        max(10px, env(safe-area-inset-top))
        10px
        max(10px, env(safe-area-inset-bottom))
        10px;
      overflow: hidden;
    }

    dialog::backdrop { background: rgba(2, 6, 16, 0.72); }

    .modal-card {
      position: relative;
      background: var(--surface);
      border: 1px solid var(--border);
      border-radius: var(--radius-lg);
      padding: 16px;
      display: flex;
      flex-direction: column;
      gap: 14px;
      width: min(640px, 100%);
      min-width: 0;
      max-height: min(760px, calc(var(--viewport-height) - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 20px));
      overflow: auto;
      overscroll-behavior: contain;
      -webkit-overflow-scrolling: touch;
      box-shadow: var(--shadow-lg);
      z-index: 1;
    }

    .modal-visual-preview {
      position: fixed;
      inset: 0;
      height: var(--viewport-height);
      pointer-events: none;
      opacity: 0;
      z-index: 30;
      overflow: hidden;
    }
    .modal-visual-preview[data-active="true"] { opacity: 1; }

    .modal-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      min-width: 0;
      /* Sticky so Close stays reachable at any text size. */
      position: sticky;
      top: 0;
      z-index: 2;
      background: var(--surface);
      border-bottom: 1px solid var(--border);
      padding-bottom: 12px;
      margin: -16px -16px 0;
      padding-left: 16px;
      padding-right: 16px;
      padding-top: 16px;
    }

    .modal-header h2 {
      margin: 0;
      min-width: 0;
      font-size: 1.25rem;
      font-weight: 800;
      letter-spacing: -0.01em;
      line-height: 1.1;
      overflow-wrap: anywhere;
    }

    .close-modal {
      border: 2px solid var(--border);
      background: var(--surface-2);
      border-radius: 999px;
      padding: 9px 16px;
      font-size: 1rem;
      font-weight: 700;
      cursor: pointer;
      color: var(--text);
      white-space: normal;
      text-align: center;
      max-width: 100%;
      flex: 0 0 auto;
      overflow-wrap: anywhere;
    }

    .setup {
      display: flex;
      flex-direction: column;
      gap: 16px;
      text-align: left;
      min-width: 0;
    }

    .setup-group {
      border: 1px solid var(--border);
      border-radius: var(--radius);
      background: var(--surface-2);
      padding: 14px;
      display: flex;
      flex-direction: column;
      gap: 12px;
      min-width: 0;
    }

    /* Real headings (h2/h3) since build 10, so VoiceOver's headings rotor
       can jump between the sections; the look is unchanged. */
    .setup-heading {
      margin: 0;
      font-size: 0.8rem;
      line-height: 1.3;
      font-weight: 800;
      text-transform: uppercase;
      letter-spacing: 0.07em;
      color: var(--accent);
      overflow-wrap: anywhere;
    }

    body.high-contrast .setup-heading,
    body[data-theme="inverted"] .setup-heading { color: var(--text); }

    .setup-note {
      margin: 0;
      font-size: 0.88rem;
      color: var(--muted);
      line-height: 1.35;
    }

    .setup label {
      font-size: 1rem;
      color: var(--text);
      line-height: 1.35;
      overflow-wrap: anywhere;
    }

    .setup input[type="number"],
    .setup select {
      width: 100%;
      max-width: 100%;
      padding: 12px;
      border-radius: var(--radius-sm);
      border: 2px solid var(--border);
      font-size: 1.05rem;
      font-family: inherit;
      margin-top: 6px;
      background: var(--surface);
      color: var(--text);
    }

    .setup input[type="checkbox"],
    .setup input[type="radio"] {
      width: 1.45rem;
      height: 1.45rem;
      margin: 0;
      accent-color: var(--accent);
      flex: 0 0 auto;
    }

    fieldset,
    .option-group {
      border: 1px solid var(--border);
      border-radius: var(--radius-sm);
      background: var(--surface);
      padding: 10px 12px 12px;
      margin: 0;
      min-width: 0;
      display: flex;
      flex-direction: column;
      gap: 10px;
    }

    legend,
    .option-group-title {
      padding: 0 6px;
      font-size: 0.78rem;
      font-weight: 700;
      letter-spacing: 0.05em;
      text-transform: uppercase;
      color: var(--muted);
    }

    .option-group-title {
      display: inline-block;
      margin-bottom: 8px;
      overflow-wrap: anywhere;
    }

    .sound-options {
      display: flex;
      flex-direction: column;
      gap: 10px;
      min-width: 0;
    }

    .sound-option {
      display: grid;
      grid-template-columns: auto minmax(0, 1fr);
      grid-template-areas:
        "input label"
        "button button";
      align-items: center;
      gap: 10px 12px;
      padding: 4px 0;
      min-width: 0;
    }

    .sound-option input { grid-area: input; }
    .sound-option label { grid-area: label; min-width: 0; line-height: 1.25; overflow-wrap: anywhere; }
    .sound-option button { grid-area: button; width: 100%; }

    .preview-btn,
    .settings-action,
    .sound-option button {
      border: 2px solid var(--border);
      border-radius: 999px;
      background: var(--surface-2);
      padding: 11px 16px;
      cursor: pointer;
      font-size: 0.98rem;
      font-weight: 700;
      font-family: inherit;
      min-height: 2.9rem;
      color: var(--text);
      white-space: normal;
      text-align: center;
      line-height: 1.25;
      max-width: 100%;
      overflow-wrap: anywhere;
    }

    .settings-action.primary {
      background-image: linear-gradient(140deg, var(--brand-1), var(--brand-2));
      background-color: var(--brand-1);
      color: var(--on-accent);
      border-color: transparent;
    }

    body.high-contrast .settings-action.primary,
    body[data-theme="inverted"] .settings-action.primary {
      background-image: none;
      background-color: var(--accent);
      border-color: var(--outline);
    }

    .preview-btn:disabled,
    .settings-action:disabled,
    .sound-option button:disabled { opacity: 0.55; cursor: not-allowed; }

    .exemplar-actions { display: grid; gap: 8px; }

    .share-message-output {
      width: 100%;
      min-height: 92px;
      resize: vertical;
      padding: 12px;
      padding-right: 52px;
      border-radius: var(--radius-sm);
      border: 2px solid var(--border);
      background: var(--surface);
      color: var(--text);
      font: inherit;
      font-size: 0.92rem;
      line-height: 1.4;
    }

    .share-message-wrap { position: relative; }
    .share-message-group { display: flex; flex-direction: column; gap: 8px; }

    .copy-icon-btn {
      position: absolute;
      top: 10px;
      right: 10px;
      width: 36px;
      height: 36px;
      padding: 0;
      border: 2px solid var(--border);
      border-radius: 10px;
      background: var(--surface-2);
      color: var(--text);
      display: inline-flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
    }

    .copy-icon-btn svg {
      width: 18px; height: 18px;
      stroke: currentColor;
      fill: none;
      stroke-width: 1.8;
      stroke-linecap: round;
      stroke-linejoin: round;
    }

    .platform-note {
      margin: 0;
      font-size: 0.85rem;
      line-height: 1.4;
      color: var(--muted);
      padding: 9px 11px;
      border-radius: var(--radius-sm);
      border: 1px dashed var(--border);
      background: var(--surface);
    }

    button:focus-visible,
    input:focus-visible,
    select:focus-visible,
    textarea:focus-visible,
    [tabindex]:focus-visible {
      outline: 4px solid var(--outline);
      outline-offset: 2px;
    }

    body.focus-boost :focus-visible {
      outline-width: 6px;
      outline-offset: 4px;
    }

    /* ---------------- Full-screen visual replay ----------------
       These colors are calibrated for low vision on a black field and
       are deliberately NOT themed. Do not restyle them. */
    .visual-replay-overlay {
      position: fixed;
      inset: 0;
      width: 100%;
      height: var(--viewport-height);
      pointer-events: none;
      opacity: 0;
      z-index: 9999;
    }

    .visual-replay-overlay[data-active="true"] { opacity: 1; }

    .visual-replay-flash,
    .visual-replay-shape-layer {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
    }

    .visual-replay-flash { background: #000000; }

    .visual-replay-shape-layer {
      display: grid;
      place-items: center;
      z-index: 1;
    }

    .visual-replay-shape {
      width: min(70vmin, calc(var(--viewport-height) * 0.7), 70vw);
      height: min(70vmin, calc(var(--viewport-height) * 0.7), 70vw);
      display: none;
    }

    .visual-replay-shape[data-type="acceptable"] {
      border-radius: 50%;
      background: #00FF66;
    }

    .visual-replay-shape[data-type="outside"] {
      background: #FF5500;
      clip-path: polygon(50% 0%, 6.7% 75%, 93.3% 75%);
    }

    .visual-replay-shape[data-outside-variant="down"] { transform: rotate(180deg); }

    /* ---------------- Large-text + small-screen reflow ---------------- */
    body.large-text-layout .app-subtitle,
    body.large-text-layout .card-label,
    body.large-text-layout .setup-heading,
    body.large-text-layout .option-group-title,
    body.large-text-layout .marker-label,
    body.large-text-layout .action-btn,
    body.large-text-layout .action-btn-hint {
      text-transform: none;
      letter-spacing: 0;
    }

    body.large-text-layout .mode-toggle { grid-template-columns: minmax(0, 1fr); }
    body.large-text-layout .mode-toggle label { flex-direction: row; justify-content: flex-start; gap: 10px; }
    body.large-text-layout .markers { flex-direction: column; }
    body.large-text-layout .marker { flex-direction: row; justify-content: flex-start; gap: 12px; }
    body.large-text-layout .app-header { position: static; flex-direction: column; align-items: stretch; }
    body.large-text-layout .header-actions { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
    body.large-text-layout .icon-btn { width: 100%; height: auto; min-height: 3rem; padding: 10px; }
    body.large-text-layout .action-btn { height: auto; min-height: 8rem; padding: 1.25rem; }

    body.short-screen-layout .panel { gap: 12px; }
    body.short-screen-layout .action-btn { min-height: 6.5rem; height: auto; padding: 1rem; }
    body.short-screen-layout .brand-mark { width: 2rem; height: 2rem; }

    body.phone-safe-layout .panel { width: min(44rem, 100vw); }
    body.phone-safe-layout .setup-group { padding: 12px; }
    body.phone-safe-layout .close-modal { padding: 9px 14px; }

    body.landscape-layout.large-text-layout .action-btn { min-height: 6rem; }

/* ============================================================
   MULTI-SCREEN SHELL
   ============================================================ */
.screen {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

.screen[hidden] { display: none; }

.screen-heading {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.screen-heading:focus-visible {
  outline: 4px solid var(--outline);
  outline-offset: 4px;
}

#backBtn[hidden] { display: none; }

/* ---------------- Home ---------------- */
.home-times {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--muted);
  text-align: center;
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.step-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.step-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 14px;
  align-items: start;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  min-width: 0;
}

.step-card.locked { opacity: 0.55; }

.step-number {
  width: 2.2rem;
  height: 2.2rem;
  flex: 0 0 auto;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-weight: 900;
  font-size: 1.05rem;
  background-image: linear-gradient(140deg, var(--brand-1), var(--brand-2));
  background-color: var(--brand-1);
  color: var(--on-accent);
}

body.high-contrast .step-number,
body[data-theme="inverted"] .step-number {
  background-image: none;
  background-color: var(--accent);
  border: 2px solid var(--outline);
}

.step-body { min-width: 0; display: flex; flex-direction: column; gap: 8px; }

.step-title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 800;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

.step-desc {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.4;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.home-links {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px;
}

/* ---------------- Measure ---------------- */
.trial-list {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.trial-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  font-size: 0.92rem;
  min-width: 0;
}

.trial-index { font-weight: 700; color: var(--muted); }
.trial-values { font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 10px;
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
  min-width: 0;
}

.stat-label {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.stat-value {
  font-size: 1.6rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.stat-note { font-size: 0.8rem; color: var(--muted); }

.field-help.warn { color: var(--warn); font-weight: 600; }

/* ---------------- Comparison answers ---------------- */
.big-action { width: 100%; min-height: 3.4rem; font-size: 1.05rem; }

.answer-grid {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.answer-btn {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 14px;
  text-align: left;
  width: 100%;
  /* Deliberately large: at a curb, with gloves or a cane in one hand, and
     reachable without hunting for a small control under VoiceOver. */
  min-height: 4.2rem;
  padding: 14px 18px;
  border-radius: var(--radius);
  border: 2px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 1.02rem;
  font-weight: 700;
  font-family: inherit;
  line-height: 1.25;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  overflow-wrap: anywhere;
}

.answer-btn:disabled { opacity: 0.45; cursor: not-allowed; }

.answer-btn:active:not(:disabled) { transform: scale(0.99); }

.answer-glyph {
  font-size: 1.7rem;
  line-height: 1;
  font-weight: 900;
  color: var(--accent);
}

body.high-contrast .answer-glyph,
body[data-theme="inverted"] .answer-glyph { color: var(--text); }

@media (prefers-reduced-motion: reduce) {
  .answer-btn:active:not(:disabled) { transform: none; }
}

/* ---------------- Progress ---------------- */
.progress-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.progress-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  min-width: 0;
}

.progress-label {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.progress-value {
  font-size: 1.7rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.progress-note { font-size: 0.82rem; color: var(--muted); }

.run-strip {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  margin: 6px 0 14px;
}

.run-dot {
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 3px;
  background: var(--warn);
  flex: 0 0 auto;
}

.run-dot.ok { background: var(--ok); }

.plain-list {
  margin: 0;
  padding-left: 1.15rem;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 0.94rem;
  line-height: 1.45;
}

.plain-list li { overflow-wrap: anywhere; }

.report-preview { min-height: 240px; font-size: 0.86rem; padding-right: 12px; }

#screen-progress input[type="text"] {
  width: 100%;
  padding: 12px;
  border-radius: var(--radius-sm);
  border: 2px solid var(--border);
  font-size: 1.05rem;
  font-family: inherit;
  margin-top: 6px;
  background: var(--surface);
  color: var(--text);
}

/* ---------------- Large-text reflow ---------------- */
body.large-text-layout .step-card { grid-template-columns: minmax(0, 1fr); }
body.large-text-layout .home-links { grid-template-columns: minmax(0, 1fr); }
body.large-text-layout .stat-row,
body.large-text-layout .progress-grid { grid-template-columns: minmax(0, 1fr); }
body.large-text-layout .answer-btn { grid-template-columns: minmax(0, 1fr); }
body.large-text-layout .screen-heading { text-transform: none; letter-spacing: 0; }
body.large-text-layout .trial-row { flex-direction: column; gap: 4px; }

/* ---------------- Quick-start / demo ---------------- */
.try-demo {
  width: 100%;
  min-height: 3.6rem;
  font-size: 1.08rem;
}

.try-demo[hidden] { display: none; }

.demo-note {
  margin: 0;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  border: 1px dashed var(--border);
  background: var(--surface-2);
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.4;
  overflow-wrap: anywhere;
}

.demo-note[hidden] { display: none; }

/* ============================================================
   POLISH
   Restrained on purpose. Decoration that reduces clarity would be a
   regression for this audience, so this is limited to depth, press
   feedback, and a per-step accent that adds a second, redundant cue
   to the step number.
   ============================================================ */

.step-card {
  position: relative;
  overflow: hidden;
  transition: transform 120ms ease, box-shadow 120ms ease;
}

/* A color bar per step, echoing the stage colors used on the action
   button. Never the only signal — the number and title always carry it. */
.step-card::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 5px;
  background: var(--accent);
}

.step-card[data-screen="measure"]::before { background: var(--brand-1); }
.step-card[data-screen="practice"]::before { background: var(--stage-start-2); }
.step-card[data-screen="compare"]::before { background: var(--stage-half-2); }
.step-card[data-screen="live"]::before { background: var(--stage-finish-2); }

.step-card:not(.locked):active { transform: scale(0.995); }

.step-card:focus-within {
  box-shadow: var(--shadow-md);
  border-color: var(--accent);
}

/* Depth on the primary controls, so the thing to press reads as raised. */
.settings-action.primary,
.answer-btn {
  transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
}

.settings-action.primary:active:not(:disabled) { transform: scale(0.985); }

.answer-btn:not(:disabled):hover { border-color: var(--accent); }

/* A very soft brand glow behind the header, which lifts the whole screen
   without introducing any new foreground color. */
body::before {
  content: "";
  position: fixed;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(720px, 120vw);
  height: 220px;
  pointer-events: none;
  z-index: -1;
  background: radial-gradient(60% 100% at 50% 0%, var(--bg-tint-1) 0%, transparent 70%);
}

body.high-contrast::before,
body[data-theme="inverted"]::before { display: none; }

.card,
.step-card,
.progress-card,
.stat { transition: border-color 120ms ease; }

@media (prefers-reduced-motion: reduce) {
  .step-card,
  .settings-action.primary,
  .answer-btn,
  .card,
  .progress-card,
  .stat { transition: none; }
  .step-card:not(.locked):active,
  .settings-action.primary:active:not(:disabled) { transform: none; }
}

/* ---------------- Compare: swipe answer pad, sample loudness ---------------- */
.swipe-pad {
  width: 100%;
  min-height: 7.5rem;
  border-radius: var(--radius);
  border: 2px dashed var(--accent);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-weight: 700;
  line-height: 1.3;
  display: grid;
  gap: 6px;
  place-items: center;
  padding: 14px;
  text-align: center;
  cursor: pointer;
  /* Swipes are read by the pad itself; the page must not scroll instead. */
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
.swipe-pad[hidden] { display: none; }
.swipe-pad .swipe-arrows {
  font-size: 1.6rem;
  font-weight: 900;
  letter-spacing: 0.3em;
  color: var(--accent);
}
.swipe-pad:focus-visible { outline: 4px solid var(--outline); outline-offset: 3px; }
body.high-contrast .swipe-pad,
body[data-theme="inverted"] .swipe-pad { border-style: solid; }
body.high-contrast .swipe-pad .swipe-arrows,
body[data-theme="inverted"] .swipe-pad .swipe-arrows { color: var(--text); }

.range-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
}
.range-row input[type="range"] {
  width: 100%;
  min-height: 2.75rem;
  accent-color: var(--accent);
}
.range-row output {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  min-width: 3.5ch;
  text-align: right;
}

.setup input[type="text"],
.setup input[type="email"] {
  width: 100%;
  min-height: 2.9rem;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  border: 2px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font: inherit;
}
.setup input[type="text"]:focus-visible,
.setup input[type="email"]:focus-visible { outline: 4px solid var(--outline); outline-offset: 2px; }

.badge-experimental {
  white-space: nowrap;
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1.5px solid var(--warn);
  color: var(--warn);
  margin-left: 6px;
  vertical-align: middle;
}
body.high-contrast .badge-experimental { color: var(--text); border-color: var(--text); }

.step-card[data-screen="signal"]::before { background: var(--brand-2); }

/* The copy icon button was 36 px; iOS asks for 44. */
.copy-icon-btn { min-width: 44px; min-height: 44px; }

/* Collapsible option blocks keep the big controls near the top on a phone. */
details.options-card > summary {
  cursor: pointer;
  list-style: none;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}
details.options-card > summary::-webkit-details-marker { display: none; }
details.options-card > summary::before {
  content: "\25B8";
  font-size: 1rem;
  color: var(--accent);
  flex: 0 0 auto;
}
details.options-card[open] > summary::before { content: "\25BE"; }
details.options-card[open] > summary { margin-bottom: 10px; }
details.options-card > summary:focus-visible { outline: 4px solid var(--outline); outline-offset: 3px; border-radius: 8px; }
body.high-contrast details.options-card > summary::before,
body[data-theme="inverted"] details.options-card > summary::before { color: var(--text); }

/* Checkbox and radio labels placed directly in a card or options block are
   full-width rows with a 44 px touch height, never inline runs of text. */
.card > label,
details.options-card > label,
#screen-progress .card label {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 44px;
  padding: 6px 0;
  line-height: 1.35;
}
.card > label input[type="checkbox"],
details.options-card > label input[type="checkbox"],
#screen-progress .card label input[type="checkbox"] {
  width: 1.3rem;
  height: 1.3rem;
  flex: 0 0 auto;
  margin-top: 0.15rem;
}
.card > label[for],
details.options-card > label[for] { display: block; min-height: 0; padding: 10px 0 4px; font-weight: 700; }
.card > .settings-action,
details.options-card > .settings-action { display: block; width: 100%; margin: 10px 0; }
details.options-card > .field-help { margin: 4px 0 8px; }

/* No double-tap zoom anywhere (it trapped the native app in a zoomed state);
   pinch zoom stays available in web browsers. */
html, body {
  touch-action: manipulation;
  /* No double-tap zoom; see lockNativeViewport() in engine.js for the shell. */
}
button, label, input, select, textarea, summary, a { touch-action: manipulation; }

/* ============================================================
   BUILD 7: instructor setup, full-screen pads,
   safety notes, O&M guidance, single-button activity cards
   ============================================================ */

/* The hidden attribute always wins, even over display rules on cards and
   labels (the instructor's on/off switches rely on it). */
[hidden] { display: none !important; }

/* Persistent, prominent: for use with an O&M Specialist. */
.om-guidance {
  margin: 0;
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  border: 2px solid var(--accent);
  background: var(--surface);
  color: var(--text);
  font-size: 0.92rem;
  font-weight: 700;
  line-height: 1.35;
}

.screen-intro {
  margin: 0;
  font-size: 0.98rem;
  line-height: 1.45;
  color: var(--text);
  overflow-wrap: anywhere;
}

/* Activity cards: the whole card is one button. */
.step-card { padding: 0; display: block; }
.step-button {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 14px;
  align-items: start;
  width: 100%;
  min-height: 44px;
  padding: 16px 16px 16px 20px;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  border-radius: var(--radius);
}
.step-button:disabled { cursor: not-allowed; }
.step-button:focus-visible { outline: 4px solid var(--outline); outline-offset: -4px; }
.step-button .step-body { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.step-button .step-title,
.step-button .step-desc { display: block; }
body.large-text-layout .step-button { grid-template-columns: minmax(0, 1fr); }
.step-card[data-screen="signal"]::before { background: var(--brand-2); }

/* Safety note: "longer does not mean long enough". */
.safety-note {
  border: 2px solid var(--warn);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  padding: 14px;
  display: grid;
  gap: 10px;
  min-width: 0;
}
.safety-note p { margin: 0; line-height: 1.4; }
.safety-note-title { font-weight: 800; }
.safety-note .settings-action { width: 100%; }

/* Instructor setup */
.check-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-height: 44px;
  padding: 6px 0;
  line-height: 1.35;
}
.setup .text-input,
.card .text-input {
  width: 100%;
  min-height: 2.9rem;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  border: 2px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font: inherit;
}
.text-input:focus-visible { outline: 4px solid var(--outline); outline-offset: 2px; }
#screen-instructor .setup { display: flex; flex-direction: column; gap: 14px; }
#screen-instructor select,
#screen-live select {
  width: 100%;
  max-width: 100%;
  padding: 12px;
  border-radius: var(--radius-sm);
  border: 2px solid var(--border);
  font-size: 1rem;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
}
#screen-instructor .settings-action { width: 100%; }
.share-details > summary {
  cursor: pointer;
  font-weight: 700;
  min-height: 44px;
  display: flex;
  align-items: center;
}
.share-details[open] > summary { margin-bottom: 8px; }
.link-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  width: 100%;
}

/* Full-screen gesture pads. Below the visual replay overlay (z 9999) so the
   flash and shapes show on top of them; above everything else. */
.gesture-overlay {
  position: fixed;
  inset: 0;
  z-index: 9000;
  height: var(--viewport-height);
  background: var(--bg);
  color: var(--text);
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  overscroll-behavior: contain;
}
#answerOverlay,
#howMuchOverlay { z-index: 9100; }
/* Skip and Done keep their word on one line (Skip used to wrap to
   "S / ki / p", bug 25); the title wraps instead. */
.gesture-header .settings-action {
  flex: 0 0 auto;
  white-space: nowrap;
  min-width: 0;
  min-height: 48px;
  padding: 8px 16px;
}
.gesture-header .gesture-title { flex: 1 1 auto; min-width: 0; overflow-wrap: break-word; }
/* A pad fills one screen and cannot scroll (a drag is a gesture), so its
   text is capped: at 300% the title alone filled the screen and the answer
   buttons and gesture area were below it (bug 24). The caps are still about
   twice the default size. */
.gesture-overlay .gesture-title { font-size: min(1.15rem, 34px); }
.gesture-overlay .gesture-status { font-size: min(1rem, 28px); }
.gesture-overlay .gesture-surface { font-size: min(1.1rem, 30px); min-height: min(8rem, 30vh); gap: min(10px, 1vh); }
.gesture-overlay .gesture-arrow { font-size: min(2rem, 44px); }
.gesture-overlay .settings-action { font-size: min(1rem, 28px); }
.gesture-overlay .answer-btn { font-size: min(1.02rem, 28px); min-height: min(4.2rem, 12vh); padding: min(14px, 1.5vh) 18px; }
.gesture-overlay .answer-glyph { font-size: min(1.7rem, 40px); }
.gesture-overlay .answer-grid { gap: min(10px, 1.2vh); }
.howmuch-btn { font-size: min(1.4rem, 40px); }
/* At the large text sizes a pad gets fixed sizes, still about twice the
   default, like the app header: the swipe area and the three answers must
   all fit on one screen of an iPhone SE. The arrows repeat what the words
   say, so they go; the symbol sits beside each answer, not above it. */
body.large-text-layout .gesture-overlay { gap: 8px; }
body.large-text-layout .gesture-overlay .gesture-title { font-size: 24px; line-height: 1.2; }
body.large-text-layout .gesture-overlay .gesture-status { font-size: 22px; line-height: 1.25; }
body.large-text-layout .gesture-overlay .gesture-surface { font-size: 22px; gap: 4px; padding: 8px; min-height: 96px; }
body.large-text-layout .gesture-overlay .gesture-arrow { display: none; }
body.large-text-layout .gesture-overlay .settings-action { font-size: 22px; }
body.large-text-layout .gesture-overlay .answer-btn {
  grid-template-columns: auto minmax(0, 1fr);
  font-size: 22px;
  min-height: 56px;
  padding: 6px 14px;
  gap: 10px;
}
body.large-text-layout .gesture-overlay .answer-glyph { font-size: 28px; }
/* Landscape: the gesture area on the left, the controls on the right, so a
   short screen holds both ("Shorter" used to be below the screen, bug 24,
   Oct 2026 review). */
@media (orientation: landscape) and (max-height: 520px) {
  .gesture-overlay {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    column-gap: 14px;
    row-gap: 8px;
    padding: max(10px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(10px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  }
  .gesture-overlay .gesture-header { grid-column: 1 / -1; }
  .gesture-overlay .gesture-surface { grid-column: 1; grid-row: 2 / span 3; min-height: 0; }
  .gesture-overlay .gesture-status { grid-column: 2; font-size: min(1rem, 20px); }
  .gesture-overlay .answer-grid { grid-column: 2; align-content: start; gap: 6px; }
  .gesture-overlay .answer-btn { min-height: 44px; padding: 4px 12px; font-size: min(1.02rem, 20px); grid-template-columns: auto minmax(0, 1fr); }
  .gesture-overlay .gesture-title { font-size: min(1.15rem, 22px); }
  .gesture-overlay .gesture-arrow { display: none; }
  .gesture-overlay .howmuch-btn { grid-column: 1 / -1; min-height: 0; }
}
.gesture-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.gesture-title {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 800;
  line-height: 1.3;
}
.gesture-title:focus { outline: none; }
.gesture-title:focus-visible { outline: 4px solid var(--outline); outline-offset: 3px; }
.gesture-status {
  margin: 0;
  font-size: 1rem;
  line-height: 1.4;
}
.gesture-surface {
  flex: 1 1 auto;
  min-height: 8rem;
  border: 3px dashed var(--accent);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
  display: grid;
  place-content: center;
  gap: 10px;
  padding: 16px;
  text-align: center;
  font-size: 1.1rem;
  font-weight: 700;
  line-height: 1.35;
}
.gesture-arrow {
  font-size: 2rem;
  font-weight: 900;
  color: var(--accent);
}
body.high-contrast .gesture-surface,
body[data-theme="inverted"] .gesture-surface { border-style: solid; }
body.high-contrast .gesture-arrow,
body[data-theme="inverted"] .gesture-arrow { color: var(--text); }
.gesture-overlay .answer-grid { flex: 0 0 auto; }
.gesture-overlay.buttons-only .answer-grid { flex: 1 1 auto; align-content: center; }
.gesture-overlay.buttons-only .answer-btn { min-height: 5rem; }
.howmuch-btn { flex: 1 1 auto; height: auto; min-height: 12rem; }
body.pad-open { overflow: hidden; }

/* The sample warning time on the visual channel: a held bar across the
   middle of the screen, never the student's own flash. Calibrated for low
   vision on black; not themed. */
.visual-replay-sample {
  position: absolute;
  left: 6%;
  right: 6%;
  top: 42%;
  height: 16%;
  background: #4DA3FF;
  border-radius: 999px;
  display: none;
  z-index: 1;
}

.disclaimer-text { font-size: 1rem; color: var(--text); }

/* Forced colors (Windows high contrast, Chrome's setting) painted the flash
   and the circle and triangle all white, so visual feedback vanished (bug
   28). Their colours are the feedback, so they keep them. */
@media (forced-colors: active) {
  .visual-replay-overlay,
  .visual-replay-overlay * { forced-color-adjust: none; }
}

/* The screen title takes focus on every screen change so screen readers
   announce it; it is not a control, so no focus box for sighted users. */
#screenTitle:focus { outline: none; }
dialog h2[tabindex="-1"]:focus { outline: none; }

/* At very large text sizes the header used to fill the whole first screen
   (logo, name and two full-width buttons). Keep it to one compact row with
   fixed sizes: still large (title 32 px, buttons 52 px), and the content
   below stays at the size the student chose. */
body.large-text-layout .app-header { flex-direction: row; align-items: center; gap: 10px; }
body.large-text-layout .brand { min-width: 0; flex: 1 1 auto; }
body.large-text-layout .brand-mark { width: 44px; height: 44px; flex: 0 0 auto; }
body.large-text-layout .app-title { font-size: 32px; line-height: 1.15; }
body.large-text-layout .app-subtitle { display: none; }
body.large-text-layout .header-actions { display: flex; gap: 8px; flex: 0 0 auto; }
body.large-text-layout .icon-btn { width: 52px; height: 52px; min-height: 52px; padding: 0; flex: 0 0 auto; }

/* Pad titles take focus for screen readers; no box for sighted users. */
.gesture-title:focus-visible { outline: none; }
body.large-text-layout .icon-btn svg { width: 28px; height: 28px; }
body.large-text-layout .app-title { font-size: 26px; overflow-wrap: break-word; word-break: normal; hyphens: manual; }
body.large-text-layout .app-header { padding-left: 12px; padding-right: 12px; }
body.large-text-layout #backBtn:not([hidden]) ~ .brand .brand-mark { display: none; }
body.large-text-layout .app-title { font-size: 24px; }

/* Input boundaries (bug 34): after the form rules above, so it wins. */
.setup input[type="number"],
.setup input[type="text"],
.setup input[type="email"],
.setup select { border-color: var(--control-border); }
