/* Andika Bold (SIL OFL) — single-story a/g literacy letterforms.
   Self-hosted; the app is offline-first, never a CDN. It is the
   face of every word the learner sees: tile labels, strip cards,
   sentence chips, keycaps. */
@font-face {
  font-family: "Andika";
  src: url("/fonts/andika-bold.woff2") format("woff2");
  font-weight: 700;
  font-display: block;
}

/* Design tokens — docs/product/Design_System.md owns this palette.
   Hue means grammar and nothing else: role colors paint word tiles,
   and UI chrome stays ink + warm neutrals. Pip's amber is the bird's
   — icon and marketing only, never a control. */
:root {
  --gap: 6px;
  --ink: #2a241d;          /* primary action, focus, icon ground */
  --ink-text: #1a1a1a;     /* text on light; pressed/focus ink */
  --cream: #f6f4ef;        /* page background */
  --line: #d8d4c8;         /* hairlines, empty/ghost dashes */
  --tray: #e8e3d6;         /* prediction tray, neutral fills */
  --edge: #8a8578;         /* neutral cell border */
  --muted: #5b5348;        /* secondary text, anchor border */
  --neutral-text: #3a352c; /* neutral on-fill text */
  --mask-b: #cfc9bb;       /* masked border */
  --mask-f: #efeadf;       /* masked/disabled fill */
  --mask-t: #a39c8a;       /* masked text */
  --press-f: #f2efe6;      /* pressed tile art area */
  --glow: #e8a200;         /* attention layer — target word glow */
  --dim-o: 0.45;           /* attention layer — non-target dim */
  --word-font: "Andika", -apple-system, "Helvetica Neue", sans-serif;
}
/* Grammar roles: --rb border, --rf label-strip fill. One pair per
   role; every surface (grid tile, strip card, swatch) reads the
   same two vars. The sentence bar carries no role color. */
.r-Yellow { --rb: #b07f00; --rf: #fdf0c8; }
.r-Green  { --rb: #2e8b3a; --rf: #dcf0dd; }
.r-Blue   { --rb: #2f6fd0; --rf: #dcecfd; }
.r-Pink   { --rb: #d0438c; --rf: #fbdfee; }
.r-Purple { --rb: #6f55b0; --rf: #ebe5f7; }
.r-Red    { --rb: #c62828; --rf: #fbdcdc; }
.r-None   { --rb: #8a8578; --rf: #f2efe6; } /* typed words — no role */

* { box-sizing: border-box; margin: 0; }
/* The hidden attribute always wins. Without this, any class that sets
   display (.sheet .row is flex) silently un-hides the element: Delete
   account showed while signed out. */
[hidden] { display: none !important; }
body {
  font-family: -apple-system, "Helvetica Neue", sans-serif;
  background: var(--cream);
  height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: var(--gap);
  gap: var(--gap);
}
button { font: inherit; cursor: pointer; }

/* Switch / keyboard / eye-gaze focus: cream + ink double ring.
   :focus-visible never fires for touch — the ring only shows for
   non-pointer input, as the spec requires. */
.cell:focus-visible, .pred:focus-visible, .anchor:focus-visible,
.gcell:focus-visible, .kb-key:focus-visible, .bar-btn:focus-visible,
.corner-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 4px var(--cream), 0 0 0 9px var(--ink-text);
  z-index: 2;
}

/* --- top bar: Clear + Backspace (edit), sentence, Fix it +
   Question, ⏪ Play ⏩ (023), Parent corner. Controls are ink line
   glyphs, never clipart — art means a word, a glyph means a
   control. Clear sits far from Play. --- */
#topbar { display: flex; gap: var(--gap); height: 68px; }
#bar {
  flex: 1;
  min-width: 0;
  border: 2px solid var(--line);
  border-radius: 10px;
  background: #fff;
  display: flex;
  align-items: center;
  padding: 3px 8px;
  gap: 12px;
  overflow-x: auto;
}
/* The ink bird (never the gold one — gold stays off the grid)
   holds the empty bar. */
#bar .pip-ink { height: 100%; flex: none; }
#bar .empty-note {
  color: #777;
  font-family: var(--word-font);
  font-weight: 700;
  font-size: 17px;
  white-space: nowrap;
}
/* Sentence chip: the picture with its word underneath in ink. No
   role color and no frame — the word was already found on the
   grid; here it only has to read, for the user and the partner. */
.chip {
  height: 100%;
  flex: none;
  min-width: 36px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.chip .cart {
  height: calc(100% - 24px);
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.chip .cart img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.chip.photo .cart img { width: 100%; height: 100%; object-fit: cover; border-radius: 6px; }
.chip .clabel {
  flex: none;
  height: 24px;
  color: var(--ink-text);
  font-family: var(--word-font);
  font-weight: 700;
  font-size: 20px;
  line-height: 24px;
  white-space: nowrap;
}
#bar .partial { color: var(--muted); font-weight: 700; font-size: 20px; white-space: nowrap; }
/* In-bar controls: quiet square buttons pinned to the right end;
   sticky so a long sentence scrolling left never carries them
   off. The solid ground keeps chips from showing through. */
#bar-btns {
  margin-left: auto;
  flex: none;
  position: sticky;
  right: 0;
  display: flex;
  gap: 8px;
  align-items: center;
  align-self: stretch;
  background: #fff;
  padding-left: 8px;
}
#bar-btns .bar-btn { width: 48px; height: 48px; padding: 0; border-color: var(--line); background: #efeadf; }
#bar-btns .bar-btn svg { width: 22px; height: 22px; }
.bar-btn {
  height: 100%;
  border: 2px solid var(--ink);
  border-radius: 10px;
  background: #fff;
  color: var(--ink);
  font-family: var(--word-font);
  font-weight: 700;
  font-size: 17px;
  padding: 0 16px;
}
.bar-btn.primary { background: var(--ink); color: var(--cream); }
/* 023: the selected tense (and the lit question / the speaking
   button) wear ink — .sel is the trio's switch, .speaking holds
   while audio plays. */
.bar-btn.sel, .bar-btn.speaking { background: var(--ink); color: var(--cream); }
.bar-btn.glyph {
  flex: none;
  width: 68px;
  padding: 0;
  display: grid;
  place-items: center;
}
.bar-btn.glyph.primary { width: 88px; }
.bar-btn.glyph.wide { width: 88px; }
.bar-btn.glyph.tx { width: 60px; }
/* A gap between the edit pair (Clear, Backspace) and the sentence,
   and between Fix it / Question and the time transport. */
#backspace { margin-right: 6px; }
#tx-question { margin-right: 6px; }
.bar-btn.glyph svg { width: 34px; height: 34px; }
/* A sentence button named in text shows its own icon (inline-icons.js),
   in the text's colour — never the emoji. */
.text-icon { display: inline-block; width: 1.15em; height: 1.15em; vertical-align: -0.22em; }
.text-icon svg { width: 100%; height: 100%; }
.bar-btn:disabled {
  border-color: var(--mask-b);
  background: var(--mask-f);
  color: var(--mask-t);
}
.corner-btn {
  flex: none;
  width: 56px;
  border: 2px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: var(--ink);
  padding: 0;
  display: grid;
  place-items: center;
}
.corner-btn svg { width: 26px; height: 26px; }
.corner-btn[hidden] { display: none; }
/* v3 spec: the settings gear is small and quiet — borderless,
   muted #8a8272, far top-left. Edit's ✓ Done and the groups Home
   keep the corner's normal chrome. */
#corner { border-color: transparent; background: transparent; color: #8a8272; }
body.editing #corner, body.groups #corner {
  border-color: var(--line); background: #fff; color: var(--ink);
}
#corner .g-done, #corner .g-home, body.editing #corner .g-open { display: none; }
body.editing #corner .g-done { display: block; }
/* 027 B5: Home replaces the corner's other jobs while a group or the
   index is open — in Edit mode too (Done is the home board's). */
body.groups #corner .g-open, body.groups #corner .g-done { display: none; }
body.groups #corner .g-home { display: block; }
/* The 📊 toggle's on state (018 D10): pressed chrome, same rule as
   the seg buttons. */
.corner-btn.on { border-color: var(--ink-text); background: var(--tray); }

/* --- prediction strip: a neutral tray holding four word tiles --- */
/* Permanent strip: fixed height, always rendered. The 60-cell grid
   below never shifts — zero layout shift on prediction updates. */
#strip {
  height: 80px;
  flex: none;
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  grid-template-rows: minmax(0, 1fr);
  gap: var(--gap);
  overflow: hidden;
}
/* The tray marks the zone that changes — neutral, so no prediction
   color is needed and lavender stays retired. */
#tray {
  grid-column: span 8;
  min-width: 0;
  min-height: 0;
  background: var(--tray);
  border-radius: 12px;
  padding: 5px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: minmax(0, 1fr);
  gap: var(--gap);
  overflow: hidden;
}
/* Strip card: an ordinary word tile turned sideways — art on a
   white square at left, label on the role fill at right. */
.pred {
  border-radius: 10px;
  border: 3px solid var(--rb, var(--edge));
  background: #fff;
  display: flex;
  align-items: stretch;
  overflow: hidden;
  padding: 0;
  min-width: 0;
  /* A symbol's intrinsic size must not stretch the card. The
     default min-height is the picture, which blew an 80px tray
     out to the full image and painted it over the board. */
  min-height: 0;
  text-align: left;
}
.pred .part {
  align-self: stretch;
  aspect-ratio: 1;
  flex: none;
  min-width: 0;
  min-height: 0;
  max-height: 100%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4px;
  font-size: clamp(18px, 3.4vmin, 34px);
  background: #fff;
}
.pred .part img {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
}
.pred.photo .part { padding: 0; }
.pred.photo .part img { object-fit: cover; }
.pred .plabel {
  flex: 1;
  min-width: 0;
  background: var(--rf, var(--tray));
  color: var(--ink-text);
  font-family: var(--word-font);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  line-height: 1.05;
  padding: 0 4px;
  overflow: hidden;
}
.pred.ghost { border-style: dashed; border-color: var(--line); background: transparent; }
/* 025 § 1: the last slot's three feeling faces — small
   ink-bordered buttons, never word cards. A lit suggestion and
   the pressed state both go dark with the selected icon. */
.pred.faces {
  display: flex;
  gap: var(--gap);
  border-color: transparent;
  background: transparent;
}
.pred.faces .face {
  flex: 1;
  min-width: 0;
  min-height: 0;
  border-radius: 10px;
  border: 3px solid var(--edge);
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.pred.faces .face img {
  width: clamp(20px, 4vmin, 38px);
  height: clamp(20px, 4vmin, 38px);
}
.pred.faces .face:active { border-color: var(--ink-text); }
.pred.faces .face.lit,
.pred.faces .face.speaking {
  background: var(--ink);
  border-color: var(--ink-text);
}
/* Settings → Talking: the same faces, live, on the sample sentence. */
.try-faces { display: flex; flex-direction: column; gap: 10px; }
.try-faces .try-row { display: flex; gap: 6px; }
.try-faces .hint { margin: 0; }
.try-faces .face {
  flex: 1; min-height: 56px; border-radius: 10px;
  border: 3px solid var(--edge); background: #fff;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.try-faces .face img { width: 34px; height: 34px; }
.try-faces .face:active { border-color: var(--ink-text); }
.try-faces .face.speaking { background: var(--ink); border-color: var(--ink-text); }
.try-faces.off .try-row { opacity: .4; }
.pred:active { border-color: var(--ink-text); }
.pred:active .part { background: var(--press-f); }
/* Utility anchors: one column each, always visible. */
.anchor {
  border-radius: 12px;
  border: 3px solid var(--muted);
  background: var(--tray);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-weight: 700;
  font-size: clamp(10px, 1.7vmin, 14px);
  color: var(--neutral-text);
  overflow: hidden;
  padding: 0 4px;
}
.anchor[hidden] { display: none; }
.anchor .glyph { font-size: clamp(16px, 3vmin, 28px); line-height: 1; flex: none; }
.anchor .glyph img, .cell.anchor-cell .glyph img { width: 1em; height: 1em; display: block; }
.anchor span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* "Show me where": a 1.5s ink halo on the Groups anchor plus a
   fixed-position caption — out of flow, so zero layout shift, and
   pointer-events: none so it never eats a tap. */
/* A map-declared anchor drawn inside the grid (grid90's Groups
   cell) — same quiet surface as the strip anchors. */
.cell.anchor-cell {
  border-color: var(--muted);
  background: var(--tray);
  display: flex;
  align-items: center;
  justify-content: center;
}
.cell.anchor-cell .glyph { font-size: clamp(18px, 4vmin, 40px); }
.anchor.halo {
  outline: 4px solid var(--ink);
  outline-offset: 2px;
  box-shadow: 0 0 14px rgba(42, 36, 29, 0.65);
}
#pathhint {
  position: fixed;
  z-index: 20;
  transform: translateX(-50%);
  background: var(--ink-text);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  padding: 4px 10px;
  border-radius: 8px;
  white-space: nowrap;
  pointer-events: none;
}

/* --- word tile anatomy (Design_System § Tiles) ---
   Label strip on top in the role's fill, art on white below, role
   color on the border. Grammar is carried by strip + border; the
   tile face itself is white. */
#grid { flex: 1; min-height: 0; display: grid; gap: var(--gap); }
.cell {
  border-radius: 10px;
  border: 3px solid var(--rb, var(--edge));
  background: #fff;
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
  user-select: none;
  cursor: pointer;
  min-width: 0;
  min-height: 0;
}
.cell .tlabel {
  flex: none;
  height: 33%;
  width: 100%;
  background: var(--rf, var(--press-f));
  color: var(--ink-text);
  font-family: var(--word-font);
  font-weight: 700;
  line-height: 1.05;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 6%;
  overflow: hidden;
  /* One label size per board: long labels wrap to a second line
     (long words hyphenate at proper points via lang) rather than
     shrinking into a different size. */
  hyphens: auto;
  overflow-wrap: break-word;
}
.cell .tart {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3%;
}
.cell .tart img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
}
/* Words only (learner_profile.presentation_mode = 'label';
   Profile_Presentation_Modes § 2.2): no pictures anywhere; the
   label takes the whole tile and grows; the border keeps the
   grammar color; nothing moves. */
.words-only .cell .tart, .words-only .pred .part, .words-only .chip .cart { display: none; }
.words-only .cell .tlabel { height: 100%; flex: 1; padding: 0 8%; }
.words-only .chip { justify-content: center; }
.words-only .chip .clabel { height: auto; font-size: 28px; line-height: 1.15; }
/* Photos fill the art area edge to edge. */
.cell.photo .tart { padding: 0; }
.cell.photo .tart img { width: 100%; height: 100%; object-fit: cover; }
/* Pressed — border goes to ink, art area to warm fill. No scale,
   no movement. */
.cell:active { border-color: var(--ink-text); background: var(--press-f); }
/* Likely next (Parent Corner setting, default OFF) — a thicker
   inner border in the tile's own role color. Tile size unchanged. */
.cell.likely { box-shadow: inset 0 0 0 4px var(--rb); }
/* Masked — space preserved, word unreachable. */
.cell.masked { border-color: var(--mask-b); background: var(--mask-f); pointer-events: none; }
.cell.masked .tlabel { background: var(--mask-f); color: var(--mask-t); }
.cell.masked .tart img { opacity: 0.18; }
/* Attention layer (013): glow the targets, dim the rest — every
   cell stays 100% tappable and speaks; nothing moves, nothing is
   disabled (§ 2.1). Steady glow; no pulse unless a setting asks. */
.cell.glow, .gcell.glow, .anchor.glow, .bar-btn.glow {
  box-shadow: 0 0 0 4px var(--glow), 0 0 18px rgba(232, 162, 0, 0.55);
  z-index: 1;
}
.cell.dimmed, .gcell.dimmed { opacity: var(--dim-o); }
/* Optional pulse (013 § 4 glow-style setting): gentle, ~2s, no
   flashing — the steady ring stays, the halo breathes. */
@keyframes spot-pulse {
  0%, 100% { box-shadow: 0 0 0 4px var(--glow), 0 0 10px rgba(232, 162, 0, 0.35); }
  50% { box-shadow: 0 0 0 4px var(--glow), 0 0 24px rgba(232, 162, 0, 0.7); }
}
.cell.glow.pulse, .gcell.glow.pulse { animation: spot-pulse 2s ease-in-out infinite; }
/* Pick mode: tapping a word adds it to the list instead of
   speaking. Picked cells get the glow outline; the bar counts. */
body.picking .cell, body.picking .gcell { cursor: copy; }
.cell.picked, .gcell.picked, .bar-btn.picked { box-shadow: 0 0 0 4px var(--glow); }
#spot-pickbar, #modelbar {
  position: fixed; left: 50%; bottom: 14px; transform: translateX(-50%);
  background: var(--ink-text); color: #fff; border-radius: 14px;
  padding: 10px 14px; display: flex; gap: 10px; align-items: center;
  z-index: 11; font-size: 15px;
}
#spot-pickbar[hidden], #modelbar[hidden] { display: none; }
#spot-pickbar button, #modelbar button {
  border: 0; border-radius: 9px; padding: 7px 12px;
  font-weight: 700; font-size: 14px; cursor: pointer;
}
#spot-pickbar .pick-start { background: var(--glow); }
#spot-pickbar .pick-quiet, #modelbar .pick-quiet { background: #4a4539; color: #fff; }
/* Transition highlight (014 § 4): a moved word keeps a soft inner
   ring for the window — quieter than the spotlight's outer glow,
   and it dims nothing. */
.cell.moved { box-shadow: inset 0 0 0 3px var(--glow); }
/* The end chip: only while a spotlight runs; one tap ends it. */
#spot-chip {
  border: 2px solid var(--glow);
  background: var(--cream);
  color: var(--ink-text);
  border-radius: 999px;
  font-weight: 700;
  padding: 0 12px;
  white-space: nowrap;
}
#spot-chip[hidden] { display: none; }
/* Empty cell — reserved space, never collapses. */
.cell.empty {
  border-style: dashed;
  border-color: var(--line);
  background: transparent;
  cursor: default;
}

body.editing #corner { font-size: 15px; }

/* --- Parent corner sheets (adult chrome: system font) --- */
.seg-row { margin-top: 14px; text-align: left; }
.seg-label { display: block; font-weight: 700; margin-bottom: 4px; }
.seg { display: flex; gap: 6px; }
.seg button {
  flex: 1; padding: 10px 8px; border-radius: 10px;
  border: 2px solid var(--edge); background: #fff; font-weight: 700;
  font-size: 15px; cursor: pointer;
}
.seg button.on { border-color: var(--ink-text); background: var(--tray); }
.seg.disabled { opacity: 0.45; pointer-events: none; }
.seg-row .hint { font-size: 13px; color: var(--muted); margin: 6px 0 0; }

/* The weekly win card (016 § 4.1) — wins only, warm, no numbers
   that compare weeks. */
.wincard {
  margin: 10px 0 14px; padding: 12px 14px; text-align: left;
  border: 2px solid var(--edge); border-radius: 14px;
  background: var(--tray);
}
.wincard-sum { font-weight: 800; margin: 0 0 6px; }
.wincard-win { margin: 4px 0; }
.wincard .hint { font-size: 13px; color: var(--muted); margin: 8px 0 0; }

/* Progress dashboard (016 § 4.2): three headline numbers with a
   per-week trend line; sections follow the corner's own style. */
.prog-heads { display: flex; gap: 8px; margin: 12px 0; }
.prog-head {
  flex: 1; text-align: center; padding: 10px 6px;
  border: 2px solid var(--edge); border-radius: 12px; background: var(--tray);
}
.prog-head-n { font-size: 22px; font-weight: 800; }
.prog-head-l { font-size: 12px; color: var(--muted); }
.prog-trend { font-size: 11px; color: var(--muted); margin-top: 4px; }
.prog-goal-name { font-weight: 700; margin: 8px 0 2px; }
#prog-body p { margin: 4px 0; }
#prog-body .seg-label { margin-top: 14px; }
.place-row { display: flex; justify-content: space-between; width: 100%; margin-top: 6px; }

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(30, 26, 20, 0.45);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 10;
}
.overlay.open { display: flex; }
.sheet {
  background: #fff;
  border-radius: 16px;
  padding: 20px;
  width: min(520px, 92vw);
  max-height: 80dvh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.sheet h2 { font-size: 20px; }
.sheet input[type="text"] {
  font-size: 20px;
  padding: 10px 12px;
  border: 2px solid var(--line);
  border-radius: 10px;
}
.sheet .row { display: flex; gap: 10px; }
.sheet .row > * { flex: 1; }
/* Primary actions are solid ink — blue is a grammar color and never
   paints a button. */
.btn {
  border: 2px solid var(--ink);
  background: var(--ink);
  color: var(--cream);
  border-radius: 10px;
  padding: 12px;
  font-size: 18px;
  font-weight: 700;
}
.btn.secondary { background: #fff; color: var(--ink); }
.btn.danger { border-color: #c62828; background: #c62828; }
/* --- Edit mode (009 slice 2): drag moves/swaps, × removes, tap
   opens the card. Removal never reflows — the slot stays empty. */
.cell, .gcell { position: relative; }
.cell .x, .gcell .x {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid var(--cream);
  background: var(--ink);
  color: var(--cream);
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  padding: 0;
  z-index: 3;
}
.drag-src { opacity: 0.35; }
.drag-clone {
  position: fixed;
  z-index: 40;
  pointer-events: none;
  opacity: 0.92;
  box-shadow: 0 8px 20px rgba(42, 36, 29, 0.35);
}
.drop-hint { outline: 3px dashed var(--ink); outline-offset: 2px; }
/* "Show on board" marks the cell for a beat. */
.flash { box-shadow: 0 0 0 5px var(--ink); z-index: 2; }

/* 018 D10: the 📊 count — the child's own taps in 30 days, quiet
   in the tile's corner. The numbers are the explanation. */
.ucount {
  position: absolute;
  right: 6px;
  bottom: 4px;
  font-size: clamp(11px, 1.2vw, 15px);
  font-weight: 700;
  color: var(--muted, #777);
  z-index: 3;
}
/* 028 § 5.2: a tile whose shared voice clip is still being made
   (or is queued) wears the state in the corner — supporter-facing,
   the child never reads it. */
.vbadge {
  position: absolute;
  left: 6px;
  bottom: 4px;
  font-size: clamp(10px, 1.1vw, 14px);
  font-weight: 700;
  color: var(--muted, #777);
  background: rgba(255, 255, 255, 0.85);
  border-radius: 6px;
  padding: 1px 5px;
  z-index: 3;
}
/* The placement sheet: tapped tile chip + count + ✎, then rows. */
.ptile {
  flex: 1;
  padding: 8px 10px;
  border-radius: 10px;
  font-weight: 700;
  background: var(--rf, #f2efe6);
  border: 2px solid var(--rb, #8a8578);
}
#place-head { align-items: center; gap: 10px; }
.place-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 10px 8px;
  border: 0;
  border-bottom: 1px solid #efece5;
  background: none;
  font-size: 17px;
  cursor: pointer;
  text-align: left;
}
.place-row .prole {
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 8px;
  background: var(--rf, transparent);
}

/* --- undo toast --- */
#toast {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--ink);
  color: var(--cream);
  border-radius: 10px;
  padding: 10px 16px;
  font-weight: 700;
  box-shadow: 0 6px 18px rgba(42, 36, 29, 0.4);
}
/* Author `display` beats the hidden attribute, so an idle toast
   was painting a stray Undo on the board. */
#toast[hidden] { display: none; }
#toast-undo {
  background: none;
  border: none;
  color: var(--cream);
  font: inherit;
  text-decoration: underline;
  padding: 0;
}
.hint { color: #777; font-size: 14px; }
/* The Settings PIN sheet: digits spaced and centered; the reset
   phrase reads as a plain word. Empty lines take no room. */
#pin-body { display: flex; flex-direction: column; gap: 8px; }
#pin-body .hint { font-size: 15px; line-height: 1.4; color: var(--muted); }
#pin-body .hint:empty { display: none; }
#pin-hint strong { color: var(--ink); }
#pin-input {
  width: 100%;
  font-size: 26px;
  letter-spacing: 8px;
  text-align: center;
  padding: 10px 12px;
  border: 2px solid var(--line);
  border-radius: 10px;
}
#pin-input::placeholder { letter-spacing: normal; font-size: 18px; color: #aaa; }
#pin-input.phrase { font-size: 20px; letter-spacing: normal; }
#pin-input:focus { outline: none; border-color: var(--ink); }
#pin-body #pin-error { color: #a33; font-weight: 600; }
.pin-forgot {
  align-self: center;
  border: 0;
  background: none;
  font: inherit;
  font-size: 15px;
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 8px 12px;
  min-height: 44px;
  cursor: pointer;
}
.pin-forgot[hidden] { display: none; }
