  :root {
    color-scheme: dark;
    --earth: #1c1612;
    --earth-2: #251d17;
    --paper: #efe8da;
    --paper-line: rgba(60, 90, 120, 0.13);
    --ink: #1f1a15;
    --ink-soft: #5d5246;
    --chalk: #f1ebe0;
    --dust: #b3a48f;
    --flag: #ff6b1a;
    --flag-ink: #2a1206;
    --good: #2f7a3f;
    --bad: #b8321f;
    --l1: #6b4a32;
    --l2: #a2643b;
    --l3: #c9a36a;
    --l4: #56606b;
    --display: "Zilla Slab", Rockwell, "Roboto Slab", Georgia, serif;
    --body: "IBM Plex Sans", "Segoe UI", system-ui, sans-serif;
    --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  }
  html, body { height: 100%; }

  /* Atmosphere ------------------------------------------------------------
     Two fixed layers behind everything. Neither takes pointer events and
     neither adds a node to the document, so nothing here can catch a tap or
     a Tab stop.

     ::before is the section itself - the same tilted beds the page has always
     had, lifted off body so it can be transformed. It creeps UPWARD, because
     descending means the rock rises past you. The travel is exactly one 94px
     bed period, so the loop lands on an identical frame and never jumps.
     At 150s that is about 0.6px a second: you should not catch it moving.

     ::after is the stratum you have reached. draw() sets --depth-tint to the
     current layer's colour, so the room around the clue warms through topsoil
     and clay and then cools into bedrock. It is game state, not decoration. */
  body::before,
  body::after {
    content: "";
    position: fixed;
    z-index: -1;
    pointer-events: none;
  }
  body::before {
    inset: -94px 0;
    background-image: repeating-linear-gradient(176deg, transparent 0 46px, rgba(255, 235, 200, 0.025) 46px 48px, transparent 48px 91px, rgba(0, 0, 0, 0.18) 91px 94px);
    animation: bed-drift 150s linear infinite;
    will-change: transform;
  }
  body::after {
    inset: 0;
    background-color: var(--depth-tint, transparent);
    opacity: 0.12;
    transition: background-color 2.5s ease;
  }
  @keyframes bed-drift {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(0, -94px, 0); }
  }

  /* The dig site (site.js) --------------------------------------------------
     One section drawing, far taller than the screen, fixed behind the page.
     --dig (0 = surface, 1 = trench floor) slides it up past a fixed window,
     so the view descends through the strata as a dig's clock runs. The
     height tracks the wider of the two axes so the 1:3 drawing always fills
     the width on a desktop and the height on a phone. */
  .site { position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
  .site-svg {
    --site-h: max(300vh, 300vw);
    position: absolute; left: 0; top: 0; width: 100%; height: var(--site-h);
    transform: translate3d(0, calc(var(--dig, 0) * (100vh - var(--site-h))), 0);
    transition: transform 1.4s cubic-bezier(0.3, 0.7, 0.2, 1);
    will-change: transform;
  }
  /* A vignette so text over the site keeps its contrast at the edges. */
  .site::after { content: ""; position: absolute; inset: 0; background: radial-gradient(120% 80% at 50% 40%, transparent 40%, rgba(8, 6, 5, 0.55)); }
  .site .bulb { animation: flicker 5s ease-in-out infinite; }
  .site .bulb.b1 { animation-delay: -1.3s; animation-duration: 6.2s; }
  .site .bulb.b2 { animation-delay: -2.6s; animation-duration: 4.4s; }
  .site .bulb.b3 { animation-delay: -3.7s; animation-duration: 7s; }
  .site .lamp { animation: flicker 3.6s ease-in-out infinite; }
  @keyframes flicker { 0%, 100% { opacity: 1; } 40% { opacity: 0.75; } 55% { opacity: 0.95; } 70% { opacity: 0.6; } }
  .site .star { animation: twinkle 7s ease-in-out infinite; }
  .site .star:nth-of-type(3n) { animation-delay: -2.5s; }
  .site .star:nth-of-type(3n+1) { animation-delay: -5s; animation-duration: 9s; }
  @keyframes twinkle { 50% { opacity: 0.08; } }
  .site .sway { transform-origin: 10px -8px; transform-box: view-box; animation: sway 6s ease-in-out infinite alternate; }
  @keyframes sway { from { transform: rotate(-4deg); } to { transform: rotate(5deg); } }
  .site .dust { transform-box: fill-box; animation: sift 9s linear infinite; }
  .site .dust.d1 { animation-delay: -1.5s; animation-duration: 11s; }
  .site .dust.d2 { animation-delay: -3s; animation-duration: 8s; }
  .site .dust.d3 { animation-delay: -4.5s; animation-duration: 13s; }
  .site .dust.d4 { animation-delay: -6s; animation-duration: 10s; }
  .site .dust.d5 { animation-delay: -7.5s; animation-duration: 12s; }
  @keyframes sift { from { transform: translate(0, -60px); opacity: 0; } 15% { opacity: 0.4; } 85% { opacity: 0.3; } to { transform: translate(14px, 220px); opacity: 0; } }

  /* Clue reveal: each word surfaces on its own, staggered by --d (set in
     renderClues through the CSSOM). The stagger is spread over a fixed window
     so every clue takes the same time to land, whatever its length. */
  .find.fresh .w { display: inline-block; opacity: 0; animation: word-up 0.34s ease-out var(--d, 0s) forwards; }
  @keyframes word-up { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
  .sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

  /* The ground colour lives on <html> so the two fixed atmosphere layers below
     can sit behind the page content without body's own background hiding them. */
  html { background-color: var(--earth); }
  body {
    background-color: transparent;
    background-image: radial-gradient(120% 60% at 50% 0%, rgba(255, 180, 110, 0.07), transparent 70%);
    color: var(--chalk);
    font-family: var(--body);
    font-size: 16px;
    line-height: 1.45;
    -webkit-tap-highlight-color: transparent;
  }
  .wrap {
    position: relative;
    max-width: 480px;
    margin: 0 auto;
    padding-inline: 16px;
    padding-block: 12px 28px;
    min-height: 100%;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: 16px;
  }
  button { font: inherit; color: inherit; cursor: pointer; }
  button:focus-visible, input:focus-visible { outline: 2px solid var(--flag); outline-offset: 2px; }
  [hidden] { display: none !important; }

  /* Header */
  .top { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-top: 4px; }
  .brand { display: flex; align-items: baseline; gap: 8px; margin: 0; font-family: var(--display); font-weight: 700; font-size: 1.75rem; letter-spacing: 0.01em; }
  .brand .mark { display: inline-grid; grid-template-rows: repeat(4, 4px); gap: 2px; width: 18px; align-self: center; }
  /* The mark is the menu button: strip every UA default so the bars stay pixel-identical */
  button.mark { appearance: none; -webkit-appearance: none; border: 0; background: none; padding: 0; margin: 0; position: relative; }
  /* Widen the tap target without moving the bars; 8px stops short of the word "Strata" */
  button.mark::before { content: ""; position: absolute; inset: -11px -8px; }
  .brand .mark i { display: block; border-radius: 1px; }
  .brand .mark i:nth-child(1) { background: var(--l1); }
  .brand .mark i:nth-child(2) { background: var(--l2); }
  .brand .mark i:nth-child(3) { background: var(--l3); }
  .brand .mark i:nth-child(4) { background: var(--l4); }
  .brand small { font-family: var(--mono); font-size: 0.85rem; color: var(--flag); font-weight: 700; }
  /* Marks a replay so it reads differently from today's dig: nobody's streak
     is at stake here. */
  .mode-tag { display: inline-block; vertical-align: middle; margin-left: 6px; font-family: var(--mono); font-size: 0.6rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--flag-ink); background: var(--flag); padding: 2px 7px; border-radius: 3px; }
  /* Sits under the header: wrap padding (12px) + header padding (4px) + one brand line */
  .menu { position: absolute; z-index: 10; top: calc(16px + 1.75rem * 1.45 + 6px); left: 16px; display: flex; flex-direction: column; min-width: 190px; padding: 4px; background: var(--earth-2); border: 1px solid rgba(241, 235, 224, 0.2); border-radius: 6px; box-shadow: 0 10px 24px rgba(0, 0, 0, 0.35); }
  .menu button, .menu a { appearance: none; display: flex; justify-content: space-between; align-items: baseline; gap: 12px; border: 0; border-radius: 4px; background: none; padding: 10px 12px; text-align: left; font-family: var(--mono); font-size: 0.85rem; font-weight: 500; color: var(--chalk); text-decoration: none; }
  /* Hover only where there is a pointer that hovers: on touch a :hover style
     sticks after the tap and reads as a control stuck on. Every :hover rule
     goes inside @media (hover: hover); tests/ui.test.mjs enforces it. */
  @media (hover: hover) { .menu button:not(:disabled):hover, .menu a:hover { background: rgba(241, 235, 224, 0.08); } }
  .menu button:disabled { cursor: default; color: var(--dust); }
  .menu button span { font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--dust); }
  .sheet { position: fixed; inset: 0; z-index: 20; display: grid; place-items: center; padding: 16px; background: rgba(12, 9, 7, 0.72); }
  .sheet-card { display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 448px; }
  .sheet-foot { display: flex; align-items: center; gap: 12px; }
  .sheet-note { flex: 1; margin: 0; font-size: 0.85rem; color: var(--dust); }
  .sheet-foot .ghost { margin-left: auto; }
  /* The Unlimited picker: a scrolling list of published days inside the same
     sheet-card shell the rules use, so 4 entries and 33 both read well. */
  .unl-picker { padding: 16px; display: flex; flex-direction: column; gap: 10px; }
  .unl-picker h3 { margin: 0; font-family: var(--display); font-size: 1.15rem; }
  .unl-note { margin: 0; font-size: 0.85rem; color: var(--ink-soft); }
  .unl-head { margin: 4px 0 0; font-family: var(--mono); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-soft); }
  .unl-status { margin: 0; font-size: 0.85rem; color: var(--ink-soft); }
  .unl-status:empty { display: none; }
  .unl-sets { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 6px; max-height: 26vh; overflow-y: auto; }
  .unl-set { appearance: none; width: 100%; min-height: 48px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; border: 1px solid rgba(31, 26, 21, 0.18); border-radius: 4px; background: none; padding: 6px 4px; font: inherit; color: var(--ink); }
  @media (hover: hover) { .unl-set:hover:not(:disabled) { background: rgba(31, 26, 21, 0.06); } }
  .unl-set:disabled { opacity: 0.55; }
  .unl-set-num { font-family: var(--display); font-weight: 700; font-size: 1.05rem; }
  .unl-set-state { font-family: var(--mono); font-size: 0.58rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-soft); }
  .unl-set-state.done { color: var(--good); }
  .unl-days { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; max-height: 26vh; overflow-y: auto; }
  .unl-day { appearance: none; width: 100%; display: flex; justify-content: space-between; align-items: baseline; gap: 10px; border: 1px solid rgba(31, 26, 21, 0.18); border-radius: 4px; background: none; padding: 10px 12px; text-align: left; font: inherit; color: var(--ink); }
  @media (hover: hover) { .unl-day:hover { background: rgba(31, 26, 21, 0.06); } }
  .unl-day-num { font-family: var(--display); font-weight: 700; }
  .unl-day-date { font-family: var(--mono); font-size: 0.72rem; color: var(--ink-soft); margin-right: auto; padding-left: 8px; }
  .unl-day-done { font-family: var(--mono); font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--good); }
  .unl-empty { font-size: 0.9rem; color: var(--ink-soft); padding: 8px 0; }
  /* Sets without the upgrade: the section keeps its heading and says why, with the $5 button. */
  .unl-upgrade { display: flex; flex-direction: column; gap: 8px; }
  .unl-upgrade[hidden] { display: none; }
  .unl-upgrade p { margin: 0; font-size: 0.85rem; color: var(--ink-soft); }
  .unl-buy { font-size: 1rem; padding: 11px; }
  .top-right { display: flex; align-items: center; gap: 10px; }
  /* Account: one small button, a person outline until Google sends a photo */
  .avatar { appearance: none; position: relative; display: grid; place-items: center; width: 30px; height: 30px; padding: 0; border: 1px solid rgba(241, 235, 224, 0.2); border-radius: 50%; background: none; color: var(--dust); }
  /* A 44px touch target without moving anything, as for the logo button. The
     photo rounds itself: overflow: hidden here would also clip the hit area. */
  .avatar::before { content: ""; position: absolute; inset: -7px; }
  .avatar svg { width: 18px; height: 18px; }
  .avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
  .avatar:disabled { opacity: 0.4; cursor: default; }
  .account-menu { left: auto; right: 16px; }
  .account-menu .who { margin: 0; padding: 8px 12px 6px; font-family: var(--mono); font-size: 0.78rem; color: var(--dust); overflow-wrap: anywhere; }
  .linkish { appearance: none; border: 0; background: none; padding: 0; color: var(--chalk); font: inherit; text-decoration: underline; text-underline-offset: 2px; }
  .score-pill { font-family: var(--mono); font-weight: 700; font-size: 1rem; color: var(--chalk); font-variant-numeric: tabular-nums; }
  .score-pill small { color: var(--dust); font-weight: 500; }

  /* Progress: five dig sites */
  .track { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; }
  .track div { height: 36px; border-radius: 4px; background: var(--earth-2); border: 1px dashed rgba(241, 235, 224, 0.2); display: grid; place-items: center; font-size: 1.05rem; }
  .track div.now { border: 2px solid var(--flag); }
  .track div.done { border-style: solid; border-color: rgba(241, 235, 224, 0.18); }

  /* Timed ------------------------------------------------------------------
     The sprint clock sits beside the score, reading m:ss. It turns flag orange
     under fifteen seconds and pulses when a layer-1 find buys time back - the
     bonus is the mechanic the mode is built on, so it gets the one animation.
     Orange, not --good: the header sits on --earth, where a dark green reads
     as nearly black. */
  .sprint-clock { font-family: var(--mono); font-weight: 700; font-size: 1rem; color: var(--chalk); font-variant-numeric: tabular-nums; padding: 2px 8px; border: 1px solid rgba(241, 235, 224, 0.25); border-radius: 4px; }
  .sprint-clock.low { color: var(--flag); border-color: var(--flag); }
  .sprint-clock.bonus { animation: bonus 0.6s ease-out; }
  @keyframes bonus {
    0% { color: var(--flag); transform: scale(1.2); }
    100% { color: var(--chalk); transform: scale(1); }
  }
  /* The marks strip grows all run rather than standing at five, so it wraps
     into smaller cells instead of using the dig's five fixed columns. */
  .track.sprint { display: flex; flex-wrap: wrap; gap: 4px; }
  .track.sprint div { width: 24px; height: 24px; font-size: 0.8rem; }
  .sprint-pool { text-align: center; font-family: var(--mono); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--dust); margin: 0; }
  /* The reveal a timed run gets. No button: asking for a press is the one
     thing a timed mode cannot do, so it shows the answer and advances itself.
     Lighter than .reveal for the same reason - it is read in about a second. */
  .flash { padding: 14px 18px; display: flex; flex-direction: column; gap: 4px; border-left: 4px solid var(--ink-soft); animation: unearth 0.5s ease-out; }
  .flash.ok { border-left-color: var(--good); }
  .flash.no { border-left-color: var(--bad); }
  .flash .tag { font-family: var(--mono); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-soft); }
  .flash .big { font-family: var(--display); font-weight: 700; font-size: 1.6rem; line-height: 1.05; margin: 0; text-wrap: balance; }
  .flash .meta { display: flex; gap: 10px; align-items: baseline; margin: 0; }
  .flash .pts { font-family: var(--mono); font-weight: 700; color: var(--good); }
  .flash .pts.zero { color: var(--bad); }
  .flash .bonus { font-family: var(--mono); font-weight: 700; font-size: 0.85rem; color: var(--flag); }
  .flash .fix { color: var(--ink); font-size: 0.88rem; margin: 0; background: rgba(201, 163, 106, 0.35); padding: 4px 8px; border-radius: 3px; align-self: flex-start; }

  /* Intro */
  .hero { display: flex; flex-direction: column; gap: 16px; padding-top: 14px; }
  .hero h2 { font-family: var(--display); font-weight: 700; font-size: clamp(2.4rem, 11.5vw, 3.3rem); line-height: 0.98; margin: 0; text-wrap: balance; }
  .hero h2 em { font-style: normal; color: var(--flag); }
  .hero p { margin: 0; color: var(--dust); max-width: 38ch; }
  .section-cut { display: grid; grid-template-rows: repeat(4, auto); border-radius: 6px; overflow: hidden; }
  .section-cut div { display: flex; justify-content: space-between; align-items: center; padding: 9px 12px; font-family: var(--mono); font-size: 0.78rem; }
  .section-cut div:nth-child(1) { background: var(--l1); color: #f4e6d6; }
  .section-cut div:nth-child(2) { background: var(--l2); color: #fff3e6; }
  .section-cut div:nth-child(3) { background: var(--l3); color: #2b1d0e; }
  .section-cut div:nth-child(4) { background: var(--l4); color: #eef1f4; }
  .section-cut b { font-size: 1.05rem; font-weight: 400; }
  .notebook {
    background-color: var(--paper);
    background-image: linear-gradient(var(--paper-line) 1px, transparent 1px), linear-gradient(90deg, var(--paper-line) 1px, transparent 1px);
    background-size: 18px 18px;
    color: var(--ink);
    border-radius: 4px;
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.3), 0 10px 24px rgba(0, 0, 0, 0.35);
  }
  .rules { padding: 16px; display: flex; flex-direction: column; gap: 8px; }
  .rules h3 { margin: 0; font-family: var(--display); font-size: 1.15rem; }
  .rules ul { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; font-size: 0.95rem; color: var(--ink-soft); }
  .topics { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
  .topics li { font-family: var(--mono); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; padding: 5px 9px; border: 1px solid rgba(241, 235, 224, 0.28); border-radius: 3px; color: var(--chalk); }
  .cta { appearance: none; border: 0; border-radius: 6px; background: var(--flag); color: var(--flag-ink); font-family: var(--display); font-weight: 700; font-size: 1.2rem; padding: 15px; width: 100%; box-shadow: 0 3px 0 #a8410b; }
  .cta:active:not(:disabled):not([aria-disabled="true"]) { transform: translateY(2px); box-shadow: 0 1px 0 #a8410b; }
  .cta:disabled, .cta[aria-disabled="true"] { opacity: 0.55; cursor: default; }
  /* A link styled as a button: every other .cta is a <button>, which the UA
     makes border-box; an <a> is content-box, so in the flex empty state
     width: 100% plus 15px padding overflowed its column by 30px, scrolling
     account.html sideways at 320px and 390px. box-sizing is the fix;
     display: block keeps an a.cta full width outside a flex container.
     Scoped to a.cta so no button's box model changes. */
  a.cta { display: block; box-sizing: border-box; text-align: center; text-decoration: none; }

  /* Play */
  .dig { display: flex; flex-direction: column; gap: 14px; flex: 1; }
  .dig-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; }
  .eyebrow { font-family: var(--mono); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--flag); font-weight: 700; }
  .qnum { font-family: var(--display); font-weight: 700; font-size: 1.4rem; margin: 2px 0 0; }
  .depth { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
  .depth b { display: block; font-size: 1.7rem; line-height: 1; }
  .depth small { color: var(--dust); font-size: 0.72rem; letter-spacing: 0.05em; text-transform: uppercase; }
  /* Horizontal section: the marker moves through four layers */
  .core { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); height: 14px; border-radius: 3px; overflow: hidden; }
  .core span:nth-child(1) { background: var(--l1); }
  .core span:nth-child(2) { background: var(--l2); }
  .core span:nth-child(3) { background: var(--l3); }
  .core span:nth-child(4) { background: var(--l4); }
  .core .dug { position: absolute; inset: 0 auto 0 0; width: 0; background: rgba(15, 11, 8, 0.55); }
  .core .edge { position: absolute; top: -2px; bottom: -2px; width: 3px; left: 0; background: var(--flag); box-shadow: 0 0 0 2px var(--earth); }

  .finds { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
  .find { display: grid; grid-template-columns: 8px 1fr; overflow: hidden; }
  .find .band { display: block; }
  /* Layer colours are classes, not inline styles: the CSP forbids style attributes */
  .find .band.l1 { background: var(--l1); }
  .find .band.l2 { background: var(--l2); }
  .find .band.l3 { background: var(--l3); }
  .find .band.l4 { background: var(--l4); }
  .find .body { padding: 11px 14px 12px; display: flex; flex-direction: column; gap: 3px; }
  .find .tag { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft); }
  .find p { margin: 0; font-size: 1rem; }
  .find.locked { background: transparent; box-shadow: none; border: 1px dashed rgba(241, 235, 224, 0.2); border-radius: 4px; }
  .find.locked .tag { color: var(--dust); }
  .find.locked p { color: var(--dust); opacity: 0.75; font-size: 0.9rem; }
  /* Opacity only on the card: a rotating, clipped parent around per-word
     transforms smears the words while the camera glides behind them. */
  .find.fresh { animation: fade-in 0.4s ease-out; }
  @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
  @keyframes unearth { from { opacity: 0; transform: translateY(-10px) rotate(-0.6deg); } to { opacity: 1; transform: none; } }

  .guessbar { display: flex; flex-direction: column; gap: 8px; margin-top: auto; position: sticky; bottom: 0; padding-block: 12px calc(8px + env(safe-area-inset-bottom, 0px)); background: linear-gradient(rgba(28, 22, 18, 0), var(--earth) 24%); }
  .field { display: flex; gap: 8px; }
  .field input { flex: 1; min-width: 0; font: inherit; font-size: 17px; padding: 14px; border-radius: 6px; border: 2px solid rgba(241, 235, 224, 0.25); background: #120e0b; color: var(--chalk); }
  .field input::placeholder { color: var(--dust); }
  .field input:focus { border-color: var(--flag); }
  .field button { border: 0; border-radius: 6px; background: var(--flag); color: var(--flag-ink); font-weight: 700; padding: 0 18px; font-family: var(--display); font-size: 1.1rem; }
  .field.shake { animation: shake 0.35s; }
  @keyframes shake { 20%, 60% { transform: translateX(-6px); } 40%, 80% { transform: translateX(6px); } }
  .row { display: flex; justify-content: space-between; gap: 8px; align-items: center; min-height: 24px; }
  .row .btns { display: flex; gap: 8px; }
  .ghost { background: none; border: 1px solid rgba(241, 235, 224, 0.3); border-radius: 6px; padding: 8px 12px; font-size: 0.88rem; color: var(--chalk); position: relative; }
  /* Every ghost button draws 32-38px tall, under the 44px touch target. The hit
     area grows instead of the drawing, the same way button.mark and .avatar do it:
     6px above and below takes the shortest (32px) to 44px without moving any
     layout. Vertical only, so side-by-side ghosts never overlap each other. */
  .ghost::before { content: ""; position: absolute; inset: -6px 0; }
  .ghost:disabled, .ghost[aria-disabled="true"] { opacity: 0.35; cursor: default; }
  .msg { font-size: 0.92rem; color: var(--dust); min-height: 1.3em; }
  .msg.bad { color: #ff9a80; }
  .msg.near { color: var(--l3); }
  .misses { display: flex; flex-wrap: wrap; gap: 6px; }
  .misses span { font-family: var(--mono); font-size: 0.78rem; padding: 3px 8px; border-radius: 3px; background: rgba(184, 50, 31, 0.2); color: #ffb9a8; text-decoration: line-through; }

  .reveal { padding: 18px; display: flex; flex-direction: column; gap: 6px; animation: unearth 0.5s ease-out; position: relative; }
  .reveal .stamp { position: absolute; top: 14px; right: 14px; font-family: var(--mono); font-size: 0.7rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; padding: 4px 8px; border: 2px solid currentColor; border-radius: 3px; transform: rotate(4deg); }
  .reveal .stamp.ok { color: var(--good); }
  .reveal .stamp.no { color: var(--bad); }
  .reveal .tag { font-family: var(--mono); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-soft); }
  .reveal .big { font-family: var(--display); font-weight: 700; font-size: 1.9rem; line-height: 1.05; margin: 0; padding-right: 90px; text-wrap: balance; }
  .reveal .meta { color: var(--ink-soft); font-size: 0.92rem; margin: 0; }
  .reveal .pts { font-family: var(--mono); font-weight: 700; color: var(--good); }
  .reveal .pts.zero { color: var(--bad); }
  .reveal .cta { margin-top: 10px; }
  .reveal .fix { color: var(--ink); font-size: 0.88rem; margin: 0; background: rgba(201, 163, 106, 0.35); padding: 4px 8px; border-radius: 3px; align-self: flex-start; }

  /* Done */
  .final { display: flex; flex-direction: column; gap: 16px; padding-top: 6px; }
  .total { text-align: center; }
  .total b { display: block; font-family: var(--display); font-weight: 700; font-size: 4.8rem; line-height: 1; font-variant-numeric: tabular-nums; }
  .total small { color: var(--dust); font-family: var(--mono); font-size: 0.78rem; letter-spacing: 0.08em; }
  .emojis { text-align: center; font-size: 2.1rem; letter-spacing: 0.08em; }
  .recap { list-style: none; margin: 0; padding: 4px 0; }
  .recap li { display: grid; grid-template-columns: 28px 1fr auto; gap: 10px; align-items: center; padding: 10px 14px; }
  .recap li + li { border-top: 1px dashed rgba(31, 26, 21, 0.22); }
  .recap .cat { display: block; font-family: var(--mono); font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-soft); }
  .recap .ans { font-weight: 700; }
  .recap .p { font-family: var(--mono); font-weight: 700; font-variant-numeric: tabular-nums; }
  .stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; text-align: center; }
  .stats div { padding: 10px 4px; border-radius: 4px; border: 1px solid rgba(241, 235, 224, 0.18); }
  .stats b { display: block; font-family: var(--mono); font-size: 1.25rem; }
  .stats span { font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--dust); }
  .sharebox { font-family: var(--body); white-space: pre; background: #120e0b; border: 1px solid rgba(241, 235, 224, 0.15); border-radius: 6px; padding: 12px 14px; margin: 0; font-size: 0.95rem; overflow-x: auto; user-select: all; -webkit-user-select: all; }
  .next { text-align: center; color: var(--dust); font-size: 0.9rem; margin: 0; }
  .next b { font-family: var(--mono); color: var(--chalk); font-variant-numeric: tabular-nums; }
  .next .ghost { margin-left: 6px; padding: 5px 12px; }

  @media (prefers-reduced-motion: reduce) {
    .find.fresh, .reveal, .flash, .field.shake, .sprint-clock.bonus { animation: none; }
    /* The drift goes; the depth tint stays. It is a colour, not motion, and
       it is the half that carries information. */
    body::before { animation: none; }
    body::after { transition: none; }
    /* The site holds still: no flicker, no falling dust, and the camera
       steps between strata instead of gliding (see digTo in site.js). */
    .site *, .site { animation: none !important; transition: none !important; }
    .find.fresh .w { animation: none; opacity: 1; }
  }

  /* Account page: drawn as an overlay card over the dig, dismissed with the X. */
  html:has(.acct-overlay) { background-color: #120e0b; }
  .wrap.acct-overlay { min-height: 0; margin-block: max(16px, 5vh); padding: 14px 18px 22px; width: calc(100% - 32px); background: rgba(37, 29, 23, 0.94); border: 1px solid rgba(241, 235, 224, 0.16); border-radius: 12px; box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55); animation: unearth 0.35s ease-out; }
  .close-x { position: relative; display: grid; place-items: center; width: 36px; height: 36px; margin-right: -6px; border-radius: 50%; color: var(--chalk); border: 1px solid rgba(241, 235, 224, 0.25); }
  .close-x svg { width: 18px; height: 18px; }
  /* 36px drawn, 44px to the finger, like the other small controls. */
  .close-x::before { content: ""; position: absolute; inset: -4px; }
  @media (hover: hover) { .close-x:hover { background: rgba(241, 235, 224, 0.08); } }
  @media (prefers-reduced-motion: reduce) { .wrap.acct-overlay { animation: none; } }

  /* Account page */
  .acct { display: flex; flex-direction: column; gap: 16px; padding-top: 6px; }
  .who-line { display: flex; align-items: center; gap: 6px; margin: 0; font-family: var(--mono); font-size: 0.78rem; color: var(--dust); }
  .who-line b { color: var(--chalk); font-weight: 700; }
  .section-h { margin: 0; font-family: var(--display); font-weight: 700; font-size: 1.15rem; }
  .upgrade { display: flex; flex-direction: column; gap: 12px; margin-top: 22px; padding-top: 18px; border-top: 1px solid rgba(241, 235, 224, 0.16); }
  .upgrade[hidden], .upgrade-offer[hidden], .upgrade-pending[hidden] { display: none; }
  .upgrade-pending { display: flex; flex-direction: column; gap: 12px; }
  .upgrade-offer .ghost, .upgrade-pending .ghost { align-self: flex-start; }
  .upgrade p { margin: 0; color: var(--dust); max-width: 38ch; }
  .upgrade b { color: var(--chalk); }
  .upgrade-active { font-family: var(--mono); font-size: 0.85rem; }
  .upgrade-offer { display: flex; flex-direction: column; gap: 12px; }
  .upgrade-msg { font-size: 0.85rem; }
  .upgrade-msg:empty { display: none; }
  /* Same tile as the results screen's .stats, at three across: five tiles
     (played, best, average, current streak, max streak) read better in two
     short rows than crammed four-wide with long labels wrapping. */
  .tiles { grid-template-columns: repeat(3, 1fr); }
  .tiles span { font-size: 0.6rem; }

  /* The per-topic breakdown: a notebook list, like .recap, one row per topic. */
  .topic-stats { list-style: none; margin: 0; padding: 4px 16px 8px; }
  .topic-stats li { padding: 12px 0; }
  .topic-stats li + li { border-top: 1px dashed rgba(31, 26, 21, 0.22); }
  .topic-row-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
  .topic-name { font-family: var(--display); font-weight: 700; font-size: 1.02rem; color: var(--ink); }
  .topic-count { font-family: var(--mono); font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-soft); white-space: nowrap; }
  .bar-line { display: grid; grid-template-columns: 66px 1fr 34px; align-items: center; gap: 8px; margin-top: 8px; }
  .bar-tag { font-family: var(--mono); font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-soft); }
  .bar { height: 8px; border-radius: 4px; background: rgba(31, 26, 21, 0.12); overflow: hidden; }
  /* Width is set through the CSSOM (el.style.setProperty("--w", ...)) at
     render time, never an inline style= attribute: the CSP forbids that. */
  .bar-fill { display: block; height: 100%; width: var(--w, 0%); border-radius: 4px; }
  .bar-fill.l1 { background: var(--l1); }
  .bar-fill.l2 { background: var(--l2); }
  .bar-fill.l3 { background: var(--l3); }
  .bar-fill.l4 { background: var(--l4); }
  .bar-num { font-family: var(--mono); font-weight: 700; font-size: 0.8rem; color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; }
