/* ===========================================================================
   Perpolita — site stylesheet

   Porcelain, ink, horn. The mark is drawn; the site stays quiet around it.
   Fraunces is the brand face (decisions.md 20.23); its axes are set per ROLE
   rather than loading a second family.

   The `opsz` axis is the load-bearing one and it was previously wrong: every
   heading asked for `opsz 144`, the display end, at ~23px. Fraunces' optical
   axis REBUILDS the letterform rather than scaling it — at 144 the strokes go
   thin and high-contrast because they are meant to be seen at poster size — so
   a 23px heading set at 144 renders as hairlines. Each role now asks for an
   optical size near the size it is actually rendered at.

   Layout is a THREE-TRACK GRID, not a single narrow column. The header, the
   footer and any non-prose block share one wide edge; prose sits on a text
   edge centred inside it. Two edges read as a system; the four unrelated
   widths this page used to have read as an accident.
   =========================================================================== */

/* --------------------------------------------------------------- 1. fonts */

/* Subset to Latin + the punctuation the site actually emits, with SOFT and
   WONK pinned to 0 (the values every role here uses), then WOFF2 — 352 KB of
   TTF down to ~79 KB. `opsz` and `wght` stay live because the roles below vary
   them. Regenerate with `python web/tools/make-webfonts.py`; never hand-edit
   the binary. */
@font-face {
  font-family: 'Fraunces';
  src: url('fonts/Fraunces.woff2?v=a5522bc1') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* -------------------------------------------------------------- 2. tokens */

:root {
  color-scheme: light dark;

  /* The brand constants. These never change; only the roles below do. */
  --porcelain: #f4f2ec;
  --mist: #e5e1d6;
  --ink: #101014;
  --shade: #4a4740;
  --horn: #6d4f20;        /* link/accent, 6.7:1 on porcelain */
  --horn-soft: #b08a4c;   /* decorative only */

  /* Roles. Every rule below paints with these, never with a colour name, so
     dark mode is a token swap rather than a second stylesheet. */
  --bg: var(--porcelain);
  --bg-2: #ebe8df;        /* recessed bands */
  --surface: #fbfaf6;
  --fg: var(--ink);
  --fg-2: #3a3833;
  --muted: var(--shade);
  --line: var(--mist);
  --line-strong: #8e8a7e; /* 3:1 — interactive boundaries only */
  --accent: var(--horn);
  --accent-soft: var(--horn-soft);
  --btn-bg: var(--ink);
  --btn-fg: var(--porcelain);
  --btn-bg-hover: #2c2a24;
  --code-bg: var(--mist);
  --flag: #a33;
  --mark-filter: none;
  --veil: rgba(244, 242, 236, 0.86);
  --shadow: 0 1px 2px rgba(16, 16, 20, 0.06), 0 10px 28px -14px rgba(16, 16, 20, 0.28);

  /* Body weight. Light-on-dark makes stems look thinner than they measure, so
     dark mode asks for a little more (see the dark block). */
  --wght-body: 400;

  --serif: 'Fraunces', Georgia, 'Iowan Old Style', serif;
  --mono: ui-monospace, 'Cascadia Mono', 'SF Mono', Consolas, 'Liberation Mono', monospace;

  /* Fluid scale. h2 tops out near 2× the body size so a section heading is
     unmistakably a section heading — the old 1.45rem sat a hair above the
     paragraphs and did no work. */
  --t-xs:   0.8rem;
  --t-sm:   0.9375rem;
  --t-base: clamp(1.0625rem, 1.006rem + 0.28vw, 1.1875rem);
  --t-lg:   clamp(1.1875rem, 1.121rem + 0.33vw, 1.3125rem);
  --t-h3:   clamp(1.1875rem, 1.105rem + 0.41vw, 1.375rem);
  --t-h2:   clamp(1.625rem, 1.348rem + 1.39vw, 2.25rem);
  --t-h1:   clamp(2rem, 1.612rem + 1.94vw, 2.875rem);

  --lh-tight: 1.12;
  --lh-head: 1.2;
  --lh-body: 1.68;

  --s-1: 0.25rem; --s-2: 0.5rem;  --s-3: 0.75rem; --s-4: 1rem;
  --s-5: 1.5rem;  --s-6: 2rem;    --s-7: 3rem;    --s-8: 4rem;
  --band-y: clamp(3rem, 6vw, 5rem);

  /* `--w-text` is in rem, not ch, so the column does not resize when the font
     stack resolves differently on another platform. */
  --gutter: clamp(1.25rem, 4vw, 2.5rem);
  --w-text: 38rem;
  --w-wide: 64rem;

  --r-sm: 3px; --r-md: 6px; --r-lg: 10px;
  --ring-off: 3px;
}

/* Porcelain after dark: a warm near-black ground rather than a neutral one, so
   the horn accent still reads as horn. Horn itself opens up to #cba25c, and the
   light-mode value is tuned for contrast on porcelain and fails on ink. Every
   pair here is AA or better (fg 15.3:1, fg-2 11.9:1, muted 8.7:1, accent 7.9:1).

   FOLLOWS THE OS SETTING, WITH NO TOGGLE, ON PURPOSE. A switch has to remember
   its position, and web/README.md and semblature.com/privacy.html both promise
   this site stores nothing. That promise is worth more than the switch. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #131218;
    --bg-2: #0e0d12;
    --surface: #1b1a21;
    --fg: #ece9e1;
    --fg-2: #cfcabe;
    --muted: #b8b0a2;
    --line: #2c2a34;
    --line-strong: #66625b;
    --accent: #cba25c;
    --accent-soft: #8a6c38;
    --btn-bg: #ece9e1;
    --btn-fg: #131218;
    --btn-bg-hover: #fffdf6;
    --code-bg: #1b1a21;
    --flag: #e07a7a;
    --veil: rgba(19, 18, 24, 0.86);
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 28px -14px rgba(0, 0, 0, 0.75);
    --wght-body: 430;
    /* the mark and the wordmark are one-tone #101014 on transparency, so an
       invert lands them within a shade of porcelain, so no second asset is needed */
    --mark-filter: invert(1);
  }
}

/* ------------------------------------------------------- 3. reset + base */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;   /* the header is sticky */
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--serif);
  /* opsz 14 is Fraunces' TEXT end — thicker stems, looser spacing, less
     contrast. This is the setting a paragraph wants. */
  font-variation-settings: 'opsz' 14, 'wght' var(--wght-body);
  font-size: var(--t-base);
  line-height: var(--lh-body);
  text-rendering: optimizeLegibility;
  font-kerning: normal;
  overflow-wrap: break-word;
}

::selection { background: rgba(109, 79, 32, 0.18); color: var(--fg); }
@media (prefers-color-scheme: dark) {
  ::selection { background: rgba(203, 162, 92, 0.28); }
}

img, svg, video { max-width: 100%; height: auto; }

a {
  color: var(--accent);
  text-underline-offset: 0.18em;
  text-decoration-thickness: from-font;
}
a:hover { color: var(--fg); text-decoration-thickness: 2px; }

:where(a, button, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: var(--ring-off);
  border-radius: var(--r-sm);
}

.skip-link {
  position: absolute; left: var(--s-4); top: var(--s-4);
  transform: translateY(-250%);
  z-index: 50;
  background: var(--btn-bg); color: var(--btn-fg);
  font-family: var(--mono); font-size: var(--t-xs);
  letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none;
  padding: var(--s-3) var(--s-4); border-radius: var(--r-sm);
}
.skip-link:focus { transform: translateY(0); color: var(--btn-fg); }

/* ------------------------------------------------------------ 4. layout */

/* The three-track grid. Everything sits in `text` unless it says otherwise.
   All three tracks share a centre line, so the wide edge reads as a deliberate
   outdent of the text edge rather than a second, unrelated column. */
.flow, .page, .entry {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--gutter), 1fr)
    [wide-start] minmax(0, calc((var(--w-wide) - var(--w-text)) / 2))
    [text-start] min(100% - var(--gutter) * 2, var(--w-text)) [text-end]
    minmax(0, calc((var(--w-wide) - var(--w-text)) / 2)) [wide-end]
    minmax(var(--gutter), 1fr) [full-end];
}
.flow > *, .page > *, .entry > * { grid-column: text; min-width: 0; }
.u-wide { grid-column: wide; }
.u-full { grid-column: full; }

.band { padding-block: var(--band-y); }
.band-deep { background: var(--bg-2); }
.band + .band-deep, .band-deep + .band { border-top: 1px solid var(--line); }

main { display: block; }
.page-main { padding-block: clamp(2.5rem, 5vw, 4rem) var(--s-8); }

/* -------------------------------------------------------- 5. typography */

h1, h2, h3, h4 {
  line-height: var(--lh-head);
  letter-spacing: 0.005em;
  text-wrap: balance;
  color: var(--fg);
}

/* opsz tracks the rendered size. 72 for the page title, 40 for a section
   heading, 24 for a sub-head — not 144 for all three. */
h1 {
  font-variation-settings: 'opsz' 72, 'wght' 600;
  font-size: var(--t-h1);
  line-height: var(--lh-tight);
  margin: 0 0 var(--s-5);
}

/* Section headings carry a short horn rule. It is the one repeated marker that
   tells you a new section started without relying on size alone. */
h2 {
  font-variation-settings: 'opsz' 40, 'wght' 600;
  font-size: var(--t-h2);
  margin: clamp(2.5rem, 5vw, 3.75rem) 0 var(--s-4);
}
h2::before {
  content: "";
  display: block;
  width: 2.25rem; height: 2px;
  margin-bottom: var(--s-4);
  background: var(--accent);
}
h2:first-child { margin-top: 0; }

h3 {
  font-variation-settings: 'opsz' 24, 'wght' 600;
  font-size: var(--t-h3);
  margin: var(--s-6) 0 var(--s-2);
}

p { margin: 0 0 var(--s-4); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

strong { font-variation-settings: 'opsz' 14, 'wght' 700; }
em { font-style: italic; }

.lede {
  font-variation-settings: 'opsz' 20, 'wght' var(--wght-body);
  font-size: var(--t-lg);
  color: var(--fg);
  margin-bottom: var(--s-5);
}

/* The mono register: facts, dates, labels. Never below 0.8rem — the old
   0.72rem landed at ~11px, which is where "hard to read" starts. */
.eyebrow, .entry-date, .entry-meta, .game-facts, .foot-links,
.site-head nav a, .btn, .nav-toggle, .toc {
  font-family: var(--mono);
  font-variation-settings: normal;
}

.eyebrow {
  font-size: var(--t-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 var(--s-3);
}

.anchor {
  margin-left: 0.4em;
  color: var(--line-strong);
  text-decoration: none;
  font-family: var(--mono);
  font-variation-settings: normal;
  font-size: 0.6em;
  opacity: 0;
  transition: opacity 0.15s;
}
h2:hover .anchor, h3:hover .anchor, .anchor:focus-visible { opacity: 1; }
.anchor:hover { color: var(--accent); }

/* ----------------------------------------------------------- 6. header */

.site-head-outer {
  position: sticky; top: 0; z-index: 20;
  background: var(--veil);
  border-bottom: 1px solid var(--line);
}
@supports (backdrop-filter: blur(4px)) {
  .site-head-outer { backdrop-filter: blur(10px) saturate(1.2); }
}
@media (max-height: 32rem) { .site-head-outer { position: static; } }

/* The shell containers pad INSIDE their max-width, while the flow grid's wide
   track does not — so `max-width: var(--w-wide)` put the header and footer a
   full gutter inboard of the content they sit above and below. Adding the
   gutters back to the cap makes the two edges resolve to the same pixel at
   every viewport. This is the alignment the whole layout is for; do not
   "simplify" it back to a bare --w-wide. */
.site-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4);
  max-width: calc(var(--w-wide) + var(--gutter) * 2);
  margin-inline: auto;
  padding: var(--s-3) var(--gutter);
}

.brand {
  display: inline-flex; align-items: center; gap: 0.6rem;
  text-decoration: none; color: var(--fg);
  font-variation-settings: 'opsz' 60, 'wght' 600;
  font-size: 1.05rem; letter-spacing: 0.09em; text-transform: uppercase;
  white-space: nowrap;
}
.brand:hover { color: var(--accent); }
.brand img { flex: none; }

.site-head nav { display: flex; gap: var(--s-5); align-items: center; }
.site-head nav a {
  position: relative;
  text-decoration: none; color: var(--muted);
  font-size: var(--t-xs);
  letter-spacing: 0.12em; text-transform: uppercase;
  padding-block: var(--s-2);
}
.site-head nav a:hover { color: var(--fg); }

/* Current section: an underline as well as a colour change, so the state is
   not carried by colour alone. */
.site-head nav a[aria-current] { color: var(--fg); }
.site-head nav a[aria-current]::after {
  content: ""; position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--accent);
}

/* ------------------------------------------------------------- 7. hero */

.hero { padding-block: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 3vw, 2.5rem); }
.hero-inner {
  grid-column: wide;
  display: flex; align-items: center; gap: clamp(1.5rem, 5vw, 3.5rem);
}
.hero-mark { flex: 0 0 auto; }
.hero-mark img { display: block; width: min(280px, 34vw); height: auto; }
.hero-word { min-width: 0; }
.hero-word .wordmark { width: min(420px, 100%); height: auto; display: block; }
.hero-line {
  font-variation-settings: 'opsz' 32, 'wght' 500;
  font-size: var(--t-lg);
  color: var(--fg);
  margin: var(--s-5) 0 0;
  max-width: 32ch;
  /* one sentence now, so balance the wrap rather than orphaning the tail */
  text-wrap: balance;
}

@media (max-width: 46rem) {
  .hero-inner { flex-direction: column; gap: var(--s-5); text-align: center; }
  .hero-mark img { width: min(200px, 42vw); }
  .hero-word .wordmark { margin: 0 auto; }
  .hero-line { margin-inline: auto; }
}

/* -------------------------------------------------------- 8. game card */

/* the eyebrow labels the card, so it takes the card's edge, not the text edge */
.now-making .eyebrow { grid-column: wide; }

.game-card {
  grid-column: wide;
  display: grid; grid-template-columns: minmax(0, 20rem) 1fr;
  gap: clamp(1.25rem, 3vw, 2rem);
  align-items: start;
  border: 1px solid var(--line);
  background: var(--surface);
  padding: clamp(1rem, 2.5vw, 1.5rem);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
}
.game-art { display: block; border-radius: var(--r-md); overflow: hidden; }
.game-art img {
  display: block; width: 100%; height: auto;
  transition: transform 0.3s ease;
}
.game-card:hover .game-art img { transform: scale(1.02); }
.game-copy > :first-child { margin-top: 0; }
.game-copy h2 { margin-top: 0; font-size: var(--t-h3); }
.game-copy h2::before { content: none; }
.game-copy h2 a { color: inherit; text-decoration: none; }
.game-copy h2 a:hover { color: var(--accent); text-decoration: underline; }
.game-copy h2 span {
  display: block;
  font-variation-settings: 'opsz' 24, 'wght' 400;
  color: var(--muted);
}
.game-copy p { color: var(--fg-2); }
.game-facts {
  font-size: var(--t-xs);
  letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--muted);
  margin: var(--s-4) 0;
}
.game-links { display: flex; gap: var(--s-3); flex-wrap: wrap; margin: 0; }

@media (max-width: 46rem) {
  .game-card { grid-template-columns: 1fr; }
}
@media (max-width: 30rem) {
  /* stacked buttons of unequal label length read as two loose links; equal
     width makes them one control group */
  .game-links { flex-direction: column; align-items: stretch; }
}
@media (prefers-reduced-motion: reduce) {
  .game-card:hover .game-art img { transform: none; }
}

/* --------------------------------------------------------- 9. buttons */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 2.75rem;                 /* 44px touch target */
  padding: 0.6rem 1.25rem;
  background: var(--btn-bg); color: var(--btn-fg);
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  font-size: var(--t-xs);
  letter-spacing: 0.1em; text-transform: uppercase;
  transition: background-color 0.18s, color 0.18s, transform 0.18s, box-shadow 0.18s;
}
.btn:hover {
  background: var(--btn-bg-hover); color: var(--btn-fg);
  transform: translateY(-1px);
  box-shadow: var(--shadow);
}
.btn:active { transform: translateY(0); box-shadow: none; }

.btn.ghost {
  background: transparent; color: var(--fg);
  border-color: var(--line-strong);
}
.btn.ghost:hover {
  background: transparent;
  border-color: var(--accent); color: var(--accent);
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce) {
  .btn, .btn:hover, .btn:active { transform: none; transition: none; }
}

/* --------------------------------------------------- 10. entry listings */

.entry-list { list-style: none; margin: 0; padding: 0; }
.entry-list li {
  padding: var(--s-5) 0;
  border-top: 1px solid var(--line);
}
.entry-list li:last-child { border-bottom: 1px solid var(--line); }

.entry-date, .entry-meta {
  font-size: var(--t-xs);
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted);
}
.entry-list .entry-date { display: block; margin-bottom: var(--s-2); }
.entry-list a {
  font-variation-settings: 'opsz' 30, 'wght' 600;
  font-size: var(--t-h3);
  text-decoration: none; color: var(--fg);
  line-height: var(--lh-head);
}
.entry-list a:hover { color: var(--accent); text-decoration: underline; }
.entry-desc { margin: var(--s-2) 0 0; color: var(--fg-2); font-size: var(--t-sm); }

.empty { color: var(--muted); font-style: italic; }
.more { margin-top: var(--s-5); }
.feed-link { margin-top: var(--s-6); }
.entry-meta { display: block; margin-bottom: var(--s-3); }
.entry-back { margin-top: var(--s-8); }

/* ---------------------------------------------------------- 11. drafts */

.draft-tag {
  font-family: var(--mono); font-variation-settings: normal;
  font-size: 0.65rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--flag);
  border: 1px solid var(--flag); border-radius: var(--r-sm); padding: 0.05em 0.4em;
  vertical-align: middle;
}
.draft-banner {
  position: relative; z-index: 30;
  background: #a33; color: #fff; text-align: center;
  font-family: var(--mono); font-size: var(--t-sm); padding: var(--s-2);
}

/* ----------------------------------------------------- 12. prose bodies */

.page > h1:first-child, .entry > h1:first-child { margin-top: 0; }

.page ul, .page ol, .entry ul, .entry ol {
  margin: 0 0 var(--s-4);
  padding-left: 1.3em;
}
.page li, .entry li { margin-bottom: var(--s-3); }
.page li::marker, .entry li::marker { color: var(--accent); }

blockquote {
  margin: var(--s-5) 0;
  padding: var(--s-1) var(--s-5);
  border-left: 3px solid var(--accent-soft);
  color: var(--fg-2);
  font-style: italic;
}

pre {
  background: var(--code-bg); border: 1px solid var(--line);
  padding: var(--s-4); border-radius: var(--r-md);
  overflow-x: auto; font-size: var(--t-sm);
  line-height: 1.5;
}
code { font-family: var(--mono); font-variation-settings: normal; font-size: 0.88em; }
:not(pre) > code {
  background: var(--code-bg); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 0.1em 0.35em;
}

hr { border: none; border-top: 1px solid var(--line); margin: var(--s-7) 0; }

/* ------------------------------------------------- 13. on-this-page rail

   Wide screens only. Below the breakpoint there is no rail and the page is
   exactly what it was — the prose never depends on it. */
.toc { display: none; }

@media (min-width: 78rem) {
  .with-toc {
    display: grid;
    grid-template-columns:
      minmax(0, 1fr)
      min(100% - var(--gutter) * 2, var(--w-text))
      minmax(0, 1fr);
    column-gap: var(--gutter);
  }
  .with-toc > .page { grid-column: 2; display: block; padding: 0; }
  .with-toc > .toc { grid-column: 1; justify-self: end; }

  .toc {
    display: block;
    position: sticky; top: 5.5rem;
    width: min(15rem, 100%);
    max-height: calc(100vh - 8rem);
    overflow-y: auto;
    padding-right: var(--s-5);
    font-size: var(--t-xs);
  }
  .toc-title {
    display: block;
    color: var(--muted);
    letter-spacing: 0.14em; text-transform: uppercase;
    margin-bottom: var(--s-3);
  }
  .toc ol { list-style: none; margin: 0; padding: 0; }
  .toc li { margin: 0 0 var(--s-3); }
  .toc a {
    color: var(--fg-2);
    text-decoration: none;
    display: block;
    line-height: 1.4;
    padding: 0.15rem 0 0.15rem var(--s-3);
    border-left: 2px solid transparent;
    margin-left: -2px;
  }
  .toc a:hover { color: var(--accent); border-left-color: var(--accent); }
}

/* ----------------------------------------------------------- 14. footer */

.site-foot {
  background: var(--bg-2);
  border-top: 1px solid var(--line);
  padding-block: var(--s-7) var(--s-8);
  margin-top: var(--s-8);
  color: var(--muted);
  font-size: var(--t-sm);
}
.band-deep + .site-foot { border-top-color: transparent; }

.foot-inner {
  max-width: calc(var(--w-wide) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-5) var(--s-7);
  align-items: start;
  justify-content: space-between;
}
.foot-brand { display: flex; align-items: center; gap: var(--s-3); }
.foot-brand img { display: block; opacity: 0.85; flex: none; }
.foot-brand p { margin: 0; color: var(--fg-2); max-width: 24ch; }

.foot-links {
  display: flex; flex-wrap: wrap;
  gap: var(--s-2) var(--s-5);
  font-size: var(--t-xs);
  letter-spacing: 0.08em; text-transform: uppercase;
  margin: 0; padding: 0; list-style: none;
}
.foot-links a { color: var(--muted); text-decoration: none; }
.foot-links a:hover { color: var(--fg); text-decoration: underline; }

/* The mark, the footer mark and the wordmark are all single-tone #101014 art on
   transparency, so one filter carries them both ways. */
.hero-mark img, .brand img, .foot-brand img, .wordmark { filter: var(--mark-filter); }

/* -------------------------------------------------------- 15. mobile nav

   Two layers on purpose: the media query alone un-crams the header with no JS
   at all (the nav wraps to its own row), and the .js-nav layer collapses it
   behind a button when the script has run. Touch targets are 44px; the button
   is a real <button> with aria-expanded, not a checkbox hack, because this
   site advertises its accessibility on the store page. */
.nav-toggle { display: none; }
.nav-icon rect { fill: currentColor; }

@media (max-width: 46rem) {
  .site-head { flex-wrap: wrap; row-gap: var(--s-2); }
  .site-head nav { flex-basis: 100%; flex-wrap: wrap; gap: 0; }

  .nav-toggle {
    display: inline-flex; align-items: center; gap: var(--s-2);
    min-height: 2.75rem; padding: 0 var(--s-3);
    background: none; color: var(--muted); cursor: pointer;
    border: 1px solid var(--line-strong); border-radius: var(--r-sm);
    font-size: var(--t-xs);
    letter-spacing: 0.12em; text-transform: uppercase;
  }
  .nav-toggle:hover, .nav-toggle:focus-visible { color: var(--fg); border-color: var(--accent); }

  .js-nav .site-head nav { display: none; }
  .js-nav .site-head nav[data-open] { display: flex; flex-direction: column; }
  .js-nav .site-head nav[data-open] a {
    display: block; width: 100%;
    padding: var(--s-3) 0; font-size: var(--t-sm);
    border-top: 1px solid var(--line);
  }
  .site-head nav a[aria-current]::after { left: 0; right: auto; width: 1.5rem; bottom: 0.35rem; }
}

/* ---------------------------------------------------- 16. motion + print */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

@media print {
  .site-head-outer, .nav-toggle, .toc, .skip-link, .draft-banner { display: none; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .band, .site-foot { background: none; padding-block: 0; }
  a { color: #000; }
  .page, .entry, .flow { display: block; max-width: none; }
  h2::before { background: #000; }
}
