/* =====================================================================
   EchoBridge — stylesheet
   ---------------------------------------------------------------------
   Design principles, all of them borrowed from AAC practice rather than
   from fashion:
     * Low-arousal by default. Muted, desaturated colour; no pure white,
       no pure black, no saturated red except where danger is meant.
     * Enormous touch targets. A child with motor differences must be able
       to hit a button reliably; 88px is the floor, not the ceiling.
     * Stable geometry. Buttons never move between renders. Motor planning
       is how AAC users get fast, and a shifting board destroys it.
     * Motion is decorative only and can be switched off entirely.
     * Every interactive element has a visible focus ring, because switch
       and keyboard access is not optional here.
   ===================================================================== */

/* ---------------- design tokens ---------------- */
/* Calm — the default, and what almost every child will see.
   ---------------------------------------------------------------------
   A light leafy green: hue 83°, lightness 88%. Light enough to rest on,
   deep enough that you can actually see it is green. Green
   at this end of the scale is the least demanding thing an eye can rest
   on, which is why it turns up in hospital rooms and reading lamps, and
   why it suits a board a distressed child may be staring at for an hour.

   Every value here is measured, not chosen by eye — see logo/palette.mjs.
   The whole neutral family is tinted the same green rather than the ground
   alone, because a green page with warm-grey borders reads as a mistake.

   Two things this fixed that the old cream never met: hint text now clears
   4.5:1 (it was 3.3:1), and button and tile borders now clear the 3:1 that
   WCAG asks of a control boundary (they were 1.7:1). */
:root {
  --bg:            #E4EED4;   /* the page */
  --bg-raised:     #F4F9EC;   /* cards and tiles, lifted */
  --bg-sunken:     #CCDBB2;   /* recessed panels */
  --ink:           #232A20;
  --ink-soft:      #4C5545;
  --ink-faint:     #636D59;
  --line:          #C6D4AE;
  --line-strong:   #808A73;

  /* The teal is the logo's own colour, kept exactly. Against a yellow-green
     page it sits 97° away in hue, so a button never reads as background. */
  --accent:        #4A7C7E;
  --accent-soft:   #DCEFEF;
  --accent-ink:    #FFFFFF;
  --accent-deep:   #35595B;

  --warm:          #99572F;
  --warm-soft:     #FBF1E5;
  --danger:        #AE3F36;
  --danger-soft:   #FCE3DF;
  --success:       #3D6B39;
  --success-soft:  #D6F0E8;

  --radius:        18px;
  --radius-sm:     12px;
  --radius-lg:     26px;
  --shadow:        0 2px 4px rgba(37,43,34,.06), 0 8px 22px rgba(37,43,34,.07);
  --shadow-lift:   0 4px 8px rgba(37,43,34,.09), 0 16px 40px rgba(37,43,34,.11);
  --ring:          0 0 0 4px rgba(74,124,126,.35);

  --tile:          128px;   /* driven by the board-size setting */
  --tile-font:     1rem;
  --tile-emoji:    2.5rem;
  --gap:           12px;

  --font: 'Atkinson Hyperlegible', 'Verdana', -apple-system, BlinkMacSystemFont,
          'Segoe UI', system-ui, sans-serif;
  --emoji-font: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji',
                'Android Emoji', 'EmojiSymbols', sans-serif;

  --dur: .18s;
}

/* Bright — higher contrast and more saturated, for children who need
   stronger visual signal. */
[data-theme="bright"] {
  --bg: #FFFFFF; --bg-raised: #FFFFFF; --bg-sunken: #F0F3F7;
  --ink: #16202C; --ink-soft: #46536420; --ink-soft: #465364; --ink-faint: #6B7887;
  --line: #D3DCE6; --line-strong: #AEBAC8;
  --accent: #2563A8; --accent-soft: #DCEAF8; --accent-deep: #1B4A80;
  --warm: #D4761F; --warm-soft: #FCEBD9;
  --danger: #C3352A; --success: #2E7D32;
}

/* Dark — for evening use and light-sensitive children. */
[data-theme="dark"] {
  --bg: #1B1F23; --bg-raised: #252A30; --bg-sunken: #14171A;
  --ink: #E9E4DC; --ink-soft: #B4ADA3; --ink-faint: #857D73;
  --line: #363C44; --line-strong: #4A525C;
  --accent: #6FA8AA; --accent-soft: #2A3B3C; --accent-ink: #10171A; --accent-deep: #8FC3C5;
  --warm: #D9955F; --warm-soft: #3A2E24;
  --danger: #D4685E; --danger-soft: #3B2523;
  --success: #7FAE78; --success-soft: #263120;
  --shadow: 0 2px 4px rgba(0,0,0,.3), 0 8px 22px rgba(0,0,0,.35);
  --shadow-lift: 0 4px 10px rgba(0,0,0,.4), 0 18px 44px rgba(0,0,0,.45);
}

/* High contrast — meets and exceeds WCAG AAA, for low vision. */
[data-theme="contrast"] {
  --bg: #000000; --bg-raised: #000000; --bg-sunken: #0A0A0A;
  --ink: #FFFFFF; --ink-soft: #F0F0F0; --ink-faint: #D0D0D0;
  --line: #FFFFFF; --line-strong: #FFFFFF;
  --accent: #FFE500; --accent-soft: #2A2600; --accent-ink: #000000; --accent-deep: #FFF07A;
  --warm: #FFB000; --warm-soft: #2A1D00;
  --danger: #FF5A4E; --danger-soft: #2A0A08;
  --success: #5AFF7A; --success-soft: #052A0D;
  --shadow: none; --shadow-lift: none;
  --ring: 0 0 0 5px #FFE500;
}
[data-theme="contrast"] .tile { border-width: 3px; }
[data-theme="contrast"] .tile__emoji { filter: none; }

/* Board size presets. */
[data-size="small"]  { --tile: 96px;  --tile-font: .82rem; --tile-emoji: 1.9rem; --gap: 8px; }
[data-size="medium"] { --tile: 128px; --tile-font: 1rem;   --tile-emoji: 2.5rem; --gap: 12px; }
[data-size="large"]  { --tile: 164px; --tile-font: 1.2rem; --tile-emoji: 3.3rem; --gap: 14px; }
[data-size="huge"]   { --tile: 208px; --tile-font: 1.5rem; --tile-emoji: 4.4rem; --gap: 18px; }

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

/* Any class below that sets `display` would otherwise beat the user-agent
   `[hidden] { display: none }` rule, leaving hidden screens stacked on the
   page. This one line is load-bearing. */
[hidden] { display: none !important; }

/* Grid and flex children default to `min-width: auto`, which means they
   refuse to shrink below their min-content width — one wide child then
   forces the whole page wider than a phone screen. Opting every layout
   child out of that is what keeps the app usable at 320px. */
.hero > *, .grid3 > *, .stats > *, .kpis > *, .bar__row > *,
.main > *, .strip > *, .board__grid > *, .editrow > * { min-width: 0; }

/* Long words in a heading must break rather than push the page sideways. */
h1, h2, h3, h4, .tile__label, .wordchip { overflow-wrap: break-word; }

html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
  line-height: 1.5;
}
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; border: none; background: none; }
img { max-width: 100%; display: block; }
h1, h2, h3, h4 { margin: 0 0 .4em; line-height: 1.22; font-weight: 700; letter-spacing: -.01em; }
p { margin: 0 0 1em; }
a { color: var(--accent-deep); }

:focus-visible { outline: none; box-shadow: var(--ring); border-radius: 8px; }

/* Everyone gets a way to skip to the board. */
.skip-link {
  position: absolute; left: -999px; top: 0; z-index: 999;
  background: var(--accent); color: var(--accent-ink);
  padding: 12px 20px; border-radius: 0 0 12px 0; font-weight: 700;
}
.skip-link:focus { left: 0; }

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

/* Respect the operating system, then the in-app switch. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}
[data-motion="off"] *, [data-motion="off"] *::before, [data-motion="off"] *::after {
  animation: none !important; transition: none !important;
}

/* ---------------- shared components ---------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  min-height: 52px; padding: 0 22px;
  border-radius: var(--radius-sm);
  background: var(--bg-raised); color: var(--ink);
  border: 2px solid var(--line-strong);
  font-weight: 700; font-size: 1rem;
  transition: transform var(--dur), background var(--dur), border-color var(--dur);
}
.btn:hover  { border-color: var(--accent); background: var(--accent-soft); }
.btn:active { transform: scale(.97); }
.btn--primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn--primary:hover { background: var(--accent-deep); border-color: var(--accent-deep); color: var(--accent-ink); }
.btn--danger  { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.btn--ghost   { border-color: transparent; background: transparent; }
.btn--ghost:hover { background: var(--bg-sunken); border-color: transparent; }
.btn--lg { min-height: 64px; font-size: 1.1rem; padding: 0 30px; }
.btn--block { width: 100%; }
.btn[disabled] { opacity: .45; pointer-events: none; }

.icon { width: 1.25em; height: 1.25em; flex: none; }

.card {
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow);
}

.pill {
  display: inline-flex; align-items: center; gap: .4em;
  padding: 5px 13px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent-deep);
  font-size: .82rem; font-weight: 700;
}
.pill--warm    { background: var(--warm-soft);    color: var(--warm); }
.pill--danger  { background: var(--danger-soft);  color: var(--danger); }
.pill--success { background: var(--success-soft); color: var(--success); }

.field { margin-bottom: 18px; }
.field label { display: block; font-weight: 700; margin-bottom: 6px; font-size: .95rem; }
.field .hint { font-size: .85rem; color: var(--ink-faint); margin-top: 5px; }
.input, select.input, textarea.input {
  width: 100%; min-height: 52px; padding: 12px 16px;
  border: 2px solid var(--line-strong); border-radius: var(--radius-sm);
  background: var(--bg-raised); color: var(--ink);
}
.input:focus { border-color: var(--accent); box-shadow: var(--ring); outline: none; }
textarea.input { min-height: 96px; resize: vertical; }

.alert {
  padding: 13px 17px; border-radius: var(--radius-sm);
  border: 2px solid var(--danger); background: var(--danger-soft);
  color: var(--danger); font-weight: 600; margin-bottom: 16px;
}
.alert--ok   { border-color: var(--success); background: var(--success-soft); color: var(--success); }
.alert--info { border-color: var(--accent);  background: var(--accent-soft);  color: var(--accent-deep); }

.switch { display: flex; align-items: center; gap: 12px; padding: 11px 0; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch__track {
  width: 56px; height: 32px; border-radius: 999px; flex: none;
  background: var(--line-strong); position: relative; transition: background var(--dur);
}
.switch__track::after {
  content: ''; position: absolute; top: 3px; left: 3px;
  width: 26px; height: 26px; border-radius: 50%; background: #fff;
  transition: transform var(--dur); box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
.switch input:checked + .switch__track { background: var(--accent); }
.switch input:checked + .switch__track::after { transform: translateX(24px); }
.switch input:focus-visible + .switch__track { box-shadow: var(--ring); }
.switch__label { font-weight: 600; }
.switch__label small { display: block; font-weight: 400; color: var(--ink-faint); font-size: .84rem; }

/* =====================================================================
   THE BOARD
   ===================================================================== */
.app { display: flex; flex-direction: column; height: 100dvh; overflow: hidden; }

.topbar {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; background: var(--bg-raised);
  border-bottom: 1px solid var(--line); flex: none;
}
.topbar__brand { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 1.05rem; }
.topbar__brand .mark { font-size: 1.4rem; }

/* The logo in a page header. An <img> of the SVG rather than inline markup,
   so one file is the single source of the mark and the service worker can
   cache it once for every page. */
.brandmark {
  width: 30px; height: 30px; flex: none; display: block;
  border-radius: 7px;
}
.topbar__brand .brandmark { width: 28px; height: 28px; }
/* The mark standing on its own — a call-to-action card, a splash. Centred,
   because in that position it is the picture rather than a bullet point. */
.brandmark--lg { width: 64px; height: 64px; border-radius: 15px; margin: 0 auto 6px; }
.topbar__spacer { flex: 1; }
/* The tools row scrolls rather than pushing buttons off the edge, so
   nothing — least of all Settings — can become unreachable on a phone. */
.topbar__tools {
  display: flex; align-items: center; gap: 6px;
  overflow-x: auto; overflow-y: hidden; min-width: 0;
  scrollbar-width: none; -ms-overflow-style: none;
}
.topbar__tools::-webkit-scrollbar { display: none; }
.topbar__tools > * { flex: none; }
.topbar__child {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 14px; border-radius: 999px; background: var(--bg-sunken);
  font-weight: 700; font-size: .92rem;
}
.iconbtn {
  width: 50px; height: 50px; border-radius: var(--radius-sm);
  display: grid; place-items: center; font-size: 1.3rem;
  border: 2px solid transparent; transition: background var(--dur), border-color var(--dur);
}
.iconbtn:hover { background: var(--bg-sunken); border-color: var(--line); }
.iconbtn--on { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.iconbtn--danger { color: var(--danger); }

/* ---- sentence strip: the child's own words, never rewritten ---- */
.strip {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; background: var(--bg-raised);
  border-bottom: 2px solid var(--line); flex: none; min-height: 96px;
}
.strip__words {
  flex: 1; display: flex; gap: 8px; align-items: center;
  overflow-x: auto; overflow-y: hidden; min-height: 76px;
  padding: 4px; border-radius: var(--radius-sm); background: var(--bg-sunken);
  scrollbar-width: thin;
}
.strip__empty {
  color: var(--ink-faint); font-style: italic; padding: 0 14px;
  display: flex; align-items: center; gap: 8px; font-size: .95rem;
}
.strip__word {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-width: 72px; padding: 6px 10px; border-radius: var(--radius-sm);
  background: var(--bg-raised); border: 2px solid var(--line-strong);
  flex: none; animation: pop var(--dur) ease-out;
}
.strip__word .e { font-size: 1.6rem; line-height: 1; font-family: var(--emoji-font); }
.strip__word .t { font-size: .78rem; font-weight: 700; margin-top: 3px; white-space: nowrap; }
@keyframes pop { from { transform: scale(.6); opacity: 0; } to { transform: scale(1); opacity: 1; } }

.strip__actions { display: flex; gap: 8px; flex: none; }
.strip__speak {
  min-width: 116px; height: 76px; border-radius: var(--radius);
  background: var(--accent); color: var(--accent-ink);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-weight: 800; font-size: 1rem; gap: 2px;
  box-shadow: var(--shadow); transition: transform var(--dur);
}
.strip__speak:active { transform: scale(.96); }
.strip__speak .e { font-size: 1.7rem; font-family: var(--emoji-font); }
.strip__small {
  width: 62px; height: 76px; border-radius: var(--radius);
  background: var(--bg-sunken); border: 2px solid var(--line-strong);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-size: .68rem; font-weight: 700; gap: 2px;
}
.strip__small .e { font-size: 1.35rem; font-family: var(--emoji-font); }

/* ---- smart row: the AI's suggestions, clearly marked as suggestions ---- */
.smartrow {
  display: flex; align-items: center; gap: 8px; flex: none;
  padding: 8px 12px; background: linear-gradient(var(--accent-soft), var(--bg-raised));
  border-bottom: 1px solid var(--line); overflow-x: auto;
}
.smartrow__label {
  display: flex; align-items: center; gap: 6px; flex: none;
  font-size: .78rem; font-weight: 800; color: var(--accent-deep);
  text-transform: uppercase; letter-spacing: .06em; padding-right: 4px;
}
.smartrow__items { display: flex; gap: 8px; }
.smart {
  display: flex; align-items: center; gap: 7px; flex: none;
  padding: 9px 15px; border-radius: 999px;
  background: var(--bg-raised); border: 2px dashed var(--accent);
  font-weight: 700; font-size: .93rem; color: var(--accent-deep);
  transition: transform var(--dur), background var(--dur);
}
.smart:hover  { background: var(--accent-soft); }
.smart:active { transform: scale(.95); }
.smart .e { font-size: 1.25rem; font-family: var(--emoji-font); }

/* ---- main area ---- */
.main { flex: 1; display: flex; min-height: 0; }

/* The rail is a column: a scrolling list of categories, and a pinned HELP
   button at the foot. HELP is deliberately part of the layout rather than
   floating over it — a safety control that can cover a category, or be
   covered by one, is not a safety control. */
.rail {
  width: 128px; flex: none; display: flex; flex-direction: column;
  background: var(--bg-sunken); border-right: 1px solid var(--line);
  min-height: 0;
}
.rail__list {
  flex: 1; overflow-y: auto; min-height: 0;
  padding: 10px 8px; display: flex; flex-direction: column; gap: 7px;
}
.rail__foot {
  flex: none; padding: 10px 8px 14px;
  border-top: 1px solid var(--line);
  display: grid; place-items: center;
  background: var(--bg-sunken);
}
.rail__btn {
  border-radius: var(--radius-sm); padding: 11px 6px;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  border: 2px solid transparent; background: var(--bg-raised);
  font-size: .72rem; font-weight: 700; text-align: center; line-height: 1.2;
  transition: transform var(--dur), border-color var(--dur);
}
.rail__btn .e { font-size: 1.65rem; font-family: var(--emoji-font); }
.rail__btn:active { transform: scale(.96); }
.rail__btn--on { border-color: var(--ink); box-shadow: var(--shadow); }

/* Bottom padding clears the floating Buddy so the last row of words is
   never covered by it. */
.board { flex: 1; overflow-y: auto; padding: 12px 12px 120px; }
.board__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--tile), 1fr));
  gap: var(--gap);
  align-content: start;
}
.board__section + .board__section { margin-top: 22px; }
.board__heading {
  display: flex; align-items: center; gap: 9px; margin: 0 0 10px;
  font-size: .95rem; font-weight: 800; color: var(--ink-soft);
  text-transform: uppercase; letter-spacing: .06em;
}
.board__heading .e { font-size: 1.25rem; font-family: var(--emoji-font); }

/* ---- the word tile: the single most important element in the app ---- */
.tile {
  aspect-ratio: 1 / .94;
  min-height: 88px;               /* the accessibility floor */
  border-radius: var(--radius);
  border: 2px solid var(--line-strong);
  background: var(--bg-raised);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 5px; padding: 8px 6px; position: relative; overflow: hidden;
  transition: transform var(--dur), box-shadow var(--dur), border-color var(--dur);
  text-align: center;
}
.tile:hover  { box-shadow: var(--shadow-lift); border-color: var(--ink-faint); }
.tile:active { transform: scale(.95); }
.tile__emoji { font-size: var(--tile-emoji); line-height: 1; font-family: var(--emoji-font); }
.tile__photo {
  width: 100%; flex: 1; min-height: 0; object-fit: cover;
  border-radius: var(--radius-sm);
}
.tile__label {
  font-size: var(--tile-font); font-weight: 700; line-height: 1.15;
  word-break: break-word; hyphens: auto;
}
.tile--core  { border-width: 3px; }
.tile--urgent { border-color: var(--danger); background: var(--danger-soft); }
.tile--just-used { animation: usedFlash .6s ease-out; }
@keyframes usedFlash {
  0%   { box-shadow: 0 0 0 0 rgba(74,124,126,.55); }
  100% { box-shadow: 0 0 0 22px rgba(74,124,126,0); }
}
.tile__dwell {
  position: absolute; inset: auto 0 0 0; height: 5px;
  background: var(--accent); width: 0;
}

/* ---- Buddy ---- */
.buddy {
  position: fixed; right: 18px; bottom: 18px; z-index: 60;
  display: flex; align-items: flex-end; gap: 12px; max-width: min(430px, 88vw);
  pointer-events: none;
}
.buddy__bubble {
  background: var(--bg-raised); border: 2px solid var(--accent);
  border-radius: var(--radius-lg) var(--radius-lg) 6px var(--radius-lg);
  padding: 14px 18px; box-shadow: var(--shadow-lift);
  font-size: 1.02rem; font-weight: 600; pointer-events: auto;
  animation: bubbleIn .28s cubic-bezier(.2,.9,.3,1.2);
}
@keyframes bubbleIn { from { transform: translateY(14px) scale(.9); opacity: 0; } }
.buddy__choices { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 11px; }
.buddy__choice {
  padding: 7px 13px; border-radius: 999px; border: 2px solid var(--line-strong);
  background: var(--bg-sunken); font-size: .87rem; font-weight: 700;
  display: inline-flex; align-items: center; gap: 5px;
}
.buddy__choice:hover { border-color: var(--accent); background: var(--accent-soft); }
/* Talking back to Buddy. Kept visually quieter than the board itself —
   this is a companion, not a second communication system competing with
   the child's own words. */
.buddy__say {
  /* The .buddy container is pointer-events:none on purpose, so Buddy can
     never swallow a tap meant for a word. Interactive children have to opt
     back in one at a time — without this the reply box renders perfectly
     and cannot be clicked, because a board tile is underneath it. */
  pointer-events: auto;
  display: flex; gap: 7px; margin-top: 9px; align-items: center;
  background: var(--bg-raised); border: 2px solid var(--line-strong);
  border-radius: 999px; padding: 5px 6px 5px 8px;
  box-shadow: var(--shadow);
}
.buddy__input {
  flex: 1; min-width: 0; border: none; background: none; outline: none;
  font-size: .95rem; padding: 7px 4px; color: var(--ink);
}
.buddy__input::placeholder { color: var(--ink-faint); }
.buddy__mic, .buddy__send {
  flex: none; width: 38px; height: 38px; border-radius: 50%;
  display: grid; place-items: center; font-size: 1.05rem;
  background: var(--bg-sunken); color: var(--ink);
}
.buddy__send { background: var(--accent); color: var(--accent-ink); font-size: 1.1rem; }
.buddy__mic:hover, .buddy__send:hover { filter: brightness(.95); }
.buddy__mic--on {
  background: var(--danger); color: #fff;
  animation: micPulse 1.1s ease-in-out infinite;
}
@keyframes micPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.12); } }
[data-motion="off"] .buddy__mic--on { animation: none; }

.buddy__face {
  width: 78px; height: 78px; flex: none; border-radius: 50%;
  background: var(--accent-soft); border: 3px solid var(--accent);
  display: grid; place-items: center; font-size: 2.6rem;
  box-shadow: var(--shadow); pointer-events: auto; font-family: var(--emoji-font);
  animation: breathe 4.5s ease-in-out infinite;
}
@keyframes breathe { 0%,100% { transform: scale(1); } 50% { transform: scale(1.05); } }

/* ---- HELP button: always reachable, never accidental ---- */
.helpbtn {
  position: relative; z-index: 1;
  width: 96px; height: 96px; border-radius: 50%;
  background: var(--danger); color: #fff;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-weight: 800; font-size: .82rem; gap: 1px;
  box-shadow: 0 6px 22px rgba(180,69,60,.42);
  border: 4px solid var(--bg-raised);
}
.helpbtn .e { font-size: 1.9rem; font-family: var(--emoji-font); }
.helpbtn:active { transform: scale(.94); }
.helpbtn__ring {
  position: absolute; inset: -4px; border-radius: 50%;
  border: 4px solid var(--danger); opacity: 0;
}
.helpbtn--holding .helpbtn__ring { animation: helpRing .9s linear; opacity: 1; }
@keyframes helpRing { from { transform: scale(1); opacity: .9; } to { transform: scale(1.5); opacity: 0; } }

/* ---- overlays ---- */
.overlay {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(30,27,24,.55); backdrop-filter: blur(3px);
  display: grid; place-items: center; padding: 20px;
  animation: fade .18s ease-out;
}
@keyframes fade { from { opacity: 0; } }
.overlay__panel {
  background: var(--bg); border-radius: var(--radius-lg);
  width: min(760px, 100%); max-height: 90dvh; overflow-y: auto;
  box-shadow: var(--shadow-lift); border: 1px solid var(--line);
}
.overlay__head {
  display: flex; align-items: center; gap: 12px;
  padding: 20px 24px; border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--bg); z-index: 1;
}
.overlay__head h2 { margin: 0; font-size: 1.3rem; }
.overlay__body { padding: 24px; }
.overlay__foot {
  padding: 16px 24px; border-top: 1px solid var(--line);
  display: flex; gap: 10px; justify-content: flex-end;
  position: sticky; bottom: 0; background: var(--bg);
}

/* ---- calm space ---- */
.calm {
  position: fixed; inset: 0; z-index: 120;
  background: linear-gradient(165deg, #2C4A52, #16262B);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 30px; color: #EAF3F4;
}
.calm__orb {
  width: 190px; height: 190px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #9FD6D8, #4A8A8E 55%, #2F6367);
  box-shadow: 0 0 70px rgba(159,214,216,.42);
  animation: breatheBig 11s ease-in-out infinite;
}
@keyframes breatheBig {
  0%, 100% { transform: scale(.66); }
  36%      { transform: scale(1); }
  64%      { transform: scale(1); }
}
.calm__text { font-size: 1.5rem; font-weight: 700; min-height: 2em; }
.calm__sub  { opacity: .78; font-size: .98rem; }

/* ---- cause-and-effect game ---- */
.play { position: fixed; inset: 0; z-index: 120; background: var(--bg-sunken); overflow: hidden; }
.play__target {
  position: absolute; width: 118px; height: 118px; border-radius: 50%;
  display: grid; place-items: center; font-size: 3.2rem; font-family: var(--emoji-font);
  box-shadow: var(--shadow-lift); border: 4px solid var(--bg-raised);
  transition: transform .2s;
}
.play__target:active { transform: scale(.88); }
.play__burst {
  position: absolute; pointer-events: none; font-size: 2rem;
  animation: burst .95s ease-out forwards; font-family: var(--emoji-font);
}
@keyframes burst {
  to { transform: translate(var(--dx), var(--dy)) scale(.2) rotate(var(--rot)); opacity: 0; }
}

/* ---- reward ---- */
.reward {
  position: fixed; inset: 0; z-index: 130; display: grid; place-items: center;
  pointer-events: none;
}
.reward__star {
  font-size: 8rem; font-family: var(--emoji-font);
  animation: rewardPop 1.5s cubic-bezier(.2,.9,.3,1.4) forwards;
}
@keyframes rewardPop {
  0%   { transform: scale(0) rotate(-30deg); opacity: 0; }
  35%  { transform: scale(1.25) rotate(8deg); opacity: 1; }
  70%  { transform: scale(1) rotate(0); opacity: 1; }
  100% { transform: scale(.85) translateY(-40px); opacity: 0; }
}

/* ---- schedule strip ---- */
.schedule {
  display: flex; align-items: center; gap: 8px; flex: none;
  padding: 8px 12px; background: var(--warm-soft);
  border-bottom: 1px solid var(--line); overflow-x: auto;
}
.schedule__step {
  display: flex; flex-direction: column; align-items: center; gap: 3px; flex: none;
  padding: 7px 13px; border-radius: var(--radius-sm);
  background: var(--bg-raised); border: 2px solid var(--line-strong);
  font-size: .74rem; font-weight: 700; min-width: 78px;
}
.schedule__step .e { font-size: 1.5rem; font-family: var(--emoji-font); }
.schedule__step--now  { border-color: var(--warm); box-shadow: var(--shadow); }
.schedule__step--done { opacity: .42; text-decoration: line-through; }

/* =====================================================================
   LANDING PAGE
   ===================================================================== */
.site { max-width: 1120px; margin: 0 auto; padding: 0 22px; }
.sitehead {
  display: flex; align-items: center; gap: 16px;
  padding: 20px 0; flex-wrap: wrap;
}
.sitehead nav { display: flex; gap: 6px; margin-left: auto; flex-wrap: wrap; }
.sitehead nav a {
  padding: 10px 16px; border-radius: var(--radius-sm);
  font-weight: 700; text-decoration: none; color: var(--ink-soft);
}
.sitehead nav a:hover { background: var(--bg-sunken); color: var(--ink); }

.hero { padding: 44px 0 56px; display: grid; gap: 44px; grid-template-columns: 1.1fr .9fr; align-items: center; }
.hero h1 { font-size: clamp(2.1rem, 5vw, 3.4rem); letter-spacing: -.025em; }
.hero p.lede { font-size: 1.18rem; color: var(--ink-soft); max-width: 48ch; }
.hero__actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 26px; }
.hero__demo {
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 18px; box-shadow: var(--shadow-lift);
}
.hero__demo-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 9px; }
.hero__demo-tile {
  aspect-ratio: 1/.9; border-radius: var(--radius-sm); border: 2px solid var(--line-strong);
  background: var(--bg); display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 3px; font-size: .74rem; font-weight: 700;
}
.hero__demo-tile .e { font-size: 1.8rem; font-family: var(--emoji-font); }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; margin: 8px 0 50px; }
.stat { background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px; text-align: center; }
.stat b { display: block; font-size: 1.9rem; color: var(--accent-deep); line-height: 1.1; }
.stat span { font-size: .86rem; color: var(--ink-soft); font-weight: 600; }

.section { padding: 54px 0; border-top: 1px solid var(--line); }
.section > h2 { font-size: clamp(1.6rem, 3.4vw, 2.3rem); margin-bottom: 10px; }
.section > p.sub { color: var(--ink-soft); max-width: 62ch; font-size: 1.06rem; margin-bottom: 32px; }

.grid3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); gap: 18px; }
.feature { background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius); padding: 24px; }
.feature__icon {
  width: 54px; height: 54px; border-radius: 15px; display: grid; place-items: center;
  font-size: 1.7rem; background: var(--accent-soft); margin-bottom: 14px; font-family: var(--emoji-font);
}
.feature h3 { font-size: 1.13rem; }
.feature p { color: var(--ink-soft); font-size: .96rem; margin: 0; }

.sitefoot { padding: 40px 0; border-top: 1px solid var(--line); color: var(--ink-faint); font-size: .9rem; }
.sitefoot a { color: var(--ink-soft); }

/* ---- auth panel ---- */
.authwrap { min-height: 100dvh; display: grid; place-items: center; padding: 24px; }
.auth { width: min(470px, 100%); }
.auth__tabs { display: flex; gap: 6px; margin-bottom: 22px; background: var(--bg-sunken); padding: 5px; border-radius: var(--radius-sm); }
.auth__tab { flex: 1; padding: 12px; border-radius: 9px; font-weight: 700; color: var(--ink-soft); }
.auth__tab--on { background: var(--bg-raised); color: var(--ink); box-shadow: var(--shadow); }

/* ---- consent ---- */
.consent {
  border: 2px solid var(--line-strong); border-radius: var(--radius);
  background: var(--bg-sunken); padding: 15px 16px; margin-bottom: 18px;
}
.consent__check { display: flex; gap: 12px; align-items: flex-start; cursor: pointer; }
.consent__check input[type=checkbox] {
  flex: none; width: 24px; height: 24px; margin-top: 2px; accent-color: var(--accent);
}
.consent__check span { font-size: .88rem; line-height: 1.6; color: var(--ink-soft); }
.consent__check a { font-weight: 700; }
.consent--bad { border-color: var(--danger); background: var(--danger-soft); }

/* ---- onboarding ---- */
.steps { display: flex; gap: 7px; margin-bottom: 26px; }
.steps__dot { flex: 1; height: 6px; border-radius: 999px; background: var(--line); }
.steps__dot--on { background: var(--accent); }
.chipset { display: flex; flex-wrap: wrap; gap: 9px; }
.chip {
  padding: 11px 17px; border-radius: 999px; border: 2px solid var(--line-strong);
  background: var(--bg-raised); font-weight: 700; font-size: .95rem;
  display: inline-flex; align-items: center; gap: 7px;
}
.chip--on { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-deep); }

/* =====================================================================
   DASHBOARD
   ===================================================================== */
.dash { max-width: 1240px; margin: 0 auto; padding: 22px; }
.dash__head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 24px; }
.dash__tabs { display: flex; gap: 5px; flex-wrap: wrap; margin-bottom: 24px; border-bottom: 2px solid var(--line); }
.dash__tab {
  padding: 13px 20px; font-weight: 700; color: var(--ink-soft);
  border-bottom: 3px solid transparent; margin-bottom: -2px;
}
.dash__tab--on { color: var(--accent-deep); border-bottom-color: var(--accent); }

.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); gap: 14px; margin-bottom: 26px; }
.kpi { background: var(--bg-raised); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px; }
.kpi b { display: block; font-size: 2rem; line-height: 1.1; color: var(--accent-deep); }
.kpi span { font-size: .84rem; color: var(--ink-soft); font-weight: 600; }
.kpi small { display: block; font-size: .78rem; color: var(--ink-faint); margin-top: 5px; }

.bars { display: flex; flex-direction: column; gap: 11px; }
.bar__row { display: grid; grid-template-columns: 190px 1fr 62px; gap: 12px; align-items: center; font-size: .92rem; }
.bar__track { height: 26px; border-radius: 7px; background: var(--bg-sunken); overflow: hidden; position: relative; }
.bar__fill { height: 100%; background: var(--accent); border-radius: 7px; transition: width .5s; }
.bar__target { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--warm); }
.bar__val { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }

.spark { display: flex; align-items: flex-end; gap: 3px; height: 76px; }
.spark__bar { flex: 1; background: var(--accent); border-radius: 3px 3px 0 0; min-height: 2px; }

.insight {
  border-left: 5px solid var(--accent); background: var(--bg-raised);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: 16px 20px; margin-bottom: 13px; border-top: 1px solid var(--line);
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.insight h4 { margin: 0 0 5px; font-size: 1.02rem; }
.insight p { margin: 0; color: var(--ink-soft); font-size: .95rem; }
.insight--good      { border-left-color: var(--success); }
.insight--action    { border-left-color: var(--warm); }
.insight--attention { border-left-color: var(--danger); }
.insight--info      { border-left-color: var(--ink-faint); }

.wordchips { display: flex; flex-wrap: wrap; gap: 8px; }
.wordchip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: 999px; background: var(--bg-sunken);
  border: 1px solid var(--line); font-size: .89rem; font-weight: 600;
}
.wordchip .e { font-size: 1.05rem; font-family: var(--emoji-font); }
.wordchip b { color: var(--accent-deep); font-variant-numeric: tabular-nums; }

.table { width: 100%; border-collapse: collapse; font-size: .93rem; }
.table th, .table td { padding: 11px 13px; text-align: left; border-bottom: 1px solid var(--line); }
.table th { font-weight: 800; color: var(--ink-soft); font-size: .82rem; text-transform: uppercase; letter-spacing: .05em; }

.editrow {
  display: grid; grid-template-columns: 54px 1fr 1fr auto; gap: 11px;
  align-items: center; padding: 11px; border-bottom: 1px solid var(--line);
}
.editrow__e { font-size: 1.9rem; text-align: center; font-family: var(--emoji-font); }

/* ---- dedication ----
   Sits in the corner of the board and is never in the way. It cannot be
   tapped, so it can never steal a press meant for a word. */
.dedication {
  margin: 0; flex: none; max-width: 268px;
  font-size: .68rem; line-height: 1.28; color: var(--ink-faint);
  display: flex; align-items: center; gap: 7px;
  pointer-events: none; user-select: none;
}
.dedication__heart { font-size: .95rem; font-family: var(--emoji-font); }
.dedication b { color: var(--ink-soft); font-weight: 700; }
/* ---- the donation ask ----
   Warm, but quieter than anything the child uses. It must never look like
   the most important thing on a page about a disabled child's voice. */
.give {
  background: var(--warm-soft); border: 1px solid var(--warm);
  border-left: 4px solid var(--warm);
  border-radius: 4px var(--radius) var(--radius) 4px;
  padding: 22px 24px; margin: 24px 0;
}
.give h3 { margin: 0 0 12px; font-size: 1.12rem; color: var(--ink); }
.give p { color: var(--ink-soft); line-height: 1.7; margin: 0 0 12px; }
.give__actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 18px 0 12px; }
.give__small { font-size: .86rem; color: var(--ink-faint); margin: 0; }
.give--compact { padding: 16px 18px; margin: 18px 0; }
.give--compact p { font-size: .92rem; margin-bottom: 12px; }

/* ---- the language table ---- */
.langtable td { vertical-align: top; }
.langtable td small {
  display: block; color: var(--ink-faint); font-size: .8rem; font-weight: 400;
}
.langtable b { font-size: 1.02rem; }
.langrow--on { background: var(--accent-soft); }
.langrow--on td:first-child b { color: var(--accent-deep); }
.langrow__ok   { color: var(--success); font-weight: 700; }
.langrow__no   { color: var(--danger);  font-weight: 700; }
.langrow__wait { color: var(--ink-faint); }

/* The slogan, where it is the line rather than a footnote. */
.slogan {
  font-size: 1.06rem; font-weight: 700; color: var(--accent-deep);
  margin: -4px 0 18px; max-width: 30ch; line-height: 1.4;
}
.slogan--foot {
  color: var(--ink-soft); font-size: 1rem; max-width: none; margin: 0 0 10px;
}

/* One of the two is shown, never both: the top bar on a wide screen, the
   foot of the board on a narrow one. */
.dedication--foot {
  max-width: none; justify-content: center; margin: 18px 0 6px;
  font-size: .78rem; display: none;
}
@media (max-width: 1040px) {
  .topbar .dedication { display: none; }
  .dedication--foot { display: flex; }
}

.empty { text-align: center; padding: 56px 20px; color: var(--ink-faint); }
.empty .e { font-size: 3.2rem; display: block; margin-bottom: 14px; font-family: var(--emoji-font); }

/* ---------------- responsive ---------------- */
@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; gap: 32px; }
  .bar__row { grid-template-columns: 118px 1fr 50px; font-size: .84rem; }
}
@media (max-width: 720px) {
  .topbar { padding: 6px 8px; gap: 6px; }
  .topbar__brand .hide-sm { display: none; }
  .topbar__child { padding: 5px 10px; font-size: .84rem; max-width: 108px;
                   overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .iconbtn { width: 44px; height: 44px; font-size: 1.15rem; }
  .strip { gap: 7px; padding: 8px; }
  .strip__hint { display: none; }
  .strip__empty { padding: 0 8px; }
  .strip__small { width: 52px; font-size: .6rem; }
  .strip__speak { min-width: 84px; font-size: .86rem; }
  .rail { width: 88px; }
  .rail__list { padding: 8px 5px; }
  .rail__foot { padding: 8px 5px 10px; }
  .rail__btn { font-size: .62rem; padding: 8px 3px; }
  .rail__btn .e { font-size: 1.35rem; }
  .buddy { right: 10px; bottom: 14px; max-width: calc(100vw - 20px); }
  .buddy__face { width: 58px; height: 58px; font-size: 1.9rem; }
  .helpbtn { width: 74px; height: 74px; font-size: .7rem; border-width: 3px; }
  .helpbtn .e { font-size: 1.5rem; }
  .strip__speak { min-width: 92px; }
  .site { padding: 0 16px; }
  .dash { padding: 14px; }
}
@media (max-width: 560px) {
  /* Every control must fit without scrolling the tools row — an adult
     hunting for Settings on a phone is a failure of the design. */
  .topbar__child #childName { display: none; }
  .topbar__child { max-width: none; padding: 5px 9px; }
  .iconbtn { width: 40px; height: 40px; font-size: 1.05rem; }
  .topbar { gap: 4px; }
  .topbar__tools { gap: 3px; }
}

/* Smallest phones still in use (iPhone SE, budget Android). */
@media (max-width: 360px) {
  .iconbtn { width: 37px; height: 37px; font-size: .98rem; }
  .topbar { gap: 3px; padding: 5px 5px; }
  .topbar__tools { gap: 2px; }
  .topbar__brand .mark { font-size: 1.2rem; }
  .topbar__child { padding: 4px 7px; }
}

@media (max-width: 480px) {
  .hero__demo-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .hero__demo { padding: 12px; }
  .hero { padding: 24px 0 34px; }
  .stat b { font-size: 1.6rem; }
  .strip { min-height: 84px; }
  .strip__words { min-height: 66px; }
  .strip__word { min-width: 60px; }
  .strip__speak, .strip__small { height: 66px; }
}

/* Landscape phones: every vertical pixel counts. */
@media (max-height: 500px) and (orientation: landscape) {
  .strip { min-height: 72px; padding: 6px 10px; }
  .strip__words { min-height: 58px; }
  .strip__speak, .strip__small { height: 58px; }
  .smartrow { padding: 5px 10px; }
}

@media print {
  body { background: #fff; }
  .topbar, .rail, .smartrow, .buddy, .strip__actions { display: none !important; }
}

/* =====================================================================
   Switch scanning highlight
   ---------------------------------------------------------------------
   The moving highlight is the only thing on screen telling a switch user
   where they are. If it is subtle, it is useless — a child with cortical
   visual impairment scanning a board across the room needs to see it
   without hunting for it. So: thick, and drawn as a two-colour sandwich
   (a solid ring with a contrasting collar around it) so that it stays
   obvious over any tile colour, photo or emoji in any of the four themes.

   Drawn with `outline` and `box-shadow` only, never `border` or padding.
   An outline takes no space in layout, so nothing on the board moves as
   the highlight passes. A shifting board destroys motor planning and is
   unusable for the children this feature exists for.

   Two levels are visually distinct, because in row-column scanning the
   child must be able to tell "this whole row is offered" from "this one
   cell is offered": the group ring is thinner and dashed, the item ring
   is thicker and solid, and both can be on screen at once.
   ===================================================================== */
:root {
  --scan-w:        6px;        /* item ring thickness */
  --scan-group-w:  4px;        /* group ring thickness */
  --scan-gap:      2px;        /* clear space between tile and ring */
  --scan-ring:     #0B4FA0;    /* item ring — deep blue against the leafy bg */
  --scan-halo:     #FFD400;    /* collar around it, for figure/ground */
  --scan-group-ring: #B3541E;  /* group ring — warm, clearly not the item */
  --scan-group-halo: #FFF0C2;
}

[data-theme="bright"] {
  --scan-ring: #08409A; --scan-halo: #FFE01F;
  --scan-group-ring: #A8410F; --scan-group-halo: #FFEDCB;
}

/* On a dark board the polarity flips: a bright ring on a dark collar. */
[data-theme="dark"] {
  --scan-ring: #FFC53D; --scan-halo: #0B0E10;
  --scan-group-ring: #7FD4D7; --scan-group-halo: #0B0E10;
}

/* Maximum available contrast: pure yellow on pure black, and thicker. */
[data-theme="contrast"] {
  --scan-w: 8px; --scan-group-w: 6px;
  --scan-ring: #FFE500; --scan-halo: #000000;
  --scan-group-ring: #FFFFFF; --scan-group-halo: #000000;
}

/* Every item of the row/category currently being offered. */
.scan-group-hl {
  position: relative;
  z-index: 4;
  outline: var(--scan-group-w) dashed var(--scan-group-ring);
  outline-offset: var(--scan-gap);
  box-shadow:
    0 0 0 calc(var(--scan-gap) + var(--scan-group-w) + 2px) var(--scan-group-halo);
}

/* The single item the switch would choose right now. */
.scan-hl {
  position: relative;
  z-index: 6;                  /* always drawn over its neighbours */
  outline: var(--scan-w) solid var(--scan-ring);
  outline-offset: var(--scan-gap);
  box-shadow:
    inset 0 0 0 3px var(--scan-halo),
    0 0 0 calc(var(--scan-gap) + var(--scan-w) + 3px) var(--scan-halo);
  animation: scanPulse 1s ease-in-out infinite alternate;
}

/* An item inside the offered group wins: its ring replaces the group's. */
.scan-hl.scan-group-hl {
  outline: var(--scan-w) solid var(--scan-ring);
  outline-offset: var(--scan-gap);
}

/* A gentle breath, so the highlight reads as "live" and is easier to
   locate for a child with low vision. It moves the ring outwards rather
   than changing its colour: contrast never drops below full, and outline
   sits outside layout so nothing on the board moves. Never a flash —
   flicker between 3 and 50Hz is a seizure risk, and this app is used by
   children with epilepsy. */
@keyframes scanPulse {
  from { outline-offset: var(--scan-gap); }
  to   { outline-offset: calc(var(--scan-gap) + 4px); }
}

/* Motion off means motion off. The static ring alone is already at full
   contrast, so nothing is lost. */
[data-motion="off"] .scan-hl,
[data-motion="off"] .scan-group-hl {
  animation: none !important;
  outline-offset: var(--scan-gap);
}
@media (prefers-reduced-motion: reduce) {
  .scan-hl { animation: none; }
}

/* =====================================================================
   Spelling keyboard
   ---------------------------------------------------------------------
   For children who can spell, or are learning to. Sizing rules:
     * No key is ever shorter than 44px. That is the accessibility floor,
       not a target — the letter keys grow with available height.
     * The whole keyboard has to fit 320px without a sideways scroll, so
       every row is flex with `min-width: 0` children and the keys share
       the width rather than demanding their own.
     * Only colours from the token set above, so all four themes work
       with no extra rules.
     * The prediction row keeps its height when it is empty. Keys that
       shift under a child's finger destroy motor planning.
   ===================================================================== */
.kbd {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  padding: 10px;
  background: var(--bg-sunken);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* ---- the line the child is typing ---- */
.kbd__line {
  min-height: 52px;
  padding: 12px 14px;
  background: var(--bg-raised);
  border: 2px solid var(--line-strong);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-size: 1.25rem;
  line-height: 1.35;
  overflow-wrap: break-word;
  word-break: break-word;
}
.kbd__placeholder { color: var(--ink-faint); font-style: italic; }
.kbd__caret {
  display: inline-block;
  width: 2px;
  height: 1.1em;
  margin-left: 1px;
  vertical-align: text-bottom;
  background: var(--accent);
}

/* ---- prediction row ---- */
.kbd__pred {
  display: flex;
  gap: 6px;
  min-height: 48px;
  align-items: stretch;
}
.kbd__pred > * { flex: 1 1 0; min-width: 0; }
.kbd__predslot {
  border: 2px dashed var(--line);
  border-radius: var(--radius-sm);
  opacity: .4;
}
.kbd__predbtn {
  min-height: 48px;
  padding: 6px 4px;
  font-family: inherit;
  font-size: clamp(.72rem, 3vw, 1rem);
  font-weight: 700;
  color: var(--accent-ink);
  background: var(--accent);
  border: 2px solid var(--accent-deep);
  border-radius: var(--radius-sm);
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: transform var(--dur), filter var(--dur);
}
/* A word the child has used before is theirs; mark it so a caregiver can
   see the model working, and so the child recognises their own words. */
.kbd__predbtn[data-source="learned"] { background: var(--success); border-color: var(--success); }
.kbd__predbtn[data-source="context"] { background: var(--warm); border-color: var(--warm); color: #fff; }
.kbd__predbtn:hover { filter: brightness(1.08); }
.kbd__predbtn:active { transform: scale(.97); }

/* ---- the keys ---- */
.kbd__keys { display: flex; flex-direction: column; gap: 6px; }
.kbd__row { display: flex; gap: 5px; }
.kbd__row > * { flex: 1 1 0; min-width: 0; }

.kbd__key {
  min-height: 46px;
  padding: 4px 2px;
  font-family: inherit;
  font-size: clamp(.85rem, 3.6vw, 1.15rem);
  font-weight: 700;
  color: var(--ink);
  background: var(--bg-raised);
  border: 2px solid var(--line-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
  user-select: none;
  transition: transform var(--dur), background var(--dur);
}
.kbd__key:hover { background: var(--accent-soft); }
.kbd__key:active { transform: scale(.95); }
.kbd__key--letter { text-transform: uppercase; }
.kbd__key--punct { flex-grow: .7; color: var(--ink-soft); }

.kbd__row--actions .kbd__key { min-height: 52px; font-size: clamp(.72rem, 3vw, .95rem); }
.kbd__key--space { flex-grow: 3; letter-spacing: .06em; }
.kbd__key--back { flex-grow: 1.2; font-size: 1.2rem; }
.kbd__key--clear { flex-grow: 1.2; color: var(--danger); border-color: var(--danger); }
.kbd__key--clear:hover { background: var(--danger-soft); }

/* SPEAK is the point of the whole screen, so it is the biggest thing on
   it and it never shares a row with anything that could be mis-hit. */
.kbd__row--speak .kbd__key { min-height: 60px; }
.kbd__key--speak {
  flex-grow: 5;
  font-size: clamp(1rem, 4.4vw, 1.35rem);
  color: var(--accent-ink);
  background: var(--accent);
  border-color: var(--accent-deep);
}
.kbd__key--speak:hover { background: var(--accent-deep); }
.kbd__speakicon { font-family: var(--emoji-font); }
.kbd__key--close { flex-grow: 1; color: var(--ink-soft); font-size: 1.1rem; }

.kbd__key:focus-visible, .kbd__predbtn:focus-visible {
  outline: none;
  box-shadow: var(--ring);
  position: relative;
  z-index: 1;
}

/* Small phones: tighten the gaps, never the touch targets. */
@media (max-width: 400px) {
  .kbd { padding: 7px; gap: 6px; }
  .kbd__row { gap: 3px; }
  .kbd__keys { gap: 5px; }
  .kbd__pred { gap: 4px; }
  .kbd__key { padding: 4px 0; border-width: 2px; }
  .kbd__line { font-size: 1.1rem; padding: 10px; }
}

/* Landscape phones: a keyboard that pushes SPEAK off screen is useless. */
@media (max-height: 500px) and (orientation: landscape) {
  .kbd__line { min-height: 44px; padding: 8px 12px; }
  .kbd__key { min-height: 44px; }
  .kbd__row--speak .kbd__key { min-height: 48px; }
  .kbd__pred, .kbd__predbtn { min-height: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  .kbd__key, .kbd__predbtn { transition: none; }
  .kbd__key:active, .kbd__predbtn:active { transform: none; }
}

/* =====================================================================
   Quick phrases — whole utterances in one tap
   ===================================================================== */
.phrasebar {
  display: flex; align-items: center; gap: 8px; flex: none;
  padding: 8px 12px; background: var(--warm-soft);
  border-bottom: 1px solid var(--line); overflow-x: auto;
  scrollbar-width: thin;
}
.phrasebar__label {
  display: flex; align-items: center; gap: 6px; flex: none;
  font-size: .74rem; font-weight: 800; color: var(--warm);
  text-transform: uppercase; letter-spacing: .06em; padding-right: 4px;
}
.phrasebar__items { display: flex; gap: 8px; }
.phrase {
  display: flex; align-items: center; gap: 7px; flex: none;
  min-height: 48px; padding: 9px 15px; border-radius: 999px;
  background: var(--bg-raised); border: 2px solid var(--warm);
  font-weight: 700; font-size: .93rem; color: var(--ink);
  transition: transform var(--dur), background var(--dur);
}
.phrase:hover  { background: var(--warm-soft); }
.phrase:active { transform: scale(.95); }
.phrase .e { font-size: 1.25rem; font-family: var(--emoji-font); }

/* =====================================================================
   Word forms
   ===================================================================== */
.tile__forms {
  position: absolute; top: 4px; inset-inline-end: 4px;
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--bg-raised); border: 2px solid var(--ink-faint);
  color: var(--ink-soft); font-size: .8rem; font-weight: 800;
  z-index: 2;
}
.tile__forms:hover { border-color: var(--accent); color: var(--accent-deep); }

.formgrid {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr));
}
.formbtn {
  text-align: start; padding: 14px 16px; border-radius: var(--radius-sm);
  border: 2px solid var(--line-strong); background: var(--bg-raised);
  display: flex; flex-direction: column; gap: 3px; min-height: 76px;
  transition: border-color var(--dur), background var(--dur);
}
.formbtn:hover { border-color: var(--accent); background: var(--accent-soft); }
.formbtn b     { font-size: 1.15rem; }
.formbtn small { color: var(--ink-soft); font-size: .84rem; font-weight: 600; }
.formbtn em    { color: var(--ink-faint); font-size: .8rem; font-style: italic; }
.formbtn--base { border-color: var(--accent); background: var(--accent-soft); }

/* =====================================================================
   Guided access
   ---------------------------------------------------------------------
   Locking hides every grown-up control. It must never hide HELP, the
   board, the phrases or the speak button — locking a child out of their
   own voice would be the exact opposite of the point.
   ===================================================================== */
[data-locked="on"] .topbar__tools,
[data-locked="on"] .topbar__child { display: none !important; }

.lockbtn {
  position: fixed; top: 8px; inset-inline-end: 10px; z-index: 70;
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center; font-size: 1.15rem;
  background: var(--bg-sunken); border: 2px solid var(--line-strong);
  color: var(--ink-soft);
}
.lockbtn--holding { border-color: var(--accent); background: var(--accent-soft); }
.lockbtn--holding::after {
  content: ''; position: absolute; inset: -5px; border-radius: 50%;
  border: 3px solid var(--accent); animation: lockRing 3s linear forwards;
}
@keyframes lockRing { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }

/* With a small vocabulary the whole board fits on one screen, so the
   category rail collapses to just the HELP button. */
.rail[data-mode="hidden"] { width: auto; }
.rail[data-mode="hidden"] .rail__list { display: none; }
.rail[data-mode="hidden"] .rail__foot { border-top: none; padding-top: 12px; }

/* =====================================================================
   Movement Coach
   ===================================================================== */
.coach__cam {
  position: relative; border-radius: var(--radius); overflow: hidden;
  background: var(--bg-sunken); border: 2px solid var(--line);
  aspect-ratio: 4/3; max-height: 340px; display: grid; place-items: center;
}
.coach__video { width: 100%; height: 100%; object-fit: cover; transform: scaleX(-1); }
.coach__off {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  padding: 20px; background: var(--bg-sunken); color: var(--ink-soft);
}
.coach__live {
  position: absolute; top: 10px; left: 10px;
  display: flex; align-items: center; gap: 7px;
  padding: 6px 13px; border-radius: 999px;
  background: rgba(20,18,16,.72); color: #fff;
  font-size: .8rem; font-weight: 700;
}
.coach__dot {
  width: 9px; height: 9px; border-radius: 50%; background: #FF5A4E;
  animation: camPulse 1.6s ease-in-out infinite;
}
@keyframes camPulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

.coach__meter { margin-top: 16px; }
.coach__meterlabel { font-size: .84rem; font-weight: 700; color: var(--ink-soft); margin-bottom: 6px; }
.coach__bar {
  position: relative; height: 22px; border-radius: 8px;
  background: var(--bg-sunken); overflow: hidden;
  border: 1px solid var(--line);
}
.coach__fill { height: 100%; width: 0; background: var(--accent); transition: width .08s linear; }
.coach__mark { position: absolute; top: 0; bottom: 0; width: 3px; background: var(--warm); }
.coach__hint { font-size: .85rem; color: var(--ink-faint); margin-top: 6px; min-height: 1.3em; }

.coach__list { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(min(300px,100%),1fr)); }
.coach__card {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 16px; background: var(--bg-raised);
}
.coach__cardhead { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.coach__cardhead b { font-size: 1.05rem; }
.coach__field { display: block; margin-bottom: 10px; }
.coach__field span { display: block; font-size: .85rem; font-weight: 700; margin-bottom: 5px; }

.coach__count {
  display: flex; align-items: center; gap: 16px; padding: 18px 22px;
  border-radius: var(--radius); background: var(--accent-soft);
  border: 2px solid var(--accent);
}
.coach__count b { font-size: 2.6rem; line-height: 1; color: var(--accent-deep); }
.coach__count span { font-weight: 700; }
.coach__count--go { background: var(--success-soft); border-color: var(--success); }
.coach__count--go b { color: var(--success); }

/* =====================================================================
   The camera indicator on the board itself
   ---------------------------------------------------------------------
   Non-negotiable: whenever this app is looking through a camera, everyone
   in the room can see that it is, and switching it off is one tap away.
   ===================================================================== */
.camflag {
  position: fixed; top: 8px; left: 50%; transform: translateX(-50%);
  z-index: 90; display: flex; align-items: center; gap: 9px;
  padding: 7px 15px; border-radius: 999px;
  background: var(--ink); color: var(--bg);
  font-size: .84rem; font-weight: 700;
  box-shadow: var(--shadow-lift);
}
.camflag__dot {
  width: 9px; height: 9px; border-radius: 50%; background: #FF5A4E;
  animation: camPulse 1.6s ease-in-out infinite;
}
.camflag button {
  color: inherit; font-weight: 800; text-decoration: underline;
  padding: 2px 4px; min-height: auto;
}

/* The live self-view. Top-centre, small, and deliberately NOT over the
   board: a child's words must never sit underneath a picture of the room.
   It is a fixed panel rather than a floating one because a draggable
   self-view is one more thing to knock out of place by accident. */
.camview {
  position: fixed; top: 8px; left: 50%; transform: translateX(-50%);
  z-index: 90; width: 180px;
  border-radius: var(--radius); overflow: hidden;
  background: var(--ink); color: var(--bg);
  box-shadow: var(--shadow-lift);
}
.camview__vid {
  display: block; width: 100%; height: 135px; object-fit: cover;
  background: #000;
  /* Mirrored: raise your right hand, the child on screen raises theirs. */
  transform: scaleX(-1);
}
.camview__bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 6px 11px; font-size: .78rem; font-weight: 700;
}
.camview__label { margin-right: auto; }
.camview__btn {
  color: inherit; font-weight: 800; text-decoration: underline;
  padding: 2px 3px; min-height: auto; font-size: .78rem;
}
/* Picture hidden: collapse to the pill the app used to show, so the red
   dot and the "camera on" words never disappear with it. */
.camview--min { width: auto; border-radius: 999px; }
.camview--min .camview__bar { flex-wrap: nowrap; padding: 7px 15px; font-size: .84rem; }

@media (max-width: 480px) {
  .camview { width: 132px; }
  .camview__vid { height: 99px; }
}
@media (prefers-reduced-motion: reduce) {
  .camflag__dot { animation: none; }
}

/* A movement the app thinks it saw, offered rather than spoken. */
.movesuggest {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
  z-index: 95; display: flex; align-items: center; gap: 12px;
  padding: 14px 20px; border-radius: var(--radius-lg);
  background: var(--bg-raised); border: 3px solid var(--accent);
  box-shadow: var(--shadow-lift); max-width: min(560px, 92vw);
}
.movesuggest__body { flex: 1; min-width: 0; }
.movesuggest__body b { display: block; font-size: 1.05rem; }
.movesuggest__body small { color: var(--ink-faint); }
.movesuggest__yes {
  min-height: 52px; padding: 0 20px; border-radius: var(--radius-sm);
  background: var(--accent); color: var(--accent-ink); font-weight: 800;
}
.movesuggest__no {
  min-height: 52px; width: 52px; border-radius: var(--radius-sm);
  border: 2px solid var(--line-strong); font-weight: 800;
}

/* =====================================================================
   The conversation thread
   ===================================================================== */
.thread {
  position: fixed; right: 14px; bottom: 118px; z-index: 88;
  width: min(360px, calc(100vw - 28px)); max-height: min(52vh, 460px);
  display: flex; flex-direction: column;
  background: var(--bg-raised); border: 2px solid var(--accent);
  border-radius: var(--radius); box-shadow: var(--shadow-lift);
}
.thread__head {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; border-bottom: 1px solid var(--line);
}
.thread__head .iconbtn { width: 36px; height: 36px; font-size: 1rem; }
.thread__body {
  flex: 1; overflow-y: auto; padding: 12px; min-height: 0;
  display: flex; flex-direction: column; gap: 10px;
}
.thread__turn { display: flex; gap: 9px; align-items: flex-start; font-size: .95rem; }
.thread__who { font-size: 1.2rem; flex: none; font-family: var(--emoji-font); }
.thread__text {
  padding: 8px 12px; border-radius: 14px; background: var(--bg-sunken);
  line-height: 1.45;
}
.thread__turn--buddy .thread__text { background: var(--accent-soft); color: var(--accent-deep); }
.thread__turn--child { flex-direction: row-reverse; }
.thread__turn--child .thread__text { background: var(--warm-soft); }

@media (max-width: 720px) {
  .thread { right: 8px; left: 8px; width: auto; bottom: 96px; max-height: 44vh; }
}


/* =====================================================================
   Counting and math
   ---------------------------------------------------------------------
   Full-screen, because a child counting should not also be resisting a
   board full of words behind the numbers. Nothing here is red, and there
   is no state that means "wrong" — a not-yet-right answer dims for a
   moment and comes back.
   ===================================================================== */
.maths {
  position: fixed; inset: 0; z-index: 96;
  display: flex; flex-direction: column;
  background: var(--bg); color: var(--ink);
  overflow: auto;
}
.maths__head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
  background: var(--bg-raised); position: sticky; top: 0; z-index: 2;
}
.maths__modes { display: flex; gap: 8px; flex-wrap: wrap; }
.maths__body {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 18px; padding: 24px 18px 40px;
  text-align: center; width: min(900px, 100%); margin: 0 auto;
}
.maths__question { font-size: 1.5rem; font-weight: 800; margin: 0; line-height: 1.4; }
.maths__hint { color: var(--ink-soft); margin: 0; min-height: 1.4em; font-size: 1rem; }

.maths__stage {
  display: flex; align-items: center; justify-content: center;
  gap: 18px; flex-wrap: wrap; min-height: 120px;
}
.maths__set {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 8px; max-width: 420px;
  padding: 12px; border-radius: var(--radius-lg);
  background: var(--bg-raised); border: 2px solid var(--line);
}
.maths__op { font-size: 2rem; font-weight: 800; }

/* Each object is a button, because counting is a motor act first. */
.maths__dot {
  font-size: 2.1rem; line-height: 1;
  width: 54px; height: 54px; min-height: 54px; padding: 0;
  border-radius: var(--radius); background: transparent;
  transition: transform .12s ease, background .12s ease, opacity .2s ease;
}
.maths__dot:hover { background: var(--bg-sunken); }
.maths__dot--counted { background: var(--accent-soft); transform: scale(1.12); }
.maths__dot--b { filter: hue-rotate(25deg); }
/* Taken away: still visible, so the child can see what left rather than
   being asked to remember it. */
.maths__dot--gone { opacity: .22; filter: grayscale(1); }

.maths__answers { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }
.maths__ans {
  font-size: 2rem; font-weight: 800; font-variant-numeric: tabular-nums;
  min-width: 92px; min-height: 92px; padding: 10px 18px;
  border-radius: var(--radius-lg);
  background: var(--bg-raised); border: 3px solid var(--line-strong);
  color: var(--ink);
  transition: transform .12s ease, background .15s ease, border-color .15s ease, opacity .2s ease;
}
.maths__ans:hover { border-color: var(--accent); }
.maths__ans--yes {
  background: var(--success-soft); border-color: var(--success);
  transform: scale(1.08);
}
/* NOT an error state. It fades and returns — nothing is marked wrong. */
.maths__ans--soft { opacity: .45; transform: scale(.96); }

.maths__foot { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }

@media (max-width: 560px) {
  .maths__question { font-size: 1.2rem; }
  .maths__dot { font-size: 1.7rem; width: 44px; height: 44px; min-height: 44px; }
  .maths__ans { min-width: 74px; min-height: 74px; font-size: 1.6rem; }
  .maths__set { max-width: 300px; }
}
@media (prefers-reduced-motion: reduce) {
  .maths__dot, .maths__ans { transition: background .12s ease, opacity .12s ease; }
  .maths__dot--counted, .maths__ans--yes, .maths__ans--soft { transform: none; }
}


/* =====================================================================
   Phones
   ---------------------------------------------------------------------
   Measured on a 390×664 phone before this block existed: the top bar,
   sentence strip, quick phrases and smart row together took 275px — 41%
   of the screen — leaving 389px of board, which at two tiles a row showed
   the child FOUR WORDS. The bars are all useful; none of them is worth
   four words.

   So on a phone the chrome gets tighter and the tiles get smaller, which
   buys back roughly a hundred vertical pixels and a third column. Nothing
   is removed: a control a caregiver cannot find is a control that does not
   exist, and a phrase a child cannot reach is a phrase they do not have.
   ===================================================================== */

/* The message to the grown-up. */
.toast {
  position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%);
  z-index: 200; box-sizing: border-box;
  background: var(--ink); color: var(--bg);
  padding: 13px 18px; border-radius: var(--radius);
  font-weight: 700; font-size: .95rem; line-height: 1.45; text-align: left;
  box-shadow: var(--shadow-lift);
  width: max-content; max-width: min(560px, calc(100vw - 28px));
  max-height: 40vh; overflow-y: auto;
}
.toast--pill { border-radius: 999px; text-align: center; padding: 13px 22px; }
@media (max-width: 560px) {
  /* Clear of the HELP button, which lives in the bottom-left and must
     never be covered by a message about voices. */
  .toast { bottom: 14px; font-size: .86rem; padding: 11px 14px; max-height: 34vh; }
  .toast--pill { padding: 11px 18px; }
}

@media (max-width: 560px) {
  /* --- buy back vertical space, a few pixels at a time --- */
  .phrasebar, .smartrow { padding: 4px 8px; gap: 6px; }
  .phrasebar__label, .smartrow__label { font-size: .62rem; letter-spacing: .02em; }
  .phrasebar__items, .smartrow__items { gap: 6px; }
  /* 44px is the smallest target a finger can hit reliably, and these are
     grown-up-sized shortcuts rather than the child's word tiles — so they
     come down to 44 and stop there. */
  .phrase, .smart { min-height: 44px; padding: 6px 12px; font-size: .84rem; }
  .phrase .e, .smart .e { font-size: 1.1rem; }
  .board { padding: 8px 8px 110px; }

  /* --- three tiles to a row instead of two --- */
  [data-size="small"]  { --tile: 82px;  --tile-font: .72rem; --tile-emoji: 1.6rem; --gap: 6px; }
  [data-size="medium"] { --tile: 98px;  --tile-font: .82rem; --tile-emoji: 2rem;   --gap: 7px; }
  [data-size="large"]  { --tile: 124px; --tile-font: .98rem; --tile-emoji: 2.6rem; --gap: 9px; }
  /* "huge" is a deliberate choice by a caregiver for a child who needs a
     big target. It is never shrunk — that would override the one setting
     that exists precisely to make tiles bigger. */

  .rail { width: 72px; }
  .rail__btn { font-size: .58rem; }
  .rail__btn .e { font-size: 1.2rem; }
  .board__heading { font-size: .95rem; margin-bottom: 6px; }
}

@media (max-width: 400px) {
  [data-size="medium"] { --tile: 88px; --tile-font: .76rem; --tile-emoji: 1.8rem; }
  [data-size="large"]  { --tile: 110px; --tile-font: .9rem; --tile-emoji: 2.3rem; }
  .rail { width: 64px; }
}

/* =====================================================================
   The caregiver pages on a phone
   ---------------------------------------------------------------------
   The dashboard, account page and diagnostics were laid out for a tablet.
   On a phone the header links wrapped onto three rows, the seven tabs onto
   four, and the privacy notice ran to eleven lines of 1.05rem text — about
   1100px of scrolling before the first actual panel. Everything below
   scales that down. Nothing is hidden; it is the same page, sized for the
   screen it is on.
   ===================================================================== */
@media (max-width: 620px) {
  .dash { padding: 12px 12px 40px; }
  .dash__head { gap: 8px; margin-bottom: 14px; }
  .dash__head .btn, .dash__head .topbar__child {
    min-height: 42px; padding: 0 12px; font-size: .86rem;
  }
  .dash__head .topbar__brand { font-size: 1rem; }

  /* One scrolling row, not four wrapped ones. A wrapped tab bar on a phone
     is 200px of navigation above every panel. */
  .dash__tabs {
    flex-wrap: nowrap; overflow-x: auto; margin-bottom: 14px;
    scrollbar-width: thin; -webkit-overflow-scrolling: touch;
  }
  .dash__tab { flex: none; padding: 10px 13px; font-size: .84rem; white-space: nowrap; }

  .card { padding: 14px; }
  .card h2 { font-size: 1.12rem; }
  .card h3 { font-size: 1rem; }
  .dash p, .dash li, .plain p, .plain li { font-size: .92rem; line-height: 1.6; }
  .note, .notice { font-size: .88rem; line-height: 1.55; }

  .grid3, .grid2 { grid-template-columns: 1fr; gap: 12px; }
  .kpi, .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* A table on a phone scrolls sideways inside its own box rather than
     stretching the page. */
  .tablewrap, .table__wrap { overflow-x: auto; }
  .table { font-size: .84rem; }
  .table th, .table td { padding: 8px 9px; }
}

@media (max-width: 420px) {
  .btn { min-height: 46px; padding: 0 14px; font-size: .92rem; }
  .btn--lg { min-height: 52px; font-size: 1rem; }
  .kpi, .kpis { grid-template-columns: 1fr; }
}


/* =====================================================================
   The games
   ---------------------------------------------------------------------
   Nothing here is ever red, and no state means "wrong". A tap that is not
   the expected one dims for half a second and comes back — the same
   treatment the counting activity gives it, for the same reason.
   ===================================================================== */
.games {
  position: fixed; inset: 0; z-index: 96;
  display: flex; flex-direction: column;
  background: var(--bg); color: var(--ink); overflow: auto;
}
.games__head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
  background: var(--bg-raised); position: sticky; top: 0; z-index: 2;
}
.games__title { font-size: 1.05rem; }
.games__body {
  flex: 1; width: min(900px, 100%); margin: 0 auto;
  padding: 20px 16px 44px; text-align: center;
}

/* ---- the menu ---- */
.games__grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(min(230px, 100%), 1fr));
}
.games__card {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 20px 14px; min-height: 150px;
  border-radius: var(--radius-lg);
  background: var(--bg-raised); border: 2px solid var(--line-strong);
  text-align: center; transition: transform var(--dur), border-color var(--dur);
}
.games__card:hover { border-color: var(--accent); transform: translateY(-2px); }
.games__card b { font-size: 1.02rem; }
.games__card span:last-child { font-size: .85rem; color: var(--ink-soft); }
.games__emoji { font-size: 2.4rem; line-height: 1; font-family: var(--emoji-font); }

/* ---- shared game furniture ---- */
.games__ask { font-size: 1.25rem; font-weight: 800; margin: 0 0 14px; line-height: 1.4; }
.games__hint { color: var(--ink-soft); margin: 10px 0 14px; min-height: 1.4em; }
.games__foot { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin-top: 18px; }

.games__tiles {
  display: grid; gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(min(128px, 45%), 1fr));
}
.games__tile {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 14px 8px; min-height: 108px;
  border-radius: var(--radius); background: var(--bg-raised);
  border: 2px solid var(--line-strong);
  transition: transform var(--dur), border-color var(--dur), opacity var(--dur);
}
.games__tile:hover { border-color: var(--accent); }
.games__temoji { font-size: 2.3rem; line-height: 1; font-family: var(--emoji-font); }
.games__tlabel { font-weight: 700; font-size: .92rem; }
.games__tile--yes {
  background: var(--success-soft); border-color: var(--success); transform: scale(1.05);
}
/* NOT an error state. It fades and returns. */
.games__tile--soft { opacity: .45; transform: scale(.97); }

.games__big {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  font-size: 4rem; line-height: 1; font-family: var(--emoji-font);
  margin: 10px 0 4px;
}
.games__big span { font-size: 1.1rem; font-weight: 800; font-family: var(--font); }

/* ---- build a sentence ---- */
.games__strip {
  display: flex; gap: 8px; flex-wrap: wrap; justify-content: center;
  min-height: 62px; align-items: center;
  padding: 10px; border-radius: var(--radius);
  background: var(--bg-raised); border: 2px dashed var(--line-strong);
}
.games__chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 13px; border-radius: 999px;
  background: var(--accent-soft); border: 2px solid var(--accent);
  font-weight: 700; color: var(--accent-deep);
}
.games__empty { color: var(--ink-faint); }

/* ---- matching pairs ---- */
.games__tiles--cards { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.games__card2 {
  position: relative; min-height: 84px; padding: 0;
  border-radius: var(--radius); border: 2px solid var(--line-strong);
  background: var(--bg-sunken); font-family: var(--emoji-font); font-size: 2rem;
  transition: background var(--dur), border-color var(--dur), transform var(--dur);
}
.games__card2 .games__front { display: none; }
.games__card2--up { background: var(--bg-raised); border-color: var(--accent); }
.games__card2--up .games__front { display: inline; }
.games__card2--up .games__back { display: none; }
.games__card2--done {
  background: var(--success-soft); border-color: var(--success); transform: scale(.96);
}

@media (max-width: 560px) {
  .games__body { padding: 14px 10px 36px; }
  .games__ask { font-size: 1.05rem; }
  .games__card { min-height: 124px; padding: 14px 10px; }
  .games__emoji { font-size: 2rem; }
  .games__tile { min-height: 92px; padding: 10px 6px; }
  .games__temoji { font-size: 1.9rem; }
  .games__tlabel { font-size: .82rem; }
  .games__tiles--cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .games__big { font-size: 3rem; }
}
@media (prefers-reduced-motion: reduce) {
  .games__card, .games__tile, .games__card2 { transition: opacity .1s ease; }
  .games__card:hover, .games__tile--yes, .games__tile--soft, .games__card2--done { transform: none; }
}
