/* The spine — the document pages. Paper register.
   The material system is in /tokens.css, linked first. This is layout and prose.

   Built for four hundred lines of normative text, so the constraints are the
   readable ones: a fixed 68ch measure, one modular scale, hairline rules, and a
   4px rhythm. Constraints that are visible are what make plainness read as
   neutrality rather than as carelessness — the two are indistinguishable at a
   glance, and the page this replaces died partly of looking like nothing.

   THE TYPE RULE CARRIES MEANING: serif is prose, mono is machine-checkable.
   That is an epistemic marker, not a flavour. So field names, version strings,
   penalties and anchors are mono, and block code sits on Basanite in BOTH
   themes — a reader learns within a page that a dark panel means executable. */

.wrap { max-width:1080px; margin:0 auto; padding:40px 24px 96px; }

.page-head { margin-bottom:2.4rem; }

/* ---------- spine layout: a table of contents that stays put ---------- */
.spine { display:block; }
/* `.has-toc` and not `.spine` alone: a page with no table of contents has
   nothing to put in the sidebar track, and the prose would land in it and wrap
   at a fifth of its measure. The generator sets the class only when it emits a
   TOC — layout conditional on content has to be stated in the markup. */
@media (min-width:1000px) {
  .spine.has-toc { display:grid; grid-template-columns:15rem minmax(0,1fr); gap:48px; align-items:start; }
  .spine.has-toc .toc { position:sticky; top:40px; max-height:calc(100vh - 80px); overflow-y:auto; }
}
.toc { font-family:var(--mono); font-size:var(--type-00); line-height:1.6; }
.toc-title {
  margin:0 0 .6rem; text-transform:uppercase; letter-spacing:.14em; color:var(--muted);
}
.toc ul { list-style:none; margin:0; padding:0; border-left:1px solid var(--line); }
.toc li { margin:0; }
.toc a { display:block; padding:.28em 0 .28em .9rem; color:var(--muted); border-bottom:none; margin-left:-1px; border-left:1px solid transparent; }
.toc a:hover { color:var(--fg); border-left-color:var(--fg); }
.toc .toc-d3 a { padding-left:1.9rem; }
@media (max-width:999px) {
  .toc { margin-bottom:2.4rem; padding-bottom:1.4rem; border-bottom:1px solid var(--line); }
}

/* ---------- prose ---------- */
.prose { max-width:68ch; }
.prose > :first-child { margin-top:0; }
.prose p, .prose li { font-size:var(--type-1); line-height:1.65; }
.prose p { margin:0 0 1.1rem; }

.prose h1 { font-size:var(--type-4); line-height:1.15; font-weight:600; letter-spacing:-.005em; margin:0 0 1.4rem; }
.prose h2 { font-size:var(--type-3); line-height:1.25; font-weight:600; margin:2.6rem 0 .8rem; padding-top:1.4rem; border-top:1px solid var(--line); }
.prose h3 { font-size:var(--type-2); line-height:1.3; font-weight:600; margin:2rem 0 .6rem; }
.prose h4 { font-size:var(--type-1); font-weight:600; margin:1.6rem 0 .5rem; }

/* Every heading is a stable, citable address. The anchor is a real link with an
   accessible name — a grading dispute is settled by pasting a URL, so the URL
   has to be reachable without a mouse. It is quiet until hover or focus, and
   never hides from a keyboard. */
.prose .anchor {
  font-family:var(--mono); font-weight:400; color:var(--muted); border-bottom:none;
  margin-left:.4em; opacity:0; transition:opacity .12s ease;
}
.prose h1:hover .anchor, .prose h2:hover .anchor, .prose h3:hover .anchor,
.prose h4:hover .anchor, .prose .anchor:focus-visible { opacity:1; }
/* A fragment link must not land the heading under the viewport edge. */
.prose :target { scroll-margin-top:1.4rem; }

.prose ul, .prose ol { margin:0 0 1.1rem; padding-left:1.4rem; }
.prose li { margin:.35rem 0; }
.prose li::marker { color:var(--muted); }

.prose strong { font-weight:600; }
.prose hr { border:none; border-top:1px solid var(--line); margin:2.6rem 0; }

.prose blockquote {
  margin:1.4rem 0; padding:.2rem 0 .2rem 1.2rem;
  border-left:2px solid var(--line); color:var(--muted);
}
.prose blockquote p:last-child { margin-bottom:0; }

/* ---------- machine territory ---------- */
.prose code {
  font-family:var(--mono); font-size:.92em; font-variant-numeric:tabular-nums;
  background:var(--bg-up); border:1px solid var(--line); border-radius:2px; padding:.08em .3em;
}
/* Block code sits on stone in BOTH themes — the reader learns that a dark panel
   is something that runs. */
.prose pre {
  background:var(--basanite); color:var(--stone-fg);
  border:1px solid var(--stone-line); border-radius:2px;
  padding:14px 16px; overflow-x:auto; margin:0 0 1.1rem;
}
.prose pre code { background:none; border:none; padding:0; color:inherit; font-size:var(--type-0); }

/* ---------- tables: hairline, tabular, and never wider than the page ----------
   The measure is 68ch and a penalty table is not; it scrolls inside its own
   container so the document itself never scrolls sideways. */
.prose .table-wrap, .prose table { display:block; overflow-x:auto; max-width:100%; }
.prose table {
  border-collapse:collapse; font-size:var(--type-0); margin:0 0 1.4rem;
  font-variant-numeric:tabular-nums;
}
.prose th, .prose td { text-align:left; padding:7px 16px 7px 0; border-bottom:1px solid var(--line); vertical-align:top; }
.prose thead th {
  font-family:var(--mono); font-weight:400; font-size:var(--type-00);
  text-transform:uppercase; letter-spacing:.08em; color:var(--muted); white-space:nowrap;
}
.prose tbody td:first-child, .prose tbody th { white-space:nowrap; }

/* ---------- print: the specification must read on paper ----------
   Paper is forced, stone blocks print white with a hairline, interactive chrome
   goes away, and every link's destination is spelled out — a printed page that
   says "see the licence" and does not say where is a dead end. */
@media print {
  :root { --bg:#fff; --bg-up:#fff; --fg:#000; --muted:#444; --line:#00000033; }
  body { background:#fff; color:#000; }
  .site-nav, .toc, .anchor { display:none !important; }
  .spine { display:block; }
  .prose { max-width:none; }
  .prose pre { background:#fff !important; color:#000 !important; border:1px solid #00000033 !important; }
  .prose pre code { color:#000 !important; }
  .prose h2 { break-after:avoid; }
  .prose table, .prose pre, .prose blockquote { break-inside:avoid; }
  .prose a[href^="http"]::after { content:" (" attr(href) ")"; font-family:var(--mono); font-size:.8em; color:#444; word-break:break-all; }
}
