/* ============================================================
   Sensory Speak
   A single-page AAC board. No page navigation, ever — everything
   the child needs is on one screen.
   ============================================================ */

/* ---------- 1. Theme tokens ---------------------------------- */

:root {
  --bg:        #f4f1ea;
  --fg:        #1b1b1b;
  --panel:     #ffffff;
  --panel-fg:  #1b1b1b;
  --muted:     #6b6b6b;
  --line:      #d9d4c8;
  --accent:    #2f6f4f;
  --accent-fg: #ffffff;
  --danger:    #b3261e;

  /* Button surface. Themes override these; colour modes override them per
     button via an inline --btn-bg. */
  --btn-bg:     #ffffff;
  --btn-fg:     #1b1b1b;
  --btn-border: #c9c4b8;

  --border-w: 3px;
  --radius:   18px;
  --gap:      10px;
  --label-size: clamp(0.85rem, 2.2vw, 1.35rem);
  --symbol-size: clamp(1.6rem, 6vw, 3.4rem);
  --focus: #0a84ff;

  /* Set to 1 by the high-contrast themes so buttons can drop their own
     colours and adopt the theme's pairing instead. */
  --hc: 0;
}

/* High contrast pairings. These are the four combinations low-vision users are
   most often prescribed; we keep the pure pairing on the button faces and push
   part-of-speech colour into a stripe so no information is lost. */

.theme-hc-bw {   /* white on black — the most common prescription */
  --bg: #000000; --fg: #ffffff; --panel: #000000; --panel-fg: #ffffff;
  --muted: #c8c8c8; --line: #ffffff; --accent: #ffffff; --accent-fg: #000000;
  --btn-bg: #000000; --btn-fg: #ffffff; --btn-border: #ffffff;
  --danger: #ff6b6b; --focus: #ffd400; --hc: 1;
}

.theme-hc-wb {   /* black on white */
  --bg: #ffffff; --fg: #000000; --panel: #ffffff; --panel-fg: #000000;
  --muted: #333333; --line: #000000; --accent: #000000; --accent-fg: #ffffff;
  --btn-bg: #ffffff; --btn-fg: #000000; --btn-border: #000000;
  --danger: #b3261e; --focus: #0000ff; --hc: 1;
}

.theme-hc-yb {   /* yellow on black — highest luminance contrast available */
  --bg: #000000; --fg: #ffe500; --panel: #000000; --panel-fg: #ffe500;
  --muted: #d4c200; --line: #ffe500; --accent: #ffe500; --accent-fg: #000000;
  --btn-bg: #000000; --btn-fg: #ffe500; --btn-border: #ffe500;
  --danger: #ff6b6b; --focus: #ffffff; --hc: 1;
}

.theme-hc-by {   /* black on yellow */
  --bg: #ffe500; --fg: #000000; --panel: #ffe500; --panel-fg: #000000;
  --muted: #3a3400; --line: #000000; --accent: #000000; --accent-fg: #ffe500;
  --btn-bg: #ffe500; --btn-fg: #000000; --btn-border: #000000;
  --danger: #8b0000; --focus: #0000ff; --hc: 1;
}

/* ---------- 2. Base ------------------------------------------ */

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;                  /* the board must never scroll away */
  background: var(--bg);
  color: var(--fg);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
}

/* A communication board is not a document: text selection and long-press
   callouts only ever get in a child's way. */
body {
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  touch-action: manipulation;
}

button { font: inherit; color: inherit; cursor: pointer; }

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

:focus-visible { outline: 4px solid var(--focus); outline-offset: 3px; }

/* ---------- 3. App shell ------------------------------------- */

#app { display: flex; flex-direction: column; height: 100%; }

.screen { display: none; height: 100%; flex-direction: column; }
.screen.active { display: flex; }

/* ---------- 4. The board ------------------------------------- */

#board-screen { position: relative; }

.board-area {
  flex: 1;
  display: flex;
  min-height: 0;
  min-width: 0;
}

.board-wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: var(--gap);
  min-height: 0;
  min-width: 0;
}

/* ---- side rail ----
   Off unless the board asks for it. Narrow on purpose: it must not eat the
   space the words need, and its job is one-tap reach, not browsing. */

#sidebar {
  display: none;
  flex-direction: column;
  gap: 6px;
  padding: var(--gap) 6px;
  overflow-y: auto;
  flex: none;
  width: 108px;
  border-right: var(--border-w) solid var(--line);
}
body.rail-left  #sidebar { display: flex; }
body.rail-right #sidebar {
  display: flex;
  order: 2;
  border-right: none;
  border-left: var(--border-w) solid var(--line);
}
body.rail-right .board-wrap { order: 1; }

@media (max-width: 560px) {
  #sidebar { width: 82px; }
}

.rail-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 8px 4px;
  border: var(--border-w) solid var(--btn-border);
  border-radius: 14px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-weight: 700;
  font-size: 0.72rem;
  line-height: 1.05;
  text-align: center;
  min-height: 64px;
  flex: none;
  overflow: hidden;
  word-break: break-word;
}
.rail-btn .rail-icon { font-size: 1.5rem; line-height: 1; }
.rail-btn.current {
  outline: 4px solid var(--focus);
  outline-offset: -4px;
}
.rail-btn.home {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
}

#grid {
  flex: 1;
  display: grid;
  gap: var(--gap);
  min-height: 0;
}

/* Gap presets. The wide steps exist for children who need generous dead space
   between targets to tell one button from the next. */
.gap-tight  { --gap: 4px; }
.gap-normal { --gap: 10px; }
.gap-wide   { --gap: 26px; }
.gap-xwide  { --gap: 46px; }

/* In checkerboard mode the empty tracks are already doing the separating.
   Letting the gap run at its full width on top of them stacks two kinds of
   space and leaves the buttons themselves too small to read, so the wider
   settings are capped here. The visible separation is unchanged. */
body.checker.gap-wide  { --gap: 8px; }
body.checker.gap-xwide { --gap: 12px; }

/* Border weight presets, for low vision. */
.border-normal { --border-w: 3px; }
.border-thick  { --border-w: 6px; }
.border-xthick { --border-w: 10px; }

/* Text size presets. These are multipliers rather than absolute sizes: the
   real size comes from the button itself (see the container query block
   below), so a preset means "bigger relative to the button" and never pushes
   the word out of a short button. */
.text-sm { --sym-scale: 0.78; --lab-scale: 0.8; }
.text-md { --sym-scale: 1;    --lab-scale: 1; }
.text-lg { --sym-scale: 1.1;  --lab-scale: 1.3; }
.text-xl { --sym-scale: 1.2;  --lab-scale: 1.65; }

/* Fallback for browsers without container query units: scale with the
   viewport, as before. Overridden below wherever containers are supported. */
.text-sm { --label-size: clamp(0.7rem, 1.7vw, 1rem);     --symbol-size: clamp(1.2rem, 4.5vw, 2.4rem); }
.text-md { --label-size: clamp(0.85rem, 2.2vw, 1.35rem); --symbol-size: clamp(1.6rem, 6vw, 3.4rem); }
.text-lg { --label-size: clamp(1.05rem, 3.2vw, 2rem);    --symbol-size: clamp(2rem, 7vw, 4.2rem); }
.text-xl { --label-size: clamp(1.3rem, 4.4vw, 3rem);     --symbol-size: clamp(2.4rem, 8vw, 5rem); }

/* --- the button itself --- */

.cell {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25em;
  padding: 0.4em;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  border: var(--border-w) solid var(--btn-border);
  border-radius: var(--radius);
  background: var(--btn-bg);
  color: var(--btn-fg);
  text-align: center;
  line-height: 1.1;
  transition: transform 90ms ease-out, filter 90ms ease-out;
}

/* A blank cell in checkerboard mode. Not a button — it exists purely to give
   each real button a moat of empty space. */
.cell.blank {
  border: none;
  background: transparent;
  pointer-events: none;
}

.cell .symbol {
  /* An explicit height, not a font-size that flex may squash, so the space
     left over for the word is knowable before the word is laid out. */
  height: var(--sym-h, var(--symbol-size));
  font-size: var(--sym-h, var(--symbol-size));
  line-height: 1;
  flex: 0 0 auto;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.cell .symbol img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 8px;
}

.cell .label {
  font-size: var(--label-size);
  font-weight: 700;
  letter-spacing: 0.01em;
  /* Never break a word across lines. A child learning to recognise "come"
     must not be shown "com / e" — the text shrinks to fit instead (see --len
     below). Multi-word labels still wrap at the space. */
  overflow-wrap: normal;
  word-break: keep-all;
  hyphens: none;
  /* Never shrink and never get clipped — this is the part that communicates.
     A definite width gives the fit pass in board.js something to measure
     wrapping against. */
  flex: 0 0 auto;
  width: 100%;
}

/* ---- Content sized to the BUTTON, not the viewport --------------------
   Without this, a wide screen makes the emoji enormous no matter how short
   the button is, and the word gets pushed out of the bottom of the button.
   Container query units measure the button itself, so a short wide button in
   LAMP mode gets a proportionate symbol and a word that always fits. */
@supports (container-type: size) {
  .cell { container-type: size; container-name: cell; }

  /* --len   = characters in the label's LONGEST word
     --lines = how many lines the label will wrap onto
     Both are set per button in board.js. The width term divides the button's
     width by the longest word so that word always fits on one line; the height
     term divides the available height by the number of lines. Whichever is
     smaller wins, so the text shrinks to fit rather than breaking or clipping. */
  /* These are the LARGEST sizes the preset would like, expressed relative to
     the button. They are a starting point only: the fit pass in board.js
     measures the text as actually laid out and shrinks it where it does not
     fit, which is the only reliable way to know where a browser will wrap. */
  .cell .symbol { --sym-h: min(calc(40cqh * var(--sym-scale, 1)), 30cqw); }
  .cell .label  { font-size: calc(22cqh * var(--lab-scale, 1)); }

  .sym-none .cell .label { font-size: calc(48cqh * var(--lab-scale, 1)); }

  /* Very narrow buttons: the word needs the width more than the picture does. */
  @container cell (max-width: 76px) {
    .symbol { display: none; }
  }
}

/* Symbols off: the label takes the whole face and grows to fill it. Chosen by
   families whose child reads text faster than they parse a picture, and by
   low-vision users for whom one big word beats a small word under a symbol. */
.sym-none .cell .symbol { display: none; }
.sym-none .cell .label  { font-size: calc(var(--label-size) * 1.7); }

/* Part-of-speech stripe. In normal themes this is decorative reinforcement; in
   high contrast it carries the colour information that the button face gave up. */
.cell .pos-stripe {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 10px;
  background: var(--pos-color, transparent);
}
.cell.no-stripe .pos-stripe { display: none; }

/* --- folders ---
   A folder has to be tellable from a word at a glance and without relying on
   colour, since the colour is already carrying other meaning. It gets a
   dashed inner edge and a corner chevron: two redundant, non-colour cues. */

.cell.is-folder {
  border-style: double;
  border-width: calc(var(--border-w) + 3px);
}

.cell.is-folder::before {
  content: "›";
  position: absolute;
  right: 6px;
  bottom: 2px;
  font-size: clamp(14px, 3cqh, 28px);
  font-weight: 900;
  line-height: 1;
  opacity: 0.65;
}

.cell.is-folder .label { text-decoration: underline; text-underline-offset: 2px; }

/* --- pressed / active states --- */

.cell.is-armed {                      /* first tap of auditory preview */
  filter: brightness(1.12);
  box-shadow: inset 0 0 0 4px var(--focus);
}

.cell.is-holding {                    /* hold-to-activate in progress */
  transform: scale(0.97);
}

/* The hold progress bar gives a visible countdown so a hold never feels like
   the button simply failed to respond. */
.cell .hold-bar {
  position: absolute;
  bottom: 0; left: 0;
  height: 6px;
  width: 0;
  background: var(--focus);
}

/* ---------- 5. Activation animations ------------------------- */
/* Each is a separate class so a child can be given exactly one, and it can be
   swapped without touching anything else. */

@keyframes ss-shake {
  0%, 100% { transform: translateX(0); }
  15% { transform: translateX(-7px) rotate(-1.5deg); }
  30% { transform: translateX(7px) rotate(1.5deg); }
  45% { transform: translateX(-6px) rotate(-1deg); }
  60% { transform: translateX(6px) rotate(1deg); }
  80% { transform: translateX(-3px); }
}

@keyframes ss-pulse {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.14); }
  70%  { transform: scale(0.97); }
  100% { transform: scale(1); }
}

@keyframes ss-bounce {
  0%   { transform: translateY(0); }
  30%  { transform: translateY(-16px); }
  55%  { transform: translateY(0); }
  72%  { transform: translateY(-7px); }
  100% { transform: translateY(0); }
}

@keyframes ss-glow {
  0%   { box-shadow: 0 0 0 0 var(--glow-color, #fff), 0 0 0 0 var(--glow-color, #fff); }
  35%  { box-shadow: 0 0 26px 12px var(--glow-color, #fff), inset 0 0 22px 4px var(--glow-color, #fff); }
  100% { box-shadow: 0 0 0 0 transparent, inset 0 0 0 0 transparent; }
}

@keyframes ss-flash {
  0%, 100% { filter: brightness(1); }
  30%      { filter: brightness(2.1); }
  60%      { filter: brightness(1.3); }
}

.anim-shake  { animation: ss-shake  420ms ease-in-out; }
.anim-pulse  { animation: ss-pulse  380ms cubic-bezier(.34,1.56,.64,1); }
.anim-bounce { animation: ss-bounce 520ms cubic-bezier(.28,.84,.42,1); }
.anim-glow   { animation: ss-glow   620ms ease-out; }
.anim-flash  { animation: ss-flash  420ms ease-out; }

/* Respect the OS setting, but only for the decorative case: if a child's
   feedback depends on the animation, the app's own setting wins and we simply
   shorten it rather than removing it. */
@media (prefers-reduced-motion: reduce) {
  .cell { transition: none; }
  .anim-shake, .anim-pulse, .anim-bounce, .anim-glow, .anim-flash {
    animation-duration: 180ms;
  }
}

/* ---------- 6. Message bar ----------------------------------- */

#top-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px var(--gap);
  border-bottom: var(--border-w) solid var(--line);
  min-height: 64px;
  flex: none;
}

#page-title {
  font-weight: 800;
  font-size: 1.05rem;
  white-space: nowrap;
  opacity: 0.75;
}
/* On Home the title is redundant — the board itself says where you are. */
body.at-home #page-title { display: none; }

#message-text {
  flex: 1;
  font-size: clamp(1rem, 2.4vw, 1.6rem);
  font-weight: 700;
  overflow-x: auto;
  white-space: nowrap;
  min-height: 1.2em;
  min-width: 0;
  scrollbar-width: thin;
}

/* With the strip switched off, Home and Stop still hold their places. */
body:not(.show-message-bar) #message-text,
body:not(.show-message-bar) #msg-speak,
body:not(.show-message-bar) #msg-back,
body:not(.show-message-bar) #msg-clear { display: none; }
body:not(.show-message-bar) #page-title { flex: 1; }

.msg-btn {
  border: var(--border-w) solid var(--line);
  background: var(--panel);
  color: var(--panel-fg);
  border-radius: 12px;
  padding: 10px 14px;
  font-weight: 700;
  white-space: nowrap;
  flex: none;
  min-height: 48px;
}

/* Stop is the one control an adult reaches for while a child is mid-spiral,
   so it is coloured to be findable without reading it. */
.msg-btn.stop {
  background: var(--danger);
  color: #fff;
  border-color: var(--danger);
}
.theme-hc-bw .msg-btn.stop, .theme-hc-yb .msg-btn.stop {
  background: #000; color: var(--danger); border-color: var(--danger);
}

.msg-btn.home {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
}

/* ---------- 7. Adult controls -------------------------------- */
/* Deliberately small, low-contrast and corner-anchored: an adult can find it,
   a child exploring the board is unlikely to land on it. The long-press gate
   in app.js is the real lock. */

#adult-btn {
  position: absolute;
  right: 6px;
  bottom: 6px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 2px solid var(--line);
  background: var(--panel);
  color: var(--muted);
  opacity: 0.45;
  font-size: 18px;
  display: grid;
  place-items: center;
  z-index: 20;
}
#adult-btn:hover { opacity: 1; }

#hold-hint {
  position: absolute;
  right: 56px;
  bottom: 14px;
  background: var(--panel);
  color: var(--panel-fg);
  border: 2px solid var(--line);
  border-radius: 10px;
  padding: 6px 10px;
  font-size: 13px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 150ms;
  z-index: 20;
}
#hold-hint.show { opacity: 1; }

/* ---------- 8. Panels & setup -------------------------------- */

.panel {
  position: fixed;
  inset: 0;
  background: var(--bg);
  color: var(--fg);
  z-index: 50;
  display: none;
  flex-direction: column;
  overflow: hidden;
}
.panel.open { display: flex; }

.panel-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 2px solid var(--line);
  background: var(--panel);
}
.panel-head h2 { margin: 0; font-size: 1.15rem; flex: 1; }

.panel-body {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  -webkit-overflow-scrolling: touch;
}

.panel-foot {
  display: flex;
  gap: 10px;
  padding: 12px 16px;
  border-top: 2px solid var(--line);
  background: var(--panel);
}

.btn {
  border: 2px solid var(--line);
  background: var(--panel);
  color: var(--panel-fg);
  border-radius: 12px;
  padding: 12px 16px;
  font-weight: 600;
  min-height: 48px;
}
.btn.primary { background: var(--accent); color: var(--accent-fg); border-color: var(--accent); }
.btn.danger  { color: var(--danger); border-color: var(--danger); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn.grow { flex: 1; }

fieldset {
  border: 2px solid var(--line);
  border-radius: 14px;
  margin: 0 0 18px;
  padding: 14px;
}
legend { font-weight: 700; padding: 0 8px; font-size: 1rem; }

.field { margin-bottom: 14px; }
.field:last-child { margin-bottom: 0; }
.field > label { display: block; font-weight: 600; margin-bottom: 6px; }
.field .hint { display: block; font-weight: 400; color: var(--muted); font-size: 0.85rem; margin-top: 4px; }

select, input[type="text"], input[type="number"], textarea {
  width: 100%;
  padding: 11px 12px;
  border: 2px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  color: var(--panel-fg);
  font: inherit;
  min-height: 48px;
}

input[type="range"] { width: 100%; }

.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.row > * { flex: 1 1 auto; }

/* Segmented choice control — used everywhere a setting has 2-5 options. */
.seg { display: flex; flex-wrap: wrap; gap: 8px; }
.seg input { position: absolute; opacity: 0; pointer-events: none; }
.seg label {
  flex: 1 1 auto;
  text-align: center;
  padding: 11px 12px;
  border: 2px solid var(--line);
  border-radius: 10px;
  font-weight: 600;
  min-height: 48px;
  display: grid;
  place-items: center;
  background: var(--panel);
}
.seg input:checked + label {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
}
.seg input:focus-visible + label { outline: 4px solid var(--focus); outline-offset: 2px; }

.switch { display: flex; align-items: center; gap: 12px; cursor: pointer; }
.switch input { width: 26px; height: 26px; flex: none; accent-color: var(--accent); }
.switch span { font-weight: 600; }

/* --- word picker --- */

.wordgroup { margin-bottom: 20px; }
.wordgroup h4 { margin: 0 0 2px; font-size: 1rem; }
.wordgroup .grouphint { margin: 0 0 10px; color: var(--muted); font-size: 0.85rem; }

.chips { display: flex; flex-wrap: wrap; gap: 8px; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 10px 13px;
  border: 2px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  color: var(--panel-fg);
  font-weight: 600;
  min-height: 46px;
}
.chip[aria-pressed="true"] {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
}
.chip .dot {
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--pos-color, transparent);
  border: 1px solid rgba(0,0,0,.25);
  flex: none;
}
.chip .star { font-size: 0.75rem; opacity: 0.9; }

/* --- folder picker --- */

.folder-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px;
  border: 2px solid var(--line);
  border-radius: 12px;
  margin-bottom: 8px;
}
.setup-folder-actions { flex-wrap: wrap; margin: 10px 0; }
.folder-group-title { margin: 20px 0 8px; color: var(--fg); font-size: 1rem; }
.folder-group-title:first-child { margin-top: 8px; }
.folder-badge { display: inline-block; margin-left: 8px; padding: 2px 7px; border-radius: 999px; background: var(--accent); color: var(--accent-fg); font-size: .68rem; vertical-align: middle; }
.folder-swatch {
  width: 42px; height: 42px;
  border-radius: 10px;
  display: grid; place-items: center;
  font-size: 22px;
  flex: none;
  border: 2px solid rgba(0,0,0,.2);
}
.folder-sub {
  display: block;
  font-weight: 400;
  font-size: 0.82rem;
  color: var(--muted);
}

/* --- picture picker --- */

.pic-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 10px;
  margin-top: 12px;
}
.pic-grid button {
  border: 3px solid var(--line);
  border-radius: 12px;
  background: #fff;
  padding: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.pic-grid button[aria-pressed="true"] {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent);
}
.pic-grid img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
}
.pic-grid .cap {
  font-size: 0.72rem;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.pic-preview img {
  max-width: 180px;
  max-height: 180px;
  border: 2px solid var(--line);
  border-radius: 12px;
  margin-top: 12px;
}

.pic-spinner { color: var(--muted); font-style: italic; }

/* --- intent coverage report --- */

.intent-warn, .intent-ok {
  border: 2px solid var(--line);
  border-radius: 12px;
  padding: 12px 14px;
  margin-bottom: 16px;
}
.intent-warn { border-color: var(--danger); }
.intent-warn p { margin: 0 0 8px; }
.intent-warn ul { margin: 0 0 8px; padding-left: 20px; }
.intent-warn li { margin-bottom: 6px; }
.intent-ok { border-color: var(--accent); margin: 0 0 16px; }
.intent-ok { color: var(--accent); font-weight: 600; }

#selection-count {
  position: sticky;
  top: -16px;
  z-index: 5;
  margin: -16px -16px 14px;
  padding: 12px 16px;
  background: var(--panel);
  border-bottom: 2px solid var(--line);
  font-weight: 700;
}
#selection-count.over { color: var(--danger); }

/* --- board preview inside setup --- */

#preview {
  display: grid;
  gap: 4px;
  border: 2px solid var(--line);
  border-radius: 10px;
  padding: 8px;
  background: var(--bg);
  aspect-ratio: 4 / 3;
  max-height: 260px;
}
#preview .pcell {
  border-radius: 4px;
  border: 1px solid rgba(0,0,0,.18);
  min-height: 0;
}
#preview .pcell.blank { border: none; background: transparent; }

/* --- edit mode --- */

body.edit-mode .cell { cursor: pointer; }
body.edit-mode .cell::after {
  content: "✎";
  position: absolute;
  top: 2px; right: 6px;
  font-size: 14px;
  opacity: 0.75;
}
body.edit-mode .cell.blank { pointer-events: auto; }
body.edit-mode .cell.blank::after { content: "+"; opacity: 0.5; }

#edit-banner {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--accent);
  color: var(--accent-fg);
  font-weight: 700;
}
body.edit-mode #edit-banner { display: flex; }
#edit-banner .spacer { flex: 1; }
#edit-banner .btn { background: transparent; color: inherit; border-color: currentColor; min-height: 40px; padding: 8px 12px; }

/* --- recording indicator --- */

.rec-dot {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--danger);
  display: inline-block;
  margin-right: 8px;
  animation: ss-recblink 1s steps(2, start) infinite;
}
@keyframes ss-recblink { 0%, 100% { opacity: 1; } 50% { opacity: 0.15; } }

/* --- toast --- */

#toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%) translateY(20px);
  background: #1b1b1b;
  color: #fff;
  padding: 13px 20px;
  border-radius: 12px;
  font-weight: 600;
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms, transform 180ms;
  z-index: 100;
  max-width: 90vw;
  text-align: center;
}
#toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* --- setup steps --- */

.step { display: none; }
.step.active { display: block; }

#step-dots { display: flex; gap: 6px; }
#step-dots .dot {
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--line);
}
#step-dots .dot.on { background: var(--accent); }

/* ---------- 9. Landscape phones ------------------------------ */
/* Short viewports are the normal case for a phone held sideways; give the grid
   every pixel we can. */
@media (max-height: 480px) {
  #message-bar { min-height: 48px; padding: 4px var(--gap); }
  .board-wrap { padding: 6px; }
}

@media print { #adult-btn, #hold-hint { display: none; } }
