/* ============================================================================
   polygeek — EDITORIAL DESIGN  (LogosPress canonical, v0.2)
   ----------------------------------------------------------------------------
   Newsreader (serif, display + body) + JetBrains Mono (labels/meta/code).
   Warm paper, warm ink, single terracotta accent. Fully tokenized: every
   visual value lives in the :root block below — reskin the whole site by
   overriding those custom properties alone. Component CSS only references
   var()s; it never hardcodes a color, font, size, radius, or width.

   Source: Claude Design handoff (polygeek-skeleton), implemented 2026-06-02.
   Self-hosted fonts (no third-party CDN), automatic dark mode, print floor.
   ========================================================================== */

/* ---- Self-hosted fonts ----------------------------------------------------
   WOFF2 variable fonts served locally from /assets/fonts/ — no Google CDN
   request, faster + privacy-clean. font-optical-sizing pulls Newsreader's
   opsz axis automatically. */
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("/assets/fonts/newsreader.woff2") format("woff2");
}
@font-face {
  font-family: "Newsreader";
  font-style: italic;
  font-weight: 200 800;
  font-display: swap;
  src: url("/assets/fonts/newsreader-italic.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/jetbrains-mono.woff2") format("woff2");
}

:root {
  /* ---- Type families --------------------------------------------------- */
  --font-display: "Newsreader", Georgia, "Times New Roman", serif;
  --font-body:    "Newsreader", Georgia, "Times New Roman", serif;
  --font-mono:    "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* ---- Type scale (fluid where it earns it) --------------------------- */
  --fs-2xs:  0.72rem;
  --fs-xs:   0.80rem;
  --fs-sm:   0.92rem;
  --fs-base: 1.0625rem;                                   /* ~17px body    */
  --fs-md:   clamp(1.18rem, 0.4vw + 1.05rem, 1.32rem);
  --fs-lg:   clamp(1.4rem,  0.8vw + 1.2rem,  1.65rem);
  --fs-xl:   clamp(1.7rem,  1.4vw + 1.3rem,  2.15rem);
  --fs-2xl:  clamp(2.1rem,  2.6vw + 1.4rem,  3.1rem);
  --fs-3xl:  clamp(2.6rem,  4.2vw + 1.4rem,  4.2rem);
  --fs-display: clamp(3rem, 6vw + 1.2rem,    5.6rem);

  /* ---- Line height ----------------------------------------------------- */
  --lh-solid:   1;
  --lh-tight:   1.08;
  --lh-snug:    1.24;
  --lh-normal:  1.5;
  --lh-relaxed: 1.72;

  /* ---- Letter spacing -------------------------------------------------- */
  --ls-tighter: -0.025em;
  --ls-tight:   -0.012em;
  --ls-normal:  0;
  --ls-wide:    0.04em;
  --ls-label:   0.16em;                                   /* mono eyebrows */

  /* ---- Weight ---------------------------------------------------------- */
  --fw-light:    300;
  --fw-normal:   400;
  --fw-medium:   500;
  --fw-semibold: 600;
  --fw-bold:     700;

  /* ---- Color: surfaces & ink (warm neutral) --------------------------- */
  --c-bg:            oklch(0.987 0.006 83);               /* warm paper    */
  --c-surface:       oklch(1 0 0);                        /* raised cards  */
  --c-surface-sunken:oklch(0.965 0.008 83);              /* wells, code   */
  --c-ink:           oklch(0.255 0.012 66);              /* body ink      */
  --c-ink-strong:    oklch(0.19 0.013 66);               /* headlines     */
  --c-ink-soft:      oklch(0.44 0.011 66);               /* secondary     */
  --c-muted:         oklch(0.58 0.009 66);               /* metadata      */
  --c-faint:         oklch(0.7 0.008 66);                /* placeholders  */

  /* ---- Color: lines ---------------------------------------------------- */
  --c-border:        oklch(0.905 0.008 78);
  --c-border-strong: oklch(0.82 0.01 78);

  /* ---- Color: accent (terracotta / clay) ------------------------------ */
  --c-accent:        oklch(0.565 0.135 42);
  --c-accent-strong: oklch(0.485 0.135 42);              /* hover/active  */
  --c-accent-soft:   oklch(0.95 0.028 52);               /* tint wash     */
  --c-accent-line:   oklch(0.86 0.05 48);                /* tint border   */
  --c-on-accent:     oklch(0.99 0.008 83);               /* text on accent*/

  /* ---- Color: roles ---------------------------------------------------- */
  --c-link:          var(--c-accent);
  --c-link-hover:    var(--c-accent-strong);
  --c-selection:     var(--c-accent-soft);

  /* ---- Spacing scale --------------------------------------------------- */
  --sp-0:  0;
  --sp-1:  0.25rem;
  --sp-2:  0.5rem;
  --sp-3:  0.75rem;
  --sp-4:  1rem;
  --sp-5:  1.5rem;
  --sp-6:  2rem;
  --sp-7:  3rem;
  --sp-8:  4rem;
  --sp-9:  6rem;
  --sp-10: 8rem;
  --sp-11: 11rem;

  /* ---- Radius ---------------------------------------------------------- */
  --r-xs:   3px;
  --r-sm:   6px;
  --r-md:   10px;
  --r-lg:   18px;
  --r-pill: 999px;

  /* ---- Layout widths --------------------------------------------------- */
  --w-prose:   42rem;                                     /* article text  */
  --w-narrow:  54rem;
  --w-content: 72rem;                                     /* page shell    */
  --w-wide:    78rem;

  /* ---- Borders --------------------------------------------------------- */
  --bd-hair:  1px;
  --bd-thick: 2px;
  --border:        var(--bd-hair) solid var(--c-border);
  --border-strong: var(--bd-hair) solid var(--c-border-strong);

  /* ---- Elevation ------------------------------------------------------- */
  --shadow-sm: 0 1px 2px oklch(0.255 0.012 66 / 0.05);
  --shadow-md: 0 6px 24px -10px oklch(0.255 0.012 66 / 0.18);
  --shadow-lg: 0 18px 50px -18px oklch(0.255 0.012 66 / 0.28);
  /* Optional button glow hook — default off; themes can opt into an outer glow. */
  --btn-shadow: none;
  /* Optional chip glow hook — default off; themes can opt into a soft outer glow. */
  --chip-shadow: none;

  /* ---- Motion ---------------------------------------------------------- */
  --dur-fast: 120ms;
  --dur:      180ms;
  --ease:     cubic-bezier(0.2, 0.6, 0.2, 1);

  /* ---- Decorative placeholder fill (imagery drop zones) --------------- */
  --ph-stripe: repeating-linear-gradient(
    135deg,
    var(--c-border) 0 1px,
    transparent 1px 11px
  );
}

/* ---- Automatic dark mode -------------------------------------------------
   Because every visual value is a token, dark mode is a pure token swap:
   the component CSS below is untouched. Warm-dark paper, light ink, a
   slightly brighter terracotta so links/CTAs stay legible on dark. */
@media (prefers-color-scheme: dark) {
  :root {
    --c-bg:            oklch(0.185 0.011 66);
    --c-surface:       oklch(0.225 0.012 66);
    --c-surface-sunken:oklch(0.16 0.010 66);
    --c-ink:           oklch(0.90 0.010 83);
    --c-ink-strong:    oklch(0.965 0.008 83);
    --c-ink-soft:      oklch(0.74 0.011 83);
    --c-muted:         oklch(0.62 0.010 83);
    --c-faint:         oklch(0.50 0.009 83);

    --c-border:        oklch(0.32 0.010 78);
    --c-border-strong: oklch(0.44 0.012 78);

    --c-accent:        oklch(0.72 0.130 46);
    --c-accent-strong: oklch(0.80 0.120 48);
    --c-accent-soft:   oklch(0.30 0.055 46);
    --c-accent-line:   oklch(0.42 0.070 46);
    --c-on-accent:     oklch(0.17 0.012 66);

    --shadow-sm: 0 1px 2px oklch(0 0 0 / 0.30);
    --shadow-md: 0 6px 24px -10px oklch(0 0 0 / 0.55);
    --shadow-lg: 0 18px 50px -18px oklch(0 0 0 / 0.65);
  }
}

/* ============================================================================
   COMPONENT CSS — references theme tokens only. No literal visual values.
   ========================================================================== */

/* ---- Reset / base ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-ink);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  font-weight: var(--fw-normal);
  letter-spacing: var(--ls-normal);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: "kern", "liga", "onum", "pnum";
}

::selection { background: var(--c-selection); }

img { max-width: 100%; display: block; }

a {
  color: var(--c-link);
  text-decoration: none;
  text-underline-offset: 0.2em;
  text-decoration-thickness: var(--bd-hair);
  transition: color var(--dur) var(--ease);
}
a:hover { color: var(--c-link-hover); }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--c-ink-strong);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  margin: 0;
  text-wrap: balance;
}

p { margin: 0; text-wrap: pretty; }

hr {
  border: 0;
  border-top: var(--border);
  margin: var(--sp-7) 0;
}

/* ---- Layout shell ------------------------------------------------------- */
.shell {
  width: 100%;
  max-width: var(--w-content);
  margin-inline: auto;
  padding-inline: var(--sp-5);
}
.shell--narrow { max-width: var(--w-narrow); }
.shell--prose  { max-width: var(--w-prose); }

.section { padding-block: var(--sp-8); }
.section--tight { padding-block: var(--sp-7); }
.section--lead  { padding-block: var(--sp-9); }

/* ---- Eyebrow / kicker / labels ----------------------------------------- */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-accent);
  margin: 0;
}
.eyebrow--muted { color: var(--c-muted); }

.meta {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  color: var(--c-muted);
}

/* ---- Masthead / nav ----------------------------------------------------- */
.masthead {
  border-bottom: var(--border);
  background: color-mix(in oklab, var(--c-bg) 86%, transparent);
  backdrop-filter: saturate(1.4) blur(8px);
  position: sticky;
  top: 0;
  z-index: 50;
}
.masthead__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-5);
  padding-block: var(--sp-4);
}
.wordmark {
  font-family: var(--font-display);
  font-weight: var(--fw-bold);
  font-size: var(--fs-lg);
  letter-spacing: var(--ls-tighter);
  color: var(--c-ink-strong);
  line-height: var(--lh-solid);
}
.wordmark:hover { color: var(--c-ink-strong); }
.wordmark .dot { color: var(--c-accent); }

/* Promo masthead (ui.masthead — en.runpee.com, Dan 2026-08-26): the header IS
   the advert. Logo + one-sentence pitch on the left, store badges above the nav
   on the right. Every rule here is scoped to .masthead--promo or to a class only
   that variant emits, so polygeek.com and cn.runpee.com are byte-identical. */
.masthead--promo .masthead__bar {
  align-items: center;
  gap: var(--sp-5);
}
.masthead__brand {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-width: 0;
  color: var(--c-ink-soft);
}
.masthead__brand:hover { color: var(--c-ink-soft); }
.masthead__logo {
  display: block;
  flex: none;
  height: 4.25rem;
  width: auto;
}
.masthead__pitch {
  display: grid;
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
}
/* Dan wrote the pitch as `*run* and *pee*`, so it arrives as <em>. Upright and
   accented reads as the brand's own emphasis; italic serif reads as a citation. */
.masthead__pitch em {
  font-style: normal;
  font-weight: var(--fw-bold);
  color: var(--c-accent);
}
.masthead__aside {
  display: flex;
  flex: none;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-3);
}
.masthead__stores {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
/* Native size is 100x30 (Dan's own WP assets). Pinned to it rather than scaled
   up — these are bitmaps with baked-in wordmarks and they smear when enlarged. */
.masthead__store img { display: block; height: 30px; width: auto; }

.nav {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
}
.nav a {
  color: var(--c-ink-soft);
  position: relative;
  padding-block: var(--sp-1);
}
.nav a:hover { color: var(--c-ink-strong); }
.nav a[aria-current="page"] { color: var(--c-ink-strong); }
.nav a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: calc(-1 * var(--sp-1));
  height: var(--bd-thick);
  background: var(--c-accent);
}
.nav .nav__rss { color: var(--c-accent); }

/* ---- Buttons ------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  line-height: var(--lh-solid);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--r-pill);
  border: var(--bd-hair) solid transparent;
  box-shadow: var(--btn-shadow);
  cursor: pointer;
  transition: background var(--dur) var(--ease),
              color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn--primary {
  background: var(--c-accent);
  color: var(--c-on-accent);
}
.btn--primary:hover { background: var(--c-accent-strong); color: var(--c-on-accent); }

/* Dan, 2026-08-12: every pill button carries the gold. The ghost variant used
   to be a transparent fill over --c-ink-strong text, which meant it inherited
   whatever was behind it — on the dark-mode cn homepage that was near-white
   label text on a pale cream card, i.e. invisible. Filling it retires the whole
   class of bug rather than retuning one colour. Primary and ghost now render
   identically; the `style: ghost` config key is kept so they can diverge again
   without a template change. */
.btn--ghost {
  background: var(--c-accent);
  color: var(--c-on-accent);
  border-color: transparent;
}
.btn--ghost:hover { background: var(--c-accent-strong); color: var(--c-on-accent); }

.btn--lg { font-size: var(--fs-sm); padding: var(--sp-4) var(--sp-6); }

.btn .arrow { transition: transform var(--dur) var(--ease); }
.btn:hover .arrow { transform: translateX(3px); }

/* ---- Text link with arrow ---------------------------------------------- */
.tlink {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-accent);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}
.tlink .arrow { transition: transform var(--dur) var(--ease); }
.tlink:hover .arrow { transform: translateX(3px); }

/* ---- Tags --------------------------------------------------------------- */
.tags { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
/* Plain text, no pill (Dan, 2026-08-17). The chip outline read as a category
   badge, which made a film name look like a genre — "The Odyssey" sitting in
   the same box as "Peetimes". Tags are a list of words; the underline on hover
   is enough to say they're links. */
.tag {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-wide);
  color: var(--c-muted);
  text-decoration: none;
}
.tag:hover,
.tag:focus-visible { color: var(--c-link); text-decoration: underline; }
/* Without the pills the words need their own separator, or they read as one
   run-on string — on the tags index that was "Behind the Scenes 5 About 3
   Peetime 3", with the counts blurring into the next tag's name.

   The separator TRAILS each item rather than leading the next one. Both read
   identically on a single line, but these are flex-wrap lists: a leading
   separator puts a stray "·" at the start of every wrapped line, where it is
   glaring. A trailing one ends a line instead, where it reads as continuation. */
.tags { gap: var(--sp-1) var(--sp-3); }
/* .tagcloud's own gap is set in the Tags-index block below; don't restate it
   here or the two silently disagree and the later one quietly wins. */
.tags .tag:not(:last-child)::after,
.tagcloud li:not(:last-child)::after {
  content: "·";
  margin-left: var(--sp-3);
  color: var(--c-border-strong);
  text-decoration: none;
  display: inline-block;
}

/* ---- Tags index (popularity) -------------------------------------------- */
.tagcloud {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  list-style: none;
  padding: 0;
  margin: var(--sp-4) 0 0;
}
.tagcloud li { margin: 0; }
.tag__count {
  margin-left: var(--sp-1);
  opacity: 0.6;
  font-variant-numeric: tabular-nums;
}

/* ---- Image placeholder -------------------------------------------------- */
.ph {
  background-color: var(--c-surface-sunken);
  background-image: var(--ph-stripe);
  border: var(--border);
  border-radius: var(--r-md);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--c-faint);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  text-align: center;
  padding: var(--sp-4);
  aspect-ratio: 16 / 9;
}
.ph--portrait { aspect-ratio: 4 / 5; }
.ph--square   { aspect-ratio: 1 / 1; }
.ph--avatar   { aspect-ratio: 1 / 1; border-radius: var(--r-pill); }

/* ========================================================================
   HOME / BLOG INDEX
   ===================================================================== */
.intro {
  border-bottom: var(--border);
  padding-block: var(--sp-8) var(--sp-7);
}
.intro__statement {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
  color: var(--c-ink-strong);
  max-width: var(--w-narrow);
  margin-top: var(--sp-4);
}
.intro__statement em { color: var(--c-accent); font-style: italic; }
.intro__sub {
  margin-top: var(--sp-5);
  color: var(--c-ink-soft);
  font-size: var(--fs-md);
  max-width: var(--w-prose);
}

/* Lead / featured article */
.lead {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: var(--sp-7);
  align-items: center;
  padding-block: var(--sp-8);
  border-bottom: var(--border);
}
.lead__media { border-radius: var(--r-lg); overflow: hidden; }
.lead__media .ph { aspect-ratio: 5 / 4; border-radius: var(--r-lg); }
.lead__title {
  font-size: var(--fs-2xl);
  margin-block: var(--sp-3) var(--sp-4);
  font-weight: var(--fw-bold);
}
.lead__title a { color: inherit; }
.lead__title a:hover { color: var(--c-accent); }
.lead__dek {
  font-size: var(--fs-md);
  color: var(--c-ink-soft);
  margin-bottom: var(--sp-5);
}
.lead__foot { display: flex; align-items: center; gap: var(--sp-5); flex-wrap: wrap; }

/* Section heading row */
.rowhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-bottom: var(--sp-5);
  margin-bottom: var(--sp-2);
  border-bottom: var(--border-strong);
}
.rowhead h2 { font-size: var(--fs-lg); font-weight: var(--fw-semibold); }

/* Post list */
.postlist { display: grid; gap: var(--sp-0); }
.post {
  display: grid;
  grid-template-columns: 9rem 1fr auto;
  gap: var(--sp-6);
  align-items: baseline;
  padding-block: var(--sp-6);
  border-bottom: var(--border);
}
.post:hover .post__title a { color: var(--c-accent); }
.post__date {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--c-muted);
  letter-spacing: var(--ls-wide);
  padding-top: var(--sp-2);
}
.post__title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-medium);
  margin-bottom: var(--sp-2);
}
.post__title a { color: var(--c-ink-strong); }
.post__dek { color: var(--c-ink-soft); font-size: var(--fs-base); margin-bottom: var(--sp-3); }
.post__read {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--c-muted);
  white-space: nowrap;
  padding-top: var(--sp-2);
}
/* ---- Archive + tag listing --------------------------------------------- */
.archive { padding-block: var(--sp-8) var(--sp-9); }
.archive-title {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight);
  line-height: var(--lh-tight);
  margin: 0 0 var(--sp-2);
}
.archive-lede {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-muted);
  margin: 0 0 var(--sp-7);
}
.archive-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: var(--border);
}
.archive-item {
  display: grid;
  grid-template-columns: 9rem 1fr auto;
  gap: var(--sp-5);
  align-items: baseline;
  padding-block: var(--sp-4);
  border-bottom: var(--border);
}
.archive-item time {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--c-muted);
  letter-spacing: var(--ls-wide);
}
.archive-item a {
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  color: var(--c-ink-strong);
  transition: color var(--dur) var(--ease);
}
.archive-item:hover a { color: var(--c-accent); }
.archive-read {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--c-muted);
  letter-spacing: var(--ls-wide);
  white-space: nowrap;
}
@media (max-width: 36rem) {
  .archive-item { grid-template-columns: 1fr auto; gap: var(--sp-2) var(--sp-4); }
  .archive-item time { grid-column: 1 / -1; order: -1; }
}

/* ---- Consulting promo strip (home) ------------------------------------- */
.promo {
  background: var(--c-accent-soft);
  border: var(--bd-hair) solid var(--c-accent-line);
  border-radius: var(--r-lg);
  padding: var(--sp-7);
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-6);
  align-items: center;
}
.promo__title {
  font-size: var(--fs-xl);
  margin-block: var(--sp-2) var(--sp-3);
  max-width: 28ch;
}
.promo__text { color: var(--c-ink-soft); max-width: 48ch; }

/* ========================================================================
   ARTICLE
   ===================================================================== */
.article__header {
  padding-block: var(--sp-8) var(--sp-6);
  border-bottom: var(--border);
}
.article__title {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-bold);
  margin-block: var(--sp-4) var(--sp-5);
}
.article__dek {
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  color: var(--c-ink-soft);
  font-weight: var(--fw-light);
  max-width: var(--w-prose);
}
.byline {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-top: var(--sp-6);
}
.byline .ph--avatar { width: var(--sp-7); height: var(--sp-7); flex: none; }
.byline__who { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--c-ink-soft); letter-spacing: var(--ls-wide); }
.byline__who strong { color: var(--c-ink-strong); font-weight: var(--fw-medium); }

.article__figure { margin-block: var(--sp-7); }
.article__figure .ph { aspect-ratio: 16 / 9; }
.article__figure figcaption {
  margin-top: var(--sp-3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--c-muted);
  text-align: center;
}

/* Prose */
.prose { padding-block: var(--sp-7); font-size: var(--fs-base); }
.prose > * + * { margin-top: var(--sp-5); }
.prose h2 {
  font-size: var(--fs-xl);
  font-weight: var(--fw-semibold);
  margin-top: var(--sp-8);
  margin-bottom: var(--sp-2);
}
.prose h3 {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  margin-top: var(--sp-7);
}
.prose p { color: var(--c-ink); }
.prose a { text-decoration: underline; }
.prose strong { font-weight: var(--fw-semibold); color: var(--c-ink-strong); }
.prose ul, .prose ol { margin-left: var(--sp-5); padding-left: var(--sp-4); color: var(--c-ink); }
.prose li + li { margin-top: var(--sp-2); }
.prose blockquote {
  margin-inline: 0;
  padding: var(--sp-2) 0 var(--sp-2) var(--sp-5);
  border-left: var(--bd-thick) solid var(--c-accent);
  color: var(--c-ink-soft);
  font-style: italic;
  font-size: var(--fs-md);
}
.prose figure { margin: var(--sp-7) 0; }
.prose img { border-radius: var(--r-md); }
.prose code {
  font-family: var(--font-mono);
  font-size: 0.86em;
  background: var(--c-surface-sunken);
  border: var(--border);
  border-radius: var(--r-xs);
  padding: 0.1em 0.4em;
}
.prose pre {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
  background: var(--c-surface-sunken);
  border: var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-5);
  /* Wrap long lines instead of a horizontal-scroll inset. pre-wrap keeps the
     indentation + line breaks; overflow-wrap breaks any overlong token. */
  white-space: pre-wrap;
  overflow-wrap: break-word;
}
.prose pre code { background: none; border: 0; padding: 0; font-size: inherit; }

/* Tables. Parsedown emits a bare <table> with no wrapper, so everything here
   has to work on the element itself. `width: max-content` + `max-width: 100%`
   is the GitHub rule: a narrow table keeps its natural width, a wide one
   clamps to the column and wraps inside the cells rather than pushing the
   page sideways. Row rules do the actual work of tracking across a wide
   row — without them a 32-row returner chart is unreadable (Ink, 2026-09-03;
   these selectors matched nothing before, so this is additive). */
.prose table {
  display: block;
  width: max-content;
  max-width: 100%;
  overflow-x: auto;
  border-collapse: collapse;
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
}
.prose th,
.prose td {
  padding: var(--sp-2) var(--sp-4);
  text-align: left;
  vertical-align: top;          /* a wrapped cell must not float against a short neighbour */
  border-bottom: var(--border);
}
.prose th {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide);
  color: var(--c-ink-soft);
  border-bottom: var(--border-strong);
  white-space: nowrap;
}
/* First column is the key (team code, language, grade) — keep it on one line
   so it reads as a spine down the left edge. */
.prose td:first-child { white-space: nowrap; color: var(--c-ink-strong); }
.prose tbody tr:last-child td { border-bottom: 0; }
.prose th:first-child,
.prose td:first-child { padding-left: 0; }
.prose th:last-child,
.prose td:last-child  { padding-right: 0; }

.pullquote {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
  color: var(--c-ink-strong);
  letter-spacing: var(--ls-tight);
  border-top: var(--border-strong);
  border-bottom: var(--border-strong);
  padding-block: var(--sp-6);
  margin-block: var(--sp-7);
  text-align: center;
}

/* Author bio + work-with-me CTA (article foot) */
.biocta {
  margin-top: var(--sp-8);
  border: var(--border);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  box-shadow: var(--shadow-sm);
  padding: var(--sp-7);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-6);
  align-items: start;
}
.biocta .ph--avatar { width: calc(var(--sp-8) + var(--sp-2)); height: calc(var(--sp-8) + var(--sp-2)); flex: none; }
.biocta__avatar { width: calc(var(--sp-8) + var(--sp-2)); height: calc(var(--sp-8) + var(--sp-2)); flex: none; border-radius: var(--r-pill); object-fit: cover; border: var(--border); }
.biocta__name { font-size: var(--fs-lg); font-weight: var(--fw-semibold); }
.biocta__role { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--c-accent); letter-spacing: var(--ls-wide); text-transform: uppercase; margin-top: var(--sp-1); }
.biocta__text { color: var(--c-ink-soft); margin-block: var(--sp-4); max-width: 60ch; }
.biocta__actions { display: flex; gap: var(--sp-3); flex-wrap: wrap; align-items: center; }

/* Related posts (article foot) — design vocabulary */
.related {
  margin-top: var(--sp-8);
  padding-top: var(--sp-6);
  border-top: var(--border-strong);
}
.related__head {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--c-muted);
  font-weight: var(--fw-medium);
  margin-bottom: var(--sp-5);
}
.related__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-4); }
.related__list a { color: var(--c-ink-strong); font-size: var(--fs-md); font-weight: var(--fw-medium); }
.related__list a:hover { color: var(--c-accent); }
.related__list p { color: var(--c-ink-soft); font-size: var(--fs-sm); margin-top: var(--sp-1); }

.backlink { margin-top: var(--sp-7); }

/* ========================================================================
   CONSULTING
   ===================================================================== */
.chero {
  padding-block: var(--sp-9) var(--sp-8);
  border-bottom: var(--border);
}
.chero__grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: var(--sp-8);
  align-items: center;
}
.chero__title {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-bold);
  margin-block: var(--sp-4) var(--sp-5);
}
.chero__title em { color: var(--c-accent); font-style: italic; }
.chero__lede { font-size: var(--fs-lg); color: var(--c-ink-soft); line-height: var(--lh-snug); max-width: 46ch; }
.chero__actions { display: flex; gap: var(--sp-4); align-items: center; flex-wrap: wrap; margin-top: var(--sp-6); }
.chero__note { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--c-muted); margin-top: var(--sp-4); letter-spacing: var(--ls-wide); }
.chero__card { border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-md); }
.chero__card .ph { aspect-ratio: 4 / 5; border-radius: var(--r-lg); }
.chero__card .chero__photo { display: block; width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }

/* Generic section heading */
.shead { max-width: var(--w-prose); margin-bottom: var(--sp-6); }
.shead h2 { font-size: var(--fs-2xl); margin-top: var(--sp-3); }
.shead p { color: var(--c-ink-soft); font-size: var(--fs-md); margin-top: var(--sp-4); }

/* Steps */
.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
  counter-reset: step;
}
.step {
  border-top: var(--bd-thick) solid var(--c-ink-strong);
  padding-top: var(--sp-4);
}
.step__n {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-label);
  color: var(--c-accent);
}
.step h3 { font-size: var(--fs-lg); margin-block: var(--sp-3) var(--sp-3); }
.step p { color: var(--c-ink-soft); }

/* Feature list (what you'll build / who it's for) */
.features { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-3) var(--sp-7); }
.feature {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-4);
  padding-block: var(--sp-5);
  border-bottom: var(--border);
  align-items: start;
}
.feature__mark {
  font-family: var(--font-mono);
  color: var(--c-accent);
  font-size: var(--fs-md);
  line-height: var(--lh-snug);
}
.feature h3 { font-size: var(--fs-md); font-weight: var(--fw-semibold); margin-bottom: var(--sp-2); }
.feature p { color: var(--c-ink-soft); font-size: var(--fs-sm); }

/* Tools panel */
.tools {
  background: var(--c-surface);
  border: var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  display: grid;
  grid-template-columns: 1fr 1fr;
}
.tool { padding: var(--sp-7); }
.tool + .tool { border-left: var(--border); }
.tool__name { font-size: var(--fs-lg); font-weight: var(--fw-semibold); display: flex; align-items: baseline; gap: var(--sp-3); }
.tool__name .chip {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-accent);
  border: var(--bd-hair) solid var(--c-accent-line);
  border-radius: var(--r-pill);
  padding: var(--sp-1) var(--sp-3);
  box-shadow: var(--chip-shadow);
}
.tool p { color: var(--c-ink-soft); margin-top: var(--sp-3); font-size: var(--fs-sm); }

/* Pricing / format band */
.band {
  background: var(--c-ink-strong);
  color: var(--c-bg);
  border-radius: var(--r-lg);
  padding: var(--sp-8);
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-6);
  align-items: center;
}
.band h2 { color: var(--c-bg); font-size: var(--fs-2xl); }
.band p { color: color-mix(in oklab, var(--c-bg) 78%, var(--c-accent)); margin-top: var(--sp-3); max-width: 44ch; }
.band .eyebrow { color: var(--c-on-accent); }
.band__col { text-align: right; }
.band .btn--primary { background: var(--c-bg); color: var(--c-ink-strong); }
.band .btn--primary:hover { background: var(--c-on-accent); color: var(--c-ink-strong); }
.band__price { font-family: var(--font-display); font-size: var(--fs-2xl); font-weight: var(--fw-bold); }
.band__price small { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: var(--fw-normal); letter-spacing: var(--ls-wide); display: block; color: color-mix(in oklab, var(--c-bg) 70%, var(--c-accent)); margin-top: var(--sp-2); }

/* FAQ */
.faq { display: grid; gap: var(--sp-0); }
.qa { padding-block: var(--sp-5); border-bottom: var(--border); display: grid; grid-template-columns: 1fr 1.4fr; gap: var(--sp-6); }
.qa h3 { font-size: var(--fs-md); font-weight: var(--fw-semibold); }
.qa p { color: var(--c-ink-soft); font-size: var(--fs-sm); }

/* ========================================================================
   GENERIC PAGE (markdown body, e.g. /about/, /logos/, error pages)
   ===================================================================== */
.page__header { padding-block: var(--sp-8) var(--sp-5); border-bottom: var(--border); }
.page__title { font-size: var(--fs-3xl); font-weight: var(--fw-bold); }
.page__lede { color: var(--c-ink-soft); font-size: var(--fs-md); margin-top: var(--sp-4); }

/* ========================================================================
   FOOTER
   ===================================================================== */
.foot {
  border-top: var(--border);
  margin-top: var(--sp-9);
  padding-block: var(--sp-8) var(--sp-7);
}
.foot__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: var(--sp-7);
  align-items: start;
}
.foot__blurb { color: var(--c-ink-soft); max-width: 42ch; margin-top: var(--sp-3); }
.foot__col h4 {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--c-muted);
  font-weight: var(--fw-medium);
  margin-bottom: var(--sp-4);
}
.foot__col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3); }
.foot__col a { color: var(--c-ink-soft); font-size: var(--fs-sm); }
.foot__col a:hover { color: var(--c-ink-strong); }
/* Paid-placement row: deliberately quiet — one small line above the base. */
.foot__sponsored {
  margin-top: var(--sp-6);
  font-size: var(--fs-2xs);
  color: var(--c-muted);
}
.foot__sponsored a { color: var(--c-muted); }
.foot__sponsored a:hover { color: var(--c-ink-soft); }
.foot__base {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-4);
  margin-top: var(--sp-8);
  padding-top: var(--sp-5);
  border-top: var(--border);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--c-muted);
  letter-spacing: var(--ls-wide);
}
.foot__base a { color: var(--c-muted); }
.foot__base a:hover { color: var(--c-ink-strong); }
/* Compact variant (ui.footer_style === 'compact'): no wordmark column, SITE
   (+ RSS) runs as one wrapping horizontal list instead of a stacked grid. */
.foot__compact-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
}
.foot__compact-list li { display: flex; align-items: baseline; }
.foot__compact-list li:not(:last-child)::after {
  content: '·';
  margin: 0 var(--sp-3);
  color: var(--c-muted);
}
.foot__compact-list a { color: var(--c-ink-soft); font-size: var(--fs-sm); }
.foot__compact-list a:hover { color: var(--c-ink-strong); }

/* ========================================================================
   RESPONSIVE
   ===================================================================== */
@media (max-width: 56rem) {
  .lead, .chero__grid, .promo, .biocta, .band { grid-template-columns: 1fr; }
  .steps, .features { grid-template-columns: 1fr; }
  .tools { grid-template-columns: 1fr; }
  .tool + .tool { border-left: 0; border-top: var(--border); }
  .qa { grid-template-columns: 1fr; gap: var(--sp-2); }
  .foot__grid { grid-template-columns: 1fr 1fr; }
  .chero__card { order: -1; max-width: 22rem; }
  .post { grid-template-columns: 1fr; gap: var(--sp-2); }
  .post__date { padding-top: 0; }
  .post__read { padding-top: 0; }
  .band__col { text-align: left; }
  .biocta .ph--avatar { width: var(--sp-8); height: var(--sp-8); }
  /* Promo masthead: brand and aside stop competing for one row. */
  .masthead--promo .masthead__bar { flex-wrap: wrap; gap: var(--sp-4); }
  .masthead__logo { height: 3.5rem; }
  .masthead__pitch { font-size: var(--fs-xs); }
}

@media (max-width: 40rem) {
  .nav { display: none; }
  .foot__grid { grid-template-columns: 1fr; }
  .foot__base { flex-direction: column; align-items: flex-start; gap: var(--sp-3); }
  .promo, .band { padding: var(--sp-6); }
  /* Phone: the pitch is the advert, so it keeps its three lines — the logo and
     the badges give up the space instead, and the aside sits under the brand
     left-aligned (.nav is already display:none at this width). */
  .masthead--promo .masthead__bar { flex-direction: column; align-items: stretch; }
  .masthead__logo { height: 3rem; }
  .masthead__aside { align-items: flex-start; }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* ========================================================================
   PRINT — reading floor
   ===================================================================== */
@media print {
  .masthead, .foot, .promo, .biocta, .related, .backlink, .band { display: none; }
  body { background: #fff; color: #000; }
  a { color: #000; text-decoration: underline; }
  .shell, .shell--narrow, .shell--prose { max-width: none; padding: 0; }
  .prose pre, .prose code { border: 1px solid #999; }
}


/* =====================================================================
   THEME SYSTEM — user-switchable skins (2026-06-03)
   Base = the default :root above. Each block below is a PURE custom-
   property override scoped to [data-theme="<id>"], set on <html> by
   the masthead theme picker (see partials/header.php + footer.php).
   Source: Claude Design "Theme Lab" handoff. Theme fonts are lazy-
   loaded from Google Fonts on selection; Base stays self-hosted.
   ===================================================================== */

/* @theme reading-room | Reading Room
   @fonts display="Playfair Display" body="Spectral" mono="IBM Plex Mono"
   @mood A quiet, warm-paper reading room where serifs breathe and the page feels printed, not rendered. */
[data-theme="reading-room"] {
  --font-display: "Playfair Display", Georgia, serif;
  --font-body:    "Spectral", Georgia, "Times New Roman", serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, Menlo, monospace;

  --c-bg:             oklch(0.984 0.009 84);
  --c-surface:        oklch(0.997 0.004 84);
  --c-surface-sunken: oklch(0.964 0.012 82);
  --c-ink:            oklch(0.30 0.018 60);
  --c-ink-strong:     oklch(0.22 0.02 56);
  --c-ink-soft:       oklch(0.46 0.016 60);
  --c-muted:          oklch(0.60 0.012 60);
  --c-faint:          oklch(0.72 0.01 60);

  --c-border:         oklch(0.90 0.012 76);
  --c-border-strong:  oklch(0.81 0.014 74);

  --c-accent:         oklch(0.52 0.12 38);
  --c-accent-strong:  oklch(0.44 0.12 36);
  --c-accent-soft:    oklch(0.945 0.03 50);
  --c-accent-line:    oklch(0.85 0.05 46);
  --c-on-accent:      oklch(0.99 0.008 84);

  --lh-relaxed:       1.78;
  --w-prose:          40rem;
}


/* @theme brutalist | Brutalist
   @fonts display="Archivo Black" body="Archivo" mono="Space Mono"
   @mood Raw structure, fixed type scale, hard offset shadows, and one electric red that refuses to be ignored. */
[data-theme="brutalist"] {
  --font-display: "Archivo Black", "Arial Black", sans-serif;
  --font-body:    "Archivo", system-ui, sans-serif;
  --font-mono:    "Space Mono", ui-monospace, monospace;

  /* deliberately fixed — no fluid softness */
  --fs-md:       1.125rem;
  --fs-lg:       1.5rem;
  --fs-xl:       2rem;
  --fs-2xl:      2.75rem;
  --fs-3xl:      3.75rem;
  --fs-display:  4.5rem;
  --lh-tight:    0.96;
  --ls-tighter:  -0.04em;
  --ls-label:    0.2em;
  --fw-bold:     900;

  --c-bg:             oklch(0.96 0 0);
  --c-surface:        oklch(1 0 0);
  --c-surface-sunken: oklch(0.92 0 0);
  --c-ink:            oklch(0.16 0 0);
  --c-ink-strong:     oklch(0.08 0 0);
  --c-ink-soft:       oklch(0.30 0 0);
  --c-muted:          oklch(0.44 0 0);
  --c-faint:          oklch(0.58 0 0);

  --c-border:         oklch(0.08 0 0);
  --c-border-strong:  oklch(0.08 0 0);

  --c-accent:         oklch(0.56 0.24 27);
  --c-accent-strong:  oklch(0.48 0.24 27);
  --c-accent-soft:    oklch(0.92 0.06 30);
  --c-accent-line:    oklch(0.08 0 0);
  --c-on-accent:      oklch(0.99 0 0);

  --r-xs: 0; --r-sm: 0; --r-md: 0; --r-lg: 0; --r-pill: 0;
  --bd-hair:  2px;
  --bd-thick: 4px;
  --shadow-sm: 4px 4px 0 0 oklch(0.08 0 0);
  --shadow-md: 8px 8px 0 0 oklch(0.08 0 0);
  --shadow-lg: 12px 12px 0 0 oklch(0.56 0.24 27);
}


/* @theme studio | Studio
   @fonts display="Space Grotesk" body="Work Sans" mono="Space Mono"
   @mood Confident modern studio — acres of white space, crisp grotesque headers, one electric cobalt note. */
[data-theme="studio"] {
  --font-display: "Space Grotesk", system-ui, sans-serif;
  --font-body:    "Work Sans", system-ui, sans-serif;
  --font-mono:    "Space Mono", ui-monospace, monospace;

  --ls-tighter:  -0.03em;
  --lh-relaxed:  1.68;

  --c-bg:             oklch(1 0 0);
  --c-surface:        oklch(1 0 0);
  --c-surface-sunken: oklch(0.972 0.003 250);
  --c-ink:            oklch(0.25 0.012 260);
  --c-ink-strong:     oklch(0.17 0.014 260);
  --c-ink-soft:       oklch(0.44 0.012 260);
  --c-muted:          oklch(0.58 0.01 260);
  --c-faint:          oklch(0.72 0.008 260);

  --c-border:         oklch(0.92 0.006 260);
  --c-border-strong:  oklch(0.84 0.01 260);

  --c-accent:         oklch(0.55 0.20 258);
  --c-accent-strong:  oklch(0.47 0.20 258);
  --c-accent-soft:    oklch(0.95 0.04 258);
  --c-accent-line:    oklch(0.86 0.07 258);
  --c-on-accent:      oklch(0.99 0.005 258);

  --r-md: 12px; --r-lg: 20px;
  --sp-9: 7rem; --sp-10: 9rem;
  --shadow-sm: 0 1px 2px oklch(0.25 0.012 260 / 0.04);
  --shadow-md: 0 10px 34px -14px oklch(0.25 0.012 260 / 0.18);
  --shadow-lg: 0 24px 60px -20px oklch(0.25 0.012 260 / 0.26);
}


/* @theme y2k | Y2K
   @fonts display="Rubik Mono One" body="Rubik" mono="VT323"
   @mood Late-90s web energy on purpose — icy chrome surfaces, bubblegum magenta, chunky rounded everything. */
[data-theme="y2k"] {
  --font-display: "Rubik Mono One", system-ui, sans-serif;
  --font-body:    "Rubik", system-ui, sans-serif;
  --font-mono:    "VT323", ui-monospace, monospace;

  --fs-2xs:  0.86rem;   /* VT323 runs small */
  --fs-xs:   0.96rem;
  --ls-label: 0.1em;
  --ls-tighter: -0.01em;

  --c-bg:             oklch(0.94 0.04 250);
  --c-surface:        oklch(0.99 0.012 250);
  --c-surface-sunken: oklch(0.90 0.05 248);
  --c-ink:            oklch(0.28 0.06 285);
  --c-ink-strong:     oklch(0.20 0.08 288);
  --c-ink-soft:       oklch(0.44 0.06 282);
  --c-muted:          oklch(0.56 0.07 290);
  --c-faint:          oklch(0.68 0.07 292);

  --c-border:         oklch(0.80 0.07 270);
  --c-border-strong:  oklch(0.62 0.12 285);

  --c-accent:         oklch(0.60 0.26 350);
  --c-accent-strong:  oklch(0.52 0.26 350);
  --c-accent-soft:    oklch(0.92 0.07 330);
  --c-accent-line:    oklch(0.74 0.16 340);
  --c-on-accent:      oklch(0.99 0.01 330);

  --r-xs: 6px; --r-sm: 10px; --r-md: 16px; --r-lg: 24px;
  --shadow-sm: 0 2px 0 0 oklch(0.62 0.12 285 / 0.4);
  --shadow-md: 0 6px 0 -1px oklch(0.60 0.26 350 / 0.35);
  --shadow-lg: 0 12px 0 -2px oklch(0.60 0.26 350 / 0.4);
}


/* @theme accessible | High-Contrast Print
   @fonts display="Atkinson Hyperlegible" body="Atkinson Hyperlegible" mono="IBM Plex Mono"
   @mood Maximum legibility, zero ornament — large type, pure black on pure white, AAA-minded blue. */
[data-theme="accessible"] {
  --font-display: "Atkinson Hyperlegible", system-ui, sans-serif;
  --font-body:    "Atkinson Hyperlegible", system-ui, sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, monospace;

  --fs-base:     1.2rem;
  --fs-md:       1.35rem;
  --fs-lg:       1.6rem;
  --lh-relaxed:  1.8;
  --lh-snug:     1.4;
  --ls-tighter:  -0.01em;
  --ls-tight:    0;

  --c-bg:             oklch(1 0 0);
  --c-surface:        oklch(1 0 0);
  --c-surface-sunken: oklch(0.96 0 0);
  --c-ink:            oklch(0.16 0 0);
  --c-ink-strong:     oklch(0.06 0 0);
  --c-ink-soft:       oklch(0.30 0 0);
  --c-muted:          oklch(0.40 0 0);
  --c-faint:          oklch(0.50 0 0);

  --c-border:         oklch(0.62 0 0);
  --c-border-strong:  oklch(0.30 0 0);

  --c-accent:         oklch(0.45 0.17 252);
  --c-accent-strong:  oklch(0.36 0.17 252);
  --c-accent-soft:    oklch(0.93 0.04 252);
  --c-accent-line:    oklch(0.70 0.10 252);
  --c-on-accent:      oklch(1 0 0);

  --r-xs: 2px; --r-sm: 4px; --r-md: 6px; --r-lg: 8px; --r-pill: 999px;
  --bd-hair: 2px;
  --shadow-sm: none;
  --shadow-md: 0 4px 16px -8px oklch(0.16 0 0 / 0.3);
  --shadow-lg: 0 8px 28px -10px oklch(0.16 0 0 / 0.35);
}


/* @theme matrix | The Matrix
   @fonts display="Share Tech Mono" body="Share Tech Mono" mono="Share Tech Mono"
   @mood Black void, falling code, that one impossible green — the desert of the real. */
[data-theme="matrix"] {
  --font-display: "Share Tech Mono", ui-monospace, monospace;
  --font-body:    "Share Tech Mono", ui-monospace, monospace;
  --font-mono:    "Share Tech Mono", ui-monospace, monospace;

  --fs-display:  3.2rem;
  --fs-3xl:      2.7rem;
  --lh-relaxed:  1.55;
  --ls-tight:    0;
  --ls-tighter:  0;
  --ls-wide:     0.08em;

  --c-bg:             oklch(0.13 0.02 150);
  --c-surface:        oklch(0.16 0.025 150);
  --c-surface-sunken: oklch(0.10 0.018 150);
  --c-ink:            oklch(0.82 0.18 148);
  --c-ink-strong:     oklch(0.90 0.22 146);
  --c-ink-soft:       oklch(0.64 0.14 150);
  --c-muted:          oklch(0.50 0.10 152);
  --c-faint:          oklch(0.38 0.07 154);

  --c-border:         oklch(0.30 0.06 150);
  --c-border-strong:  oklch(0.44 0.10 148);

  --c-accent:         oklch(0.86 0.22 146);
  --c-accent-strong:  oklch(0.94 0.24 145);
  --c-accent-soft:    oklch(0.22 0.06 150);
  --c-accent-line:    oklch(0.46 0.12 148);
  --c-on-accent:      oklch(0.11 0.03 150);

  --r-xs: 0; --r-sm: 0; --r-md: 0; --r-lg: 0; --r-pill: 0;
  --shadow-sm: 0 0 0 1px oklch(0.46 0.12 148 / 0.3);
  --shadow-md: 0 0 24px -4px oklch(0.86 0.22 146 / 0.45);
  --shadow-lg: 0 0 44px -6px oklch(0.86 0.22 146 / 0.55);
}


/* @theme multipass | Multipass
   @fonts display="Orbitron" body="Chakra Petch" mono="Oxanium"
   @mood Warm-white future-transit panels with a hot tangerine signal — clipped, technical, optimistic. */
[data-theme="multipass"] {
  --font-display: "Orbitron", system-ui, sans-serif;
  --font-body:    "Chakra Petch", system-ui, sans-serif;
  --font-mono:    "Oxanium", ui-monospace, monospace;

  --ls-label:    0.22em;
  --ls-wide:     0.08em;
  --lh-relaxed:  1.66;

  --c-bg:             oklch(0.965 0.012 58);
  --c-surface:        oklch(0.995 0.006 58);
  --c-surface-sunken: oklch(0.94 0.018 56);
  --c-ink:            oklch(0.26 0.03 50);
  --c-ink-strong:     oklch(0.18 0.035 48);
  --c-ink-soft:       oklch(0.42 0.03 50);
  --c-muted:          oklch(0.56 0.04 52);
  --c-faint:          oklch(0.70 0.06 54);

  --c-border:         oklch(0.86 0.03 56);
  --c-border-strong:  oklch(0.70 0.12 52);

  --c-accent:         oklch(0.66 0.19 48);
  --c-accent-strong:  oklch(0.57 0.19 46);
  --c-accent-soft:    oklch(0.94 0.05 58);
  --c-accent-line:    oklch(0.80 0.12 52);
  --c-on-accent:      oklch(0.99 0.01 70);

  --r-xs: 0; --r-sm: 2px; --r-md: 3px; --r-lg: 4px; --r-pill: 999px;
  --bd-thick: 3px;
  --shadow-sm: 0 1px 0 0 oklch(0.70 0.12 52 / 0.3);
  --shadow-md: 0 8px 26px -14px oklch(0.66 0.19 48 / 0.5);
  --shadow-lg: 0 18px 44px -18px oklch(0.66 0.19 48 / 0.55);
}


/* @theme lcars | Library Computer
   @fonts display="Antonio" body="Jura" mono="Oxanium"
   @mood A starship console at rest — black voids framed by burnt-orange and lilac blocks, all pills and labels. */
[data-theme="lcars"] {
  --font-display: "Antonio", "Arial Narrow", sans-serif;
  --font-body:    "Jura", system-ui, sans-serif;
  --font-mono:    "Oxanium", ui-monospace, monospace;

  --ls-label:    0.18em;
  --ls-wide:     0.06em;
  --lh-tight:    1.06;
  --lh-relaxed:  1.62;
  --fw-bold:     700;

  --c-bg:             oklch(0.13 0.01 300);
  --c-surface:        oklch(0.19 0.018 300);
  --c-surface-sunken: oklch(0.10 0.008 300);
  --c-ink:            oklch(0.86 0.05 72);
  --c-ink-strong:     oklch(0.92 0.07 70);
  --c-ink-soft:       oklch(0.70 0.05 74);
  --c-muted:          oklch(0.62 0.09 310);
  --c-faint:          oklch(0.50 0.08 312);

  --c-border:         oklch(0.40 0.10 310);
  --c-border-strong:  oklch(0.58 0.14 308);

  --c-accent:         oklch(0.70 0.16 55);
  --c-accent-strong:  oklch(0.78 0.17 58);
  --c-accent-soft:    oklch(0.30 0.08 308);
  --c-accent-line:    oklch(0.58 0.13 312);
  --c-on-accent:      oklch(0.12 0.02 60);

  --r-xs: 4px; --r-sm: 10px; --r-md: 18px; --r-lg: 28px; --r-pill: 999px;
  --shadow-sm: none;
  --shadow-md: 0 0 0 1px oklch(0.58 0.14 308 / 0.5);
  --shadow-lg: 0 0 36px -10px oklch(0.70 0.16 55 / 0.5);
}


/* @theme battlestar | Battlestar
   @fonts display="Saira Condensed" body="Chakra Petch" mono="JetBrains Mono"
   @mood Colonial fleet CIC at condition one — gunmetal dark, amber DRADIS glow, hard military edges. (Ink, 2026-06-04) */
[data-theme="battlestar"] {
  --font-display: "Saira Condensed", "Arial Narrow", sans-serif;
  --font-body:    "Chakra Petch", system-ui, sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, monospace;

  --ls-label:    0.2em;
  --ls-wide:     0.06em;
  --lh-tight:    1.02;
  --lh-relaxed:  1.6;
  --fw-bold:     700;

  --c-bg:             oklch(0.17 0.012 245);
  --c-surface:        oklch(0.215 0.014 245);
  --c-surface-sunken: oklch(0.13 0.01 245);
  --c-ink:            oklch(0.88 0.018 80);
  --c-ink-strong:     oklch(0.95 0.03 82);
  --c-ink-soft:       oklch(0.70 0.02 80);
  --c-muted:          oklch(0.56 0.018 240);
  --c-faint:          oklch(0.44 0.016 240);

  --c-border:         oklch(0.34 0.02 245);
  --c-border-strong:  oklch(0.48 0.03 240);

  --c-accent:         oklch(0.78 0.14 72);
  --c-accent-strong:  oklch(0.85 0.15 74);
  --c-accent-soft:    oklch(0.26 0.04 70);
  --c-accent-line:    oklch(0.52 0.10 72);
  --c-on-accent:      oklch(0.16 0.02 60);

  --r-xs: 0; --r-sm: 0; --r-md: 1px; --r-lg: 2px; --r-pill: 0;
  --bd-thick: 2px;
  --shadow-sm: 0 0 0 1px oklch(0.52 0.10 72 / 0.25);
  --shadow-md: 0 0 22px -8px oklch(0.78 0.14 72 / 0.4);
  --shadow-lg: 0 0 40px -10px oklch(0.78 0.14 72 / 0.5);
}


/* @theme interstellar | Interstellar
   @fonts display="Orbitron" body="Jura" mono="JetBrains Mono"
   @mood The void around Gargantua — pure black, a gold accretion-disk glow, blocky TARS lettering, buttons that bloom orange. (Ink, 2026-06-04) */
[data-theme="interstellar"] {
  --font-display: "Orbitron", system-ui, sans-serif;
  --font-body:    "Jura", system-ui, sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, monospace;

  /* Orbitron runs wide — tame the big display sizes so headlines don't blow out. */
  --fs-2xl:     2rem;
  --fs-3xl:     2.4rem;
  --fs-display: clamp(2.4rem, 5vw + 1rem, 4rem);
  --ls-tighter: 0;
  --ls-tight:   0;
  --ls-label:   0.18em;
  --ls-wide:    0.06em;
  --lh-tight:   1.1;
  --lh-relaxed: 1.62;

  --c-bg:             oklch(0.135 0.008 65);
  --c-surface:        oklch(0.18 0.010 65);
  --c-surface-sunken: oklch(0.10 0.006 65);
  --c-ink:            oklch(0.93 0.018 82);
  --c-ink-strong:     oklch(0.975 0.022 84);
  --c-ink-soft:       oklch(0.74 0.020 78);
  --c-muted:          oklch(0.58 0.018 74);
  --c-faint:          oklch(0.46 0.015 70);

  --c-border:         oklch(0.30 0.015 65);
  --c-border-strong:  oklch(0.44 0.020 68);

  --c-accent:         oklch(0.80 0.150 72);
  --c-accent-strong:  oklch(0.87 0.160 76);
  --c-accent-soft:    oklch(0.26 0.055 64);
  --c-accent-line:    oklch(0.55 0.120 70);
  --c-on-accent:      oklch(0.16 0.025 60);

  --r-xs: 4px; --r-sm: 8px; --r-md: 14px; --r-lg: 22px; --r-pill: 999px;
  /* The signature: a dark interior, a bright accretion-gold ring, and a soft
     outer glow. The CTA is just a bigger version of the .chip, so its glow is
     the chip glow scaled up — subtle, not a heavy bloom. */
  --chip-shadow: 0 0 9px -2px oklch(0.85 0.18 72 / 0.42), 0 0 18px 0 oklch(0.80 0.16 70 / 0.20);
  --btn-shadow:  0 0 14px -2px oklch(0.85 0.18 72 / 0.48), 0 0 34px 1px oklch(0.80 0.16 70 / 0.24);
  --shadow-sm: 0 0 0 1px oklch(0.55 0.12 70 / 0.18);
  --shadow-md: 0 0 28px -12px oklch(0.80 0.15 72 / 0.45);
  --shadow-lg: 0 0 60px -16px oklch(0.80 0.15 72 / 0.55);
}

/* Interstellar treats the primary CTA like a larger .chip: dark interior, a
   bright gold ring, gold lettering, and the soft glow — not a solid gold fill.
   Scoped to this theme only so every other theme's primary button is untouched. */
[data-theme="interstellar"] .btn--primary {
  background: transparent;
  color: var(--c-accent);
  border-color: var(--c-accent-line);
}
[data-theme="interstellar"] .btn--primary:hover {
  background: var(--c-accent-soft);
  color: var(--c-accent-strong);
  border-color: var(--c-accent);
}
/* The pricing band inverts to a near-white field; keep its button a solid dark
   pill (the original look) so we never get low-contrast gold-on-white. */
[data-theme="interstellar"] .band .btn--primary {
  background: var(--c-bg);
  color: var(--c-ink-strong);
  border-color: var(--c-bg);
}
[data-theme="interstellar"] .band .btn--primary:hover {
  background: var(--c-surface);
  color: var(--c-accent);
  border-color: var(--c-surface);
}


/* Theme picker (masthead) — token-styled so it adapts to the active theme */
.theme-picker {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-ink-soft);
  background: var(--c-surface);
  border: var(--border);
  border-radius: var(--r-sm);
  padding: 0.35em 0.6em;
  line-height: 1;
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.theme-picker:hover { color: var(--c-ink-strong); border-color: var(--c-border-strong); }
.theme-picker:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 2px; }

/* ========================================================================
   IN-CONTENT CTA  —  shortcode [cta:NAME], expanded at build time
   Inset accent-tinted call-out that sits within article prose. Distinct from
   the always-on .biocta at the article foot. No motion by design.
   Inner selectors are scoped under .lp-cta so they beat `.prose p` color.
   ===================================================================== */
.lp-cta {
  margin-block: var(--sp-7);
  padding: var(--sp-6);
  display: flow-root;   /* contain the floated image */
  background: var(--c-accent-soft);
  border: var(--bd-hair) solid var(--c-accent-line);
  border-left: 3px solid var(--c-accent);
  border-radius: var(--r-lg);
}
/* The avatar floats to the upper-right; the eyebrow and headline sit beside it
   and the body copy wraps edge-to-edge underneath. Scoped under .lp-cta so the
   rules beat `.prose figure` (margin) and `.prose img` (border-radius), which
   would otherwise square off the avatar. */
.lp-cta .lp-cta__media {
  float: right;
  margin: 0 0 var(--sp-4) var(--sp-5);
}
.lp-cta .lp-cta__avatar {
  display: block;
  /* ~50% larger than the foot-bio avatar (4.5rem → 6.75rem). */
  width: calc((var(--sp-8) + var(--sp-2)) * 1.5);
  height: calc((var(--sp-8) + var(--sp-2)) * 1.5);
  border-radius: var(--r-pill);
  object-fit: cover;
  border: var(--bd-hair) solid var(--c-accent-line);
}
.lp-cta .lp-cta__eyebrow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-accent-strong);
}
.lp-cta .lp-cta__title {
  margin: var(--sp-1) 0 0;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-tight);
  color: var(--c-ink-strong);
}
.lp-cta .lp-cta__text {
  margin: var(--sp-3) 0 var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--c-ink-soft);
}
.lp-cta__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  align-items: center;
}

@media (max-width: 640px) {
  /* Narrow screens: drop the float so the image sits on top, full text below. */
  .lp-cta .lp-cta__media { float: none; margin: 0 0 var(--sp-4); }
}
@media print {
  .lp-cta { display: none; }
}

/* ── Comments thread (baked, server-side) ──────────────────────────────────
   The approved comment list is rendered into the post HTML at build time
   (zero runtime cost to read). All values are design tokens, so dark mode is
   the automatic :root swap — no separate dark block needed. The progressive
   post-a-comment FORM carries its own inline CSS in partials/comments.php. */
.lp-comments {
  margin: var(--sp-7) 0 var(--sp-5);
  padding-top: var(--sp-5);
  border-top: var(--border);
}
.lp-comments-title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  color: var(--c-ink-strong);
  margin: 0 0 var(--sp-5);
}
.lp-comments-empty {
  color: var(--c-muted);
  font-size: var(--fs-base);
  font-style: italic;
}
.lp-comment-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}
.lp-comment {
  display: block;
}
.lp-comment-head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin: 0 0 var(--sp-2);
}
.lp-comment-avatar {
  flex: 0 0 auto;
  display: inline-flex;
  width: 40px;
  height: 40px;
}
.lp-comment-avatar .lp-avatar {
  display: block;
  border-radius: var(--r-pill);
}
.lp-comment-name {
  font-weight: var(--fw-semibold);
  color: var(--c-ink-strong);
}
.lp-comment-badge {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--c-on-accent);
  background: var(--c-accent);
  border-radius: var(--r-pill);
  padding: 0.08rem 0.5rem;
}
.lp-comment-date {
  margin-left: auto;
  font-size: var(--fs-sm);
  color: var(--c-muted);
}
.lp-comment-text {
  color: var(--c-ink);
  font-size: var(--fs-base);
  line-height: var(--lh-relaxed);
  /* The 40px avatar + gap, so the body aligns under the name. */
  padding-left: calc(40px + var(--sp-3));
  word-break: break-word;
  overflow-wrap: anywhere;
}
.lp-comment-text a {
  color: var(--c-link);
}
.lp-comment-author .lp-comment-name {
  color: var(--c-accent-strong);
}
@media (max-width: 560px) {
  .lp-comment-text { padding-left: 0; }
  .lp-comment-date { margin-left: 0; }
}
@media print {
  .lp-comments-form { display: none; }
}

/* ========================================================================
   SEARCH
   ===================================================================== */
.search-bar { margin-bottom: var(--sp-5); }
.search-input {
  width: 100%;
  padding: var(--sp-3) var(--sp-4);
  font-family: var(--font-body);
  font-size: var(--fs-md);
  color: var(--c-ink-strong);
  background: var(--c-surface);
  border: var(--bd-hair) solid var(--c-border-strong);
  border-radius: var(--r-md);
  outline: none;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.search-input:focus {
  border-color: var(--c-accent);
  box-shadow: 0 0 0 3px var(--c-accent-soft);
}
.search-status {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-muted);
  margin-bottom: var(--sp-4);
  min-height: 1.4em;
}
/* extra lines inside an archive-item (excerpt + tag chips in search results) */
.archive-excerpt, .archive-tags { grid-column: 1 / -1; margin: 0; }
.archive-excerpt { color: var(--c-muted); font-size: var(--fs-sm); margin-top: calc(-1 * var(--sp-3)); }
.archive-tags { display: flex; flex-wrap: wrap; gap: var(--sp-1); margin-top: 0; }

/* ========================================================================
   PAGINATION
   ===================================================================== */
.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-top: var(--sp-7);
  border-top: var(--border);
  margin-top: var(--sp-2);
}
.pagination__info {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--c-muted);
}
.pagination__nav { display: flex; gap: var(--sp-3); }
.pagination__link {
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--c-link);
  padding: var(--sp-2) var(--sp-4);
  border: var(--border);
  border-radius: var(--r-md);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.pagination__link:hover { background: var(--c-surface-raised); color: var(--c-accent); }
.pagination__link--disabled { opacity: 0.4; pointer-events: none; }

/* ========================================================================
   LIGHTBOX (opt-in: ui.lightbox — see partials/footer.php)
   ===================================================================== */
.lp-lightbox {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 200;
  align-items: center;
  justify-content: center;
  padding: var(--sp-5);
  background: color-mix(in oklab, black 80%, transparent);
  cursor: zoom-out;
}
.lp-lightbox.is-open { display: flex; }
.lp-lightbox__img {
  display: block;
  max-width: 95vw;
  max-height: 95vh;
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  cursor: default;
}
body.lp-lightbox-open { overflow: hidden; }

/* ========================================================================
   UTILITIES
   ===================================================================== */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

/* ═══ Calendar booking widget (/calendar/) ═══════════════════════════════════
   All colors/spacing/radius read the :root design tokens so the widget inherits
   every [data-theme] override automatically (no per-theme rules needed). */
.cal {
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  padding: var(--sp-6);
  box-shadow: var(--shadow-sm);
}
.cal__bar {
  display: flex; flex-wrap: wrap; gap: var(--sp-4);
  align-items: center; justify-content: space-between;
  padding-bottom: var(--sp-4); margin-bottom: var(--sp-4);
  border-bottom: 1px solid var(--c-border);
}
.cal__type { font-family: var(--font-display); font-size: var(--fs-lg); font-weight: var(--fw-semibold); color: var(--c-ink-strong); }
.cal__tz { display: flex; flex-direction: column; gap: var(--sp-1); font-family: var(--font-mono); font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .08em; color: var(--c-muted); }
.cal__tz select {
  font-family: var(--font-body); font-size: var(--fs-sm); color: var(--c-ink);
  background: var(--c-surface-sunken); border: 1px solid var(--c-border);
  border-radius: var(--r-sm); padding: var(--sp-2) var(--sp-3); text-transform: none; letter-spacing: 0;
}
.cal__live { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Paid session bar (signed-in + balance): type toggle + duration slider */
.cal__paidbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); padding-bottom: var(--sp-4); margin-bottom: var(--sp-4); border-bottom: 1px solid var(--c-border); }
.cal__paidbar[hidden], .cal__dur[hidden] { display: none; }
.cal__seg { display: inline-flex; border: 1px solid var(--c-border-strong); border-radius: var(--r-pill); overflow: hidden; }
.cal__seg-btn { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--c-ink); background: var(--c-surface-sunken); border: 0; padding: var(--sp-2) var(--sp-4); cursor: pointer; transition: background .12s ease, color .12s ease; }
.cal__seg-btn + .cal__seg-btn { border-left: 1px solid var(--c-border-strong); }
.cal__seg-btn.is-active { background: var(--c-accent); color: var(--c-on-accent); }
.cal__seg-btn:focus-visible { outline: 3px solid var(--c-accent); outline-offset: -2px; }
.cal__dur { display: flex; flex-direction: column; gap: var(--sp-1); font-family: var(--font-mono); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .06em; color: var(--c-muted); }
.cal__dur-head strong { color: var(--c-accent-strong); }
.cal__dur input[type=range] { accent-color: var(--c-accent); width: 12rem; max-width: 100%; }
.cal__grid { display: flex; flex-direction: column; gap: var(--sp-5); }
.cal__day-head { font-family: var(--font-mono); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .08em; color: var(--c-accent-strong); margin: 0 0 var(--sp-3); }
.cal__slots { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.cal__slot {
  font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--c-ink);
  background: var(--c-surface-sunken); border: 1px solid var(--c-border-strong);
  border-radius: var(--r-pill); padding: var(--sp-2) var(--sp-4); cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.cal__slot:hover { border-color: var(--c-accent); color: var(--c-accent-strong); }
.cal__slot:focus-visible { outline: 3px solid var(--c-accent); outline-offset: 2px; }
.cal__slot:active { background: var(--c-accent); color: var(--c-on-accent); }
.cal__slot--booked {
  cursor: not-allowed; color: var(--c-muted); background: var(--c-surface-sunken);
  border-color: var(--c-border); border-style: dashed; opacity: .7;
  text-decoration: line-through; text-decoration-thickness: 1px;
}
.cal__slot--booked:hover { border-color: var(--c-border); color: var(--c-muted); }
.cal__booked-tag { font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .08em; text-decoration: none; opacity: .85; }
/* the viewer's OWN booking — accent-tinted "booked by you" */
.cal__slot--mine { color: var(--c-accent-strong); background: var(--c-accent-soft); border-color: var(--c-accent-line); opacity: .9; }
.cal__slot--mine:hover { border-color: var(--c-accent-line); color: var(--c-accent-strong); }
.cal__slot--mine .cal__booked-tag { color: var(--c-accent-strong); opacity: 1; }
.cal__msg { text-align: center; padding: var(--sp-5) var(--sp-2); }
.cal__msg-lead { font-family: var(--font-display); font-size: var(--fs-lg); color: var(--c-ink-strong); margin: 0 0 var(--sp-3); }
.cal__msg--error { color: var(--c-ink); }
.cal__msg--ok .cal__msg-lead { color: var(--c-accent-strong); }
.cal__copy { margin-top: var(--sp-3); }
.cal__warn { color: var(--c-accent-strong); font-size: var(--fs-sm); }
.cal__notice { background: var(--c-accent-soft); border: 1px solid var(--c-accent-line); border-radius: var(--r-sm); padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4); font-size: var(--fs-sm); color: var(--c-ink-strong); }
.cal__note { font-size: var(--fs-sm); color: var(--c-muted); }
.cal__form { max-width: 28rem; }
.cal__form-lead { font-size: var(--fs-md); color: var(--c-ink); margin: 0 0 var(--sp-4); }
.cal__form label { display: flex; flex-direction: column; gap: var(--sp-1); margin-bottom: var(--sp-3); font-family: var(--font-mono); font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .08em; color: var(--c-muted); }
.cal__form input {
  font-family: var(--font-body); font-size: var(--fs-md); color: var(--c-ink);
  background: var(--c-surface-sunken); border: 1px solid var(--c-border-strong);
  border-radius: var(--r-sm); padding: var(--sp-3); text-transform: none; letter-spacing: 0;
}
.cal__form input:focus-visible { outline: 3px solid var(--c-accent); outline-offset: 1px; }
.cal__form-actions { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-4); }

/* Step 1 — month calendar (pick a day) */
.cal__calendar { max-width: 30rem; }
.cal__monthbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--sp-4); }
.cal__monthlabel { font-family: var(--font-display); font-size: var(--fs-lg); font-weight: var(--fw-semibold); color: var(--c-ink-strong); }
.cal__navbtn {
  font-family: var(--font-body); font-size: var(--fs-lg); line-height: 1; color: var(--c-ink);
  background: var(--c-surface-sunken); border: 1px solid var(--c-border-strong);
  border-radius: var(--r-sm); width: 2.25rem; height: 2.25rem; cursor: pointer;
  transition: border-color .12s ease, color .12s ease;
}
.cal__navbtn:hover:not(:disabled) { border-color: var(--c-accent); color: var(--c-accent-strong); }
.cal__navbtn:focus-visible { outline: 3px solid var(--c-accent); outline-offset: 2px; }
.cal__navbtn:disabled { opacity: .35; cursor: default; }
.cal__weekdays { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--sp-1); margin-bottom: var(--sp-2); }
.cal__weekdays span { text-align: center; font-family: var(--font-mono); font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: .06em; color: var(--c-muted); }
.cal__month { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--sp-1); }
.cal__cell {
  display: flex; align-items: center; justify-content: center; aspect-ratio: 1 / 1;
  font-family: var(--font-mono); font-size: var(--fs-sm);
  border-radius: var(--r-sm); border: 1px solid transparent;
}
.cal__cell--empty { border: 0; }
.cal__cell--off { color: var(--c-muted); opacity: .45; }
.cal__cell--avail {
  color: var(--c-accent-strong); background: var(--c-accent-soft); border-color: var(--c-accent-line);
  cursor: pointer; font-weight: var(--fw-semibold);
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.cal__cell--avail:hover { background: var(--c-accent); color: var(--c-on-accent); border-color: var(--c-accent); }
.cal__cell--avail:focus-visible { outline: 3px solid var(--c-accent); outline-offset: 2px; }
.cal__cell--today { box-shadow: inset 0 0 0 2px var(--c-accent); }

/* Step 2 — chosen day's open times */
.cal__back {
  font-family: var(--font-mono); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .06em;
  color: var(--c-muted); background: none; border: 0; padding: 0; cursor: pointer; margin-bottom: var(--sp-3);
}
.cal__back:hover { color: var(--c-accent-strong); }
.cal__back:focus-visible { outline: 3px solid var(--c-accent); outline-offset: 2px; border-radius: var(--r-sm); }
.cal__daynav { display: flex; justify-content: space-between; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.cal__daynav-btn {
  font-family: var(--font-mono); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .06em;
  color: var(--c-ink); background: var(--c-surface-sunken); border: 1px solid var(--c-border-strong);
  border-radius: var(--r-sm); padding: var(--sp-2) var(--sp-3); cursor: pointer;
  transition: border-color .12s ease, color .12s ease;
}
.cal__daynav-btn:hover:not(:disabled) { border-color: var(--c-accent); color: var(--c-accent-strong); }
.cal__daynav-btn:focus-visible { outline: 3px solid var(--c-accent); outline-offset: 2px; }
.cal__daynav-btn:disabled { opacity: .3; cursor: default; }
.cal__dayhead { font-family: var(--font-display); font-size: var(--fs-lg); font-weight: var(--fw-semibold); color: var(--c-ink-strong); margin: 0 0 var(--sp-4); }
.cal__rel { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: var(--fw-regular, 400); text-transform: uppercase; letter-spacing: .06em; color: var(--c-accent-strong); margin-left: var(--sp-2); }

/* "You're scheduled…" strip — thin contrasted band above the masthead (signed-in
   visitors with an upcoming confirmed booking). Hidden until the script fills it. */
.appt-strip {
  background: var(--c-accent); color: var(--c-on-accent);
  text-align: center; font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: .02em; padding: var(--sp-2) var(--sp-4);
}
.appt-strip[hidden] { display: none; }

@media (max-width: 36rem) {
  .cal { padding: var(--sp-4); }
  .cal__bar { flex-direction: column; align-items: stretch; }
  .cal__calendar { max-width: none; }
}

/* ============================================================================
   VIEW TRANSITIONS + SCROLL-DRIVEN ANIMATIONS
   ----------------------------------------------------------------------------
   Cross-document view transitions (Chrome 126+): navigations between pages
   get a smooth animated handoff instead of a hard cut. The companion
   Speculation Rules block in header.php prerenders hovered links so the new
   page is already in memory when the user clicks.

   Scroll-driven animations (Chrome 115+): article reading-progress bar and
   subtle entry animation on archive list items.

   All motion is gated on prefers-reduced-motion: no-preference. The @view-
   transition rule is also removed for reduced-motion users so the OS setting
   is fully respected.
   ============================================================================ */

@view-transition {
  navigation: auto;
}

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

@media (prefers-reduced-motion: no-preference) {

  /* ---- Named shared elements -------------------------------------------- */
  /* Masthead stays in place across page loads — no flash, no crossfade flicker */
  .masthead {
    view-transition-name: masthead;
  }
  /* Article title gets its own transition layer for a distinct entrance      */
  .article__title {
    view-transition-name: page-title;
  }

  /* ---- Page slide + fade (root snapshot) -------------------------------- */
  ::view-transition-old(root) {
    animation: lp-vt-out var(--dur, 180ms) var(--ease, ease) both;
  }
  ::view-transition-new(root) {
    animation: lp-vt-in var(--dur, 180ms) var(--ease, ease) both;
  }
  /* Masthead: very short crossfade so it feels locked in place              */
  ::view-transition-old(masthead),
  ::view-transition-new(masthead) {
    animation-duration: 90ms;
  }
  /* Page title: fades out quickly, rises in on the new page                 */
  ::view-transition-old(page-title) {
    animation: lp-vt-fade-out 120ms ease both;
  }
  ::view-transition-new(page-title) {
    animation: lp-vt-rise-in 260ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
  }

  @keyframes lp-vt-out {
    from { opacity: 1; transform: translateX(0); }
    to   { opacity: 0; transform: translateX(-1.5rem); }
  }
  @keyframes lp-vt-in {
    from { opacity: 0; transform: translateX(1.5rem); }
    to   { opacity: 1; transform: translateX(0); }
  }
  @keyframes lp-vt-fade-out {
    to { opacity: 0; }
  }
  @keyframes lp-vt-rise-in {
    from { opacity: 0; transform: translateY(0.5rem); }
    to   { opacity: 1; transform: translateY(0); }
  }

  /* ---- Reading progress bar (article pages only) ------------------------ */
  @supports (animation-timeline: scroll()) {
    body:has(article .prose)::before {
      content: '';
      position: fixed;
      inset: 0 0 auto 0;
      height: 3px;
      background: var(--c-accent);
      transform-origin: left center;
      transform: scaleX(0);
      z-index: 100;
      animation: lp-reading-progress linear both;
      animation-timeline: scroll(root block);
    }
  }
  @keyframes lp-reading-progress {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
  }

  /* ---- Archive item entrance on scroll ---------------------------------- */
  @supports (animation-timeline: view()) {
    .archive-item {
      animation: lp-item-enter 280ms linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 25%;
    }
  }
  @keyframes lp-item-enter {
    from { opacity: 0; transform: translateY(0.4rem); }
    to   { opacity: 1; transform: translateY(0); }
  }

}

/* ══ Landing page (layouts/landing.php) ═══════════════════════════════════
   Used by the shared RunPee-style marketing landing, which every language
   site inherits. polygeek has its own landing.php and never touches these. */

.intro { padding: 3.25rem 0 1.5rem; }

.intro__statement {
  font-size: var(--fs-lg);
  line-height: var(--lh-relaxed);
  margin: 0;
}

.intro__sub {
  margin: 0.75rem 0 0;
  color: var(--c-muted);
  line-height: var(--lh-relaxed);
}

/* padding-block, NOT the `padding` shorthand. `.section--tight` is worn on the
   same element as `.shell` (<section class="shell section--tight">), both are
   single-class selectors, and this rule is 1600 lines below `.shell` — so a
   shorthand here silently reset `.shell`'s padding-inline to 0 and ran every
   landing section edge-to-edge on narrow viewports while the .intro block,
   which nests its .shell in a separate <div>, kept its margins. Dan caught it
   on cn/en 2026-08-14. Never use the shorthand on a class that shares an
   element with .shell. */
.section--tight { padding-block: 1.75rem 0; }

.lp-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}

/* Landing-page CTA wrapper. Named lp-homecta, NOT lp-cta: it used to share the
   latter with the [cta:NAME] shortcode aside 500 lines up, so every landing
   button silently inherited that aside's cream panel, amber left border and
   padding. Nobody wanted a card here — it only became obvious in dark mode,
   where the panel stayed light while the text tokens flipped (2026-08-12). */
.lp-homecta { flex: 1 1 13rem; }

.lp-homecta__sub {
  margin: 0.5rem 0 0;
  color: var(--c-muted);
  font-size: var(--fs-sm);
}

.lp-steps {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  counter-reset: step;
  border-top: 1px solid var(--c-border);
}

.lp-steps li {
  counter-increment: step;
  padding: 1.05rem 0 1.05rem 2.5rem;
  border-bottom: 1px solid var(--c-border);
  position: relative;
  line-height: var(--lh-relaxed);
}

.lp-steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 1.35rem;
  width: 1.6rem;
  height: 1.6rem;
  line-height: 1.6rem;
  text-align: center;
  border-radius: 50%;
  background: var(--c-accent-soft);
  color: var(--c-accent-strong);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: 0;
}

/* ── [apk] download block ─────────────────────────────────────────────────
   The download button, then the checksum. The hash is deliberately quiet:
   most visitors skip it, but the people who do read it are the ones who'd
   otherwise distrust an APK served off a website — unofficial RunPee builds
   circulate on mirror sites, and this is how someone tells ours from theirs. */
.lp-apk {
  margin-block: var(--sp-7);
  padding: var(--sp-6);
  background: var(--c-surface-sunken);
  border: var(--bd-hair) solid var(--c-border);
  border-radius: var(--r-lg);
}
.lp-apk__btn { font-size: var(--fs-sm); padding: var(--sp-4) var(--sp-6); }
.lp-apk__meta {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-xs);
  color: var(--c-ink-soft);
}
.lp-apk__verify {
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: var(--bd-hair) solid var(--c-border);
}
.lp-apk__verify-lede {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-xs);
  color: var(--c-muted);
}
.lp-apk__sha {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}
/* break-all because 64 hex characters will not fit a phone otherwise, and
   user-select:all so one tap takes the whole string — dragging a selection
   across it on a touchscreen is the reason people give up on checksums. */
.lp-apk__hash {
  flex: 1 1 18rem;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  line-height: var(--lh-snug);
  color: var(--c-ink);
  word-break: break-all;
  user-select: all;
  -webkit-user-select: all;
}
.lp-apk__copy {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  padding: var(--sp-1) var(--sp-3);
  color: var(--c-ink-soft);
  background: var(--c-surface);
  border: var(--bd-hair) solid var(--c-border);
  border-radius: var(--r-sm);
  cursor: pointer;
}
.lp-apk__copy:hover { color: var(--c-ink-strong); border-color: var(--c-border-strong); }
.lp-apk__how {
  margin-top: var(--sp-3);
  font-size: var(--fs-2xs);
  color: var(--c-muted);
}
.lp-apk__how summary { cursor: pointer; }
.lp-apk__cmd {
  margin: var(--sp-2) 0 0;
  padding: var(--sp-3);
  overflow-x: auto;
  background: var(--c-surface);
  border: var(--bd-hair) solid var(--c-border);
  border-radius: var(--r-sm);
}
.lp-apk__cmd code { font-family: var(--font-mono); font-size: var(--fs-2xs); white-space: pre; }

@media (max-width: 640px) {
  .lp-apk { padding: var(--sp-5); }
  .lp-apk__btn { display: block; text-align: center; }
}

/* ── Share row ──────────────────────────────────────────────────────────────
   Emitted only where a site declares share.targets (see partials/share.php), so
   these rules are inert on any site that hasn't opted in.

   Built entirely from existing tokens — no literal colours — because share
   chrome has to survive all eleven polygeek themes plus cn/en's two, and the
   house convention (from the --chip-shadow thread) is a reusable var() hook
   first, a theme-scoped override only where a token genuinely can't express
   intent. Nothing here needs one. */
.share {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: var(--border);
}
.share__label {
  font-size: var(--fs-2xs);
  color: var(--c-muted);
  letter-spacing: 0.04em;
}
.share__list { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.share__btn {
  display: inline-block;
  padding: 0.4em 0.85em;
  font: inherit;
  font-size: var(--fs-2xs);
  line-height: 1.4;
  color: var(--c-text);
  text-decoration: none;
  background: var(--c-surface);
  border: var(--border);
  border-radius: var(--r-sm);
  box-shadow: var(--btn-shadow);
  cursor: pointer;
  transition: border-color 120ms ease, color 120ms ease;
}
.share__btn:hover,
.share__btn:focus-visible {
  color: var(--c-link);
  border-color: var(--c-border-strong);
  text-decoration: none;
}
/* Confirmation state for copy-link: colour only, no size or weight change, so
   the row doesn't jump under the reader's cursor. The label itself still swaps
   (复制链接 → 已复制), which moves the right-hand edge by roughly one glyph —
   it's the last control in the row, so nothing reflows around it. */
.share__btn.is-copied { color: var(--c-link); border-color: var(--c-link); }

/* An author `display` beats the UA stylesheet's [hidden] { display: none }, so
   setting display:inline-block above silently un-hides every button we marked
   hidden — which is exactly the dead-control-for-JS-off-readers case the markup
   was written to avoid. Found on the live page; invisible in the DOM, where the
   hidden attribute is still faithfully present. */
.share__btn[hidden],
.figshare__btn[hidden] { display: none; }

/* Shown only inside WeChat's browser, where no button we could render is able
   to open the share sheet. */
.share__wechat {
  flex-basis: 100%;
  margin: 0;
  font-size: var(--fs-2xs);
  color: var(--c-muted);
}

@media (max-width: 640px) {
  .share { gap: var(--sp-2); }
}

/* ── Shareable figure ───────────────────────────────────────────────────────
   The lead image of a post, when the build judged it card-shaped, plus the
   control for sending it onward. Only emitted where a site declares share
   targets, so inert everywhere else. */
.figure--share { margin: var(--sp-6) 0; }
.figure--share img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--r-sm);
}
.figshare {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-3);
}
.figshare__label {
  font-size: var(--fs-2xs);
  color: var(--c-muted);
}
.figshare__list { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
/* Same shape as .share__btn — one visual language for "send this somewhere",
   whether the somewhere is fed a page or a picture. */
.figshare__btn {
  display: inline-block;
  padding: 0.35em 0.75em;
  font: inherit;
  font-size: var(--fs-2xs);
  line-height: 1.4;
  color: var(--c-text);
  text-decoration: none;
  background: var(--c-surface);
  border: var(--border);
  border-radius: var(--r-sm);
  box-shadow: var(--btn-shadow);
  cursor: pointer;
  transition: border-color 120ms ease, color 120ms ease;
}
.figshare__btn:hover,
.figshare__btn:focus-visible {
  color: var(--c-link);
  border-color: var(--c-border-strong);
  text-decoration: none;
}
/* The native sheet is the best available option on a phone, so it reads as the
   primary action rather than a fifth peer in the row. */
.figshare__btn--native { border-color: var(--c-link); color: var(--c-link); }
.figshare__btn[disabled] { opacity: 0.55; cursor: default; }

/* ═══ Pitch layout (layouts/pitch.php) ═══════════════════════════════════════
   A page cut into a deck: hero, then alternating full-width slides. Markdown
   inside a slide gets deck treatment — big heading, lead paragraph, a list
   becomes a grid of cards (a **bold** first line is the card's title). */
.pitch { overflow-x: clip; }
.pitch__hero { padding: var(--sp-8) 0 var(--sp-6); text-align: center; }
.pitch__title {
  font-size: var(--fs-3xl); line-height: 1.05; letter-spacing: -0.02em;
  color: var(--c-ink-strong); margin: 0 auto var(--sp-4); max-width: 18ch;
}
.pitch__lede > p { font-size: var(--fs-md); color: var(--c-ink-soft); max-width: 40rem; margin: 0 auto var(--sp-4); }
.pitch__lede > .rp-ad { margin-top: var(--sp-6); }
.pitch__slide { padding: var(--sp-8) 0; }
.pitch__slide--alt { background: var(--c-surface-sunken); }
.pitch__slide h2 {
  font-size: var(--fs-2xl); line-height: 1.1; letter-spacing: -0.015em;
  color: var(--c-ink-strong); margin: 0 0 var(--sp-4); max-width: 22ch;
}
.pitch__slide h3 { font-size: var(--fs-lg); color: var(--c-ink-strong); margin: var(--sp-6) 0 var(--sp-2); }
.pitch__slide p { font-size: var(--fs-md); line-height: 1.6; color: var(--c-ink); max-width: 44rem; margin: 0 0 var(--sp-4); }
.pitch__slide p:first-of-type { font-size: var(--fs-lg); color: var(--c-ink-soft); line-height: 1.45; }
.pitch__slide a { color: var(--c-link); }
.pitch__slide ul {
  list-style: none; padding: 0; margin: var(--sp-6) 0 var(--sp-4);
  display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fit, minmax(11.5rem, 1fr));
}
.pitch__slide li {
  background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--r-md);
  padding: var(--sp-5); color: var(--c-ink); line-height: 1.5; font-size: var(--fs-base);
}
.pitch__slide--alt li { background: var(--c-bg); }
.pitch__slide li > strong:first-child {
  display: block; font-size: var(--fs-md); color: var(--c-ink-strong); margin-bottom: var(--sp-2);
}
/* Raw-HTML stat row: <div class="pitch-stats"><div><b>2008</b>since</div>…</div> */
.pitch-stats {
  display: grid; gap: var(--sp-4); margin: var(--sp-6) 0 var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}
.pitch-stats > div { text-align: center; color: var(--c-ink-soft); font-size: var(--fs-sm); }
.pitch-stats b {
  display: block; font-size: var(--fs-2xl); line-height: 1.1; color: var(--c-accent);
  font-variant-numeric: tabular-nums; margin-bottom: var(--sp-1);
}
.pitch__slide img { max-width: 100%; height: auto; }
/* [stores] — the closing call. */
.rp-stores { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin: var(--sp-5) 0; }

/* ══════════════════════════════════════════════════════════════════════════
   cn.runpee.com — overlay on sites/_shared/templates/css/main.css.
   The build concatenates shared first, this second, so everything here wins
   the cascade. Keep it to (a) tokens the language changes and (b) the classes
   only this site's landing page uses. Anything structural belongs in _shared.

   Rewritten 2026-08-11: this file used to be a standalone 197-line stylesheet
   for a one-page site. Once the site had nineteen pages it was missing every
   blog surface (archive lists, post cards, tags, pagination, prose), so it
   inherits the shared design system now and only overrides what Chinese
   actually needs.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ---- Type: CJK system stack ------------------------------------------
     The shared sheet's @font-face rules stay declared but are never matched,
     so newsreader.woff2 / jetbrains-mono.woff2 are never fetched — 163KB of
     Latin faces that render zero Chinese glyphs, requested cross-border with
     no CDN. Naming them here would be worse than useless. */
  --font-display: -apple-system, BlinkMacSystemFont, "PingFang SC",
                  "Hiragino Sans GB", "Source Han Sans SC", "Noto Sans CJK SC",
                  "Microsoft YaHei", sans-serif;
  --font-body:    var(--font-display);
  --font-mono:    ui-monospace, "SFMono-Regular", Menlo, "PingFang SC",
                  "Microsoft YaHei", monospace;

  /* ---- Accent: #FCA905 -------------------------------------------------
     RunPee amber. The pure value carries fills, rules, buttons and the active
     nav item. Inline text links use the darkened variant: #FCA905 on paper is
     ~1.9:1, nowhere near the 4.5:1 body-text floor, while the darkened one
     clears it. Same hue, so the page still reads as one colour. */
  --c-accent:        #FCA905;
  --c-accent-strong: #8A5A00;
  --c-accent-soft:   #FFF4DC;
  --c-accent-line:   #F3D79A;
  --c-link:          var(--c-accent-strong);
  --c-link-hover:    #6B4600;
  --c-selection:     var(--c-accent-soft);

  /* ---- Leading and measure --------------------------------------------
     CJK at Latin leading reads cramped, and Chinese carries more information
     per character so a comfortable English line runs short (Clio, 2026-08-11).
     Both numbers are deliberately looser than the shared defaults. */
  --lh-relaxed: 1.78;
  --lh-normal:  1.6;
  --ls-tight:   0;      /* negative tracking smears CJK glyphs */
  --ls-tighter: 0;
}

/* The accent tokens above are light-mode values pinned at :root. The shared
   sheet flips its surface and ink tokens for dark, so anything painted with
   --c-accent-soft kept a pale panel while the text on it went near-white. Give
   the soft/line pair dark counterparts so accent surfaces stay legible in both
   themes; the pure accent needs no change, amber reads on either ground. */
:root[data-theme="interstellar"],
:root:not([data-theme]) {
  --c-accent-soft: #FFF4DC;
  --c-accent-line: #F3D79A;
}
:root[data-theme="interstellar"] {
  --c-accent-soft: oklch(0.26 0.045 78);
  --c-accent-line: oklch(0.40 0.060 78);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --c-accent-soft: oklch(0.26 0.045 78);
    --c-accent-line: oklch(0.40 0.060 78);
  }
}

/* Amber holds up on dark; only the text-link variant has to lighten, and it
   has to happen in both places a dark page can come from — the explicit theme
   and the OS preference the base theme follows. */
:root[data-theme="interstellar"] {
  --c-link:       #FFC85A;
  --c-link-hover: #FFD98A;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --c-link:       #FFC85A;
    --c-link-hover: #FFD98A;
  }
}

/* Chinese has no inter-word spaces, so justified text can't stretch spaces to
   fit — break-word keeps a long run of Latin (film titles, URLs) from spilling. */
body { overflow-wrap: break-word; }

/* Prose measure: wider than the Latin default, per the note above. */
.shell--prose { max-width: 40rem; }
