/* ============================================================
   Forum Design System — TOKENS
   Single source of truth for all design values. No raw hex/px/oklch
   outside this file; reference the variables everywhere else.
   Ported verbatim from the approved mockups in "Forum Designs/".
   ============================================================ */
:root{
  /* Brand */
  --nd-navy:#0C2340;
  --nd-navy-2:#0a1c32;
  --nd-green:oklch(0.48 0.115 150);
  --nd-green-hover:oklch(0.43 0.12 150);
  --nd-green-soft:oklch(0.95 0.04 148);
  --nd-green-ink:oklch(0.35 0.1 150);
  --nd-gold:oklch(0.72 0.14 82);
  --gold:var(--nd-gold);
  --gold-border:color-mix(in srgb, var(--nd-gold) 38%, transparent);
  /* Visited links. --nd-gold's own hue, dropped in lightness until it clears
     WCAG AA (4.5:1) on both --bg and the white card; the accent gold itself is
     only 2.4:1 and unreadable at title size. Mixing toward navy also works but
     desaturates into olive, so darken in oklch and keep hue 82. */
  --link-visited:oklch(0.56 0.125 82);
  --accent:var(--nd-navy);
  --accent-hover:#0a1c32;
  --accent-tint:rgba(12,35,64,0.08);

  /* Surfaces & ink */
  --bg:oklch(0.985 0.006 85);
  --bg-sunk:oklch(0.97 0.008 82);
  --bg-elevated:oklch(0.995 0.004 85);
  --bg-muted:#EDECEA;
  --card:oklch(0.995 0.004 85);
  --card-raised:#ffffff;
  --text:oklch(0.22 0.015 70);
  --text-muted:oklch(0.52 0.01 75);
  --ink:var(--text);
  --ink-2:oklch(0.34 0.012 72);
  --ink-3:var(--text-muted);
  --ink-inverse:#ffffff;
  --ink-4:oklch(0.62 0.008 78);
  --line:oklch(0.9 0.008 80);
  --line-soft:oklch(0.915 0.01 78);
  --line-strong:oklch(0.82 0.01 78);
  --chip-bg:#EDECEA;

  /* Status */
  --success:var(--nd-green);
  --success-tint:rgba(0,132,61,0.12);
  --danger:#c41e1e;
  --danger-tint:rgba(196,30,30,0.12);
  --gold-tint:color-mix(in srgb, var(--nd-gold) 22%, transparent);

  /* Public-site extensions */
  --win:var(--nd-green);
  --loss:var(--danger);
  --live:var(--nd-green);
  --upcoming:var(--ink-3);
  --final:var(--ink-2);
  --ad-frame:var(--line-soft);
  --ad-label-ink:var(--ink-4);

  /* Forum-specific — alias existing tokens but named for forum semantics so
     vote/thread treatments can diverge later without rewriting call sites. */
  --vote-pos:var(--nd-green);
  --vote-neg:var(--danger);
  --thread-rule:var(--line-strong);

  /* Type */
  --font-sans:"Inter",system-ui,sans-serif;
  --font-serif:"Source Serif 4",Georgia,serif;
  --font-title:var(--font-serif);
  --font-mono:"JetBrains Mono",ui-monospace,monospace;

  --type-doc-body-size:18px;
  --type-doc-body-line:1.7;
  --type-meta-size:13px;
  --type-micro-size:11px;
  --type-micro-tracking:0.12em;
  --type-mono-label-size:10px;
  --type-mono-label-tracking:0.12em;

  --type-article-headline-size:clamp(2.25rem, 3.4vw, 3rem);
  --type-section-title-size:0.6875rem;

  /* Post content sizes -- the reader text size setting's territory
     (docs/forum/plans/user-text-size.md). One token per element per surface,
     because the setting does not move them all by the same amount. These are
     the medium values; the setting redefines them for small and large.

     Components read these and nothing else: no rule anywhere, in any media
     query, may set font-size on one of these elements directly. A literal in
     a later-loading file (pages.css loads last) beats the token, and the
     setting silently stops working at that width. */
  /* Surface 1: forum index */
  --fs-thread-subject:16px;       /* .topic-title */
  --fs-thread-meta:12.5px;        /* .topic-meta -- author, time, reply count */
  --fs-reply-subject:13px;        /* .reply-preview .pr-title */
  --fs-reply-meta:11.5px;         /* .reply-preview .pr-by */
  /* Surface 2: reply index (single post) */
  --fs-post-title:clamp(1.5rem, 2.4vw, 2rem); /* .op-title */
  --fs-post-body:17px;            /* .op-body */
  /* 2026-09-15: a reply reads the same wherever it's shown. .rt-title/.rt-meta
     used to run a pixel ahead of .pr-title/.pr-by on purpose ("the thread you
     opened, not a preview of one") -- asked to match instead, and pointing
     these at the index's own tokens makes that permanent rather than two
     numbers that happen to agree today. */
  --fs-tree-subject:var(--fs-reply-subject); /* .rt-title */
  --fs-tree-meta:var(--fs-reply-meta);       /* .rt-meta */
  /* Surface 3: View All -- the focused post is sized to its replies, not to
     the single post page, so it has tokens of its own (see pages.css) */
  --fs-va-subject:18px;           /* .va-title, .va-layout .op-title */
  --fs-va-body:16px;              /* .va-body, .va-layout .op-body */
  --fs-va-meta:13px;              /* .va-byline .who */

  /* Row and section spacing that the setting now moves too (see the small/
     large blocks below) -- medium keeps today's literals exactly; these
     tokens just give the other two steps somewhere to land. */
  --sp-topic-row-v:12px;          /* .topic vertical padding */
  --sp-topic-title-gap:6px;       /* .topic-title-row margin-bottom */
  --sp-reply-preview-gap:8px;     /* .reply-preview margin-top */
  --sp-reply-row-v:3px;           /* .reply-preview .pr-row vertical padding */
  --sp-op-title-gap:12px;         /* .op-title margin-bottom */
  --sp-op-author-pad:10px;        /* .op-author-row vertical padding */
  --sp-op-body-gap:6px;           /* .op-body margin-top, no tools row */
  --sp-op-body-gap-2:14px;        /* .op-author-row + .op-body margin-top */
  --sp-rt-row-v:var(--sp-reply-row-v); /* .rt-row vertical padding -- matches the index's reply row */
  --vote-col-arrow-h:20px;        /* .vote-col button/.upvote/.downvote height */
  --vote-col-score-pad:1px;       /* .vote-col .score vertical padding */
  --lh-reply-row:1.35;            /* .reply-preview .pr-row line-height */
  --lh-tree-subject:var(--lh-reply-row); /* .rt-title line-height -- matches the index's reply row */

  /* Geometry */
  --radius:6px;
  --r-card:8px;
  --r-input:6px;

  /* Shadows */
  --shadow-sm:0 1px 2px rgba(12,35,64,0.06);
  --shadow-card:0 1px 0 oklch(1 0 0 / .9) inset, 0 1px 2px oklch(0.2 0.02 70 / .04), 0 2px 6px oklch(0.2 0.02 70 / .035);

  /* Layout */
  --page-max:1180px;
  --page-pad:32px;
  --utility-h:32px;
  --masthead-h:88px;
}

/* Reader text size: small and large redefine the post content tokens above.
   Medium is :root itself, and the attribute is absent for it (base.twig).
   :root[...] rather than [...] so these outrank the plain :root redefinitions
   inside the phone media query below on specificity, not on source order.

   2026-09-13 rework (docs/forum/plans/user-text-size.md): small now unifies
   every "subject line" size -- a new topic and a reply are the same kind of
   thing to read at a glance, so .topic-title, .pr-title and .rt-title all
   read at one size, with the byline/meta line just slightly under it. Row
   and section spacing also moves now, tightening at small and opening up at
   large -- spacing was deliberately frozen in the original version of this
   feature, but "condensed, no empty whitespace" and "more styled, more
   pleasant" both asked for it to move too. */
:root[data-textsize="small"]{
  /* .topic-title is serif (--font-serif) against .pr-title/.rt-title's sans,
     and at the same px the serif reads visually smaller -- checked in the
     browser next to a reply directly below it. 13.5px against their 13px
     closes that gap; the two are meant to read as the same size, not
     necessarily share a literal number. */
  --fs-thread-subject:13.5px;
  --fs-thread-meta:11.5px;
  --fs-reply-subject:13px;
  --fs-reply-meta:11.5px;
  --fs-post-title:clamp(1.4375rem, 2.3vw, 1.9375rem);
  --fs-post-body:16px;
  --fs-va-subject:17px;
  --fs-va-body:15px;
  --fs-va-meta:12.5px;

  --sp-topic-row-v:8px;
  --sp-topic-title-gap:3px;
  --sp-reply-preview-gap:4px;
  /* 2026-09-14: components.css calls 2px the floor for the reply-tree row's
     hover target and its title's descenders, and that held right up until
     this was checked at small in the browser -- a subject wrapping to two
     lines there made every row's own padding read as real air on top of the
     leading it already has, and the ask was to cut it further despite the
     floor. 1px it is, here and on the index's own reply row (--sp-rt-row-v
     matches this one, tokens.css root); the connector tick position and
     hover band aren't visibly hurt by it at this size. */
  --sp-reply-row-v:1px;
  --sp-op-title-gap:8px;
  --sp-op-author-pad:6px;
  --sp-op-body-gap:4px;
  --sp-op-body-gap-2:8px;
  --lh-reply-row:1.15;
  /* 2026-09-15: the vote column's arrows sit at a fixed height regardless of
     text size, so as the row around it condensed for small, the column's own
     height stopped shrinking with it -- the downvote arrow ended up low
     enough to collide with the reply-preview thread line starting just below
     it. Bring the arrows in against the count instead of leaving them at
     medium's height. */
  --vote-col-arrow-h:15px;
  --vote-col-score-pad:0px;
}
:root[data-textsize="large"]{
  --fs-thread-subject:18px;
  --fs-thread-meta:13.5px;
  --fs-reply-subject:15px;
  --fs-reply-meta:12.5px;
  --fs-post-title:clamp(1.625rem, 2.6vw, 2.125rem);
  --fs-post-body:19px;
  --fs-va-subject:20px;
  --fs-va-body:18px;
  --fs-va-meta:14px;

  --sp-topic-row-v:16px;
  --sp-topic-title-gap:9px;
  --sp-reply-preview-gap:12px;
  --sp-reply-row-v:5px;
  --sp-op-title-gap:18px;
  --sp-op-author-pad:14px;
  --sp-op-body-gap:10px;
  --sp-op-body-gap-2:18px;
  --lh-reply-row:1.4;
  --vote-col-arrow-h:22px;
  --vote-col-score-pad:2px;
}

/* The page gutter is the one token that has to move with the viewport. At
   32px a side it eats ~16% of a 390px phone as empty margin, which is what
   made the topic cards read as cramped. Redefined rather than overridden per
   component so all four consumers travel together — .page (base.css),
   .utility-inner, .masthead-inner and .footer-inner (chrome.css) — keeping the
   search field, wordmark, breadcrumbs, cards and footer on one left edge.
   Still a real margin, so the cards keep the border and shadow that read well
   on desktop; this narrows the gutter rather than going edge-to-edge. */
@media (max-width:640px){
  :root{--page-pad:14px}
  /* Phone: the index preview's reply subject was the smallest thing on the
     card that a reader is actually meant to read — 12.5px against the topic
     title, and only 1px clear of its own 11.5px byline. On a phone that read
     as caption text rather than as a list of posts to choose from, so the
     subjects were being skipped.

     13.5px puts 2px between the subject and its byline, which is enough for
     the subject to lead. 14px was tried first and read too large against the
     rows around it. It is the only post content size that differs by width;
     the reply tree keeps its 14px everywhere — it is the post you opened
     rather than a preview of one, so its subject never competed with a byline
     the way this one did. */
  :root{--fs-reply-subject:13.5px}
  /* Each step's own phone value, after the step block above so it wins at
     equal specificity. Small pins this back to its own (now unified) desktop
     value rather than inheriting medium's phone bump, or the reply subject
     would read larger than the topic subject it's supposed to match. Large
     just matches its own desktop value for the same reason. */
  :root[data-textsize="small"]{--fs-reply-subject:13px}
  :root[data-textsize="large"]{--fs-reply-subject:15px}
}
