/* Exploratory-mode stylesheet, v2 — "field notes with a margin".
   Serif body for the prose; monospace for all metadata (the ledger voice);
   ALL margin content (numbered notes + labelled boxes) is click-to-open,
   click-to-dismiss — pure CSS, no JavaScript. ONE neon highlight used
   like a marker pen. Nothing moves uninvited.
   Rationale & receipts: Y. Design-Research/ (and /colophon/ on the site). */

/* Newsreader (SIL OFL — license vendored at /src/assets/fonts/), a serif
   designed for on-screen essay reading. Self-hosted per the research rules:
   single variable WOFF2 per style, latin subset, preloaded in the layout,
   system-serif fallback. */
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("/src/assets/fonts/newsreader-roman-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Newsreader";
  font-style: italic;
  font-weight: 200 800;
  font-display: swap;
  src: url("/src/assets/fonts/newsreader-italic-latin.woff2") format("woff2");
}

/* ALL colors and fonts live in theme.css — the parameters file.
   Edit values there, not here; this file only consumes the variables. */

/* Structural geometry. The knobs live in theme.css (--leftbar-width,
   --ribbon-min, --panel-width, --panel-min, --column-inset,
   --marginbox-width); everything here derives from them and from the
   window width, in the order the layout comment above describes. */
:root {
  --rail-reserve: calc(var(--marginbox-width) + var(--marginbox-gap) + 0.75rem);   /* room for an open card */
  --vw: 100vw;   /* the width the layout responds to (desktop: floored at --page-min, below) */
  /* 1. the ribbon gives way first … */
  --ribbon: clamp(var(--ribbon-min, 1rem), calc(var(--vw) - var(--panel-width, 48rem) - var(--rail-reserve)), var(--leftbar-width));
  /* 2. … then the panel, down to its minimum */
  --panel: clamp(var(--panel-min, 30rem), calc(var(--vw) - var(--ribbon-min, 1rem) - var(--rail-reserve)), var(--panel-width, 48rem));
  --inset-extra: calc(var(--column-inset, 1.25rem) - 1.25rem);   /* how much wider the column is than its 1.25rem default inset */
  --col-w: calc(var(--panel) - 2.5rem - var(--inset-extra));     /* the text measure */
  --page-left: var(--ribbon);                                     /* column offset = ribbon width */
  --col-total: calc(var(--page-left) + var(--panel));
}

/* THE LAYOUT, AT EVERY WIDTH — what gives way as the window narrows
   Three bands: left ribbon | main panel | right rail. The column is
   anchored at the left; it never centres. When the window is wide, all
   extra width goes to the right rail. As it narrows, in this order:
     1. the RIBBON shrinks, from --leftbar-width down to 1rem;
     2. then the PANEL shrinks, from --panel-width down to 30rem — the
        rail keeps room for an open card throughout;
     3. at that point (window < 47.65rem ≈ 762px) margin cards switch to
        opening BELOW their trigger, inside the panel, and the rail gives
        up its width;
     4. under 31rem (≈ 496px) on touch devices only the panel remains,
        full width, no ribbon, no rail; cards open below. Desktop windows
        instead stop shrinking at --page-min and clip.
   The minimums are theme.css knobs (--ribbon-min, --panel-min); the two
   switch points are the @media lines below (47.65rem and 31rem), derived
   from those knobs and the card width — see theme.css for the sums. */

/* THE TYPE SCALE (standardized 16 Jul 2026) — five sizes, no others:
   body 1.1875rem · small-body 1rem · mono-meta 0.8rem ·
   mono-micro 0.7rem · headings h1 1.6 / h2 1.3 / h3 1.125rem.
   New elements must reuse one of these. */

* { box-sizing: border-box; }
html {
  background: var(--bg);
  border-top: var(--top-rule, 4px) solid var(--accent);   /* the ink ribbon — full width; thickness is a theme.css knob */
  overflow-x: hidden;                    /* textures run past both edges */
}

body {
  position: relative;
  margin: 0 auto 0 var(--page-left);     /* FIXED left anchor, always */
  padding: 1.75rem 2.5rem 4rem var(--column-inset, 1.25rem);   /* right 2.5rem = the rail gap */
  max-width: var(--panel);                /* the panel, rule to rule */
  border-left: 1px solid var(--hairline); /* the ribbon's rule */
  border-right: 1px solid var(--hairline);   /* the rail's rule */
  font-family: var(--font-body);
  font-size: 1.1875rem;            /* 19px — Newsreader runs a touch small */
  font-optical-sizing: auto;
  line-height: 1.5;
  color: var(--ink);
}

/* The left ribbon: dotted texture from the screen's LEFT EXTREME up to
   the column's left rule — at every width. */
body::before {
  content: "";
  position: absolute;
  z-index: -1;
  right: 100%;
  top: 0;
  bottom: 0;
  width: 100vw;
  background-color: var(--rail-bg);
  background-image: var(--rail-pattern);
  background-size: var(--rail-spacing);
}

/* The RIGHT rail: dotted field from the panel's right rule to the
   screen's right extreme — whatever width is left over. Margin cards
   sit on top of it while it is wide enough for them. */
body::after {
  content: "";
  position: absolute;
  z-index: -1;
  left: 100%;
  top: 0;
  bottom: 0;
  width: calc(var(--vw) - var(--col-total));   /* to the window's edge (or the frozen page's edge) */
  background-color: var(--rail-bg);
  background-image: var(--rail-pattern);
  background-size: var(--rail-spacing);
}

/* ---- the marker pen: the ONLY loud thing on the site ---- */
::selection { background: var(--highlight); }
mark {
  background: var(--highlight);
  padding: 0 0.15em;
}

/* ---- page links: ink words, GREEN underline ---- */
/* The words stay prose-colored; the line carries the green. Green thus
   means "you can go somewhere", moved from the letters to the underline.
   Margin triggers (›chips) look nothing like this. */
a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--link);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 2px;
}
a:hover {
  background: var(--highlight);
  text-decoration-color: var(--link-hover);
}

/* ---- site header / footer: the mono frame around the serif page ---- */
header.site {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 0.9rem;
  margin-bottom: 2.9rem;           /* 2 × leading */
  font-family: var(--font-mono);
  font-size: 0.8rem;
}
a.site-name {
  font-weight: bold;
  color: var(--site-name);
  text-decoration: none;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
nav.site-nav a {
  margin-left: 1.1rem;
  color: var(--ink);
  text-decoration: none;
}
nav.site-nav a:first-child { margin-left: 0; }
nav.site-nav a:hover { background: var(--highlight); }
nav.site-nav a.current {
  box-shadow: inset 0 -0.45em 0 var(--highlight);  /* marker under current page */
}

footer.site {
  margin-top: 4.35rem;             /* 3 × leading */
  border-top: 1px solid var(--hairline);
  padding-top: 0.9rem;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.8rem;
}
footer.site a { color: var(--muted); }

/* ---- headings: serif, modest scale, spacing in leading multiples ---- */
h1 { font-size: 1.6rem;  line-height: 1.25; margin: 0 0 1.45rem; font-weight: bold; }
h2 { font-size: 1.3rem;  line-height: 1.3;  margin: 2.9rem 0 0.75rem; color: var(--accent); }
h3 { font-size: 1.125rem; margin: 1.45rem 0 0.5rem; }
p, ul, ol { margin: 0 0 1.05rem; }
blockquote {
  margin: 1.45rem 0;
  padding: 0.1rem 0 0.1rem 1.1rem;
  border-left: 3px solid var(--accent);
  color: var(--ink);
}

/* ---- metadata: everything mono, everything quiet ---- */
.meta, .status, .type {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--muted);
}
.status::before { content: "["; }
.status::after  { content: "]"; }

/* ---- THE LEDGER (homepage stream + section lists) ---- */
table.ledger {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-mono);
  font-size: 0.8rem;   /* mono-meta */
}
table.ledger td, table.ledger th {
  text-align: left;
  vertical-align: baseline;
  padding: 0.45rem 1rem 0.45rem 0;
  border-bottom: 1px solid var(--hairline);
}
table.ledger th {
  color: var(--muted);
  font-weight: normal;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.7rem;
}
table.ledger td.t-title {
  font-family: var(--font-body);
  font-size: 1rem;
  width: 60%;
}
table.ledger td:last-child, table.ledger th:last-child { padding-right: 0; }
table.ledger .status { white-space: nowrap; }
table.ledger td.t-date { white-space: nowrap; color: var(--muted); }
.pin { color: var(--accent); }

/* ---- highlight-view picks ---- */
ul.picks { list-style: none; padding: 0; }
ul.picks li { margin-bottom: 0.55rem; }
ul.picks li::before { content: "→ "; font-family: var(--font-mono); color: var(--muted); }
ul.picks .why { color: var(--muted); font-size: 1rem; }   /* small-body */

/* ---- the arrangement toggle: one collection, four views ---- */
/* Radios (group "view") select which pre-rendered arrangement shows;
   the default is checked at build time from site-config.json's
   homeView. Same no-JS machinery as the margin. */
input.view-input { display: none; }
.view { display: none; }
#view-highlight:checked ~ .view-highlight,
#view-date:checked ~ .view-date,
#view-type:checked ~ .view-type,
#view-tag:checked ~ .view-tag { display: block; }
.view-toggle {
  font-family: var(--font-mono);
  font-size: 0.8rem;   /* mono-meta */
  color: var(--muted);
}
.view-toggle label {
  cursor: pointer;
  padding: 0 0.3em;
  user-select: none;
}
.view-toggle label:hover { background: var(--highlight); color: var(--ink); }
#view-highlight:checked ~ .view-toggle label[for="view-highlight"],
#view-date:checked ~ .view-toggle label[for="view-date"],
#view-type:checked ~ .view-toggle label[for="view-type"],
#view-tag:checked ~ .view-toggle label[for="view-tag"] {
  box-shadow: inset 0 -0.45em 0 var(--highlight);   /* marker = current */
  color: var(--ink);
}
/* the category menu inside grouped views (type, tag): jump-links to
   the group headings — chrome, not content, so quiet like the nav */
.view-menu {
  font-family: var(--font-mono);
  font-size: 0.8rem;   /* mono-meta */
  color: var(--muted);
  margin: 0.4rem 0 1.05rem;
}
.view-menu a { color: var(--muted); text-decoration: none; }
.view-menu a:hover { background: var(--highlight); color: var(--ink); }

/* ---- tags: quiet mono chips; neon only on touch ---- */
a.tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.7rem;   /* mono-micro */
  color: var(--muted);
  text-decoration: none;
  border: 1px solid var(--hairline);
  border-radius: 3px;
  padding: 0 0.45em;
  margin-right: 0.3em;
}
a.tag:hover { background: var(--highlight); color: var(--ink); border-color: var(--ink); }

/* ---- article (essay / project / paper) header ---- */
article.essay > header { margin-bottom: 2.9rem; }
article.essay > header h1 { margin-bottom: 0.4rem; }

/* ================= THE MARGIN APPARATUS ================= */
/* Two devices, ONE behavior: everything in the margin is click-on /
   click-off (state carried by a hidden checkbox — no JavaScript).
     1. Numbered notes — footnote-style superscript triggers.
     2. Margin boxes   — labelled dotted-underline triggers.
   Wide screens: they open as soft cards in the dotted rail, close to
   the rule; width/gap/corners are parameters in theme.css. Narrow
   screens: they open inline and wear the rail's dotted texture, so
   the margin identity travels to mobile.
   RULES OF THE HOUSE: (1) nothing else on the site may float — a card
   slots between line boxes only if no other float occupies its band;
   (2) triggers must sit in text that spans the full column (not inside
   flex/grid sub-columns), or the rail offsets won't line up. */

article, main { counter-reset: sidenote-counter; }
input.margin-toggle { display: none; }

/* -- the twin-label swap: click the SAME chip to close -- */
/* Every trigger is two stacked labels: the opener shows while its card
   is closed; the identical twin (targeting margin-none) swaps in while
   open — so re-clicking the chip closes the card. */
.m-close { display: none; }
.m-open:has(+ .m-close + input:checked) { display: none; }
.m-close:has(+ input:checked) { display: inline; }

/* -- ONE trigger grammar: › means "opens here, in the margin" -- */
/* Every margin trigger — numbered note, labelled box, or full reader —
   is the same object: a mono chip starting with ›. Marker on hover,
   marker held while open. Page links look nothing like this. */
.mtrig {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.8rem;   /* mono-meta */
  color: var(--ink);
  padding: 0 0.15em;
  user-select: none;
  white-space: nowrap;
}
.mtrig::before { content: "›"; padding-right: 0.12em; }
.mtrig:hover { background: var(--highlight); }
.mtrig.m-close { background: var(--highlight); }   /* held while open */
/* numbered notes: the auto number follows the › */
.mtrig.sidenote-number.m-open { counter-increment: sidenote-counter; }
.mtrig.sidenote-number::after { content: counter(sidenote-counter); }

/* -- the cards: closed by default; simple soft boxes, no hard edges -- */
.sidenote, .marginbox {
  display: none;
  background: var(--bg);
  border: none;
  border-radius: var(--marginbox-radius);
}
.sidenote {
  font-family: var(--font-mono);
  font-size: 0.8rem;   /* mono-meta */
  line-height: 1.5;
  color: var(--muted);
  padding: 0.5rem 0.65rem;
}
.marginbox {
  font-family: var(--marginbox-font);
  font-size: var(--marginbox-size);
  line-height: 1.55;
  color: var(--ink);
  padding: 0.7rem 0.85rem;
}
input.margin-toggle:checked + .sidenote,
input.margin-toggle:checked + .marginbox { display: block; }

/* The window-width SWITCHES (cards in the rail vs below, the reader's
   pin, the sideways scrollbar) are generated at build time from the
   theme.css knobs — see src/content/breakpoints.css.liquid. */

/* ---- the ✕ close chip (every open card carries one) ---- */
.margin-close {
  display: block;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.7rem;   /* mono-micro */
  color: var(--muted);
  user-select: none;
  margin-bottom: 0.35rem;
}
.margin-close:hover span { background: var(--highlight); color: var(--ink); }   /* the marker covers the words, not the row */

/* ---- the margin READER: a full piece, readable in the rail ---- */
.marginreader {
  display: none;
  font-family: var(--font-body);   /* real reading content = serif */
  font-size: 1rem;                 /* small-body */
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg);
  border-radius: var(--marginbox-radius);
  padding: 0.9rem 1.1rem;
}
input.margin-toggle:checked + .marginreader { display: block; }
/* Inside a reader, embedded pieces keep their margin markup — flatten
   it: triggers vanish, notes render inline as quiet italic asides. */
.marginreader .mtrig,
.marginreader input.margin-toggle,
.marginreader .margin-close ~ * .margin-close { display: none; }
.marginreader .sidenote,
.marginreader .marginbox {
  display: inline;
  float: none;
  position: static;
  font-style: italic;
  font-family: var(--font-body);
  background: none;
  border: none;
  padding: 0;
}
.marginreader .sidenote::before { content: " ("; counter-increment: none; }
.marginreader .sidenote::after { content: ")"; }
.marginreader .sidenote .margin-close,
.marginreader .marginbox .margin-close { display: none; }

/* ---- images: photographs are the only color on the site ---- */
img { max-width: 100%; height: auto; }

/* ---- the intro row: text beside ONE portrait — NO floats ---- */
/* The photo is a flex sibling, not a float. Floats are reserved for
   the margin cards alone: a card slots between line boxes only if no
   other float occupies its band, so nothing else may ever float. */
.intro {
  display: flex;
  gap: 1.4rem;
  align-items: flex-start;
}
.intro-text { flex: 1; min-width: 0; }
figure.portrait {
  flex: 0 0 auto;
  width: 8rem;
  margin: 0.3rem 0 0;
}
figure.portrait img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border: 1px solid var(--hairline);
  border-radius: var(--marginbox-radius);
}
@media (max-width: 480px) and (hover: none) and (pointer: coarse) {
  figure.portrait { width: 6rem; }
}

/* ---- small screens ---- */
/* The ledger reflows from a 4-column table into stacked entries: date,
   type and status sit on one small mono line; the title gets the full
   width below. Same HTML, no horizontal squeeze. */
@media (max-width: 640px) and (hover: none) and (pointer: coarse) {
  table.ledger thead { display: none; }
  table.ledger, table.ledger tbody,
  table.ledger tr, table.ledger td { display: block; width: 100%; }
  table.ledger tr { padding: 0.6rem 0; border-bottom: 1px solid var(--hairline); }
  table.ledger td { border: none; padding: 0.06rem 0; }
  table.ledger td.t-date, table.ledger td.type,
  table.ledger td:last-child {
    display: inline-block;
    width: auto;
    margin-right: 0.8rem;
  }
  table.ledger td.t-title { width: 100%; font-size: 1.05rem; }
}
/* Desktop browsers (a mouse): the page never gets narrower than
   --page-min — the layout freezes there and the window clips it.
   Touch devices skip this and stay fluid. */
@media (hover: hover), (pointer: fine) {
  :root { --vw: max(100vw, var(--page-min, 40rem)); }
  html { min-width: var(--page-min, 40rem); }
}
@media (max-width: 30.99rem) and (hover: none) and (pointer: coarse) {
  /* phones: only the panel, full width — no ribbon, no rail */
  :root { --ribbon: 0rem; }
  body { max-width: none; padding-left: 1.25rem; padding-right: 1.25rem; border-left: 0; border-right: 0; }
  body::before, body::after { display: none; }
}
@media (max-width: 480px) and (hover: none) and (pointer: coarse) {
  body { font-size: 1.125rem; padding-top: 1.25rem; }
}
