@charset "UTF-8";
/* ==========================================================================
   SCALE-TIME DYNAMICS — stylesheet
   --------------------------------------------------------------------------
   Brand:  Public Sans · Turquoise #00A0A8 · Graphite #1B1E23 · Bone #F4F3F0
   No build step, no preprocessor, no framework. Plain CSS.

   CONTENTS
     1. Fonts
     2. Color & size tokens          ← change colors here, once
     3. Reset
     4. Typography
     5. Layout helpers
     6. Header & navigation
     7. Footer
     8. Hero
     9. Buttons
    10. Cards
    11. Prose (article & page text)
    12. Audio player
    13. Resource grid
    14. Table of contents
    15. Home page
    16. Scale-Time Theory page
    17. About page
    18. Contact page
    19. Legal pages
    20. 404
   ========================================================================== */


/* ==========================================================================
   1. FONTS
   Public Sans, self-hosted from /fonts. Nothing is requested from Google.
   ========================================================================== */

@font-face {
  font-family: 'Public Sans';
  src: url('fonts/public-sans.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Public Sans';
  src: url('fonts/public-sans-italic.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}


/* ==========================================================================
   2. TOKENS
   Every color and size the site uses. Change a value here and it changes
   everywhere. The dark theme is the same list of names with different values.
   ========================================================================== */

:root {
  /* --- Brand constants (identical in both themes) --- */
  --brand-turquoise: #00a0a8;
  --brand-graphite: #1b1e23;
  --brand-bone: #f4f3f0;

  /* --- Light theme --- */
  --bg: #f4f3f0;
  --bg-sunken: #eceae5;
  --surface: #ffffff;
  --surface-2: #f9f8f6;

  --text: #1b1e23;
  --text-muted: #5c6169;
  --text-faint: #868b93;

  --line: #dedbd4;
  --line-strong: #c8c4bb;

  --accent: #00767d;          /* links — darker so it passes contrast on bone */
  --accent-hover: #005e64;
  --accent-brand: #00a0a8;    /* rules, fills, decoration */
  --accent-soft: rgba(0, 160, 168, 0.10);

  --header-bg: rgba(244, 243, 240, 0.85);
  --shadow-s: 0 1px 2px rgba(27, 30, 35, .05), 0 2px 8px rgba(27, 30, 35, .04);
  --shadow-m: 0 2px 4px rgba(27, 30, 35, .05), 0 12px 32px rgba(27, 30, 35, .08);
  --selection: rgba(0, 160, 168, .22);

  /* --- Type --- */
  --font: 'Public Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, monospace;

  /* Fluid sizes: min at 320px wide, max at ~1400px, no media queries needed */
  --size--1: clamp(0.83rem, 0.80rem + 0.14vw, 0.92rem);
  --size-0:  clamp(1.03rem, 1.00rem + 0.16vw, 1.14rem);
  --size-1:  clamp(1.19rem, 1.13rem + 0.30vw, 1.38rem);
  --size-2:  clamp(1.42rem, 1.31rem + 0.55vw, 1.79rem);
  --size-3:  clamp(1.72rem, 1.51rem + 1.03vw, 2.42rem);
  --size-4:  clamp(2.07rem, 1.71rem + 1.79vw, 3.27rem);
  --size-5:  clamp(2.49rem, 1.90rem + 2.95vw, 4.42rem);

  /* --- Spacing --- */
  --space-2xs: 0.5rem;
  --space-xs:  0.75rem;
  --space-s:   1rem;
  --space-m:   1.5rem;
  --space-l:   2.25rem;
  --space-xl:  3.5rem;
  --space-2xl: 5rem;

  /* --- Measurements --- */
  --measure: 68ch;        /* comfortable reading width */
  --container: 74rem;
  --radius-s: 4px;
  --radius-m: 8px;
  --radius-l: 14px;
  --ease: cubic-bezier(.22, .61, .36, 1);

  color-scheme: light dark;
}

/* --- Dark theme -----------------------------------------------------------
   Applied automatically when the visitor's system is set to dark. There is
   no switch and no JavaScript: the browser tells us, we respond.
   -------------------------------------------------------------------------- */

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14171b;
    --bg-sunken: #101317;
    --surface: #1b1e23;
    --surface-2: #22262c;

    --text: #e9e7e2;
    --text-muted: #a2a8b0;
    --text-faint: #767d86;

    --line: #2c3138;
    --line-strong: #3b414a;

    --accent: #2bc0c8;        /* lighter so it passes contrast on graphite */
    --accent-hover: #59d4da;
    --accent-brand: #00a0a8;
    --accent-soft: rgba(0, 160, 168, .16);

    --header-bg: rgba(20, 23, 27, .85);
    --shadow-s: 0 1px 2px rgba(0, 0, 0, .22);
    --shadow-m: 0 2px 6px rgba(0, 0, 0, .20), 0 14px 40px rgba(0, 0, 0, .28);
    --selection: rgba(43, 192, 200, .28);
  }
}


/* ==========================================================================
   3. RESET
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
}

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

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--size-0);
  font-weight: 400;
  line-height: 1.65;
  letter-spacing: -.006em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

main { flex: 1; }

::selection { background: var(--selection); }

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

a {
  color: var(--accent);
  text-underline-offset: .18em;
  text-decoration-thickness: 1px;
  transition: color .15s var(--ease);
}
a:hover { color: var(--accent-hover); }

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

hr { border: 0; height: 1px; background: var(--line); }


/* ==========================================================================
   4. TYPOGRAPHY
   ========================================================================== */

h1, h2, h3, h4 {
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.022em;
  text-wrap: balance;
}

h1 { font-size: var(--size-4); font-weight: 800; }
h2 { font-size: var(--size-2); }
h3 { font-size: var(--size-1); }

p { text-wrap: pretty; }


/* ==========================================================================
   5. LAYOUT HELPERS
   ========================================================================== */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 5vw, 3rem);
}

.section       { padding-block: clamp(var(--space-l), 5.5vw, var(--space-2xl)); }
.section-roomy { padding-block: clamp(var(--space-xl), 8vw, 7.5rem); }
.section-tight { padding-block: clamp(var(--space-m), 4vw, var(--space-xl)); }

.narrow { max-width: var(--measure); margin-inline: auto; }

/* `clip-path` rather than the old `clip: rect(0 0 0 0)`: `clip` is deprecated, and the
   space-separated rect() form it was written in was never valid CSS2 either (that syntax
   wants commas). `inset(50%)` is the current idiom and needs no legacy fallback here. */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100%;
  left: 1rem;
  z-index: 99;
  padding: .6rem 1rem;
  border-radius: var(--radius-s);
  background: var(--accent-brand);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { top: 1rem; color: #fff; }

/* Section heading block */
.sec-head { max-width: 54ch; margin-block-end: var(--space-l); }
.sec-head h2 { font-size: var(--size-3); letter-spacing: -.028em; }
.sec-head p  { margin-block-start: var(--space-s); color: var(--text-muted); }

.sec-head-row {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: var(--space-m);
  max-width: none;
}


/* ==========================================================================
   6. HEADER & NAVIGATION
   On narrow screens the nav simply wraps onto a second line and the header
   stops sticking. No hamburger, no toggle, no script — nothing to break.
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--header-bg);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--line);
}

.site-header .container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .4rem var(--space-m);
  padding-block: .85rem;
}

/* --- Wordmark ---
   Per the logo sheet: mark, then "Scale-Time" 700, then "Dynamics" 800 turquoise.
   The lockup ends on "Dynamics". The sheet's entity variant, which sets the company
   suffix at 500 / 0.6em / +0.06em tracking, is reserved for legal naming and is not
   used anywhere on this site. */
.wordmark {
  display: inline-flex;
  align-items: baseline;
  font-size: 1.15rem;
  line-height: 1;
  letter-spacing: -.01em;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  transition: opacity .18s var(--ease);
}
.wordmark:hover { opacity: .75; color: var(--text); }
.wordmark b  { font-weight: 800; color: var(--accent-brand); }
/* .253em, not the .3em the earlier build used. Measured off the sheet artwork:
   the ink gap between "Scale-Time" and "Dynamics" is 0.508 x cap height, and .3em
   overshot it by a fifth. */
.wordmark i  { font-weight: 700; font-style: normal; margin-inline-end: .253em; }

/* The mark. These four numbers were re-measured off the sheet artwork at 600dpi
   rather than read off its written rule, because the two disagree — the same way
   the gap did. Artwork over prose.

     height        1.65 x cap height, not the 1.50 the sheet's note states.
                   Public Sans caps are .723em, so 1.65 x .723 = 1.193em. The disk
                   is a circle: at 1.50 it measures right and reads small, because
                   a circle needs overshoot to match a flat-topped cap.
     top           .244em. Centering the disk geometrically on the cap band gives
                   H/2 - .3615 = .235em; the artwork sits it .009em lower, which is
                   the optical correction, not a rounding error.
     gap to text   .48em, giving an ink gap of 0.745 x cap height.

   Verified by overlay against the sheet at 600dpi: mark/cap, disk center, and both
   gaps all land inside the spread between the light and dark artwork. Everything
   hangs off font-size, so scaling the lockup means changing that alone.

   Its sigma is a knockout, so the counters pick up whatever ground it sits on. */
.wordmark img {
  height: 1.193em;
  width: auto;
  margin-inline-end: .48em;
  position: relative;
  top: .244em;
}

/* Optical centering of the lockup in the header bar.

   The mark is 1.193em tall and baseline-aligned, so it sets the flex line's top well
   above the cap line of the text beside it; its .244em nudge is `position: relative`,
   which moves ink and not the box. The lockup's box therefore carries empty space at
   the top, and centering that box in the header leaves everything visible sitting low.
   Measured at 1.15rem: the wordmark's text center fell 3.41px below the nav's.

   -.185em brings it to within 0.02px of the nav text. Scoped to the header, because
   the footer lockup sits in normal flow above its tagline and must not move. If the
   mark's height or the wordmark font-size ever changes, re-measure this number. */
.site-header .wordmark {
  position: relative;
  top: -.185em;
}

.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .1rem .15rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav a {
  display: block;
  padding: .4rem .7rem;
  border-radius: var(--radius-m);
  font-size: .92rem;
  font-weight: 500;
  letter-spacing: -.008em;
  color: var(--text-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color .18s var(--ease), background .18s var(--ease);
}
.site-nav a:hover { color: var(--text); background: var(--accent-soft); }

/* The current page. Add class="here" to the matching link on each page. */
.site-nav a.here { color: var(--text); font-weight: 600; }

@media (max-width: 46rem) {
  .site-header { position: static; }
  .site-header .container { justify-content: center; padding-block: .9rem; }
  .site-nav { width: 100%; }
  .site-nav ul { justify-content: center; }
  .site-nav a { padding: .35rem .55rem; font-size: .88rem; }
}


/* ==========================================================================
   7. FOOTER
   ========================================================================== */

.site-footer {
  margin-block-start: auto;
  padding-block: var(--space-xl) var(--space-m);
  background: var(--brand-graphite);
  border-top: 2px solid var(--brand-turquoise);
  color: #b6bcc4;
  font-size: var(--size--1);
}

.site-footer .wordmark { color: var(--brand-bone); }
.site-footer .wordmark b { color: var(--brand-turquoise); }
.site-footer .wordmark:hover { color: var(--brand-bone); }

.footer-top {
  display: grid;
  grid-template-columns: minmax(14rem, 1fr) 2fr;
  gap: var(--space-xl);
  align-items: start;
}

.footer-tagline {
  margin-block-start: .9rem;
  max-width: 22ch;
  color: #8b929b;
  line-height: 1.5;
}

.footer-cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-m);
}

.footer-cols h2 {
  margin-block-end: .9rem;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--brand-turquoise);
}

.footer-cols ul { display: grid; gap: .55rem; margin: 0; padding: 0; list-style: none; }

.footer-cols a {
  color: #b6bcc4;
  text-decoration: none;
  overflow-wrap: anywhere;
  transition: color .16s var(--ease);
}
.footer-cols a:hover { color: #fff; text-decoration: underline; text-underline-offset: .2em; }

.footer-base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: .5rem var(--space-m);
  margin-block-start: var(--space-xl);
  padding-block-start: var(--space-m);
  border-top: 1px solid rgba(255, 255, 255, .09);
  color: #767d86;
  font-size: .8rem;
}

/* The copyright line sits on the footer's graphite in BOTH themes, so a link in
   it must not inherit the global `--accent`: that token is tuned for the page
   ground and goes dark teal on graphite in light mode.

   It takes the line's own color instead, so it reads as part of the sentence
   and not as something to click. That is deliberate (André, Sept 2026): the
   domain is there for the record, and it resolves to this same site, so a
   reader who never notices it loses nothing. `inherit` rather than a literal
   #767d86, so it follows `.footer-base` if that color ever moves.

   Discoverability is carried entirely by the two states below: the hover pair,
   and the global `:focus-visible` outline, which is what a keyboard user
   tabbing into the footer gets. Do not remove either. */
.footer-base a {
  color: inherit;
  text-decoration: none;
  transition: color .16s var(--ease);
}
.footer-base a:hover { color: #fff; text-decoration: underline; text-underline-offset: .2em; }

@media (max-width: 52rem) {
  .footer-top  { grid-template-columns: 1fr; gap: var(--space-l); }
  .footer-cols { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: var(--space-l) var(--space-m); }
}


/* ==========================================================================
   8. HERO
   A full-bleed photo with a dark gradient over it and the title on top.
   ========================================================================== */

.hero {
  position: relative;
  display: grid;
  align-items: end;
  isolation: isolate;
  min-height: min(46svh, 26rem);
  padding-block: var(--space-2xl) var(--space-xl);
  color: var(--brand-bone);
}

.hero-media {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: var(--brand-graphite);
}

.hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Dark wash so white text stays readable over any photo.
   The wash is pure black, not the graphite of the dark theme: a gray veil desaturates
   the photo underneath and reads as washed out, while black only darkens it. */
.hero-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
    rgba(0, 0, 0, .83) 0%,
    rgba(0, 0, 0, .63) 35%,
    rgba(0, 0, 0, .29) 70%,
    rgba(0, 0, 0, .41) 100%);
}


.hero h1 {
  max-width: 20ch;
  font-size: var(--size-4);
  letter-spacing: -.028em;
  line-height: 1.06;
}

.hero-sub {
  margin-block-start: 1.1rem;
  max-width: 48ch;
  font-size: var(--size-1);
  line-height: 1.55;
  letter-spacing: -.012em;
  /* Lifted from .82 / .7: over the hero wash these read dimmer than the h1 beside
     them, which is opaque bone. Contrast was never the problem (both cleared AA
     comfortably); the hierarchy just sat too low. Not theme-dependent, because the
     hero is a photo under a black wash in both themes. */
  color: rgba(244, 243, 240, .92);
}

.hero-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5em;
  margin-block-start: var(--space-m);
  font-size: var(--size--1);
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: rgba(244, 243, 240, .82);
}

/* Page header with no photo */
.hero-plain {
  min-height: 0;
  padding-block: clamp(var(--space-xl), 7vw, var(--space-2xl)) var(--space-m);
  border-bottom: 1px solid var(--line);
  color: var(--text);
}
.hero-plain .hero-sub { color: var(--text-muted); }

@media (max-width: 40rem) {
  .hero { min-height: 18rem; }
}


/* ==========================================================================
   9. BUTTONS
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  gap: .55em;
  padding: .68em 1.25em;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-m);
  color: var(--text);
  font-size: var(--size--1);
  font-weight: 600;
  text-decoration: none;
  transition: background .18s var(--ease), border-color .18s var(--ease),
              color .18s var(--ease), transform .18s var(--ease);
}
.btn:hover { border-color: var(--accent-brand); color: var(--text); transform: translateY(-1px); }

/* `border-color: transparent` rather than repeating the fill: the background paints under
   the border box, so the button looks identical and keeps the same outer size as the
   bordered `.btn` variants beside it. */
.btn-primary {
  background: var(--accent-brand);
  border-color: transparent;
  color: #fff;
}
.btn-primary:hover { background: #00b3bc; border-color: transparent; color: #fff; }

.btn-ghost { background: var(--surface); border-color: var(--line); }

/* On a photo background */
.btn-onphoto {
  color: var(--brand-bone);
  border-color: rgba(244, 243, 240, .32);
  backdrop-filter: blur(6px);
}
.btn-onphoto:hover { color: var(--brand-bone); background: rgba(244, 243, 240, .1); }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--space-2xs); }


/* ==========================================================================
   10. CARDS
   ========================================================================== */

.card {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  color: inherit;
  text-decoration: none;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-m);
  border-color: var(--line-strong);
  color: inherit;
}

.card-media { overflow: hidden; background: var(--bg-sunken); aspect-ratio: 16 / 9; }
.card-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s var(--ease); }
.card:hover .card-media img { transform: scale(1.035); }

.card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: .5rem;
  padding: var(--space-m);
}

.card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .45em;
  font-size: .78rem;
  font-weight: 500;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.card-body h3 {
  font-size: var(--size-1);
  line-height: 1.2;
  letter-spacing: -.022em;
  color: var(--text);
}

.card-sub {
  margin-block-start: -.15rem;
  font-size: var(--size-0);
  font-weight: 500;
  line-height: 1.4;
  color: var(--accent);
}

.card-desc { font-size: .95rem; line-height: 1.6; color: var(--text-muted); }

.card-more {
  margin-block-start: auto;
  padding-block-start: var(--space-s);
  font-size: .85rem;
  font-weight: 600;
  color: var(--accent);
}
.card:hover .card-more { text-decoration: underline; text-underline-offset: .2em; }

/* Wide variant for the first article on the home page */
@media (min-width: 56rem) {
  .card-wide { display: grid; grid-template-columns: 1.05fr 1fr; }
  .card-wide .card-media { aspect-ratio: auto; height: 100%; min-height: 22rem; }
  .card-wide .card-body { justify-content: center; padding: var(--space-l); }
  .card-wide .card-body h3 { font-size: var(--size-3); letter-spacing: -.026em; }
  .card-wide .card-sub { font-size: var(--size-1); }
  .card-wide .card-desc { font-size: var(--size-0); }
  .card-wide .card-more { margin-block-start: var(--space-s); padding-block-start: 0; }
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
  gap: var(--space-m);
}


/* ==========================================================================
   11. PROSE — the running text of articles and pages
   ========================================================================== */

.prose {
  max-width: var(--measure);
  font-size: var(--size-0);
  line-height: 1.75;
}

.prose > * + * { margin-block-start: 1.35em; }

.prose h2 {
  margin-block-start: 2.2em;
  margin-block-end: 0;
  font-size: var(--size-2);
  letter-spacing: -.024em;
  scroll-margin-top: 5.5rem;
}

.prose h3 { margin-block-start: 1.9em; margin-block-end: -.5em; font-size: var(--size-1); }
.prose h2:first-child, .prose h3:first-child { margin-block-start: 0; }

.prose a {
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 40%, transparent);
  text-underline-offset: .2em;
}
.prose a:hover { text-decoration-color: currentColor; }

.prose strong { font-weight: 700; }

.prose ul, .prose ol { padding-inline-start: 1.35em; }
.prose li + li { margin-block-start: .5em; }
.prose li::marker { color: var(--text-muted); }

/* Quotes read at the same size as the running text; the rule, the italic and
   the softer color are what set them apart. */
.prose blockquote {
  padding: .1em 0 .1em 1.4em;
  border-inline-start: 2px solid var(--accent-brand);
  font-size: var(--size-0);
  font-style: italic;
  line-height: 1.75;
  letter-spacing: -.006em;
  color: var(--text-muted);
}
.prose blockquote cite {
  display: block;
  margin-block-start: .7em;
  font-size: var(--size--1);
  font-style: normal;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.prose img { border-radius: var(--radius-m); box-shadow: var(--shadow-s); }
.prose figure { margin-block: 2em; }
.prose figcaption {
  margin-block-start: .75rem;
  font-size: var(--size--1);
  line-height: 1.5;
  color: var(--text-muted);
}

.prose code {
  padding: .15em .4em;
  border-radius: var(--radius-s);
  background: var(--accent-soft);
  font-family: var(--font-mono);
  font-size: .9em;
}

.prose hr { margin-block: 2.5em; }

/* Opening paragraph of an article — add class="lead"
   Full --text, not --text-muted: a lead is the largest type in the column, and
   setting it dimmer than the body that follows reads as greyed out rather than
   emphasized. The size and the tighter tracking are what mark it. This shows up
   worst on the dark theme, where muted drops to #a2a8b0 against #e9e7e2 body. */
.prose .lead {
  font-size: var(--size-1);
  line-height: 1.6;
  letter-spacing: -.014em;
  color: var(--text);
}

/* Article footer: tags, share links */
.article-foot {
  display: grid;
  gap: var(--space-s);
  max-width: var(--measure);
  margin-block-start: var(--space-xl);
  padding-block-start: var(--space-m);
  border-top: 1px solid var(--line);
}

.tags { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0; padding: 0; list-style: none; }
.tags li {
  padding: .25em .7em;
  border-radius: 999px;
  background: var(--accent-soft);
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--accent);
}

.article-foot p { font-size: var(--size--1); color: var(--text-faint); }
.article-foot p a { color: var(--text-muted); }

.related {
  padding-block: var(--space-xl);
  border-top: 1px solid var(--line);
  background: var(--bg-sunken);
}
.related h2 { margin-block-end: var(--space-m); font-size: var(--size-2); }


/* ==========================================================================
   12. AUDIO PLAYER
   The markup ships a normal <audio controls>. site.js swaps the browser's
   default controls for the styled player below. With JavaScript off, the
   native player shows instead and everything still works.
   ========================================================================== */

/* Ground, border and radius match `.release` on the book page, so an audio box and
   a book card read as the same kind of panel in both themes. The seek thumb's ring
   below is painted in the same token: it exists to separate the thumb from whatever
   the box is sitting on, so it has to move with the background. */
.audio-box {
  max-width: var(--measure);
  padding: var(--space-m);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
}

.audio-box h2,
.audio-label {
  display: flex;
  align-items: center;
  gap: .5em;
  margin-block-end: .9rem;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.audio-label svg { flex: none; width: 1.2em; height: 1.2em; color: var(--accent-brand); }

/* Fallback player, shown only when site.js has not run */
.audio-box audio { width: 100%; height: 2.75rem; }
.audio-box audio.is-enhanced { display: none; }

/* --- The styled player --- */
.player {
  display: flex;
  align-items: center;
  gap: var(--space-s);
}

.player__btn {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.9rem;
  height: 2.9rem;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  border-radius: 50%;
  background: var(--accent-brand);
  color: #fff;
  box-shadow: none;
  -webkit-tap-highlight-color: transparent;
  transition: background .18s var(--ease), transform .18s var(--ease);
}
.player__btn svg { width: 1.35rem; height: 1.35rem; fill: currentColor; }
.player__btn:hover { background: #00b3bc; transform: scale(1.04); }
/* No press effect: the button must not shrink, square off or pick up a shadow. */
.player__btn:active { box-shadow: none; }
.player__btn:focus-visible { border-radius: 50%; }

/* Seek bar. --played is set by site.js and fills the track up to the thumb. */
.player__seek {
  flex: 1;
  min-width: 0;
  height: 1.15rem;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.player__seek::-webkit-slider-runnable-track {
  height: 5px;
  border-radius: 999px;
  background: linear-gradient(to right,
    var(--accent-brand) 0 var(--played, 0%), var(--line-strong) var(--played, 0%) 100%);
}
.player__seek::-moz-range-track {
  height: 5px;
  border-radius: 999px;
  background: var(--line-strong);
}
.player__seek::-moz-range-progress {
  height: 5px;
  border-radius: 999px;
  background: var(--accent-brand);
}

.player__seek::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  margin-top: -4.5px;
  border: 3px solid var(--bg-sunken);
  border-radius: 50%;
  background: var(--accent-brand);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
  transition: transform .15s var(--ease);
}
.player__seek::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border: 3px solid var(--bg-sunken);
  border-radius: 50%;
  background: var(--accent-brand);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
}
.player:hover .player__seek::-webkit-slider-thumb { transform: scale(1.25); }
.player__seek:focus-visible { outline: 2px solid var(--accent-brand); outline-offset: 4px; }

.player__time {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: .3em;
  font-family: var(--font-mono);
  font-size: .82rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}
.player__time b { font-weight: 600; color: var(--text); }
.player__time i { font-style: normal; opacity: .4; }

.audio-note {
  margin-block-start: .9rem;
  font-size: var(--size--1);
  line-height: 1.5;
  color: var(--text-faint);
}
.audio-note a { color: var(--text-muted); }

@media (max-width: 30rem) {
  .player { flex-wrap: wrap; }
  .player__seek { order: 3; flex-basis: 100%; }
}


/* ==========================================================================
   13. RESOURCE GRID — download / link tiles
   ========================================================================== */

.resources {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: var(--space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The tile itself promises no destination, so the same card can be a plain <div>
   that states something at the head of an article. Everything meaning "this leads
   somewhere" — the arrow, the clearance it needs, the hover lift — is scoped to
   `a.resource`, so a non-link card needs no modifier class and cannot inherit a
   false affordance by accident. */
.resource {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: .3rem;
  height: 100%;
  padding: var(--space-s);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
  color: var(--text);
  text-decoration: none;
  transition: border-color .2s var(--ease), background .2s var(--ease), transform .2s var(--ease);
}
a.resource { padding-inline-end: 2.6rem; }
a.resource:hover {
  border-color: var(--accent-brand);
  background: var(--surface-2);
  transform: translateY(-2px);
  color: var(--text);
}

.resource-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem; }
.resource-head b { font-size: .98rem; font-weight: 600; letter-spacing: -.012em; }

.resource-tag {
  padding: .12em .5em;
  border-radius: 999px;
  background: var(--accent-soft);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent);
}

.resource span.desc { font-size: .88rem; line-height: 1.5; color: var(--text-muted); }

a.resource::after {
  content: '→';
  position: absolute;
  top: var(--space-s);
  right: var(--space-s);
  color: var(--text-faint);
  transition: color .2s var(--ease), transform .2s var(--ease);
}
a.resource:hover::after { color: var(--accent); transform: translateX(2px); }
a.resource.external::after { content: '↗'; }


/* ==========================================================================
   14. TABLE OF CONTENTS (long pages)
   ========================================================================== */

.with-toc {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 15rem;
  gap: var(--space-xl);
  align-items: start;
}

.with-toc > .main { min-width: 0; max-width: var(--measure); }
.with-toc > .main > * + * { margin-block-start: var(--space-l); }

.toc {
  position: sticky;
  top: 5.5rem;
  padding-inline-start: var(--space-s);
  border-inline-start: 1px solid var(--line);
}

.toc h2 {
  margin-block-end: var(--space-s);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.toc ol { display: grid; gap: .55rem; margin: 0; padding: 0; list-style: none; }

.toc a {
  display: block;
  font-size: .86rem;
  line-height: 1.4;
  color: var(--text-muted);
  text-decoration: none;
}
.toc a:hover { color: var(--text); }

/* Set by the small scroll-spy script at the bottom of the two long pages.
   Delete the script and everything still works — you just lose the highlight. */
.toc a[aria-current='true'] { color: var(--accent); font-weight: 600; }

@media (max-width: 62rem) {
  .with-toc { grid-template-columns: 1fr; }
  .with-toc > .main { margin-inline: auto; }
  .toc { display: none; }
}


/* ==========================================================================
   15. HOME PAGE
   ========================================================================== */

.lede {
  position: relative;
  display: grid;
  align-items: center;
  isolation: isolate;
  min-height: min(88svh, 46rem);
  padding-block: var(--space-2xl);
  color: var(--brand-bone);
}

/* Pure black, two stacked washes. Every alpha was lightened by 20% of its own
   value in Sept 2026 (x0.8): .498/.398/.167 became .398/.318/.134, and the
   bottom wash .415 became .332. The stop positions and the 105deg angle are
   unchanged, so the shape of the wash is the same, only lighter. */
.lede .hero-media::after {
  background:
    linear-gradient(105deg, rgba(0,0,0,0.398) 0%, rgba(0,0,0,0.318) 42%, rgba(0,0,0,0.134) 100%),
    linear-gradient(to top, rgba(0,0,0,0.332), rgba(0,0,0,0) 45%);
}


.lede h1 {
  margin-block-start: var(--space-s);
  max-width: 15ch;
  font-size: var(--size-5);
  letter-spacing: -.032em;
  line-height: 1.02;
  /* Pure white, not the bone the rest of the hero inherits. The hero sits on a
     photograph under a black wash, so this reads the same in both themes and is
     deliberately not scoped to one of them. */
  color: #fff;
}

.lede p {
  margin-block-start: var(--space-m);
  max-width: 46ch;
  font-size: var(--size-1);
  line-height: 1.55;
  letter-spacing: -.012em;
  /* Pure white and fully opaque, matching the h1 above it. Size and weight carry
     the hierarchy here, not a difference in tint. */
  color: #fff;
}

.lede .btn-row { margin-block-start: var(--space-l); }

.pillars {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  gap: var(--space-m);
}

.pillar .card-media { aspect-ratio: 21 / 9; }
.pillar .card-body { padding-block-end: var(--space-l); }

.pillar h3 { font-size: var(--size-2); letter-spacing: -.024em; }
.pillar p { font-size: .97rem; line-height: 1.6; color: var(--text-muted); }

.quote-band {
  padding-block: clamp(var(--space-xl), 7vw, var(--space-2xl));
  background: var(--brand-graphite);
}

.quote-band blockquote {
  max-width: 26ch;
  margin-inline: auto;
  text-align: center;
  font-size: var(--size-3);
  font-weight: 700;
  line-height: 1.28;
  letter-spacing: -.026em;
  color: var(--brand-bone);
  text-wrap: balance;
}

.quote-band cite {
  display: block;
  margin-block-start: var(--space-m);
  font-size: var(--size--1);
  font-style: normal;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--brand-turquoise);
}

.cta {
  padding-block: var(--space-xl);
  border-top: 1px solid var(--line);
  background: var(--bg-sunken);
}

.cta .container {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m) var(--space-l);
}

.cta h2 { font-size: var(--size-2); letter-spacing: -.024em; }
.cta p {
  margin-block-start: .6rem;
  max-width: 52ch;
  font-size: .97rem;
  line-height: 1.6;
  color: var(--text-muted);
}


/* ==========================================================================
   16. SCALE-TIME THEORY PAGE
   ========================================================================== */

/* The status strip sits full width under the opening paragraph.
   The opening paragraph itself uses the ordinary body text style. */
.intro {
  max-width: var(--measure);
  font-size: var(--size-0);
  line-height: 1.75;
  letter-spacing: -.006em;
  color: var(--text);
}

/* Same ground as `.audio-box` and `.release`: the panels on this site read as one
   family, recessed from the page rather than raised off it. */
.status {
  padding: var(--space-m);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
}

.status dl {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: var(--space-m) var(--space-l);
  margin: 0;
}

.status dl > div { display: grid; gap: .3rem; align-content: start; }

.status dt {
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.status dd {
  margin: 0;
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -.012em;
  overflow-wrap: anywhere;
}

.status__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s) var(--space-m);
  margin-block-start: var(--space-m);
  padding-block-start: var(--space-m);
  border-top: 1px solid var(--line);
}

.status__doi {
  display: flex;
  align-items: baseline;
  gap: .6rem;
  font-size: .85rem;
  color: var(--text-muted);
}
.status__doi b {
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.axioms {
  padding-block: clamp(var(--space-xl), 7vw, var(--space-2xl));
  background: var(--bg-sunken);
  border-block: 1px solid var(--line);
  scroll-margin-top: 5rem;
}

.axiom-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: 1px;
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  overflow: hidden;
}

.axiom-grid li {
  display: flex;
  flex-direction: column;
  gap: .45rem;
  padding: var(--space-m);
  background: var(--bg);
  transition: background .2s var(--ease);
}
.axiom-grid li:hover { background: var(--surface); }

.axiom-grid b { font-size: .72rem; font-weight: 700; letter-spacing: .14em; color: var(--accent); }
.axiom-grid h3 { font-size: var(--size-0); letter-spacing: -.018em; line-height: 1.3; }
.axiom-grid p { font-size: .9rem; line-height: 1.6; color: var(--text-muted); }


/* ==========================================================================
   17. ABOUT PAGE
   ========================================================================== */

.about-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 18rem;
  gap: var(--space-xl);
  align-items: start;
}
.about-layout > .main { min-width: 0; max-width: var(--measure); }

.portrait { max-width: 20rem; margin: 0 0 var(--space-l); }
/* The portrait sits inside the prose column, level with the first paragraph
   rather than with the heading above it. */
.prose .portrait { margin-block: 1.35em var(--space-l); }
.portrait img { width: 100%; border-radius: var(--radius-l); box-shadow: var(--shadow-m); }
.portrait figcaption {
  margin-block-start: .7rem;
  font-size: var(--size--1);
  letter-spacing: .04em;
  color: var(--text-faint);
}

.side { position: sticky; top: 5.5rem; display: grid; gap: var(--space-m); }

.side-card {
  padding: var(--space-m);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
}

.side-card h2 {
  margin-block-end: var(--space-s);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
}

.side-card p { font-size: .88rem; line-height: 1.6; color: var(--text-muted); }
.side-card .btn { margin-block-start: var(--space-s); }

.timeline { display: grid; gap: .9rem; margin: 0; padding: 0; list-style: none; }
.timeline li {
  display: grid;
  gap: .15rem;
  padding-inline-start: var(--space-s);
  border-inline-start: 2px solid var(--line);
}
.timeline li:hover { border-inline-start-color: var(--accent-brand); }
.timeline b {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent);
}
.timeline span { font-size: .88rem; line-height: 1.5; color: var(--text-muted); }

.about-cta {
  margin-block-start: var(--space-xl);
  padding-block-start: var(--space-m);
  border-top: 1px solid var(--line);
}

@media (min-width: 40rem) {
  /* No `shape-outside` here. It was `inset(0 round var(--radius-l))`, and measuring the
     rendered line boxes with and without it showed every line of the surrounding prose in
     exactly the same place: a 14px corner arc is far smaller than one line box, so nothing
     ever reflows. It only cost a validator error. */
  .portrait {
    float: right;
    max-width: 15rem;
    margin-inline-start: var(--space-l);
    margin-block-start: .4rem;
  }
}

@media (max-width: 62rem) {
  .about-layout { grid-template-columns: 1fr; }
  .about-layout > .main { margin-inline: auto; }
  .side {
    position: static;
    width: 100%;
    max-width: var(--measure);
    margin-inline: auto;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  }
}


/* ==========================================================================
   18. CONTACT PAGE
   ========================================================================== */

.contact-block { padding-block-end: var(--space-l); border-bottom: 1px solid var(--line); }
.contact-block:last-child { padding-block-end: 0; border-bottom: 0; }

.contact-block h2 {
  margin-block-end: var(--space-s);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
}

.contact-list { display: grid; gap: .7rem; margin: 0; padding: 0; list-style: none; }
.contact-list li {
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: .5rem 1rem;
  align-items: baseline;
}
.contact-list span {
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.contact-list a { font-size: var(--size-0); font-weight: 500; overflow-wrap: anywhere; }

/* On this page the links are the content itself, not accents inside running text.
   Never underlined. They rest one step down from full strength and come up to it on
   hover, so the emphasis runs the opposite way to an ordinary link. */
.contact-block a { color: var(--text-muted); text-decoration: none; }
.contact-block a:hover { color: var(--text); text-decoration: none; }

address { font-style: normal; line-height: 1.7; }

@media (max-width: 34rem) {
  .contact-list li { grid-template-columns: 1fr; gap: .1rem; }
}


/* ==========================================================================
   19. LEGAL PAGES
   ========================================================================== */

.updated {
  margin-block-start: var(--space-xl);
  padding-block-start: var(--space-s);
  border-top: 1px solid var(--line);
  font-size: var(--size--1);
  color: var(--text-faint);
}


/* ==========================================================================
   20. 404
   ========================================================================== */

.notfound {
  display: grid;
  place-items: center;
  min-height: 60svh;
  padding-block: var(--space-2xl);
  text-align: center;
}

.notfound .code { font-size: var(--size-2); font-weight: 800; letter-spacing: .2em; color: var(--accent); }
.notfound h1 { margin-block-start: var(--space-s); letter-spacing: -.03em; }
.notfound > div > p {
  margin-block-start: var(--space-m);
  font-size: var(--size-1);
  line-height: 1.6;
  color: var(--text-muted);
}

.notfound ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .4rem 1.2rem;
  margin-block-start: var(--space-l);
  padding: 0;
  list-style: none;
}
.notfound ul a { font-size: .95rem; font-weight: 600; }


/* ==========================================================================
   21. THE BOOK
   Two places carry it: the announcement band on the home page, and the
   closing lockup on ouroboros-book.html. The storefront row is the only
   piece the two share. No new colors: the accent, the sunken ground and
   the existing card surface do all the work.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Book page hero. Height matches every other hero on the site, so this
   modifier now does one job: framing. The picture is 16:9 with the ring of
   light sitting right of center and high in the frame, and a default 50% crop
   cuts the top of the ring off. 42% keeps the whole circle inside the frame,
   which is the one thing this image exists to show.
   -------------------------------------------------------------------------- */

.hero-cover .hero-media img { object-position: center 42%; }

/* --------------------------------------------------------------------------
   Home page announcement band. Sits between the quote band and the article
   list. Sunken ground with a rule top and bottom, so it separates from the
   graphite quote band above it and the page ground below it without adding
   a third value.
   -------------------------------------------------------------------------- */

.coming {
  padding-block: clamp(var(--space-xl), 7vw, var(--space-2xl));
  border-block: 1px solid var(--line);
  background: var(--bg-sunken);
}

.coming-inner {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(var(--space-m), 4vw, var(--space-xl));
}

/* 3/2 rather than the 16/9 used by cards: the cover stands upright in the
   frame and a 16/9 crop cuts its head and foot off. */
.coming-media {
  overflow: hidden;
  border-radius: var(--radius-l);
  background: var(--brand-graphite);
  /* Second shadow layer is a hairline ring, the same idiom `.release-cover` uses on the
     book page and for the same reason: the artwork is nearly black and the band ground is
     nearly black, so the drop shadow has nothing to fall on and the frame disappears in
     dark mode. The ring is what actually draws the card edge there. */
  box-shadow: var(--shadow-m), 0 0 0 1px var(--line);
}
.coming-media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  transition: transform .5s var(--ease);
}
.coming-media:hover img { transform: scale(1.025); }

.coming-eyebrow {
  font-size: var(--size--1);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
}

.coming-body h2 {
  margin-block-start: var(--space-xs);
  font-size: var(--size-3);
  letter-spacing: -.028em;
}

.coming-sub {
  margin-block-start: .55rem;
  font-size: var(--size-1);
  line-height: 1.5;
  letter-spacing: -.014em;
  color: var(--text-muted);
}

.coming-desc {
  margin-block-start: var(--space-s);
  max-width: 46ch;
  font-size: .97rem;
  line-height: 1.65;
  color: var(--text-muted);
}

.coming-body .btn-row { margin-block-start: var(--space-m); }

@media (max-width: 54rem) {
  .coming-inner { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   Closing lockup on the book page: the cover, then the release line. Centered,
   because it is a colophon rather than running text.

   The cover carries the title and subtitle as artwork, so no heading is set
   here: by this point the page has already said the title in the hero and the
   `<h1>`, and a third setting in type reads as a stutter. The `<h2>` is kept
   for the document outline and screen readers, and the full title is in the
   image's alt text.
   -------------------------------------------------------------------------- */

.release {
  margin-block-start: var(--space-xl);
  padding: var(--space-l) var(--space-m);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  background: var(--bg-sunken);
  text-align: center;
}

/* Sized off its own height rather than its width, so the cover keeps the same
   presence whatever the column does. Shadow and radius so it reads as an
   object lying on the card rather than a picture pasted into it.

   The hairline in the second shadow layer is what holds the edge on the dark
   theme, where a nearly black cover sits on a nearly black card and the drop
   shadow has almost nothing to fall on. */
.release-cover {
  width: min(13.5rem, 60%);
  height: auto;
  margin-inline: auto;
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-m), 0 0 0 1px var(--line);
}

.release-when {
  margin-block-start: var(--space-l);
  font-size: var(--size--1);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent);
}

/* The wide layout lives at the end of this section, after the storefront rules,
   because it has to override `.release .storefronts { justify-content: center }`
   and a media query adds no specificity of its own. */

/* --------------------------------------------------------------------------
   Storefront marks: where the book will be sold. The marks are inline SVG
   rather than <img>, so they inherit currentColor and need no second file
   for the dark theme. An <img>-referenced SVG cannot do that, which is the
   whole reason the stardrive wordmark ships as two files.

   Not links. They become links when the store pages exist; until then a
   dead badge is worse than a plain one.
   -------------------------------------------------------------------------- */

.storefronts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin: var(--space-m) 0 0;
  padding: 0;
  list-style: none;
}

.release .storefronts { justify-content: center; }

.storefronts li {
  display: inline-flex;
  align-items: center;
  gap: .55em;
  padding: .5em .95em;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-m);
  background: var(--surface);
  font-size: var(--size--1);
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--text);
}

.storefronts svg {
  flex: none;
  width: 1.2em;
  height: 1.2em;
  fill: currentColor;
}

/* A chip becomes a link the day its store listing opens. The anchor takes the chip
   box over so the whole chip is the target, and the <li> steps back to a bare flex
   item. Marked with a class rather than :has(), so there is no way for the two chip
   boxes to end up nested if the selector is ever unsupported. */
.storefronts .storefront-link {
  padding: 0;
  border: 0;
  background: none;
}

.storefronts .storefront-link > a {
  display: inline-flex;
  align-items: center;
  gap: .55em;
  padding: .5em .95em;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-m);
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  transition: border-color .18s var(--ease), background .18s var(--ease), transform .18s var(--ease);
}

.storefronts .storefront-link > a:hover {
  border-color: var(--accent-brand);
  background: var(--surface-2);
  color: var(--text);
  transform: translateY(-1px);
}

/* Linked and unlinked chips are otherwise identical, so a store that is open needs
   a mark that says so without a hover. The same arrow `.resource.external` uses. */
.storefronts .storefront-link > a::after {
  content: '↗';
  margin-inline-start: .15em;
  font-weight: 400;
  color: var(--text-faint);
  transition: color .18s var(--ease);
}
.storefronts .storefront-link > a:hover::after { color: var(--accent); }

/* --------------------------------------------------------------------------
   Release card, wide layout. Once there is room for the cover beside the text
   the card becomes a jacket lockup: cover left, release line and storefronts
   right, each centered on the other. Below 44rem it stays the stacked, centered
   colophon defined above.

   44rem is where the text column still clears roughly 340px, which is what the
   two storefront chips need to sit on one line. A viewport query rather than a
   container query on purpose: the card's width comes from `.with-toc`, which is
   itself driven by the viewport, so the two stay in step.

   This block sits last in the section because it overrides
   `.release .storefronts { justify-content: center }` at equal specificity, and
   a media query contributes none of its own.
   -------------------------------------------------------------------------- */

@media (min-width: 44rem) {
  .release {
    display: grid;
    grid-template-columns: 13.5rem minmax(0, 1fr);
    align-items: center;
    gap: clamp(var(--space-m), 4vw, var(--space-xl));
    padding: var(--space-l);
    text-align: start;
  }
  .release-cover { width: 100%; margin-inline: 0; }
  .release-when { margin-block-start: 0; }
  .release .storefronts { justify-content: flex-start; }
}


/* ==========================================================================
   PRINT
   ========================================================================== */

@media print {
  .site-header, .site-footer, .toc, .hero-media, .btn-row, .related, .coming { display: none !important; }
  body { background: #fff; color: #000; }
  .hero { min-height: 0; padding-block: 0 1rem; color: #000; }
  .hero h1, .hero-sub { color: #000; }
  a { color: #000; text-decoration: underline; }
  .prose { max-width: none; }
}
