/* ============================================================
   Art Daily game chrome — sketchbook edition.
   Every drill wears this same paper: warm sheet, graphite ink,
   one watercolor accent (--game-accent), handwritten Caveat for
   the display type (shared with the page, OFL — /fonts/LICENSE.txt), mono for
   numbers and annotations. Paper-first: light is the default,
   dark is "night studio". Token NAMES match the Art Daily page
   so a game's canvas inks (--ink/--muted/--game-accent, read via
   getComputedStyle) follow the theme automatically.
   A game's own styles belong BELOW the marker at the end.
   ============================================================ */

@font-face {
  font-family: 'Caveat';
  src: url('../../fonts/caveat-latin.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
}

:root {
  color-scheme: light;
  --bg: #F6EFDF;
  --card: #FDFAF1;
  --ink: #33291E;
  --muted: #766850; /* AA on the paper card (was #8A7B66 at ~3.9:1) */
  --line: #D9CBB2;
  --shadow: rgba(59, 47, 32, 0.16);
  --focus: #C4622F;
  --link: #3E6C8E;
  --prompt: #C4622F;

  --coral: #E26D5A;
  --sunny: #E9A93D;
  --mint: #56A382;
  --sky: #5C93B8;
  --lilac: #907BC0;
  --bubblegum: #D077A0;

  --hand: 'Caveat', 'Segoe Print', 'Comic Sans MS', cursive;
  --mono: ui-monospace, "Cascadia Code", "JetBrains Mono", "Fira Code", Menlo, Consolas, monospace;

  --game-accent: var(--sunny); /* TODO: pick this game's accent */
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #191511;
  --card: #221D16;
  --ink: #EFE7D7;
  --muted: #A39682;
  --line: #443A2C;
  --shadow: rgba(0, 0, 0, 0.5);
  --focus: #E88B4F;
  --link: #7FB2D8;
  --prompt: #E88B4F;

  --coral: #F08262;
  --sunny: #F2B345;
  --mint: #5FBF97;
  --sky: #6FADD6;
  --lilac: #A78FDF;
  --bubblegum: #E58AB5;
}

* { box-sizing: border-box; }

[hidden] { display: none !important; }

html { height: 100%; scrollbar-color: var(--muted) var(--bg); }

/* Selecting text runs a highlighter over it. */
::selection { background: #F3DF7E; color: #33291E; }
:root[data-theme="dark"] ::selection { background: #B99A2E; color: #191511; }

body {
  margin: 0;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  background:
    radial-gradient(color-mix(in srgb, var(--ink) 6%, transparent) 1px, transparent 1.4px) 0 0 / 22px 22px,
    var(--bg);
  color: var(--ink);
  font-family: var(--mono);
  font-variant-ligatures: none;
  font-variant-numeric: tabular-nums lining-nums;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }

:is(a, button, input, [tabindex]):focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ===== The sheet (keeps the .term class so games need no markup edits) ===== */

.term {
  position: relative;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 6px 14px 8px 12px;
  box-shadow: 0 2px 0 var(--shadow), 0 14px 30px -20px var(--shadow);
  text-align: left;
}
/* washi tape holding the sheet */
.term::before {
  content: "";
  position: absolute;
  top: -11px;
  left: 34px;
  width: 84px;
  height: 22px;
  transform: rotate(-3deg);
  background:
    repeating-linear-gradient(105deg, transparent 0 7px, rgba(255, 255, 255, 0.28) 7px 12px),
    color-mix(in srgb, var(--game-accent) 55%, transparent);
  border-radius: 2px;
  box-shadow: 0 1px 2px var(--shadow);
  pointer-events: none;
  z-index: 1;
}

/* The old terminal title bar becomes a pencil label in the corner. */
.term-bar {
  display: flex;
  justify-content: flex-end;
  padding: 10px 16px 0;
}
.dot { display: none; }
.term-title {
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 0.05em;
}

.term-body { padding: 14px 24px 26px; }

.promptline { margin: 0 0 10px; font-size: 0.85rem; font-weight: 700; color: var(--muted); }
.prompt { color: var(--prompt); font-weight: 900; user-select: none; }

/* ===== Topbar ===== */

.topbar { display: flex; align-items: center; gap: 8px; padding: 16px 16px 8px; }
.topbar-spacer { flex: 1; }

.backlink {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  font-size: 0.82rem;
  text-decoration: none;
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 3px 10px 4px 9px;
  background: var(--card);
  box-shadow: 0 2px 0 var(--shadow);
  transform: rotate(-0.6deg);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.backlink:hover { transform: rotate(0deg) translateY(-2px); box-shadow: 0 4px 0 var(--shadow); }

.iconbtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 10px 4px 9px 5px;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  padding: 0;
  text-decoration: none;
  box-shadow: 0 2px 0 var(--shadow);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.iconbtn:hover { transform: translateY(-2px) rotate(2deg); box-shadow: 0 4px 0 var(--shadow); }

/* Light (default) shows the moon (click → dark); dark shows the sun. */
.ic-sun { display: none; }
:root[data-theme="dark"] .ic-sun { display: inline; }
:root[data-theme="dark"] .ic-moon { display: none; }

/* ===== Stage ===== */

.stage {
  flex: 1;
  width: 100%;
  max-width: 860px;
  margin: 0 auto;
  padding: 20px 20px 48px;
}
.stage.game-wide { max-width: 780px; }

.game-body { text-align: left; }

/* ===== HUD ===== */

.game-hud {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}

.game-name {
  margin: 0;
  font-family: var(--hand);
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.05;
}
.game-emoji { margin-right: 2px; font-size: 1.5rem; }
.game-tagline {
  margin: 2px 0 0;
  font-family: var(--hand);
  font-size: 1.2rem;
  font-weight: 500;
  color: var(--muted);
}

.hud-stats { display: flex; gap: 8px; margin: 0; }

.hud-stat {
  min-width: 64px;
  padding: 5px 10px 6px;
  border: 1px solid var(--line);
  border-radius: 4px 10px 5px 9px;
  background: color-mix(in srgb, var(--line) 14%, var(--card));
  text-align: center;
}
.hud-stat dt {
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.hud-stat dd {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 900;
  /* the 45% mix — the same ink the canvas uses — measured worst case 5.01:1 on paper (sunny); 55% left sunny at 4.09, under the 4.5 text owes */
  color: color-mix(in srgb, var(--game-accent) 45%, var(--ink));
}
/* …and pure accent on the dark sheet, where it already passes. */
:root[data-theme="dark"] .hud-stat dd { color: var(--game-accent); }

.hint { min-height: 1.6em; margin: 6px 0 10px; color: var(--muted); font-size: 0.83rem; font-weight: 600; }

/* ===== Drill stage ===== */

.game-stage { position: relative; }

/* The canvas stays transparent; this graph-paper grid shows through.
   Games repaint on ArtDaily.onTheme() so inks follow the theme. */
.game-canvas {
  display: block;
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 5px 12px 6px 11px;
  background:
    radial-gradient(color-mix(in srgb, var(--ink) 8%, transparent) 1px, transparent 1.5px) 0 0 / 18px 18px,
    var(--card);
  touch-action: none;      /* draw, don't scroll, on touch screens */
  cursor: crosshair;
}

/* Score pop — a little sticker. The global reduced-motion rule
   flattens the animation. */
.toast {
  position: absolute;
  left: 50%;
  top: 14px;
  transform: translateX(-50%) rotate(-1.5deg);
  padding: 6px 16px;
  border: 1px solid var(--line);
  border-radius: 4px 12px 5px 10px;
  background: var(--card);
  box-shadow: 0 3px 0 var(--shadow);
  font-family: var(--hand);
  font-size: 1.2rem;
  font-weight: 700;
  white-space: nowrap;
  animation: toast-pop 0.25s ease;
}
.toast .toast-accent { color: color-mix(in srgb, var(--game-accent) 45%, var(--ink)); }
:root[data-theme="dark"] .toast .toast-accent { color: var(--game-accent); }
@keyframes toast-pop {
  from { transform: translateX(-50%) translateY(-8px) rotate(-1.5deg); opacity: 0; }
  to   { transform: translateX(-50%) translateY(0) rotate(-1.5deg);    opacity: 1; }
}

/* ===== Controls — sticker buttons ===== */

.game-controls { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }

.btn {
  font-family: var(--hand);
  font-size: 1.18rem;
  font-weight: 700;
  color: var(--ink);
  padding: 6px 18px;
  border: 1px solid var(--line);
  border-radius: 4px 12px 5px 10px;
  background: var(--card);
  box-shadow: 0 2px 0 var(--shadow);
  cursor: pointer;
  transform: rotate(-0.5deg);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.btn:hover { transform: rotate(0deg) translateY(-2px); box-shadow: 0 4px 0 var(--shadow); }
.btn:active { transform: translateY(1px); box-shadow: 0 1px 0 var(--shadow); }
.btn:disabled { opacity: 0.45; cursor: default; transform: none; box-shadow: 0 1px 0 var(--shadow); }

.btn-primary {
  background: color-mix(in srgb, var(--game-accent) 26%, var(--card));
  border-color: color-mix(in srgb, var(--game-accent) 60%, var(--line));
}

.howto {
  margin-top: 12px;
  padding: 10px 16px;
  border: 1px dashed var(--line);
  border-radius: 6px 12px 6px 12px;
  color: var(--muted);
  font-size: 0.83rem;
  font-weight: 600;
}
.howto p { margin: 4px 0; }
.howto-cmd { font-weight: 800; }

/* ---- page copy ----
   What this drill is, in prose, for the visitor who arrived from a search
   result rather than from the catalogue — the drill itself says almost
   nothing a crawler can read, because it is a canvas. It sits OUTSIDE
   <main> and is hidden in the player (see the :root.embed rule further
   down), so the arcade's iframe is exactly what it always was. */
.about {
  width: 100%;
  max-width: 860px;      /* the .stage column, so it lines up under the drill */
  margin: 0 auto;
  padding: 0 20px 40px;
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.65;
}
.about h2, .about h3 {
  color: var(--ink);
  font-family: var(--hand);
  font-weight: 700;
  letter-spacing: 0.01em;
}
.about h2 { font-size: 1.5rem; margin: 8px 0 6px; }
.about h3 { font-size: 1.2rem; margin: 18px 0 4px; }
.about p { margin: 0 0 10px; }
.about a { color: var(--link); }
.about-more {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px dashed var(--line);
  font-size: 0.86rem;
}

/* ===== Footer ===== */

.footer { text-align: center; padding: 40px 20px 28px; color: var(--muted); }
.footnav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-weight: 700;
  font-size: 0.85rem;
}
.footnav a { text-decoration: none; }
.footnav a:hover { text-decoration: underline wavy; text-decoration-thickness: 2px; }
#supportLinks { display: contents; }
.heart-ink { color: var(--coral); }
.fineprint { margin: 12px 0 0; font-size: 0.76rem; }

/* ===== Embedded inside the Art Daily player ===== */
/* The player supplies the sheet, so the game sheds its own. */

:root.embed .topbar,
:root.embed .footer,
:root.embed .term-bar { display: none; }
:root.embed .stage { padding: 10px 12px 16px; max-width: none; }
:root.embed .term { border: 0; box-shadow: none; border-radius: 0; background: transparent; }
:root.embed .term::before { display: none; }
:root.embed .term-body { padding: 0; }
:root.embed .about { display: none; }

@media (max-width: 480px) {
  .stage { padding: 14px 12px 36px; }
  .term-body { padding: 12px 16px 20px; }
  .game-name { font-size: 1.7rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* The SDK fills this when it knows the input hardware. Scores are eased
   per device, so the drill says which device it eased for. */
.hud-input { min-width: 0; border: 0; background: none; padding: 5px 2px; display: flex; align-items: flex-end; }
.hud-input dd {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--muted);
  max-width: 8.5rem;
  line-height: 1.25;
}

/* Shown by the SDK when a drill is played on its own page: progress
   lives per-origin, so a standalone score needs a way home. */
.handoff {
  margin: 12px 0 0;
  padding: 9px 14px;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--muted);
  border: 1px dashed color-mix(in srgb, var(--game-accent) 55%, var(--line));
  border-radius: 5px 12px 6px 11px;
  background: color-mix(in srgb, var(--game-accent) 8%, transparent);
}
.handoff-link {
  font-family: var(--hand);
  font-size: 1.15rem;
  font-weight: 700;
  color: color-mix(in srgb, var(--game-accent) 45%, var(--ink));
  text-decoration: underline;
  text-underline-offset: 3px;
}
:root[data-theme="dark"] .handoff-link { color: var(--game-accent); }

/* ============================================================
   game-specific styles below this line
   ============================================================ */

/* ===== Value Trap board — same graph paper as the canvas games.
   Chip fills are inline (they ARE the drill); everything else
   reads theme vars so light/dark both work untouched. ===== */

.vt-board {
  border: 1px solid var(--line);
  border-radius: 5px 12px 6px 11px;
  background:
    radial-gradient(color-mix(in srgb, var(--ink) 8%, transparent) 1px, transparent 1.5px) 0 0 / 18px 18px,
    var(--card);
  padding: 16px 16px 18px;
}

.vt-caption {
  margin: 0 0 6px;
  font-family: var(--hand);
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--muted);
  text-align: center;
}

.vt-target {
  width: min(240px, 70%);
  height: 64px;
  margin: 0 auto 18px;
  border: 1px solid var(--line);
  border-radius: 4px 10px 5px 9px;
  box-shadow: 0 2px 0 var(--shadow);
  display: flex;
  align-items: center;
  justify-content: center;
}

.vt-chips {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

.vt-chip {
  position: relative;
  min-height: 84px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 4px 10px 5px 9px;
  box-shadow: 0 2px 0 var(--shadow);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.vt-chip:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px 0 var(--shadow); }
.vt-chip:active:not(:disabled) { transform: translateY(1px); box-shadow: 0 1px 0 var(--shadow); }
.vt-chip:disabled { cursor: default; }

/* L* annotations that appear in the squint view. The chips underneath
   span L* ~12–93, so the label sits on its own fixed dark pill: ink is
   ≥ 4.5:1 against the pill on every chip grey, in both themes. */
.vt-lab {
  font-family: var(--mono);
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  pointer-events: none;
  color: #f7f1e4;
  background: rgba(20, 15, 8, 0.78);
  padding: 3px 9px;
  border-radius: 999px;
}

/* keyboard affordance: each chip's 1–6 numeral, same fixed dark pill
   as .vt-lab (ink ≥ 4.5:1 on the pill over any chip colour, both
   themes). Shown only where a hover pointer exists — i.e. where a
   keyboard is likely — so touch layouts stay clean. */
.vt-key {
  position: absolute;
  top: 6px;
  left: 8px;
  display: none;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 800;
  color: #f7f1e4;
  background: rgba(20, 15, 8, 0.78);
  padding: 1px 7px;
  border-radius: 999px;
  pointer-events: none;
}
@media (hover: hover) and (pointer: fine) {
  .vt-key { display: block; }
}

/* explicit tap-to-continue out of the squint view */
.vt-next {
  display: block;
  margin: 14px auto 0;
}

/* The reveal: correct chip ringed in the accent, wrong pick dashed.
   The accent alone is only 1.97:1 against paper (sunny on a warm sheet),
   so the single most meaning-bearing mark in the drill would go missing
   in the light theme. An ink hairline inside the accent band fixes that:
   the ring is a two-band mark, and in each theme a DIFFERENT boundary
   carries it, which is why both bands have to be there.
     light: ink|accent 6.91  (accent|sheet is only 1.97)
     dark:  accent|sheet 9.01 (ink|accent is only 1.51)
   The inner ink|chip edge cannot be relied on either way, because the
   squint-view greys run L* 12–93: ink reads 11.9:1 on the lightest chip
   in the light theme and 1.16:1 on the darkest, and the reverse in the
   night studio. Measured, not assumed — do not drop a band. */
/* The :hover and :active rules above also set box-shadow, and they are
   (0,3,1) selectors against this rule's (0,2,1) — so once the chips were
   left LIVE through the squint view, hovering the answer chip wiped the
   one mark the whole reveal is built on. Restate the ring at matching
   specificity, after them, so a pointer resting on the chip cannot
   erase it. (.vt-chosen is an outline, which nothing here touches.) */
.vt-chip.vt-correct,
.vt-chip.vt-correct:hover:not(:disabled),
.vt-chip.vt-correct:active:not(:disabled) {
  box-shadow: 0 0 0 2px var(--ink), 0 0 0 5px var(--game-accent), 0 2px 0 var(--shadow);
}
/* "your pick" was an `outline` — and `outline` is the one property
   :focus-visible has to have. The shared focus rule is
   `:is(a, button, input, [tabindex]):focus-visible`, which computes to
   the same (0,2,0) specificity as `.vt-chip.vt-chosen`, and this rule
   comes later in the file, so on a tie it WON: the chip a player picked
   wore the identical dashed graphite ring whether it was focused or
   not. That is no focus indicator at all on the one chip a keyboard
   player is most likely to come back to — the chips stay live right
   through the squint view, so tabbing back into the board is a normal
   move, and the chosen chip is the one they want to re-read.
   Carry the mark as an INSET ring instead. box-shadow and outline are
   different properties, so the two coexist: the focus ring sits OUTSIDE
   the chip (offset 3px, i.e. on the board's paper — --focus measures
   3.92:1 there in the light theme, 6.56:1 in the night studio) and the
   pick mark sits INSIDE it. That also matches the family's existing
   vocabulary — neutral-hunt marks its picked chip with exactly this
   paper-then-graphite inset pair, and outer-ring = the answer,
   inner-ring = your pick now reads the same way in both drills.
   The two bands are pinned sRGB, not theme inks, for the same reason
   .vt-correct's are: the squint greys run L* 12–93 and no single
   theme-following ink survives that span. Measured on every one:
   paper|graphite is 13.63:1 everywhere, and against the CHIP the
   stronger of the two bands never drops below 3:1 —
     L*12 15.79 (paper) · L*30 8.90 (paper) · L*50 4.29 (paper)
     L*60  4.51 (graphite) · L*70 6.19 · L*93 11.93 (graphite)
   — so the pick is always readable, and which band carries it simply
   swaps over as the chip gets lighter.
   Restated at :hover/:active specificity, exactly as .vt-correct is,
   because those rules also set box-shadow and would otherwise wipe it
   the moment a pointer rested on the chip. */
.vt-chip.vt-chosen,
.vt-chip.vt-chosen:hover:not(:disabled),
.vt-chip.vt-chosen:active:not(:disabled) {
  box-shadow:
    inset 0 0 0 3px #FDFAF1,
    inset 0 0 0 6px #33291E,
    0 2px 0 var(--shadow);
}

@media (max-width: 520px) {
  .vt-chips { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .vt-chip { min-height: 72px; }
}

/* ============================================================
   Tablet + phone gestures — shared hardening.
   A slow, deliberate press is exactly the gesture that raises the
   iOS copy/share callout over a drawing surface, and a quick second
   tap on a control is exactly what zooms the sheet mid-round. Both
   read to a beginner as "this page is broken", so both are shut off
   here rather than left to the platform default.
   ============================================================ */
html, body { overscroll-behavior-y: contain; }

.game-canvas {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

button, .btn {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  touch-action: manipulation;  /* a second quick tap must not zoom the sheet */
}

.btn { min-height: 44px; }     /* the phone tap-target floor */

/* ---- six chips, not four ----
   One right answer in four meant a blind tapper banked 25/100 before
   any judgement at all. Three columns on a wide sheet keeps every chip
   well above the 44px floor; two columns under 520px as before. */
.vt-chips { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 520px) {
  .vt-chips { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.vt-caption { font-size: 1.05rem; line-height: 1.2; }
