/* =============================================================================
   esmailpour.se — design system
   -----------------------------------------------------------------------------
   Identity notes, so future edits stay coherent:

   · Ground        Warm paper in light, warm ink in dark. Never neutral grey —
                   every surface carries a trace of ochre so the site reads as
                   printed matter rather than as an application chrome.
   · Shape         Cut corners, not radii. One 14px notch on the top-right of
                   cards and badges. Rounded corners appear nowhere.
   · Rules         Hairlines separate; 2px rules structure. Boxes are rare.
   · Type          Fraunces for voice, Inter for interface, JetBrains Mono for
                   anything a machine would say. Mono is also the metadata
                   voice — dates, labels, counts, kickers.
   · Colour        One accent per content type, used at small scale only:
                   rules, glyphs, labels. Never a filled hero.
   · Motion        120–260ms, ease-out, opacity and 2–8px transforms. Anything
                   larger is a bug.
   ========================================================================== */

/* ------------------------------------------------------------------ tokens */

:root {
  color-scheme: light;

  /* Ground */
  --paper:      #f4f1e9;
  --paper-2:    #fbf9f4;
  --paper-3:    #e9e4d7;
  --paper-sunk: #ece7db;

  /* Ink */
  --ink:        #16130f;
  --ink-2:      #453e34;
  --ink-3:      #736a5c;
  --ink-4:      #9c9284;

  /* Structure */
  --line:       #dcd5c4;
  --line-2:     #c7bea9;
  --line-hard:  #16130f;

  /* Accents — one per content type */
  --ember: #b8431c;
  --moss:  #2c6549;
  --plum:  #6b3a62;
  --sun:   #9a700a;
  --tide:  #1c6873;
  --lake:  #2c5872;
  --berry: #9d2246;

  --accent: var(--ember);
  --accent-soft: color-mix(in oklab, var(--accent) 12%, var(--paper));
  --accent-line: color-mix(in oklab, var(--accent) 40%, var(--line));

  --select: color-mix(in oklab, var(--accent) 26%, var(--paper));
  --shadow: 0 1px 0 var(--line), 0 12px 28px -22px rgba(30, 22, 10, .5);

  /* Type */
  --font-display: 'Fraunces', 'Iowan Old Style', Georgia, serif;
  --font-ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --t-display: clamp(3.2rem, 11.5vw, 9rem);
  --t-h1:      clamp(2.1rem, 5.2vw, 3.6rem);
  --t-h2:      clamp(1.55rem, 2.9vw, 2.25rem);
  --t-h3:      clamp(1.15rem, 1.7vw, 1.4rem);
  --t-body:    1.0625rem;
  --t-read:    clamp(1.075rem, .35vw + 1rem, 1.2rem);
  --t-small:   .875rem;
  --t-micro:   .6875rem;

  --display-variation: 'SOFT' 12, 'WONK' 1, 'opsz' 40;
  --display-weight: 550;        /* headings */
  --display-weight-strong: 600; /* card and hero titles */
  --display-tracking: -.015em;

  --lh-tight: 1.02;
  --lh-snug: 1.22;
  --lh-body: 1.68;

  /* Space */
  --s1: .25rem;  --s2: .5rem;   --s3: .75rem;  --s4: 1rem;
  --s5: 1.5rem;  --s6: 2rem;    --s7: 3rem;    --s8: 4rem;
  --s9: 6rem;    --s10: 9rem;

  /* Density. A theme sets how much air there is and how much chrome shows,
     so "make it calmer" is a data change rather than a redesign. Each
     --chrome-* token is a display value: `none` removes that piece of
     furniture without removing any content. */
  --space-section: clamp(var(--s7), 7vw, var(--s9));
  --rule-section: var(--line);
  --lift: -3px;
  --chrome-ticker: block;
  --chrome-texture: block;
  --chrome-meta-icon: inline-block;
  --chrome-dek-small: block;
  --chrome-explore-note: block;
  --chrome-eyebrow-icon: inline-block;

  --gutter: clamp(1.15rem, 4.2vw, 3.5rem);
  --measure: 66ch;
  --max: 82rem;

  /* Corners. Two mechanisms, one switch: sharp themes cut a notch with
     clip-path, soft themes round with border-radius and set the clips to
     none. Components reference the tokens, never a literal shape, so a theme
     can change the entire shape language without touching a component rule. */
  --r-sm: 0; --r-md: 0; --r-lg: 0; --r-pill: 0; --r-btn: 0; --r-input: 0;
  /* A card's media fills the box to the border, so it needs the card's
     radius less the 1px border. It carries its own rounding because a
     rounded overflow clip on the card is not applied to a child that has
     been promoted to its own compositing layer, which is what the hover
     scale does: the image then paints over the card's top border. */
  --r-media-top: max(0px, calc(var(--r-md) - 1px));
  --clip-sm: polygon(0 0, calc(100% - 6px) 0, 100% 6px, 100% 100%, 0 100%);
  --clip-md: polygon(0 0, calc(100% - var(--notch)) 0, 100% var(--notch), 100% 100%, 0 100%);
  --clip-lg: polygon(0 0, calc(100% - 22px) 0, 100% 22px, 100% 100%, 0 100%);

  --notch: 14px;
  --ease: cubic-bezier(.2, .7, .3, 1);
}

:root:not([data-theme='light']) {
  @media (prefers-color-scheme: dark) {
    color-scheme: dark;
    --paper:      #14120e;
    --paper-2:    #1b1814;
    --paper-3:    #251f19;
    --paper-sunk: #100e0b;
    --ink:        #f3eee2;
    --ink-2:      #cdc4b3;
    --ink-3:      #948b7c;
    --ink-4:      #6d6558;
    --line:       #2f2a22;
    --line-2:     #453e33;
    --line-hard:  #f3eee2;
    --ember: #ef7444;
    --moss:  #64c493;
    --plum:  #c891bd;
    --sun:   #e0b048;
    --tide:  #55bfcc;
    --lake:  #86b5d8;
    --berry: #ec7d93;
    --shadow: 0 1px 0 var(--line), 0 18px 34px -26px rgba(0, 0, 0, .9);
  }
}

:root[data-theme='dark'] {
  color-scheme: dark;
  --paper:      #14120e;
  --paper-2:    #1b1814;
  --paper-3:    #251f19;
  --paper-sunk: #100e0b;
  --ink:        #f3eee2;
  --ink-2:      #cdc4b3;
  --ink-3:      #948b7c;
  --ink-4:      #6d6558;
  --line:       #2f2a22;
  --line-2:     #453e33;
  --line-hard:  #f3eee2;
  --ember: #ef7444;
  --moss:  #64c493;
  --plum:  #c891bd;
  --sun:   #e0b048;
  --tide:  #55bfcc;
  --lake:  #86b5d8;
  --berry: #ec7d93;
  --shadow: 0 1px 0 var(--line), 0 18px 34px -26px rgba(0, 0, 0, .9);
}

/* Content-type accent binding. Every card, badge and page sets data-accent. */
[data-accent='ember'] { --accent: var(--ember); }
[data-accent='moss']  { --accent: var(--moss); }
[data-accent='plum']  { --accent: var(--plum); }
[data-accent='sun']   { --accent: var(--sun); }
[data-accent='tide']  { --accent: var(--tide); }
[data-accent='lake']  { --accent: var(--lake); }
[data-accent='berry'] { --accent: var(--berry); }

/* --------------------------------------------------------------------- base */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1;
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  font-variation-settings: var(--display-variation);
  line-height: var(--lh-snug);
  letter-spacing: var(--display-tracking);
  margin: 0;
  text-wrap: balance;
}

p { margin: 0 0 1em; }

a { color: inherit; text-decoration-color: var(--line-2); text-underline-offset: .18em; }
a:hover { text-decoration-color: var(--accent); }

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

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

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

hr { border: 0; border-top: 1px solid var(--line); margin: var(--s7) 0; }

/* Utility voices ----------------------------------------------------------- */

.mono {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 500;
}

.dek { color: var(--ink-2); font-size: 1.0625rem; line-height: 1.55; text-wrap: pretty; }
.muted { color: var(--ink-3); }
.center { text-align: center; }
.sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: var(--s4); top: -4rem; z-index: 100;
  background: var(--ink); color: var(--paper); padding: var(--s3) var(--s4);
  transition: top .18s var(--ease);
}
.skip:focus { top: var(--s4); }

/* Shapes ------------------------------------------------------------------- */

.notch { border-radius: var(--r-md); clip-path: var(--clip-md); }

.grid-paper {
  background-image:
    linear-gradient(to right, color-mix(in oklab, var(--line) 55%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in oklab, var(--line) 55%, transparent) 1px, transparent 1px);
  background-size: 28px 28px;
  background-position: center;
}

/* -------------------------------------------------------------------- layout */

.wrap { width: min(var(--max), 100% - var(--gutter) * 2); margin-inline: auto; }
.wrap-narrow { width: min(58rem, 100% - var(--gutter) * 2); margin-inline: auto; }

.section { padding-block: var(--space-section); }
.section + .section { border-top: 1px solid var(--rule-section); }

.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s6);
}
.section-head h2 { font-size: var(--t-h2); }
.section-head .mono { color: var(--ink-3); }

.eyebrow {
  display: flex; align-items: center; gap: var(--s3);
  color: var(--ink-3); margin-bottom: var(--s4);
}
.eyebrow::after {
  content: ''; flex: 1; height: 1px; background: var(--line);
}
.eyebrow > .tick { color: var(--accent); }

/* ----------------------------------------------------------------- masthead */

.masthead {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in oklab, var(--paper) 88%, transparent);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--line);
}
.masthead__bar {
  display: flex; align-items: center; gap: var(--s5);
  height: 3.75rem;
}
.brand {
  display: flex; align-items: center; gap: var(--s3);
  text-decoration: none; flex: none;
}
.brand__mark {
  width: 1.85rem; height: 1.85rem; flex: none;
  display: grid; place-items: center;
  background: var(--ink); color: var(--paper);
  font-family: var(--font-mono); font-size: .7rem; font-weight: 700;
  letter-spacing: .04em;
  border-radius: var(--r-sm); clip-path: var(--clip-sm);
  transition: transform .2s var(--ease);
}
.brand:hover .brand__mark { transform: translateY(-2px) rotate(-3deg); }
.brand__name {
  font-family: var(--font-display); font-size: 1.05rem; font-weight: var(--display-weight-strong);
  font-variation-settings: 'SOFT' 20, 'WONK' 1, 'opsz' 20;
  letter-spacing: -.01em;
}
.brand__dot { color: var(--ember); }

.mainnav { display: flex; gap: var(--s1); margin-left: auto; }
.mainnav a {
  padding: .4rem .6rem; text-decoration: none; font-size: .9rem;
  color: var(--ink-2); position: relative; white-space: nowrap;
}
.mainnav a::after {
  content: ''; position: absolute; left: .6rem; right: .6rem; bottom: .1rem;
  height: 2px; background: var(--accent); transform: scaleX(0);
  transform-origin: left; transition: transform .2s var(--ease);
}
.mainnav a:hover { color: var(--ink); }
.mainnav a:hover::after, .mainnav a[aria-current='page']::after { transform: scaleX(1); }
.mainnav a[aria-current='page'] { color: var(--ink); }

.masthead__tools { display: flex; align-items: center; gap: var(--s2); }

.iconbtn {
  width: 2.1rem; height: 2.1rem; display: grid; place-items: center;
  border: 1px solid var(--line); color: var(--ink-2);
  transition: border-color .18s var(--ease), color .18s var(--ease), transform .18s var(--ease);
  border-radius: var(--r-sm); clip-path: var(--clip-sm);
}
.iconbtn:hover { border-color: var(--line-hard); color: var(--ink); transform: translateY(-1px); }
.iconbtn svg { width: 1rem; height: 1rem; }

.searchbtn {
  display: flex; align-items: center; gap: var(--s3);
  border: 1px solid var(--line); padding: .35rem .5rem .35rem .6rem;
  color: var(--ink-3); font-family: var(--font-mono); font-size: .75rem;
  border-radius: var(--r-sm); clip-path: var(--clip-sm);
  transition: border-color .18s var(--ease), color .18s var(--ease);
}
.searchbtn:hover { border-color: var(--line-hard); color: var(--ink); }
.searchbtn kbd {
  font-family: var(--font-mono); font-size: .65rem; border: 1px solid var(--line);
  padding: 0 .25rem; color: var(--ink-4);
}

.navtoggle { display: none; }

/* Ticker under the masthead — the "what's live" strip */
.ticker {
  display: var(--chrome-ticker);
  border-bottom: 1px solid var(--line);
  background: var(--paper-sunk);
  overflow: hidden;
}
.ticker__inner {
  display: flex; align-items: center; gap: var(--s5);
  height: 2rem; white-space: nowrap;
}
.ticker__label { color: var(--accent); flex: none; }
.ticker__track {
  display: flex; gap: var(--s6); overflow-x: auto; scrollbar-width: none;
  font-family: var(--font-mono); font-size: .72rem; color: var(--ink-3);
}
.ticker__track::-webkit-scrollbar { display: none; }
.ticker__track a { text-decoration: none; }
.ticker__track a:hover { color: var(--ink); }
.ticker__sep { color: var(--line-2); }

/* ------------------------------------------------------------------- badges */

.badge {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--font-mono); font-size: var(--t-micro);
  letter-spacing: .1em; text-transform: uppercase; font-weight: 600;
  color: var(--accent);
}
.badge__glyph { font-size: .85rem; line-height: 1; }
.badge--solid {
  border-radius: var(--r-pill);
  background: var(--accent); color: var(--paper);
  padding: .2rem .45rem .2rem .5rem;
  border-radius: var(--r-sm); clip-path: var(--clip-sm);
}

.chip {
  border-radius: var(--r-pill);
  display: inline-flex; align-items: center; gap: .3rem;
  font-family: var(--font-mono); font-size: .7rem; letter-spacing: .04em;
  border: 1px solid var(--line); padding: .15rem .45rem;
  color: var(--ink-3); text-decoration: none;
  transition: border-color .16s var(--ease), color .16s var(--ease), background .16s var(--ease);
}
.chip:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.chip::before { content: '#'; color: var(--ink-4); }
.chip--plain::before { content: none; }

.meta {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  font-family: var(--font-mono); font-size: .72rem; color: var(--ink-3);
  letter-spacing: .02em;
}
.meta > * { display: inline-flex; align-items: center; gap: .35rem; }
.meta__sep { color: var(--line-2); }

/* ------------------------------------------------------------------ buttons */

.btn {
  display: inline-flex; align-items: center; gap: var(--s2);
  padding: .6rem 1rem; text-decoration: none;
  font-family: var(--font-mono); font-size: .75rem; letter-spacing: .08em;
  text-transform: uppercase; font-weight: 600;
  border: 1px solid var(--line-hard); color: var(--ink);
  border-radius: var(--r-btn); clip-path: var(--clip-sm);
  transition: background .18s var(--ease), color .18s var(--ease), transform .18s var(--ease);
}
.btn:hover { background: var(--ink); color: var(--paper); transform: translateY(-2px); }
.btn--primary { background: var(--ink); color: var(--paper); }
.btn--primary:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn--ghost { border-color: var(--line); color: var(--ink-2); }
.btn--sm { padding: .4rem .7rem; font-size: .68rem; }

/* ---------------------------------------------------------------- home hero */

.hero { position: relative; padding-block: clamp(var(--s7), 9vw, var(--s10)) var(--s7); overflow: hidden; }
.hero::before {
  content: ''; display: var(--chrome-texture); position: absolute; inset: -10% -20% auto -20%; height: 70%;
  background-image:
    linear-gradient(to right, color-mix(in oklab, var(--line) 45%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in oklab, var(--line) 45%, transparent) 1px, transparent 1px);
  background-size: 34px 34px;
  mask-image: radial-gradient(120% 80% at 20% 0%, #000 10%, transparent 72%);
  pointer-events: none;
}
.hero__inner { position: relative; }

.hero__name {
  font-family: var(--font-display);
  font-size: var(--t-display);
  line-height: var(--lh-tight);
  letter-spacing: -.045em;
  font-weight: var(--display-weight-strong);
  font-variation-settings: 'SOFT' 8, 'WONK' 1, 'opsz' 144;
  margin: 0 0 var(--s5);
  max-width: 14ch;
}
.hero__name .glyph {
  color: var(--ember); display: inline-block;
  transition: transform .3s var(--ease);
}
.hero__name:hover .glyph { transform: rotate(14deg) scale(1.08); }

.hero__disciplines {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3);
  margin-bottom: var(--s6); color: var(--ink-2);
  font-family: var(--font-mono); font-size: .78rem; letter-spacing: .04em;
}
.hero__disciplines span:not(:last-child)::after {
  content: ' ·'; color: var(--line-2); margin-left: var(--s3);
}
.hero__disciplines em { font-style: normal; color: var(--accent); }

.hero__grid {
  display: grid; gap: var(--s7);
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  align-items: start;
}
.hero__intro { font-size: 1.15rem; line-height: 1.62; color: var(--ink-2); max-width: 46ch; }
.hero__intro strong { color: var(--ink); font-weight: 550; }
.hero__actions { display: flex; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s5); }

/* Status board — "currently" */
.board {
  border: 1px solid var(--line); background: var(--paper-2);
  border-radius: var(--r-lg); clip-path: var(--clip-lg);
  box-shadow: var(--shadow);
}
.board__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line); color: var(--ink-3);
}
.board__pulse {
  width: .5rem; height: .5rem; background: var(--moss); flex: none;
  animation: pulse 2.6s var(--ease) infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .28; } }
@media (prefers-reduced-motion: reduce) { .board__pulse { animation: none; } }

.board__row {
  display: grid; grid-template-columns: 6.25rem 1fr; gap: var(--s4);
  padding: var(--s3) var(--s4); align-items: baseline;
  border-bottom: 1px dashed var(--line); text-decoration: none;
  transition: background .16s var(--ease);
}
.board__row:last-child { border-bottom: 0; }
.board__row:hover { background: var(--accent-soft); }
.board__row dt { color: var(--accent); }
.board__row dd { margin: 0; font-size: .95rem; line-height: 1.45; color: var(--ink-2); }
.board__row:hover dd { color: var(--ink); }
.board__foot {
  padding: var(--s3) var(--s4); border-top: 1px solid var(--line);
  color: var(--ink-4); display: flex; justify-content: space-between; gap: var(--s3);
}

/* ------------------------------------------------------------------ stories */

.stories { position: relative; }
.stories__rail {
  display: flex; gap: var(--s4); overflow-x: auto; padding-block: var(--s2) var(--s5);
  scroll-snap-type: x mandatory; scrollbar-width: none;
  margin-inline: calc(var(--gutter) * -1); padding-inline: var(--gutter);
}
.stories__rail::-webkit-scrollbar { display: none; }

.story {
  flex: 0 0 clamp(13rem, 40vw, 15.5rem);
  scroll-snap-align: start;
  border: 1px solid var(--line); background: var(--paper-2);
  display: flex; flex-direction: column; text-align: left; padding: 0;
  border-radius: var(--r-md); clip-path: var(--clip-md); overflow: hidden;
  transition: transform .2s var(--ease), border-color .2s var(--ease);
}
.story:hover { transform: translateY(-4px); border-color: var(--accent); }
/* The same 4:3 the homepage rail uses. A fixed height forced a portrait
   photo and a wide video frame into the same letterbox strip, and made one
   story two different shapes depending on which page you found it on.
   The media also carries the card's corners, less the 1px border: square
   corners on a rounded card paint the image over the border, which is most
   visible on hover, when that border turns the accent colour. */
.story__art {
  aspect-ratio: 4 / 3; position: relative; overflow: hidden;
  border-bottom: 1px solid var(--line);
  border-radius: var(--r-media-top) var(--r-media-top) 0 0;
}
/* Topics that actually have depth: one row each, with what is in them. */
.topics { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.topic {
  display: grid; gap: .35rem; padding: var(--s4) 0; border-bottom: 1px solid var(--line);
  text-decoration: none; color: inherit;
  transition: background .2s var(--ease), padding-inline .2s var(--ease);
}
.topic:hover { background: var(--paper-2); padding-inline: var(--s3); }
.topic__head { display: flex; align-items: baseline; gap: var(--s3); flex-wrap: wrap; }
.topic__name {
  font-family: var(--font-display); font-weight: var(--display-weight-strong);
  font-size: 1.5rem; letter-spacing: -.02em; color: var(--ink);
}
.topic:hover .topic__name { color: var(--accent); }
.topic__count { font-size: .62rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-4); }
.topic__items { color: var(--ink-3); font-size: .9rem; line-height: 1.5; }

/* What the blog publishes, on the About page: one row per format. */
.writes { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.writes__row {
  display: grid; grid-template-columns: minmax(7rem, auto) minmax(0, 1fr) auto;
  gap: var(--s3); align-items: baseline; padding: var(--s4) 0;
  border-bottom: 1px solid var(--line); text-decoration: none; color: inherit;
  transition: background .2s var(--ease), padding-inline .2s var(--ease);
}
.writes__row:hover { background: var(--paper-2); padding-inline: var(--s3); }
.writes__title { font-family: var(--font-display); font-weight: var(--display-weight-strong); font-size: 1.05rem; color: var(--ink); }
.writes__note { color: var(--ink-3); font-size: .93rem; line-height: 1.5; }
.writes__go { color: var(--accent); display: inline-flex; opacity: 0; transition: opacity .2s var(--ease); }
.writes__row:hover .writes__go { opacity: 1; }
.writes__go svg { width: 1rem; height: 1rem; }
@media (max-width: 42rem) { .writes__row { grid-template-columns: minmax(0, 1fr) auto; } .writes__note { grid-column: 1 / -1; } }

.cover--image { padding: 0; overflow: hidden; }
.cover--image img { width: 100%; height: 100%; object-fit: cover; display: block; }
.story__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.reader__art--photo .story__kind { background: rgba(0, 0, 0, .45); color: #fff; }
.reader__art--photo .story__glyph { text-shadow: 0 2px 10px rgba(0, 0, 0, .5); }
.story__glyph {
  position: absolute; right: .6rem; bottom: .35rem;
  font-size: 2rem; color: var(--accent); opacity: .9; line-height: 1;
}
.story__kind {
  position: absolute; left: .6rem; top: .5rem;
  font-family: var(--font-mono); font-size: .6rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent);
  background: var(--paper-2); padding: .1rem .3rem;
}
.story__body { padding: var(--s3) var(--s4) var(--s4); display: flex; flex-direction: column; gap: var(--s2); flex: 1; }
.story__title { font-family: var(--font-display); font-size: 1rem; line-height: 1.28; font-weight: var(--display-weight-strong); }
.story__date { font-family: var(--font-mono); font-size: .65rem; color: var(--ink-4); letter-spacing: .06em; }
.story__more { margin-top: auto; font-family: var(--font-mono); font-size: .65rem; color: var(--ink-3); letter-spacing: .08em; text-transform: uppercase; }

/* Subscribe dialog: asks for the address where the reader is standing,
   rather than sending them to a form on another page. */
.subdlg {
  position: fixed; inset: 0; z-index: 75; display: grid; place-items: center;
  background: color-mix(in oklab, var(--paper-sunk) 82%, transparent);
  backdrop-filter: blur(6px); padding: var(--gutter);
  animation: subdlg-in .18s var(--ease);
}
@keyframes subdlg-in { from { opacity: 0 } to { opacity: 1 } }
.subdlg__card {
  position: relative; width: min(28rem, 100%);
  background: var(--paper-2); border: 1px solid var(--line-2);
  border-radius: var(--r-lg); clip-path: var(--clip-lg);
  padding: var(--s6) var(--s5) var(--s5);
  box-shadow: 0 40px 80px -40px rgba(0, 0, 0, .55);
}
.subdlg__x {
  position: absolute; top: .7rem; right: .7rem; width: 2rem; height: 2rem;
  display: grid; place-items: center; border-radius: 50%; color: var(--ink-3);
}
.subdlg__x:hover { background: var(--paper-3); color: var(--ink); }
.subdlg__x svg { width: 1rem; height: 1rem; }
.subdlg__eyebrow { font-size: .62rem; letter-spacing: .14em; text-transform: uppercase; color: var(--accent); margin: 0 0 .4rem; }
.subdlg__title { font-size: 1.5rem; letter-spacing: -.02em; margin: 0 0 var(--s3); }
.subdlg__note { color: var(--ink-2); font-size: .92rem; line-height: 1.6; margin: 0 0 var(--s4); }
.subdlg__form { display: flex; gap: var(--s2); flex-wrap: wrap; }
.subdlg__form input {
  flex: 1 1 12rem; min-width: 0; font: inherit; font-size: .95rem; padding: .6rem .9rem;
  background: var(--paper); border: 1px solid var(--line); color: var(--ink); border-radius: var(--r-input);
}
.subdlg__form input:focus-visible { outline: none; border-color: var(--accent); }
.subdlg__fine { margin: var(--s3) 0 0; font-size: .65rem; letter-spacing: .06em; color: var(--ink-4); }
/* 1rem is not cosmetic here: iOS Safari zooms the page when a field it is
   focusing is under 16px, and the reader has to pinch back out. */
@media (max-width: 30rem) {
  .subdlg__form button { width: 100% }
  .subdlg__form input { font-size: 1rem }
}

/* Story reader overlay */
.reader {
  position: fixed; inset: 0; z-index: 70; display: grid; place-items: center;
  background: color-mix(in oklab, var(--paper-sunk) 82%, transparent);
  backdrop-filter: blur(6px); padding: var(--gutter);
}
.reader__card {
  position: relative;
  width: min(30rem, 100%); max-height: 88vh; overflow: auto;
  background: var(--paper-2); border: 1px solid var(--line-2);
  border-radius: var(--r-lg); clip-path: var(--clip-lg);
  box-shadow: 0 40px 80px -40px rgba(0, 0, 0, .55);
}
.reader__bars { display: flex; gap: 3px; padding: var(--s3) var(--s4) 0; }
.reader__bar { height: 2px; flex: 1; background: var(--line); position: relative; overflow: hidden; border-radius: 2px; }
.reader__bar[data-on='1'] { background: var(--accent); }
/* The current story's bar fills as its time runs; the script sets --p. */
.reader__bar[data-current] i { position: absolute; inset: 0; width: calc(var(--p, 0) * 100%); background: var(--accent); }
.reader--paused .reader__bar[data-current] i { opacity: .6; }
.story__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* The same shape the card shows, rather than a fixed height. A story was
   4:3 in the rail and then opened as a 2.7:1 letterbox, which is a
   different crop of the same picture. */
.reader__art {
  aspect-ratio: 4 / 3; position: relative; overflow: hidden;
  margin: var(--s3) 0 0; border-block: 1px solid var(--line);
}
.reader__body { padding: var(--s5); display: flex; flex-direction: column; gap: var(--s3); }
.reader__nav { display: flex; justify-content: space-between; gap: var(--s3); padding: 0 var(--s5) var(--s5); }

/* -------------------------------------------------------------------- cards */

.card {
  display: flex; flex-direction: column; gap: var(--s3);
  text-decoration: none; position: relative; height: 100%;
  transition: transform .22s var(--ease);
}
.card:hover { transform: translateY(var(--lift)); }
.card__art {
  position: relative; overflow: hidden; border: 1px solid var(--line);
  background: var(--paper-3); aspect-ratio: 16 / 10;
  border-radius: var(--r-md); clip-path: var(--clip-md);
}
.card__art::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, color-mix(in oklab, var(--paper) 26%, transparent), transparent 55%);
  opacity: 0; transition: opacity .22s var(--ease);
}
.card:hover .card__art::after { opacity: 1; }
.card__title {
  font-family: var(--font-display); font-size: 1.2rem; line-height: 1.24;
  font-weight: var(--display-weight-strong); letter-spacing: -.012em;
}
.card:hover .card__title { text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: .16em; }
.card__dek { font-size: .92rem; line-height: 1.5; color: var(--ink-3); }
.card__foot { margin-top: auto; padding-top: var(--s2); }

/* Feature card — the lead slot */
.card--feature { grid-column: span 2; }
.card--feature .card__art { aspect-ratio: 16 / 8; }
.card--feature .card__title { font-size: clamp(1.6rem, 3.1vw, 2.4rem); }
.card--feature .card__dek { font-size: 1.02rem; max-width: 54ch; }

/* Horizontal card — listing default */
.card--row {
  display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: var(--s5);
  align-items: start; padding-block: var(--s5); border-bottom: 1px solid var(--line);
}
.card--row:hover { transform: none; }
.card--row .card__art { aspect-ratio: 4 / 3; }
.card--row .card__body { display: flex; flex-direction: column; gap: var(--s3); }
.card--row .card__title { font-size: 1.35rem; }

/* Small card — dense grids */
.card--small .card__art { aspect-ratio: 3 / 2; }
.card--small .card__title { font-size: 1.02rem; }
.card--small .card__dek { display: var(--chrome-dek-small); font-size: .86rem; }

/* Text-only card, no art — used for notes and quick items */
.card--bare {
  border-top: 2px solid var(--accent); padding-top: var(--s3);
}

.grid {
  display: grid; gap: var(--s6) var(--s5);
  grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
}
.grid--editorial {
  display: grid; gap: var(--s6) var(--s5);
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.grid--editorial > *:nth-child(1) { grid-column: span 2; grid-row: span 2; }
.grid--3 { grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr)); }

/* ------------------------------------------------------------------ explore */

.explore { display: grid; gap: 0; border-top: 2px solid var(--line-hard); }
.explore__item {
  display: grid; grid-template-columns: minmax(0, 8rem) minmax(0, 1fr) auto;
  gap: var(--s5); align-items: center; padding: var(--s5) var(--s2);
  border-bottom: 1px solid var(--line); text-decoration: none;
  transition: padding-left .22s var(--ease), background .22s var(--ease);
}
.explore__item:hover { padding-left: var(--s5); background: var(--accent-soft); }
.explore__verb {
  font-family: var(--font-display); font-size: clamp(1.5rem, 3.4vw, 2.5rem);
  font-weight: var(--display-weight-strong); letter-spacing: -.02em; color: var(--accent);
  font-variation-settings: 'SOFT' 0, 'WONK' 1, 'opsz' 60;
}
.explore__title { font-size: 1.05rem; font-weight: 550; }
.explore__note { display: var(--chrome-explore-note); color: var(--ink-3); font-size: .92rem; }
.explore__arrow { font-family: var(--font-mono); color: var(--ink-4); transition: transform .22s var(--ease), color .22s var(--ease); }
.explore__item:hover .explore__arrow { transform: translateX(6px); color: var(--accent); }

/* ------------------------------------------------------------ page headers */

.pagehead { padding-block: var(--s8) var(--s6); border-bottom: 1px solid var(--line); }
.pagehead h1 { font-size: var(--t-h1); letter-spacing: -.03em; max-width: 18ch; }
.pagehead .dek { margin-top: var(--s4); max-width: 58ch; font-size: 1.1rem; }
.pagehead__stats { display: flex; gap: var(--s5); flex-wrap: wrap; margin-top: var(--s5); }
.pagehead__stat { display: flex; flex-direction: column; gap: .1rem; }
.pagehead__stat b { font-family: var(--font-display); font-size: 1.6rem; font-weight: var(--display-weight-strong); }

.crumbs { display: flex; gap: var(--s2); align-items: center; margin-bottom: var(--s4); color: var(--ink-4); }
.crumbs a { text-decoration: none; }
.crumbs a:hover { color: var(--accent); }

.filterbar {
  display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center;
  padding-block: var(--s4); border-bottom: 1px solid var(--line);
  position: sticky; top: 3.75rem; background: var(--paper); z-index: 20;
}
.filterbar__spacer { flex: 1; }
.pill {
  border-radius: var(--r-pill);
  font-family: var(--font-mono); font-size: .7rem; letter-spacing: .06em;
  text-transform: uppercase; padding: .3rem .6rem; border: 1px solid var(--line);
  color: var(--ink-3); transition: all .16s var(--ease);
}
.pill:hover { border-color: var(--line-hard); color: var(--ink); }
.pill[aria-pressed='true'] { background: var(--ink); border-color: var(--ink); color: var(--paper); }

/* ------------------------------------------------------ article & tutorial */

.reading-progress {
  position: fixed; top: 0; left: 0; height: 2px; z-index: 60;
  background: var(--accent); width: 0; transition: width .08s linear;
}
.reading-pct {
  position: fixed; right: var(--gutter); bottom: var(--s5); z-index: 55;
  font-family: var(--font-mono); font-size: .65rem; letter-spacing: .1em;
  color: var(--ink-4); background: var(--paper);
  border: 1px solid var(--line); padding: .2rem .45rem;
  opacity: 0; transition: opacity .25s var(--ease);
}
.reading-pct[data-on='1'] { opacity: 1; }

.entryhead { padding-block: var(--s7) var(--s6); }
.entryhead__title {
  font-size: clamp(2.2rem, 5.6vw, 4.1rem); letter-spacing: -.035em;
  line-height: 1.03; font-variation-settings: 'SOFT' 6, 'WONK' 1, 'opsz' 90;
  max-width: 20ch;
}
.entryhead__dek {
  font-size: clamp(1.1rem, 1.7vw, 1.35rem); line-height: 1.5; color: var(--ink-2);
  max-width: 54ch; margin-top: var(--s5); font-family: var(--font-display);
  font-variation-settings: 'SOFT' 40, 'WONK' 0, 'opsz' 20; font-weight: 300;
}
.entryhead__meta {
  display: flex; gap: var(--s5); flex-wrap: wrap; align-items: center;
  margin-top: var(--s6); padding-top: var(--s4); border-top: 1px solid var(--line);
}
.byline { display: flex; align-items: center; gap: var(--s3); }
.byline__face {
  width: 2.2rem; height: 2.2rem; flex: none; border: 1px solid var(--line);
  border-radius: var(--r-sm); clip-path: var(--clip-sm);
}
.byline__who { display: flex; flex-direction: column; line-height: 1.25; }
.byline__name { font-size: .9rem; font-weight: 550; }

.entry-layout {
  display: grid; gap: var(--s7);
  grid-template-columns: minmax(0, 1fr);
  align-items: start; padding-bottom: var(--s8);
}
@media (min-width: 62rem) {
  .entry-layout { grid-template-columns: 14rem minmax(0, 1fr); }
  .entry-layout--wide { grid-template-columns: 15rem minmax(0, 1fr); }
}

.toc { position: sticky; top: 5.5rem; align-self: start; max-height: calc(100vh - 8rem); overflow-y: auto; }
.toc__title { color: var(--ink-3); margin-bottom: var(--s3); padding-bottom: var(--s2); border-bottom: 1px solid var(--line); }
.toc ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.toc a {
  display: flex; gap: var(--s3); padding: .3rem 0 .3rem var(--s3);
  text-decoration: none; font-size: .84rem; line-height: 1.35;
  color: var(--ink-3); border-left: 2px solid var(--line);
  transition: color .16s var(--ease), border-color .16s var(--ease);
}
.toc a:hover { color: var(--ink); border-color: var(--line-2); }
.toc a[data-active='1'] { color: var(--ink); border-color: var(--accent); }
.toc li[data-level='3'] a { padding-left: var(--s5); font-size: .8rem; }
.toc__n { font-family: var(--font-mono); font-size: .65rem; color: var(--accent); flex: none; padding-top: .15rem; }
@media (max-width: 61.99rem) {
  .toc {
    position: static; max-height: none; border: 1px solid var(--line);
    padding: var(--s4); background: var(--paper-2);
  }
  .toc__title { border: 0; }
}

/* Prose ------------------------------------------------------------------- */

.prose { max-width: var(--measure); font-size: var(--t-read); }
.prose > * + * { margin-top: 1.15em; }
.prose h2 {
  font-size: var(--t-h2); margin-top: 2.2em; margin-bottom: .55em;
  letter-spacing: -.022em; scroll-margin-top: 6rem;
}
.prose h2::before {
  content: ''; display: block; width: 2.5rem; height: 2px;
  background: var(--accent); margin-bottom: var(--s4);
}
.prose h3 { font-size: var(--t-h3); margin-top: 1.9em; margin-bottom: .4em; scroll-margin-top: 6rem; }
.prose p { line-height: var(--lh-body); text-wrap: pretty; }
.prose strong { font-weight: 600; color: var(--ink); }
.prose em { font-style: italic; }
.prose a {
  text-decoration: underline; text-decoration-thickness: 1px;
  text-decoration-color: var(--accent-line); text-underline-offset: .2em;
}
.prose a:hover { color: var(--accent); text-decoration-color: var(--accent); }
.prose ul, .prose ol { padding-left: 1.3em; }
.prose li + li { margin-top: .45em; }
.prose li::marker { color: var(--accent); font-family: var(--font-mono); font-size: .85em; }
.prose code {
  border-radius: var(--r-sm);
  font-family: var(--font-mono); font-size: .86em;
  background: var(--paper-3); padding: .1em .32em; color: var(--ink);
  border: 1px solid var(--line);
}

/* Pull quote / blockquote */
.prose blockquote {
  margin: 2em 0; padding-left: var(--s5); border-left: 2px solid var(--accent);
  font-family: var(--font-display); font-size: 1.28em; line-height: 1.42;
  font-variation-settings: 'SOFT' 40, 'WONK' 1, 'opsz' 30; font-weight: 400;
  color: var(--ink); text-wrap: pretty;
}
.prose blockquote p:last-child { margin-bottom: 0; }

/* Callouts */
/* The accent tints the whole block rather than a 3px edge on one side. A
   warning that differs from a tip by three pixels is not a warning, and the
   left-border card has become the house style of generated UI, which is a
   poor thing for a site to look like. color-mix keeps it honest: one accent
   per kind, mixed into the page's own paper, so nothing here is a pastel
   borrowed from another palette.

   The flat background is declared first as the fallback for anything that
   cannot do color-mix; such a browser gets the old surface and loses only
   the tint. */
.callout {
  border-radius: var(--r-md);
  margin: 1.8em 0;
  padding: var(--s5);
  font-size: .96em;
  background: var(--paper-2);
  border: 1px solid var(--line);
  background: color-mix(in oklab, var(--accent) 6%, var(--paper-2));
  border: 1px solid color-mix(in oklab, var(--accent) 22%, var(--line));
}
.callout__head {
  display: flex; align-items: center; gap: var(--s3);
  color: var(--accent); margin-bottom: var(--s3);
}
/* The glyph gets a tile to sit in. A bare icon beside a line of small caps
   has nothing to hold it; this gives the eye somewhere to land and carries
   the kind's colour at a size you can actually see. */
.callout__chip {
  flex: none; width: 30px; height: 30px; border-radius: 8px;
  display: grid; place-items: center;
  background: color-mix(in oklab, var(--accent) 16%, transparent);
}
.callout p:last-child { margin-bottom: 0; }
.callout ul, .callout ol { margin: .6em 0 0; }

/* An author pulling an exception out into a blockquote gets an inset card
   for it, which is the one piece of structure these blocks were missing.
   It costs no new syntax: the callout body is fully rendered markdown, so
   this already worked and merely looked like nothing. */
.callout blockquote {
  margin: var(--s4) 0 0; padding: var(--s3) var(--s4);
  border: 0; border-left: 2px solid color-mix(in oklab, var(--accent) 45%, transparent);
  border-radius: 0 6px 6px 0;
  background: color-mix(in oklab, var(--accent) 5%, transparent);
  font-size: .95em; font-style: normal; color: var(--ink-2);
}
.callout blockquote p:last-child { margin-bottom: 0; }
.callout blockquote strong:first-child { color: var(--accent); }
.callout[data-kind='note'] { --accent: var(--tide); }
.callout[data-kind='tip']  { --accent: var(--moss); }
.callout[data-kind='warn'] { --accent: var(--ember); }

/* Figures — procedurally generated, no stock photography anywhere */
.figure { margin: 2.2em 0; }
.figure__frame {
  border: 1px solid var(--line); background: var(--paper-3); overflow: hidden;
  border-radius: var(--r-md); clip-path: var(--clip-md);
}
/* A photograph keeps its own proportions; only generated art is 16:9. */
/* A photograph keeps its proportions but not the whole screen, and the
   frame hugs it rather than letterboxing a portrait into a wide box. */
.figure--photo .figure__frame { display: block; width: fit-content; max-width: 100%; margin-inline: auto; }
.figure--photo .figure__frame img { display: block; width: auto; max-width: 100%; max-height: 34rem; }
/* A clip is framed like a photograph, held to a height a reader can see all
   of at once, but the frame keeps the full measure instead of hugging it.
   Hugging costs nothing for a photograph, whose width is known from the
   markup. A video only reports its width once the metadata has arrived, so
   a fit-content frame and an auto-width video each wait on the other, and on
   a connection slow enough for first layout to happen first, the pair
   settles at zero and stays there. A full-width ground needs no answer. */
.figure--clip .figure__frame { width: auto; max-width: 100%; background: #000; }
.figure--clip .figure__frame video {
  display: block; margin-inline: auto;
  width: auto; max-width: 100%; max-height: 34rem;
}
.figures .figure--photo .figure__frame img { max-height: 26rem; }
.figures { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); margin: 2.2em 0; align-items: start; }
.figures .figure { margin: 0; }
@media (max-width: 40rem) { .figures { grid-template-columns: 1fr; } }
/* Map figure: an OpenStreetMap frame, with the address readable as text
   underneath so the block still says something if the frame never loads. */
.mapfig { margin: 2.2em 0; }
.mapfig__frame {
  border: 1px solid var(--line); background: var(--paper-3); overflow: hidden;
  border-radius: var(--r-md); clip-path: var(--clip-md); aspect-ratio: 16 / 9;
}
.mapfig__frame iframe { width: 100%; height: 100%; border: 0; display: block; }
.mapfig figcaption {
  margin-top: var(--s3); font-family: var(--font-mono); font-size: .72rem;
  color: var(--ink-3); display: flex; gap: var(--s3); flex-wrap: wrap; align-items: baseline; line-height: 1.5;
}
.mapfig figcaption::before { content: 'MAP'; color: var(--accent); flex: none; }
.mapfig__attr { color: var(--ink-4); }
@media (max-width: 40rem) { .mapfig__frame { aspect-ratio: 4 / 3; } }

.figure figcaption {
  margin-top: var(--s3); font-family: var(--font-mono); font-size: .72rem;
  color: var(--ink-3); display: flex; gap: var(--s3); line-height: 1.5;
}
.figure figcaption::before { content: 'FIG'; color: var(--accent); flex: none; }
@media (min-width: 75rem) {
  .figure--wide { width: calc(100% + 8rem); }
}

/* Tables */
.prose .table-wrap { border-radius: var(--r-md);  overflow-x: auto; margin: 2em 0; border: 1px solid var(--line); }
.prose table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.prose th {
  text-align: left; font-family: var(--font-mono); font-size: .68rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3);
  padding: var(--s3) var(--s4); background: var(--paper-3);
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
.prose td { padding: var(--s3) var(--s4); border-bottom: 1px solid var(--line); vertical-align: top; }
.prose tr:last-child td { border-bottom: 0; }

/* Footnotes */
.fnref {
  font-family: var(--font-mono); font-size: .7em; vertical-align: super;
  color: var(--accent); text-decoration: none; padding: 0 .12em;
}
.footnotes { margin-top: var(--s8); padding-top: var(--s5); border-top: 1px solid var(--line); font-size: .9rem; color: var(--ink-3); }
.footnotes ol { padding-left: 1.2em; }

/* Code -------------------------------------------------------------------- */

.code { border-radius: var(--r-md); overflow: hidden; margin: 1.8em 0; border: 1px solid var(--line); background: var(--paper-sunk); }
.code__head {
  display: flex; align-items: center; gap: var(--s3);
  padding: .4rem var(--s4); border-bottom: 1px solid var(--line);
  background: var(--paper-3);
}
.code__lang { font-family: var(--font-mono); font-size: .65rem; letter-spacing: .12em; text-transform: uppercase; color: var(--accent); }
.code__file { font-family: var(--font-mono); font-size: .7rem; color: var(--ink-3); }
.code__copy {
  margin-left: auto; font-family: var(--font-mono); font-size: .65rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
  border: 1px solid var(--line); padding: .15rem .45rem;
  transition: all .16s var(--ease);
}
.code__copy:hover { border-color: var(--accent); color: var(--accent); }
.code__copy[data-done='1'] { border-color: var(--moss); color: var(--moss); }
.code pre {
  margin: 0; padding: var(--s4); overflow-x: auto;
  font-family: var(--font-mono); font-size: .82rem; line-height: 1.72;
  tab-size: 2;
}
.code code { background: none; border: 0; padding: 0; font-size: inherit; }
.code .ln {
  display: inline-block; width: 2.2em; margin-right: .6em; text-align: right;
  color: var(--ink-4); user-select: none; opacity: .55;
}
/* Syntax — three tones, deliberately restrained */
.tok-c { color: var(--ink-4); font-style: italic; }
.tok-s { color: var(--moss); }
.tok-k { color: var(--plum); font-weight: 500; }
.tok-n { color: var(--ember); }
.tok-a { color: var(--tide); }

/* Terminal variant */
.code--term { background: var(--paper-sunk); }
.code--term .code__head::before { content: '●●●'; letter-spacing: .1em; color: var(--line-2); font-size: .6rem; }
.code--term pre .prompt { color: var(--accent); user-select: none; }

/* Tutorial specifics ------------------------------------------------------ */

.tutorbar {
  display: grid; gap: var(--s4) var(--s6); margin-top: var(--s6);
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  border: 1px solid var(--line); background: var(--paper-2); padding: var(--s5);
  border-radius: var(--r-lg); clip-path: var(--clip-lg);
}
.tutorbar__cell { display: flex; flex-direction: column; gap: .2rem; }
.tutorbar__cell dt { color: var(--ink-4); font-family: var(--font-mono); font-size: var(--t-micro); letter-spacing: .1em; text-transform: uppercase; }
.tutorbar__cell dd { margin: 0; font-weight: 550; font-size: .98rem; }
.difficulty { display: inline-flex; gap: 3px; align-items: center; }
.difficulty i { width: 14px; height: 4px; background: var(--line-2); display: block; }
.difficulty i[data-on='1'] { background: var(--accent); }

.panels { display: grid; gap: var(--s5); grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr)); margin: var(--s6) 0; }
.panel { border-top: 2px solid var(--accent); padding-top: var(--s3); }
.panel h3 { font-size: 1.05rem; margin-bottom: var(--s3); }
.panel ul { margin: 0; padding-left: 1.1em; font-size: .94rem; color: var(--ink-2); }
.panel li + li { margin-top: .4em; }
.panel li::marker { color: var(--accent); }

.step { margin: var(--s7) 0; scroll-margin-top: 6rem; }
.step__head { display: flex; gap: var(--s4); align-items: baseline; margin-bottom: var(--s4); }
.step__n {
  font-family: var(--font-mono); font-size: .7rem; letter-spacing: .1em;
  color: var(--paper); background: var(--accent); padding: .25rem .5rem;
  flex: none; align-self: flex-start; margin-top: .3rem;
  border-radius: var(--r-sm); clip-path: var(--clip-sm);
}
.step__title { font-size: var(--t-h3); letter-spacing: -.015em; }
.step__body { padding-left: 0; border-left: 1px solid var(--line); padding-left: var(--s5); margin-left: .35rem; }
@media (max-width: 40rem) { .step__body { padding-left: var(--s4); } }

/* Entry footer ------------------------------------------------------------ */

.entryfoot { margin-top: var(--s8); padding-top: var(--s5); border-top: 2px solid var(--line-hard); }
.related { display: grid; gap: var(--s5); grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr)); margin-top: var(--s5); }
.related__item {
  display: flex; flex-direction: column; gap: var(--s2); text-decoration: none;
  border-top: 1px solid var(--line); padding-top: var(--s3);
  transition: border-color .18s var(--ease);
}
.related__item:hover { border-color: var(--accent); }
.related__title { font-family: var(--font-display); font-size: 1rem; line-height: 1.25; font-weight: var(--display-weight-strong); }
.related__why { font-family: var(--font-mono); font-size: .65rem; color: var(--ink-4); letter-spacing: .04em; }

/* ---------------------------------------------------------------- bookshelf */

.shelf {
  display: flex; align-items: flex-end; gap: 3px; flex-wrap: wrap;
  padding: var(--s6) var(--s4) 0; border-bottom: 6px solid var(--ink);
  background: linear-gradient(to bottom, transparent 70%, color-mix(in oklab, var(--ink) 6%, transparent));
}
.spine {
  --h: 12rem;
  width: clamp(2.1rem, 3.4vw, 2.9rem); height: var(--h);
  background: var(--accent); color: var(--paper);
  display: flex; align-items: flex-end; justify-content: center;
  padding: var(--s3) .2rem; position: relative;
  transition: transform .2s var(--ease), filter .2s var(--ease);
  border: 1px solid color-mix(in oklab, var(--ink) 30%, var(--accent));
  text-decoration: none;
}
.spine:hover { transform: translateY(-14px); filter: saturate(1.25); z-index: 2; }
.spine__text {
  writing-mode: vertical-rl; transform: rotate(180deg);
  font-family: var(--font-display); font-size: .78rem; font-weight: var(--display-weight-strong);
  line-height: 1.1; letter-spacing: .01em; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-height: calc(var(--h) - 2.6rem);
  color: #fff;
}
.spine::after {
  content: ''; position: absolute; inset: .35rem .28rem auto; height: 2px;
  background: color-mix(in oklab, #fff 55%, transparent);
}
.spine[data-status='reading']::before {
  content: ''; position: absolute; left: 0; right: 0; bottom: -6px; height: 6px;
  background: var(--accent);
}

.bookrow {
  display: grid; grid-template-columns: 5.5rem minmax(0, 1fr) auto; gap: var(--s5);
  align-items: start; padding-block: var(--s5); border-bottom: 1px solid var(--line);
  text-decoration: none;
}
.bookrow:hover .bookrow__title { text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: .15em; }
.cover {
  aspect-ratio: 2 / 3; position: relative; overflow: hidden;
  border: 1px solid var(--line); background: var(--accent);
  display: flex; flex-direction: column; justify-content: space-between;
  padding: .5rem .45rem; color: #fff;
  border-radius: var(--r-sm); clip-path: var(--clip-sm);
}
.cover__title { font-family: var(--font-display); font-size: .62rem; line-height: 1.15; font-weight: var(--display-weight-strong); }
.cover__author { font-family: var(--font-mono); font-size: .48rem; letter-spacing: .04em; opacity: .85; }
.cover__rule { height: 1px; background: rgba(255, 255, 255, .5); }
.bookrow__title { font-family: var(--font-display); font-size: 1.2rem; font-weight: var(--display-weight-strong); line-height: 1.2; }
.bookrow__author { color: var(--ink-3); font-size: .9rem; }
.bookrow__note { color: var(--ink-2); font-size: .95rem; line-height: 1.55; margin-top: var(--s3); max-width: 62ch; }
.bookrow__side { text-align: right; display: flex; flex-direction: column; gap: var(--s2); align-items: flex-end; }

.stars { display: inline-flex; gap: 2px; color: var(--sun); font-size: .8rem; letter-spacing: .1em; }
.stars i { font-style: normal; color: var(--line-2); }
.stars i[data-on='1'] { color: var(--sun); }

.progressbar { width: 5rem; height: 3px; background: var(--line); position: relative; }
.progressbar span { position: absolute; inset: 0 auto 0 0; background: var(--accent); }

.status {
  border-radius: var(--r-pill);
  font-family: var(--font-mono); font-size: .62rem; letter-spacing: .1em;
  text-transform: uppercase; padding: .12rem .4rem; border: 1px solid currentColor;
}
.status[data-s='reading'] { color: var(--moss); }
.status[data-s='read']    { color: var(--ink-3); }
.status[data-s='want']    { color: var(--tide); }
.status[data-s='shelved'] { color: var(--ink-4); }

/* -------------------------------------------------------------------- CV */

.cvgrid { display: grid; gap: var(--s7); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 60rem) { .cvgrid { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: var(--s8); } }

.timeline { position: relative; padding-left: var(--s6); }
.timeline::before {
  content: ''; position: absolute; left: .3rem; top: .5rem; bottom: .5rem;
  width: 1px; background: var(--line);
}
.job { position: relative; padding-bottom: var(--s7); }
.job::before {
  content: ''; position: absolute; left: calc(var(--s6) * -1 + .05rem); top: .55rem;
  width: .55rem; height: .55rem; background: var(--paper); border: 2px solid var(--accent);
}
.job__when { font-family: var(--font-mono); font-size: .7rem; letter-spacing: .08em; color: var(--accent); }
/* The employer leads; the job title sits under it, quieter. */
.job__org { font-size: 1.35rem; margin-top: .2rem; letter-spacing: -.015em; font-weight: var(--display-weight-strong); }
.job__role { color: var(--ink-2); font-size: .98rem; }
.job__summary { color: var(--ink-2); font-size: .98rem; margin-top: var(--s3); }
.job__kind { color: var(--ink-4); font-size: .85rem; }
.job__points { margin: var(--s4) 0 var(--s4); padding-left: 1.1em; color: var(--ink-2); font-size: .96rem; }
.job__points li + li { margin-top: .5em; }
.job__points li::marker { color: var(--accent); }
.tagrow { display: flex; gap: var(--s2); flex-wrap: wrap; }

.skillgroup + .skillgroup { margin-top: var(--s6); }
.skill { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s3); align-items: center; padding-block: .4rem; border-bottom: 1px dashed var(--line); }
.skill__name { font-size: .94rem; }
.skill__years { font-family: var(--font-mono); font-size: .65rem; color: var(--ink-4); }
.skill__bars { display: inline-flex; gap: 3px; }
.skill__bars i { width: 12px; height: 10px; background: var(--line); display: block; }
.skill__bars i[data-on='1'] { background: var(--accent); }

.factlist { display: flex; flex-direction: column; }
.fact { display: grid; grid-template-columns: 7rem minmax(0, 1fr); gap: var(--s4); padding-block: var(--s3); border-bottom: 1px solid var(--line); align-items: baseline; }
.fact dt { color: var(--ink-4); }
.fact dd { margin: 0; font-size: .95rem; }

/* --------------------------------------------------------------- courses */

.course {
  border: 1px solid var(--line); background: var(--paper-2);
  border-radius: var(--r-lg); clip-path: var(--clip-lg);
  display: flex; flex-direction: column;
}
.course__top { padding: var(--s5); border-bottom: 1px solid var(--line); position: relative; overflow: hidden; }
.course__title { font-size: clamp(1.4rem, 2.6vw, 1.9rem); letter-spacing: -.02em; margin-top: var(--s3); }
.course__sub { color: var(--ink-3); font-size: .98rem; margin-top: var(--s2); }
.course__body { padding: var(--s5); display: flex; flex-direction: column; gap: var(--s4); flex: 1; }
.module {
  display: grid; grid-template-columns: 2rem minmax(0, 1fr) auto; gap: var(--s3);
  padding: var(--s3) 0; border-bottom: 1px dashed var(--line); align-items: baseline;
}
.module__n { font-family: var(--font-mono); font-size: .7rem; color: var(--accent); }
.module__t { font-size: .96rem; font-weight: 500; }
.module__note { color: var(--ink-3); font-size: .85rem; }
.module__free { border-radius: var(--r-pill); font-family: var(--font-mono); font-size: .6rem; letter-spacing: .1em; text-transform: uppercase; color: var(--moss); border: 1px solid var(--moss); padding: .05rem .3rem; }
.module__lock { color: var(--ink-4); font-size: .75rem; }

/* ------------------------------------------------------------------ outside */

.gallery { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr)); }
.plate { position: relative; border: 1px solid var(--line); overflow: hidden; aspect-ratio: 4 / 5; }
.plate--wide { aspect-ratio: 3 / 2; grid-column: span 2; }
.plate__cap {
  position: absolute; left: 0; right: 0; bottom: 0; padding: var(--s3);
  background: linear-gradient(to top, color-mix(in oklab, var(--paper) 92%, transparent), transparent);
  font-family: var(--font-mono); font-size: .65rem; color: var(--ink-2); letter-spacing: .04em;
}

.tripstats { display: flex; gap: var(--s6); flex-wrap: wrap; margin-top: var(--s5); }
.tripstat b { display: block; font-family: var(--font-display); font-size: 1.7rem; font-weight: var(--display-weight-strong); letter-spacing: -.02em; }

/* ------------------------------------------------------------------ support */

.supportgrid { display: grid; gap: var(--s5); grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr)); }
.supportcard { border: 1px solid var(--line); padding: var(--s5); background: var(--paper-2); display: flex; flex-direction: column; gap: var(--s3); }
.disclosure {
  border-left: 3px solid var(--sun); background: var(--paper-2);
  padding: var(--s4) var(--s5); font-size: .9rem; color: var(--ink-2); margin-top: var(--s5);
}
.toolrow { display: grid; grid-template-columns: 8rem minmax(0, 1fr) auto; gap: var(--s4); padding-block: var(--s3); border-bottom: 1px solid var(--line); align-items: baseline; }
.toolrow__name { font-weight: 550; }
.toolrow__what { color: var(--ink-3); font-size: .92rem; }

/* --------------------------------------------------------------- newsletter */

.newsletter {
  border: 2px solid var(--line-hard); padding: var(--s6);
  display: grid; gap: var(--s5); grid-template-columns: minmax(0, 1fr);
  background: var(--paper-2); position: relative; overflow: hidden;
}
@media (min-width: 48rem) { .newsletter { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); align-items: center; gap: var(--s7); } }
.newsletter h2 { font-size: var(--t-h2); }
.subscribe { display: flex; gap: var(--s2); flex-wrap: wrap; }
.subscribe input {
  border-radius: var(--r-input);
  flex: 1 1 12rem; padding: .65rem var(--s3); font: inherit; font-size: .95rem;
  background: var(--paper); border: 1px solid var(--line-2); color: var(--ink);
}
.subscribe input:focus-visible { border-color: var(--accent); outline: none; }

/* ------------------------------------------------------------------- search */

.palette {
  position: fixed; inset: 0; z-index: 80; display: grid;
  grid-template-rows: 12vh auto; justify-items: center;
  background: color-mix(in oklab, var(--paper-sunk) 78%, transparent);
  backdrop-filter: blur(8px); padding: 0 var(--gutter);
}
.palette__box {
  width: min(42rem, 100%); background: var(--paper-2);
  border: 1px solid var(--line-2); box-shadow: 0 40px 90px -50px rgba(0, 0, 0, .6);
  border-radius: var(--r-lg); clip-path: var(--clip-lg);
  display: flex; flex-direction: column; max-height: 70vh;
}
.palette__field { display: flex; align-items: center; gap: var(--s3); padding: var(--s4) var(--s5); border-bottom: 1px solid var(--line); }
.palette__field span { color: var(--accent); font-family: var(--font-mono); }
.palette__field input { flex: 1; font: inherit; font-size: 1.05rem; background: none; border: 0; color: var(--ink); outline: none; }
.palette__results { overflow-y: auto; padding: var(--s2) 0; }
.palette__group { padding: var(--s3) var(--s5) var(--s2); color: var(--ink-4); }
.palette__item {
  display: grid; grid-template-columns: 4.5rem minmax(0, 1fr) auto; gap: var(--s4);
  padding: var(--s3) var(--s5); text-decoration: none; align-items: baseline;
  border-left: 2px solid transparent;
}
.palette__item[data-active='1'] { background: var(--accent-soft); border-left-color: var(--accent); }
.palette__item b { font-weight: 550; font-size: .96rem; }
.palette__item small { color: var(--ink-4); font-family: var(--font-mono); font-size: .65rem; }
.palette__foot {
  border-top: 1px solid var(--line); padding: var(--s3) var(--s5);
  display: flex; gap: var(--s5); color: var(--ink-4); flex-wrap: wrap;
}
.palette__empty { padding: var(--s6) var(--s5); color: var(--ink-3); }

/* ------------------------------------------------------------------- footer */

.footer { border-top: 2px solid var(--line-hard); padding-block: var(--s7) var(--s6); margin-top: var(--s8); }
.footer__grid { display: grid; gap: var(--s6); grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr)); }
.footer h3 { font-family: var(--font-mono); font-size: var(--t-micro); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-4); font-weight: 500; margin-bottom: var(--s3); }
.footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .35rem; }
.footer a, .footer ul button { text-decoration: none; font-size: .92rem; color: var(--ink-2); padding: 0; text-align: left; }
.footer a:hover, .footer ul button:hover { color: var(--accent); }
/* Phones: the intro spans the width, the menus pair up instead of stacking. */
@media (max-width: 40rem) {
  .footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s6) var(--s5); }
  .footer__grid > :first-child { grid-column: 1 / -1; }
}
.colophon { margin-top: var(--s7); padding-top: var(--s4); border-top: 1px solid var(--line); display: grid; gap: var(--s4); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 52rem) { .colophon { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); } }
.colophon p { color: var(--ink-3); font-size: .86rem; line-height: 1.6; max-width: 62ch; }

/* -------------------------------------------------------------- responsive */

@media (max-width: 68rem) {
  .grid--editorial { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--editorial > *:nth-child(1) { grid-column: span 2; grid-row: auto; }
  .hero__grid { grid-template-columns: minmax(0, 1fr); gap: var(--s6); }
}

@media (max-width: 56rem) {
  .mainnav {
    position: fixed; inset: 3.75rem 0 auto; flex-direction: column; gap: 0;
    background: var(--paper); border-bottom: 1px solid var(--line);
    padding: var(--s3) var(--gutter) var(--s5);
    transform: translateY(-120%); transition: transform .26s var(--ease);
    box-shadow: 0 24px 40px -30px rgba(0, 0, 0, .5);
  }
  .mainnav[data-open='1'] { transform: translateY(0); }
  .mainnav a { padding: var(--s3) 0; font-size: 1.05rem; border-bottom: 1px dashed var(--line); }
  .mainnav a::after { display: none; }
  .navtoggle { display: grid; }
  .searchbtn span { display: none; }
  .explore__item { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--s2); }
  .explore__verb { grid-column: 1 / -1; }
  .card--row { grid-template-columns: 6.5rem minmax(0, 1fr); gap: var(--s4); }
  .bookrow { grid-template-columns: 4rem minmax(0, 1fr); }
  .bookrow__side { grid-column: 2; flex-direction: row; align-items: center; justify-content: flex-start; }
  .toolrow { grid-template-columns: minmax(0, 1fr); gap: var(--s1); }
  .plate--wide { grid-column: span 1; }
  .reading-pct { display: none; }
}

@media (max-width: 40rem) {
  :root { --measure: 100%; --notch: 10px; }
  .grid--editorial { grid-template-columns: minmax(0, 1fr); }
  .grid--editorial > *:nth-child(1) { grid-column: auto; }
  .card--feature { grid-column: auto; }
  .card--row { grid-template-columns: minmax(0, 1fr); }
  .card--row .card__art { aspect-ratio: 16 / 9; }
  .filterbar { overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; }
  .filterbar::-webkit-scrollbar { display: none; }
  .hero__name { font-size: clamp(2.9rem, 15vw, 4.5rem); }
  .stories__rail { padding-bottom: var(--s4); }
  .story { flex-basis: 74vw; }
  .fact { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .pagehead { padding-block: var(--s6) var(--s5); }
}

/* Print — the CV should print like a CV */
@media print {
  .masthead, .ticker, .footer, .reading-progress, .reading-pct, .stories, .btn { display: none !important; }
  body { background: #fff; color: #000; font-size: 10.5pt; }
  .job { page-break-inside: avoid; }
  a { text-decoration: none; }
}

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

/* Entrance — one small, cheap reveal, disabled for reduced motion */
[data-reveal] { opacity: 0; transform: translateY(10px); }
[data-reveal][data-shown='1'] { opacity: 1; transform: none; transition: opacity .5s var(--ease), transform .5s var(--ease); }
@media (prefers-reduced-motion: reduce) { [data-reveal] { opacity: 1; transform: none; } }

/* ------------------------------------------------------- appearance picker */

.skins { position: relative; }
.skins__panel {
  position: absolute; right: 0; top: calc(100% + .55rem); z-index: 50;
  width: min(20rem, calc(100vw - var(--gutter) * 2));
  background: var(--paper-2); border: 1px solid var(--line-2);
  box-shadow: 0 28px 60px -34px rgba(0, 0, 0, .55);
  border-radius: var(--r-md); clip-path: var(--clip-md);
  padding: var(--s4);
}
.skins__label { color: var(--ink-4); margin: 0 0 var(--s2); }
.skins__label + * { margin-bottom: var(--s4); }
.skins__modes { display: flex; gap: var(--s2); }
.skins__modes .pill { flex: 1; text-align: center; }
.skins__list { display: flex; flex-direction: column; }

.skin {
  display: grid; grid-template-columns: auto minmax(0, 1fr) 1rem;
  gap: var(--s3); align-items: center; text-align: left;
  padding: var(--s2) var(--s2); border: 1px solid transparent;
  transition: background .16s var(--ease), border-color .16s var(--ease);
}
.skin:hover { background: var(--paper-3); }
.skin[aria-pressed='true'] { border-color: var(--line-2); background: var(--paper-3); }
.skin__swatch { display: flex; border: 1px solid var(--line-2); }
.skin__swatch i { width: .78rem; height: 1.5rem; display: block; }
.skin__name { display: block; font-size: .9rem; font-weight: 550; line-height: 1.25; }
.skin__note { display: block; font-size: .76rem; color: var(--ink-3); line-height: 1.35; }
.skin__tick { color: var(--accent); }
.skins__foot { color: var(--ink-4); margin: var(--s3) 0 0; padding-top: var(--s3); border-top: 1px solid var(--line); }

/* The whole page shifts palette at once, so a short crossfade reads as
   intentional rather than as a flash. Structure never animates. */
body, .masthead, .ticker, .board, .card__art, .code, .callout, .story, .course {
  transition: background-color .22s var(--ease), border-color .22s var(--ease), color .22s var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  body, .masthead, .ticker, .board, .card__art, .code, .callout, .story, .course { transition: none; }
}

/* -------------------------------------------------------------------- icons */

.icon {
  flex: none; display: inline-block; vertical-align: -.14em;
  stroke-width: 1.6;
}
.badge { gap: .4rem; }
.badge__icon { width: 1.05em; height: 1.05em; vertical-align: -.2em; }
.badge--solid .badge__icon { stroke-width: 2; }
.meta .icon { display: var(--chrome-meta-icon); width: .95em; height: .95em; opacity: .8; margin-right: .1em; }
.chip .icon { width: .85em; height: .85em; opacity: .55; }
.chip::before { content: none; }
.seclink { display: inline-flex; align-items: center; gap: .4rem; text-decoration: none; }
.seclink .icon { transition: transform .2s var(--ease); }
.seclink:hover .icon { transform: translateX(4px); }
.btn .icon { width: 1.05em; height: 1.05em; }
.pill { display: inline-flex; align-items: center; gap: .35rem; }
.pill .icon { width: .9em; height: .9em; }
.eyebrow .tick .icon { display: var(--chrome-eyebrow-icon); width: 1.1em; height: 1.1em; vertical-align: -.22em; }
.callout__head .icon { width: 1.05em; height: 1.05em; }
.code__copy { display: inline-flex; align-items: center; gap: .3rem; }
.code__copy .icon { width: .95em; height: .95em; }
.stars i .icon { width: .95em; height: .95em; }
.stars i[data-on='1'] .icon { fill: currentColor; }
.explore__arrow .icon { display: block; }
.skin__tick .icon { width: 1rem; height: 1rem; }

/* --------------------------------------------------------- cover artwork */

.art__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card__art { background: var(--paper-3); }

.entryhead__plate {
  position: relative; overflow: hidden; margin-bottom: var(--s6);
  border: 1px solid var(--line); background: var(--paper-3);
  aspect-ratio: 21 / 9;
  border-radius: var(--r-lg); clip-path: var(--clip-lg);
}
@media (max-width: 40rem) { .entryhead__plate { aspect-ratio: 16 / 10; } }
.entryhead__plate .art__img { transition: transform 7s var(--ease); }
.entryhead:hover .entryhead__plate .art__img { transform: scale(1.03); }
@media (prefers-reduced-motion: reduce) { .entryhead__plate .art__img { transition: none; } }

.prose .figure__frame .art__img { aspect-ratio: 16 / 9; }

/* ---------------------------------------------------------- theme: Bloom */

/* Bloom is the one palette that changes weight as well as colour: heavier
   display type, filled category pills, deeper lifts, image-led cards. Every
   rule here is scoped to the skin, so no other palette is affected and the
   underlying components are untouched. */

:root[data-skin='bloom'] {
  --measure: 64ch;
  --t-read: clamp(1.1rem, .4vw + 1rem, 1.24rem);
}

:root[data-skin='bloom'] .hero__name { letter-spacing: -.055em; }
:root[data-skin='bloom'] .entryhead__title { letter-spacing: -.045em; line-height: .98; }
:root[data-skin='bloom'] .entryhead__dek { font-family: var(--font-ui); font-weight: 400; }

/* Type identity becomes a filled pill rather than a coloured label. */
:root[data-skin='bloom'] .card .badge,
:root[data-skin='bloom'] .related__item .badge {
  background: var(--accent); color: #fff;
  padding: .28rem .6rem .28rem .5rem; border-radius: var(--r-pill);
  align-self: flex-start; letter-spacing: .08em;
}
:root[data-skin='bloom'] .card .badge .icon { stroke-width: 2.1; }

/* Cards become objects: filled, lifted, image-led. */
:root[data-skin='bloom'] .card:not(.card--row):not(.card--bare) {
  background: var(--paper-2); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: var(--s3) var(--s3) var(--s5);
  box-shadow: var(--shadow);
}
:root[data-skin='bloom'] .card:not(.card--row):not(.card--bare) .card__body { padding-inline: var(--s3); }
:root[data-skin='bloom'] .card:not(.card--row):not(.card--bare):hover {
  transform: translateY(-6px);
  border-color: color-mix(in oklab, var(--accent) 45%, var(--line));
}
:root[data-skin='bloom'] .card__art { border: 0; }
:root[data-skin='bloom'] .card--row .card__art { border-radius: var(--r-md); }

:root[data-skin='bloom'] .board,
:root[data-skin='bloom'] .course,
:root[data-skin='bloom'] .newsletter,
:root[data-skin='bloom'] .supportcard,
:root[data-skin='bloom'] .tutorbar { box-shadow: var(--shadow); }

:root[data-skin='bloom'] .newsletter { border-width: 1px; border-color: var(--line); }

/* Explore rows read as big colour blocks. */
:root[data-skin='bloom'] .explore { border-top: 0; gap: var(--s2); }
:root[data-skin='bloom'] .explore__item {
  border-bottom: 0; border-radius: var(--r-lg);
  background: color-mix(in oklab, var(--accent) 8%, var(--paper-2));
  border: 1px solid color-mix(in oklab, var(--accent) 18%, var(--line));
  padding: var(--s5);
}
:root[data-skin='bloom'] .explore__item:hover {
  background: color-mix(in oklab, var(--accent) 16%, var(--paper-2));
  padding-left: var(--s5);
  transform: translateX(4px);
}

:root[data-skin='bloom'] .story { box-shadow: var(--shadow); }
:root[data-skin='bloom'] .story__art { border-bottom: 0; }
:root[data-skin='bloom'] .story__kind {
  background: var(--accent); color: #fff; border-radius: var(--r-pill); padding: .12rem .45rem;
}

:root[data-skin='bloom'] .prose h2::before { width: 3.2rem; height: 4px; border-radius: 2px; }
:root[data-skin='bloom'] .step__n { border-radius: var(--r-pill); padding: .3rem .7rem; }
:root[data-skin='bloom'] .spine { border-radius: 3px 8px 8px 3px; }
:root[data-skin='bloom'] .cover { border-radius: 3px 10px 10px 3px; }
:root[data-skin='bloom'] .brand__mark { border-radius: 50%; }
:root[data-skin='bloom'] .masthead { border-bottom: 0; box-shadow: 0 1px 0 var(--line); }

/* ---------------------------------------------------------- theme: Quiet */

/* Quiet is the default. Everything here removes weight rather than adding
   decoration: fewer rules, softer edges, no fills, more air. The rest of the
   calm comes from the density tokens in site.json, not from this block. */

:root[data-skin='quiet'] .masthead {
  border-bottom: 0;
  background: color-mix(in oklab, var(--paper) 82%, transparent);
}
:root[data-skin='quiet'] .masthead__bar { height: 4.25rem; }
:root[data-skin='quiet'] .mainnav a { color: var(--ink-3); }
:root[data-skin='quiet'] .mainnav a:hover,
:root[data-skin='quiet'] .mainnav a[aria-current='page'] { color: var(--ink); }
:root[data-skin='quiet'] .mainnav a::after { height: 1px; }

:root[data-skin='quiet'] .hero { padding-block: clamp(4rem, 10vw, 8.5rem) clamp(3rem, 6vw, 5rem); }
:root[data-skin='quiet'] .hero__name { letter-spacing: -.02em; }
:root[data-skin='quiet'] .hero__intro { font-size: 1.08rem; line-height: 1.72; color: var(--ink-2); }
:root[data-skin='quiet'] .eyebrow::after { background: transparent; }

/* The status board loses its frame and becomes a list. */
:root[data-skin='quiet'] .board { border: 0; background: none; box-shadow: none; }
:root[data-skin='quiet'] .board__head { border-bottom: 1px solid var(--line); padding-inline: 0; }
:root[data-skin='quiet'] .board__row { border-bottom: 0; padding-inline: 0; }
:root[data-skin='quiet'] .board__row:hover { background: none; }
:root[data-skin='quiet'] .board__row:hover dd { color: var(--accent); }
:root[data-skin='quiet'] .board__foot { border-top: 1px solid var(--line); padding-inline: 0; }

/* Type identity stays, at a whisper. */
:root[data-skin='quiet'] .badge { color: var(--ink-4); letter-spacing: .12em; }
:root[data-skin='quiet'] .badge__icon { color: var(--accent); }

:root[data-skin='quiet'] .card__art { border-color: transparent; }
:root[data-skin='quiet'] .card__dek { color: var(--ink-3); }
:root[data-skin='quiet'] .card--row { border-bottom: 1px solid var(--line); padding-block: var(--s6); }
:root[data-skin='quiet'] .section-head { margin-bottom: var(--s5); }
:root[data-skin='quiet'] .section-head h2 { font-size: clamp(1.35rem, 2.2vw, 1.7rem); }

:root[data-skin='quiet'] .story { border-color: var(--line); box-shadow: none; }
:root[data-skin='quiet'] .story__art { border-bottom: 0; }
:root[data-skin='quiet'] .story:hover { border-color: var(--line-2); }

/* Explore becomes a plain list of destinations. */
:root[data-skin='quiet'] .explore { border-top: 0; }
:root[data-skin='quiet'] .explore__item {
  border-bottom: 1px solid var(--line);
  grid-template-columns: minmax(0, 7rem) minmax(0, 1fr) auto;
  padding-block: var(--s5);
}
:root[data-skin='quiet'] .explore__item:hover { background: none; padding-left: var(--s3); }
:root[data-skin='quiet'] .explore__verb {
  font-size: clamp(1.05rem, 1.6vw, 1.3rem); color: var(--ink-4); letter-spacing: .04em;
}
:root[data-skin='quiet'] .explore__item:hover .explore__verb { color: var(--accent); }

:root[data-skin='quiet'] .prose h2::before { width: 1.6rem; height: 1px; opacity: .7; }
/* Quiet strips the container and keeps the chip, which is the one part that
   still reads as a kind without drawing a box. */
:root[data-skin='quiet'] .callout { background: none; border: 0; border-radius: 0; padding: 0; }
:root[data-skin='quiet'] .callout__chip { background: none; width: auto; height: auto; }
:root[data-skin='quiet'] .code { background: var(--paper-2); }
:root[data-skin='quiet'] .code__head { background: var(--paper-2); border-bottom: 1px solid var(--line); }
:root[data-skin='quiet'] .tutorbar { background: none; border: 0; border-block: 1px solid var(--line); border-radius: 0; padding-inline: 0; }
:root[data-skin='quiet'] .newsletter { border: 0; border-top: 1px solid var(--line); background: none; padding-inline: 0; }
:root[data-skin='quiet'] .entryfoot { border-top-width: 1px; }
:root[data-skin='quiet'] .filterbar { border-bottom: 1px solid var(--line); }
:root[data-skin='quiet'] .pagehead { border-bottom: 0; }
:root[data-skin='quiet'] .footer { border-top: 1px solid var(--line); }

/* =============================================================================
   Editorial layout  (used by the Inkwell theme)
   -----------------------------------------------------------------------------
   A second homepage composition rather than a restyle of the first: a split
   hero with floating cards, an illustrated about block, an asymmetric featured
   grid, a compact archive grid, a topic cloud and a dark newsletter band.
   Alternating tinted sections do the dividing, so there are no rules anywhere.
   ========================================================================== */

.section--tint { background: var(--paper-3); }

.ink-eyebrow {
  display: flex; align-items: center; gap: .55rem;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ember); margin: 0 0 var(--s3);
}
.ink-eyebrow::before { content: ''; width: 1.6rem; height: 2px; background: currentColor; flex: none; }

.ink-h2 {
  font-size: clamp(1.8rem, 3.4vw, 2.7rem); letter-spacing: -.02em;
  line-height: 1.14; margin: 0 0 var(--s4); max-width: 20ch;
}
.fl { font-style: italic; color: var(--ember); }
.ink-body { color: var(--ink-2); line-height: 1.75; max-width: 52ch; }

.ink-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--s5); flex-wrap: wrap; margin-bottom: var(--s6);
}
.ink-head .ink-h2 { margin-bottom: 0; }

/* ------------------------------------------------------------------- hero */

.ink-hero { padding-block: clamp(2.5rem, 6vw, 5rem) clamp(3rem, 7vw, 6rem); overflow: hidden; }
.ink-hero__grid {
  display: grid; gap: clamp(2rem, 5vw, 4.5rem); align-items: center;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
}
.ink-hero__title {
  font-size: var(--t-display); line-height: 1.06; letter-spacing: -.03em;
  margin: 0 0 var(--s5); max-width: 12ch;
}
.ink-hero__dek { color: var(--ink-2); font-size: 1.02rem; line-height: 1.7; max-width: 44ch; }
.ink-actions { display: flex; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s5); }
.ink-scroll { color: var(--ink-4); margin-top: var(--s7); font-size: .62rem; }
.ink-scroll::after { content: ''; display: inline-block; width: 2.5rem; height: 1px; background: currentColor; margin-left: .6rem; vertical-align: middle; }

.ink-hero__art { position: relative; }
.ink-hero__art > img {
  width: 100%; height: auto; border-radius: var(--r-lg);
  box-shadow: var(--shadow);
}
.ink-float {
  position: absolute; background: var(--paper-2); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--s3) var(--s4);
  box-shadow: 0 18px 36px -22px rgba(80, 50, 30, .35);
  display: flex; flex-direction: column; gap: .15rem; text-decoration: none;
  max-width: 15rem;
}
.ink-float__label { color: var(--ink-4); display: flex; align-items: center; gap: .35rem; font-size: .6rem; }
.ink-float__label .icon { color: var(--ember); }
.ink-float b { font-family: var(--font-display); font-size: 1.35rem; line-height: 1.15; }
.ink-float--post b { font-size: .92rem; font-family: var(--font-ui); font-weight: 600; }
.ink-float__meta { color: var(--ink-4); font-size: .58rem; margin-top: .15rem; }
.ink-float--stat { top: 8%; right: -4%; }
.ink-float--post { bottom: 6%; left: -6%; transition: transform .22s var(--ease); }
.ink-float--post:hover { transform: translateY(-4px); }

/* ------------------------------------------------------------------ about */

.ink-about__grid {
  display: grid; gap: clamp(2rem, 5vw, 4.5rem); align-items: center;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1fr);
}
.ink-about__art { position: relative; }
.ink-about__art > img {
  width: 100%; height: auto; border-radius: var(--r-lg);
  border: 1px solid var(--line);
}
.ink-badge {
  position: absolute; right: -.75rem; bottom: -.75rem;
  background: var(--ink); color: var(--paper);
  border-radius: var(--r-md); padding: var(--s3) var(--s4);
  display: flex; flex-direction: column; line-height: 1.1;
  font-family: var(--font-mono); font-size: .58rem; letter-spacing: .1em; text-transform: uppercase;
  max-width: 9rem;
}
.ink-badge b { font-family: var(--font-display); font-size: 1.5rem; letter-spacing: -.02em; text-transform: none; }

.ink-pills { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: var(--s5); }
.ink-pill {
  display: inline-flex; align-items: center; gap: .4rem;
  background: var(--paper-2); border: 1px solid var(--line);
  border-radius: 999px; padding: .35rem .8rem; font-size: .84rem;
  color: var(--ink-2); text-decoration: none;
  transition: border-color .18s var(--ease), color .18s var(--ease), transform .18s var(--ease);
}
.ink-pill .icon { width: .9em; height: .9em; color: var(--ember); }
.ink-pill--link:hover { border-color: var(--ember); color: var(--ink); transform: translateY(-2px); }
.ink-pill__n {
  font-family: var(--font-mono); font-size: .62rem; color: var(--ink-4);
  background: var(--paper-3); border-radius: 999px; padding: .05rem .4rem; margin-left: .1rem;
}
.ink-pills--topics { margin-top: var(--s5); gap: .6rem; }
.ink-pills--topics .ink-pill { padding: .5rem 1rem; font-size: .9rem; }

.ink-social { display: flex; gap: .5rem; margin-top: var(--s5); }
.ink-social__dot {
  width: 2.2rem; height: 2.2rem; border-radius: 50%;
  border: 1px solid var(--line); display: grid; place-items: center;
  color: var(--ink-3); background: var(--paper-2);
  transition: all .18s var(--ease);
}
.ink-social__dot:hover { border-color: var(--ember); color: var(--ember); transform: translateY(-2px); }
.ink-social__dot .icon { width: 1rem; height: 1rem; }

/* ------------------------------------------------------------------- cards */

.icard {
  display: flex; flex-direction: column; text-decoration: none;
  background: var(--paper-2); border: 1px solid var(--line);
  border-radius: var(--r-lg); overflow: hidden;
  transition: transform .24s var(--ease), box-shadow .24s var(--ease), border-color .24s var(--ease);
}
.icard:hover {
  transform: translateY(var(--lift));
  box-shadow: var(--shadow);
  border-color: color-mix(in oklab, var(--accent) 40%, var(--line));
}
.icard__art { display: block; overflow: hidden; background: var(--paper-3); }
.icard__art img, .icard__art svg { width: 100%; height: 100%; object-fit: cover; display: block; }
.icard__body { display: flex; flex-direction: column; gap: .55rem; padding: var(--s4) var(--s5) var(--s5); flex: 1; }
.icard__top { display: flex; align-items: center; gap: .6rem; }
.icard__cat {
  font-family: var(--font-mono); font-size: .6rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); background: color-mix(in oklab, var(--accent) 12%, var(--paper-2));
  border-radius: 999px; padding: .18rem .55rem;
}
.icard__date { font-family: var(--font-mono); font-size: .62rem; color: var(--ink-4); letter-spacing: .04em; }
.icard__title {
  font-family: var(--font-display); font-weight: var(--display-weight-strong);
  font-size: 1.12rem; line-height: 1.25; letter-spacing: -.012em; color: var(--ink);
}
.icard__dek { color: var(--ink-3); font-size: .9rem; line-height: 1.55; }
.icard__foot {
  margin-top: auto; padding-top: var(--s3); display: flex;
  align-items: center; justify-content: space-between; gap: var(--s3);
  border-top: 1px solid var(--line);
}
.icard__more {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .8rem; font-weight: 500; color: var(--ink-2);
}
.icard__more .icon { width: .9em; height: .9em; transition: transform .2s var(--ease); }
.icard:hover .icard__more { color: var(--accent); }
.icard:hover .icard__more .icon { transform: translateX(4px); }
.icard__by { display: inline-flex; align-items: center; gap: .4rem; font-size: .78rem; color: var(--ink-4); }
.icard__face { width: 1.5rem; height: 1.5rem; border-radius: 50%; overflow: hidden; display: block; flex: none; }
.icard__face svg { width: 100%; height: 100%; }
.icard__time { display: inline-flex; align-items: center; gap: .3rem; font-family: var(--font-mono); font-size: .62rem; color: var(--ink-4); }

.icard--lead .icard__art { aspect-ratio: 4 / 3; }
.icard--lead .icard__title { font-size: clamp(1.3rem, 2.1vw, 1.65rem); }
.icard--wide { flex-direction: column; }
.icard--wide .icard__art { aspect-ratio: 16 / 7; }
.icard--compact .icard__art { aspect-ratio: 16 / 10; }
.icard--compact .icard__body { padding: var(--s3) var(--s4) var(--s4); gap: .45rem; }
.icard--compact .icard__title { font-size: .98rem; }

.ink-feature-grid {
  display: grid; gap: var(--s5);
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  grid-template-rows: auto auto;
}
.ink-feature-grid > :first-child { grid-row: span 2; }
.ink-archive-grid {
  display: grid; gap: var(--s5);
  grid-template-columns: repeat(auto-fill, minmax(min(16rem, 100%), 1fr));
}

/* -------------------------------------------------------------- newsletter */

.ink-news {
  background: var(--ink); color: var(--paper);
  padding-block: clamp(3.5rem, 7vw, 6rem);
}
.ink-news .ink-eyebrow { color: var(--ember); justify-content: center; }
.ink-news__title {
  font-family: var(--font-display); font-weight: var(--display-weight-strong);
  font-size: clamp(1.8rem, 3.6vw, 2.9rem); line-height: 1.16; letter-spacing: -.02em;
  margin: 0 auto var(--s4); max-width: 18ch;
}
.ink-news__title .fl { color: var(--ember); }
.ink-news__dek { color: color-mix(in oklab, var(--paper) 72%, transparent); max-width: 46ch; margin-inline: auto; line-height: 1.7; }
.ink-form {
  display: flex; gap: .5rem; max-width: 30rem; margin: var(--s6) auto var(--s3);
  background: color-mix(in oklab, var(--paper) 12%, transparent);
  border: 1px solid color-mix(in oklab, var(--paper) 22%, transparent);
  border-radius: 999px; padding: .35rem .35rem .35rem 1.1rem;
}
.ink-form input {
  flex: 1; background: none; border: 0; outline: none; font: inherit;
  font-size: .95rem; color: var(--paper); min-width: 0;
}
.ink-form input::placeholder { color: color-mix(in oklab, var(--paper) 45%, transparent); }
.ink-form .btn { background: var(--ember); border-color: var(--ember); color: #fff; }
.ink-form .btn:hover { filter: brightness(1.08); transform: none; }
.ink-news__fine { color: color-mix(in oklab, var(--paper) 45%, transparent); font-size: .62rem; }

/* --------------------------------------------------------------- responsive */

@media (max-width: 62rem) {
  .ink-hero__grid, .ink-about__grid { grid-template-columns: minmax(0, 1fr); }
  .ink-hero__art { order: -1; }
  .ink-float--stat { right: 2%; }
  .ink-float--post { left: 2%; }
  .ink-feature-grid { grid-template-columns: minmax(0, 1fr); }
  .ink-feature-grid > :first-child { grid-row: auto; }
}
@media (max-width: 40rem) {
  .ink-float { position: static; max-width: none; margin-top: var(--s3); box-shadow: none; }
  .ink-hero__art { display: flex; flex-direction: column; }
  .ink-badge { right: 0; bottom: -.5rem; }
  .ink-head { align-items: flex-start; }
}

/* ------------------------------------------------------------ theme: Inkwell */

:root[data-skin='inkwell'] .masthead {
  background: color-mix(in oklab, var(--paper) 88%, transparent);
  border-bottom: 1px solid var(--line);
}
:root[data-skin='inkwell'] .brand__mark { border-radius: 8px; }
:root[data-skin='inkwell'] .btn--primary { background: var(--ink); border-color: var(--ink); }
:root[data-skin='inkwell'] .btn--primary:hover { background: var(--ember); border-color: var(--ember); }
:root[data-skin='inkwell'] .footer { background: var(--ink); color: var(--paper); border-top: 0; margin-top: 0; }
:root[data-skin='inkwell'] .footer a, :root[data-skin='inkwell'] .footer ul button { color: color-mix(in oklab, var(--paper) 74%, transparent); }
:root[data-skin='inkwell'] .footer a:hover, :root[data-skin='inkwell'] .footer ul button:hover { color: var(--ember); }
:root[data-skin='inkwell'] .footer h3 { color: color-mix(in oklab, var(--paper) 48%, transparent); }
:root[data-skin='inkwell'] .footer .muted,
:root[data-skin='inkwell'] .colophon p { color: color-mix(in oklab, var(--paper) 55%, transparent); }
:root[data-skin='inkwell'] .colophon { border-top-color: color-mix(in oklab, var(--paper) 18%, transparent); }
:root[data-skin='inkwell'] .footer .brand__mark { background: var(--ember); color: #fff; }
:root[data-skin='inkwell'] .footer .brand__name { color: var(--paper); }

:root[data-skin='inkwell'] .card__art,
:root[data-skin='inkwell'] .entryhead__plate { border-color: var(--line); }
:root[data-skin='inkwell'] .prose h2::before { background: var(--ember); }


/* ------------------------------------------- editorial: interior pages */

.ink-pagehead {
  background: var(--paper-3);
  padding-block: clamp(2.5rem, 5vw, 4.5rem) clamp(2.5rem, 5vw, 4rem);
}
.ink-pagehead__title {
  font-size: clamp(2.1rem, 4.6vw, 3.4rem); line-height: 1.1;
  letter-spacing: -.025em; margin: 0 0 var(--s4); max-width: 16ch;
}
.ink-pagehead__dek { color: var(--ink-2); font-size: 1.05rem; line-height: 1.7; max-width: 54ch; }
.ink-stats { display: flex; gap: var(--s6); flex-wrap: wrap; margin-top: var(--s5); }
.ink-stats span { font-family: var(--font-mono); font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3); }
.ink-stats b {
  display: block; font-family: var(--font-display); font-size: 1.8rem;
  font-weight: var(--display-weight-strong); letter-spacing: -.02em;
  color: var(--ink); text-transform: none; letter-spacing: -.02em;
}

.ink-filters { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: var(--s6); }
.ink-filters .ink-pill[aria-pressed='true'] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.ink-filters .ink-pill[aria-pressed='true'] .icon { color: var(--paper); }

.ink-list-grid {
  display: grid; gap: var(--s5);
  grid-template-columns: repeat(auto-fill, minmax(min(17rem, 100%), 1fr));
}
.ink-list-lead { grid-column: span 2; }
.ink-list-lead .icard--lead .icard__art { aspect-ratio: 21 / 9; }
@media (max-width: 46rem) { .ink-list-lead { grid-column: auto; } }

.ink-entryhead { padding-block: clamp(2.5rem, 5vw, 4rem) 0; background: var(--paper-3); }
.ink-entryhead .crumbs { justify-content: center; }
.ink-entryhead__title {
  font-size: clamp(2.1rem, 4.8vw, 3.6rem); line-height: 1.08;
  letter-spacing: -.028em; margin: var(--s4) auto var(--s4); max-width: 18ch;
}
.ink-entryhead__dek {
  color: var(--ink-2); font-size: 1.12rem; line-height: 1.65;
  max-width: 46ch; margin-inline: auto;
}
.ink-byline {
  display: inline-flex; align-items: center; gap: .65rem;
  margin-top: var(--s5); text-align: left;
}
.ink-byline b { display: block; font-size: .92rem; }
.ink-byline__meta { display: block; color: var(--ink-4); font-size: .62rem; margin-top: .1rem; }
.ink-byline .icard__face { width: 2.4rem; height: 2.4rem; }
.ink-entryhead__plate {
  margin-top: clamp(2rem, 4vw, 3.5rem); margin-bottom: calc(clamp(2rem, 4vw, 3.5rem) * -1);
  position: relative; z-index: 1;
  border-radius: var(--r-lg); overflow: hidden; border: 1px solid var(--line);
  aspect-ratio: 21 / 9; box-shadow: var(--shadow);
}
.ink-entryhead__plate img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ink-entryhead + .wrap { padding-top: clamp(3.5rem, 7vw, 6rem); }
@media (max-width: 40rem) { .ink-entryhead__plate { aspect-ratio: 16 / 10; } }

/* Library, courses and about keep their templates but pick up the framing. */
:root[data-skin='inkwell'] .pagehead { background: var(--paper-3); padding-block: clamp(2.5rem, 5vw, 4rem); border-bottom: 0; }
:root[data-skin='inkwell'] .pagehead + .wrap,
:root[data-skin='inkwell'] .pagehead + .section { padding-top: var(--s7); }
:root[data-skin='inkwell'] .filterbar { border-bottom: 0; background: var(--paper); }
:root[data-skin='inkwell'] .pill { border-radius: 999px; }
:root[data-skin='inkwell'] .bookrow,
:root[data-skin='inkwell'] .card--row { border-bottom-color: var(--line); }

/* -------------------------------------------------- editorial: shelf widget */

.ink-shelf__grid {
  display: grid; gap: var(--s6);
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  align-items: start;
}

.ink-now {
  display: grid; grid-template-columns: 8.5rem minmax(0, 1fr); gap: var(--s5);
  background: var(--paper-2); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: var(--s5); text-decoration: none;
  transition: transform .24s var(--ease), box-shadow .24s var(--ease), border-color .24s var(--ease);
}
.ink-now:hover {
  transform: translateY(var(--lift)); box-shadow: var(--shadow);
  border-color: color-mix(in oklab, var(--accent) 40%, var(--line));
}
.ink-now__cover { display: block; }
.ink-now__cover .cover { border-radius: 3px 10px 10px 3px; box-shadow: 0 12px 24px -14px rgba(60, 40, 20, .5); }
.ink-now__text { display: flex; flex-direction: column; gap: .45rem; align-items: flex-start; }
.ink-now__title {
  font-family: var(--font-display); font-weight: var(--display-weight-strong);
  font-size: 1.25rem; line-height: 1.2; letter-spacing: -.015em; color: var(--ink);
}
.ink-now__by { color: var(--ink-3); font-size: .88rem; }
.ink-now__meta { color: var(--ink-4); font-size: .62rem; display: flex; align-items: center; gap: .4rem; }
.ink-now__note {
  color: var(--ink-2); font-size: .9rem; line-height: 1.6; margin-top: .2rem;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.ink-now .icard__more { margin-top: .3rem; }

.ink-progress {
  display: block; width: 100%; max-width: 14rem; height: 4px;
  background: var(--paper-3); border-radius: 999px; overflow: hidden;
}
.ink-progress > span { display: block; height: 100%; background: var(--accent); border-radius: 999px; }

.ink-shelf__side {
  border: 1px solid var(--line); border-radius: var(--r-lg);
  background: var(--paper-2); padding: var(--s5);
}
.ink-shelf__label {
  display: flex; align-items: center; gap: .4rem; color: var(--ink-4);
  padding-bottom: var(--s3); border-bottom: 1px solid var(--line); margin: 0 0 var(--s2);
}
.ink-shelf__label .icon { color: var(--ember); }
.ink-shelf__list { list-style: none; margin: 0; padding: 0; }
.ink-shelf__list li + li { border-top: 1px dashed var(--line); }

.ink-mini {
  display: grid; grid-template-columns: 2.4rem minmax(0, 1fr); gap: var(--s3);
  align-items: center; padding: var(--s3) 0; text-decoration: none;
}
.ink-mini__cover .cover { border-radius: 2px 5px 5px 2px; padding: .25rem .2rem; }
.ink-mini__cover .cover__title { font-size: .38rem; }
.ink-mini__cover .cover__author { display: none; }
.ink-mini__text { display: flex; flex-direction: column; gap: .1rem; min-width: 0; }
.ink-mini__title {
  font-size: .92rem; font-weight: 550; line-height: 1.3; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ink-mini:hover .ink-mini__title { color: var(--accent); }
.ink-mini__by { font-size: .78rem; color: var(--ink-4); }
.ink-mini .stars { font-size: .6rem; margin-top: .1rem; }
.ink-mini .stars .icon { width: .8em; height: .8em; }

.ink-shelf__stats {
  display: flex; gap: var(--s5); flex-wrap: wrap; color: var(--ink-4);
  margin: var(--s4) 0 0; padding-top: var(--s3); border-top: 1px solid var(--line);
}
.ink-shelf__stats b { color: var(--ink); font-family: var(--font-display); font-size: 1rem; }

@media (max-width: 62rem) {
  .ink-shelf__grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 40rem) {
  .ink-now { grid-template-columns: 6rem minmax(0, 1fr); gap: var(--s4); padding: var(--s4); }
}

/* ======================================================= layout: Halo */

/* Halo is built from one primitive: a large rounded media panel, with text
   laid over or beside it. Sections are separated by air and radius, never by
   rules. Everything here is scoped to the halo layout's own class names, so it
   costs the other layouts nothing. */

.halo-eyebrow {
  display: inline-flex; align-items: center; gap: .55rem;
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--plum); margin: 0 0 var(--s3);
}
.halo-eyebrow::before { content: ''; width: 1.4rem; height: 2px; background: var(--plum); border-radius: 2px; }
.halo-h1 {
  font-size: clamp(2.4rem, 5.6vw, 4.4rem); line-height: 1.02; letter-spacing: -.04em;
  margin: 0 0 var(--s4); max-width: 18ch;
}
.halo-h2 {
  font-size: clamp(1.8rem, 3.6vw, 2.9rem); line-height: 1.06; letter-spacing: -.035em;
  margin: 0; max-width: 20ch;
}
.halo-h1 .fl, .halo-h2 .fl, .halo-hero__title .fl, .halo-cta__title .fl {
  font-style: normal;
  background: linear-gradient(100deg, var(--plum), var(--berry) 60%, var(--ember));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.halo-lede { color: var(--ink-2); font-size: 1.1rem; line-height: 1.7; max-width: 52ch; margin: 0; }
.halo-head { margin-bottom: var(--s6); }
.halo-head--row { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s4); flex-wrap: wrap; }

/* Buttons: pills, three weights. */
.hbtn {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .8rem 1.35rem; border-radius: 999px; text-decoration: none;
  font-family: var(--font-ui); font-size: .92rem; font-weight: 600;
  background: var(--paper-2); color: var(--ink); border: 1px solid var(--line);
  transition: transform .22s var(--ease), background .22s var(--ease), border-color .22s var(--ease), color .22s var(--ease);
}
.hbtn:hover { transform: translateY(-2px); border-color: var(--plum); }
.hbtn .icon { width: 1.05em; height: 1.05em; transition: transform .22s var(--ease); }
.hbtn:hover .icon { transform: translateX(3px); }
.hbtn--dark { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.hbtn--dark:hover { background: var(--plum); border-color: var(--plum); color: #fff; }
.hbtn--light { background: #fff; color: #1a1030; border-color: #fff; }
.hbtn--light:hover { background: #fff; border-color: #fff; }
.hbtn--ghost { background: rgba(255, 255, 255, .14); color: #fff; border-color: rgba(255, 255, 255, .45); backdrop-filter: blur(8px); }
.hbtn--ghost:hover { background: rgba(255, 255, 255, .24); border-color: #fff; }

.halo-pills { display: flex; gap: .5rem; flex-wrap: wrap; }
.hpill {
  display: inline-flex; align-items: center; gap: .4rem; padding: .42rem .85rem;
  border-radius: 999px; background: var(--paper-2); border: 1px solid var(--line);
  font-size: .82rem; font-weight: 500; color: var(--ink-2); text-decoration: none;
  transition: border-color .18s var(--ease), color .18s var(--ease), background .18s var(--ease);
}
.hpill:hover { border-color: var(--plum); color: var(--plum); }
.hpill .icon { width: .9em; height: .9em; opacity: .6; }
.hpill--btn[aria-pressed='true'] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.halo-filters { margin-bottom: var(--s6); }

/* Video primitive ---------------------------------------------------------- */

.vid { position: relative; overflow: hidden; background: var(--paper-3); }
.vid video, .vid iframe { display: block; width: 100%; height: 100%; }
.vid--ambient { position: absolute; inset: 0; }
.vid--ambient video { object-fit: cover; }
.vid--player { aspect-ratio: 16 / 9; border-radius: var(--r-lg); }
.vid--player video { object-fit: cover; }
.vid--embed { aspect-ratio: 16 / 9; border-radius: var(--r-lg); }
.vid--embed iframe { border: 0; }

/* Hero ---------------------------------------------------------------------- */

.halo-hero { padding-top: var(--s4); }
.halo-hero__panel {
  position: relative; overflow: hidden; border-radius: var(--r-lg);
  min-height: clamp(30rem, 78vh, 46rem); display: flex; flex-direction: column;
  justify-content: space-between; padding: clamp(1.5rem, 4vw, 3.5rem);
  color: #fff; background: var(--plum); box-shadow: var(--shadow);
}
.halo-hero__scrim {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, rgba(20, 8, 40, .58) 0%, rgba(20, 8, 40, .22) 45%, rgba(20, 8, 40, .05) 75%),
              linear-gradient(to top, rgba(20, 8, 40, .55), transparent 45%);
}
.halo-hero__scrim--soft { background: linear-gradient(to right, rgba(255, 255, 255, .55), rgba(255, 255, 255, .15)); }
.halo-hero__text { position: relative; max-width: 40rem; }
.halo-hero__text .halo-eyebrow { color: #fff; opacity: .88; }
.halo-hero__text .halo-eyebrow::before { background: #fff; }
/* On a post slide the label sits in a chip: the backdrop varies with the
   post's accent, and a bare line of type could land on a colour close to it. */
.halo-hero__text--post .halo-eyebrow {
  opacity: 1; gap: .45rem; padding: .32rem .7rem; border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .14); border: 1px solid rgba(255, 255, 255, .22);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); color: #fff;
}
.halo-hero__text--post .halo-eyebrow::before { width: .45rem; height: .45rem; border-radius: 50%; background: #ffd9ec; }
/* A post in the hero. The brand loop stays as the backdrop; the post sits on
   it as a split - headline-sized title and the dek on the left, the cover in
   a framed, floating card on the right, tinted by the post's accent. The
   panel is shorter than the brand hero: this is a front page, not a poster. */
.halo-hero__panel--post { min-height: clamp(26rem, 62vh, 38rem); }
.halo-hero__post {
  position: relative; display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(1.5rem, 4vw, 4rem); align-items: center; flex: 1;
}
.halo-hero__post--solo { grid-template-columns: minmax(0, 1fr); }
/* Slides share one grid cell so the panel is as tall as the tallest of them
   and never jumps between posts; the active one fades in, the rest sit
   underneath, inert. */
.halo-hero__slides { position: relative; display: grid; flex: 1; }
.halo-hero__slides > .halo-hero__post { grid-area: 1 / 1; opacity: 0; visibility: hidden; transform: translateY(6px); transition: opacity .6s var(--ease), transform .6s var(--ease), visibility 0s .6s; }
.halo-hero__slides > .halo-hero__post[data-active] { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.halo-hero__slides[data-slider] > .halo-hero__post .halo-hero__card { transition-delay: .1s; }
.halo-hero__foot { position: relative; display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s4); flex-wrap: wrap; margin-top: var(--s5); }
.halo-hero__foot .halo-hero__stats { margin-top: 0; margin-left: auto; }
.halo-hero__nav { display: flex; align-items: center; gap: var(--s3); padding-bottom: .2rem; }
.halo-hero__arrow {
  display: inline-grid; place-items: center; width: 2.4rem; height: 2.4rem; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .25); background: rgba(255, 255, 255, .08); color: #fff; cursor: pointer;
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.halo-hero__arrow:hover { background: rgba(255, 255, 255, .18); border-color: rgba(255, 255, 255, .45); }
.halo-hero__arrow:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.halo-hero__arrow svg { width: 1.1rem; height: 1.1rem; }
.halo-hero__arrow[data-prev] svg { transform: rotate(180deg); }
.halo-hero__dots { display: flex; gap: .4rem; }
.halo-hero__dots button { padding: .5rem .15rem; border: 0; background: none; cursor: pointer; }
.halo-hero__dots i { display: block; width: 1.4rem; height: .22rem; border-radius: 1rem; background: rgba(255, 255, 255, .3); transition: background .3s var(--ease), width .3s var(--ease); }
.halo-hero__dots button[aria-selected="true"] i { width: 2.6rem; background: #fff; }
.halo-hero__dots button:hover i { background: rgba(255, 255, 255, .6); }
.halo-hero__dots button:focus-visible { outline: 2px solid #fff; outline-offset: -2px; border-radius: 1rem; }
@media (prefers-reduced-motion: reduce) { .halo-hero__slides > .halo-hero__post { transition: none; } }
.halo-hero__text--post { max-width: 36rem; }
.halo-hero__text--post .halo-hero__sub { margin-bottom: var(--s3); }
.halo-hero__title.halo-hero__title--post {
  font-size: clamp(1.9rem, 3.6vw, 3.3rem); line-height: 1.06; letter-spacing: -.03em;
  margin: 0 0 var(--s3); max-width: 22ch;
}
.halo-hero__title--post a { color: inherit; text-decoration: none; }
.halo-hero__title--post a:hover { text-decoration: underline; text-decoration-thickness: .06em; text-underline-offset: .12em; }
.halo-hero__meta { font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: rgba(255, 255, 255, .82); margin: 0 0 var(--s5); }
.halo-hero__meta a { color: inherit; text-decoration: none; } .halo-hero__meta a:hover { color: #fff; }
.halo-hero__card {
  position: relative; display: block; aspect-ratio: 4 / 3; overflow: hidden;
  border-radius: var(--r-lg); background: var(--accent, var(--plum));
  border: 1px solid rgba(255, 255, 255, .18);
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, .55), 0 0 0 10px rgba(255, 255, 255, .05);
  transform: rotate(1.5deg); transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}
.halo-hero__card:hover { transform: rotate(0) scale(1.02); box-shadow: 0 40px 70px -20px rgba(0, 0, 0, .6), 0 0 0 10px rgba(255, 255, 255, .08); }
.halo-hero__card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.halo-hero__card .vid--ambient { position: absolute; inset: 0; }
.halo-hero__card::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top, rgba(20, 8, 40, .35), transparent 50%); pointer-events: none; }
.halo-hero__post .halo-hero__actions .hbtn--light { box-shadow: 0 10px 30px -10px rgba(0, 0, 0, .5); }
@media (max-width: 56rem) {
  .halo-hero__post { grid-template-columns: minmax(0, 1fr); }
  .halo-hero__card { order: -1; max-width: 22rem; aspect-ratio: 16 / 10; transform: none; }
}
.halo-hero__title {
  font-size: clamp(2.8rem, 7.2vw, 6.2rem); line-height: .98; letter-spacing: -.045em;
  margin: 0 0 var(--s4); color: #fff; text-wrap: balance;
}
.halo-hero__title .fl { background: linear-gradient(100deg, #fff, #ffd9ec 60%, #ffc2a8); -webkit-background-clip: text; background-clip: text; }
.halo-hero__sub { font-size: clamp(1rem, 1.4vw, 1.2rem); line-height: 1.6; color: rgba(255, 255, 255, .9); max-width: 44ch; margin: 0 0 var(--s5); }
.halo-hero__actions { display: flex; gap: var(--s3); flex-wrap: wrap; }
.halo-hero__stats {
  position: relative; display: flex; gap: clamp(1.5rem, 4vw, 3.5rem); flex-wrap: wrap;
  justify-content: flex-end; margin-top: var(--s6);
}
.halo-stat b {
  display: block; font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2rem, 4.2vw, 3.4rem); line-height: 1; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
}
.halo-stat span { display: block; margin-top: .3rem; font-size: .8rem; color: rgba(255, 255, 255, .8); }

/* Marquee ------------------------------------------------------------------- */

.halo-marquee { overflow: hidden; padding: var(--s6) 0 0; mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent); }
.halo-marquee__track {
  display: flex; gap: 0; width: max-content;
  animation: halo-scroll 38s linear infinite;
}
.halo-marquee__track span {
  display: inline-flex; align-items: center; gap: 1.4rem; padding-right: 1.4rem;
  font-family: var(--font-display); font-weight: 700; font-size: clamp(1.4rem, 2.8vw, 2.2rem);
  letter-spacing: -.03em; color: var(--ink-4); white-space: nowrap;
}
.halo-marquee__track span i { width: .5em; height: .5em; border-radius: 50%; background: var(--plum); opacity: .55; }
@keyframes halo-scroll { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .halo-marquee__track { animation: none; } }

/* Services ------------------------------------------------------------------ */

.halo-services__grid {
  display: grid; gap: var(--s4);
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
}
.hservice {
  position: relative; display: flex; flex-direction: column; gap: .55rem;
  padding: var(--s5); border-radius: var(--r-md);
  background: var(--paper-2); border: 1px solid var(--line);
  transition: transform .24s var(--ease), box-shadow .24s var(--ease), border-color .24s var(--ease);
}
.hservice:hover { transform: translateY(-6px); box-shadow: var(--shadow); border-color: color-mix(in oklab, var(--plum) 40%, var(--line)); }
.hservice__media { display: block; aspect-ratio: 4 / 3; border-radius: var(--r-sm); overflow: hidden; margin-bottom: var(--s3); }
.hservice__media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .6s var(--ease); }
.hservice:hover .hservice__media img { transform: scale(1.05); }
.hservice__n { color: var(--plum); font-size: .7rem; letter-spacing: .14em; }
.hservice__title { display: flex; align-items: center; gap: .5rem; font-size: 1.25rem; letter-spacing: -.02em; }
.hservice__title .icon { color: var(--plum); width: 1.1em; height: 1.1em; }
.hservice__text { color: var(--ink-3); font-size: .93rem; line-height: 1.6; margin: 0; }

/* Stories rail ------------------------------------------------------------- */

.halo-stories .wrap { padding-bottom: 0; }
.halo-stories__rail {
  display: flex; gap: var(--s4); overflow-x: auto; scroll-snap-type: x mandatory;
  padding: .25rem var(--gutter) var(--s4); scrollbar-width: none;
  max-width: var(--wrap, 76rem); margin: 0 auto;
}
.halo-stories__rail::-webkit-scrollbar { display: none; }
.hstory {
  flex: 0 0 15.5rem; scroll-snap-align: start; display: flex; flex-direction: column; text-align: left;
  padding: 0; border-radius: var(--r-md); overflow: hidden; background: var(--paper-2); border: 1px solid var(--line);
  transition: transform .24s var(--ease), box-shadow .24s var(--ease), border-color .24s var(--ease);
}
.hstory:hover { transform: translateY(var(--lift)); box-shadow: var(--shadow); border-color: color-mix(in oklab, var(--accent) 45%, var(--line)); }
.hstory__media { position: relative; display: block; aspect-ratio: 4 / 3; overflow: hidden; background: var(--paper-3); border-radius: var(--r-media-top) var(--r-media-top) 0 0; }
.hstory__media img, .hstory__media svg { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .7s var(--ease); }
.hstory:hover .hstory__media img { transform: scale(1.05); }
/* An advisory is short-form like any other note, but it should not look
   like a weekend walk. The kind chip carries the weight.

   Fixed red rather than var(--ember): ember is decorative and swings from
   pink to orange across the palettes, and "urgent" should not depend on
   which theme the reader happens to have picked. */
.hstory[data-kind='alert'] .hstory__kind,
.story[data-kind='alert'] .story__kind,
.reader[data-kind='alert'] .story__kind {
  background: #d92d20; color: #fff; border: 0;
}
.hstory[data-kind='alert'] { border-color: rgba(217, 45, 32, .5); }
.hstory__kind {
  position: absolute; left: .8rem; top: .8rem; padding: .28rem .6rem; border-radius: 999px;
  font-family: var(--font-mono); font-size: .6rem; letter-spacing: .12em; text-transform: uppercase;
  background: rgba(255, 255, 255, .88); color: #1a1030; backdrop-filter: blur(6px);
}
.hstory__glyph { position: absolute; right: .7rem; bottom: .4rem; font-size: 1.7rem; line-height: 1; color: #fff; text-shadow: 0 2px 10px rgba(0, 0, 0, .45); }
.hstory__body { display: flex; flex-direction: column; gap: .35rem; padding: var(--s3) var(--s4) var(--s4); }
.hstory__date { font-size: .62rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-4); }
.hstory__title { font-family: var(--font-display); font-weight: var(--display-weight-strong); font-size: 1.02rem; line-height: 1.3; letter-spacing: -.01em; color: var(--ink); }
@media (max-width: 40rem) { .hstory { flex-basis: 74vw; } }

/* Cards + bento ------------------------------------------------------------- */

.hcard {
  display: flex; flex-direction: column; text-decoration: none; height: 100%;
  border-radius: var(--r-md); overflow: hidden; background: var(--paper-2);
  border: 1px solid var(--line);
  transition: transform .24s var(--ease), box-shadow .24s var(--ease), border-color .24s var(--ease);
}
.hcard:hover { transform: translateY(var(--lift)); box-shadow: var(--shadow); border-color: color-mix(in oklab, var(--accent) 45%, var(--line)); }
.hcard__media { position: relative; display: block; aspect-ratio: 16 / 10; overflow: hidden; background: var(--paper-3); border-radius: var(--r-media-top) var(--r-media-top) 0 0; }
.hcard__media img, .hcard__media svg { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .7s var(--ease); }
.hcard:hover .hcard__media img { transform: scale(1.05); }
.hcard__cat {
  position: absolute; left: .9rem; top: .9rem; display: inline-flex; align-items: center; gap: .35rem;
  padding: .32rem .7rem; border-radius: 999px; font-size: .7rem; font-weight: 600; letter-spacing: .04em;
  background: rgba(255, 255, 255, .88); color: #1a1030; backdrop-filter: blur(6px);
}
.hcard__cat .icon { width: .95em; height: .95em; color: var(--accent); }
.hcard__cat--static { position: static; display: inline-flex; margin-bottom: var(--s4); background: var(--paper-2); border: 1px solid var(--line); color: var(--ink); }
.hcard__play {
  position: absolute; right: .9rem; bottom: .9rem; width: 2.6rem; height: 2.6rem; border-radius: 50%;
  display: grid; place-items: center; background: rgba(255, 255, 255, .92); color: #1a1030;
  box-shadow: 0 10px 24px -10px rgba(0, 0, 0, .5);
}
.hcard__play .icon { width: 1.1rem; height: 1.1rem; }
.hcard__body { display: flex; flex-direction: column; gap: .45rem; padding: var(--s4) var(--s4) var(--s5); }
.hcard__title { font-family: var(--font-display); font-weight: 700; font-size: 1.12rem; line-height: 1.25; letter-spacing: -.02em; color: var(--ink); }
.hcard__dek { color: var(--ink-3); font-size: .9rem; line-height: 1.55; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.hcard__meta { color: var(--ink-4); font-size: .64rem; letter-spacing: .08em; margin-top: auto; padding-top: .3rem; }

.hcard--lead .hcard__media { aspect-ratio: 16 / 9; }
.hcard--lead .hcard__title { font-size: clamp(1.4rem, 2.4vw, 2rem); }
.hcard--lead .hcard__dek { font-size: 1rem; -webkit-line-clamp: 3; }
.hcard--lead .hcard__body { padding: var(--s5); }

.halo-bento {
  display: grid; gap: var(--s4);
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.halo-bento > .hcard--lead, .halo-bento > .halo-bento__lead { grid-column: span 2; grid-row: span 2; }
.halo-bento--list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.halo-bento--list > .halo-bento__lead { grid-column: span 2; grid-row: auto; }
@media (max-width: 62rem) {
  .halo-bento, .halo-bento--list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .halo-bento > .hcard--lead, .halo-bento > .halo-bento__lead, .halo-bento--list > .halo-bento__lead { grid-column: span 2; grid-row: auto; }
}
@media (max-width: 40rem) {
  .halo-bento, .halo-bento--list { grid-template-columns: minmax(0, 1fr); }
  .halo-bento > .hcard--lead, .halo-bento > .halo-bento__lead, .halo-bento--list > .halo-bento__lead { grid-column: auto; }
}

/* Showreel ------------------------------------------------------------------ */

.halo-reel__panel {
  position: relative; display: block; overflow: hidden; border-radius: var(--r-lg);
  aspect-ratio: 21 / 9; min-height: 20rem; text-decoration: none; color: #fff;
  background: var(--plum); box-shadow: var(--shadow);
}
.halo-reel__panel::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top, rgba(10, 4, 24, .75), transparent 55%); }
.halo-reel__text { position: absolute; left: clamp(1.25rem, 3vw, 2.5rem); right: clamp(1.25rem, 3vw, 2.5rem); bottom: clamp(1.25rem, 3vw, 2.5rem); z-index: 1; display: flex; flex-direction: column; gap: .5rem; max-width: 40rem; }
.halo-reel__text .hcard__cat { position: static; align-self: flex-start; }
.halo-reel__text b { font-family: var(--font-display); font-size: clamp(1.4rem, 3vw, 2.4rem); line-height: 1.1; letter-spacing: -.03em; }
.halo-reel__text span:last-child { color: rgba(255, 255, 255, .85); font-size: .95rem; }
.halo-reel__play {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%; z-index: 1;
  width: 5rem; height: 5rem; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255, 255, 255, .92); color: #1a1030; box-shadow: 0 20px 50px -20px rgba(0, 0, 0, .7);
  transition: transform .24s var(--ease);
}
.halo-reel__panel:hover .halo-reel__play { transform: scale(1.08); }
@media (max-width: 40rem) { .halo-reel__panel { aspect-ratio: 4 / 5; } }

/* About split --------------------------------------------------------------- */

/* The media column used to be half the width at 4:5, which made a 762px
   image sit beside 364px of text. Give the text the room and cap the
   portrait: it is an illustration of a person, not a hero image. */
.halo-split { display: grid; gap: var(--s6); grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); align-items: center; }
.halo-split__media { position: relative; border-radius: var(--r-lg); overflow: hidden; aspect-ratio: 4 / 5; box-shadow: var(--shadow); max-width: 21rem; margin-inline: auto; }
.halo-split__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Where, in the text rather than stuck on the picture. The initials badge
   this replaces earned its place over an abstract illustration, which needed
   something to say whose page it was. A photograph does that on its own. */
.halo-where {
  display: flex; align-items: center; gap: .45rem; margin: var(--s3) 0 0;
  font-size: .7rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3);
}
.halo-where svg { width: .95rem; height: .95rem; color: var(--accent); }
.halo-split__text .halo-lede { margin: var(--s4) 0 var(--s5); }
.halo-split__text .halo-pills { margin-bottom: var(--s5); }
/* Keep the portrait ratio on small screens too. The old 4:3 was fine for an
   abstract illustration, but against a photograph it centre-crops a
   standing figure and takes the top of the head off. */
@media (max-width: 56rem) { .halo-split { grid-template-columns: minmax(0, 1fr); } }

/* CTA band ------------------------------------------------------------------ */

.halo-cta__panel {
  position: relative; overflow: hidden; border-radius: var(--r-lg);
  padding: clamp(2rem, 6vw, 5rem); color: #1a1030; box-shadow: var(--shadow); background: var(--paper-3);
}
.halo-cta__inner { position: relative; max-width: 40rem; }
.halo-cta__inner .halo-eyebrow { color: #4a2c86; }
.halo-cta__inner .halo-eyebrow::before { background: #4a2c86; }
.halo-cta__title { font-size: clamp(2rem, 4.4vw, 3.4rem); line-height: 1.02; letter-spacing: -.04em; margin: 0 0 var(--s4); }
.halo-cta__sub { color: #3f3550; line-height: 1.65; margin: 0 0 var(--s5); max-width: 46ch; }
.halo-form { display: flex; gap: .5rem; flex-wrap: wrap; }
.halo-form input {
  flex: 1 1 14rem; padding: .85rem 1.2rem; border-radius: 999px; border: 1px solid rgba(26, 16, 48, .15);
  background: rgba(255, 255, 255, .85); font: inherit; font-size: .95rem; color: #1a1030;
}
.halo-form input:focus-visible { outline: 2px solid var(--plum); outline-offset: 2px; }

/* Listing + entry heads ---------------------------------------------------- */

.halo-pagehead { padding-block: clamp(2.5rem, 5vw, 4rem) var(--s6); }
.halo-entryhead { padding-block: clamp(2rem, 4vw, 3.5rem) 0; }
.halo-entryhead .halo-h1 { max-width: 22ch; }
.halo-byline { display: inline-flex; align-items: center; gap: .7rem; margin-top: var(--s5); }
.halo-byline b { display: block; font-size: .92rem; }
.halo-byline .mono { display: block; font-size: .62rem; color: var(--ink-4); margin-top: .1rem; letter-spacing: .06em; }
.halo-byline .icard__face { width: 2.4rem; height: 2.4rem; }
.halo-entryhead__media {
  margin-top: var(--s6); border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow);
  aspect-ratio: 21 / 9; background: var(--paper-3);
}
.halo-entryhead__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.halo-entryhead__media .vid { aspect-ratio: auto; height: 100%; border-radius: 0; }
.halo-entryhead + .wrap { padding-top: var(--s7); }
@media (max-width: 40rem) { .halo-entryhead__media { aspect-ratio: 16 / 10; } }

/* Skin-level touches -------------------------------------------------------- */

:root[data-skin='halo'] .masthead { border-bottom: 0; background: color-mix(in oklab, var(--paper) 80%, transparent); }
:root[data-skin='halo'] .brand__mark { border-radius: 50%; background: linear-gradient(135deg, var(--plum), var(--berry)); }
:root[data-skin='halo'] .mainnav a[aria-current='page']::after { background: var(--plum); }
:root[data-skin='halo'] .pagehead { background: none; border-bottom: 0; }
:root[data-skin='halo'] .footer { border-top: 0; background: var(--paper-3); border-radius: var(--r-lg) var(--r-lg) 0 0; }
:root[data-skin='halo'] .prose h2::before { width: 2.2rem; height: 3px; border-radius: 2px; background: linear-gradient(90deg, var(--plum), var(--berry)); }
:root[data-skin='halo'] .code { border-radius: var(--r-md); }
:root[data-skin='halo'] .callout { border-radius: var(--r-md); }
:root[data-skin='halo'] .tutorbar { border-radius: var(--r-md); }

/* ---------------------------------------------------------- nav: sub-menus */

.mainnav__group { position: relative; display: inline-flex; align-items: center; }
.mainnav__parent[data-child-current] { color: var(--ink); }
.mainnav__toggle {
  display: inline-grid; place-items: center; width: 1.4rem; height: 1.4rem;
  margin-left: -.35rem; color: var(--ink-3); border-radius: 50%;
  transition: transform .2s var(--ease), color .2s var(--ease);
}
.mainnav__toggle .icon { transform: rotate(90deg); transition: transform .2s var(--ease); }
.mainnav__group:hover .mainnav__toggle,
.mainnav__group:focus-within .mainnav__toggle,
.mainnav__group[data-open='1'] .mainnav__toggle { color: var(--ink); }
.mainnav__group[data-open='1'] .mainnav__toggle .icon { transform: rotate(-90deg); }

.mainnav__sub {
  position: absolute; left: 0; top: calc(100% + .5rem); min-width: 12rem; z-index: 45;
  display: flex; flex-direction: column; padding: .4rem;
  background: var(--paper-2); border: 1px solid var(--line-2);
  border-radius: var(--r-md); box-shadow: var(--shadow);
  opacity: 0; visibility: hidden; transform: translateY(-4px);
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility 0s .18s;
}
.mainnav__group:hover .mainnav__sub,
.mainnav__group:focus-within .mainnav__sub,
.mainnav__group[data-open='1'] .mainnav__sub {
  opacity: 1; visibility: visible; transform: none; transition-delay: 0s;
}
/* A hover bridge so the pointer can cross the gap without closing it. */
.mainnav__group::after { content: ''; position: absolute; left: 0; right: 0; top: 100%; height: .6rem; }
.mainnav__child {
  padding: .5rem .7rem !important; border-radius: var(--r-sm); font-size: .9rem;
  white-space: nowrap;
}
.mainnav__child::after { display: none !important; }
.mainnav__child:hover, .mainnav__child[aria-current] { background: var(--paper-3); color: var(--ink) !important; }
.mainnav button { font: inherit; color: var(--ink-2); }

@media (max-width: 56rem) {
  /* On the mobile panel the sub-menu becomes an accordion beneath its parent. */
  .mainnav__group { display: flex; flex-wrap: wrap; align-items: center; width: 100%; border-bottom: 1px dashed var(--line); }
  .mainnav__group > .mainnav__parent { flex: 1; border-bottom: 0 !important; }
  .mainnav__toggle { width: 2.4rem; height: 2.4rem; margin: 0; }
  .mainnav__group::after { display: none; }
  .mainnav__sub {
    position: static; width: 100%; min-width: 0; box-shadow: none; border: 0;
    background: none; padding: 0 0 .5rem .75rem; transform: none;
    display: none; opacity: 1; visibility: visible;
  }
  .mainnav__group[data-open='1'] .mainnav__sub { display: flex; }
  .mainnav__child { border-bottom: 0 !important; font-size: .98rem; }
}

/* ---------------------------------------------------------- halo: shelf */

.halo-shelf__grid {
  display: grid; gap: var(--s4);
  grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr));
  align-items: stretch;
}
.hbook {
  display: flex; gap: var(--s4); padding: var(--s4); text-decoration: none;
  background: var(--paper-2); border: 1px solid var(--line); border-radius: var(--r-md);
  transition: transform .24s var(--ease), box-shadow .24s var(--ease), border-color .24s var(--ease);
}
.hbook:hover { transform: translateY(var(--lift)); box-shadow: var(--shadow); border-color: color-mix(in oklab, var(--accent) 45%, var(--line)); }
.hbook__cover { flex: none; width: 4.6rem; }
.hbook__cover .cover { border-radius: 3px 8px 8px 3px; box-shadow: 0 10px 22px -12px rgba(30, 10, 50, .5); }
.hbook__text { display: flex; flex-direction: column; gap: .35rem; min-width: 0; }
.hbook__title { font-family: var(--font-display); font-weight: 700; font-size: 1rem; line-height: 1.25; letter-spacing: -.02em; color: var(--ink); }
.hbook__by { color: var(--ink-3); font-size: .84rem; }
.hbook__meta { color: var(--ink-4); font-size: .62rem; letter-spacing: .06em; display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.hbook__note { color: var(--ink-2); font-size: .9rem; line-height: 1.55; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; margin-top: .2rem; }
.hbook .stars { font-size: .65rem; } .hbook .stars .icon { width: .85em; height: .85em; }
.hbook .hcard__cat--static { margin-bottom: .1rem; align-self: flex-start; }

.hbook--lead { grid-row: span 1; padding: var(--s5); gap: var(--s5); }
.hbook--lead .hbook__cover { width: 7.5rem; }
.hbook--lead .hbook__title { font-size: 1.35rem; }
.hbook--lead .hcard__meta { margin-top: auto; padding-top: .5rem; }

.halo-progress { display: block; width: 100%; max-width: 16rem; height: 5px; background: var(--paper-3); border-radius: 999px; overflow: hidden; }
.halo-progress > span { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--accent), color-mix(in oklab, var(--accent) 60%, var(--berry))); }

.halo-shelf__stats { display: flex; gap: var(--s5); flex-wrap: wrap; color: var(--ink-4); margin: var(--s5) 0 0; }
.halo-shelf__stats b { color: var(--ink); font-family: var(--font-display); font-size: 1.05rem; }

@media (max-width: 62rem) {
  .halo-shelf__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hbook--lead { grid-column: span 2; }
}
@media (max-width: 40rem) {
  .halo-shelf__grid { grid-template-columns: minmax(0, 1fr); }
  .hbook--lead { grid-column: auto; }
}

/* ------------------------------------------------------------- quote band
   One borrowed line between the shelf and the About block. Deliberately
   quiet: large type, generous space, and the attribution small underneath,
   so it reads as a pause rather than as another card competing for a click. */
.quoteband__fig { margin: 0; max-width: 46rem; }
.quoteband__text {
  margin: 0; font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.5rem, 3.2vw, 2.4rem); line-height: 1.25; letter-spacing: -.015em;
  color: var(--ink); text-wrap: balance;
}
.quoteband__text::before { content: '\201C'; color: var(--accent); margin-inline-start: -.5em; }
.quoteband__text::after { content: '\201D'; color: var(--accent); }
.quoteband__by {
  margin-top: var(--s4); display: flex; flex-wrap: wrap; align-items: baseline; gap: .55rem;
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .08em; text-transform: uppercase;
}
.quoteband__who { font-style: normal; color: var(--ink-2); }
.quoteband__where { color: var(--ink-4); }
.quoteband__where::before { content: '· '; }

/* ------------------------------------------------------------- text size
   A reader control for the article body only, not the whole interface.
   Browser zoom already scales everything; what long-form reading actually
   wants is bigger prose at the same layout, so the measure stays comfortable.
   Because --measure is in ch, the column widens with the text by itself.

   Most sizes inside .prose are already in em and inherit. The few in rem are
   restated here so a table or a code block grows with the paragraph it sits
   next to, instead of staying put and looking broken. */
:root { --read-scale: 1; }
:root[data-read='l']  { --read-scale: 1.13; }
:root[data-read='xl'] { --read-scale: 1.28; }

.prose { font-size: calc(var(--t-read) * var(--read-scale)); }
.prose h2 { font-size: calc(var(--t-h2) * var(--read-scale)); }
.prose h3 { font-size: calc(var(--t-h3) * var(--read-scale)); }
.prose table { font-size: calc(.92rem * var(--read-scale)); }
.prose .footnotes { font-size: calc(.9rem * var(--read-scale)); }
.prose .code pre { font-size: calc(.82rem * var(--read-scale)); }

/* The control itself: three steps, each drawn at the size it produces. */
.readsize { display: inline-flex; align-items: baseline; gap: .1rem; margin-left: auto; }
.readsize button {
  border: 0; background: none; cursor: pointer; color: var(--ink-4);
  font-family: var(--font-display); line-height: 1; padding: .3rem .45rem;
  border-radius: var(--r-sm); transition: color .15s var(--ease), background .15s var(--ease);
}
.readsize button:nth-child(1) { font-size: .82rem; }
.readsize button:nth-child(2) { font-size: 1rem; }
.readsize button:nth-child(3) { font-size: 1.22rem; }
.readsize button:hover { color: var(--ink-2); background: var(--paper-3); }
.readsize button[aria-pressed='true'] { color: var(--accent); }
/* Kept on phones too: a small screen is where bigger text matters most. */
@media (max-width: 34rem) { .readsize { margin-left: 0; } }

/* ------------------------------------------------------------ entry test
   A diagnostic, so it is styled to feel like reading rather than like sitting
   an exam: one question at a time, no clock, and the explanation given more
   room than the score. */
.chk { max-width: var(--measure); margin: 0 auto; }
.chk__bar { height: 3px; background: var(--line); border-radius: 2px; overflow: hidden; margin-bottom: var(--s3); }
.chk__bar i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .3s var(--ease); }
.chk__tier { font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-4); margin: 0 0 var(--s5); }

.chk__stem { font-size: 1.15rem; line-height: 1.5; margin: 0 0 var(--s4); }
.chk__pre {
  font-family: var(--font-mono); font-size: .8rem; line-height: 1.55;
  background: var(--paper-sunk); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: var(--s4);
  overflow-x: auto; margin: 0 0 var(--s4); white-space: pre;
}
.chk__opts { display: flex; flex-direction: column; gap: var(--s2); }
.chk__opt {
  text-align: left; font: inherit; font-size: .95rem;
  padding: .7rem .9rem; min-height: 2.75rem;
  background: var(--paper-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-sm); cursor: pointer;
  transition: border-color .15s var(--ease), background .15s var(--ease);
}
.chk__opt:hover:not(:disabled) { border-color: var(--accent); }
.chk__opt:disabled { cursor: default; opacity: .75; }
.chk__opt[data-state='right'] {
  border-color: var(--moss); background: color-mix(in oklab, var(--moss) 10%, var(--paper-2)); opacity: 1;
}
.chk__opt[data-state='wrong'] {
  border-color: var(--ember); background: color-mix(in oklab, var(--ember) 10%, var(--paper-2)); opacity: 1;
}

.chk__after { margin-top: var(--s4); display: flex; flex-direction: column; gap: var(--s3); align-items: flex-start; }
/* An author `display` beats the browser's own rule for [hidden], whatever the
   specificity, so any flex container the script hides has to say so itself. */
.chk__after[hidden], .chk__start[hidden] { display: none; }

/* An author `display` beats the browser's own [hidden] rule whatever the
   specificity, and every button on this site sets one. So anything the script
   hides by attribute has to be told again, here, once, rather than in each
   component that trips over it. */
button[hidden], .btn[hidden] { display: none; }

/* The console. Dark whatever the page is doing: a terminal that follows the
   site's light theme stops reading as a terminal, and the whole point of this
   question is that it feels like the real thing. */
.chk__goals { list-style: none; padding: 0; margin: 0 0 var(--s4); display: flex; flex-direction: column; gap: .3rem; }
.chk__goals li {
  font-size: .9rem; color: var(--ink-3); padding-left: 1.5rem; position: relative;
  transition: color .2s var(--ease);
}
.chk__goals li::before {
  content: '○'; position: absolute; left: 0; color: var(--ink-4);
}
.chk__goals li[data-done='1'] { color: var(--moss); }
.chk__goals li[data-done='1']::before { content: '●'; color: var(--moss); }

.chk__term {
  background: #12101a; border: 1px solid var(--line-2); border-radius: var(--r-sm);
  padding: var(--s3); font-family: var(--font-mono); font-size: .8rem; line-height: 1.5;
  color: #d8d3e4; margin-bottom: var(--s4);
}
.chk__termlog {
  margin: 0; max-height: 15rem; overflow: auto; white-space: pre; color: #b9b2c9;
  font: inherit;
}
.chk__termlog:empty { display: none; }
.chk__termline { display: flex; gap: .5rem; align-items: baseline; }
.chk__prompt { color: #9d7bff; white-space: nowrap; }
.chk__input {
  flex: 1; min-width: 0; background: none; border: 0; outline: none;
  font: inherit; color: #f2eefb; padding: .15rem 0;
}
.chk__input:disabled { opacity: .5; }
.chk__labacts { margin-top: var(--s3); }
.chk__invite {
  margin: 0 0 var(--s4); padding: var(--s3) var(--s4);
  font-size: .9rem; line-height: 1.55; color: var(--ink-2);
  background: var(--paper-2); border-left: 2px solid var(--accent);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}

/* The simulator runs in a frame, which is what lets it keep its own layout,
   its own stylesheet and its own idea of a canvas without any of it leaking
   into the page around it. It needs real height to be usable at all. */
.chk__sim {
  border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden;
  background: var(--paper-2); margin-bottom: var(--s4);
  /* Wider than the reading column: a topology is not prose. */
  width: min(72rem, calc(100vw - var(--gutter) * 2));
  margin-inline: calc((min(72rem, calc(100vw - var(--gutter) * 2)) - 100%) / -2);
}
.chk__sim iframe { display: block; width: 100%; height: min(78vh, 46rem); border: 0; }
.chk__simlines { margin: 0; padding-left: 1.2em; font-size: .9rem; color: var(--ink-3); }
.chk__simlines li { margin-bottom: .3em; }

@media (max-width: 60rem) {
  .chk__sim { width: 100%; margin-inline: 0; }
  .chk__sim iframe { height: min(82vh, 40rem); }
}
.chk__why[data-ok='1'] { border-left-color: var(--moss); }

@media (max-width: 34rem) {
  /* 16px or iOS zooms the page when the field takes focus. */
  .chk__input, .chk__term { font-size: 16px; }
  .chk__termlog { max-height: 11rem; }
}
.chk__why { margin: 0; font-size: .95rem; color: var(--ink); border-left: 2px solid var(--ember); padding-left: var(--s3); }
.chk__note { margin: 0; font-size: .88rem; color: var(--ink-3); line-height: 1.55; }

.chk__start { display: flex; flex-direction: column; gap: var(--s3); align-items: flex-start; max-width: var(--measure); }

/* The address panel. Same column as the Start panel it replaces, so the page
   does not jump when the probe comes back and one swaps for the other. */
.chk__gate { display: flex; flex-direction: column; gap: var(--s3); align-items: flex-start; max-width: var(--measure); }
.chk__gatehead { margin: 0; font-size: 1.1rem; font-weight: 600; }
.chk__who { font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-4); margin: 0; }
/* Sits inside the "signed in as" line, so it has to read as part of the
   sentence rather than as another button on the page. */
.signout {
  font: inherit; letter-spacing: inherit; text-transform: inherit;
  background: none; border: 0; padding: 0;
  color: var(--accent); cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.signout:disabled { color: var(--ink-4); cursor: default; text-decoration: none; }

/* An author `display` beats the browser's own rule for [hidden], whatever the
   specificity, so each of these has to say so itself. */
.chk__gate[hidden], .chk__who[hidden] { display: none; }

/* The offer that stands in for the course page while there is not one. It is
   a sales box on a page that is otherwise not selling anything, so it is
   quiet: an accent edge rather than a filled panel. */
.chk__offer {
  margin: var(--s7) 0 0;
  max-width: var(--measure);
  padding: var(--s5);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-card, 10px);
  background: var(--paper-2);
}
.chk__offerhead { margin: 0 0 var(--s3); font-size: 1.05rem; font-weight: 650; }
.chk__offerbody { margin: 0 0 var(--s4); font-size: .95rem; line-height: 1.6; color: var(--ink-2); }
.chk__offer p:last-child { margin-bottom: 0; }

/* ------------------------------------------------------------------- lab art */

.labfig { margin: var(--s6) 0; max-width: var(--measure); }
/* An author display beats the browser rule for [hidden], as ever. */
.labfig[hidden], [data-chk-intro][hidden] { display: none; }
.labfig--tight { margin: 0 0 var(--s6); }
.labart {
  display: block; width: 100%; height: auto;
  background: var(--paper-3);
  border: 1px solid var(--line);
  border-radius: var(--r-card, 10px);
  padding: var(--s4);
  box-sizing: border-box;
}
.labfig figcaption {
  margin-top: var(--s3);
  font-size: .86rem; line-height: 1.55; color: var(--ink-3);
}

/* ------------------------------------------------------------- pre-order */

.presale {
  margin: var(--s7) 0 0;
  padding: var(--s6);
  border: 1px solid var(--line);
  border-top: 3px solid var(--accent);
  border-radius: var(--r-card, 10px);
  background: var(--surface-2, var(--surface));
}
.presale__eyebrow {
  margin: 0 0 var(--s2);
  font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent);
}
.presale__fig { margin: 0 0 var(--s4); display: flex; align-items: baseline; gap: var(--s3); flex-wrap: wrap; }
.presale__now { font-size: 2.1rem; font-weight: 650; line-height: 1; letter-spacing: -.02em; }
/* "€99 at launch", in words rather than a strike through the number: a line
   through a price reads as a discount already applied, and this one has not
   been. */
.presale__was { font-size: .82rem; color: var(--ink-3); }
.presale__note { margin: 0 0 var(--s4); font-size: .95rem; color: var(--ink-2); }
.presale__list { list-style: none; padding: 0; margin: 0 0 var(--s5); display: flex; flex-direction: column; gap: var(--s2); }
.presale__list li { font-size: .92rem; line-height: 1.5; padding-left: 1.3em; position: relative; color: var(--ink-2); }
.presale__list li::before { content: '\2713'; position: absolute; left: 0; color: var(--accent); }
.presale__terms { margin: var(--s4) 0 0; font-size: .82rem; line-height: 1.6; color: var(--ink-3); }

/* The two states the panel can open on once it can take money: asking for an
   address, or ready to charge. An author `display` beats the browser's own
   rule for [hidden], so both have to say so themselves. */
.presale__gate, .presale__ready { display: flex; flex-direction: column; gap: var(--s3); align-items: flex-start; }
.presale__gate[hidden], .presale__ready[hidden] { display: none; }
.presale__gate .presale__note, .presale__ready p { margin: 0; }

/* A form with more than one field, so it stacks with visible labels rather
   than hiding them the way the one-line subscribe row does. */
.signup { display: flex; flex-direction: column; gap: var(--s3); align-items: stretch; width: min(26rem, 100%); }
.signup__field { display: flex; flex-direction: column; gap: .3rem; margin: 0; }
.signup__field label { font-size: .78rem; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-3); }
.signup__field input,
.signup__field select,
.signup__field textarea {
  font: inherit; padding: .6rem .7rem;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px;
  width: 100%; box-sizing: border-box;
}
.signup__field textarea { resize: vertical; min-height: 7rem; line-height: 1.55; }
/* The arrow a native select draws is the one bit of the control a page cannot
   restyle, so the rest is left alone rather than half-replaced. */
.signup__field select { appearance: none; padding-right: 2rem;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%),
                    linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: calc(100% - 1rem) 55%, calc(100% - .72rem) 55%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
.signup__field input:focus-visible,
.signup__field select:focus-visible,
.signup__field textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.signup__opt { font-size: .85em; letter-spacing: 0; text-transform: none; color: var(--ink-4); }
/* The contact form has more in it than a sign-up row, so it gets more room. */
.contact { width: min(38rem, 100%); }
.contact[hidden] { display: none; }
/* Pairs sit side by side where there is room: first and last name, postcode
   and city. One column on a phone. */
.signup__row { display: grid; grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); gap: var(--s3); }
.signup button { align-self: flex-start; }
@media (max-width: 40rem) {
  /* 16px or iOS zooms the page on focus. */
  .signup__field input { font-size: 16px; }
}

@media (max-width: 40rem) {
  .presale { padding: var(--s5); }
  .presale__now { font-size: 1.8rem; }
}
.chk__start .btn { align-self: flex-start; }

.chk__result h2 { margin-top: 0; }
.chk__score { font-size: .72rem; letter-spacing: .05em; color: var(--ink-4); }
.chk__skills { display: flex; flex-direction: column; gap: var(--s2); margin: var(--s5) 0; }
.chk__skill { display: grid; grid-template-columns: minmax(8rem, 11rem) 1fr auto; gap: var(--s3); align-items: center; }
.chk__skill-label { font-size: .88rem; color: var(--ink-2); }
.chk__skill-bar { height: 6px; background: var(--line); border-radius: 3px; overflow: hidden; }
.chk__skill-bar i { display: block; height: 100%; background: var(--moss); }
.chk__skill-bar i[data-weak='1'] { background: var(--ember); }
.chk__skill-n { font-size: .7rem; color: var(--ink-4); }
.chk__reading { margin: var(--s5) 0; }
.chk__reading h3 { font-size: 1rem; }
.chk__reading li { margin-bottom: .35em; line-height: 1.5; }
.chk__acts { display: flex; gap: var(--s3); flex-wrap: wrap; margin: var(--s5) 0 var(--s4); }

@media (max-width: 34rem) {
  .chk__skill { grid-template-columns: 1fr auto; }
  .chk__skill-bar { grid-column: 1 / -1; }
}

/* ----------------------------------------------------------------- heart
   Sits in the gutter between the article and its comments, as one quiet
   row. It is hidden until the endpoint answers, so a deployment without the
   counters configured shows nothing rather than a control that does not
   work. */
.pulse {
  display: flex; align-items: center; gap: var(--s3);
  max-width: var(--measure); margin: 0 auto var(--s6);
  padding: var(--gutter) 0 0; border-top: 1px solid var(--line);
}
.pulse[hidden] { display: none; }
.pulse__btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: .45rem .8rem; min-height: 2.25rem;
  color: var(--ink-3); background: var(--paper-2);
  border: 1px solid var(--line); border-radius: var(--r-pill); clip-path: var(--clip-sm);
  cursor: pointer;
  transition: color .2s var(--ease), border-color .2s var(--ease), transform .2s var(--ease);
}
.pulse__btn:hover { color: var(--accent); border-color: var(--accent); }
.pulse__btn .icon { width: 1.15rem; height: 1.15rem; transition: fill .2s var(--ease), transform .25s var(--ease); }
/* The same outline, filled. The drawing is one closed path for this reason:
   nothing moves between the two states, it only gains mass. */
.pulse[data-on='1'] .pulse__btn { color: var(--accent); border-color: var(--accent); }
.pulse[data-on='1'] .pulse__btn .icon { fill: currentColor; }
.pulse__btn:active .icon { transform: scale(.82); }
.pulse__btn:disabled { cursor: default; }
.pulse__say { font-size: .85rem; color: var(--ink-4); }
/* Inside a story, where the card supplies the frame and the rule above it
   would be a second line across a box that already has one. */
.pulse--reader {
  max-width: none; margin: var(--s2) 0 0; padding: 0;
  border-top: 0; align-self: flex-start;
}

/* A finger needs a bigger target than a cursor does. */
@media (pointer: coarse) {
  .pulse__btn { min-height: 2.75rem; padding-inline: 1rem; }
}
@media (prefers-reduced-motion: reduce) {
  .pulse__btn, .pulse__btn .icon { transition: none; }
}

/* -------------------------------------------------------------- comments
   The section starts hidden and the app reveals only the parts that have
   something in them, so a post with no comments yet shows an invitation
   rather than a count of zero. */
.cmt__list, .cmt__form { max-width: var(--measure); }
.cmt__h { font-family: var(--font-display); font-size: var(--t-h3); margin: 0 0 var(--s4); }
.cmt__list { margin-bottom: var(--s7); }
.cmt__item { padding: var(--s4) 0; border-top: 1px solid var(--line); }
.cmt__by { display: flex; align-items: baseline; gap: .6rem; margin: 0 0 .4rem; }
.cmt__by b { font-size: .95rem; }
.cmt__by time { font-family: var(--font-mono); font-size: .68rem; letter-spacing: .06em; color: var(--ink-4); }
.cmt__body { color: var(--ink-2); line-height: 1.65; overflow-wrap: anywhere; }
.cmt__note { color: var(--ink-3); font-size: .88rem; margin: 0 0 var(--s4); }
.cmt__row { display: grid; gap: var(--s3); grid-template-columns: 1fr 1fr; }
@media (max-width: 34rem) { .cmt__row { grid-template-columns: 1fr; } }
.cmt__field { display: block; margin-bottom: var(--s3); }
.cmt__field > span {
  display: block; margin-bottom: .35rem; font-family: var(--font-mono);
  font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-3);
}
.cmt__field > span i { font-style: normal; color: var(--ink-4); text-transform: none; letter-spacing: 0; }
.cmt__field input, .cmt__field textarea {
  width: 100%; font: inherit; font-size: 1rem; padding: .6rem .8rem;
  background: var(--paper); border: 1px solid var(--line); color: var(--ink);
  border-radius: var(--r-input); resize: vertical;
}
/* --r-input is a full pill in some skins, which suits a single line and
   turns a tall box into a blob. The textarea takes the panel radius. */
.cmt__field textarea { border-radius: var(--r-sm); padding: .7rem .9rem; }
.cmt__field input:focus-visible, .cmt__field textarea:focus-visible { outline: none; border-color: var(--accent); }

/* The honeypot. Off-screen rather than display:none, because some bots skip
   hidden fields but happily fill one that is merely out of view. */
.cmt__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.cmt__actions { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; margin-top: var(--s4); }
.cmt__msg { font-size: .88rem; color: var(--ink-3); }
.cmt__msg[data-state='ok'] { color: var(--moss, var(--accent)); }
.cmt__msg[data-state='bad'] { color: var(--ember, var(--accent)); }

/* Moderation queue in the panel. */
.cq { display: grid; }
.cq__item { padding: var(--s4); border-top: 1px solid var(--line); transition: opacity .2s var(--ease); }
.cq__head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3); flex-wrap: wrap; }
.cq__head .badge { margin-left: .4rem; }
.cq__on { margin: .3rem 0 var(--s3); font-size: .82rem; color: var(--ink-3); }
.cq__body {
  white-space: pre-wrap; overflow-wrap: anywhere; color: var(--ink-2);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--s3); font-size: .92rem; line-height: 1.6;
}
.cq__acts { display: flex; gap: var(--s2); margin-top: var(--s3); flex-wrap: wrap; }

/* A reply from the author, tucked under the comment it answers. */
.cmt__reply { margin: var(--s3) 0 0 var(--s4); padding-left: var(--s4); border-left: 2px solid var(--accent); }
.cmt__tag {
  font-family: var(--font-mono); font-size: .58rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); border: 1px solid currentColor; border-radius: var(--r-pill);
  padding: .1rem .4rem; line-height: 1.4;
}

/* Replying from the panel. */
.cq__reply { margin-top: var(--s3); padding-left: var(--s3); border-left: 2px solid var(--accent); font-size: .9rem; color: var(--ink-2); }
.cq__reply b { display: block; font-size: .62rem; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); margin-bottom: .25rem; }
.cq__replyform { margin-top: var(--s3); }
.cq__replyform textarea {
  width: 100%; font: inherit; font-size: .92rem; padding: .6rem .8rem; resize: vertical;
  background: var(--paper); border: 1px solid var(--line); color: var(--ink); border-radius: var(--r-sm);
}

/* ------------------------------------------------- story edge tapping
   Tap the left or right third to move between stories, as a phone expects.
   Touch only: on a pointer device the buttons under the card are the
   obvious control, and invisible click targets would be a trap. */
.reader__tap {
  display: none; position: absolute; top: 0; bottom: 0; width: 30%;
  border: 0; background: none; padding: 0; margin: 0; z-index: 1;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.reader__tap--prev { left: 0; }
.reader__tap--next { right: 0; }
@media (pointer: coarse) { .reader__tap { display: block; } }

/* The real controls stay above the zones, so Close, the bars and any link
   in a story still take the tap that lands on them. */
.reader__bars, .reader__nav { position: relative; z-index: 3; }
.reader__body a, .reader__body button { position: relative; z-index: 3; }

/* Story controls on the picture: back and forward on the edges, close in the
   top corner. Faint at rest so the picture is the thing you look at, full
   strength the moment the pointer is on the card. On a touch screen there is
   no hover to bring them up, so they stay readable. */
.reader__ctl {
  position: absolute; z-index: 3;
  width: 2.4rem; height: 2.4rem; display: grid; place-items: center;
  border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(0, 0, 0, .5); color: #fff; backdrop-filter: blur(4px);
  opacity: .75;
  transition: opacity .2s var(--ease), background .15s var(--ease);
}
.reader__ctl svg { width: 1.15rem; height: 1.15rem; }
.reader__ctl--prev { left: .6rem; top: 50%; transform: translateY(-50%) scaleX(-1); }
.reader__ctl--next { right: .6rem; top: 50%; transform: translateY(-50%); }
.reader__ctl--close { right: .6rem; top: .6rem; }
.reader__ctl:hover { background: rgba(0, 0, 0, .78); opacity: 1; }
.reader__ctl:focus-visible { opacity: 1; }
/* Nothing to go back to, or nowhere further: still there, visibly spent. */
.reader__ctl[disabled] { opacity: .22; cursor: default; pointer-events: none; }
@media (hover: hover) {
  .reader__ctl { opacity: .38; }
  .reader__card:hover .reader__ctl { opacity: .85; }
  .reader__card:hover .reader__ctl[disabled] { opacity: .22; }
}

/* Sound toggle on a story clip. Above the tap zones, like the other
   controls, and beside the close button rather than under it. */
.story__sound {
  position: absolute; right: 3.3rem; top: .75rem; z-index: 3;
  width: 2.1rem; height: 2.1rem; display: grid; place-items: center;
  border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(0, 0, 0, .55); color: #fff; backdrop-filter: blur(4px);
  transition: background .15s var(--ease);
}
.story__sound:hover { background: rgba(0, 0, 0, .75); }
.story__sound svg { width: 1.05rem; height: 1.05rem; }

/* Formatting bar above a markup textarea in the panel. */
.mkbar { display: flex; align-items: center; gap: .15rem; margin-bottom: .35rem; }
.mkbar__b {
  display: grid; place-items: center; width: 1.85rem; height: 1.85rem;
  border: 1px solid var(--line); background: var(--paper-2); color: var(--ink-2);
  border-radius: var(--r-sm); cursor: pointer;
  transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.mkbar__b:hover { background: var(--paper-3); color: var(--ink); border-color: var(--line-2); }
.mkbar__b svg { width: .95rem; height: .95rem; }
.mkbar__note {
  margin-left: auto; font-family: var(--font-mono); font-size: .58rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-4);
}
