/* ==========================================================================
   Axelerate — axeleraterei.com
   Design system. Hand-maintained; not generated. Page markup is built by
   tools/build_site.py, this file is not.

   Layout system: a clone of the almentor.net home/catalogue architecture
   (reference screenshot: almentor.png in the project root). The reference is
   an all-dark UI; the client rejected that on 2026-09-10 ("I don't like that
   it's all black"), which also happens to be what the brand book says —
   60% white · 30% blue · 10% yellow (BRAND.md p22). So the ground is white,
   blue does the heavy lifting, and the only dark surface is the footer.

     almentor            Axelerate                  token
     Inter               Josefin Sans               --font-1
     #eb2027 red         #003DFF Axelerate Blue     --accent
     #000 ground         #FFFFFF                    --bg
     #101010 alt band    #F8F8F8                    --bg-alt
     #1D2121 raised      #EFEFEF                    --bg-raised
     #141717 card        #FFFFFF + 1px #E4E7E7      --surface / --line
     #d4d4d4 text        #0A0A0A Ink Black          --text
     #a1a1a1 dim text    #545C5C                    --text-dim  (see note)

   Deliberate departures, recorded so they are not "fixed" later:

   1. TYPE STEPS ARE +1px. Josefin Sans has a much smaller x-height than
      Inter, so the reference's 14px UI step is 15px and its 16px body step
      is 17px. Display steps keep nominal values.
   2. WEIGHTS 400/500/600/700 ONLY. Those are the four woff2 files on disk.
      Never write 300 or 800 — the browser synthesizes them and it shows.
   3. DIM TEXT IS #545C5C, NOT THE BRAND'S SOFT GREY #6B7280. Soft Grey is
      4.25:1 on the #EFEFEF band, which fails AA for 13–15px text. #545C5C
      is 6.0:1 there and 6.9:1 on white. Soft Grey is kept for rules and
      icons where contrast is not a text requirement.

   Brand rules enforced here:
   - Yellow (#FFE600) is ACCENT ONLY: the highlight behind one word per
     page (.mark), one corner swoosh in the hero art, and the focus ring on
     blue and black surfaces. Never a surface, a button, or a bar fill.
   - #003DFF on white is 6.75:1 — fine for text, buttons and icons alike.
     On black it is 3.1:1, so the footer uses no blue text.
   ========================================================================== */

/* --- fonts --------------------------------------------------------------- */

@font-face {
  font-family: 'Josefin Sans';
  src: url('/assets/fonts/JosefinSans-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Josefin Sans';
  src: url('/assets/fonts/JosefinSans-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Josefin Sans';
  src: url('/assets/fonts/JosefinSans-SemiBold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Josefin Sans';
  src: url('/assets/fonts/JosefinSans-Bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

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

:root {
  --font-1: 'Josefin Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* brand */
  --accent: #003DFF;
  --accent-deep: #0036BC;
  --highlight: #FFE600;
  --ink: #0A0A0A;
  --soft-grey: #6B7280;

  /* grounds */
  --bg: #FFFFFF;
  --bg-alt: #F8F8F8;
  --bg-raised: #EFEFEF;
  --surface: #FFFFFF;
  --line: #E4E7E7;
  --line-strong: #C9CFCF;

  /* text on light */
  --text: #0A0A0A;
  --text-dim: #545C5C;

  /* text on dark (footer) */
  --on-dark: #D4D4D4;
  --on-dark-dim: #A1A1A1;

  /* type scale (+1px over the reference) */
  --t-micro: 13px;
  --t-meta: 15px;
  --t-body: 17px;
  --t-lead: 19px;
  --t-card: 18px;
  --t-h3: 21px;
  --t-h2: 27px;
  --t-h1: 44px;

  /* spacing */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px; --sp-9: 96px;

  --max-w: 1536px;
  --gutter: 20px;
  --block: 48px;
  --radius: 12px;
  --radius-sm: 7px;
  --header-h: 66px;
  --shadow-card: 0 1px 2px rgba(10, 10, 10, .04), 0 8px 24px -12px rgba(0, 61, 255, .18);
  --shadow-float: 0 18px 44px -16px rgba(10, 10, 10, .28);
}

@media (min-width: 768px) {
  :root { --gutter: 48px; --block: 64px; --t-h1: 56px; --t-h2: 30px; }
}
@media (min-width: 1200px) {
  :root { --gutter: 72px; --block: 80px; --t-h1: 64px; --t-h2: 32px; }
}

/* --- reset --------------------------------------------------------------- */

*, *::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(--bg);
  color: var(--text);
  font-family: var(--font-1);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

/* author display rules (.card is flex) beat the UA's [hidden]{display:none};
   without this, a filtered-out card or the signed-in library block stays visible */
[hidden] { display: none !important; }

h1, h2, h3, h4 { margin: 0; font-weight: 600; line-height: 1.15; color: var(--ink); }
p { margin: 0 0 var(--sp-4); }
ul, ol { margin: 0; padding: 0; }
li { list-style: none; }

a { color: inherit; text-decoration: none; }
a:hover { color: var(--accent); }

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input, select, textarea { font: inherit; }

:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}
/* on blue and on black the ring is yellow — the one place yellow is a line */
.band--blue :focus-visible, .split-blue :focus-visible, .site-footer :focus-visible,
.btn--primary:focus-visible, .hero-art :focus-visible, .promo-mark :focus-visible {
  outline-color: var(--highlight);
}

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

.skip-link {
  position: absolute; left: var(--sp-4); top: -60px; z-index: 200;
  background: var(--accent); color: #fff; padding: 10px 16px;
  border-radius: var(--radius-sm); font-weight: 600;
  transition: top .15s ease;
}
.skip-link:focus { top: 12px; color: #fff; }

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

.wrap {
  width: 100%;
  max-width: var(--max-w);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.band { padding-block: var(--block); }
.band--alt { background: var(--bg-alt); }
.band--raised { background: var(--bg-raised); }
.band--tight { padding-block: var(--sp-6); }

/* the blue band: white type, yellow focus, ghost buttons in white */
.band--blue { background: var(--accent); color: #fff; }
.band--blue h1, .band--blue h2, .band--blue h3 { color: #fff; }
.band--blue .lead, .band--blue p { color: rgba(255, 255, 255, .92); }
.band--blue .eyebrow { color: #fff; }
.band--blue a:hover { color: #fff; }

/* The ink band — "not all white, not a colour party" (2026-09-10). One or
   two per page, near-black with dark cards, so the page has a rhythm of
   white / light grey / ink with the blue kept for the ticker and the closes.
   Tokens for dark surfaces are the reference's own (#141717 card, #2E3535
   line, #D4D4D4 / #A1A1A1 text — 7.7:1 on the band). No blue text on ink:
   #003DFF on black is 3.1:1. */
.band--ink { background: var(--ink); color: var(--on-dark); }
.band--ink h1, .band--ink h2, .band--ink h3, .band--ink h4 { color: #fff; }
.band--ink .lead, .band--ink .sec-head p, .band--ink .card-kicker, .band--ink .card-meta,
.band--ink .card-foot, .band--ink .tile p, .band--ink .quote p, .band--ink .eyebrow,
.band--ink .stats-kicker, .band--ink .stat-l, .band--ink .t-note, .band--ink .t-foot { color: var(--on-dark-dim); }
.band--ink .card, .band--ink .quote, .band--ink .panel, .band--ink .promo-body {
  background: #141717; border-color: #2E3535; box-shadow: 0 10px 30px -18px rgba(0, 0, 0, .8);
}
.band--ink .card:hover { border-color: #46504F; }
.band--ink .card-title, .band--ink .quote footer, .band--ink .quote h3, .band--ink .tile h3 { color: #fff; }
.band--ink .card a.card-title:hover { color: #fff; }
.band--ink .card-foot { border-top-color: #2E3535; }
.band--ink .card-media { background: #1D2121; }
.band--ink .tile { border-top-color: #2E3535; }
.band--ink .tile-ico { color: #fff; }
.band--ink .sec-link { color: #fff; }
.band--ink .sec-link:hover { color: var(--highlight); }
.band--ink .btn--ghost { background: transparent; border-color: #55605F; color: #fff; }
.band--ink .btn--ghost:hover { border-color: #fff; }
.band--ink .btn--investor { color: #fff; border-color: var(--accent); background: rgba(0, 61, 255, .25); }
.band--ink .rail-btn { background: #141717; border-color: #2E3535; color: #fff; }
.band--ink .rail-btn[disabled]:hover { background: #141717; border-color: #2E3535; color: #fff; }
.band--ink .chip-soon { background: #fff; color: var(--ink); }
.band--ink .pill { background: #141717; border-color: #46504F; color: #fff; }
.band--ink table th, .band--ink table td { border-bottom-color: #2E3535; }
.band--ink th { color: #fff; }
.band--ink thead th, .band--ink caption { color: var(--on-dark-dim); }
.band--ink .checklist svg { color: #fff; }
.band--ink :focus-visible { outline-color: var(--highlight); }
.band--ink .stat { border-left-color: #fff; }
.band--ink .stat-n { color: #fff; }
.band--ink .dots button { background: #2E3535; }
.band--ink .dots button[aria-current="true"] { background: #fff; }
.band--ink .rail { scrollbar-color: #2E3535 transparent; }
.band--ink a:hover { color: #fff; }
.band--ink .avatar { background: #fff; color: var(--ink); }

main { display: block; }

/* --- header (frosted glass) ---------------------------------------------- */
/* Translucent white over a real backdrop blur, so the hero's blue panel and
   the card artwork smear through as the page scrolls under it. The solid
   fallback is for browsers without backdrop-filter. */

.site-header {
  position: sticky; top: 0; z-index: 90;
  background: rgba(255, 255, 255, .62);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid rgba(10, 10, 10, .08);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .6) inset;
}
@supports not ((backdrop-filter: blur(4px)) or (-webkit-backdrop-filter: blur(4px))) {
  .site-header { background: rgba(255, 255, 255, .97); }
}

.header-in {
  display: flex; align-items: center; gap: var(--sp-5);
  min-height: var(--header-h);
}

.brand { display: inline-flex; align-items: center; flex: 0 0 auto; }
/* the supplied PNGs carry transparent padding; the -trim files are the real
   ink box (450x104, 4.327:1). Never size the padded originals. */
.brand img { width: 138px; height: auto; }

.nav-primary { display: none; }
@media (min-width: 1100px) {
  .nav-primary { display: flex; align-items: center; gap: var(--sp-5); }
}
.nav-primary a, .nav-primary summary {
  font-size: var(--t-meta); font-weight: 500; color: var(--text);
  padding: 6px 0; white-space: nowrap;
}
.nav-primary a:hover, .nav-primary summary:hover { color: var(--accent); }
.nav-primary a[aria-current="page"] {
  color: var(--accent);
  box-shadow: inset 0 -2px 0 var(--accent);
}

/* dropdown built on <details> so it opens with JavaScript disabled */
.menu { position: relative; }
.menu > summary {
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer; list-style: none;
}
.menu > summary::-webkit-details-marker { display: none; }
.menu > summary .chev { transition: transform .18s ease; }
.menu[open] > summary .chev { transform: rotate(180deg); }
.menu-panel {
  position: absolute; top: calc(100% + 12px); left: -16px; z-index: 95;
  min-width: 270px; padding: var(--sp-3);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-float);
}
.menu-panel a {
  display: block; padding: 9px 12px; border-radius: var(--radius-sm);
  font-size: var(--t-meta); font-weight: 500;
}
.menu-panel a:hover { background: var(--bg-raised); color: var(--accent); }
.menu-panel .menu-note {
  display: block; padding: 9px 12px 2px;
  font-size: var(--t-micro); color: var(--text-dim); font-weight: 400;
}

.header-tail { display: flex; align-items: center; gap: var(--sp-3); margin-left: auto; }

.icon-btn {
  display: inline-grid; place-items: center;
  width: 38px; height: 38px; border-radius: 50%;
  color: var(--text); border: 1px solid transparent;
}
.icon-btn:hover { background: var(--bg-raised); color: var(--accent); }

.burger { display: inline-grid; }
@media (min-width: 1100px) { .burger { display: none; } }

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

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 20px; border-radius: var(--radius-sm);
  font-size: var(--t-meta); font-weight: 600; line-height: 1.2;
  white-space: nowrap;
  transition: background-color .16s ease, color .16s ease, border-color .16s ease, transform .16s ease;
}
.btn:active { transform: translateY(1px); }

.btn--primary { background: var(--accent); color: #fff; }
.btn--primary:hover { background: var(--accent-deep); color: #fff; }

.btn--ghost { border: 1px solid var(--line-strong); color: var(--ink); background: var(--surface); }
.btn--ghost:hover { border-color: var(--ink); color: var(--ink); }

/* the one investor button: outlined in Axelerate Blue, filled on hover */
.btn--investor {
  border: 1px solid var(--accent);
  color: var(--accent);
  background: rgba(0, 61, 255, .06);
}
.btn--investor:hover { background: var(--accent); color: #fff; }

/* ghost on a blue ground */
.band--blue .btn--ghost, .split-blue .btn--ghost {
  background: transparent; border-color: rgba(255, 255, 255, .6); color: #fff;
}
.band--blue .btn--ghost:hover, .split-blue .btn--ghost:hover { background: #fff; color: var(--accent); border-color: #fff; }
.band--blue .btn--primary, .split-blue .btn--primary { background: #fff; color: var(--accent); }
.band--blue .btn--primary:hover, .split-blue .btn--primary:hover { background: var(--ink); color: #fff; }

.btn--lg { padding: 14px 28px; font-size: var(--t-body); }
.btn--block { width: 100%; }

/* declared AFTER .btn on purpose: .btn sets display:inline-flex at the same
   specificity, so an earlier .hide-sm loses on source order and the phone
   header overflows. It did, once. */
.hide-sm { display: none; }
@media (min-width: 700px) { .hide-sm { display: inline-flex; } }

/* --- mobile sheet -------------------------------------------------------- */
/* The previous build's review caught four defects here: no focus trap, no
   scroll on short viewports, sat under other fixed UI, and the scroll lock
   survived a resize to desktop. All four are handled in site.js. */

.sheet {
  position: fixed; inset: 0; z-index: 120;
  display: none;
  background: rgba(10, 10, 10, .45);
}
.sheet[data-open="true"] { display: block; }
.sheet-panel {
  position: absolute; inset: 0 0 0 auto;
  width: min(420px, 100%);
  max-height: 100%; overflow-y: auto; overscroll-behavior: contain;
  background: var(--surface); border-left: 1px solid var(--line);
  padding: var(--sp-4) var(--sp-5) var(--sp-8);
  box-shadow: var(--shadow-float);
}
.sheet-head { display: flex; align-items: center; justify-content: space-between; min-height: var(--header-h); }
.sheet-nav { display: grid; gap: 2px; margin-top: var(--sp-4); }
.sheet-nav a {
  padding: 13px 12px; border-radius: var(--radius-sm);
  font-size: var(--t-lead); font-weight: 500;
}
.sheet-nav a:hover { background: var(--bg-raised); color: var(--accent); }
.sheet-actions { display: grid; gap: var(--sp-3); margin-top: var(--sp-5); }
.sheet-actions .btn { width: 100%; }

/* --- hero (full screen: the photo fills the first viewport) --------------- */
/* One screen tall under the sticky header — 100svh where supported, so a
   phone's collapsing address bar does not leave a gap — and taller only if
   the copy needs it. The photo is the ground; a deep-blue scrim sits where
   the copy sits (left on desktop, bottom on phones and portrait tablets), so
   white type stays above 7:1 and the trainer's face stays clear of it. */

.hero {
  position: relative; overflow: hidden; isolation: isolate;
  display: flex; align-items: flex-end;
  min-height: calc(100vh - var(--header-h));
  background: var(--accent-deep); color: #fff;
}
@supports (height: 100svh) { .hero { min-height: calc(100svh - var(--header-h)); } }
@media (min-width: 900px) { .hero { align-items: center; } }

.hero-in { position: relative; z-index: 2; width: 100%; padding-block: var(--sp-7) var(--sp-7); }
@media (min-width: 900px) { .hero-in { padding-block: var(--sp-8) var(--sp-9); } }
.hero-copy { max-width: 640px; }
.hero h1 {
  font-size: clamp(34px, 5vw, 62px);
  font-weight: 700; letter-spacing: -.02em; color: #fff;
  margin-bottom: var(--sp-4);
}
.hero .eyebrow { color: rgba(255, 255, 255, .85); }
.hero .btn--ghost { background: transparent; border-color: rgba(255, 255, 255, .65); color: #fff; }
.hero .btn--ghost:hover { background: #fff; color: var(--ink); border-color: #fff; }
.hero :focus-visible { outline-color: var(--highlight); }
/* Yellow highlight behind one key word — brand composition rule 2, p24.
   Ink on yellow is 16.6:1. One word per page. Yellow appears nowhere else
   as a fill. */
.mark {
  background: var(--highlight);
  color: var(--ink);
  padding: 0 .1em;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.hero p.lead { font-size: var(--t-lead); color: rgba(255, 255, 255, .9); max-width: 42ch; }
.hero-cta { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-5); }
/* .hero-note is reused on light pages (course, book and investor heroes),
   so only the home hero's copy goes white */
.hero-note { margin-top: var(--sp-5); font-size: var(--t-meta); color: var(--text-dim); }
.hero-note strong { color: var(--ink); font-weight: 600; }
.hero .hero-note { color: rgba(255, 255, 255, .82); }
.hero .hero-note strong { color: #fff; }

/* the photo layer covers the whole section; the copy floats over it */
.hero-art { position: absolute; inset: 0; z-index: 0; overflow: hidden; background: var(--accent-deep); }

/* --- hero photo + motion ------------------------------------------------- */
/* The photo sits on the blue panel and is cropped by it. Three motions, all
   transform/opacity only and all switched off under prefers-reduced-motion:
   a slow Ken Burns drift on the photo, a scroll parallax on its wrapper
   (site.js sets --py), and two glass chips that bob. Copy rises in on load,
   scoped under .js so a JS-off render is complete and still. */

/* Three stacked layers, one transform each, so nothing fights:
     .hero-photo-wrap    scroll parallax        transform: translateY(--py)
     .hero-photo-settle  entrance zoom-out      animation on transform (backwards fill)
                          + cursor tilt          the separate `translate` property
     .hero-photo         Ken Burns drift        animation on transform            */
.hero-photo-wrap {
  position: absolute; inset: -12% 0;
  transform: translateY(calc(var(--py, 0) * 1px));
  will-change: transform;
}
.hero-photo-settle {
  position: absolute; inset: 0;
  translate: calc(var(--mx, 0) * -12px) calc(var(--my, 0) * -8px);
  transition: translate .35s ease-out;
}
.js .hero-photo-settle { animation: settle 1.6s cubic-bezier(.2, .7, .2, 1) backwards; }
@keyframes settle { from { transform: scale(1.18); } to { transform: scale(1); } }
.hero-photo {
  width: 100%; height: 100%; object-fit: cover; object-position: 62% 30%;
  transform-origin: 60% 45%;
  animation: kenburns 18s ease-in-out infinite alternate;
}
/* Portrait screens: the photo is cropped to a tall slice around the trainer.
   His face sits at ~20% of the picture's height, and the parallax wrapper
   already starts 12% above the panel, so without help the face lands under
   the header. Growing the settle layer from its TOP edge pushes the face
   down into the clear third above the copy (≈150px down on a 390px phone,
   ≈200px on an iPad). object-position-y does nothing here — there is no
   vertical crop to move. */
@media (max-width: 899px) {
  .hero-photo { object-position: 58% 50%; }
  .hero-photo-settle { scale: 1.18; transform-origin: 58% 0%; }
}
@keyframes kenburns {
  from { transform: scale(1) translate(0, 0); }
  to   { transform: scale(1.10) translate(-1.6%, 1.2%); }
}
/* the panel wipes open from the left on load; JS-off shows it open */
.js .hero-art { animation: wipe 1.1s cubic-bezier(.2, .7, .2, 1) both; }
@keyframes wipe { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
/* the scrim: deep blue where the copy sits, clear where the trainer is.
   Phones and portrait tablets read bottom-up; from 900px it reads left-to-
   right. rgb(0,20,80) at .85 over a mid-tone photo puts white type near 9:1. */
.hero-shade {
  position: absolute; inset: 0; pointer-events: none; z-index: 1;
  background:
    linear-gradient(180deg, rgba(0, 20, 80, .10) 0%, rgba(0, 20, 80, .35) 36%, rgba(0, 20, 80, .88) 58%, rgba(0, 14, 60, .96) 100%);
}
@media (min-width: 900px) {
  .hero-shade {
    background:
      linear-gradient(90deg, rgba(0, 20, 80, .92) 0%, rgba(0, 20, 80, .84) 32%, rgba(0, 20, 80, .45) 50%, rgba(0, 61, 255, .06) 68%, rgba(0, 61, 255, 0) 100%),
      linear-gradient(180deg, rgba(0, 20, 80, 0) 60%, rgba(0, 14, 60, .55) 100%);
  }
}
.hero-swoosh {
  position: absolute; top: 0; right: 0; width: 120px; height: auto; pointer-events: none; z-index: 2;
  transform-origin: 100% 0; animation: breathe 5s ease-in-out infinite;
}
@media (max-width: 899px) { .hero-swoosh { width: 84px; } }
@keyframes breathe { 50% { transform: scale(1.07) rotate(-2deg); } }

.hero-chip {
  position: absolute; z-index: 3;
  display: inline-flex; align-items: baseline; gap: 8px;
  padding: 12px 16px; border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .82);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, .7);
  box-shadow: var(--shadow-float);
  color: var(--ink); font-size: var(--t-meta); font-weight: 600; white-space: nowrap;
  /* bob rides on transform; the cursor tilt rides on the separate
     `translate` property; the pop-in rides on opacity + `scale` */
  animation: bob 6s ease-in-out infinite;
  translate: calc(var(--mx, 0) * 16px) calc(var(--my, 0) * 12px);
  transition: translate .35s ease-out;
}
.js .hero-chip { animation: pop .6s cubic-bezier(.2, .7, .2, 1) .9s backwards, bob 6s ease-in-out 1.5s infinite; }
.js .hero-chip--b { animation-delay: 1.1s, -1.5s; }
@keyframes pop { from { opacity: 0; scale: .8; } to { opacity: 1; scale: 1; } }
.hero-chip strong { font-size: 26px; font-weight: 700; line-height: 1; color: var(--accent); }
/* the chips live on the photo side, stacked bottom-right, from 900px up.
   Below that the copy owns the bottom of the screen and the stats strip
   right under the hero carries the same figures — so no chips on phones. */
.hero-chip { display: none; }
@media (min-width: 900px) {
  .hero-chip { display: inline-flex; }
  .hero-chip--a { right: var(--gutter); bottom: 56px; }
  .hero-chip--b { right: var(--gutter); bottom: 130px; }
}
@keyframes bob { 50% { transform: translateY(-8px); } }

.js .hero-copy > * { opacity: 0; transform: translateY(14px); animation: rise .7s cubic-bezier(.2, .7, .2, 1) forwards; }
.js .hero-copy > :nth-child(2) { animation-delay: .08s; }
.js .hero-copy > :nth-child(3) { animation-delay: .18s; }
.js .hero-copy > :nth-child(4) { animation-delay: .28s; }
.js .hero-copy > :nth-child(5) { animation-delay: .4s; }
.js .hero-copy > :nth-child(6) { animation-delay: .55s; }
@keyframes rise { to { opacity: 1; transform: none; } }

/* Reduced motion, decided 2026-09-10: the client asked for motion twice and
   may well have Windows' "animation effects" switched off, which is what
   sets this flag. So the flag stops the LOOPS (drift, bob, breathe, tilt,
   parallax) and keeps the one-shot entrances, which are short and end. The
   ticker keeps moving under it too, because it has its own pause button. */
@media (prefers-reduced-motion: reduce) {
  .hero-photo, .hero-swoosh { animation: none; }
  .js .hero-chip { animation: pop .6s cubic-bezier(.2, .7, .2, 1) .9s backwards; }
  .hero-photo-wrap { transform: none; }
  .hero-photo-settle, .hero-chip { translate: 0 0; }
}

/* --- ticker (the news bar) ----------------------------------------------- */
/* Two identical tracks in a max-content row; the row slides by exactly half
   its width and snaps back, which is invisible because track two is track
   one. The second track is aria-hidden so a screen reader hears the list
   once. Pauses on hover and on keyboard focus; static and wrapped under
   reduced motion. */

.ticker {
  position: relative; overflow: hidden;
  background: var(--accent); color: #fff;
  border-block: 1px solid rgba(255, 255, 255, .18);
}
.ticker-in { display: flex; width: max-content; animation: ticker 48s linear infinite; }
.ticker:hover .ticker-in, .ticker:focus-within .ticker-in { animation-play-state: paused; }
.ticker-track { display: flex; flex: 0 0 auto; margin: 0; padding: 0; }
.ticker-track li {
  display: inline-flex; align-items: baseline; gap: 10px;
  padding: 13px 0 12px 22px; margin-right: 22px;
  font-size: var(--t-meta); font-weight: 500; white-space: nowrap;
}
.ticker-track li strong { font-size: 22px; font-weight: 700; line-height: 1; }
.ticker-track li::before {
  content: ''; align-self: center; width: 22px; height: 16px; margin-right: 4px;
  background: url('/assets/logos/emblem-white-trim.png') center / contain no-repeat;
  opacity: .9;
}
@keyframes ticker { to { transform: translateX(-50%); } }
.ticker.is-paused .ticker-in { animation-play-state: paused; }

/* the pause/play control (WCAG 2.2.2: moving content longer than 5s needs
   a way to stop it that does not depend on hover). Sits on a fade so the
   text slides under it rather than into it. */
.ticker-btn {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 2;
  display: grid; place-items: center; width: 64px;
  padding-left: 18px; color: #fff;
  background: linear-gradient(90deg, rgba(0, 61, 255, 0), var(--accent) 40%);
}
.ticker-btn:hover { color: var(--highlight); }
.ticker-btn:focus-visible { outline-color: var(--highlight); outline-offset: -4px; }
.ticker-btn .ico-play { display: none; }
.ticker.is-paused .ticker-btn .ico-pause { display: none; }
.ticker.is-paused .ticker-btn .ico-play { display: block; }
.ticker-in { padding-right: 64px; }

/* --- stats strip (count-up numbers) -------------------------------------- */

.stats { background: var(--bg); border-bottom: 1px solid var(--line); }
.stats-in { padding-block: var(--sp-6); }
.stats-kicker {
  font-size: var(--t-micro); font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-dim); margin-bottom: var(--sp-4);
}
.stats-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-5) var(--sp-4); }
@media (min-width: 760px) { .stats-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.stat { display: grid; gap: 4px; padding-left: var(--sp-4); border-left: 3px solid var(--accent); }
.stat-n {
  font-size: clamp(36px, 4.4vw, 56px); font-weight: 700; line-height: 1; letter-spacing: -.02em;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.stat-l { font-size: var(--t-meta); color: var(--text-dim); font-weight: 500; }
/* a short lift when the count starts; the number itself is set by site.js */
.stat.is-counting .stat-n { animation: lift .9s cubic-bezier(.2, .7, .2, 1); }
@keyframes lift { from { opacity: .2; transform: translateY(10px); } }

/* --- section heads ------------------------------------------------------- */

.sec-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--sp-4); margin-bottom: var(--sp-5);
}
.sec-head h2 { font-size: var(--t-h2); font-weight: 600; letter-spacing: -.01em; }
.sec-head p { margin: 6px 0 0; font-size: var(--t-meta); color: var(--text-dim); }
.sec-link { font-size: var(--t-meta); font-weight: 600; color: var(--accent); white-space: nowrap; }
.sec-link:hover { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 4px; }

/* --- rails (horizontal card scrollers) ----------------------------------- */
/* Native overflow scrolling with snap points, so the rail works with the
   arrow buttons, with a trackpad, with a keyboard, and with JS disabled.
   Track widths are FIXED percentages, not minmax(): inside a scroll
   container a minmax() track only overflows through its minimum, so a
   three-slide deck simply fit and never scrolled. */

.rail-wrap { position: relative; }
.rail {
  display: grid; grid-auto-flow: column;
  grid-auto-columns: 82%;
  gap: var(--sp-4);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline: 2px;
  padding: 4px 2px var(--sp-3);
  scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent;
}
@media (min-width: 620px)  { .rail { grid-auto-columns: 44%; } }
@media (min-width: 1000px) { .rail { grid-auto-columns: 30%; } }
@media (min-width: 1400px) { .rail { grid-auto-columns: 23%; } }
.rail > * { scroll-snap-align: start; }
.rail::-webkit-scrollbar { height: 6px; }
.rail::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 99px; }

/* one slide at a time with the next one peeking; the end padding lets the
   last slide's start position be reached, so its dot can select it */
[data-deck] .rail { grid-auto-columns: 86%; padding-inline-end: 14%; }
@media (min-width: 1000px) { [data-deck] .rail { grid-auto-columns: 46%; padding-inline-end: 8%; } }

.rail-btn {
  position: absolute; top: 92px; z-index: 3;
  display: none; place-items: center;
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--surface); border: 1px solid var(--line-strong);
  color: var(--ink);
  box-shadow: var(--shadow-float);
}
@media (min-width: 1000px) { .rail-btn { display: grid; } }
.rail-btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.rail-btn[disabled] { opacity: .35; cursor: default; }
.rail-btn[disabled]:hover { background: var(--surface); border-color: var(--line-strong); color: var(--ink); }
.rail-btn--prev { left: -20px; }
.rail-btn--next { right: -20px; }

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

.card {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  transition: border-color .16s ease, transform .16s ease, box-shadow .16s ease;
}
.card:hover { border-color: var(--line-strong); transform: translateY(-2px); box-shadow: var(--shadow-float); }
@media (prefers-reduced-motion: reduce) { .card:hover { transform: none; } }

.card-media { position: relative; aspect-ratio: 16 / 9; background: var(--bg-raised); }
.card-media img { width: 100%; height: 100%; object-fit: cover; }
/* book covers are 2:3; they stand on a grey shelf inside a 4:3 box with a
   soft shadow, so a rail of them reads as products rather than as photos */
.card-media--cover { aspect-ratio: 4 / 3; display: grid; place-items: center; background: var(--bg-raised); }
.card-media--cover img {
  width: auto; height: 84%; object-fit: contain; border-radius: 3px;
  box-shadow: 0 10px 24px -10px rgba(10, 10, 10, .45), 0 1px 2px rgba(10, 10, 10, .2);
}
.card:hover .card-media--cover img { transform: translateY(-3px); transition: transform .2s ease; }

/* the founder feature on the home page */
.who { display: grid; gap: var(--sp-6); align-items: center; }
@media (min-width: 900px) { .who { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--sp-8); } }
.who-photo img { border-radius: var(--radius); width: 100%; aspect-ratio: 3 / 4; object-fit: cover; box-shadow: var(--shadow-float); }
@media (min-width: 900px) { .who-photo img { max-width: 440px; } }
.who-body h2 { font-size: var(--t-h2); margin-bottom: var(--sp-3); }

/* a photo behind the split panel's second half, with the copy on a scrim
   (two classes, because .split-side sets its padding later in this file) */
.split-side.split-side--photo { position: relative; padding: 0; min-height: 320px; display: grid; align-items: end; }
.split-side--photo > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.split-side-copy {
  position: relative; padding: var(--sp-6);
  background: linear-gradient(180deg, rgba(10, 10, 10, 0) 0%, rgba(10, 10, 10, .78) 40%, rgba(10, 10, 10, .9) 100%);
  color: #fff;
}
.split-side-copy h3 { color: #fff; font-size: var(--t-h3); margin-bottom: var(--sp-2); }
.split-side-copy .checklist { margin-bottom: 0; }
.split-side-copy .checklist svg { color: var(--highlight); }
.card-body { display: flex; flex-direction: column; flex: 1 1 auto; padding: var(--sp-4); gap: 6px; }
.card-kicker { font-size: var(--t-micro); font-weight: 500; color: var(--text-dim); letter-spacing: .01em; }
.card-title {
  font-size: var(--t-card); font-weight: 600; line-height: 1.25; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.card a.card-title:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
.card-meta { display: flex; align-items: center; gap: 6px; font-size: var(--t-micro); color: var(--text-dim); }
.card-foot {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  margin-top: auto; padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--line);
  font-size: var(--t-micro); color: var(--text-dim);
}

/* stretched-link pattern: whole card clickable, one real link in the a11y tree */
.card--link { position: relative; }
.card--link .stretch::after { content: ''; position: absolute; inset: 0; }
.card--link:focus-within { border-color: var(--accent); }

/* person tiles carry no card chrome — portrait, then name under it */
.person { background: none; border: 0; overflow: visible; box-shadow: none; }
.person:hover { border: 0; box-shadow: none; }
.person .card-media { border-radius: var(--radius); overflow: hidden; }
.person .card-body { padding: var(--sp-3) 0 0; }

/* placeholder rating row — visibly marked, see .ph-chip */
.stars { display: inline-flex; gap: 2px; color: var(--accent); }
.stars svg { width: 14px; height: 14px; fill: currentColor; }

/* --- placeholder marking ------------------------------------------------- */
/* Client chose visible placeholders over swapped-in real content. Everything
   provisional carries one of these so nothing is mistaken for a live figure. */

.ph-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 8px; border-radius: 4px;
  background: var(--bg-raised); border: 1px dashed var(--soft-grey);
  font-size: 11px; font-weight: 600; letter-spacing: .04em;
  color: var(--text-dim); text-transform: uppercase;
}
.ph-chip--onmedia {
  position: absolute; left: 8px; top: 8px; z-index: 2;
  background: rgba(255, 255, 255, .9);
}
.ph-note {
  display: flex; align-items: flex-start; gap: 10px;
  padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-5);
  border: 1px dashed var(--soft-grey); border-radius: var(--radius-sm);
  background: var(--bg-alt);
  font-size: var(--t-meta); color: var(--text-dim);
}
.band--alt .ph-note { background: var(--surface); }
.ph-note svg { flex: 0 0 auto; margin-top: 3px; }
.ph-note strong { color: var(--ink); font-weight: 600; }

/* --- calm notes (functional truths: the LMS is a shell, the form is unwired) */

.t-note {
  display: flex; align-items: flex-start; gap: 10px;
  padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-5);
  border-left: 3px solid var(--accent); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--bg-alt);
  font-size: var(--t-meta); color: var(--text-dim);
}
.t-note svg { flex: 0 0 auto; margin-top: 3px; color: var(--accent); }
.t-note strong { color: var(--ink); font-weight: 600; }
.band--alt .t-note { background: var(--surface); }
.band--ink .t-note { background: #141717; border-left-color: #fff; }
.band--ink .t-note strong, .band--ink .t-note svg { color: #fff; }

/* --- testimonials -------------------------------------------------------- */

.t-card {
  display: flex; flex-direction: column; gap: var(--sp-3);
  padding: var(--sp-5); border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-card);
}
.t-card blockquote { margin: 0; font-size: var(--t-body); line-height: 1.55; color: var(--ink); }
.t-card blockquote::before { content: '\201C'; display: block; font-size: 44px; line-height: .6; color: var(--accent); margin-bottom: 8px; font-weight: 700; }
.t-who { display: flex; align-items: center; gap: 12px; margin-top: auto; }
.t-who .avatar { width: 40px; height: 40px; font-size: var(--t-meta); color: #fff; }
.t-who b { display: block; font-weight: 600; color: var(--ink); font-size: var(--t-meta); }
.t-who span { font-size: var(--t-micro); color: var(--text-dim); }
.band--ink .t-card { background: #141717; border-color: #2E3535; box-shadow: 0 10px 30px -18px rgba(0, 0, 0, .8); }
.band--ink .t-card blockquote, .band--ink .t-who b { color: #fff; }
.band--ink .t-card blockquote::before { color: var(--highlight); }
.band--ink .t-who span { color: var(--on-dark-dim); }
.band--ink .t-who .avatar { background: #fff; color: var(--ink); }
.t-foot { font-size: var(--t-micro); color: var(--text-dim); margin-top: var(--sp-4); }

/* the quote ribbon in the hero: one testimonial at a time, rotating */
.hero-quote {
  position: relative; display: grid; gap: 8px;
  max-width: 520px; margin-top: var(--sp-6); padding: 14px 16px 14px 18px;
  border-left: 3px solid var(--highlight);
  background: rgba(0, 14, 60, .45);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.hero-quote blockquote { margin: 0; font-size: var(--t-meta); line-height: 1.5; color: #fff; }
.hero-quote .t-who b { color: #fff; }
.hero-quote .t-who span { color: rgba(255, 255, 255, .78); }
.hero-quote .t-who .avatar { width: 32px; height: 32px; font-size: 13px; background: #fff; color: var(--accent); }
.hero-quote .t-who b, .hero-quote .t-who span { color: #fff; }
.hero-quote-item { display: none; }
.hero-quote-item.is-on { display: grid; gap: 8px; animation: rise .6s cubic-bezier(.2, .7, .2, 1); }
.hero-quote-item.is-on:first-child { animation: none; }
html:not(.js) .hero-quote-item:first-child { display: grid; gap: 8px; }
@media (prefers-reduced-motion: reduce) { .hero-quote-item.is-on { animation: none; } }

/* --- promo panel (the reference's partner strip) ------------------------- */

.promo {
  display: grid; gap: 0;
  border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line); box-shadow: var(--shadow-card);
}
@media (min-width: 860px) { .promo { grid-template-columns: 360px minmax(0, 1fr); } }
.promo-mark {
  display: grid; place-items: center;
  background: var(--accent); padding: var(--sp-7) var(--sp-5); min-height: 180px;
}
.promo-mark img { width: min(240px, 80%); }
.promo-body { background: var(--surface); padding: var(--sp-6) var(--sp-5); }
.promo-body h2, .promo-body h3 { font-size: var(--t-h3); margin-bottom: var(--sp-2); }
.promo-body p { font-size: var(--t-meta); color: var(--text-dim); max-width: 62ch; }

/* --- grids --------------------------------------------------------------- */

.grid { display: grid; gap: var(--sp-4); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }

/* --- feature tiles ------------------------------------------------------- */

.tile { padding: var(--sp-5) var(--sp-4); border-top: 2px solid var(--line); }
.tile-ico { color: var(--accent); margin-bottom: var(--sp-3); }
.tile-ico svg { width: 26px; height: 26px; }
.tile h3 { font-size: var(--t-card); margin-bottom: 6px; }
.tile p { font-size: var(--t-meta); color: var(--text-dim); margin: 0; }

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

.quote {
  display: flex; flex-direction: column; gap: var(--sp-3);
  padding: var(--sp-5); border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-card);
}
.quote h3 { font-size: var(--t-meta); font-weight: 600; }
.quote p { font-size: var(--t-meta); color: var(--text-dim); margin: 0; }
.quote footer { margin-top: auto; font-size: var(--t-meta); font-weight: 600; color: var(--ink); }

/* --- split panel (brand composition rule 1: half white, half blue) ------- */

.split {
  display: grid; gap: 0; border-radius: var(--radius); overflow: hidden;
  border: 1px solid var(--line); box-shadow: var(--shadow-card);
}
@media (min-width: 900px) { .split { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.split-blue { background: var(--accent); color: #fff; padding: var(--sp-7) var(--sp-6); }
.split-blue h2, .split-blue h3 { color: #fff; }
.split-blue p { color: rgba(255, 255, 255, .92); }   /* 5.9:1 on Axelerate Blue */
.split-blue .eyebrow { color: #fff; }
.split-blue a:hover { color: #fff; }
.split-side { background: var(--surface); padding: var(--sp-7) var(--sp-6); }

.checklist { display: grid; gap: 10px; margin: var(--sp-4) 0 var(--sp-5); }
.checklist li { display: flex; gap: 10px; font-size: var(--t-meta); }
.checklist svg { flex: 0 0 auto; margin-top: 3px; color: var(--accent); }
.split-blue .checklist svg, .band--blue .checklist svg { color: #fff; }

/* --- tables (never delete data at small widths — scroll instead) --------- */

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { width: 100%; border-collapse: collapse; font-size: var(--t-meta); min-width: 520px; }
caption { text-align: left; font-size: var(--t-meta); color: var(--text-dim); padding-bottom: var(--sp-3); }
th, td { text-align: left; padding: 12px var(--sp-3); border-bottom: 1px solid var(--line); vertical-align: top; }
th { font-weight: 600; color: var(--ink); }
thead th { font-size: var(--t-micro); color: var(--text-dim); font-weight: 600; }

/* --- forms --------------------------------------------------------------- */

.form { display: grid; gap: var(--sp-4); }
.field { display: grid; gap: 6px; }
.field label { font-size: var(--t-meta); font-weight: 600; color: var(--ink); }
.field .hint { font-size: var(--t-micro); color: var(--text-dim); }
.field input, .field select, .field textarea {
  width: 100%; padding: 12px 14px;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
}
.field textarea { min-height: 150px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: #737B7B; } /* 4.6:1 */
.field input:focus, .field textarea:focus { border-color: var(--accent); }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"] {
  border-color: var(--accent-deep); box-shadow: inset 3px 0 0 var(--accent-deep);
}
.field .err { font-size: var(--t-micro); color: var(--accent-deep); font-weight: 600; }
.field .err:empty { display: none; }

.form-note { font-size: var(--t-micro); color: var(--text-dim); }
.form-result {
  padding: var(--sp-3) var(--sp-4); border-radius: var(--radius-sm);
  border: 1px solid var(--line-strong); background: var(--bg-alt);
  font-size: var(--t-meta);
}
.form-result:empty { display: none; }

.auth-shell { display: grid; gap: var(--sp-7); align-items: start; }
@media (min-width: 960px) { .auth-shell { grid-template-columns: minmax(0, 460px) minmax(0, 1fr); gap: var(--sp-9); } }
.auth-card {
  padding: var(--sp-6); border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-card);
}
.auth-card h1 { font-size: var(--t-h2); margin-bottom: 6px; }
.auth-card > p { font-size: var(--t-meta); color: var(--text-dim); }
.auth-alt { font-size: var(--t-meta); color: var(--text-dim); text-align: center; margin: 0; }
.auth-alt a { color: var(--accent); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }

/* --- library (the signed-in resource area) ------------------------------- */

.lib-head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-4); padding-bottom: var(--sp-5); border-bottom: 1px solid var(--line);
}
.lib-who { display: flex; align-items: center; gap: var(--sp-3); }
.avatar {
  display: grid; place-items: center; width: 44px; height: 44px;
  border-radius: 50%; background: var(--accent); color: #fff;
  font-weight: 700; font-size: var(--t-body);
}
.lib-tabs { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin: var(--sp-5) 0; }
.lib-tabs a {
  padding: 8px 14px; border-radius: 99px; font-size: var(--t-meta); font-weight: 600;
  border: 1px solid var(--line-strong); color: var(--ink); background: var(--surface);
}
.lib-tabs a[aria-current="page"] { background: var(--accent); border-color: var(--accent); color: #fff; }
.lib-tabs a:hover { color: var(--accent); border-color: var(--accent); }
.lib-tabs a[aria-current="page"]:hover { color: #fff; }

.progress { height: 6px; border-radius: 99px; background: var(--bg-raised); overflow: hidden; }
.progress > span { display: block; height: 100%; background: var(--accent); }

.locked { position: relative; }
.locked .card-media::after { content: ''; position: absolute; inset: 0; background: rgba(255, 255, 255, .55); }
.lock-ico { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; color: var(--ink); }

/* --- article (blog posts) ------------------------------------------------ */

.article { max-width: 68ch; }
.article-meta {
  display: flex; flex-wrap: wrap; gap: 6px 14px;
  font-size: var(--t-meta); color: var(--text-dim); margin: var(--sp-4) 0 var(--sp-6);
}
.article h2 { font-size: var(--t-h3); margin: var(--sp-6) 0 var(--sp-3); }
.article p { font-size: var(--t-body); line-height: 1.65; }
.article ul, .article ol { margin: 0 0 var(--sp-4) 1.2em; }
.article li { list-style: disc; margin: 6px 0; padding-left: 4px; }
.article ol li { list-style: decimal; }
.article blockquote {
  margin: var(--sp-5) 0; padding: var(--sp-3) var(--sp-5);
  border-left: 3px solid var(--accent); background: var(--bg-alt);
  font-size: var(--t-lead); color: var(--ink);
}
.article blockquote p { margin: 0; }

/* --- footer (the one dark surface on the site) --------------------------- */

.site-footer { background: var(--ink); color: var(--on-dark); padding-block: var(--sp-8) var(--sp-5); }
.footer-grid { display: grid; gap: var(--sp-6); }
@media (min-width: 760px) { .footer-grid { grid-template-columns: 1.2fr repeat(3, 1fr); } }
.footer-grid h3 { font-size: var(--t-meta); font-weight: 600; margin-bottom: var(--sp-3); color: #fff; }
.footer-grid li + li { margin-top: 9px; }
.footer-grid a { font-size: var(--t-meta); color: var(--on-dark-dim); }
.footer-grid a:hover { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.footer-brand img { width: 150px; margin-bottom: var(--sp-4); }
.footer-brand p { font-size: var(--t-meta); color: var(--on-dark-dim); max-width: 34ch; }
.footer-bottom {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-3); margin-top: var(--sp-7); padding-top: var(--sp-4);
  border-top: 1px solid #2E3535;
  font-size: var(--t-micro); color: var(--on-dark-dim);
}

/* --- misc ---------------------------------------------------------------- */

.eyebrow {
  font-size: var(--t-micro); font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent); margin-bottom: var(--sp-3);
}
.lead { font-size: var(--t-lead); color: var(--text-dim); }
.center { text-align: center; }
.center .lead { margin-inline: auto; max-width: 56ch; }
.center .hero-cta { justify-content: center; }
.stack > * + * { margin-top: var(--sp-4); }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }

.pill-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.pill {
  padding: 6px 13px; border-radius: 99px; border: 1px solid var(--line-strong);
  font-size: var(--t-micro); font-weight: 600; color: var(--ink); background: var(--surface);
}
.chip-soon {
  padding: 3px 8px; border-radius: 4px; background: var(--ink); color: #fff;
  font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
}

.crumb { font-size: var(--t-micro); color: var(--text-dim); margin-bottom: var(--sp-3); }
.crumb a:hover { color: var(--accent); text-decoration: underline; }

.dots { display: flex; justify-content: center; gap: 8px; margin-top: var(--sp-4); }
.dots button { width: 26px; height: 4px; border-radius: 99px; background: var(--line-strong); }
.dots button[aria-current="true"] { background: var(--accent); }

.panel {
  padding: var(--sp-6); border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow-card);
}

/* reveal-on-scroll is scoped under .js so a JS-disabled render shows
   everything. The previous build shipped 57 elements at opacity:0 and 97% of
   the page was blank without JS — that is what this scoping prevents. */
.js .reveal { opacity: 0; transform: translateY(14px); }
.js .reveal.in { opacity: 1; transform: none; transition: opacity .5s ease, transform .5s ease; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; }
  .js .reveal.in { transition: none; }
}

/* --- page to page ---------------------------------------------------------
   A soft cross-fade between every page of the site, done by the browser
   (Chrome, Edge, Safari 18.2 and later; other browsers cut, and /books/ fades
   itself in and out with its own script). Asked for by the client on
   2026-09-10 for the Books tab, in and out. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation-duration: .34s; }
::view-transition-new(root) { animation-duration: .34s; }

/* build stamp — bump this line to force a new asset URL if an edge ever caches a stale
   copy under the current one (it happened once, 2026-09-10, when a check fetched the
   new URL before the deploy had propagated). stamp: 2026-09-10 r2 */
