/* ═══════════════════════════════════════════════════════════════════════════
   PUBLIC DOCUMENT — the stylesheet for ADRASI's unauthenticated pages.
   Served at /library/public-document.css (route is pipeline's; this file is the
   frontend's). Linked by GET /library/article/:id and /library/concept/:id.

   FOUNDER, 2026-10-04: "The public tenant should look identical to a private
   tenant, just that it's accessible without authentication." So this is not a
   document theme — it is the APP's look, rebuilt for a page that has no
   JavaScript, no framework and no shared bundle.

   WHAT CANNOT BE IDENTICAL, and why that is not a compromise: the app's
   interactivity. No tabs, no lens list, no theme dial, no search. The page reads
   with JavaScript disabled because that is the whole point — controlled
   experiments say answer engines extract VISIBLE BODY TEXT and ignore
   machine-only metadata (Ahrefs: −4.6 to +2.4%, statistically zero, from JSON-LD
   across 1,885 pages). Appearance can be identical; behaviour is deliberately not.

   🔴 THE TOKEN BLOCK BELOW IS A MIRROR OF atlas.css's :root, not a reference.
   A public page cannot import the app's bundled, hashed stylesheet, so the values
   are copied — which makes this ONE FACT IN TWO PLACES, the failure mode this
   codebase has paid for most often. It is named here rather than hidden: if the
   palette moves in atlas.css, it must be moved here too. The durable fix is a
   third file holding only tokens, served to both; that needs pipeline's agreement
   and is proposed rather than assumed.

   SILVER (founder 2026-10-25: "public atlas (in silver theme)"). The cornflower
   family (--bar*, --pin, --sel, --band) is swapped for the homepage's silver, the
   values of the 10-21 Atlas-in-silver preview (docs/frontend/img-2026-10-21/
   atlas-silver). The surfaces and the meaning colours stay as mirrored. Until the
   app's Atlas turns silver too, those swapped tokens are the one place this file
   deliberately differs from atlas.css.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Mirrored from src/routes/atlas/atlas.css :root — the app's own surfaces. */
  --paper: #fcfcfd;  --card: #ffffff;
  --ink: #1b1e26;    --ink-2: #3c414d;  --muted: #82889a;  --faint: #bcc2ce;
  --line: #d7dae3;   --line-2: #e6e9f0; --band: #f6f7f8;   --sel: #f0f1f3;
  --bar: #eceef0;    --bar-ink: #4a525b; --bar-dim: #6b727a;
  --bar-line: rgba(74, 82, 91, .22);   --bar-soft: rgba(74, 82, 91, .06);
  --pin: #a9aeb5;    --corn-deep: #15181e;
  --ember: #d98a3d;  --sem-warn: #b07d2b;  --sem-error: #dc2626;
  --add-ink: #2c7a3f;

  --serif: Charter, 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
  --sans: -apple-system, 'SF Pro Text', 'Segoe UI', Roboto, system-ui, sans-serif;
  --mono: 'SF Mono', ui-monospace, Menlo, monospace;

  /* The reading contract, verbatim from the app's --rd-* scale. The evidence
     behind these numbers is docs/concept/typography-rules.html. */
  --rd-title: clamp(2.1875rem, 1.9rem + 1.4vw, 2.625rem);
  --rd-h2:    clamp(1.8125rem, 1.6rem + 1vw, 2.1875rem);
  --rd-h3:    clamp(1.5rem, 1.35rem + .7vw, 1.8125rem);
  --rd-body:  1rem;      /* 16px here, not the app's 15: no chrome competes for width */
  --rd-lh: 1.75;
  --rd-lh-head: 1.2;
}

/* NO THEME DIAL IS POSSIBLE — a dial needs JavaScript. So the system preference
   is the whole mechanism, which means it must be right rather than an extra. */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #111318;  --card: #171a21;
    --ink: #eceef4;    --ink-2: #bdc2ce;  --muted: #7d8496;  --faint: #4b5160;
    --line: #434a57;   --line-2: #353b47; --band: #1b1d21;   --sel: #22252a;
    --bar: #0e1117;    --bar-ink: #cfd5dd; --bar-dim: #9aa1aa;
    --bar-line: rgba(207, 213, 221, .22); --bar-soft: rgba(207, 213, 221, .08);
    --pin: #a4abb4;
    --corn-deep: #c2c8d2;
    --ember: #e29a55;  --sem-warn: #e8ad54;  --sem-error: #ff5c5c;
    --add-ink: #5fce7d;
  }
}

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--rd-body);
  line-height: var(--rd-lh);
  -webkit-font-smoothing: antialiased;
}

/* ── THE MASTHEAD, AND WHY IT IS CSS CONTENT ───────────────────────────────
   The app's chrome is a 54px bar with the brand in small caps over an inset
   cornflower pin. Reproduced here so the page is recognisably the same product
   before a reader has read a word of it — the founder's "identical to a private
   tenant" starts at the top of the viewport.

   It is a ::before rather than markup, and that is the RIGHT place for it twice
   over. Pipeline's markup has no site-level header to style — the only <header>
   is inside the article and holds its <h1> — so markup would be an ask. And more
   importantly: a machine reading this page should get title → AIS → boundary →
   article and NOTHING ELSE. Chrome in CSS is chrome a crawler never sees, which
   is exactly what we want of furniture. The usual objection to content-in-CSS —
   that it is invisible to machines — is the feature here.
   (It follows that nothing load-bearing may ever join it. The boundary sentence
   is real markup for precisely that reason.) */
body::before {
  content: 'adrasi';
  display: block;
  height: 54px;
  line-height: 54px;
  padding: 0 18px;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--bar);
  box-shadow: inset 0 2px 0 var(--pin), inset 0 -1px 0 var(--line);
}

main {
  max-width: 46rem;      /* ≈72 characters at this size — the reading measure */
  margin: 0 auto;
  padding: 2.5rem 1.25rem 4rem;
}

/* ── THE TITLE BLOCK ────────────────────────────────────────────────────── */
article > header { margin: 0 0 2rem; }
article > header h1 {
  margin: 0;
  font-family: var(--serif);
  font-size: var(--rd-title);
  line-height: var(--rd-lh-head);
  letter-spacing: -.01em;
  color: var(--ink);
  overflow-wrap: break-word;
}
/* The aboutness line (D6, founder's default 2026-10-07; pipeline API 01094) now
   lives INSIDE the labelled band, after the label and before the lede. It is
   model-written, so it belongs under the disclosure. Styled as a quiet one-line
   description in sans, not as the summary's first sentence: the serif lede that
   follows is the summary. If there is no lede, the bottom margin still separates
   it from the box edge or the asks below. */
.derived .aboutness {
  margin: 0 0 1rem;
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--muted);
  overflow-wrap: break-word;
}
article > header time,
article > header .kind {
  display: inline-block;
  margin-top: .6rem;
  font-family: var(--mono);
  font-size: .8125rem;
  color: var(--muted);
}

/* ── THE DERIVED BAND — what ADRASI wrote ───────────────────────────────── */
/* SHAPE BY PIPELINE (eac51595), founder's ruling: the disclosure is a LABEL AT THE
   TOP of the band, not a sentence after it. Better for the reader: they learn what
   they are reading BEFORE they read it, not after.

   BOXED ON ARTICLES, NEVER ON CONCEPTS — and that is not a style preference.
   · data-surface=article: ADRASI's summary sits above the CONTRIBUTOR'S text, so
     the box marks a real boundary between two authors.
   · data-surface=concept: the report beneath the summary is ALSO ours. Boxing the
     summary alone would draw a boundary that does not exist and imply the report
     below is someone else's. So no border AND no tint — a tinted panel without a
     border still reads as a box, and would draw the same false line.

   🔴 ON ARTICLES THE BOX EDGE NOW CARRIES MEANING. The old boundary sentence said
   in words that everything below was the contributor's own text, unaltered. That
   half now lives only in the label's title= tooltip, which a touch screen never
   shows. So on a phone the BOTTOM EDGE of this box is the only thing marking where
   ADRASI's text stops — hence a full-strength --line border rather than a faint
   one, and real space after it. */
.derived { margin: 0 0 2.25rem; }
.derived[data-surface="article"] {
  padding: 1.25rem 1.5rem .5rem;
  background: var(--band);
  border: 1px solid var(--line);
  border-radius: 12px;
}

/* ── 🔴 THE LABEL — A DISCLOSURE, NOT A DECORATION ──────────────────────────
   Rendering derived prose makes us the author of the top of this page, which
   engages the duty to disclose machine-generated content in a way that is
   "clear and distinguishable" and "perceivable by natural persons". It is the
   first child of the band and unsuppressible server-side.
   DO NOT display:none it, collapse it, shrink it below legibility, or rely on its
   title= — pipeline is explicit that the tooltip is "detail only, never the
   disclosure" (invisible on touch, weak to screen readers). The visible words ARE
   the disclosure; the section's role="note" and aria-label carry it to assistive
   tech separately.
   A pill, in the app's own chip idiom, so it reads as a LABEL rather than as the
   first sentence of the summary — and so it stands out identically on a concept
   page, where there is no box around it. */
.derived-label {
  display: inline-block;
  margin: 0 0 1.1rem;
  padding: .25rem .7rem;
  font-family: var(--sans);
  font-size: .8125rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--bar-ink);
  background: var(--sel);
  border: 1px solid var(--bar-line);
  border-radius: 999px;
}
/* The model and the "contributor's own text" note live in title=. A help cursor
   says there is more on hover, without pretending the hover is the disclosure. */
.derived-label[title] { cursor: help; }
.derived .lede {
  margin: 0 0 1.5rem;
  font-family: var(--serif);
  font-size: 1.1875rem;
  line-height: 1.6;
  color: var(--ink);
}

/* THREE STATES, AND TWO OF THEM LOOK IDENTICAL IF STYLED THE SAME.
   · h2 + .answer + blockquote  → composed under v1.3
   · h2 ALONE                   → composed under v1.2, before the field existed.
                                  The recompose of 2026-10-04 left ZERO live
                                  articles in this shape (pipeline 4c869279), but
                                  the renderer still emits it for any v1.2 row, so
                                  it is still designed for: a question that stands
                                  on its own, never a heading missing its body —
                                  no trailing rule, no reserved space, no colon.
   · h2 + .answer.retracted     → the fact that answered this was withdrawn
                                  AFTER composition. A CORRECTION, not an
                                  absence, and not to be tidied away. */
.derived h2 {
  margin: 1.5rem 0 .5rem;
  font-family: var(--serif);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.45;
  color: var(--ink);
}
.derived h2:first-of-type { margin-top: 0; }
.derived .answer {
  margin: 0 0 .5rem;
  font-size: .9375rem;
  color: var(--ink-2);
}
/* Withdrawn, not wrong. No strikethrough: a line through the text asserts the
   WORDS were incorrect, when what happened is that the fact behind them was
   retracted. The label is what makes the state legible on a page with no
   scripting, and the colour is warn rather than error because a correction is
   housekeeping, not a failure. */
.derived .answer.retracted {
  color: var(--muted);
  padding-left: .75rem;
  border-left: 2px solid var(--sem-warn);
}
.derived .answer.retracted::before {
  content: 'Retracted — ';
  font-family: var(--mono);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--sem-warn);
}
/* OPEN — the article raises the question and no fact answers it (AIS ruling, founder
   2026-10-09). The words "No fact in this article answers this." are in the markup, so a
   crawler reads them; this only quiets them. Not a warning colour: an open question is an
   honest state of the article, not a defect. No blockquote follows, so it carries the gap. */
.derived .answer.open {
  margin-bottom: 1.25rem;
  font-family: var(--sans);
  font-size: .875rem;
  font-style: italic;
  color: var(--muted);
}
.derived blockquote {
  margin: 0 0 1.25rem;
  padding: .5rem 0 .5rem 1rem;
  border-left: 2px solid var(--line);
  font-family: var(--serif);
  font-size: .9375rem;
  line-height: 1.6;
  color: var(--muted);
}
.derived blockquote p { margin: 0; }

/* ── THE CONTRIBUTOR'S OWN TEXT, reproduced without alteration ──────────── */
article > p,
article > ul,
article > ol,
article > blockquote,
article > h2,
article > h3,
article > h4 { font-family: var(--serif); }
article > h2 {
  margin: 2.5rem 0 .75rem;
  font-size: var(--rd-h2);
  line-height: var(--rd-lh-head);
  letter-spacing: -.005em;
}
article > h4 { margin: 1.75rem 0 .5rem; font-size: 1.1875rem; line-height: 1.3; }
article > h5 {
  margin: 1.5rem 0 .4rem;
  font-family: var(--sans); font-size: .8125rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
}
/* hr appears 30 times across the twelve rendered pages and had no rule — so the
   browser's grooved 3D line was standing in the middle of real articles. */
article hr { margin: 2.25rem 0; border: none; border-top: 1px solid var(--line); }
article > h3 {
  margin: 2rem 0 .5rem;
  font-size: var(--rd-h3);
  line-height: var(--rd-lh-head);
}
article > p { margin: 0 0 1.25rem; line-height: var(--rd-lh); color: var(--ink); }
article > ul, article > ol { margin: 0 0 1.25rem; padding-left: 1.5rem; line-height: var(--rd-lh); }
article li { margin-bottom: .4rem; }
article > blockquote {
  margin: 0 0 1.25rem;
  padding-left: 1.25rem;
  border-left: 3px solid var(--line);
  color: var(--ink-2);
}
article strong { font-weight: 700; }
article a { color: var(--bar-ink); text-decoration-color: var(--bar-line); text-underline-offset: 2px; }
article a:hover { text-decoration-color: currentColor; }

/* ── CITATIONS — each number is its own link ────────────────────────────── */
/* So "2" goes to article 2. Rendered as a group of individual targets rather
   than one link covering the bracket, which is pipeline's markup and the right
   shape; the styling must not merge them back into one blob. */
sup.cites {
  font-family: var(--mono);
  font-size: .6875rem;
  line-height: 1;
  color: var(--muted);
  white-space: nowrap;
}
sup.cites a.cite {
  color: var(--bar-ink);
  text-decoration: none;
  padding: 0 .1em;
  border-radius: 3px;
}
sup.cites a.cite:hover { background: var(--sel); text-decoration: underline; }

/* ── TABLES — the wrapper scrolls, the page never does ──────────────────── */
/* The wrapper exists so a wide table scrolls inside itself on a phone rather
   than shoving the page sideways. overflow-x on the wrapper is therefore the
   whole point of it, not decoration. */
.table-wrap { overflow-x: auto; margin: 0 0 1.5rem; border: 1px solid var(--line-2); border-radius: 10px; }
.table-wrap table { width: 100%; border-collapse: collapse; font-family: var(--sans); font-size: .875rem; }
.table-wrap th, .table-wrap td { padding: .6rem .75rem; text-align: left; vertical-align: top; }
.table-wrap thead th {
  background: var(--band);
  border-bottom: 1px solid var(--line);
  font-size: .75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
.table-wrap tbody tr + tr td { border-top: 1px solid var(--line-2); }

/* ── CODE, AND MERMAID AS SOURCE ────────────────────────────────────────── */
pre {
  overflow-x: auto;
  margin: 0 0 1.5rem;
  padding: 1rem;
  background: var(--card);
  border: 1px solid var(--line-2);
  border-radius: 10px;
  font-family: var(--mono);
  font-size: .8125rem;
  line-height: 1.55;
  color: var(--ink-2);
}
code { font-family: var(--mono); font-size: .875em; }
p code, li code, td code {
  padding: .1em .35em;
  background: var(--band);
  border: 1px solid var(--line-2);
  border-radius: 4px;
}
/* A DIAGRAM SHOWN AS ITS SOURCE, labelled so it is not mistaken for gibberish.
   Pipeline left mermaid unrendered on purpose: drawing it needs JavaScript, and
   the acceptance criterion is that the page reads with none — so the diagram is
   present and honest rather than an empty box only some readers see. Without a
   label, though, "present" and "honest" stop short of "comprehensible", which is
   what this ::before buys. My call, and easy to drop. */
pre.lang-mermaid { position: relative; padding-top: 2.25rem; }
pre.lang-mermaid::before {
  content: 'Diagram source';
  position: absolute; top: .6rem; left: 1rem;
  font-family: var(--mono); font-size: .6875rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--faint);
}

/* ── THE ARTICLE LIST (concept pages) ──────────────────────────────────── */
.articles { margin: 2rem 0 0; }
.articles h2 { font-family: var(--sans); font-size: .8125rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin: 0 0 .75rem; }
.articles ul, .articles ol { list-style: none; margin: 0; padding: 0; }
.articles li { margin: 0; border-top: 1px solid var(--line-2); }
.articles li a { display: block; padding: .7rem .25rem; font-family: var(--sans);
  font-size: .9375rem; color: var(--ink); text-decoration: none; }
.articles li a:hover { background: var(--band); }
.articles .kind { font-family: var(--mono); font-size: .75rem; color: var(--muted); margin-left: .5rem; }

/* ── FOOTER: PROVENANCE, AND HOW TO CITE ────────────────────────────────── */
footer.provenance {
  margin: 3rem 0 0;
  padding: 1.25rem 0 0;
  border-top: 1px solid var(--line);
  font-size: .8125rem;
  line-height: 1.6;
  color: var(--muted);
}
footer.provenance a { color: var(--bar-dim); }
.how-to-cite { margin: 1.25rem 0 0; }
/* The footer's dl: As of · Derived by · Status · License. Two columns so the terms
   line up — the Status row in particular ("Superseded — a later version exists")
   is a sentence that must read as the value of Status, not as loose prose. */
footer.provenance dl {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: .35rem 1.25rem;
  margin: 0 0 1.25rem;
}
footer.provenance dt { font-weight: 600; color: var(--muted); }
footer.provenance dd { margin: 0; color: var(--ink-2); overflow-wrap: anywhere; }
/* Earlier versions, as dated pills — the concept page's snapshot list. */
nav.snapshots { margin: 1.25rem 0 0; }
nav.snapshots ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; }
nav.snapshots a {
  display: inline-block; padding: .2rem .6rem;
  font-family: var(--mono); font-size: .75rem; color: var(--bar-ink); text-decoration: none;
  border: 1px solid var(--bar-line); border-radius: 999px;
}
nav.snapshots a:hover { background: var(--sel); }
/* Every heading in the footer — Provenance, How to cite, Earlier versions — had no
   rule and fell back to the browser's 1.5em bold. */
footer.provenance h2, .how-to-cite h3 {
  font-family: var(--sans); font-size: .75rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--faint); margin: 0 0 .5rem;
}
/* Fenced so it copies verbatim — so it must be selectable and must not wrap in a
   way that introduces characters a paste would carry. */
.how-to-cite pre { margin: 0; white-space: pre-wrap; overflow-wrap: break-word; user-select: all; }

/* ── PAGING ─────────────────────────────────────────────────────────────── */
nav.paging {
  display: flex; flex-wrap: wrap; align-items: center; gap: 1rem;
  margin: 2.5rem 0 0; padding-top: 1.25rem; border-top: 1px solid var(--line-2);
  font-family: var(--sans); font-size: .875rem;
}
nav.paging a {
  color: var(--bar-ink); text-decoration: none;
  padding: .4rem .8rem; border: 1px solid var(--bar-line); border-radius: 999px;
}
nav.paging a:hover { background: var(--sel); }
nav.paging [rel='next'] { margin-left: auto; }

time { font-variant-numeric: tabular-nums; }

/* ── MEDIA ──────────────────────────────────────────────────────────────── */
img, video, svg { max-width: 100%; height: auto; }

/* ── NARROW ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  main { padding: 1.75rem 1rem 3rem; }
  .derived[data-surface="article"] { padding: 1.1rem 1.1rem .25rem; border-radius: 10px; }
  footer.provenance dl { grid-template-columns: minmax(0, 1fr); gap: 0; }
  footer.provenance dd { margin-bottom: .55rem; }
  nav.paging [rel='next'] { margin-left: 0; }
}

/* ── PRINT ──────────────────────────────────────────────────────────────── */
/* A public article is a document somebody will print or save as PDF. The
   boundary sentence survives printing for the same reason it survives
   everything else: it is a disclosure, and a printed page is still a page a
   natural person reads. */
@media print {
  :root { --paper: #fff; --ink: #000; --ink-2: #222; --muted: #555; --line: #bbb; --line-2: #ddd; --band: #f6f6f6; }
  body { font-size: 11pt; }
  main { max-width: none; padding: 0; }
  /* The box and its label both print: a printed page is still read by a natural
     person, which is the whole basis of the disclosure. */
  .derived[data-surface="article"] { border: 1px solid #000; background: #f6f6f6; }
  .derived-label { color: #000; background: none; border: 1px solid #000; }
  nav.paging, body::before { display: none; }   /* chrome does not print */
  pre, .table-wrap { page-break-inside: avoid; }
  a { text-decoration: none; color: #000; }
  sup.cites a.cite { color: #000; }
}
