/* Shared chrome: page frame, masthead, theme toggle, footer, home cards,
   archive list, error page. Colours come from tokens.css only.

   The STRUCTURE is sheets on a patterned ground: a masthead band with the current
   section underlined, dashed rules doing the dividing, marker bars instead of
   boxes, headlines ranged left and set tight, and every panel lifted off the page
   by a real shadow. The COLOUR is the site's own — the primary at full strength
   on the panels, scattered as dots over the page — and each puzzle's accent is
   carried through its card, its row and everything it hovers. */

*{box-sizing:border-box}
html,body{margin:0}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--page);color:var(--ink);font-family:var(--ui);
  padding-bottom:56px;
  /* Three layers over the ground. The two blooms give it some weather rather than
     one flat fill; --bloom carries its own alpha per theme, held right back on
     the dark one where the same strength would read as a smear.
     --page-texture is the field of dots and sits ON TOP of both. It is a legal
     `none`, so this list keeps its shape if the pattern is ever turned off. */
  background-image:
    var(--page-texture),
    radial-gradient(760px 420px at 12% -8%,var(--bloom),transparent 70%),
    radial-gradient(620px 380px at 92% 4%,var(--bloom),transparent 72%);
  background-size:var(--page-texture-size),auto,auto;
  background-attachment:fixed;
  transition:background-color .18s var(--ease),color .18s var(--ease);
}
a{color:var(--accent-ink)}

.wrap{max-width:880px;margin:0 auto;padding:0 20px}

/* ---------------- masthead ---------------- */
/* One band, one hairline under it, everything on a single baseline.
   The bar is --nav-bg, NOT --card. Chrome takes the ground and never a panel:
   a mint masthead would be a third sheet across the top of a page that already
   has plenty, and the entry bar at the foot would make it four. That is the whole
   rule — CHROME IS THE GROUND, PANELS ARE FOR CONTENT: cards, the gate, the
   result, the clue list, the play area, the answer squares.
   --nav-bg is var(--page) in the light theme and a step lighter than the page in
   the dark one, where a band needs a value of its own to read as a band. */
.nav{
  background:var(--nav-bg);border-bottom:1px solid var(--nav-line);
  box-shadow:var(--nav-shadow);
  margin-bottom:4px;
}
.nav-in{
  max-width:880px;margin:0 auto;padding:0 20px;
  display:flex;align-items:stretch;gap:6px;min-height:56px;
}
/* The wordmark. See --chip in tokens.css: purple on the light theme, mint on the
   dark one. It is the one mark that never takes the puzzle's accent. */
.nav-brand{
  align-self:center;
  font-family:var(--display);font-weight:700;font-size:15px;letter-spacing:-.01em;
  color:var(--chip-ink);text-decoration:none;background:var(--chip);
  padding:7px 13px;border-radius:var(--radius-card);
  transition:box-shadow .16s var(--spring),transform .16s var(--spring);
}
/* the halo is blurred, never a hard ring: a 0-blur spread draws a crisp second
   outline outside the chip and reads as two borders, not as light */
.nav-brand:hover{
  transform:translateY(-1px);
  box-shadow:0 0 16px 2px var(--nav-mark);
}
/* the cup mark, in the chip's own ink (views/partials/nav.ejs) */
.nav-brand{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.nav-mark{width:1.25em;height:1.25em;flex:none;fill:currentColor;margin-left:-2px}
.nav-links{margin-left:auto;display:flex;align-items:stretch}
/* A section link is marked the way a news site marks one: a bar under it, not a
   pill around it. The bar is always in the box and merely transparent when the
   section is not current, so nothing shifts on hover. */
.nav-links a{
  display:flex;align-items:center;
  font-size:13px;font-weight:700;letter-spacing:.01em;color:var(--nav-ink);text-decoration:none;
  padding:0 13px;border-bottom:3px solid transparent;
  transition:color .15s,border-color .15s;
}
/* Hover and current both take --nav-mark — purple on the light theme, mint on
   the dark one. It is a chrome colour, NOT --accent: the menu must not change
   colour just because today's puzzle did. */
.nav-links a:hover{color:var(--nav-mark);border-bottom-color:var(--nav-mark)}
.nav-links a.is-current{color:var(--nav-mark);border-bottom-color:var(--nav-mark)}

/* the toggle sits outside the link group, hard right, as a control rather than
   a destination */
/* Its ink comes from the BAND, not from the page's general-purpose --slate and
   --rule-firm: the masthead has a ground of its own in the dark theme, and a
   control drawn for the page turns up on it as a grey ghost. */
.theme-toggle{
  align-self:center;margin-left:10px;
  width:34px;height:34px;flex:none;display:grid;place-items:center;
  background:transparent;border:1px solid var(--nav-ink);border-radius:var(--radius-card);
  color:var(--nav-ink);cursor:pointer;padding:0;
  transition:color .15s,border-color .15s,background .15s;
}
.theme-toggle:hover{
  color:var(--nav-mark);border-color:var(--nav-mark);background:transparent;
}
.theme-toggle svg{width:17px;height:17px;display:block;fill:none;
  stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
/* Which glyph shows is decided by the theme, not by script: the sun means "you
   are in the light one", so it is the light theme that shows it. Both live in
   the button so the swap costs no layout and no second paint. */
.theme-toggle .i-moon{display:none}
:root[data-theme="dark"] .theme-toggle .i-sun{display:none}
:root[data-theme="dark"] .theme-toggle .i-moon{display:block}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .theme-toggle .i-sun{display:none}
  :root:not([data-theme="light"]) .theme-toggle .i-moon{display:block}
}

/* ---------------- footer ---------------- */
.footer{
  max-width:880px;margin:56px auto 0;padding:20px;border-top:1px dashed var(--rule);
}
.footer p{margin:0;font-size:12px;line-height:1.7;color:var(--dim);max-width:60ch}

/* ---------------- section heading ---------------- */
/* The device the whole site is built on: a short bar of the accent, then the
   label in small caps. It marks the top of the home cards, the archive and the
   puzzle's clue list, and it is the reason none of them need a box. */
.section-head{
  display:flex;align-items:center;gap:10px;
  margin:0 0 14px;font-family:var(--display);
  font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink);
}
.section-head::before{
  content:"";width:22px;height:3px;flex:none;background:var(--accent);border-radius:0;
}

/* ---------------- the play panel ----------------
   Shared by all three games, which is why it is here and not in any one of them.

   The ground carries a field of dots, and over a pattern a board stops being an
   object and becomes part of the noise — the dots run straight under a clue list
   and a keyboard and make both harder to read. So the play area sits on one
   opaque sheet: the pattern belongs to the page, not to the game.

   ONE PANEL PER THING THE EYE TREATS AS ONE THING. The acrostic's board is
   already a panel, so it gets a second for the WHOLE clue list — not a box per
   clue, which would be the dots' problem again at a different scale. `.playfield`
   (views/binary.ejs, views/wordguess.ejs) is the wrapper for the two games whose
   board and controls are separate elements: the binary's grid with the control
   that redraws it, WordGuess's tiles with the keyboard that fills them. `.rules`
   is in the list because it is the other long run of prose on a puzzle page. */
.clues,.rules,.playfield{
  background:var(--card);
  border:1px solid var(--rule);border-radius:var(--radius-card);
  box-shadow:var(--card-shadow);
}
.clues{padding:20px 20px 6px}
.rules{padding:20px 22px 22px}
/* fit-content so a wide board (the nine-block special is 18 squares across) is
   not cropped, with a floor so a 6x6 does not leave a panel barely wider than the
   grid inside it. */
.playfield{
  width:fit-content;min-width:min(100%,520px);max-width:100%;
  margin:0 auto 26px;padding:22px 20px 18px;
}
/* Both children own a bottom margin, and inside a panel that reads as the panel
   having a heavy foot. It moves to the PANEL, where it was doing the other half
   of its job all along: WordGuess's .entry margin is the only thing separating
   the keyboard from "How to play". Binary is unaffected — its own .rules carries
   a larger top margin, which simply collapses with this one. */
.playfield .entry,.playfield .keys{margin-bottom:0}

/* ---------------- home ---------------- */
/* Left-aligned. A centred headline is a poster; a news page ranges everything
   left off one margin, and the cards below inherit that edge. */
/* Every rule on the page is dashed — the pencil line in a puzzle book rather
   than the printed hairline of a newspaper.
   Per EDGE, never the `border-style` shorthand. These elements carry a border on
   ONE side and the other three are invisible because their style is `none`; set
   all four to dashed and the other three snap back to the initial `medium`
   width, which draws a full dashed box round the hero, the footer and every
   section. */
.daily{padding:44px 0 6px;margin-bottom:26px}
.daily h1{
  font-family:var(--display);font-weight:700;font-size:clamp(36px,7vw,58px);
  letter-spacing:-.035em;line-height:1.02;margin:0 0 18px;max-width:20ch;
  /* At a phone's width this wraps to two lines; balance is what keeps "day"
     off a line by itself, splitting the words evenly instead. A legal no-op
     where it is not yet supported, which just leaves the browser's default
     (last-line-short) wrap in place. */
  text-wrap:balance;
}
.daily h1 em{font-style:normal;color:var(--brand-ink)}
/* The day, once. Every section under it is today's, so the date is a property of
   the page and not of any one card — it used to sit in two card eyebrows, where
   it wrapped to a second line and read as two different dates. */
.hero-when{
  margin:0 0 22px;font-size:12px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:var(--dim);
}

/* The Archive region, below the Daily one. The rule above it is what separates
   them — the same hairline dividing that the rest of the site uses, rather than
   a box around either group. */
/* the one-sentence "what this site is", under the archive list (views/index.ejs) */
.home-about{margin:34px 0 0;max-width:62ch;font-size:14.5px;line-height:1.55;color:var(--slate)}
.archive-links{margin-top:34px;padding-top:30px;border-top:1px dashed var(--rule)}
/* Compact links, not the large prose cards the Daily tiles above are — the
   archive is one click away from here and does not need selling on the way
   past. Each still wears its own game's accent, as a rule down the left edge
   rather than a bar across the top, which is what keeps a short row from
   reading as a shrunken card. */
.arch-list{list-style:none;margin:18px 0 0;padding:0;display:grid;gap:10px}
.arch-list li{margin:0}
.arch-list a{
  display:flex;flex-wrap:wrap;align-items:baseline;column-gap:10px;row-gap:2px;
  text-decoration:none;color:inherit;
  background:var(--card);border:1px solid var(--rule);
  border-left:5px solid var(--accent);border-radius:var(--radius-card);
  box-shadow:var(--card-shadow);
  padding:13px 16px;
  transition:transform .2s var(--spring),box-shadow .2s var(--ease),border-color .18s;
}
.arch-list a:hover{
  transform:translateX(3px) rotate(-.3deg);
  box-shadow:var(--card-shadow-hover);
  border-color:var(--ink);border-left-color:var(--accent);
}
.arch-list .arch-name{font-weight:800;font-size:15px;letter-spacing:-.01em;color:var(--ink)}
.arch-list .arch-desc{font-size:13px;color:var(--dim)}

/* Separate sheets with a gap between them, not one block divided by hairlines.
   `overflow:visible` is the load-bearing line here: a grid that clips to its own
   rounded box clips the drop shadow under every card in it, and a clipped drop
   shadow is no drop shadow.

   Four tiles, laid out two-by-two at every width from 540px up — there is no
   further breakpoint, because two is the only column count four tiles ever
   take. `auto-fit,minmax(...)` did the wrapping the old two-card sections
   wanted, where the number of cards in a row genuinely varied; asked to lay
   out exactly four, it drops a column before it has to. A fixed THREE-column
   breakpoint is the same defect from the other side — the fourth tile lands
   alone at the left of row two at every width it applies — and the FOUR-across
   band this grid used to gain at 900px is gone outright: `.wrap` caps at
   880px, so "four across" was never more than four ~198px slivers, and the
   tile below is drawn for the ~432px a 2x2 column gives it rather than
   stretched to fill a fourth column that added nothing. A fifth family would
   orphan a tile in a two-column grid too (5 into 2 leaves one alone on row
   three) — a known, accepted consequence of a two-column-always grid, not
   pre-solved here for a game that does not exist (DESIGN.md §12.6).
     - one column while there is not room for two at a readable ~240px each:
       2*240 + 1*16 (gap) + 28 (the 14px mobile `.wrap` padding, doubled) = 524,
       rounded up to 540.
     - two columns (2x2, never orphaned, never three, never four) from 540px
       up, at every width after. */
.cards{display:grid;grid-template-columns:1fr;gap:16px}
@media (min-width:540px){
  .cards{grid-template-columns:repeat(2,1fr)}
}
/* Each card carries a 4px marker of its accent along the top edge, drawn as a
   background rather than a border so it cannot add to the card's height, and
   hovering one washes it in that same accent and lifts it off the page.

   Flex column, not block: the foot row's `margin-top:auto` (below) is what
   lets two tiles in the same grid row end level whatever their description's
   length — the grid already stretches both cards to the row's own height
   (grid's default `align-items:stretch`), and the flex column is what pushes
   the foot down to the bottom of that stretched box instead of leaving it
   just under a description that might be one line or two. `.archive-card`
   (below) sets `display:block` back, because it carries no foot row and reads
   top to bottom as plain prose instead. */
.card{
  display:flex;flex-direction:column;text-decoration:none;color:inherit;position:relative;
  background:var(--card);padding:24px 22px 26px;
  border:1px solid var(--rule);border-radius:var(--radius-card);
  box-shadow:var(--card-shadow);
  background-image:linear-gradient(var(--accent),var(--accent));
  background-repeat:no-repeat;background-size:100% 4px;background-position:top left;
  transition:transform .22s var(--spring),box-shadow .22s var(--ease),
             background-color .15s var(--ease);
}
/* the tip is under half a degree. Any more and a grid of cards reads as
   scattered rather than as picked up. */
.card:hover{
  background-color:var(--accent-soft);
  transform:translateY(calc(var(--lift) * -1)) rotate(-.35deg);
  box-shadow:var(--card-shadow-hover);
}
/* The head row: the family's thumbnail ahead of the naming block, so "which
   game" reads before the number does. */
.card-top{display:flex;align-items:flex-start;gap:14px}
.card-fig{display:block;flex:none}
.card-head{min-width:0}
/* The tile's thumbnail (views/partials/familyThumb.ejs) — decorative, sized
   here rather than by SVG attributes so the same markup serves both the
   72px desktop tile and the 56px one below 540px, mirroring `.cards`'s own
   breakpoint. `.fam-thumb--gate` (below, with the rest of the gate rules)
   is the ~96px start-panel size, shared by all four family sheets because
   site.css loads on every page and a fifth copy of these rules is exactly
   the kind of drift this repo keeps paying for (DESIGN.md §3). */
.fam-thumb{display:block;flex:none;width:56px;height:56px}
@media (min-width:540px){
  .fam-thumb--tile{width:72px;height:72px}
}
/* The gate's figure (views/acrostic.ejs etc, above `#gateKicker`): inline-block
   rather than the tile's block, because the gate is centred by `text-align`
   on `.gate`/`.gate-in` and a replaced element still takes vertical margin
   that way — no layout change needed at any width (judgement call #12). */
.fam-thumb--gate{display:inline-block;width:96px;height:96px;margin:0 0 14px}
.card .eyebrow{
  font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--accent-ink);
}
.card h2{
  font-family:var(--display);font-weight:700;font-size:27px;
  margin:9px 0 0;letter-spacing:-.03em;line-height:1.12;
}
/* Capped so the prose breaks into two tidy lines at a ~432px tile instead of
   running the full column width. `.archive-card p` (below) overrides this back
   out — that card takes the full width of its own, wider column. */
.card p{margin:11px 0 0;font-size:15px;line-height:1.6;color:var(--slate);max-width:34ch}
.card .cta{
  display:inline-block;margin-top:16px;font-size:13px;font-weight:800;color:var(--accent-ink);
}
.card:hover .cta{text-decoration:underline;text-underline-offset:3px}
.card.is-empty{background-image:linear-gradient(var(--rule-firm),var(--rule-firm))}
.card.is-empty:hover{background-color:var(--card)}
/* The foot row: the Daily tile's status/result on the left, a call to action on
   the right, pinned to the card's bottom edge (see `.card` above) and set off
   from the description by a hairline. `margin-left:auto` on the `.cta` (rather
   than `justify-content:space-between` on the row) is what keeps the cta at
   the right edge whether or not a badge sits beside it — the "no puzzle yet"
   tile's foot carries no badge at all.

   The badge itself is filled in by public/js/home.js from this browser's own
   saved record for today's slug — the server does not know it. It is the SAME
   `.badge` the archive rows wear (see below), so a solved tile and a solved
   row read as the same fact in the same colour. `.badge:empty{display:none}`
   (below) is what keeps this row's height coming from the cta rather than
   from the pill: a page with no script or no storage shows an empty badge, and
   the foot row is exactly as tall as it is with one. */
.card-foot{display:flex;align-items:center;gap:12px;margin-top:auto;padding-top:16px;border-top:1px solid var(--rule)}
.card-foot .badge{margin-top:0}
.card-foot .cta{margin-top:0;margin-left:auto}
.card .badge{display:inline-block;margin-top:16px}
/* On the tile the result is the headline once today's puzzle is done, so it
   is set larger than the archive's chip, and a SOLVED one is a filled accent
   pill rather than a tinted outline. The fill is --accent-ink with --accent-soft
   type, not --accent with --on-accent: the light accents are mid-tones that
   the dark ink only clears at ~4:1, while ink/soft is the pair each theme
   already flips to keep contrast (dark ink on the mint card in light, bright
   ink on the dark card in dark). Other states keep the shared outline colours,
   only at the tile's size. */
.card-foot .badge{font-size:13px;padding:8px 15px;letter-spacing:.06em;font-variant-numeric:tabular-nums}
.card-foot .badge.is-solved{
  color:var(--accent-soft);background:var(--accent-ink);border-color:var(--accent-ink);
}
.card-foot .badge.is-solved::before{content:"\2713\00a0";font-weight:900}

/* ---------------- archive ---------------- */
.page-head{padding:38px 0 18px;border-bottom:1px dashed var(--rule)}
.page-head h1{
  font-family:var(--display);font-weight:700;font-size:clamp(30px,5vw,44px);
  letter-spacing:-.03em;margin:0;line-height:1.05;
}
.page-head p{margin:11px 0 0;font-size:15px;line-height:1.6;color:var(--slate);max-width:56ch}

/* One card per puzzle, with a gap between them — not a rules-only index. Each
   card wears its own puzzle's accent as a thick rule down its left edge, so the
   list reads as the run of colours the puzzles actually are, and the pale --card
   panel is what lets that colour register against the saturated page.
   The hover slides the card right rather than washing it: the accent bar is
   already doing the colouring, and a tint underneath it only muddied both. */
.archive{list-style:none;margin:26px 0 0;padding:0;display:grid;gap:10px}
.archive li{margin:0}
.archive a{
  display:flex;align-items:center;gap:16px;text-decoration:none;color:inherit;
  background:var(--card);border:1px solid var(--rule);
  border-left:7px solid var(--accent);border-radius:var(--radius-card);
  box-shadow:var(--card-shadow);
  padding:15px 18px;
  transition:transform .2s var(--spring),box-shadow .2s var(--ease),border-color .18s;
}
.archive a:hover{
  transform:translateX(3px) rotate(-.3deg);
  box-shadow:var(--card-shadow-hover);
  border-color:var(--ink);border-left-color:var(--accent);
}
/* the figure is the serif at full wonk, as it is on the board — an archive row
   is a puzzle, and it should be numbered in the puzzle's own letterform */
.archive .no{
  font-family:var(--serif);font-weight:900;font-size:26px;
  font-variation-settings:"SOFT" 70,"WONK" 1;
  min-width:52px;color:var(--accent-ink);font-variant-numeric:tabular-nums;
}
.archive .about{min-width:0}
/* both are spans, so they need making block-level to stack — margin-top on an
   inline box does nothing, and the date and its figures ran together on one line */
.archive .when{display:block;font-size:15px;font-weight:700;letter-spacing:-.01em}
.archive .figures{display:block;font-size:13px;color:var(--dim);margin-top:3px}
/* Tags are the one round thing on the site — see the shape note in tokens.css.
   Everything structural is a rectangle; a status tag is a chip, and reads as one.

   This is the ONE badge, shared by an archive row and a Daily tile — see
   `.card .badge` above — because both say the same thing about the same saved
   record and a player should not have to learn two vocabularies for it. The
   archive positions it at the row's right edge; the tile just lets it sit
   after the tile's own prose, so only the positioning is per-context. */
.badge{
  font-size:11px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;padding:6px 12px;border-radius:var(--radius-pill);
  border:2px solid var(--rule-firm);color:var(--dim);white-space:nowrap;
}
.badge.is-solved{color:var(--accent-ink);border-color:var(--accent-deep);background:var(--accent-soft)}
.badge.is-progress{color:var(--slate);border-color:var(--slate)}
.badge.is-gaveup{color:var(--dim)}
/* Only WordGuess can reach this: it is the one game here you can LOSE outright
   rather than abandon. It is deliberately not is-gaveup — a player who ran out
   of six guesses did not give up, and a row telling them they did would be rude
   as well as wrong — and deliberately not a red alarm either. Running out is an
   ordinary way for this game to end, so it reads as a fact and not a fault. */
.badge.is-lost{color:var(--wg-present-on);border-color:var(--wg-present);background:var(--wg-present)}
/* Badges are written by /js/archive.js and /js/home.js from localStorage;
   without JS the rows and tiles are complete, just unbadged. */
.badge:empty{display:none}
.archive .badge{margin-left:auto;flex:none}
/* The chip goes back to the primary. It had to be reversed out of --ink while
   the rows sat straight on the page, because --brand and --page are the same
   colour in the light theme and a mint badge on a mint page is no badge. On a
   --card panel it has something to sit against again. */
.archive .today{
  display:inline-block;margin-left:8px;vertical-align:1px;
  font-size:10px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  color:var(--on-accent);background:var(--brand);padding:3px 8px;border-radius:var(--radius-pill);
}

/* ---------------- error ---------------- */
.error-box{padding:56px 0 20px;max-width:56ch}
.error-box h1{font-family:var(--display);font-weight:700;font-size:38px;letter-spacing:-.03em;margin:0}
.error-box p{margin:12px 0 0;font-size:16px;line-height:1.7;color:var(--slate)}
.error-box .actions{margin-top:24px;display:flex;gap:10px;flex-wrap:wrap}

/* ---------------- buttons ---------------- */
/* Two shapes for the whole site: a solid one in the ink, and a bordered one.
   Both are rectangles, because everything here is. */
.btn{
  display:inline-block;text-decoration:none;cursor:pointer;
  font-family:var(--ui);font-size:13px;font-weight:800;letter-spacing:.02em;
  padding:12px 20px;border-radius:var(--radius-card);
  border:1px solid var(--ink);background:var(--ink);color:var(--page);
  box-shadow:var(--card-shadow);
  /* A tap on a button is never a pinch or a double-tap-to-zoom gesture, so
     telling the browser that up front is what skips its ~300ms wait to see
     whether a second tap is coming — a real cost on a phone's Start, Pause or
     Give up. */
  touch-action:manipulation;
  transition:transform .16s var(--spring),box-shadow .16s var(--ease),
             background .15s,border-color .15s,color .15s;
}
/* a button is a sheet too: it lifts, it does not glow */
.btn:hover{
  background:var(--ink-lift);border-color:var(--ink-lift);
  transform:translateY(-2px);box-shadow:var(--card-shadow-hover);
}
.btn:active{transform:translateY(0);box-shadow:var(--card-shadow)}
.btn.ghost{background:transparent;color:var(--ink);border-color:var(--rule-firm)}
.btn.ghost:hover{
  background:var(--accent-soft);border-color:var(--accent-deep);color:var(--accent-ink);
  box-shadow:none;
}

/* ---------------- prev / next ---------------- */
/* Shared chrome, not a puzzle's own: both games' pages carry it and so does each
   archive, so it lives here rather than in one game's stylesheet.

   On a puzzle page this row is only prev and next: quiet steps through the run,
   for somebody who wants the one before. The way into that family's list is a
   card further up the page, and a third link here pointing at the same place was
   simply the same destination twice. An archive page does keep a middle link —
   see `.pn-key` below. */
.puzzle-nav{
  max-width:700px;margin:30px auto 0;padding-top:18px;border-top:1px dashed var(--rule);
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  font-size:13px;font-weight:700;
}
.puzzle-nav a{
  color:var(--slate);text-decoration:none;padding:6px 2px;
  border-bottom:2px solid transparent;
  transition:color .15s,border-color .15s;
}
/* The archive's "elsewhere" row: one button followed by a run of links, which
   a narrow phone cannot fit on one line. `nowrap`'s default is to shrink each
   flex item instead — three "X archive →" links each squeezed to a ~55px
   sliver with its own text wrapping two or three lines inside it, cramped and
   hard to read (review round 1, nit). Wrapping keeps every link whole; it
   moves to the next line as a unit instead of folding in on itself. */
.puzzle-nav.is-elsewhere{flex-wrap:wrap;justify-content:flex-start;row-gap:8px;column-gap:18px}
.puzzle-nav a:hover{color:var(--ink);border-bottom-color:var(--accent)}
/* The one that is a destination rather than a step, on the pages that have one.
   A PUZZLE page does not: its archive link is a card of its own further up the
   page (`.archive-card`), and the same destination offered twice made this row
   noise. An ARCHIVE page does — today's puzzle in that game, which nothing else
   on the page offers. The class names the role, not the target. */
.puzzle-nav .pn-key{
  padding:10px 18px;border-radius:var(--radius-card);
  border:1px solid var(--accent-deep);border-bottom-width:1px;
  background:var(--accent-soft);color:var(--accent-ink);
  font-size:12px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  transition:background .15s,border-color .15s,box-shadow .15s;
}
.puzzle-nav .pn-key:hover{
  border-color:var(--accent);border-bottom-color:var(--accent);
  box-shadow:0 0 16px 1px var(--accent-glow);
}

/* ---------------- the puzzle page's archive card ----------------
   The homepage card, on a puzzle page and turned up. It carries `.card` itself
   rather than copying it, so the accent bar along the top, the eyebrow, the
   hover wash and the cta all come from one definition — what changes here is
   only the things a card standing ALONE needs and a card in a `.cards` grid gets
   from its parent: its own border and radius, and a measure of its own.

   It is the last block before the prev/next row, which puts it in two good
   places at once. Behind the gate the board and everything after it are
   display:none, so it falls directly under the start panel — where somebody who
   has not started yet is looking. Mid-puzzle and after, it sits at the foot of
   the page. Same element, no state, no script.

   It is also the ONLY route from a puzzle to its family's list now: the masthead
   item, the chooser page and the third link in the prev/next row have all gone,
   which is why it is a card and not a line. */
.archive-card{
  display:block;
  /* No measure of its own: it takes the full column so its edges line up with
     the start panel it sits under. The PROSE keeps a measure (see `p` below) —
     a card can be wide, a line of text cannot. */
  margin:34px auto 0;
  border:1px solid var(--rule);border-radius:var(--radius-card);
  padding:30px 28px 32px;
  background-size:100% 5px;      /* a touch heavier than the homepage's 4px */
}
.archive-card h2{font-size:31px;margin-top:10px}
.archive-card p{font-size:15.5px;max-width:46ch}
.archive-card .cta{margin-top:18px;font-size:14px}

/* ---------------- quality floor ---------------- */
@media (max-width:680px){
  .nav-in{min-height:52px;padding:0 12px;gap:0}
  .nav-brand{padding:6px 9px;font-size:13px}
  .nav-links a{padding:0 6px;font-size:11px}
  .theme-toggle{width:28px;height:28px;margin-left:4px}
  .wrap{padding:0 14px}
  /* Every panel on the page gives back padding at this width; this one has to,
     because what it holds is the one thing that cannot reflow. A board is n
     squares across and the squares shrink to fit the panel — so 20px either side
     here is 12px taken off the board itself, and on the 18-across special that
     is most of a square. binary.css computes the square from this number. */
  .playfield{padding:18px 14px 16px}
  .daily{padding-top:30px}
  .card{padding:20px 18px 22px}
  .archive a{gap:12px;padding:13px 14px}
  .archive .no{font-size:22px;min-width:40px}
  .arch-list a{padding:11px 14px}
  .footer{margin-top:40px}
  .puzzle-nav{font-size:12px}
  .archive-card{padding:22px 18px 24px;margin-top:26px}
  .archive-card h2{font-size:25px}
  .archive-card p{font-size:14.5px}
}
/* Four links, the wordmark and the toggle stop fitting on one line below about
   450px — every phone held upright — since the wordmark became "Coffee Break
   Puzzles" with its cup (it was "Puzzles", which fit down to 350px). Four links
   do not compress much past 11px before they stop being legible, so rather than
   squeeze into an overflow (or shave the name down), the row WRAPS: the
   wordmark and the toggle stay on the first line, at the two ends they already
   occupy, and the links drop to a centred second line of their own, in full.
   Nothing is ever clipped and nothing scrolls sideways to reach it. 479 rather
   than 450 is headroom for a fifth link and for font metrics that differ. */
@media (max-width:479px){
  /* `justify-content:space-between` is what actually pushes the toggle to the
     far end of line one — without it the two line-one items (brand, toggle)
     simply pack together at the left, which is what round 2 caught: a ring
     button sitting flush against the wordmark instead of anchored opposite it. */
  .nav-in{flex-wrap:wrap;row-gap:6px;justify-content:space-between}
  .nav-brand{order:1}
  .theme-toggle{order:2;margin-left:0}
  .nav-links{order:3;flex-basis:100%;margin-left:0;justify-content:center}
  /* on a line of their own the links lose the row's height they used to
     stretch to, and a 17px-tall word is not a thumb-sized target */
  .nav-links a{min-height:34px;padding:0 8px}
}
/* ---------------- the play bar ----------------
   How far in, the clock, and the controls (Pause; WordFinder's Joker), as the
   first thing INSIDE each game's puzzle panel — .playfield on the binary,
   WordGuess and WordFinder, the dark .board on the acrostic — rather than
   floating in the page header. One definition for all four games: the four
   copies that used to live in each game's stylesheet had drifted (WordGuess's
   clock was 20px/700 against everyone else's 28px/900). */
.playbar{
  display:flex;align-items:center;flex-wrap:wrap;gap:8px 16px;
  margin:0 0 16px;padding:0 0 12px;border-bottom:1px dashed var(--rule-firm);
}
.playbar #count{
  font-family:var(--ui);font-size:11px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:var(--dim);
}
.playbar #clock{
  font-family:var(--serif);font-weight:900;font-size:26px;line-height:1;
  font-variation-settings:"SOFT" 70,"WONK" 1;
  font-variant-numeric:tabular-nums;letter-spacing:.01em;color:var(--ink);
}
.playbar #clock.paused{color:var(--dim)}
/* the buttons keep the right-hand end; on a narrow phone they wrap onto a
   line of their own, still right-aligned, rather than squeezing the clock */
.playbar-actions{margin-left:auto;display:flex;align-items:center;gap:8px}
.playbar button{
  font-family:var(--ui);font-size:11px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;line-height:1;min-height:34px;padding:0 12px;
  color:var(--slate);background:transparent;cursor:pointer;
  border:1px solid var(--rule-firm);border-radius:var(--radius-card);
  touch-action:manipulation;transition:color .15s,border-color .15s,background .15s;
}
.playbar button[hidden]{display:none}
.playbar button:disabled{cursor:default}
.playbar button:not(:disabled):hover{
  color:var(--accent-ink);border-color:var(--accent-deep);background:var(--accent-soft);
}
/* the acrostic's panel is its dark board, in both themes: the bar takes the
   panel's own light ink there (check:contrast: --accent-panel-ink on --board) */
.board .playbar{border-bottom-color:var(--board-line)}
.board .playbar #count,.board .playbar #clock,.board .playbar button{color:var(--accent-panel-ink)}
.board .playbar #clock.paused{color:var(--accent-panel-ink);opacity:.7}
.board .playbar button{border-color:var(--accent-panel-ink)}
.board .playbar button:not(:disabled):hover{
  color:var(--board);background:var(--accent-panel-ink);border-color:var(--accent-panel-ink);
}
@media (max-width:680px){
  .playbar{gap:8px 12px}
  .playbar #clock{font-size:22px}
}

@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
:focus-visible{outline:2px solid var(--brand-ink);outline-offset:2px}
:root[data-theme="dark"] :focus-visible{outline-color:var(--brand)}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) :focus-visible{outline-color:var(--brand)}
}
