/* ============================================================
   Chronos Grid
   Dark by default. One column, thumb-reachable, no page scroll
   while a tile is in hand.
   ============================================================ */

:root {
  --bg:        #07070b;
  --bg-2:      #0d0e14;
  --surface:   #14161f;
  --surface-2: #1b1e2a;
  --line:      #262a38;
  --ink:       #eef0f7;
  --ink-dim:   #9aa0b4;
  --ink-faint: #626983;

  --hit:   #2fbf71;
  --near:  #d9a441;
  --miss:  #b3384a;
  --accent:#7c6cf5;
  --accent-soft: rgba(124, 108, 245, .16);

  --tile-radius: 12px;
  --pad: clamp(12px, 3.6vw, 20px);
  --grid-gap: clamp(5px, 1.6vw, 10px);

  --shadow-lift: 0 18px 40px -12px rgba(0, 0, 0, .75);
  --ease: cubic-bezier(.2, .8, .2, 1);

  --theme-bg: none;
  --theme-bg-opacity: 0;
}

/* House theme for hoodgrimoireproductions.com: the site's own gold-on-black,
   Courier body / condensed headings. Set data-theme="grimoire" on <html>. */
[data-theme="grimoire"] {
  --bg:        #07070a;
  --bg-2:      #0c0c10;
  --surface:   #121116;
  --surface-2: #1a1820;
  --line:      #2a2318;
  --ink:       #e6dfd0;
  --ink-dim:   #a89c86;
  --ink-faint: #6f6553;
  --accent:    #d9a326;
  --accent-soft: rgba(217, 163, 38, .14);
  --hit:  #7f9c3a;
  --near: #d9a326;
  --miss: #8c2f2f;
  --tile-radius: 3px;
}
[data-theme="grimoire"] body,
[data-theme="grimoire"] .btn,
[data-theme="grimoire"] .tile { font-family: "Courier New", Consolas, ui-monospace, monospace; }
[data-theme="grimoire"] .wordmark,
[data-theme="grimoire"] .theme,
[data-theme="grimoire"] .results-title,
[data-theme="grimoire"] .modal-card h2 {
  font-family: "Franklin Gothic Medium", "Arial Narrow", Haettenschweiler, Impact, system-ui, sans-serif;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--accent);
}
[data-theme="grimoire"] .btn-primary { color: #16130a; font-weight: 700; }
/* Courier sets much wider than Inter, so every tile steps down a size to keep
   long entries from breaking mid-word. */
[data-theme="grimoire"] .tile        { font-size: clamp(9px, 2.75vw, 13.5px); }
[data-theme="grimoire"] .tile.long   { font-size: clamp(8.4px, 2.55vw, 12.5px); }
[data-theme="grimoire"] .tile.longer { font-size: clamp(7.4px, 2.35vw, 11.5px); letter-spacing: -.02em; }
[data-theme="grimoire"] .tile.longest { font-size: clamp(6.8px, 2.1vw, 10.5px); letter-spacing: -.03em; }
@container board (min-width: 0px) {
  [data-theme="grimoire"] .tile         { font-size: clamp(7.6px, 2.85cqi, 19px); }
  [data-theme="grimoire"] .tile.long    { font-size: clamp(7.2px, 2.59cqi, 17px); }
  [data-theme="grimoire"] .tile.longer  { font-size: clamp(6.6px, 2.30cqi, 15.5px); }
  [data-theme="grimoire"] .tile.longest { font-size: clamp(6px, 2.05cqi, 14px); letter-spacing: -.03em; }
}
[data-theme="grimoire"] body::after {
  background: radial-gradient(120% 70% at 50% -10%, rgba(217, 163, 38, .09), transparent 62%);
}
[data-theme="grimoire"] .btn,
[data-theme="grimoire"] .status-strip,
[data-theme="grimoire"] .results,
[data-theme="grimoire"] .modal-card { border-radius: 3px; }

/* Unlockable Higgsfield themes: drop the generated art in and flip data-theme. */
[data-theme="nebula"]     { --theme-bg: url('assets/higgsfield/themes/nebula-void.jpg');       --theme-bg-opacity: .38; --accent: #8f7cff; }
[data-theme="brutalist"]  { --theme-bg: url('assets/higgsfield/themes/brutalist-concrete.jpg'); --theme-bg-opacity: .22; --accent: #c9c4b4; }
[data-theme="neon"]       { --theme-bg: url('assets/higgsfield/themes/neon-grid.jpg');          --theme-bg-opacity: .30; --accent: #2ee6c0; }

* { box-sizing: border-box; }

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

body {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  overscroll-behavior-y: none;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

/* Premium theme wash sits behind everything, never under the text contrast. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background-image: var(--theme-bg);
  background-size: cover;
  background-position: center;
  opacity: var(--theme-bg-opacity);
  pointer-events: none;
  z-index: 0;
}
body::after {
  content: "";
  position: fixed;
  inset: 0;
  background: radial-gradient(120% 70% at 50% -10%, rgba(124, 108, 245, .10), transparent 60%);
  pointer-events: none;
  z-index: 0;
}
body > * { position: relative; z-index: 1; }

/* Locks the page while a tile is being dragged. */
body.dragging { touch-action: none; user-select: none; -webkit-user-select: none; cursor: grabbing; }

/* ---------- Top bar ---------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px var(--pad);
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(10px);
}
.topbar-right { display: flex; gap: 2px; }

.wordmark {
  margin: 0;
  font-size: clamp(15px, 4.2vw, 19px);
  font-weight: 750;
  letter-spacing: .16em;
  white-space: nowrap;
}
.wordmark span { color: var(--accent); }

.icon-btn {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  transition: background .18s var(--ease), color .18s var(--ease);
}
.icon-btn:hover { background: var(--surface); color: var(--ink); }
.icon-btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.icon-btn[aria-pressed="false"] .wave { display: none; }
.icon-btn[aria-pressed="false"] { color: var(--ink-faint); }

/* ---------- Layout ---------- */

#app {
  flex: 1;
  width: 100%;
  /* The grid is square, so column width IS tile size IS type size. 560px
     capped every tile at 128px, which is what forced the 12px ceiling on the
     labels. Widened, then widened again only where there is vertical room --
     as a media query rather than a dvh calc, so a viewport that reports zero
     height (hidden tab, print, some embeds) cannot collapse the column. */
  max-width: 640px;
  margin: 0 auto;
  padding: clamp(10px, 2.6vw, 18px) var(--pad) 8px;
  display: flex;
  flex-direction: column;
}

.puzzle-head { text-align: center; }
.meta-row { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; }

.chip {
  font-size: 11px;
  letter-spacing: .09em;
  text-transform: uppercase;
  font-weight: 650;
  padding: 4px 9px;
  border-radius: 99px;
  background: var(--accent-soft);
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
}
.chip-ghost { background: transparent; color: var(--ink-faint); border-color: var(--line); }

.theme {
  margin: 10px 0 4px;
  font-size: clamp(19px, 5.6vw, 26px);
  font-weight: 700;
  letter-spacing: -.015em;
  line-height: 1.15;
}
.blurb { margin: 0; color: var(--ink-dim); font-size: clamp(12px, 3.4vw, 14px); }

.archive-banner {
  margin: 10px 0 0;
  padding: 7px 10px;
  border-radius: 9px;
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink-dim);
  font-size: 12px;
}

/* ---------- Status strip ---------- */

.status-strip {
  display: grid;
  /* Four items. At three columns the fourth wrapped onto a row of its own and
     left two empty cells showing through as a dead slab. */
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  margin: 14px 0 12px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
}
.status-item {
  background: var(--bg-2);
  padding: 8px 4px;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.status-label { font-size: 10px; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-faint); }
.status-value { font-size: 18px; font-weight: 700; font-variant-numeric: tabular-nums; }
.status-value.warn { color: var(--near); }
.status-value.spent { color: var(--miss); }

/* ---------- Grid ---------- */

.grid-wrap { position: relative; }

.axis {
  font-size: 9.5px;
  letter-spacing: .18em;
  color: var(--ink-faint);
  text-align: center;
  padding: 3px 0;
}
.axis-start { text-align: left; }
.axis-end { text-align: right; }

.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 1fr;
  gap: var(--grid-gap);
  aspect-ratio: 1 / 1;
  width: 100%;
  /* Lets tile type scale with the board instead of the viewport. Below 560px
     the two track each other anyway; above it, only this keeps growing. */
  container-type: inline-size;
  container-name: board;
}

.tile {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: clamp(3px, 1.4vw, 8px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--tile-radius);
  color: var(--ink);
  /* Fallback for browsers without container queries; overridden below. */
  font-size: clamp(10px, 3.1vw, 15px);
  line-height: 1.28;
  font-weight: 540;
  cursor: grab;
  overflow: hidden;
  /* Kills mobile scroll-hijack and the iOS text-callout while dragging. */
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  transition: transform .17s var(--ease), background .17s var(--ease),
              border-color .17s var(--ease), box-shadow .17s var(--ease);
}
.tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tile .label {
  display: -webkit-box;
  -webkit-line-clamp: 6;
  line-clamp: 6;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
  hyphens: auto;
}
/* Long entries step down a notch so nothing clips on a 320px screen. */
.tile.long    { font-size: clamp(9.2px, 2.85vw, 13.5px); }
.tile.longer  { font-size: clamp(8.4px, 2.6vw, 12.4px); line-height: 1.22; }
.tile.longest { font-size: clamp(7.6px, 2.4vw, 11.5px); line-height: 1.18; }

/* 4 columns of 1cqi each, minus the gaps: one tile is very close to 24cqi.
   Sizing the label in cqi means the type grows with the board on every screen
   and stops being a function of how wide the browser window happens to be.

   Corner gutters only above 440px of board. On a 320px phone a tile is 70px
   and the "?" badge is a third of it: reserving a clear row for the badge and
   the arrow costs more label height than it buys legibility, and the label is
   what the player is reading. Below the threshold the corners overlap the text
   slightly, exactly as they always have. */
@container board (min-width: 440px) {
  .tile {
    padding: clamp(16px, 4.6cqi, 30px) clamp(5px, 1.6cqi, 10px) clamp(11px, 3.2cqi, 21px);
  }
}

@container board (min-width: 0px) {
  .tile         { font-size: clamp(8.2px, 3.10cqi, 21px); }
  .tile.long    { font-size: clamp(7.8px, 2.82cqi, 19px); }
  .tile.longer  { font-size: clamp(7.2px, 2.54cqi, 17.5px); }
  .tile.longest { font-size: clamp(6.6px, 2.30cqi, 16px); }
}

.tile.picked  { border-color: var(--accent); background: var(--surface-2); box-shadow: 0 0 0 1px var(--accent) inset; }
.tile.dragging-src { opacity: .28; }
.tile.drop-target { border-color: var(--accent); transform: scale(.965); background: var(--surface-2); }

.tile.hit   { background: color-mix(in srgb, var(--hit) 20%, var(--surface));  border-color: var(--hit); }
.tile.near  { background: color-mix(in srgb, var(--near) 18%, var(--surface)); border-color: var(--near); }
.tile.miss  { background: color-mix(in srgb, var(--miss) 16%, var(--surface)); border-color: var(--miss); }

.tile.locked { cursor: not-allowed; background: color-mix(in srgb, var(--hit) 24%, var(--surface)); border-color: var(--hit); }
.tile.locked::after {
  content: "";
  position: absolute; top: 4px; right: 4px;
  width: 9px; height: 11px;
  border: 1.4px solid var(--hit);
  border-radius: 2px;
  box-shadow: inset 0 -3px 0 -1px var(--hit);
  opacity: .85;
}
.tile.locked::before {
  content: "";
  position: absolute; top: 1.5px; right: 6px;
  width: 5px; height: 5px;
  border: 1.4px solid var(--hit);
  border-bottom: 0;
  border-radius: 3px 3px 0 0;
  opacity: .85;
}

/* ---------- Direction cue ----------
   A bare red square says "not here" about one slot in sixteen. The arrow says
   which half of the grid the event actually lives in, which is what turns a
   check into progress instead of a coin flip. Its own element rather than a
   pseudo-element: .tile::before and ::after are both already the lock glyph. */

.tile .dir {
  position: absolute;
  right: 4px;
  bottom: 2px;
  /* Scales with the board like the label does, so it reads at the same weight
     on a phone and on a monitor. */
  font-size: clamp(13px, 4.4cqi, 26px);
  font-weight: 700;
  line-height: 1;
  opacity: 0;
  pointer-events: none;
  transition: opacity .16s var(--ease);
}
.tile.dir-earlier .dir,
.tile.dir-later .dir { opacity: 1; }
.tile.near .dir { color: color-mix(in srgb, var(--near) 88%, white); }
.tile.miss .dir { color: color-mix(in srgb, var(--miss) 55%, white); }

/* ---------- Encyclopedia badge ---------- */

.tile-ask {
  position: absolute;
  top: 0; left: 0;
  /* Was 26px at .55 opacity in --ink-faint: under the 44px touch minimum and
     barely visible, so a thumb aiming for it started a swap instead. That is
     what "the hint doesn't work" was. Now a legible chip with a hit area that
     spills past its own box. */
  width: clamp(24px, 6.0cqi, 32px);
  height: clamp(24px, 6.0cqi, 32px);
  padding: 0;
  border: 0;
  background: var(--accent-soft);
  color: var(--accent);
  font: inherit;
  font-size: clamp(13px, 3.6cqi, 18px);
  font-weight: 800;
  line-height: 1;
  cursor: help;
  opacity: .9;
  border-radius: var(--tile-radius) 0 10px 0;
  display: grid;
  place-items: center;
  z-index: 2;
  transition: opacity .16s var(--ease), color .16s var(--ease), background .16s var(--ease);
}
.tile-ask:hover, .tile-ask:focus-visible {
  opacity: 1;
  color: var(--bg);
  background: var(--accent);
}
.tile-ask:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.grid.lookups-spent .tile-ask { opacity: .2; }
.tile.locked .tile-ask { display: none; }

.context-kicker {
  display: inline-block;
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 6px;
}
.context-body { margin: 0; font-size: 14px; line-height: 1.6; color: var(--ink); }
.context-note { margin: 12px 0 0; font-size: 11.5px; color: var(--ink-faint); }
#context-date.revealed { color: var(--hit); font-variant-numeric: tabular-nums; }

/* ---------- Mode switch ---------- */

.status-mode { justify-content: center; }
.mode-btn {
  margin-top: 1px;
  padding: 3px 10px;
  border-radius: 99px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: background .16s var(--ease), border-color .16s var(--ease);
}
.mode-btn:hover:not(:disabled) { background: var(--surface-2); border-color: var(--accent); }
.mode-btn:disabled { opacity: .5; cursor: default; }

/* ---------- Close-win tension ---------- */

@keyframes closeWinPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(217, 164, 65, 0); }
  50%      { box-shadow: 0 0 26px 3px rgba(217, 164, 65, .38); }
}
.grid.close-win {
  animation: closeWinPulse 1.4s var(--ease) infinite;
  border-radius: var(--tile-radius);
}
.grid.close-win .tile { border-color: color-mix(in srgb, var(--near) 45%, var(--line)); }

@keyframes btnPulse {
  0% { transform: scale(1); }
  40% { transform: scale(.96); }
  100% { transform: scale(1); }
}
.btn.pulse { animation: btnPulse .26s var(--ease); }

/* ---------- Score ---------- */

.score-box {
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 10px 13px;
  margin: 0 0 12px;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--line));
  border-radius: 11px;
  background: var(--accent-soft);
}
.score-box b { font-size: 24px; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.score-box span { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-dim); }

.stat-grid-2 { grid-template-columns: repeat(3, 1fr); margin-top: -8px; }
.stat-grid-2 b { font-size: 18px; }

.timeline-hint { margin: 0 0 6px; font-size: 11px; color: var(--ink-faint); }

.grid.over .tile { cursor: default; }
.tile.reveal { background: var(--surface-2); border-color: var(--line); }
.tile .stamp {
  display: block;
  margin-top: 3px;
  font-size: .82em;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

@keyframes pop { 0% { transform: scale(1); } 45% { transform: scale(1.07); } 100% { transform: scale(1); } }
.tile.flash { animation: pop .34s var(--ease); }

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-5px); }
  40% { transform: translateX(5px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(3px); }
}
.grid.shake { animation: shake .38s var(--ease); }

/* The element that actually follows the finger. */
.drag-ghost {
  position: fixed;
  z-index: 60;
  pointer-events: none;
  border-radius: var(--tile-radius);
  box-shadow: var(--shadow-lift);
  transform: scale(1.06);
  opacity: .96;
  border: 1px solid var(--accent);
}

.hint-line {
  margin: 10px 0 0;
  text-align: center;
  color: var(--ink-faint);
  font-size: 12px;
  min-height: 1.2em;
}

/* ---------- Buttons ---------- */

.actions { display: flex; gap: 8px; margin: 14px 0 6px; }

.btn {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 48px;
  padding: 0 16px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-weight: 640;
  font-size: 14px;
  cursor: pointer;
  transition: transform .12s var(--ease), background .18s var(--ease), opacity .18s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .42; cursor: not-allowed; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover:not(:disabled) { filter: brightness(1.08); }
.btn-ghost:hover:not(:disabled) { background: var(--surface-2); }
.btn-wide { width: 100%; flex: none; margin-top: 10px; }
.btn-ico { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- Results ---------- */

.results {
  margin-top: 16px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--bg-2);
}
.results-title { margin: 0; font-size: 20px; letter-spacing: -.01em; }
.results-sub { margin: 5px 0 12px; color: var(--ink-dim); font-size: 13px; }

.timeline { list-style: none; margin: 0 0 4px; padding: 0; max-height: 42vh; overflow-y: auto; }
.timeline li {
  padding: 8px 2px;
  border-bottom: 1px solid var(--line);
  font-size: 12.5px;
  cursor: pointer;
}
.timeline li:hover { background: var(--surface); }
.tl-head {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  gap: 8px;
  align-items: baseline;
}
.tl-context {
  margin: 4px 0 0 30px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--ink-faint);
}
.timeline li:last-child { border-bottom: 0; }
.timeline .rank { color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.timeline .when { color: var(--ink-dim); white-space: nowrap; font-variant-numeric: tabular-nums; font-size: 11.5px; }
.timeline li.was-right .rank { color: var(--hit); }

.next-drop { margin-top: 12px; text-align: center; color: var(--ink-dim); font-size: 13px; }
.mono { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--ink); letter-spacing: .04em; }

/* ---------- Footer ---------- */

.footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px var(--pad) 18px;
  color: var(--ink-faint);
  font-size: 11px;
}
.time-source { letter-spacing: .04em; }
.time-source.verified { color: var(--hit); }
.time-source.suspect { color: var(--near); }
.linkish { background: 0; border: 0; color: var(--accent); font: inherit; cursor: pointer; padding: 0; text-decoration: none; }
.linkish:hover { text-decoration: underline; }

/* ---------- Modals ---------- */

/* NOTE: this scrim deliberately does NOT use backdrop-filter.
   Chromium composites a backdrop-filter layer into its own "backdrop root";
   with the blurred .topbar also on screen, a modal revealed in the same frame
   (hidden -> display:grid) was painted *underneath* that root and vanished --
   the help/ad cards showed as a blurred, empty screen. A flat, slightly
   heavier wash reads the same and always paints. */
.scrim { position: fixed; inset: 0; background: rgba(3, 4, 8, .86); z-index: 40; }

/* The scrim already covers the bar at .86, so its blur buys nothing while a
   modal is open -- and dropping it removes the second full-screen blur layer
   that triggered the compositing fault above. */
body.modal-open .topbar { backdrop-filter: none; -webkit-backdrop-filter: none; }

.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: var(--pad);
  overflow-y: auto;
}
.modal[hidden] { display: none; }
.modal-card {
  position: relative;
  width: 100%;
  max-width: 430px;
  max-height: 88dvh;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 22px;
  box-shadow: var(--shadow-lift);
  animation: rise .22s var(--ease);
}
@keyframes rise { from { opacity: 0; transform: translateY(10px); } }
.modal-card h2 { margin: 0 0 6px; font-size: 20px; }
.modal-sub { margin: 0 0 14px; color: var(--ink-dim); font-size: 13px; }
.modal-close {
  position: absolute; top: 10px; right: 10px;
  width: 32px; height: 32px;
  border: 0; border-radius: 8px;
  background: transparent; color: var(--ink-dim);
  font-size: 22px; line-height: 1; cursor: pointer;
}
.modal-close:hover { background: var(--surface); color: var(--ink); }

.rules { margin: 12px 0; padding-left: 18px; color: var(--ink-dim); font-size: 13px; line-height: 1.65; }
.rules strong { color: var(--ink); }
.sw { display: inline-block; width: 13px; height: 13px; border-radius: 4px; vertical-align: -2px; }
.sw-hit { background: var(--hit); } .sw-near { background: var(--near); } .sw-miss { background: var(--miss); }

.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 8px 0 18px; text-align: center; }
.stat-grid b { display: block; font-size: 22px; font-variant-numeric: tabular-nums; }
.stat-grid span { font-size: 10px; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-faint); }

.dist-title { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); margin: 0 0 8px; font-weight: 600; }
.dist { display: flex; flex-direction: column; gap: 5px; }
.dist-row { display: grid; grid-template-columns: 14px 1fr; gap: 8px; align-items: center; font-size: 12px; }
.dist-bar { background: var(--accent); color: #fff; border-radius: 4px; padding: 2px 6px; text-align: right; min-width: 26px; font-variant-numeric: tabular-nums; }
.dist-bar.zero { background: var(--surface-2); color: var(--ink-faint); }

.archive-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.archive-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%;
  padding: 11px 13px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 11px;
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
.archive-row:hover { background: var(--surface-2); }
/* A grid still inside the catch-up window is an invitation, not a gap. */
.archive-row.catchup { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.archive-row.catchup .a-flag { color: var(--accent); }
.archive-banner.catchup { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.archive-row .a-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.archive-row .a-theme { font-weight: 640; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.archive-row .a-meta { font-size: 11px; color: var(--ink-faint); }
.archive-row .a-flag { font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); white-space: nowrap; }
.archive-row.today .a-flag { color: var(--accent); }
.archive-row.done .a-flag { color: var(--hit); }
.archive-row.locked { opacity: .72; }

.pass-state { font-size: 13px; color: var(--hit); margin: 10px 0 0; min-height: 1.2em; }
.fineprint { margin: 10px 0 0; font-size: 11px; color: var(--ink-faint); line-height: 1.5; }

.ad-slot {
  display: grid; place-items: center; gap: 12px;
  height: 140px;
  border: 1px dashed var(--line);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink-faint);
  font-size: 12px;
  text-align: center;
  padding: 14px;
}
.ad-progress { width: 100%; height: 4px; background: var(--surface-2); border-radius: 99px; overflow: hidden; }
.ad-progress i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .2s linear; }

/* ---------- Toast ---------- */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(22px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 70;
  padding: 11px 17px;
  border-radius: 11px;
  background: var(--ink);
  color: var(--bg);
  font-size: 13px;
  font-weight: 640;
  box-shadow: var(--shadow-lift);
  animation: rise .2s var(--ease);
  max-width: min(88vw, 380px);
  text-align: center;
}

/* ---------- Small screens (iPhone SE and friends) ---------- */

@media (min-height: 860px) and (min-width: 800px) {
  #app { max-width: 760px; }
}

@media (max-height: 700px) {
  .blurb { display: none; }
  .theme { font-size: clamp(17px, 5vw, 21px); margin-top: 8px; }
  .status-strip { margin: 10px 0 8px; }
}
@media (max-width: 340px) {
  .status-value { font-size: 16px; }
  .btn { font-size: 13px; min-height: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
