/* SumHunt — prose pages (CR-057).
   Loaded AFTER styles.css, which owns every token; nothing here invents a value.

   WHY A SEPARATE FILE rather than appending to styles.css: styles.css is 863 lines against a
   1,000-line hard cap, and these rules are only ever needed by the content pages — shipping them
   to the game surface would be dead weight on the one page whose load time matters most.

   AMBER IS RESERVED (DESIGN.md §1). It marks the dial, the active operator, the current selection
   and warm-letter feedback — not decoration. The only amber below is on example chips and tile
   value badges, which is the exact precedent .help-eg already sets. */

/* shell ---------------------------------------------------------------------
   Same ivory card on the same sand ground as the game, widened to a readable
   measure. 680px holds ~72 characters at 15.5px, which is inside the 45-75
   range prose wants; the game card's 432px would set a 40-character column. */
.card.prose { width: min(680px, 100%); padding: 30px 30px 34px; }
@media (max-width: 520px) { .card.prose { padding: 24px 20px 28px; } }

/* The content header reuses .topbar/.brand/.wordmark verbatim; only the right-hand
   slot differs — the game has ?/day/streak, a prose page has one way back to play. */
.prose .topbar { align-items: center; padding-bottom: 20px; border-bottom: 1px solid var(--line-2); }
/* .btn.primary carries `flex: 1.2` for the board's button row and out-specifies a lone class,
   which stretched this CTA across the whole header. Matched specificity, not !important. */
.prose .btn.back-to-play { flex: none; white-space: nowrap; padding: 9px 16px; font-size: 13.5px; }

/* type ----------------------------------------------------------------------
   One serif display size for h1, one for h2. Body is Outfit at a longer measure
   and a looser line-height than the game UI, which is all short labels. */
.prose h1 {
  margin: 26px 0 0; font-family: var(--display); font-weight: 400;
  font-size: clamp(34px, 7vw, 46px); line-height: 1.05; letter-spacing: .2px; color: var(--ink);
}
.prose .lede {
  margin: 14px 0 0; font-family: var(--display); font-style: italic;
  font-size: clamp(17px, 3.4vw, 20px); line-height: 1.45; color: var(--muted);
}
.prose h2 {
  margin: 38px 0 0; font-family: var(--display); font-weight: 400;
  font-size: 27px; line-height: 1.15; color: var(--ink);
}
.prose h3 { margin: 24px 0 0; font: 600 15px var(--ui); letter-spacing: .01em; color: var(--ink); }
.prose p { margin: 12px 0 0; font-size: 15.5px; line-height: 1.65; color: var(--ink-soft); }
.prose p.small { font-size: 13.5px; color: var(--muted); }
.prose a:not(.btn) { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 2px; }
.prose a.btn { text-decoration: none; }
.prose a:hover { color: var(--accent-deeper); }
.prose b, .prose strong { font-weight: 600; color: var(--ink); }

/* Lists align on a FIXED gutter, never on the marker's own width — DESIGN.md §3.1.
   Serif numerals measure 5–8.1px, so a marker without a set width starts every row
   at a different x. This is the B-037 rule applied to prose. */
.prose ul { margin: 12px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 9px; }
.prose ul li { position: relative; padding-left: 25px; font-size: 15.5px; line-height: 1.6; color: var(--ink-soft); }
.prose ul li::before { content: "✦"; position: absolute; left: 0; top: 0; width: 14px; color: var(--accent-label); font-size: 12px; line-height: 1.7; }

/* worked example ------------------------------------------------------------
   A static row of ceramic tiles: the fastest way to show what the game IS without
   asking anyone to read a rule. Mirrors .tile's face, border and letterpress shadow,
   but at a fixed size — .tile sizes from container queries the board provides. */
.eg-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin-top: 16px; }
.eg-tile {
  position: relative; width: 42px; height: 46px; border-radius: var(--r-tile);
  display: grid; place-items: center;
  font-family: var(--display); font-size: 22px; color: var(--ink);
  background: var(--tile); border: 1px solid var(--line-tile); box-shadow: var(--sh-tile);
}
.eg-tile .val { position: absolute; bottom: 4px; right: 5px; font: 600 9.5px var(--ui); color: var(--muted); }
.eg-op { font-family: var(--display); font-size: 21px; color: var(--accent-deep); padding: 0 3px; }
.eg-sum { font: 600 14px var(--ui); color: var(--muted); margin-left: 4px; font-variant-numeric: tabular-nums; }
.eg-cap { margin-top: 9px; font-size: 13.5px; color: var(--muted); }

/* soft panel — the .clue-card shape, reused for callouts and FAQ answers */
.panel {
  margin-top: 18px; padding: 16px 18px;
  background: var(--soft); border: 1px solid var(--soft-border); border-radius: var(--r-btn);
}
.panel p:first-child { margin-top: 0; }

/* FAQ -----------------------------------------------------------------------
   Plain headings and paragraphs, NOT <details>. An answer collapsed behind a
   summary is still in the DOM, but the question/answer pairing is what makes the
   text quotable, and open-by-default is also simply easier to read. */
.faq { margin-top: 8px; }
.faq dt { margin-top: 22px; font: 600 16px var(--ui); color: var(--ink); }
.faq dd { margin: 8px 0 0; font-size: 15.5px; line-height: 1.65; color: var(--ink-soft); }

/* archive list (CR-058) ------------------------------------------------------
   Its OWN component, and the reason is a bug rather than taste. The first cut
   reused .more-links, which is a centred horizontal row of pills for the
   cross-links at the foot of a prose page — wrong shape for a vertical dated
   list, and it rendered a DOUBLE underline: .more-links a sets
   text-decoration:none with a border-bottom, but .prose a:not(.btn) is more
   specific (0-2-1 against 0-1-1) so its underline won AND the border still
   drew. Two lines under every entry. Reusing a component whose own rules lose
   to their container is not reuse.
   One line per day: the date and variant as the link, the clue after it in
   quieter text, so the column scans by date. */
.archive-list { margin: 10px 0 0; padding: 0; list-style: none; }
.archive-list li {
  padding: 11px 0; border-bottom: 1px solid var(--line-2);
  font-size: 15px; line-height: 1.55; color: var(--ink-soft);
}
.archive-list li:last-child { border-bottom: 0; }
.archive-list a { font-weight: 600; text-underline-offset: 2px; }
.archive-list .al-clue { display: block; margin-top: 2px; color: var(--muted); font-size: 14.5px; }
/* AEO_AUDIT 5.15: the day's answer, published on the index as well as the per-day page. Tabular
   figures so the numbers form a column down the list rather than jittering line to line. */
.archive-list .al-answer { display: block; margin-top: 3px; color: var(--ink-soft); font-size: 13.5px;
  font-variant-numeric: tabular-nums; }

/* comparison table ----------------------------------------------------------
   Scrolls inside its own container so a wide table can never push the page
   sideways — the same containment rule the responsive harness asserts. */
.cmp-wrap { margin-top: 18px; overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-btn); }
.cmp { width: 100%; border-collapse: collapse; font-size: 14.5px; }
.cmp th, .cmp td { padding: 11px 14px; text-align: left; border-bottom: 1px solid var(--line-2); vertical-align: top; }
.cmp thead th { background: var(--soft); font: 600 13px var(--ui); letter-spacing: .02em; color: var(--ink); white-space: nowrap; }
.cmp tbody th { font: 600 14.5px var(--ui); color: var(--ink); white-space: nowrap; }
.cmp td { color: var(--ink-soft); }
.cmp tbody tr:last-child th, .cmp tbody tr:last-child td { border-bottom: 0; }
.cmp .is-us { background: var(--inset); }

/* closing call to action ----------------------------------------------------
   Every prose page ends by offering the game. The point of the page is to be
   found; the point of being found is that someone plays. */
.cta-end { margin-top: 40px; padding-top: 26px; border-top: 1px solid var(--line-2); text-align: center; }
.cta-end .cta-line { font-family: var(--display); font-size: 24px; line-height: 1.2; color: var(--ink); }
.cta-end .btn { margin: 16px auto 0; display: inline-flex; align-items: center; justify-content: center; padding: 13px 26px; font-size: 15px; }
.cta-end .cta-sub { margin-top: 10px; font-size: 13px; color: var(--faint); }

/* cross-links between prose pages */
.more-links { margin-top: 26px; display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.more-links a { font-size: 13.5px; color: var(--muted); text-decoration: none; border-bottom: 1px solid var(--line-strong); padding-bottom: 1px; }
.more-links a:hover { color: var(--accent-deep); border-color: var(--accent); }

/* ------------------------------------------------------------------------- */
/* Homepage prose block.
   SITS OUTSIDE .page, as its own sibling in the body. That placement is deliberate
   rather than incidental: .page is `min-height:100dvh` with a flex context the board
   depends on, so appending a second child would have put this beside the card and
   changing .page's direction would have altered the game's own layout container —
   the one CR-017 is still fighting to fit on a phone. A sibling after a 100dvh block
   lands below the fold by construction and touches none of it.
   Kept SHORT on purpose. The full articles are /how-to-play and /games-like-wordle;
   this is the part a crawler needs and a curious player might read, not a wall. */
.below { padding: 0 16px 44px; }
.about {
  width: min(680px, 100%); margin: 0 auto;
  background: var(--card); border-radius: var(--r-card);
  box-shadow: 0 30px 70px -30px rgba(60,45,20,.5), 0 2px 0 #fff inset;
  padding: 28px 26px 30px;
}
@media (max-width: 520px) { .about { padding: 22px 18px 24px; } }
.about h2:first-child { margin-top: 0; }
.about .faq dt:first-of-type { margin-top: 14px; }

/* site footer ---------------------------------------------------------------
   ONE navigation, in one place, on every page.
   DESIGN CALL, and the reasoning matters more than the markup: /how-to-play is
   player-relevant and therefore earns a route from the help sheet, where someone
   already goes to learn the game. /games-like-wordle is a LANDING page for search
   traffic — a player already on the site has no need of it, so promoting it into
   the board would be adding chrome to the game surface to serve a crawler. That is
   the trade this footer refuses to make. It gives both pages a real, crawlable,
   consistent internal link without putting a single pixel above the give-up link,
   which CR-017 is still fighting for.
   Not a card: nested cards are always wrong (DESIGN.md §3.6). It sits quietly on
   the sand ground, which is what a footer should do. */
.site-foot { width: min(680px, 100%); margin: 24px auto 0; text-align: center; }
.site-foot nav { display: flex; flex-wrap: wrap; gap: 8px 20px; justify-content: center; }
.site-foot a {
  font-size: 13.5px; color: var(--muted); text-decoration: none;
  border-bottom: 1px solid var(--line-strong); padding-bottom: 1px;
}
.site-foot a:hover { color: var(--accent-deep); border-color: var(--accent); }
/* Doubles as a visible recency + cadence statement, which is a citation gatekeeper
   (AEO.md §3.2) and happens to be the single most useful thing to tell a newcomer. */
.site-foot .foot-note { margin: 14px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--faint); }

/* today's real board (CR-057, idea 2) --------------------------------------
   WHY THIS AND NOT AN ANIMATED EXAMPLE. Every previous version of this section
   explained SumHunt with an invented example. This one shows the ACTUAL puzzle
   that is live right now: today's clue, today's eighteen tiles, today's target,
   its number and its date. It changes every day, it proves the thing is running,
   and it turns "here is how it works" into "here is one you could do now".

   It is also the only version that moves a measured AEO gatekeeper. RECENCY is
   one of four (AEO.md §3.2) and we were failing it outright — a crawler read
   "Loading today's puzzle…" and no date anywhere. functions/_middleware.js now
   renders this at the edge, so every crawl sees a dated, live page.

   THE SOLUTION IS NEVER SHOWN. Rack and clue are already public in puzzles.json;
   the answer is not, and test/today-inject.test.mjs asserts it stays out.

   Built entirely from the board's own parts — .clue-card, .dial-wrap, the rack
   tile face — so this reads as the product rather than as an advert for it.
   No motion: the board above is where things move. */
.today { margin-top: 24px; }
.today-cap { margin: 0 0 12px; font-size: 11px; letter-spacing: 2.2px; text-transform: uppercase; color: var(--accent-label); }
.today-fallback { margin: 0; font-size: 15.5px; line-height: 1.65; color: var(--ink-soft); }

.today-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 12px; }
.today-series { font-family: var(--display); font-size: 21px; color: var(--ink); }
.today-date { font-size: 13px; color: var(--faint); }
/* Amber marks the theme day for the same reason it does on the board: it is a
   state, not decoration (DESIGN.md §1). Removed by the rewriter on daily days. */
.today-theme {
  font-size: 11px; letter-spacing: 1.4px; text-transform: uppercase;
  color: var(--accent-deep); background: var(--soft);
  border: 1px solid var(--soft-border); border-radius: 20px; padding: 2px 9px;
}

/* The board's own clue card, verbatim. It is the prettiest thing in the app and
   the single most intriguing asset we have — a riddle makes people want to try. */
.today-clue-card { margin-top: 14px; animation: none; }
.today-clue-card .clue-text { display: block; margin-top: 4px; }

.today-body { margin-top: 18px; display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
/* The board's dial at ~68%. Ring geometry untouched (r=87 in a 190 viewBox) and
   the ring is drawn FULL, because this is the target rather than a progress bar. */
.today-dial { width: 130px; height: 130px; flex: none; }
.today-dial .dial-label { font-size: 8.5px; letter-spacing: 1.8px; }
.today-dial .dial-num { font-size: 34px; }
.today-ring { transition: none; }

.today-rack-wrap { flex: 1 1 260px; min-width: 0; }
.today-rack-cap { margin: 0 0 8px; font-size: 12px; letter-spacing: .04em; color: var(--faint); }
/* Nine columns, so eighteen tiles read as two clean rows at desktop. The board's
   own rack is six across; this is a display of the same tiles, not the rack, and
   two rows keeps the section compact. Drops to six then five as width allows. */
.today-rack { display: grid; grid-template-columns: repeat(9, 1fr); gap: 6px; }
@media (max-width: 620px) { .today-rack { grid-template-columns: repeat(6, 1fr); } }
@media (max-width: 380px) { .today-rack { grid-template-columns: repeat(5, 1fr); } }
.today-rack .demo-tile {
  position: relative; aspect-ratio: .92; border-radius: var(--r-tile);
  display: grid; place-items: center;
  font-family: var(--display); font-size: clamp(14px, 3.4vw, 19px); color: var(--ink);
  background: var(--tile); border: 1px solid var(--line-tile); box-shadow: var(--sh-tile);
}
.today-rack .demo-tile .val { position: absolute; bottom: 2px; right: 4px; font: 600 8.5px var(--ui); color: var(--muted); }

.today-cta { margin: 18px 0 0; }
.today-cta .btn { display: inline-flex; align-items: center; padding: 11px 22px; font-size: 14.5px; }


/* how a solve goes — the scroll storyboard (CR-057) --------------------------
   Owner 2026-08-11: "screenshots as you go down showing phases of guesses."

   BUILT AS REAL MARKUP, NOT SCREENSHOTS, and that is a deliberate substitution.
   Actual PNGs would be heavier, invisible to a crawler, and stale the moment any
   token changes — the design system would drift away from its own advert. These
   frames use the board's real components, so they are always current, they carry
   crawlable text, and they weigh nothing.

   WHY IT ANSWERS THE PACING PROBLEM PERMANENTLY: the reader scrolls. There is no
   timeline to outrun and nothing to miss, each frame is captioned with what is
   happening, and a frame can be sat with for as long as it takes. That is the one
   thing an animation could not give.

   MOTION SPEC (DESIGN.md §4b): frames start at opacity .35 / translateY 10px and
   settle to 1 / 0 over 420ms on var(--ease) when scrolled into view, staggered by
   nothing (each fires on its own). Under prefers-reduced-motion the transition is
   disabled globally by styles.css, and phases.js adds the class immediately, so
   the frames simply appear. WITHOUT JAVASCRIPT ALL FRAMES ARE FULLY VISIBLE —
   the base state is `opacity: 1` and the dimming is applied by script, so a
   crawler and a no-JS reader lose nothing. */
.phases { margin-top: 34px; }
.phases-h { margin: 0 0 4px; font-size: 11px; letter-spacing: 2.2px; text-transform: uppercase; color: var(--accent-label); }
.phases-lede { margin: 0 0 6px; font-size: 15.5px; line-height: 1.6; color: var(--ink-soft); }

.phase { padding: 22px 0; border-top: 1px solid var(--line-2); }
.phase:first-of-type { border-top: 0; }
/* Dimmed only once the script says so, so no-JS readers see everything. */
.phases.js .phase { opacity: .35; transform: translateY(10px); transition: opacity .42s var(--ease), transform .42s var(--ease); }
.phases.js .phase.in { opacity: 1; transform: none; }

.phase-head { display: flex; align-items: baseline; gap: 10px; }
.phase-n { font-family: var(--display); font-size: 21px; line-height: 1; color: var(--accent); width: 18px; flex: none; }
.phase-t { font: 600 15px var(--ui); color: var(--ink); }
.phase-say { margin: 8px 0 0 28px; font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); }

/* The frame: a recessed panel that reads as a still of the board. Not a card —
   nested cards are always wrong (DESIGN.md §3.6) — an inset well instead. */
.phase-frame {
  margin: 14px 0 0 28px; padding: 16px 18px;
  background: var(--inset); border: 1px solid var(--line-2); border-radius: var(--r-btn);
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
}
@media (max-width: 520px) { .phase-frame { margin-left: 0; padding: 14px; } }

.phase-total { flex: none; min-width: 78px; }
.phase-total .pt-n {
  font-family: var(--display); font-size: 30px; line-height: 1; color: var(--accent);
  font-variant-numeric: tabular-nums; display: block;
}
.phase-total .pt-of { font-size: 11px; color: var(--faint); }
.phase.is-near .pt-n { color: var(--bad); }
.phase.is-hit  .pt-n { color: var(--good); }

.phase-words { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; flex: 1 1 220px; min-width: 0; }
.phase-op { font-family: var(--display); font-size: 20px; color: var(--accent-deep); padding: 0 3px; }
.phase-tile {
  position: relative; width: 34px; height: 38px; border-radius: var(--r-tile);
  display: grid; place-items: center;
  font-family: var(--display); font-size: 18px; color: var(--ink);
  background: var(--tile); border: 1px solid var(--line-tile); box-shadow: var(--sh-tile);
}
.phase-tile .val { position: absolute; bottom: 2px; right: 4px; font: 600 8px var(--ui); color: var(--muted); }
.phase-tile.ghost { background: transparent; border-style: dashed; border-color: var(--dash); box-shadow: none; color: var(--faint); }

.phase-note { margin: 10px 0 0 28px; font-size: 13px; color: var(--muted); }
.phase.is-near .phase-note { color: var(--bad); }
.phase.is-hit .phase-note { color: var(--good); font-weight: 600; }

/* Today strip — series, date and the clue. NOT the rack or the dial: the board is directly above
   with the same tiles and the same target, and repeating them made the section read as a second,
   dead copy of the game. The clue is the one part of today's puzzle that is a piece of WRITING
   rather than a control, so it is the only part worth restating here. */
.today-hint { margin: 14px 0 0; font-size: 14.5px; color: var(--ink-soft); }
.today-hint b { font-family: var(--display); font-size: 19px; color: var(--accent); font-variant-numeric: tabular-nums; }


/* Step 1 shows a CLUE, not blank tiles ---------------------------------------
   The frame for step 1 held five ghost tiles, which said "you have nothing yet"
   when the step is called "Read the clue" — the one thing it had to show was the
   only thing missing. It now carries the board's real clue card. */
.phase-frame.is-clue { display: block; padding: 0; background: transparent; border: 0; }
.phase-clue { margin: 0; animation: none; }
.phase-clue .clue-text { display: block; margin-top: 4px; }

/* The near miss now reads like the hit: leading glyph, same weight, so the two
   outcomes are the same kind of statement in two colours rather than one styled
   line and one plain one. It was the line that broke worst on a phone, because an
   unweighted red sentence just looked like body copy that had gone wrong. */
.phase.is-near .phase-note { font-weight: 600; }
.phase-note { text-wrap: pretty; }

/* Two-word example, one row per word ----------------------------------------
   .eg-strip put both words in one flex row that wrapped wherever it ran out of
   width, so on a phone the break landed inside STORM. A row per word fixes that,
   each row nowrap so a word can never split again.

   THE VALUE SITS INLINE, NOT RIGHT-ALIGNED. The first attempt pushed each total
   to the right edge with margin-left:auto, which lines the numbers up into an
   implied column — and a column with no rules reads as a table someone forgot to
   finish. Inline after the tiles it reads as a phrase instead: these letters make
   this number. Same information, no phantom grid. */
.eg-sum-rows { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.eg-row { display: flex; align-items: center; gap: 7px; flex-wrap: nowrap; }
/* ARCHIVE ANSWER ROWS (CR-058). The rows above are hand-authored five-letter examples and always
   fit; the archive renders REAL answers, and a six-letter word plus its operator and total escaped
   the card by up to 56px at 375 and scrolled the page sideways — measured, not guessed, by
   test/responsive.test.mjs across all three engines.
   Wrapping rather than shrinking: at 320px a nowrap row of eight tiles needs a tile size where the
   value badge stops being readable, and an unreadable badge defeats the point of showing the
   arithmetic. A scoped class so the approved games-like-wordle rows keep their exact look. */
.eg-sum-rows.is-answer .eg-row { flex-wrap: wrap; row-gap: 6px; }
.eg-row .eg-sum { margin-left: 6px; }
/* Below the narrowest phone the five tiles plus the value still have to fit, so
   the tiles step down rather than the row wrapping. */
@media (max-width: 400px) {
  .eg-sum-rows .eg-tile { width: 36px; height: 40px; font-size: 19px; }
  .eg-row .eg-sum { font-size: 13px; margin-left: 4px; }
}
