/* ============================================================
   machine layer — the whole style system
   Five sections. Everything editable from one file.
   1 tokens · 2 base · 3 layout · 4 nav · 5 components
   ============================================================ */

/* --- 1 tokens ------------------------------------------------
   Light is the default. Dark arrives two ways: the reader's
   declared OS preference, or an explicit choice stored in
   localStorage. The explicit choice must win in BOTH directions,
   which is why [data-theme="light"] is restated below.
   ------------------------------------------------------------- */
:root {
  --bg:    #fbfbfa;
  --fg:    #1c1c1a;
  --dim:   #6b6b66;
  --line:  #dcdcd6;
  --hover: rgba(0,0,0,.04);

  --measure: 72ch;      /* content width  */
  --leading: 1.7;       /* body line-height */
  --size:    15px;      /* body */
  --lede:    25px;      /* the one sentence a page is about */
  --head:    19px;      /* section headings — the skim layer */
  --eyebrow: 13px;      /* the page label above the lede */
  --rail:    14rem;     /* nav column */
  --gap:     4rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:#111110; --fg:#e6e6e1; --dim:#8f8f88; --line:#2c2c29;
    --hover: rgba(255,255,255,.05);
  }
}

:root[data-theme="dark"] {
  --bg:#111110; --fg:#e6e6e1; --dim:#8f8f88; --line:#2c2c29;
  --hover: rgba(255,255,255,.05);
}

/* --- 2 base --------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--bg);
  color: var(--fg);
  font: var(--size)/var(--leading) ui-monospace, SFMono-Regular, "SF Mono",
        Menlo, Consolas, "Liberation Mono", monospace;
  padding: 0 5vw;
}

a { color: inherit; text-underline-offset: .2em; }
strong { font-weight: 600; }
em { font-style: normal; border-bottom: 1px dotted var(--line); }

:focus-visible { outline: 2px solid var(--fg); outline-offset: 2px; }

/* Motion is decoration here; anyone who has asked for less gets none. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

.skip { position: absolute; left: -9999px; }
.skip:focus {
  position: fixed; left: 1rem; top: 1rem; z-index: 9;
  background: var(--bg); border: 1px solid var(--fg); padding: .5rem .75rem;
}

/* --- 3 layout -------------------------------------------------- */
.wrap {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, var(--measure));
  gap: var(--gap);
  max-width: 96rem;
  margin: 0 auto;
  padding: 4rem 0 8rem;
}
@media (max-width: 60rem) {
  /* minmax(0, 1fr), never a bare 1fr. A bare 1fr is minmax(auto, 1fr), and
     `auto` means "at least as wide as my content" -- so one wide <pre> grows
     the column past the viewport and takes the whole page with it. The
     desktop rule above already guards this; this one did not, which put a
     horizontal scrollbar on every narrow screen. */
  .wrap { grid-template-columns: minmax(0, 1fr); gap: 2.5rem; padding-top: 2rem; }
}

/* --- 4 nav -----------------------------------------------------
   Scoped to .rail deliberately. These rules used to target every <nav>,
   which caught the in-page index too and left it sticky over the content. */
.rail { font-size: 14px; }
@media (min-width: 60rem) { .rail { position: sticky; top: 4rem; align-self: start; } }

.rail .brand { color: var(--dim); margin-bottom: 1rem; }
.rail ol { list-style: none; }
.rail li { margin: .15rem 0; }
.rail a {
  color: var(--dim); text-decoration: none; display: block; padding: .15rem 0;
  transition: color .15s ease;
}
.rail a:hover, .rail a:focus { color: var(--fg); }
.rail a[aria-current="page"] { color: var(--fg); }
.rail a[aria-current="page"]::before { content: "› "; }

/* theme control — text, not iconography. Three states, cycled. */
.theme {
  margin-top: 2rem; background: none; border: 0; padding: .15rem 0;
  font: inherit; color: var(--dim); cursor: pointer;
  transition: color .15s ease;
}
.theme:hover { color: var(--fg); }
.theme::before { content: "[" attr(data-mode) "]"; }

/* --- 5 components ---------------------------------------------- */

/* headings — numbered to match the index, so a reader can map between the
   two. The number replaces the old "##" prefix rather than joining it:
   both were competing for the same slot, and only one of them helps you
   find your place. The code register is carried elsewhere anyway — the
   monospace, the bracket tags, the pre blocks. */
main { counter-reset: sec; }

/* h1 is an eyebrow, not a headline — the lede below it is what the page is
   about, and it carries the weight. Small, dim, spaced. */
h1 {
  font-size: var(--eyebrow); font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--dim);
}

/* h2 is the skim layer. It was the same size as body text, which is why the
   argument was invisible unless you read every word. */
h2 {
  font-size: var(--head); font-weight: 600; line-height: 1.3;
  margin: 4.5rem 0 1rem;
  counter-increment: sec;
  scroll-margin-top: 2rem;   /* anchored headings are share targets */
}
h2::before {
  content: counter(sec);
  color: var(--line); font-weight: 400;
  margin-right: .6em;
}

/* prose */
.lede { font-size: var(--lede); line-height: 1.35; margin: .6rem 0 2.5rem; letter-spacing: -.01em; }
p { margin: 1rem 0; }

/* section index — generated from the headings, so it cannot go stale.
   Deliberately not an accordion: the evidence blocks are what make these
   pages worth trusting, and hiding them behind a click buries the thing
   that does the work. This gives the lookup affordance and hides nothing. */
.index { margin: 0 0 3rem; font-size: 14px; }
.index ol { list-style: none; counter-reset: idx; }
.index li { counter-increment: idx; margin: .1rem 0; }
.index a { color: var(--dim); text-decoration: none; display: block; padding: .15rem 0;
           transition: color .15s ease; }
.index a::before { content: counter(idx) "  "; color: var(--line); }
.index a:hover, .index a:focus { color: var(--fg); }


/* evidence — the one idea worth a component.
   solid rule = measured, dashed rule = reasoned. Carried by border
   STYLE rather than colour so it survives greyscale, colour blindness
   and a plain-text render. */
.ev { border-left: 2px solid var(--fg); padding: .1rem 0 .1rem 1.25rem; margin: 1.75rem 0; }
.ev.reasoned { border-left-style: dashed; border-left-color: var(--dim); }
.ev p { margin: .4rem 0; }
.tag { font-size: 12px; color: var(--dim); }

/* checklist — the one page that ends in something copy-pasteable.
   A real list rather than a <pre> of drawn boxes, so it survives being read
   aloud, reflowed, or pasted somewhere narrower than it was written. */
.check { list-style: none; margin: 1.25rem 0; }
.check li { position: relative; padding-left: 1.75rem; margin: .5rem 0; }
.check li::before {
  content: "\25A1";                  /* □ */
  position: absolute; left: 0; top: 0;
  color: var(--dim);
}

/* data + commands */
pre {
  border: 1px solid var(--line); padding: 1rem; overflow-x: auto;
  font-size: 13px; line-height: 1.5; margin: 1.25rem 0;
}

/* forward link — part of the reading flow, so it keeps the reader's weight */
.next {
  margin-top: 4rem; padding-top: 1.5rem; border-top: 1px solid var(--line);
  font-size: 14px; color: var(--dim);
}
.next a { color: var(--fg); }

/* footer — a citation, not navigation. Names the subject every [measured]
   claim came from, and the period, because these findings are about systems
   that change monthly and a reader who knows when should discount
   accordingly. Quieter than .next: it is not part of the argument.
   Aligned to the content column rather than spanning the grid. */
footer {
  grid-column: 2;
  margin-top: 3rem;
  font-size: 13px;
  color: var(--dim);
}
@media (max-width: 60rem) { footer { grid-column: 1; margin-top: 2rem; } }
footer a { color: var(--dim); }
footer a:hover, footer a:focus { color: var(--fg); }
