/* =============================================================================
   THE QUARTERLY - ISSUE No. 26
   amirhossein-yousefi.github.io - hand-written stylesheet, no framework,
   no build step, no external CSS. One Google Fonts request (Newsreader).

   -----------------------------------------------------------------------------
   THE COLOUR LAW  (audit this list before adding a single accent declaration)
   -----------------------------------------------------------------------------
   The page is warm paper, warm black ink and ONE second colour - iron-oxide
   vermilion (--accent) - used the way a printer uses a second plate. It is
   permitted in exactly these nine places and NOWHERE else:

     1.  Section rail: the accent tick and the mono folio numeral (No 01 - No 08).
     2.  Reference/patent hanging numerals [1]-[6], [P1]-[P3], and the 2px
         marginal stripe on the two sole-author preprints.
     3.  Identifier stamps: arXiv IDs / application numbers (text on --accent-wash).
     4.  Link underline colour at rest and its inked-in hover/focus state; the
         1px indicator that furniture and nav links grow on hover.
     5.  The focus-visible ring (--focus is an alias of --accent).
     6.  The current-role spine segment, its 7px filled square, and the
         PRESENT / PUBLISHED status tags.
     7.  The About drop cap.
     8.  The rosette (hero engraving + the 12px fleurons) and ::selection.
     9.  Index numerals and the arrow glyph on a HOVERED project row only.

   Deliberately NOT accent, though they once were: the ~18 ledger bullet dashes
   and the 7 glossary terms. Those were the two highest-density accent uses on
   the page and they were spent on its least meaningful elements, which left the
   status tags - the two places the colour actually means something - unable to
   register as status. Density is what makes a second plate read as signal.

   LICENSED EXCEPTION: --accent-soft is 4.27:1 (light) / 7.76:1 (dark). Light is
   the binding figure, so it is legal ONLY at >=24px. It appears, in dark theme
   only, on the drop cap. Putting it on any text at body size or below is a WCAG
   AA failure in light theme.

   FAILURE CONDITION: if the accent appears in an eleventh place, or --accent-soft
   appears under 24px, the direction is broken - remove it, do not rebalance.

   THE DATA CHANNEL: reported evaluation metrics (F1, WER, R@1, MRR, MAE, mIoU,
   ROC-AUC, accuracy) and the one delivered runtime figure are set in .fig -
   mono, tabular, --ink - against serif --ink-2 prose. It is a TYPOGRAPHIC
   channel, not a chromatic one; adding a colour to it would break the law above.
   No number is ever invented to feed it.

   NO SHADOWS. NO RADII. NO PHOTOGRAPHS. Depth is rules and paper tone only.

   -----------------------------------------------------------------------------
   CONTENTS
     01  Tokens (light)          08  Publications & Patents (reference lists)
     02  Tokens (dark, x2)       09  Experience & Education (ruled ledger)
     03  Reset & base            10  Projects (back-of-book index)
     04  Utilities               11  Glossary
     05  Strap (sticky nav)      12  Distinctions
     06  Masthead & stat strip   13  Colophon
     07  Section frame & rail    14  Motion / Responsive / Print / Reduced motion
   ============================================================================= */


/* =============================================================================
   01  TOKENS - LIGHT (declared on bare :root; nothing is defined only in a MQ)
   ============================================================================= */

:root {
  /* --- frame ------------------------------------------------------------- */
  --sheet: 76rem;
  --rail: 12.5rem;
  --gap: 3.5rem;
  --strap: 3.25rem;
  --pad: clamp(1.25rem, 5vw, 4.5rem);   /* the sheet gutter; rules bleed to it */

  /* --- list geometry: two gutters, one measure, two row rhythms -----------
     Every list on the page derives its left edge and its density from these
     five values. Adding a sixth means the reader has to re-find the text
     column at that section, which is exactly what this replaced. */
  --measure: 46rem;         /* every list block */
  --measure-prose: 34rem;   /* running prose only */
  --gutter-n: 3.25rem;      /* hanging numerals: refs, index */
  --gutter-label: 9.5rem;   /* hanging labels: ledger dates, glossary terms */
  --row: 1.6rem;            /* reference-list density */
  --row-tight: 1rem;        /* index / glossary density */

  /* --- three voices, one download ---------------------------------------- */
  --serif: "Newsreader", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --sans: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono", "Roboto Mono", Menlo, Consolas, monospace;

  /* --- warm paper, warm black ink, one accent ----------------------------- */
  --paper: #FAF8F4;
  --paper-2: #F2EEE6;
  --ink: #1A1A17;
  --ink-2: #423E36;
  --muted: #6B6355;
  --rule: #DCD5C6;
  --rule-strong: #B9AF9A;
  --accent: #9E2B12;
  --accent-soft: #C0563A;
  --accent-wash: #F6E4DC;
  --hair: rgba(26, 26, 23, 0.055);
  --focus: #9E2B12;

  /* --- derived ------------------------------------------------------------ */
  --underline: rgba(158, 43, 18, 0.72);
  --dropcap: var(--accent);
  --rosette-opacity: 0.14;
}

/* =============================================================================
   02  TOKENS - DARK. Same names, redefined twice so the explicit toggle wins in
       both directions. Warm ink-black, never #000.
   ============================================================================= */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #14130F;
    --paper-2: #1D1C16;
    --ink: #EDE9E0;
    --ink-2: #C6C0B2;
    --muted: #A29A8A;
    --rule: #322F28;
    --rule-strong: #4C473D;
    --accent: #E8674A;
    --accent-soft: #F08D74;
    --accent-wash: #2A1C16;
    --hair: rgba(237, 233, 224, 0.05);
    --focus: #E8674A;
    --underline: rgba(232, 103, 74, 0.72);
    --dropcap: var(--accent-soft);
    --rosette-opacity: 0.20;
  }
  /* Antialias the serif only on ink-black; on paper it renders spindly. */
  :root:not([data-theme="light"]) body { -webkit-font-smoothing: antialiased; }
}

:root[data-theme="dark"] {
  --paper: #14130F;
  --paper-2: #1D1C16;
  --ink: #EDE9E0;
  --ink-2: #C6C0B2;
  --muted: #A29A8A;
  --rule: #322F28;
  --rule-strong: #4C473D;
  --accent: #E8674A;
  --accent-soft: #F08D74;
  --accent-wash: #2A1C16;
  --hair: rgba(237, 233, 224, 0.05);
  --focus: #E8674A;
  --underline: rgba(232, 103, 74, 0.72);
  --dropcap: var(--accent-soft);
  --rosette-opacity: 0.20;
}
:root[data-theme="dark"] body { -webkit-font-smoothing: antialiased; }

/* The static <meta name="color-scheme"> follows the OS. When the toggle
   overrides the OS, the UA chrome (scrollbar track, overscroll gutter) has to
   follow the page or a white scrollbar runs down an ink-black column. */
:root[data-theme="dark"]  { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }


/* =============================================================================
   03  RESET & BASE
   ============================================================================= */

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

html {
  font-size: 100%;
  font-optical-sizing: auto;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 1.0625rem;
  font-weight: 420;
  line-height: 1.62;
  letter-spacing: 0.003em;
}

h1, h2, h3, p, ul, ol, dl, dd, figure, blockquote { margin: 0; padding: 0; }
ul, ol { list-style: none; }

img, svg { max-width: 100%; }
svg { display: block; }

::selection { background: var(--accent-wash); color: var(--ink); }

/* No element in the sheet is allowed a radius or a shadow. */
.sheet *, .strap * { border-radius: 0; box-shadow: none; }

/* --- links ------------------------------------------------------------------
   Prose links are underlined and ink in on hover. Furniture links (nav, strap,
   meta-sans) carry no rest underline and grow a 1px border instead. That split
   is the whole editorial conceit - never text-decoration:none on a body link. */

a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: var(--underline);
  transition: color .16s ease, background-color .16s ease, border-color .16s ease,
              text-decoration-color .16s ease, text-decoration-thickness .16s ease;
}
a:hover, a:focus-visible {
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
}

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

/* --- shared type voices ---------------------------------------------------- */

.meta {
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.fig, .stamp {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

.fig {
  font-size: 0.8125rem;
  letter-spacing: 0.01em;
  color: var(--ink);
  white-space: nowrap;
}

.stamp {
  display: inline-block;
  font-size: 0.8125rem;
  line-height: 1.4;
  letter-spacing: 0.01em;
  color: var(--accent);
  background: var(--accent-wash);
  padding: 0.12rem 0.4rem;
}


/* =============================================================================
   04  UTILITIES
   ============================================================================= */

.sheet {
  width: 100%;
  max-width: var(--sheet);
  margin-inline: auto;
  padding-inline: var(--pad);
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip {
  position: absolute;
  left: 1rem;
  top: -5rem;
  z-index: 60;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--paper);
  background: var(--ink);
  padding: 0.7rem 1rem;
  transition: top .16s ease;
}
.skip:focus { top: 0.5rem; }

/* The skip link moves focus to <main>; don't ring it for that programmatic hop. */
main[tabindex]:focus { outline: none; }
/* One offset, on the scrollport. scroll-padding-top covers BOTH anchor
   navigation and sequential-focus scrolling, including the ~50 focusable
   links that carry no id. A scroll-margin-top on [id] as well would stack
   with this and drop every anchor 88px below the strap instead of 20px. */
html { scroll-padding-top: calc(var(--strap) + 1.25rem); }

/* THE DOUBLE RULE - opens the masthead, closes the colophon. Twice, ever. */
.rule-double {
  height: 3px;
  border-top: 2px solid var(--ink);
  border-bottom: 1px solid var(--ink);
  box-sizing: content-box;
  margin-bottom: 1.25rem;
}

.hairline {
  height: 0;
  border-top: 1px solid var(--rule);
}


/* =============================================================================
   05  STRAP - the sticky nav
   ============================================================================= */

.strap {
  position: sticky;
  top: 0;
  z-index: 20;
  height: var(--strap);
  background: var(--paper);
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(8px);
  backdrop-filter: saturate(1.4) blur(8px);
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease;
}
.strap.is-scrolled { border-bottom-color: var(--rule); }

.strap-inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
}

.brand {
  position: relative;
  display: inline-flex;
  align-items: center;
  align-self: stretch;
  gap: 0.5rem;
  flex: 0 0 auto;
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
}
.brand::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% + 0.6rem);
  height: 1px;
  background: transparent;
  transition: background-color .16s ease;
}
.brand:hover::after, .brand:focus-visible::after { background: var(--accent); }
.brand:focus-visible { outline-offset: -3px; }
.brand .fleuron { color: var(--accent); flex: 0 0 auto; }

/* Eight nowrap links plus the brand and the toggle need ~1000px; the sheet only
   offers 0.9vw of it. So the nav is ALWAYS a scroller and only earns the right
   to sit flush right once there is genuinely room (see the 1200px query). No
   mask: a mask paints over the focus ring and, being anchored to the element
   box rather than to scroll position, never clears at the scroll end. */
.strap-nav {
  flex: 1 1 auto;
  min-width: 0;
  align-self: stretch;
  display: flex;
  align-items: stretch;
  justify-content: flex-start;
  gap: 1.1rem;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-padding-inline: 1rem;
}
.strap-nav::-webkit-scrollbar { display: none; }

/* Full-strap-height hit area (52px) with the indicator still under the text. */
.strap-nav a {
  position: relative;
  display: flex;
  align-items: center;
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
}
.strap-nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% + 0.6rem);
  height: 1px;
  background: transparent;
  transition: background-color .16s ease;
}
.strap-nav a:focus-visible { outline-offset: -3px; }
.strap-nav a:hover,
.strap-nav a:focus-visible,
.strap-nav a.is-current { color: var(--ink); }
.strap-nav a:hover::after,
.strap-nav a:focus-visible::after,
.strap-nav a.is-current::after { background: var(--accent); }

.toggle {
  display: none;
  position: relative;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  padding: 0;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--rule);
  color: var(--muted);
  cursor: pointer;
  transition: color .16s ease, border-color .16s ease;
}
/* Keep the 28px bordered box, extend the target to 44px. */
.toggle::after { content: ""; position: absolute; inset: -8px; }
.js .toggle { display: inline-flex; }
.toggle:hover, .toggle:focus-visible { color: var(--ink); border-color: var(--rule-strong); }
.toggle svg { width: 15px; height: 15px; }

.icon-moon { display: block; }
.icon-sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .icon-moon { display: none; }
  :root:not([data-theme="light"]) .icon-sun { display: block; }
}
:root[data-theme="dark"] .icon-moon { display: none; }
:root[data-theme="dark"] .icon-sun { display: block; }


/* =============================================================================
   06  MASTHEAD & STAT STRIP
   ============================================================================= */

.masthead {
  position: relative;
  overflow: hidden;                 /* scoped here ONLY - never on body/.section */
  padding-block: clamp(3rem, 7vw, 5.5rem) clamp(3rem, 6vw, 4.5rem);
}

/* LAYER 2 - the hairline weave. 9px and 13px are coprime, so the two fields
   never lock into a hard moire; masked to the top-right, gone under the text. */
.masthead::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    repeating-linear-gradient(17deg,  var(--hair) 0 1px, transparent 1px 9px),
    repeating-linear-gradient(-17deg, var(--hair) 0 1px, transparent 1px 13px);
  opacity: .55;
  -webkit-mask-image: radial-gradient(120% 90% at 88% 8%, #000 0%, transparent 62%);
  mask-image: radial-gradient(120% 90% at 88% 8%, #000 0%, transparent 62%);
}
@supports not (mask-image: radial-gradient(#000, #000)) {
  .masthead::before { opacity: .22; -webkit-mask-image: none; mask-image: none; }
}

/* LAYER 1 - the engraved rosette plate. It does not rotate; plates do not spin. */
.rosette {
  position: absolute;
  right: -6rem;
  top: -4rem;
  width: 34rem;
  height: 34rem;
  color: var(--accent);
  opacity: var(--rosette-opacity);
  pointer-events: none;
  z-index: 0;
}

/* .masthead-inner is a .sheet, so its own max-width must stay 76rem — capping the
   sheet box would let margin-inline:auto centre the masthead out of alignment with
   every section below it. Cap the children instead. 52rem is the masthead measure:
   wide enough that the four stat captions each sit on one line, narrow enough that
   the rules stop clear of the rosette. */
.masthead-inner { position: relative; z-index: 1; }
/* Text keeps the 52rem masthead measure... */
.masthead-inner > * { max-width: 52rem; }
/* ...but every RULE bleeds out to the sheet gutter, so the masthead's rules
   share one left origin and one right terminal with the eight section rules
   and the colophon rule below them. One rule datum for the whole page. */
.masthead-inner > .rule-double,
.masthead-inner > .hairline,
.masthead-inner > .stats {
  max-width: none;
  margin-inline: calc(-1 * var(--pad));
}
/* Put the gutter back as padding so the figures stay on the h1's left edge. */
.masthead-inner > .stats { padding-inline: var(--pad); }

.masthead-strap {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  justify-content: space-between;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

h1 {
  margin-top: 1.75rem;
  font-family: var(--serif);
  font-size: clamp(2.5rem, 7.2vw, 5.25rem);
  line-height: 0.98;
  overflow-wrap: anywhere;
  font-weight: 300;
  letter-spacing: -0.022em;
  color: var(--ink);
}

.deck {
  margin-top: 1.5rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.125rem, 2.2vw, 1.5rem);
  font-weight: 400;
  line-height: 1.42;
  letter-spacing: 0;
  color: var(--ink-2);
  max-width: 34rem;
}
.deck .roman { font-style: normal; font-weight: 600; letter-spacing: 0.01em; color: var(--ink); }

.masthead .hairline { margin-top: 2.25rem; }

.links {
  display: flex;
  flex-wrap: wrap;
  gap: 0 2rem;
  row-gap: 1rem;
  margin-top: 1.5rem;
}
.links a {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-top: 0.5rem;
  padding-bottom: 0.3rem;
}
.links a:hover, .links a:focus-visible { color: var(--ink); border-bottom-color: var(--accent); }
.links svg { width: 14px; height: 14px; flex: 0 0 auto; }

/* --- stat strip: a table of figures, not tiles ----------------------------- */

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-block: 1px solid var(--rule-strong);
  margin-top: 2.5rem;
}
.stat {
  padding: 1.125rem 1rem;
  border-left: 1px solid var(--rule);
  text-decoration: none;
  color: inherit;
  display: block;
}
.stat:first-child { border-left: 0; padding-left: 0; }
.stat-fig {
  display: block;
  font-family: var(--serif);
  font-size: clamp(2rem, 3.9vw, 2.75rem);
  line-height: 1;
  font-weight: 300;
  letter-spacing: -0.02em;
  color: var(--ink);
  font-variant-numeric: lining-nums tabular-nums;
}
.stat-cap { display: block; margin-top: 0.55rem; letter-spacing: 0.08em; }
.stat-sub {
  display: block;
  margin-top: 0.3rem;
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
a.stat .stat-fig { border-bottom: 1px solid var(--rule-strong); display: inline-block; }
a.stat:hover .stat-fig,
a.stat:focus-visible .stat-fig { border-bottom-color: var(--accent); }
a.stat:hover .stat-cap, a.stat:focus-visible .stat-cap { color: var(--ink); }


/* =============================================================================
   07  SECTION FRAME & RAIL - the spine of the design
   ============================================================================= */

.section {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr);
  column-gap: var(--gap);
  align-items: start;
  padding-block: clamp(4rem, 8vw, 7rem);
  border-top: 1px solid var(--rule);
}

.rail {
  position: sticky;
  top: calc(var(--strap) + 2rem);
  align-self: start;
}

.tick {
  width: 1.5rem;
  height: 2px;
  background: var(--accent);
  transition: width .28s cubic-bezier(.2, .6, .2, 1);
}
.section.is-active .tick { width: 3rem; }

.folio {
  display: block;
  margin-top: 0.9rem;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.section h2 {
  margin-top: 0.5rem;
  font-family: var(--serif);
  font-size: 1.75rem;
  line-height: 1.12;
  font-weight: 500;
  letter-spacing: -0.018em;
  color: var(--ink);
  hyphens: none;
}

.standfirst {
  margin-top: 0.7rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--muted);
}

/* Grid children default to min-width:auto; pin it so nothing can overflow. */
.section-body {
  min-width: 0;
  overflow-wrap: break-word;
}

/* Sticky rail item counts - volume and rarest fact, stated in micro type. */
.rail-count {
  display: block;
  margin-top: 0.9rem;
  font-family: var(--mono);
  font-size: 0.6875rem;
  line-height: 1.5;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}


/* =============================================================================
   08  No 01 ABOUT
   ============================================================================= */

.prose { max-width: var(--measure-prose); }
.prose p { color: var(--ink-2); }
.prose p + p { margin-top: 1.15em; }

.prose p:first-of-type::first-letter {
  float: left;
  font-size: 3.05em;
  line-height: 0.9;
  font-weight: 300;
  color: var(--dropcap);
  padding-right: 0.12em;
}



/* =============================================================================
   09  No 02 PUBLICATIONS & No 03 PATENTS - genuine reference lists
   ============================================================================= */

.refs { max-width: var(--measure); }

.ref {
  display: grid;
  grid-template-columns: var(--gutter-n) minmax(0, 1fr);
  column-gap: 0;
  border-top: 1px solid var(--rule);
  padding-block: var(--row);
  position: relative;
  transition: background-color .16s ease;
}
.ref:first-child { border-top: 0; padding-top: 0; }
.ref:last-child { padding-bottom: 0; }

.ref-n {
  font-family: var(--mono);
  font-size: 0.8125rem;
  line-height: 1.4;
  letter-spacing: 0.01em;
  color: var(--accent);
  padding-top: 0.28rem;
  font-variant-numeric: tabular-nums;
  transition: color .16s ease;
}

.ref:hover, .ref:focus-within {
  background: var(--paper-2);
  margin-inline: -1rem;
  padding-inline: 1rem;
}
.ref:hover .ref-n, .ref:focus-within .ref-n { color: var(--ink); }

.ref-body { min-width: 0; }

/* Sole-authored preprints carry a marginal stripe instead of a badge. */
.ref--sole .ref-body {
  border-left: 2px solid var(--accent);
  padding-left: 1rem;
  margin-left: -1rem;
}

.ref h3 {
  font-family: var(--serif);
  font-size: 1.1875rem;
  line-height: 1.3;
  font-weight: 500;
  letter-spacing: -0.006em;
  color: var(--ink);
  text-wrap: balance;
}
.refs--patents .ref h3 { font-size: 1.1875rem; line-height: 1.28; font-weight: 600; letter-spacing: -0.008em; }
.ref h3 a { color: inherit; padding-block: 0.2rem; }

.ref-attr {
  margin-top: 0.45rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--muted);
}

.ref-stamps {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 0.75rem;
  margin-top: 0.75rem;
}
.tag {
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.tag--accent { color: var(--accent); }


/* =============================================================================
   10  No 04 EXPERIENCE & No 08 EDUCATION - a ruled ledger
   ============================================================================= */

.ledger { max-width: var(--measure); }

.job {
  display: grid;
  grid-template-columns: var(--gutter-label) minmax(0, 1fr);
  column-gap: 2rem;
  border-top: 1px solid var(--rule);
  padding-block: var(--row);
}
.job:first-child { border-top: 0; padding-top: 0; }
.job:last-child { padding-bottom: 0; }

.job-dates {
  font-family: var(--mono);
  font-size: 0.8125rem;
  line-height: 1.5;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  text-align: right;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* The spine belongs to the ROW, not the body: on the body it stopped
   var(--row) short of every rule and restarted var(--row) after it, so seven
   segments read as a rendering accident rather than one timeline. */
.job { position: relative; }
.job::before {
  content: "";
  position: absolute;
  left: calc(var(--gutter-label) + 1rem);
  top: 0;
  bottom: 0;
  border-left: 1px solid var(--rule);
}
.job--current::before { border-left-color: var(--accent); }

.job-body {
  position: relative;
  min-width: 0;
  padding-left: 2rem;
  margin-left: -1rem;
}

.job--current .job-body::before {
  content: "";
  position: absolute;
  left: -4px;
  top: 0.4rem;
  width: 7px;
  height: 7px;
  background: var(--accent);
}

.job h3, .ledger h3 {
  font-family: var(--serif);
  font-size: 1.1875rem;
  line-height: 1.28;
  font-weight: 600;
  letter-spacing: -0.008em;
  color: var(--ink);
}

.job-role {
  margin-top: 0.2rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: 1rem;
  line-height: 1.4;
  color: var(--ink-2);
}
.job-place { margin-top: 0.45rem; }

.job-list { margin-top: 1rem; }
.job-list li {
  position: relative;
  padding-left: 1.25rem;
  font-size: 1rem;
  line-height: 1.58;
  font-weight: 420;
  color: var(--ink-2);
}
.job-list li + li { margin-top: 0.6rem; }
.job-list li::before {
  content: "\2013";
  position: absolute;
  left: 0;
  color: var(--rule-strong);
}

.edu-link { display: inline-block; margin-top: 0.75rem; }
a.furniture {
  display: inline-block;
  padding-top: 0.4rem;
  padding-bottom: 0.15rem;
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
}
a.furniture:hover, a.furniture:focus-visible { color: var(--ink); border-bottom-color: var(--accent); }


/* =============================================================================
   11  No 05 OPEN-SOURCE PROJECTS - a back-of-book index
   ============================================================================= */

/* A two-column grid, not multicol. Multicol balances by height, so with 14 rows
   of unequal depth the hairlines in the two columns land at unrelated
   y-positions — the one place on the page where the rules would go random.
   Grid rows share a height, so the rules align pairwise across the gutter. */
.index {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 3rem;
  max-width: var(--measure);
  border-top: 1px solid var(--rule);
}
.index li {
  position: relative;
  display: grid;
  grid-template-columns: var(--gutter-n) minmax(0, 1fr);
  padding: var(--row-tight) 0.75rem;
  margin-inline: -0.75rem;
  border-bottom: 1px solid var(--rule);
  transition: background-color .16s ease;
}

.index-n {
  font-family: var(--mono);
  font-size: 0.8125rem;
  line-height: 1.6;
  letter-spacing: 0.01em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  transition: color .16s ease;
}
.index-body { min-width: 0; }
.index h3 {
  font-family: var(--serif);
  font-size: 1.125rem;
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: -0.004em;
  color: var(--ink);
}
.index-body a { color: inherit; padding-block: 0.2rem; }
.index-body p {
  margin-top: 0.35rem;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--ink-2);
  text-wrap: pretty;
}
/* Out of the inline flow: as an inline-block after the title it could wrap
   onto a line of its own when the last word filled the measure, adding a
   phantom empty line to a row whose title otherwise fitted (project 11 did
   exactly that). Pinned to the row corner it can never affect the text. */
.index-arrow {
  position: absolute;
  top: calc(var(--row-tight) + 0.4rem);
  right: 0.75rem;
  width: 10px;
  height: 10px;
  color: var(--accent);
  opacity: 0;
  transition: opacity .16s ease;
}
.index li:hover, .index li:focus-within { background: var(--paper-2); }
.index li:hover .index-n, .index li:focus-within .index-n { color: var(--accent); }
.index li:hover .index-arrow, .index li:focus-within .index-arrow { opacity: 1; }

.index-foot { margin-top: 2rem; }
.index-foot .hairline { margin-bottom: 1rem; }
.index-foot p { text-align: right; }


/* =============================================================================
   12  No 06 TECHNICAL GLOSSARY
   ============================================================================= */

.glossary {
  display: grid;
  grid-template-columns: var(--gutter-label) minmax(0, 1fr);
  column-gap: 2.5rem;
  max-width: var(--measure);
}
.glossary dt,
.glossary dd {
  border-top: 1px solid var(--rule);
  padding-block: var(--row-tight);
}
.glossary dt {
  font-family: var(--sans);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  padding-top: 1.18rem;
}
.glossary dd {
  font-size: 1rem;
  line-height: 1.58;
  font-weight: 420;
  color: var(--ink-2);
}
.glossary > dt:first-of-type,
.glossary > dt:first-of-type + dd { border-top: 0; padding-top: 0; }
.glossary > dt:first-of-type { padding-top: 0.28rem; }

.glossary .gl-sep { border-top-color: var(--rule-strong); }

.terms li { display: inline-block; margin-right: 1.1rem; }


/* =============================================================================
   13  No 07 DISTINCTIONS - a figure list
   ============================================================================= */

.dists { max-width: var(--measure); }
.dist {
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr);
  column-gap: 1.75rem;
  align-items: baseline;
  border-top: 1px solid var(--rule);
  padding-block: var(--row);
}
.dist:first-child { border-top: 0; padding-top: 0; }
.dist:last-child { padding-bottom: 0; }

.dist-fig {
  font-family: var(--serif);
  font-size: 2.25rem;
  line-height: 1;
  font-weight: 300;
  letter-spacing: -0.02em;
  color: var(--ink);
  font-variant-numeric: lining-nums tabular-nums;
  white-space: nowrap;
}
.dist p {
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--ink-2);
}


/* =============================================================================
   14  COLOPHON
   ============================================================================= */

/* The rule belongs to the sheet, not the viewport: on .colophon it ran the
   full window width while every section rule stopped at the 76rem sheet. */
/* The trailing space is load-bearing, not decoration: the document has to stay
   tall enough for the LAST section to scroll up to scroll-padding-top. When the
   colophon note was removed the page lost ~62px and #education could no longer
   reach its anchor offset on a short viewport. */
.colophon { padding-block: 0 8.5rem; }
.colophon > .sheet { border-top: 1px solid var(--rule); padding-top: 3.5rem; }
.colophon .links { margin-top: 0; }
.terminal {
  display: flex;
  justify-content: center;
  margin-top: 3.5rem;
  color: var(--rule-strong);
}


/* =============================================================================
   15  MOTION
   ============================================================================= */

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}


/* =============================================================================
   16  RESPONSIVE - 360px to 1920px. Mobile is never a different document;
       only the frame changes. Above 1600px nothing grows but whitespace.
   ============================================================================= */

/* The plate has to clear the name. The collision band runs to ~1495px (the
   plate's left edge is W-448px; the masthead measure ends at (W-1216)/2+72+832),
   so the corrective query has to reach past it, not stop at 1400px. */
@media (max-width: 1500px) {
  .rosette { right: -11rem; top: -5rem; width: 32rem; height: 32rem; }
}

/* Once the nav genuinely fits, let it sit flush right against the toggle. */
@media (min-width: 1201px) {
  .strap-nav { justify-content: flex-end; gap: 1.35rem; }
}

@media (max-width: 1180px) {
  :root { --rail: 10rem; --gap: 2.5rem; }
}

@media (max-width: 1100px) {
  .index { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  /* --- the rail collapses onto a single baseline ------------------------- */
  .section {
    grid-template-columns: 1fr;
    row-gap: 1.75rem;
  }
  .rail {
    position: static;
    display: grid;
    grid-template-columns: auto auto 1fr;
    column-gap: 0.75rem;
    align-items: baseline;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--rule);
  }
  .tick { width: 2rem; align-self: center; }
  .section.is-active .tick { width: 2rem; }
  .folio { margin-top: 0; }
  .section h2 { margin-top: 0; font-size: 1.625rem; }
  .standfirst { grid-column: 1 / -1; margin-top: 0.6rem; max-width: 34rem; }
  .rail-count { grid-column: 1 / -1; margin-top: 0.6rem; }

  .rosette { width: 26rem; height: 26rem; right: -10rem; top: -2rem; opacity: .10; }
}

@media (max-width: 600px) {
  :root { --gutter-n: 2.5rem; }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .stat { padding: 1rem 1.25rem; }
  .stat:nth-child(2n+1) { border-left: 0; padding-left: 0; }
  .stat:nth-child(n+3) { border-top: 1px solid var(--rule); }

  h1 { letter-spacing: -0.015em; }
  .prose p:first-of-type::first-letter { font-size: 3em; }

  .section { padding-block: 4rem; }

  /* Ledger: dates stack above the body; the rule moves from left to top. */
  .job { grid-template-columns: 1fr; row-gap: 0.75rem; }
  .job::before { display: none; }
  .job-dates { text-align: left; }
  .job-dates .tag { display: inline; margin-top: 0; margin-left: 0.75rem; }
  .job-body {
    border-top: 1px solid var(--rule);
    padding-left: 0;
    margin-left: 0;
    padding-top: 0.9rem;
  }
  .job--current .job-body { border-top-color: var(--accent); }
  .job--current .job-body::before { left: 0; top: -3px; }

  .glossary { grid-template-columns: 1fr; }
  .glossary dt { padding-bottom: 0; padding-top: 1.1rem; }
  .glossary dd { border-top: 0; padding-top: 0.4rem; }
  .glossary > dt:first-of-type { padding-top: 0; }
  .glossary > dt:first-of-type + dd { padding-top: 0.4rem; }

  .dist { grid-template-columns: 1fr; row-gap: 0.5rem; }
  .dist-fig { font-size: 2rem; }

  .ref--sole .ref-body { padding-left: 0.6rem; margin-left: -0.6rem; }
  .index-foot p { text-align: left; }

  /* 360px: keep the name, tighten it, and let the nav keep its scroll room. */
  .brand { font-size: 0.625rem; letter-spacing: 0.12em; }
  .strap-inner { gap: 0.75rem; }
}


/* =============================================================================
   17  PRINT - the issue prints as a clean reference list, URLs included.
   ============================================================================= */

@media print {
  /* Four selectors, not three: the un-toggled system-dark case matches
     :root:not([data-theme="light"]) at (0,2,0) inside its own media query and
     would otherwise out-specify a bare :root here and print the dark plate. */
  :root,
  :root:not([data-theme="light"]),
  :root[data-theme="dark"],
  :root[data-theme="light"] {
    --paper: #FFFFFF;
    --paper-2: #FFFFFF;
    --ink: #000000;
    --ink-2: #222222;
    --muted: #444444;
    --rule: #BBBBBB;
    --rule-strong: #888888;
    --accent: #000000;
    --accent-soft: #333333;
    --accent-wash: #FFFFFF;
    --hair: transparent;
    --underline: transparent;
    --dropcap: #000000;
  }
  body { background: #fff; color: #000; font-size: 10.5pt; line-height: 1.45; }
  .strap, .toggle, .rosette, .skip, .index-arrow { display: none !important; }
  .masthead::before { display: none !important; }
  .section { grid-template-columns: 1fr; row-gap: 1rem; padding-block: 1.5rem; break-inside: auto; }
  .rail { position: static; }
  .index { grid-template-columns: 1fr; }
  .glossary { grid-template-columns: 9rem minmax(0, 1fr); }
  .job { grid-template-columns: 6.5rem minmax(0, 1fr); }
  .ref, .job, .dist, .index li { break-inside: avoid; }
  .stamp { background: none; padding: 0; }
  a { text-decoration: none; color: #000; }
  .refs a[href]::after,
  .index a[href]::after,
  .links a[href]::after,
  .ledger a[href]::after {
    content: "\0020\2014\0020" attr(href);
    font: 0.8em var(--mono);
    color: #444;
    word-break: break-all;
  }
}


/* =============================================================================
   18  REDUCED MOTION - last block in the stylesheet, deliberately
   ============================================================================= */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
