/* Ganana - count in Sanskrit */

:root {
  --bg: #0a0a14;
  --panel: #15152a;
  --panel-2: #1c1c36;
  --line: #2a2a4a;
  --text: #eceaf6;
  --muted: #9a9ac0;
  --accent: #5858FD;
  --saffron: #f2851c;
  --teal: #2ec4b6;
  --green: #2ec46b;
  --red: #e23b3b;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body {
  margin: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* The device's own Devanagari face, for the reasons set out in akshara: every
   platform ships one that shapes correctly, and a webfont for this script is a
   real download on a phone connection. */
[lang="sa"] {
  font-family: "Nirmala UI", "Noto Sans Devanagari", "Noto Serif Devanagari",
               "Devanagari Sangam MN", "Kohinoor Devanagari", "Mangal", serif;
  font-feature-settings: "kern" 1, "liga" 1;
}

.wrap { max-width: 900px; margin: 0 auto; padding: 18px 16px 40px; }

.topbar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px max(12px, env(safe-area-inset-right)) 10px max(12px, env(safe-area-inset-left));
  background: rgba(10, 10, 20, 0.92);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(6px);
}
.brand { margin: 0; font-weight: 700; letter-spacing: 0.5px; }
.back { color: var(--muted); text-decoration: none; font-size: 13.5px; }
.back::before { content: "< "; }
.back:hover { color: var(--text); }
.hud-btn {
  padding: 8px 14px;
  min-height: 40px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
}
.hud-btn:hover { color: var(--text); border-color: var(--accent); }
.hud-btn[aria-pressed="true"] { color: #ff8c8c; border-color: rgba(255, 140, 140, 0.35); }

.intro-card {
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background:
    radial-gradient(120% 130% at 8% 0%, rgba(46, 196, 182, 0.16), rgba(0, 0, 0, 0) 60%),
    radial-gradient(120% 130% at 95% 100%, rgba(88, 88, 253, 0.18), rgba(0, 0, 0, 0) 58%),
    var(--panel);
}
.kicker {
  margin: 0 0 6px;
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--teal);
}
h1 { margin: 0 0 10px; font-size: 30px; letter-spacing: -0.7px; }
.lede { margin: 0 0 16px; color: var(--muted); font-size: 15px; line-height: 1.65; max-width: 60ch; }

/* The two things a child can do from the start screen, side by side, with the
   one that starts a game first and clearly the louder of the two. On a narrow
   phone they stack and each spans the width, so neither is a small target. */
.intro-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.intro-actions .btn { flex: 1 1 auto; min-height: 46px; }
@media (max-width: 460px) {
  .intro-actions .btn { flex: 1 1 100%; }
}

.overall { margin: 0 0 16px; }
.bar { height: 8px; border-radius: 999px; background: rgba(255, 255, 255, 0.09); overflow: hidden; }
.bar span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--teal), var(--accent));
  transition: width .35s ease;
}
.overall-text { margin: 8px 0 0; color: var(--muted); font-size: 13px; }

.beta {
  margin: 18px 0 10px;
  padding: 12px 14px;
  border: 1px solid rgba(242, 133, 28, 0.4);
  border-radius: 12px;
  background: rgba(242, 133, 28, 0.08);
  color: #f6d5b4;
  font-size: 13px;
  line-height: 1.6;
}
.beta a { color: #ffd7ae; }
.cross { margin: 0 0 6px; color: var(--muted); font-size: 13.5px; }
.cross a { color: var(--teal); }

.section-title {
  margin: 26px 0 12px;
  font-size: 12px;
  letter-spacing: 1.8px;
  text-transform: uppercase;
  color: var(--muted);
}

/* Sets */
.themes { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.theme {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  flex-wrap: wrap;
}
.theme.is-complete { border-color: rgba(46, 196, 107, 0.45); }
.theme-copy { flex: 1 1 240px; min-width: 0; }
.theme-copy h3 { margin: 0 0 3px; font-size: 16px; }
.theme-copy p { margin: 0 0 8px; color: var(--muted); font-size: 13px; line-height: 1.5; }
.theme-count { margin: 6px 0 0 !important; font-size: 12px !important; }
.theme-actions { display: flex; gap: 8px; flex: 0 0 auto; }

.btn {
  padding: 10px 16px;
  min-height: 44px;
  border-radius: 10px;
  border: 1px solid transparent;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: #4646e0; }
.btn-ghost { background: transparent; border-color: var(--line); color: var(--text); }
.btn-ghost:hover { border-color: var(--accent); }

/* Word list */
.view-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 16px; }
.view-head h2 { margin: 0; font-size: 20px; }
.view-note { margin: 2px 0 0; color: var(--muted); font-size: 13.5px; }

.words { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.word {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
}
.word.is-learnt { border-color: rgba(46, 196, 107, 0.45); }
.word-sa { font-size: 24px; line-height: 1.35; }
.word-tr { color: var(--muted); font-size: 13.5px; }
.word-en { font-size: 15px; }
.word-g {
  justify-self: end;
  min-width: 24px;
  text-align: center;
  padding: 2px 7px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
}
.gender-key { margin: 14px 0 0; color: var(--muted); font-size: 12.5px; }
.gender-key .word-g { display: inline-block; margin: 0 2px; }

/* The board */
.round-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.round-theme { margin: 0; flex: 1 1 auto; font-weight: 700; }
.round-stat { margin: 0; color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }

.board {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.cell {
  min-height: 76px;
  padding: 12px 10px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  color: var(--text);
  font: inherit;
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease, opacity .2s ease;
  overflow-wrap: anywhere;
}
.cell.is-sa span { font-size: 27px; line-height: 1.35; }
.cell.is-en span { font-size: 17px; }
.cell:hover:not(:disabled) { border-color: var(--accent); }
.cell.is-picked { border-color: var(--teal); background: rgba(46, 196, 182, 0.14); }
.cell.is-wrong { border-color: var(--red); background: rgba(226, 59, 59, 0.16); }
/* Cleared pairs stay on the board rather than vanishing: the grid is a list of
   what has been learnt by the end, and an empty square teaches nothing. */
.cell.is-done {
  opacity: 0.4;
  border-color: rgba(46, 196, 107, 0.5);
  background: rgba(46, 196, 107, 0.1);
  cursor: default;
}

.feedback { margin: 16px 0 0; min-height: 44px; text-align: center; font-size: 15px; line-height: 1.55; }
.feedback.is-right { color: #8ff0b5; }
.feedback.is-wrong { color: #ffc7c7; }

/* Result */
.done-card {
  padding: 24px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--panel);
  text-align: center;
}
.done-card h2 { margin: 0 0 6px; font-size: 22px; }
.done-time {
  margin: 0 0 8px;
  font-size: 44px;
  font-weight: 800;
  letter-spacing: -1px;
  font-variant-numeric: tabular-nums;
}
.done-list { margin: 18px 0 0; padding: 0; list-style: none; display: grid; gap: 6px; text-align: left; }
.done-list li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px;
  align-items: baseline;
  padding: 8px 12px;
  border-radius: 10px;
  background: var(--panel-2);
}
.done-list span[lang="sa"] { font-size: 22px; }
.done-list em { font-style: normal; color: var(--muted); font-size: 13px; }
.done-actions { display: flex; gap: 10px; justify-content: center; margin-top: 22px; flex-wrap: wrap; }

.foot {
  padding: 22px 16px max(22px, env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}
.foot a { color: var(--muted); }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (min-width: 700px) {
  .board { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 520px) {
  h1 { font-size: 24px; }
  .theme-actions { width: 100%; }
  .theme-actions .btn { flex: 1 1 auto; }
  .word { grid-template-columns: minmax(0, 1fr) auto; row-gap: 4px; }
  .word-tr { grid-column: 1; }
  .word-en { grid-column: 1; font-size: 14px; }
  .word-g { grid-row: 1; grid-column: 2; }
  .done-list li { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* ===================================================================
   Touch targets, 12/09/2026.

   A hit test across all seven games found the same defect on every one
   of them: the chrome and the option controls were sized for a mouse.
   The way back to the games list - the single most used control on a
   game page - was 17 to 38px tall depending on the game, the option
   buttons were 34 to 36px, and links inside a sentence were 17px. The
   mark is 44px, and a phone is the main way these are played.

   Gated on a coarse pointer so a desktop keeps its compact chrome
   exactly as it was: this is a phone fix, not a redesign.
   =================================================================== */
@media (pointer: coarse) {

  /* The way out. It is the control a lost player reaches for, so it is
     the last one that should be hard to hit. */
  .back, .link-back, .hud-back {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 10px 0 6px;
    margin-left: -6px;
    border-radius: 10px;
  }
  .back:active, .link-back:active { background: rgba(255, 255, 255, 0.06); }

  /* Option rows: level, difficulty, traffic, which mark you play. */
  .segmented button { min-height: 44px; }

  /* Everything already shaped like a button, brought up to the mark. */
  .hud-btn, .ghost-btn, .icon-btn, .btn, .tbtn { min-height: 44px; }
  .icon-btn { min-width: 44px; }

  /* A link inside a sentence cannot be 44px without wrecking the line, so
     the line is opened up instead and the link padded into it. 17px to
     33px is the difference between a miss and a hit. */
  .foot p a, .beta a, .cross a, .intro a, .note a, .tip a {
    display: inline-block;
    padding: 8px 0;
  }
  .foot p, .beta, .cross { line-height: 2.05; }

  /* A disclosure triangle is a control too. */
  summary { min-height: 44px; }
}

/* ------------------------------------------- the course, in the footer
   Every Sanskrit page carries all three games and says which one the reader
   is on. It used to be one sentence with three links threaded through it:
   the order was invisible and each link was a 17px tap target. */
.foot-line { margin: 0 0 12px; }
.foot-steps {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
}
.foot-steps a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text);
  text-decoration: none;
  font-size: 13.5px;
}
.foot-steps a:hover { border-color: var(--teal, #2ec4b6); }
.foot-steps a:focus-visible { outline: 2px solid var(--teal, #2ec4b6); outline-offset: 2px; }
.foot-steps em { font-style: normal; color: var(--muted); }
.step-n {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--line);
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
}
/* The page you are already on is a label, not a link you want to take. */
.foot-steps a.is-here {
  border-color: var(--teal, #2ec4b6);
  background: rgba(46, 196, 182, 0.1);
}
.foot-steps a.is-here .step-n { background: var(--teal, #2ec4b6); color: #08131a; }

/* `.daily-share summary` sets its own 34px, which outranks the 44px in the
   touch block above on specificity. A rule that loses silently is the trap
   this project keeps meeting; this is the explicit override. */
@media (pointer: coarse) {
  .daily-share summary { min-height: 44px; }
}

/* The same bar the hub and milaojobs.tsblack.in carry: who owns the site, and
   who built it. Sits under the course row so every page ends the same way. */
.foot-bar {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--muted);
}
.foot-bar p { margin: 0; }
.foot-bar a { color: var(--teal, #2ec4b6); text-decoration: none; }
.foot-bar a:hover { text-decoration: underline; }
.foot-bar a:focus-visible { outline: 2px solid var(--teal, #2ec4b6); outline-offset: 2px; }

@media (min-width: 700px) {
  .foot-bar { flex-direction: row; justify-content: center; gap: 6px 18px; }
}

/* Those two are links inside a sentence, so they get the same treatment as the
   rest of the prose links: a line opened up and the link padded into it. */
@media (pointer: coarse) {
  .foot-bar { line-height: 2.05; }
  .foot-bar a { display: inline-block; padding: 8px 0; }
}


/* Controls are controls, not text: a thumb held on one must not raise a
   selection or an iOS copy callout. Every game here carries the same list, and
   tools/verify.js fails if one of them loses a line of it. Prose is left out on
   purpose - One Over's share card is a textarea a player copies from - and so
   is any text input, which has to stay selectable to be usable. */
button, kbd, canvas, summary, label,
.tbtn, .tbtn-stack, .touch, .touch-left, .touch-right, .touch-row, .touch-pad,
.zone, .stick, .bomb-btn, .board, .tiles, .swatches,
.hud, .hud-btn, .hud-btns, .hud-stats, .chips, .topbar, .topbar-actions,
.segmented, .more-sheet,
a.hud-back, a.icon-back, a.link-back, a.btn,
[role="button"], [role="radio"], [role="gridcell"], [role="checkbox"], [role="switch"] {
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

/* While a run is on, the page is the game. */
body.is-playing .foot { display: none !important; }

/* In fullscreen the game is the only thing on the screen. The two prefixes
   cannot share a rule: one selector a browser does not know invalidates the
   whole list, so they are written out separately. */
:fullscreen .foot { display: none !important; }
:-webkit-full-screen .foot { display: none !important; }

/* One more button in the bar, so the bar is allowed to wrap rather than push
   its last control off a narrow screen. */
.topbar { flex-wrap: wrap; }
.topbar-actions { flex-wrap: wrap; }

/* ===================================================================
   The way out is one icon button, the same in every game - 14/09/2026.

   It used to be a text link reading "All games" in six games, "Home"
   in Race Dash, each at its own size and with a "< " glued on in CSS.
   A chevron into a line reads as back at any size, costs no width on a
   narrow HUD, and is the same shape on all eight pages.

   It stays a link, not a button, so middle click and open in a new tab
   behave. The label is still in the markup for a screen reader and as
   the tooltip, so nothing is lost by dropping the visible words.
   =================================================================== */
.icon-back {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  margin: 0;
  flex: 0 0 auto;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.04);
  color: inherit;
  opacity: 0.82;
  text-decoration: none;
}
.icon-back:hover { opacity: 1; background: rgba(255, 255, 255, 0.10); }
.icon-back:active { background: rgba(255, 255, 255, 0.16); }
.icon-back svg { display: block; }
/* The old text link glued its arrow on with a pseudo element. */
.icon-back::before, .icon-back::after { content: none !important; }

/* Its own copy of the screen reader label, so the icon carries a name in
   every game whatever that game calls its hidden text class. */
.icon-back .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;
}

@media (pointer: coarse) {
  .icon-back { width: 44px; height: 44px; padding: 0; margin: 0; }
}

/* ===================================================================
   Ganana - the baskets, the tray and the four words
   =================================================================== */

.section-title { margin: 26px 0 12px; font-size: 17px; }
.hint { margin: 10px 0 0; color: var(--muted); font-size: 12.5px; line-height: 1.55; }

.levels { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.level {
  width: 100%;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  min-height: 72px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.level:hover:not(:disabled) { border-color: var(--accent); }
.level:disabled { opacity: 0.5; cursor: not-allowed; }
.level-range {
  display: inline-grid;
  place-items: center;
  min-width: 56px;
  padding: 6px 8px;
  border-radius: 10px;
  background: var(--panel-2);
  color: var(--saffron);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.level-text { display: grid; gap: 2px; }
.level-text b { font-size: 16px; }
.level-text em { font-style: normal; color: var(--muted); font-size: 13px; }
.level-best { color: var(--muted); font-size: 12.5px; font-variant-numeric: tabular-nums; }

.stars { display: inline-flex; gap: 3px; }
.star svg { width: 18px; height: 18px; display: block; fill: #33334f; }
.star.is-on svg { fill: #ffd166; }

/* The chart of all twenty */
.chart {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}
.num-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "digit sa dv" "digit tr dv";
  align-items: center;
  gap: 2px 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
}
.num-digit {
  grid-area: digit;
  min-width: 34px;
  text-align: center;
  font-size: 22px;
  font-weight: 800;
  color: var(--saffron);
  font-variant-numeric: tabular-nums;
}
.num-sa { grid-area: sa; font-size: 24px; line-height: 1.3; }
.num-tr { grid-area: tr; color: var(--muted); font-size: 12.5px; }
.num-dv { grid-area: dv; color: var(--teal); font-size: 19px; }

/* A round */
.round-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.bar {
  flex: 1 1 120px;
  height: 8px;
  border-radius: 999px;
  background: var(--panel-2);
  overflow: hidden;
}
.bar span { display: block; height: 100%; background: var(--teal); transition: width .2s ease; }
.round-count, .round-stat { margin: 0; color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }

.ask { margin: 0 0 12px; font-size: 22px; font-weight: 700; text-align: center; }

.tray {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  padding: 16px 12px;
  border: 1px dashed var(--line);
  border-radius: 18px;
  background:
    radial-gradient(120% 130% at 50% 0%, rgba(88, 88, 253, 0.10), rgba(0, 0, 0, 0) 60%),
    var(--panel);
  min-height: 140px;
  align-content: center;
}
.thing {
  position: relative;
  display: grid;
  place-items: center;
  width: 74px;
  height: 74px;
  padding: 6px;
  border: 2px solid transparent;
  border-radius: 16px;
  background: transparent;
  cursor: pointer;
  transition: transform .1s ease, border-color .12s ease, background .12s ease;
}
/* Three sizes, so twenty things still fit on a phone without scrolling the
   tray out from under the tally. */
.tray[data-size="mid"] .thing { width: 60px; height: 60px; }
.tray[data-size="small"] .thing { width: 48px; height: 48px; padding: 4px; }
.thing svg { width: 100%; height: 100%; display: block; }
.thing:hover { background: rgba(255, 255, 255, 0.05); }
.thing:active { transform: scale(0.94); }
.thing.is-counted { border-color: var(--green); background: rgba(46, 196, 107, 0.14); }
.thing-n {
  position: absolute;
  right: 2px;
  bottom: 0;
  min-width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--green);
  color: #06210f;
  font-size: 12px;
  font-weight: 800;
  line-height: 1;
}
.thing:not(.is-counted) .thing-n { display: none; }

.tally { margin: 10px 0 16px; text-align: center; color: var(--muted); font-size: 14px; min-height: 20px; }

.options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.opt {
  position: relative;
  display: grid;
  gap: 2px;
  justify-items: center;
  min-height: 78px;
  padding: 12px 10px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  color: var(--text);
  font: inherit;
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.opt:hover:not(:disabled) { border-color: var(--accent); }
.opt-key {
  position: absolute;
  top: 6px;
  left: 8px;
  color: var(--muted);
  font-size: 11px;
}
.opt-sa { font-size: 30px; line-height: 1.35; }
.opt-tr { color: var(--muted); font-size: 13px; }
.opt.is-right { border-color: var(--green); background: rgba(46, 196, 107, 0.16); }
.opt.is-wrong { border-color: var(--red); background: rgba(226, 59, 59, 0.16); }
.opt.is-hint { outline: 2px dashed var(--saffron); outline-offset: -4px; }

.feedback em { font-style: normal; color: var(--muted); }
.done-score { margin: 0 0 6px; font-size: 44px; font-weight: 800; letter-spacing: -1px; font-variant-numeric: tabular-nums; }

/* The two guides, one per input. The gate has to be !important: the blocks
   below carry their own display, which outranks a plain attribute selector
   and loses silently, showing both guides at once. */
.how { margin: 26px 0 0; padding: 16px 18px; border: 1px solid var(--line); border-radius: 14px; background: var(--panel); }
.how h3 { margin: 0 0 10px; font-size: 12px; letter-spacing: .6px; text-transform: uppercase; color: var(--muted); }
.how ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.how li { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; color: var(--muted); font-size: 14px; line-height: 1.5; }
.how kbd {
  display: inline-block;
  min-width: 24px;
  padding: 2px 7px;
  border: 1px solid #3a3a60;
  border-bottom-width: 2px;
  border-radius: 6px;
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  text-align: center;
}
@media (pointer: coarse) { .how[data-input="key"] { display: none !important; } }
@media (pointer: fine) { .how[data-input="touch"] { display: none !important; } }

@media (min-width: 620px) {
  .options { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 520px) {
  .level { grid-template-columns: auto minmax(0, 1fr); row-gap: 8px; }
  .stars, .level-best { grid-column: 2; justify-self: start; }
  .ask { font-size: 19px; }
  .opt-sa { font-size: 26px; }
}

/* ===================================================================
   The story of each tray: where it is, how the things arrive, and how
   each one answers a tap. The place is painted with gradients alone,
   so nothing is downloaded. Entrances use fill-mode backwards, so a
   thing is hidden during its own delay but the animation lets go of
   the button once it has landed - holding it would override the press
   feedback on .thing:active for the rest of the round.
   =================================================================== */
.story { display: block; margin-bottom: 2px; font-size: 14px; font-weight: 600; color: var(--muted); }

.tray[data-scene] { border-style: solid; overflow: hidden; }
.tray[data-scene="mango"] { background:
  radial-gradient(90% 60% at 50% -10%, #2f7544 0 55%, transparent 56%),
  linear-gradient(#1f3f2f, #2c2a1c); }
.tray[data-scene="fish"] { background:
  radial-gradient(60% 40% at 30% 30%, rgba(255, 255, 255, 0.08), transparent 70%),
  linear-gradient(#123a52, #0d5f6a); }
.tray[data-scene="star"] { background:
  radial-gradient(2px 2px at 12% 20%, #fff 50%, transparent 51%),
  radial-gradient(2px 2px at 78% 14%, #fff 50%, transparent 51%),
  radial-gradient(1.5px 1.5px at 44% 70%, #fff 50%, transparent 51%),
  linear-gradient(#0b0b26, #1d1740); }
.tray[data-scene="flower"] { background:
  linear-gradient(transparent 70%, #2f6b4f 70%), linear-gradient(#1a3350, #2a5a58); }
.tray[data-scene="drum"] { background:
  repeating-linear-gradient(90deg, rgba(242, 133, 28, 0.18) 0 18px, rgba(168, 119, 255, 0.18) 18px 36px),
  linear-gradient(#2a1840, #3a2030); }
.tray[data-scene="kite"] { background:
  radial-gradient(40% 30% at 80% 20%, rgba(255, 255, 255, 0.18), transparent 70%),
  linear-gradient(#2f7fd0, #9fd6ff); }
.tray[data-scene="leaf"] { background:
  linear-gradient(160deg, #3a2a1a, #5a4a2a); }
.tray[data-scene="bell"] { background:
  radial-gradient(70% 55% at 50% 0%, #6b3a1a 0 60%, transparent 61%),
  linear-gradient(#2a1a2a, #3a2230); }

.tray[data-scene] .thing { animation: enter-pop 0.6s ease-out backwards; animation-delay: var(--enter, 0ms); }
.tray[data-scene="mango"] .thing { animation-name: enter-drop; }
.tray[data-scene="fish"] .thing { animation-name: enter-swim; }
.tray[data-scene="star"] .thing { animation-name: enter-twinkle; }
.tray[data-scene="flower"] .thing { animation-name: enter-grow; transform-origin: 50% 100%; }
.tray[data-scene="kite"] .thing { animation-name: enter-float; animation-duration: 0.9s; }
.tray[data-scene="leaf"] .thing { animation-name: enter-drift; animation-duration: 0.9s; }
.tray[data-scene="bell"] .thing { animation-name: enter-swing; transform-origin: 50% 0; }
.tray[data-scene="drum"] .thing { animation-name: enter-bounce; }

.thing.is-poked svg { animation: poke-hop 0.45s ease-out; }
.tray[data-scene="fish"] .thing.is-poked svg { animation-name: poke-flip; }
.tray[data-scene="bell"] .thing.is-poked svg { animation-name: poke-ring; transform-origin: 50% 10%; }
.tray[data-scene="star"] .thing.is-poked svg { animation-name: poke-glint; }

@keyframes enter-pop { from { transform: scale(0.2); opacity: 0; } }
@keyframes enter-drop {
  0% { transform: translateY(-160px); opacity: 0; }
  60% { transform: translateY(0); opacity: 1; }
  75% { transform: translateY(-14px); }
  100% { transform: translateY(0); }
}
@keyframes enter-swim { 0% { transform: translateX(-120vw); opacity: 0; } 20% { opacity: 1; } }
@keyframes enter-twinkle { 0% { opacity: 0; transform: scale(0.3) rotate(-40deg); } 70% { transform: scale(1.2); opacity: 1; } }
@keyframes enter-grow { 0% { transform: scaleY(0); opacity: 0; } 60% { transform: scaleY(1.15); opacity: 1; } }
@keyframes enter-float {
  0% { transform: translate(40px, -200px) rotate(18deg); opacity: 0; }
  60% { transform: translate(-8px, 6px) rotate(-6deg); opacity: 1; }
}
@keyframes enter-drift {
  0% { transform: translate(-80px, -120px) rotate(-90deg); opacity: 0; }
  50% { transform: translate(20px, -30px) rotate(40deg); opacity: 1; }
}
@keyframes enter-swing {
  0% { transform: rotate(-60deg) translateY(-40px); opacity: 0; }
  50% { transform: rotate(20deg); opacity: 1; }
  75% { transform: rotate(-8deg); }
}
@keyframes enter-bounce {
  0% { transform: translateY(80px) scale(0.6); opacity: 0; }
  55% { transform: translateY(-12px) scale(1.05); opacity: 1; }
  80% { transform: translateY(0) scale(0.97); }
}
@keyframes poke-hop { 40% { transform: translateY(-8px) scale(1.12); } }
@keyframes poke-flip { 50% { transform: scaleX(-1) translateY(-4px); } }
@keyframes poke-ring { 25% { transform: rotate(18deg); } 50% { transform: rotate(-14deg); } 75% { transform: rotate(8deg); } }
@keyframes poke-glint { 50% { transform: scale(1.3) rotate(25deg); filter: brightness(1.5); } }

/* Someone who has asked for less motion still sees the things arrive one at a
   time, as a fade in place rather than a journey across the tray. Switching the
   story off entirely was the first version, and it hid the feature on any
   machine that reports reduced motion without its owner having asked for it -
   which the root CLAUDE.md records this office's own PCs doing. */
@media (prefers-reduced-motion: reduce) {
  .tray[data-scene] .thing { animation-name: enter-fade !important; animation-duration: 0.5s !important; }
  .thing.is-poked svg { animation: none !important; }
}
@keyframes enter-fade { from { opacity: 0; } }

/* THEME START - generated by tools/gen-theme.js, do not edit here */
/* Light theme. Every game was drawn dark first, and every one of them names
   its colours through the same handful of variables, so the light theme is
   mostly those variables redefined. What follows the variables are the few
   surfaces that carry a colour of their own. A game's own light fixes sit
   below the END marker, in that game's stylesheet. */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f4f4f8;
  --panel: #ffffff;
  --panel-2: #eceef6;
  --line: #d6d8e6;
  --text: #1c1c2b;
  --muted: #585a74;
  --accent: #4a4ae8;
  --amber: #b86a00;
  --teal: #0b8a80;
  --saffron: #c25f00;
  --green: #17864a;
  --red: #c42b2b;
  --rose: #c9365a;
}
:root[data-theme="light"] body { background: var(--bg); color: var(--text); }
:root[data-theme="light"] .topbar,
:root[data-theme="light"] .hud { background: rgba(255, 255, 255, 0.94); }
:root[data-theme="light"] .hud-btn[aria-pressed="true"] { color: #b3261e; border-color: rgba(179, 38, 30, 0.35); }
:root[data-theme="light"] .overlay { background: rgba(28, 28, 43, 0.45); }
:root[data-theme="light"] .modal,
:root[data-theme="light"] .panel,
:root[data-theme="light"] .intro-card,
:root[data-theme="light"] .done-card { background: var(--panel); box-shadow: 0 18px 50px rgba(28, 28, 60, 0.14); }
:root[data-theme="light"] .btn-primary { color: #fff; }
:root[data-theme="light"] kbd { background: var(--panel-2); color: var(--text); border-color: var(--line); }
:root[data-theme="light"] .beta { background: #fff4e5; border-color: #f0c48a; color: #5c3a0b; }
:root[data-theme="light"] .beta a { color: #8a4b00; }
:root[data-theme="light"] .feedback.is-right { color: #146b3a; }
:root[data-theme="light"] .feedback.is-wrong { color: #a4231f; }
:root[data-theme="light"] .foot-bar a,
:root[data-theme="light"] .cross a { color: #0b7a71; }
:root[data-theme="light"] .foot-steps a.is-here .step-n { color: #fff; }

/* The toggle itself: a sun in the dark, a moon in the light, so it always
   shows what pressing it will do - the icon alone says that, so the label
   is announced to a screen reader (title/aria-label, set in the script
   below) rather than spelled out next to it on every single page. */
.theme-toggle { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.theme-toggle svg { width: 16px; height: 16px; flex: 0 0 auto; }
.theme-toggle .ico-moon { display: none; }
:root[data-theme="light"] .theme-toggle .ico-sun { display: none; }
:root[data-theme="light"] .theme-toggle .ico-moon { display: inline; }
.theme-toggle .theme-label {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* The Play button. Every game's way into play is the same button: the widest,
   tallest thing on its start screen, with a play triangle, so nobody has to
   work out which of the options starts the game. It lives in this block
   because this block already goes into every game. */
.btn-play:not([hidden]) {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex: 1 1 auto;
  min-height: 54px !important;
  font-size: 17px !important;
  font-weight: 700;
  letter-spacing: 0.2px;
  box-shadow: 0 8px 22px rgba(74, 74, 232, 0.35);
}
/* On a Sanskrit start screen it is the whole width of the card. */
.intro-card .btn-play:not([hidden]) { display: flex !important; width: 100%; margin-top: 6px; }
.btn-play::before {
  content: "";
  width: 14px;
  height: 16px;
  flex: 0 0 auto;
  background: currentColor;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}
.btn-play:focus-visible { outline: 3px solid #ffd166; outline-offset: 3px; }
@media (prefers-reduced-motion: no-preference) {
  .btn-play { animation: btn-play-glow 2.4s ease-in-out infinite; }
  .btn-play:hover, .btn-play:focus-visible { animation: none; }
}
@keyframes btn-play-glow {
  0%, 100% { box-shadow: 0 8px 22px rgba(74, 74, 232, 0.35); }
  50% { box-shadow: 0 8px 30px rgba(74, 74, 232, 0.6); }
}
/* THEME END */

/* COMPACT PANELS (13/10/2026): start, pause and result panels use less room. Paddings and
   type only; buttons and their 12px spacing are left to the rules above. */
.overlay .modal-head, .overlay .panel-head, .overlay .m-head { padding-top: 10px; padding-bottom: 6px; }
.overlay .modal-head h1, .overlay .panel-head h1 { font-size: 20px; line-height: 1.15; }
.overlay .modal-head h2, .overlay .panel-head h2, .overlay .m-head h2 { font-size: 16px; }
.overlay .modal-body, .overlay .panel-body, .overlay .m-body { padding-top: 4px; padding-bottom: 10px; }
.overlay .modal-body p, .overlay .panel-body p, .overlay .m-body p { margin-bottom: 8px; font-size: 13.5px; line-height: 1.45; }
.overlay .modal-body h2, .overlay .panel-body h2, .overlay .modal-body h3, .overlay .panel-body h3 { margin-top: 10px; margin-bottom: 6px; }
.overlay .modal-foot, .overlay .panel-foot, .overlay .m-foot { padding-top: 8px; padding-bottom: 8px; }

/* A double tap must never zoom the page: manipulation allows scrolling and
   pinching but not the double tap zoom. On html it covers every element. */
html { touch-action: manipulation; }
