/* ==========================================================================
   Esther Findlay — estherfindlay.ca
   Design system derived from the "Empowered Women" book jacket.

   Palette sampled directly from the cover artwork:
     stone   #D5D3CE  jacket background
     ink     #221F20  "EMPOWERED"
     oxblood #66343D  back-cover headings & diamond ornaments
     plum    #4A3034  "WOMEN"
     gold    #D0B680  hairline rules & the EF monogram
     bronze / tan / cream — the silhouette gradient artwork
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Neutrals — warm, taken from the jacket stock */
  --paper:        #FCFBF9;
  --paper-alt:    #F5F3EF;
  --stone-100:    #EFECE6;
  --stone-200:    #E3E0D9;
  --stone-300:    #D5D3CE;
  --stone-400:    #BAB6AE;
  /* Control boundary. stone-400 is only 1.95:1 on paper, so the edge of a
     button or a field was invisible under WCAG 1.4.11 (3:1 for non-text UI).
     This is the same jacket stone taken down to 3.65:1 on paper. */
  --stone-500:    #86837D;

  /* Ink */
  --ink:          #221F20;
  --ink-80:       #3A3634;
  --ink-70:       #4A4644;
  --ink-55:       #6B6662;

  /* Brand accents */
  --oxblood:      #66343D;
  --oxblood-dark: #4A2830;
  --oxblood-soft: #F3EAEB;
  --plum:         #4A3034;
  --gold:         #C9A96A;
  --gold-line:    #D0B680;
  /* The jacket gold reads at 2.24:1 on white — fine as a hairline, illegible
     as type. This is the same hue deepened until it clears 4.5:1 on every
     light surface we use (5.7 paper / 5.9 white / 5.3 paper-alt / 5.0 stone).
     Rule: --gold and --gold-line draw, --gold-ink writes. */
  --gold-ink:     #75623D;
  --bronze:       #B36234;
  --tan:          #E5C7A9;
  --cream:        #E8D2BC;

  /* The silhouette spectrum from the cover — used as a hairline motif */
  --spectrum: linear-gradient(90deg,
      #F0DCC6 0%, #E5C7A9 12%, #CF9870 26%, #C8864F 38%,
      #B36234 50%, #8A4A28 62%, #5A3A2E 74%, #392E2C 86%, #1F1F1F 100%);

  /* Type */
  --font-display: "Oswald", "Haettenschweiler", "Arial Narrow", sans-serif;
  --font-serif:   "EB Garamond", "Iowan Old Style", Georgia, "Times New Roman", serif;
  --font-sans:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Rhythm
     One spacing ramp, roughly x1.45 a step, so nothing in the page is spaced
     by a number that was picked by eye. --sp-5 and up are "between blocks";
     --sp-1..4 are "inside a block". */
  --sp-1:         .375rem;
  --sp-2:         .625rem;
  --sp-3:         1rem;
  --sp-4:         1.5rem;
  --sp-5:         2.25rem;
  --sp-6:         3.25rem;
  --sp-7:         4.5rem;

  /* The single most useful rule on the page: the gap ABOVE a heading is
     roughly 2x the gap below it, so a heading is bound to the copy it owns
     rather than floating between two blocks. */
  --lead-in:      var(--sp-5);
  --lead-out:     .55em;

  --wrap:         1180px;
  --wrap-narrow:  760px;
  --gutter:       clamp(20px, 5vw, 48px);

  /* Three section heights, not nine. Every band now picks one of these
     instead of carrying its own hand-tuned clamp. */
  --section-y-sm: clamp(48px, 6vw, 80px);
  --section-y:    clamp(72px, 9vw, 128px);
  --section-y-lg: clamp(88px, 11vw, 152px);

  /* Small-caps tracking, one value, so eyebrows / meta / buttons agree */
  --track-caps:   .15em;

  --radius:       3px;
  --radius-lg:    5px;

  --shadow-sm:    0 1px 2px rgba(34, 31, 32, .05);
  --shadow-md:    0 10px 30px -14px rgba(34, 31, 32, .28);
  --shadow-lg:    0 30px 60px -28px rgba(34, 31, 32, .42);

  --ease:         cubic-bezier(.22, .61, .36, 1);
}

/* --------------------------------------------------------------------------
   2. Reset & base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* iOS lets the visitor pinch out as far as the widest element on the page
     and then leaves them there. Clipping at the root means a stray wide
     element can never widen the page and strand them zoomed out. */
  overflow-x: hidden;
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-80);
  font-family: var(--font-sans);
  font-size: clamp(1rem, .97rem + .18vw, 1.0625rem);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  /* clip rather than hidden where supported: iOS Safari can still be dragged
     sideways past an overflow-x: hidden body, and clip never creates a
     scroll container, so the sticky header keeps working. */
  overflow-x: clip;
  /* iOS paints a grey box over anything tapped. A faint oxblood wash is the
     same feedback in the site's own colour. */
  -webkit-tap-highlight-color: rgba(102, 52, 61, .12);
}

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

h1, h2, h3, h4, h5, h6 { margin: 0 0 .5em; color: var(--ink); line-height: 1.15; }
p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0 0 1.15em; padding-left: 1.25em; }
li { margin-bottom: .4em; }

a { color: var(--oxblood); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { color: var(--oxblood-dark); }

hr { border: 0; border-top: 1px solid var(--stone-200); margin: 2.5rem 0; }

/* Two separate rules, not one comma-separated selector list: a browser that
   does not recognise ::-moz-selection treats the whole selector list as
   invalid and drops the entire rule — including the ::selection part that
   it does understand. Splitting them means each browser only ever discards
   the line it doesn't need.
   White on oxblood measures 9.89:1 — comfortably past the 4.5:1 floor, and
   the same brand ink used everywhere else, not the browser's default blue. */
::selection { background: var(--oxblood); color: #fff; }
::-moz-selection { background: var(--oxblood); color: #fff; }

/* Decorative artwork and interactive controls are not copy: a stray drag
   across the 3D book, an icon or a button label should not paint a text
   selection over it the way a paragraph does — that is what made the whole
   page read as unfinished. This is one consolidated list rather than
   one-off rules scattered through the file, so a new control gets added
   here, not somewhere else. Genuine copy — body text, headings, ledes,
   quotes, detail-list values, article prose and form fields — is untouched
   and stays selectable. */
img,
svg,
.book3d,
.book3d *,
.btn,
.icon-btn,
.nav__toggle,
.filter,
.cta-tile__step,
.ornament,
.ornament__mark,
.spectrum-rule,
.podcast__transport,
.podcast__seek,
.podcast__rate,
.footer-social a {
  user-select: none;
  -webkit-user-select: none;
}
/* Images also should never be picked up and ghost-dragged around the page. */
img { -webkit-user-drag: none; }

/* Visible, consistent focus for keyboard users.
   The ring is a variable, not a literal, because oxblood on the ink surfaces
   measures 1.65:1 — a focus ring nobody can see. Dark bands re-point
   --ring at the gold (8.32:1 on ink) further down. */
:root { --ring: var(--oxblood); }

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

/* Dark surfaces: swap the ring rather than restating it per component. */
.section--ink,
.statement,
.photo-band,
.site-footer { --ring: var(--gold-line); }

.skip-link {
  position: absolute; left: 12px; top: -100px; z-index: 200;
  background: var(--ink); color: #fff; padding: 12px 20px;
  font: 600 .875rem/1 var(--font-sans); border-radius: var(--radius);
  transition: top .18s var(--ease);
}
.skip-link:focus { top: 12px; color: #fff; }

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

/* --------------------------------------------------------------------------
   3. Typography
   -------------------------------------------------------------------------- */

/* The scale.
   It used to be six independent clamps, which meant display-lg finished
   LARGER than display-xl (3.5 vs 3.4rem) and h-section (3rem) outran
   display-md (2.6rem). Every step below is now a real ratio, ~1.29 between
   display sizes, and every clamp grows across the same 375px -> 1140px
   window so the whole page reaches full size at the same moment.

   The three families do not have the same cap height at the same nominal
   size — Oswald ~.73em, EB Garamond ~.66em, Inter ~.72em — so the serif
   steps are set larger on purpose. They are sized to LOOK a step apart,
   which is not the same as measuring a step apart.

     display-xl   3.90rem  Oswald      page hero, once
     display-lg   3.05rem  Oswald      band headline
     h-section    2.70rem  Garamond   (optically ~2.44 — sits between)
     display-md   2.35rem  Oswald      sub-band
     h-sub        1.80rem  Garamond
     lede         1.45rem  Garamond   (optically ~1.20x body)
     body         1.0625rem Inter
     small        0.875rem  Inter
*/

/* Display — echoes the condensed uppercase of the book title. Used sparingly.
   Oswald opens up as it grows, so the tracking closes as it grows: negative
   at hero size, near zero by the smallest step. */
.display-xl, .display-lg, .display-md {
  font-family: var(--font-display);
  font-weight: 600;
  text-transform: uppercase;
  line-height: 1.1;
  color: var(--ink);
  text-wrap: balance;
}
.display-xl { font-size: clamp(2.15rem, 1.29rem + 3.66vw, 3.9rem);  letter-spacing: -.018em; }
.display-lg { font-size: clamp(2rem,    1.49rem + 2.2vw,  3.05rem); letter-spacing: -.014em; }
.display-md { font-size: clamp(1.7rem,  1.38rem + 1.36vw, 2.35rem); letter-spacing: -.006em; }

/* Controlled line breaks on display headings; the closing line takes the
   cover's plum, echoing EMPOWERED / WOMEN on the jacket. */
.display-line { display: block; }
.display-accent { display: block; color: var(--plum); }

/* Section headings — editorial serif, sentence case, calm */
.h-section {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(1.85rem, 1.43rem + 1.78vw, 2.7rem);
  line-height: 1.18;
  letter-spacing: -.008em;
  text-wrap: balance;
  /* A heading is only as good as its measure. Across a 1180px wrap a section
     heading was running to 60+ characters on one line, which reads as a
     banner rather than a heading. ~28 characters is the editorial measure. */
  max-width: 26ch;
}
/* Centred heads centre their own measure too. */
.section-head--center .h-section,
.cta-band .h-section,
.statement .h-section,
.center .h-section { margin-inline: auto; }

.h-sub {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(1.3rem, 1.055rem + 1.05vw, 1.8rem);
  line-height: 1.25;
  letter-spacing: -.004em;
  text-wrap: balance;
}

/* Eyebrow — small uppercase label above a heading */
/* Small type set in caps needs the tracking OPENED, not closed — the
   opposite correction to the display sizes above. */
.eyebrow {
  display: flex; align-items: center; gap: .7em;
  margin: 0 0 var(--sp-3);
  font: 600 .75rem/1.2 var(--font-sans);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--oxblood);
}
.eyebrow::before {
  content: ""; width: 28px; height: 1px; flex: none;
  background: var(--gold-line);
}
.eyebrow--center { justify-content: center; }
.eyebrow--center::after {
  content: ""; width: 28px; height: 1px; flex: none;
  background: var(--gold-line);
}

/* Lede. Garamond at 1.45rem reads about 20% larger than Inter body, which is
   the optical step we want. It may run wider than body copy but it must not
   run the full 1180px wrap — ~56ch of Garamond is about 62 characters. */
.lede {
  font-family: var(--font-serif);
  font-size: clamp(1.15rem, 1rem + .63vw, 1.45rem);
  line-height: 1.55;
  color: var(--ink-70);
  max-width: 56ch;
}
.section-head--center .lede,
.cta-band .lede,
.center .lede { margin-inline: auto; }

.muted { color: var(--ink-55); }
.small { font-size: .875rem; line-height: 1.6; }

/* Long-form article body.
   68ch of Inter is ~83 characters, past the comfortable range. 60ch lands
   at ~72, inside the 60-75 the eye tracks without losing its place. */
.prose { max-width: 60ch; font-size: 1.075rem; line-height: 1.65; }
/* Space above a heading > space below it, so each heading owns what follows. */
.prose h2 { font-family: var(--font-serif); font-weight: 500; font-size: clamp(1.55rem, 1.34rem + .9vw, 2rem); line-height: 1.22; letter-spacing: -.004em; margin: 2.1em 0 .45em; }
.prose h3 { font-family: var(--font-serif); font-weight: 600; font-size: clamp(1.25rem, 1.16rem + .38vw, 1.45rem); line-height: 1.3; margin: 1.8em 0 .35em; }
.prose h2:first-child, .prose h3:first-child { margin-top: 0; }
.prose ul, .prose ol { padding-left: 1.3em; }
.prose li { margin-bottom: .55em; }
.prose blockquote { margin: 2em 0; }

/* Pull quote — lifted from the jacket's quotation treatment */
blockquote.pull {
  margin: 0; padding: 0 0 0 var(--sp-4);
  border-left: 2px solid var(--gold-line);
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(1.2rem, 1.05rem + .8vw, 1.6rem);
  line-height: 1.45;
  color: var(--ink);
}
blockquote.pull cite {
  display: block; margin-top: var(--sp-3);
  font: 600 .8rem/1.4 var(--font-sans);
  font-style: normal; letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--oxblood);
}

/* --------------------------------------------------------------------------
   4. Layout
   -------------------------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }
/* With viewport-fit=cover the page runs under the notch in landscape, so the
   gutter grows to at least the safe-area inset on that side. */
@supports (padding: max(0px)) {
  .wrap {
    padding-left:  max(var(--gutter), env(safe-area-inset-left));
    padding-right: max(var(--gutter), env(safe-area-inset-right));
  }
}
.wrap--narrow { max-width: var(--wrap-narrow); }

.section { padding-block: var(--section-y); }
.section--tight { padding-block: var(--section-y-sm); }
.section--alt { background: var(--paper-alt); }
.section--stone { background: var(--stone-100); }
.section--ink { background: var(--ink); color: var(--stone-300); }
.section--ink h1, .section--ink h2, .section--ink h3,
.section--ink h4, .section--ink .h-section, .section--ink .h-sub { color: #fff; }
.section--ink .eyebrow { color: var(--gold); }
.section--ink .lede { color: var(--stone-300); }
/* ink-55 on the ink surface is 2.88:1. Anything "muted" inside a dark band
   has to become lighter, not darker, or it disappears. */
.section--ink .muted,
.section--ink .card__text,
.section--ink .card__meta,
.section--ink figcaption { color: rgba(213, 211, 206, .82); }

.section-head { max-width: 62ch; margin-bottom: clamp(2.5rem, 4vw, 3.75rem); }
.section-head--center { margin-inline: auto; text-align: center; }
.section-head--center .eyebrow { justify-content: center; }
.section-head--center .eyebrow::after {
  content: ""; width: 28px; height: 1px; flex: none; background: var(--gold-line);
}

.grid { display: grid; gap: clamp(1.25rem, 2.4vw, 2rem); align-items: stretch; }
/* auto-fill, not auto-fit: with auto-fit the empty tracks collapse, so a
   filter that matches one item stretches that card across the whole row.
   auto-fill keeps the columns, so filtered results stay card-sized. */
.grid--2 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 290px), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 230px), 1fr)); }

/* Messages and notices inside a grid span the full row rather than sitting
   in the first column. */
.grid > .empty-state,
.grid > .grid-full { grid-column: 1 / -1; }

/* Results fade in when a filter changes, so the grid never appears to jump. */
.grid.is-swapping { opacity: 0; }
.grid { transition: opacity .18s var(--ease); }

/* Vertical rhythm inside a text block.
   The old rule gave a heading exactly the same air as a paragraph, so every
   heading floated equidistant between the block above and the block below
   and read as unattached. Headings now get --lead-in above (about twice
   their own --lead-out below), which is what makes a page feel edited. */
.stack > * + * { margin-top: var(--sp-3); }
.stack > * + :is(h2, h3, h4, .h-section, .h-sub, .eyebrow, .ornament) {
  margin-top: var(--lead-in);
}
.stack > :is(h2, h3, h4, .h-section, .h-sub) { margin-bottom: var(--lead-out); }
/* An eyebrow belongs to the heading under it, not to the paragraph above it. */
.stack > .eyebrow + * { margin-top: 0; }
/* Body copy keeps its measure even when the column around it is wide. */
.stack > p { max-width: 66ch; }

.center { text-align: center; }

/* Split layout: media beside copy */
.split {
  display: grid; align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
  grid-template-columns: 1fr;
}
@media (min-width: 860px) {
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .sticky-media { position: sticky; top: 108px; }
  .split--media-right > .split__media { order: 2; }
  .split--narrow-media { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  /* Long-form content column beside a narrower sidebar. */
  .split--wide-main { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
}

/* --------------------------------------------------------------------------
   5. Ornaments — the jacket's gold rule + diamond, and the spectrum hairline
   -------------------------------------------------------------------------- */
.spectrum-rule {
  height: 3px; width: 100%; border: 0; margin: 0;
  background: var(--spectrum);
}
.spectrum-rule--top { position: relative; z-index: 60; }

.ornament {
  display: flex; align-items: center; justify-content: center;
  gap: 14px; margin: 0 0 1.6rem;
}
.ornament::before, .ornament::after {
  content: ""; height: 1px; width: clamp(48px, 12vw, 110px);
  background: linear-gradient(90deg, transparent, var(--gold-line), transparent);
}
.ornament__mark {
  width: 9px; height: 9px; flex: none;
  background: var(--gold-line);
  transform: rotate(45deg);
}
.ornament--start { justify-content: flex-start; }
.ornament--start::before { display: none; }

/* --------------------------------------------------------------------------
   6. Buttons
   -------------------------------------------------------------------------- */
/* Three tiers of weight, and they must not look like two.
   Filled + shadow + wider padding + bold (700) = primary. Hairline + quieter
   ink + light (500) = secondary. No box at all, same light 500 = tertiary.
   The 200-unit weight spread between primary and everything else is on top
   of the fill/hairline/box difference, not instead of it — belt and braces,
   so "Get the Book" is unmistakable even skimmed, not just read closely. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .6em;
  min-height: 48px;
  padding: .85em 1.6em;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font: 600 .875rem/1.2 var(--font-sans);
  /* Buttons are a small-caps label like an eyebrow or a meta line, so they
     share the one tracking value instead of picking their own. */
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  max-width: 100%;
  cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease),
              border-color .2s var(--ease), transform .2s var(--ease),
              box-shadow .2s var(--ease);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(1px); transition-duration: .06s; }
.btn:focus-visible { outline-offset: 3px; }

/* Primary — the only tier that carries a fill, a shadow AND bold weight. */
.btn--primary {
  background: var(--oxblood); border-color: var(--oxblood); color: #fff;
  font-weight: 700;
  padding-inline: 1.9em;
  box-shadow: 0 6px 18px -10px rgba(102, 52, 61, .75);
}
.btn--primary:hover {
  background: var(--oxblood-dark); border-color: var(--oxblood-dark); color: #fff;
  box-shadow: 0 12px 26px -12px rgba(102, 52, 61, .85);
}
.btn--primary:active { background: var(--oxblood-dark); box-shadow: 0 2px 8px -6px rgba(102,52,61,.9); }

/* Secondary — deliberately pulled DOWN so the gap to primary is unmistakable:
   ink-70 rather than full ink, a hairline that still clears 3:1 (3.65), and
   500-weight text next to primary's 700. */
.btn--outline {
  border-color: var(--stone-500); color: var(--ink-70); background: transparent;
  font-weight: 500;
}
.btn--outline:hover { border-color: var(--ink); background: var(--ink); color: #fff; }
.btn--outline:active { background: var(--ink-80); border-color: var(--ink-80); color: #fff; }

/* Tertiary — no box at all, same light weight as secondary; the box is what
   tells secondary and tertiary apart, not the type. */
.btn--ghost { color: var(--ink-70); background: transparent; font-weight: 500; padding-inline: 0; }
.btn--ghost:hover { color: var(--oxblood); }
.btn--ghost:active { color: var(--oxblood-dark); }
.btn--ghost:focus-visible { outline-offset: 3px; border-radius: 2px; }

/* Secondary on a dark or photographic surface. */
.btn--onink { border-color: rgba(255,255,255,.55); color: #fff; font-weight: 500; }
.btn--onink:hover { background: #fff; color: var(--ink); border-color: #fff; }
.btn--onink:active { background: var(--stone-200); color: var(--ink); border-color: var(--stone-200); }

/* Primary-weight fill for a dark or photographic surface. */
.btn--light { background: #fff; color: var(--ink); font-weight: 700; box-shadow: var(--shadow-sm); }
.btn--light:hover { background: var(--stone-100); color: var(--ink); box-shadow: var(--shadow-md); }
.btn--light:active { background: var(--stone-200); color: var(--ink); box-shadow: var(--shadow-sm); }

.btn--sm { min-height: 48px; padding: .65em 1.1em; font-size: .78rem; }
.btn--primary.btn--sm { padding-inline: 1.35em; }
.btn--full { width: 100%; }

/* "Get the Book" is the site's single most valuable action, so wherever it
   appears it outranks whatever else is in the row: a touch more air in the
   tracking, a wider box, and the gold hairline of the jacket under it on
   hover. [data-book-cta] is already on every one of these links. */
[data-book-cta].btn--primary {
  letter-spacing: calc(var(--track-caps) + .02em);
  padding-inline: 2.15em;
  box-shadow: 0 8px 22px -10px rgba(102, 52, 61, .8), inset 0 -2px 0 rgba(208, 182, 128, .55);
}
[data-book-cta].btn--primary:hover {
  box-shadow: 0 14px 30px -12px rgba(102, 52, 61, .9), inset 0 -2px 0 var(--gold-line);
}
[data-book-cta].btn--primary.btn--sm { padding-inline: 1.5em; }
[data-book-cta].btn--light {
  letter-spacing: calc(var(--track-caps) + .02em);
  box-shadow: var(--shadow-md), inset 0 -2px 0 var(--gold-line);
}
[data-book-cta].btn--light:hover { box-shadow: var(--shadow-lg), inset 0 -2px 0 var(--gold-line); }

.btn-row { display: flex; flex-wrap: wrap; gap: 1.1rem 1.5rem; align-items: center; }
.btn-row--center { justify-content: center; }
/* A bordered/filled .btn reads its own edge as the end of the row; a
   borderless .link-arrow or .btn--ghost has no edge, so at the row's base
   gap it optically crowds whatever comes before it. Give it extra room so
   the two read as evenly spaced rather than "smushed to the left". */
.btn-row > .btn + .btn--ghost,
.btn-row > .btn + .link-arrow { margin-inline-start: .5rem; }
@media (max-width: 480px) {
  /* Once the row wraps, that extra start margin reads as a stray indent on
     its own line rather than breathing room — the gap alone is enough. */
  .btn-row > .btn + .btn--ghost,
  .btn-row > .btn + .link-arrow { margin-inline-start: 0; }
}

/* Text link with an animated underline */
.link-arrow {
  display: inline-flex; align-items: center; gap: .5em;
  font: 600 .8125rem/1.2 var(--font-sans);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--oxblood); text-decoration: none;
}
.link-arrow span { position: relative; padding-bottom: 3px; }
.link-arrow span::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 1px; width: 100%;
  background: currentColor; transform-origin: left;
  transform: scaleX(0); transition: transform .28s var(--ease);
}
.link-arrow:hover span::after, .card:hover .link-arrow span::after { transform: scaleX(1); }
.link-arrow svg { transition: transform .28s var(--ease); flex: none; }
.link-arrow:hover svg, .card:hover .link-arrow svg { transform: translateX(4px); }

/* --------------------------------------------------------------------------
   7. Header & navigation
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(252, 251, 249, .86);
  backdrop-filter: saturate(150%) blur(12px);
  -webkit-backdrop-filter: saturate(150%) blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color .25s var(--ease), box-shadow .25s var(--ease),
              background-color .25s var(--ease);
}
.site-header.is-stuck {
  border-bottom-color: var(--stone-200);
  box-shadow: 0 1px 20px -10px rgba(34,31,32,.3);
}

.nav {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.25rem; min-height: 76px;
}

.brand { display: inline-flex; align-items: center; gap: .7rem; text-decoration: none; }
.brand img { width: 44px; height: 44px; flex: none; }
.brand__name {
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.0625rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink); line-height: 1;
}
.brand__tag {
  display: block; margin-top: 3px;
  font: 500 .625rem/1 var(--font-sans);
  letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--ink-55);
  white-space: nowrap;
}
.brand:hover .brand__name { color: var(--oxblood); }

.nav__menu { display: flex; align-items: center; gap: clamp(.5rem, 1.5vw, 1.4rem); }
.nav__list { display: flex; align-items: center; gap: clamp(.4rem, 1.4vw, 1.15rem); list-style: none; margin: 0; padding: 0; }
.nav__list li { margin: 0; }

.nav__link {
  position: relative; display: block; padding: .55rem .25rem;
  font: 500 .9375rem/1.4 var(--font-sans);
  color: var(--ink-70); text-decoration: none; white-space: nowrap;
  transition: color .2s var(--ease);
}
.nav__link::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: var(--oxblood);
  transform: scaleX(0); transform-origin: center;
  transition: transform .26s var(--ease);
}
.nav__link:hover { color: var(--ink); }
.nav__link:hover::after { transform: scaleX(.6); }
.nav__link[aria-current="page"] { color: var(--ink); font-weight: 600; }
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

.nav__actions { display: flex; align-items: center; gap: .75rem; }

/* Subtle LinkedIn icon button — deliberately quiet next to the book CTA.
   48px, not the 42px it measured at: a circular tap target under 48px fails
   the site's own touch-target floor even though it looks "big enough". */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; flex: none;
  border: 1px solid var(--stone-200); border-radius: 50%;
  color: var(--ink-70); background: transparent; text-decoration: none;
  transition: color .2s var(--ease), border-color .2s var(--ease), background-color .2s var(--ease);
}
.icon-btn:hover { color: var(--oxblood); border-color: var(--oxblood); background: var(--oxblood-soft); }
.icon-btn:active { color: var(--oxblood-dark); border-color: var(--oxblood-dark); background: var(--oxblood-soft); }
/* The global focus ring is squared off at 2px; on a circle that reads as a
   dent rather than a ring, so round controls get their own round outline. */
.icon-btn:focus-visible { outline-offset: 3px; border-radius: 50%; }
.icon-btn svg { width: 18px; height: 18px; }

/* Mobile menu toggle */
.nav__toggle {
  display: none; align-items: center; justify-content: center;
  width: 48px; height: 48px; flex: none;
  padding: 0; background: transparent;
  border: 1px solid var(--stone-200); border-radius: var(--radius);
  cursor: pointer; color: var(--ink);
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.nav__toggle:hover { border-color: var(--stone-400); background: var(--paper-alt); }
.nav__toggle:active { background: var(--stone-100); }
.nav__toggle span {
  display: block; position: relative; width: 20px; height: 2px;
  background: currentColor; border-radius: 2px;
  transition: background-color .18s var(--ease);
}
.nav__toggle span::before, .nav__toggle span::after {
  content: ""; position: absolute; left: 0; width: 20px; height: 2px;
  background: currentColor; border-radius: 2px;
  transition: transform .26s var(--ease);
}
.nav__toggle span::before { top: -6px; }
.nav__toggle span::after  { top: 6px; }
.nav__toggle[aria-expanded="true"] span { background: transparent; }
.nav__toggle[aria-expanded="true"] span::before { transform: translateY(6px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span::after  { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 1080px) {
  /* A backdrop-filter makes the header a containing block for fixed-position
     descendants, which would trap the off-canvas menu inside the header box.
     The header goes solid at this width instead. */
  .site-header {
    background: var(--paper);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  /* Keep the toggle above the open panel so it doubles as the close button. */
  .nav__toggle { display: inline-flex; position: relative; z-index: 60; }
  .nav__menu {
    position: fixed; inset: 0 0 0 auto;
    width: min(88vw, 380px);
    flex-direction: column; align-items: stretch; justify-content: flex-start;
    gap: 0; padding: 96px var(--gutter) 40px;
    padding-right: max(var(--gutter), env(safe-area-inset-right));
    padding-bottom: calc(40px + env(safe-area-inset-bottom));
    /* Reaching the end of the menu must not start scrolling the page under it. */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    background: var(--paper);
    border-left: 1px solid var(--stone-200);
    box-shadow: var(--shadow-lg);
    overflow-y: auto;
    /* Revealed with clip-path rather than a translate: an off-canvas panel
       positioned outside the viewport adds horizontal scroll on some browsers
       even when fixed. Clipping keeps the geometry inside the viewport. */
    clip-path: inset(0 0 0 100%);
    visibility: hidden;
    transition: clip-path .38s var(--ease), visibility 0s linear .38s;
  }
  .nav__menu.is-open {
    clip-path: inset(0 0 0 0);
    visibility: visible;
    transition: clip-path .38s var(--ease), visibility 0s;
  }
  .nav__menu > * { transform: translateX(18px); transition: transform .38s var(--ease); }
  .nav__menu.is-open > * { transform: none; }
  .nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav__link {
    padding: 1.05rem 0; font-size: 1.125rem;
    border-bottom: 1px solid var(--stone-200);
  }
  .nav__link::after { display: none; }
  .nav__link[aria-current="page"] { color: var(--oxblood); }
  .nav__actions { flex-direction: column; align-items: stretch; gap: var(--sp-3); margin-top: 1.75rem; }
  .nav__actions .btn { width: 100%; }
  .nav__actions .icon-btn {
    width: 100%; height: 48px; gap: .6rem;
    border-radius: var(--radius);
  }
  /* Square in the stacked mobile menu, so the focus ring should be square too. */
  .nav__actions .icon-btn:focus-visible { border-radius: 2px; }
  .nav__actions .icon-btn::after {
    content: "Connect on LinkedIn";
    font: 600 .8125rem/1 var(--font-sans);
    letter-spacing: var(--track-caps); text-transform: uppercase;
  }
  .nav-backdrop {
    position: fixed; inset: 0; z-index: 40;
    background: rgba(34, 31, 32, .42);
    opacity: 0; pointer-events: none;
    transition: opacity .3s var(--ease);
  }
  .nav-backdrop.is-open { opacity: 1; pointer-events: auto; }
  body.nav-open { overflow: hidden; }
}

/* Between the hamburger breakpoint and full width the seven labels, the brand
   and the CTA are a tight fit, so the nav trims itself rather than pushing the
   "Get the Book" button off the edge. */
@media (min-width: 1081px) and (max-width: 1220px) {
  .nav { gap: var(--sp-3); }
  .brand__tag { display: none; }
  .brand img { width: 38px; height: 38px; }
  .nav__list { gap: .55rem; }
  .nav__link { font-size: .875rem; }
  .nav__menu { gap: .75rem; }
  .nav__actions { gap: .55rem; }
  .nav__actions .btn { padding-inline: 1.05em; letter-spacing: .07em; }
  /* This band only exists between the hamburger breakpoint and full width —
     a mouse/trackpad range, not a touch one — so the icon is allowed to trim
     below the 48px touch floor here, unlike everywhere else it appears. */
  .icon-btn { width: 40px; height: 40px; }
}

/* --------------------------------------------------------------------------
   8. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  /* Asymmetric on purpose: the hero owes more air to the section under it
     than to the header above it. Both values are now scale stops. */
  padding-block: var(--section-y-sm) var(--section-y);
  background:
    radial-gradient(120% 90% at 88% 8%, rgba(213, 211, 206, .55) 0%, rgba(213, 211, 206, 0) 60%),
    linear-gradient(180deg, var(--paper) 0%, var(--paper-alt) 100%);
  overflow: hidden;
}
.hero__inner {
  display: grid; gap: clamp(2.5rem, 6vw, 5rem);
  grid-template-columns: 1fr; align-items: center;
}
@media (min-width: 900px) {
  .hero__inner { grid-template-columns: minmax(0, 1.22fr) minmax(0, .78fr); }
}
.hero__title { margin-bottom: 1.1rem; }
.hero__lede { max-width: 46ch; }
.hero__actions { margin-top: 2.1rem; }
.hero__meta {
  margin-top: 2.4rem; padding-top: 1.6rem;
  border-top: 1px solid var(--stone-200);
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) 1.75rem;
}


/* --------------------------------------------------------------------------
   9. Cards
   -------------------------------------------------------------------------- */
.card {
  position: relative; display: flex; flex-direction: column;
  padding: clamp(1.5rem, 2.6vw, 2.1rem);
  background: #fff;
  border: 1px solid var(--stone-200);
  border-radius: var(--radius);
  text-decoration: none; color: inherit;
  transition: box-shadow .25s var(--ease), transform .25s var(--ease);
}
/* Restraint: a lift + a growing shadow already reads as "this rose up" on
   its own. Also changing the border on hover was a third, redundant echo of
   the same elevation cue, and a fourth on .card--accent cards once the
   spectrum bar reveals too — so the border stays put. */
.card:hover { box-shadow: var(--shadow-md); transform: translateY(-3px); }
/* Card links sit edge-to-edge in a grid and .card--accent clips its own
   overflow, so an outside ring would be cut off by the neighbouring card or
   the card's own edge. Pulling it inward keeps it fully visible. */
.card:focus-visible { outline-offset: -3px; }
.card__title {
  font-family: var(--font-serif); font-weight: 600;
  font-size: 1.3125rem; line-height: 1.25; margin: 0 0 .6rem; color: var(--ink);
}
.card__text { color: var(--ink-55); font-size: .9375rem; line-height: 1.65; margin: 0 0 1.35rem; }
.card__foot { margin-top: auto; }

/* A thin spectrum bar that reveals across the card top on hover */
.card--accent { overflow: hidden; }
.card--accent::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--spectrum);
  transform: scaleX(0); transform-origin: left;
  transition: transform .4s var(--ease);
}
.card--accent:hover::before, .card--accent:focus-within::before { transform: scaleX(1); }
/* Media cards already carry a permanent spectrum edge under the thumbnail
   (.thumb::after below) — restraint: don't reveal a second one on hover, or
   the signature motif starts to look like wallpaper instead of a signature. */
.card--media.card--accent::before { display: none; }

/* Numbered / icon lead */
.card__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; margin-bottom: 1.25rem;
  border: 1px solid var(--gold-line); border-radius: 50%;
  color: var(--oxblood); flex: none;
}
.card__icon svg { width: 20px; height: 20px; }

.card__num {
  font-family: var(--font-display); font-weight: 500; font-size: 1.05rem;
  letter-spacing: var(--track-caps);
  /* This sits on a white card, not the ink surface below — gold-ink writes,
     gold only draws (5.88:1 here vs 2.24:1 for the raw jacket gold). */
  color: var(--gold-ink);
  margin-bottom: var(--sp-3);
}

/* Meta line: category · date · duration */
.card__meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .85rem;
  margin: 0 0 .9rem;
  font: 600 .6875rem/1.4 var(--font-sans);
  letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--ink-55);
}
.card__meta .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--stone-400); }

.tag {
  display: inline-block; padding: .35em .7em;
  border: 1px solid var(--stone-200); border-radius: 2px;
  background: var(--paper-alt);
  font: 600 .6875rem/1.3 var(--font-sans);
  letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--oxblood);
}
.tag--gold { border-color: var(--gold-line); color: var(--plum); background: transparent; }

/* Card with a cover/thumbnail area. No stock photography — a typographic
   plate built from the brand palette stands in until real art exists. */
.card--media { padding: 0; overflow: hidden; }
.card--media .card__body { padding: clamp(1.4rem, 2.4vw, 1.9rem); display: flex; flex-direction: column; flex: 1; }
.thumb {
  position: relative; aspect-ratio: 16 / 9;
  display: flex; align-items: flex-end; padding: 1.1rem 1.25rem;
  background: var(--stone-100);
  border-bottom: 1px solid var(--stone-200);
  overflow: hidden;
}
.thumb::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: var(--spectrum);
}
.thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.thumb__label {
  position: relative;
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(1.3rem, 1rem + 1vw, 1.7rem);
  line-height: 1.05; text-transform: uppercase; letter-spacing: .02em;
  color: var(--ink-70); text-wrap: balance;
}
/* The four tints below were picked by eye against the darker end of each
   gradient and read at 1.8-3.5:1 against the lighter end — a category name
   a visitor is meant to read, not a decorative wash. Replaced with the
   nearest brand ink from the established palette, checked against the
   lighter stop of each gradient (the worst case): 8.0 / 8.3 / 7.8 / 6.9:1. */
.thumb--a { background: linear-gradient(135deg, #F1E6DA, #E5C7A9); }
.thumb--a .thumb__label { color: var(--oxblood-dark); }
.thumb--b { background: linear-gradient(135deg, #EFE9EA, #DFCBCE); }
.thumb--b .thumb__label { color: var(--plum); }
.thumb--c { background: linear-gradient(135deg, #EDEAE4, #D5D3CE); }
.thumb--c .thumb__label { color: var(--ink-70); }
.thumb--d { background: linear-gradient(135deg, #F0E4DC, #DBB79C); }
.thumb--d .thumb__label { color: var(--oxblood-dark); }

/* --------------------------------------------------------------------------
   10. Feature list (the "what you'll find here" cluster)
   -------------------------------------------------------------------------- */
.checklist { list-style: none; padding: 0; margin: 0; }
.checklist li {
  position: relative; padding-left: 1.9rem; margin-bottom: .9rem;
  color: var(--ink-70);
}
.checklist li::before {
  content: ""; position: absolute; left: 2px; top: .62em;
  width: 8px; height: 8px; background: var(--oxblood);
  transform: rotate(45deg);
}
.checklist--gold li::before { background: var(--gold-line); }

/* Numbered steps used on Challenge pages */
.steps { list-style: none; padding: 0; margin: 0; counter-reset: step; }
.steps > li {
  position: relative; counter-increment: step;
  padding: 0 0 1.75rem 3.5rem; margin: 0;
  border-left: 1px solid var(--stone-200);
  margin-left: 1.1rem;
}
.steps > li:last-child { border-left-color: transparent; padding-bottom: 0; }
.steps > li::before {
  content: counter(step, decimal-leading-zero);
  position: absolute; left: -1.1rem; top: -.15rem;
  display: flex; align-items: center; justify-content: center;
  width: 2.2rem; height: 2.2rem;
  background: var(--paper); border: 1px solid var(--gold-line); border-radius: 50%;
  font: 500 .8125rem/1 var(--font-display); letter-spacing: .04em;
  color: var(--oxblood);
}
.steps h3 { font-family: var(--font-serif); font-size: 1.2rem; margin: 0 0 .35rem; }

/* --------------------------------------------------------------------------
   11. Quote / statement bands
   -------------------------------------------------------------------------- */
.statement {
  position: relative;
  padding-block: var(--section-y-lg);
  background: var(--ink);
  color: var(--stone-300);
  text-align: center;
  overflow: hidden;
}
.statement::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--spectrum);
}
.statement__quote {
  font-family: var(--font-serif); font-style: italic; font-weight: 400;
  font-size: clamp(1.5rem, 1.05rem + 2.2vw, 2.85rem);
  line-height: 1.32; color: #fff; margin: 0 auto; max-width: 20ch;
}
.statement__cite {
  display: block; margin-top: 1.9rem;
  font: 600 .75rem/1.4 var(--font-sans);
  letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--gold);
  font-style: normal;
}

/* --------------------------------------------------------------------------
   12. LinkedIn section
   -------------------------------------------------------------------------- */
.linkedin-panel {
  display: grid; gap: clamp(1.5rem, 3vw, 2.5rem);
  align-items: center;
  padding: clamp(1.75rem, 3.4vw, 2.75rem);
  background: #fff;
  border: 1px solid var(--stone-200);
  border-radius: var(--radius);
}
@media (min-width: 780px) {
  .linkedin-panel { grid-template-columns: auto minmax(0, 1fr) auto; }
}
.linkedin-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; flex: none;
  border-radius: var(--radius);
  background: var(--ink); color: #fff;
}
.linkedin-mark svg { width: 26px; height: 26px; }

.li-note {
  margin-top: 1.25rem;
  padding: .85rem 1.1rem;
  border-left: 2px solid var(--gold-line);
  background: var(--paper-alt);
  font-size: .875rem; line-height: 1.6; color: var(--ink-55);
}

/* Placeholder slot cards — obviously empty, ready for real content */
.slot {
  display: flex; flex-direction: column; justify-content: space-between;
  min-height: 190px; padding: clamp(1.4rem, 2.4vw, 1.85rem);
  border: 1px dashed var(--stone-400); border-radius: var(--radius);
  background: repeating-linear-gradient(-45deg, transparent, transparent 9px, rgba(213,211,206,.24) 9px, rgba(213,211,206,.24) 18px);
  color: var(--ink-55);
}
.slot__label {
  font: 600 .6875rem/1.3 var(--font-sans);
  letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--ink-55);
  margin-bottom: .75rem;
}
.slot__title { font-family: var(--font-serif); font-size: 1.15rem; color: var(--ink-70); margin: 0 0 .5rem; }

/* --------------------------------------------------------------------------
   13. Forms
   -------------------------------------------------------------------------- */
.form { display: grid; gap: 1.35rem; }
.form-grid { display: grid; gap: 1.35rem; grid-template-columns: 1fr; }
@media (min-width: 660px) { .form-grid--2 { grid-template-columns: 1fr 1fr; } }

.field { display: flex; flex-direction: column; gap: .45rem; min-width: 0; }
.field > label {
  font: 600 .8125rem/1.4 var(--font-sans);
  letter-spacing: .04em; color: var(--ink);
}
.field .hint { font-size: .8125rem; color: var(--ink-55); }
.req { color: var(--oxblood); }

.input, .textarea, .select {
  width: 100%; min-height: 50px;
  padding: .75rem .9rem;
  font: 400 1rem/1.5 var(--font-sans);
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--stone-300);
  border-radius: var(--radius);
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
  -webkit-appearance: none; appearance: none;
}
.textarea { min-height: 150px; resize: vertical; line-height: 1.65; }
.select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%236B6662' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 1rem center; background-size: 12px;
  padding-right: 2.6rem;
}
.input:hover, .textarea:hover, .select:hover { border-color: var(--stone-400); }
/* outline: none is only safe here because it is replaced, not removed: a
   border-colour change that is itself 9.9:1 against white, plus a wider,
   more opaque ring than the site used to ship (.13 alpha read as barely
   there against paper). */
.input:focus, .textarea:focus, .select:focus {
  outline: none; border-color: var(--oxblood);
  box-shadow: 0 0 0 3px rgba(102, 52, 61, .28);
}
.input[aria-invalid="true"], .textarea[aria-invalid="true"], .select[aria-invalid="true"] {
  border-color: #A3352F; background: #FDF7F6;
}
.field__error {
  display: none; align-items: center; gap: .4rem;
  font: 500 .8125rem/1.4 var(--font-sans); color: #8E2F2A;
}
.field__error.is-visible { display: flex; }
.field__error::before { content: "!"; display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; flex: none; border-radius: 50%; background: #8E2F2A; color: #fff;
  font-size: .625rem; font-weight: 700; }

.form-note {
  padding: 1rem 1.15rem;
  border: 1px solid var(--stone-200); border-left: 2px solid var(--gold-line);
  border-radius: var(--radius);
  background: var(--paper-alt);
  font-size: .875rem; line-height: 1.65; color: var(--ink-55);
}

.form-status {
  display: none; padding: 1.1rem 1.25rem;
  border-radius: var(--radius);
  font-size: .9375rem; line-height: 1.6;
}
.form-status.is-visible { display: block; }
.form-status--ok    { background: #F1F4EF; border: 1px solid #C7D3BE; color: #35502C; }
.form-status--info  { background: var(--oxblood-soft); border: 1px solid #E0CBCE; color: var(--oxblood-dark); }
.form-status--error { background: #FBF1F0; border: 1px solid #E6C4C1; color: #8E2F2A; }
.form-status a { color: inherit; font-weight: 600; }

/* --------------------------------------------------------------------------
   14. Page header (interior pages)
   -------------------------------------------------------------------------- */
.page-head {
  padding-block: var(--section-y-sm) clamp(36px, 4.5vw, 60px);
  background: linear-gradient(180deg, var(--paper-alt), var(--paper));
  border-bottom: 1px solid var(--stone-200);
}
.page-head__inner { max-width: 62ch; }
.page-head__title { margin-bottom: var(--sp-3); }

/* Breadcrumb */
.crumbs {
  display: flex; flex-wrap: wrap; gap: .45rem; align-items: center;
  list-style: none; margin: 0 0 var(--sp-4); padding: 0;
  font: 500 .75rem/1.4 var(--font-sans);
  letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--ink-55);
}
.crumbs li { margin: 0; }
.crumbs li + li::before { content: "/"; margin-right: .45rem; color: var(--stone-400); }
.crumbs a { color: var(--ink-55); text-decoration: none; }
.crumbs a:hover { color: var(--oxblood); text-decoration: underline; }

/* --------------------------------------------------------------------------
   15. Filters (Learn / Challenges)
   -------------------------------------------------------------------------- */
.filters {
  display: flex; flex-wrap: wrap; gap: .5rem;
  margin-bottom: clamp(2rem, 3.5vw, 3rem);
  padding-bottom: var(--sp-4); border-bottom: 1px solid var(--stone-200);
}
.filter {
  padding: .55em 1.1em; min-height: 48px;
  display: inline-flex; align-items: center;
  border: 1px solid var(--stone-200); border-radius: 999px;
  background: transparent; cursor: pointer;
  font: 500 .8125rem/1 var(--font-sans); color: var(--ink-70);
  transition: border-color .2s var(--ease), color .2s var(--ease), background-color .2s var(--ease);
}
.filter:hover { border-color: var(--stone-400); color: var(--ink); }
.filter:active { border-color: var(--stone-500); background: var(--stone-100); }
/* A pill gets a pill-shaped ring, not the global square one. */
.filter:focus-visible { outline-offset: 2px; border-radius: 999px; }
.filter[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: #fff; font-weight: 600; }
.filter[aria-pressed="true"]:hover { background: var(--oxblood-dark); border-color: var(--oxblood-dark); }

.filter-meta {
  margin: -.5rem 0 1.75rem;
  font: 500 .8125rem/1.5 var(--font-sans);
  color: var(--ink-55);
}

.empty-state {
  padding: 3rem 1.5rem; text-align: center;
  border: 1px dashed var(--stone-400); border-radius: var(--radius);
  color: var(--ink-55);
}

/* --------------------------------------------------------------------------
   16. Challenge detail
   -------------------------------------------------------------------------- */
.progress-panel {
  padding: clamp(1.4rem, 2.6vw, 2rem);
  border: 1px solid var(--stone-200); border-radius: var(--radius);
  background: #fff; position: sticky; top: 104px;
}
.progress-bar {
  height: 6px; border-radius: 999px; background: var(--stone-200); overflow: hidden; margin: .9rem 0 .6rem;
}
.progress-bar__fill {
  display: block; height: 100%; width: 0%;
  background: var(--spectrum);
  transition: width .45s var(--ease);
}
.progress-count { font: 600 .8125rem/1.4 var(--font-sans); letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--ink-55); }

.task { display: flex; gap: .9rem; align-items: flex-start; padding: var(--sp-3) 0; border-bottom: 1px solid var(--stone-200); }
.task:last-child { border-bottom: 0; }
.task input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 22px; height: 22px; flex: none; margin: .18rem 0 0;
  border: 1px solid var(--stone-400); border-radius: 3px; background: #fff;
  cursor: pointer; position: relative;
  transition: background-color .18s var(--ease), border-color .18s var(--ease);
}
.task input[type="checkbox"]:checked { background: var(--oxblood); border-color: var(--oxblood); }
.task input[type="checkbox"]:checked::after {
  content: ""; position: absolute; left: 7px; top: 3px;
  width: 6px; height: 11px; border: solid #fff; border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.task label { cursor: pointer; }
.task__title { display: block; font-weight: 600; color: var(--ink); }
.task__note { display: block; font-size: .9375rem; color: var(--ink-55); margin-top: .2rem; }
.task input:checked ~ label .task__title { color: var(--ink-55); text-decoration: line-through; text-decoration-color: var(--stone-400); }

/* Reflection prompts */
.reflect { list-style: none; padding-left: 1.4rem; margin-left: 0; border-left: 2px solid var(--gold-line); }
.reflect li { font-family: var(--font-serif); font-size: 1.15rem; font-style: italic; color: var(--ink-70); }

/* --------------------------------------------------------------------------
   17. Footer
   -------------------------------------------------------------------------- */
.site-footer { background: var(--ink); color: var(--stone-300); padding-block: var(--section-y-sm) calc(var(--sp-5) + env(safe-area-inset-bottom)); }
.site-footer a { color: var(--stone-300); text-decoration: none; }
.site-footer a:not(.btn):hover { color: #fff; text-decoration: underline; text-underline-offset: .2em; }

/* Buttons inside the footer keep their own colours — the link rule above is
   more specific than the .btn modifiers, so restate them here. */
.site-footer .btn--light { color: var(--ink); }
.site-footer .btn--light:hover { color: var(--ink); background: var(--stone-100); }
.site-footer .btn--onink { color: #fff; }
.site-footer .btn--onink:hover { color: var(--ink); background: #fff; }

.footer-grid {
  display: grid; gap: clamp(2rem, 4vw, 3.5rem);
  grid-template-columns: 1fr;
  padding-bottom: clamp(2.5rem, 4vw, 3.5rem);
  border-bottom: 1px solid rgba(255,255,255,.12);
}
@media (min-width: 720px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; } }
@media (min-width: 1000px) { .footer-grid { grid-template-columns: 1.6fr 1fr 1fr 1.2fr; } }

.footer-brand__name {
  font-family: var(--font-display); font-weight: 600; font-size: 1.25rem;
  letter-spacing: .12em; text-transform: uppercase; color: #fff; margin: 0 0 .75rem;
}
.footer-heading {
  font: 600 .75rem/1.4 var(--font-sans);
  letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--gold);
  margin: 0 0 1.15rem;
}
.footer-list { list-style: none; margin: 0; padding: 0; }
.footer-list li { margin-bottom: .6rem; }
.footer-list a { font-size: .9375rem; }
/* On touch screens an 18px-tall text link is a guess, not a tap. Each link
   becomes a 44px row (Apple's minimum) and the list spacing closes up to
   compensate, so the column looks the same height it did. */
@media (pointer: coarse) {
  .footer-list li { margin-bottom: 0; }
  .footer-list a { display: inline-flex; align-items: center; min-height: 44px; }
}

.footer-bottom {
  display: flex; flex-wrap: wrap; gap: var(--sp-3) 2rem;
  align-items: center; justify-content: space-between;
  padding-top: 2rem;
  font-size: .8125rem; color: rgba(213,211,206,.7);
}
.footer-social { display: flex; gap: .6rem; }
/* 48px, not the 42px it measured at — same touch-target floor as .icon-btn. */
.footer-social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px;
  border: 1px solid rgba(255,255,255,.2); border-radius: 50%;
  transition: background-color .2s var(--ease), border-color .2s var(--ease);
}
.footer-social a:hover { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.45); text-decoration: none; }
.footer-social a:active { background: rgba(255,255,255,.18); }
.footer-social a:focus-visible { outline-offset: 3px; border-radius: 50%; }
.footer-social svg { width: 18px; height: 18px; }

/* --------------------------------------------------------------------------
   18. Final CTA band
   -------------------------------------------------------------------------- */
.cta-band {
  padding-block: var(--section-y);
  background: var(--paper-alt);
  border-top: 1px solid var(--stone-200);
  text-align: center;
}
.cta-band__title { margin-bottom: var(--sp-3); }
.cta-grid {
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  margin-top: clamp(2.25rem, 4vw, 3rem);
  text-align: left;
}
.cta-tile {
  display: flex; flex-direction: column; gap: .35rem;
  padding: 1.25rem 1.35rem;
  background: #fff; border: 1px solid var(--stone-200); border-radius: var(--radius);
  text-decoration: none; color: inherit;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease);
}
/* Restraint, same reasoning as .card above: a lift plus a growing shadow
   already reads as "this rose up" on its own. Also swapping the border to
   oxblood on hover was a third, redundant echo of the same elevation cue
   across five tiles in a row — the border stays put. */
.cta-tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
/* White tile on the paper-alt band, not the ink surface — gold-ink writes here. */
.cta-tile__step { font: 600 .6875rem/1 var(--font-sans); letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--gold-ink); }
.cta-tile__label { font-family: var(--font-serif); font-size: 1.125rem; font-weight: 600; color: var(--ink); }
.cta-tile__desc { font-size: .875rem; color: var(--ink-55); line-height: 1.55; }

/* --------------------------------------------------------------------------
   19. Misc
   -------------------------------------------------------------------------- */
.stat-row {
  display: flex; flex-wrap: wrap; gap: var(--sp-3) 2.5rem;
  padding: var(--sp-4) 0; border-block: 1px solid var(--stone-200);
}
.stat__k { font-family: var(--font-display); font-size: 1.5rem; font-weight: 500; color: var(--ink); letter-spacing: .02em; }
.stat__v { font: 500 .75rem/1.4 var(--font-sans); letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--ink-55); }

.detail-list { list-style: none; margin: 0; padding: 0; }
/* A row is a label and a value, always in two columns — never flex-wrap,
   which let a long value (e.g. "SVP Business Development, Western Canada
   (IG Wealth Management)") drop onto its own line below the label instead
   of beside it. The label column sizes to its own content and never wraps;
   the value column takes what's left and wraps internally, still pinned to
   the right, so short values (Chair, Author) and long ones sit the same way. */
.detail-list li {
  display: grid; grid-template-columns: max-content minmax(0, 1fr);
  align-items: baseline; column-gap: var(--sp-3); row-gap: .3rem;
  padding: .8rem 0; border-bottom: 1px solid var(--stone-200); margin: 0;
  font-size: .9375rem;
}
.detail-list dt, .detail-list .k {
  font: 600 .6875rem/1.6 var(--font-sans); letter-spacing: var(--track-caps);
  text-transform: uppercase; color: var(--ink-55);
  white-space: nowrap;
}
.detail-list dd, .detail-list .v { color: var(--ink); text-align: right; margin: 0; }

/* Below ~380px even the two-column grid gets tight once a label like
   "Publication date" sits next to a value that also needs room to wrap.
   Stack deliberately here rather than letting the columns fight for space. */
@media (max-width: 380px) {
  .detail-list li { grid-template-columns: 1fr; row-gap: .25rem; }
  .detail-list dd, .detail-list .v { text-align: left; }
}


.accordion { border-top: 1px solid var(--stone-200); }
.accordion details { border-bottom: 1px solid var(--stone-200); }
.accordion summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: 1.35rem 0; cursor: pointer; list-style: none;
  font-family: var(--font-serif); font-size: 1.2rem; font-weight: 600; color: var(--ink);
  transition: color .2s var(--ease);
}
/* The arrow is already oxblood at rest; the title picking up the same colour
   on hover is the visible state change. */
.accordion summary:hover { color: var(--oxblood); }
.accordion summary::-webkit-details-marker { display: none; }
.accordion summary::after {
  content: ""; flex: none; width: 11px; height: 11px;
  border-right: 1.5px solid var(--oxblood); border-bottom: 1.5px solid var(--oxblood);
  transform: rotate(45deg) translateY(-3px);
  transition: transform .25s var(--ease);
}
.accordion details[open] summary::after { transform: rotate(-135deg) translateY(-3px); }
.accordion .accordion__body { padding-bottom: var(--sp-4); color: var(--ink-70); max-width: 68ch; }

/* --------------------------------------------------------------------------
   20. Scroll reveal
   -------------------------------------------------------------------------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
  will-change: opacity, transform;
}
[data-reveal].is-visible { opacity: 1; transform: none; }
[data-reveal-delay="1"] { transition-delay: .08s; }
[data-reveal-delay="2"] { transition-delay: .16s; }
[data-reveal-delay="3"] { transition-delay: .24s; }
[data-reveal-delay="4"] { transition-delay: .32s; }

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

/* --------------------------------------------------------------------------
   21. Print
   -------------------------------------------------------------------------- */
@media print {
  .site-header, .site-footer, .cta-band, .nav-backdrop, .skip-link { display: none !important; }
  body { background: #fff; color: #000; }
  a { color: #000; }
}

/* ==========================================================================
   22. Interactive 3D book
   --------------------------------------------------------------------------
   A real cuboid built from CSS 3D transforms — front, back, spine, fore-edge
   and head/tail — using the actual jacket artwork on each face. Drag to turn
   it, or use the Front / Spine / Back buttons and the arrow keys.

   Proportions are the real book's: 6 x 9, so 1.5 tall-to-wide, and the spine
   render is 0.163 of the book's height, so the depth is measured rather than
   guessed. Both cover files now fit that shape exactly: the back artwork is a
   true 6:9, and the front (book-cover-3d.jpg) is the supplied cover, 736 x
   1024, with 40px of its own paper margin extended top and bottom to reach
   6:9. The extension mirrors the margin's grain rather than stretching or
   cropping anything, because the women's artwork bleeds off both side edges
   and the title sits close to the top, so neither could be trimmed to fit.
   ========================================================================== */
.book3d {
  --bw: clamp(170px, 22vw, 300px);          /* cover width  */
  --bh: calc(var(--bw) * 1.5);              /* 6 x 9 trim size */
  --bd: calc(var(--bh) * 0.1626);           /* spine depth, from the render */
  --rot-y: 18deg;
  --rot-x: 6deg;

  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  margin: 0;
}

.book3d__stage {
  position: relative;
  width: var(--bw);
  height: var(--bh);
  perspective: 1700px;
  perspective-origin: 50% 46%;
}

.book3d__book {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: rotateX(var(--rot-x)) rotateY(var(--rot-y));
  transition: transform .9s var(--ease);
  cursor: grab;
  touch-action: pan-y;                       /* vertical scrolling still works */
}
.book3d__book:active { cursor: grabbing; }
.book3d.is-dragging .book3d__book { transition: none; }
.book3d.is-spinning .book3d__book { transition: none; }
/* Locking onto a face: quicker than a button jump, with a touch of overshoot */
.book3d.is-settling .book3d__book { transition: transform .5s cubic-bezier(.18, .89, .32, 1.06); }
.book3d__book:focus-visible { outline: 2px solid var(--ring); outline-offset: 14px; border-radius: 4px; }

.book3d__face {
  position: absolute;
  left: 50%;
  top: 50%;
  /* backface-visibility and overflow clipping are deliberately absent: both
     force an extra masked layer that Chrome rasterises softly. The cuboid is
     closed, so back faces are hidden by geometry anyway.
     The transparent outline is not decoration — it pushes Chrome onto the
     antialiased path for a rotated element, which is what smooths the edges. */
  outline: 1px solid transparent;
  border-radius: 2px;
}
.book3d__face img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* The six faces of the cuboid */
.book3d__face--front {
  width: var(--bw); height: var(--bh);
  transform: translate(-50%, -50%) translateZ(calc(var(--bd) / 2));
  border-radius: 2px 4px 4px 2px;      /* square at the spine, eased at the fore-edge */
  box-shadow: inset 0 0 0 .5px rgba(34, 31, 32, .16);
}
.book3d__face--back {
  width: var(--bw); height: var(--bh);
  transform: translate(-50%, -50%) rotateY(180deg) translateZ(calc(var(--bd) / 2));
  background: #F2EDE7;                      /* the back cover's own paper, behind the image while it loads */
  border-radius: 4px 2px 2px 4px;
  box-shadow: inset 0 0 0 .5px rgba(34, 31, 32, .16);
}
/* The back artwork is a true 6:9 and the face is now 6:9, so it fills the face
   exactly: no matte, no pinning, nothing to line up. */
.book3d__face--spine {
  width: var(--bd); height: var(--bh);
  transform: translate(-50%, -50%) rotateY(-90deg) translateZ(calc(var(--bw) / 2));
}
.book3d__face--edge {
  width: var(--bd); height: calc(var(--bh) + 1px);
  transform: translate(-50%, -50%) rotateY(90deg) translateZ(calc(var(--bw) / 2));
  border-radius: 0;
}
.book3d__face--head {
  width: calc(var(--bw) + 1px); height: var(--bd);
  transform: translate(-50%, -50%) rotateX(90deg) translateZ(calc(var(--bh) / 2));
  border-radius: 0;
}
.book3d__face--tail {
  width: calc(var(--bw) + 1px); height: var(--bd);
  transform: translate(-50%, -50%) rotateX(-90deg) translateZ(calc(var(--bh) / 2));
  border-radius: 0;
}

/* Paper block: the cut edges of the pages */
.book3d__face--edge,
.book3d__face--head,
.book3d__face--tail {
  background-color: #EFE8DA;
}
.book3d__face--edge {
  background-image:
    linear-gradient(90deg, rgba(34,31,32,.34) 0%, rgba(34,31,32,.02) 16%, rgba(255,255,255,.22) 50%, rgba(34,31,32,.04) 84%, rgba(34,31,32,.22) 100%),
    repeating-linear-gradient(90deg, #F8F4EA 0 1px, #E4DCCC 1px 1.7px, #F1EBDD 1.7px 2.6px);
}
.book3d__face--head,
.book3d__face--tail {
  background-image:
    linear-gradient(90deg, rgba(34,31,32,.38) 0%, rgba(34,31,32,.05) 8%, rgba(255,255,255,.16) 46%, rgba(34,31,32,.12) 100%),
    repeating-linear-gradient(180deg, #F8F4EA 0 1px, #E4DCCC 1px 1.7px, #F1EBDD 1.7px 2.6px);
}

/* Lighting: a soft sheen across the covers and a darker gutter at the binding */
.book3d__face--front::after,
.book3d__face--back::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.book3d__face--front::after {
  background:
    linear-gradient(90deg, rgba(34,31,32,.26) 0%, rgba(34,31,32,.05) 5%, rgba(34,31,32,0) 13%),
    linear-gradient(103deg, rgba(255,255,255,.20) 0%, rgba(255,255,255,0) 38%, rgba(34,31,32,.07) 100%);
}
.book3d__face--back::after {
  background:
    linear-gradient(270deg, rgba(34,31,32,.26) 0%, rgba(34,31,32,.05) 5%, rgba(34,31,32,0) 13%),
    linear-gradient(257deg, rgba(255,255,255,.16) 0%, rgba(255,255,255,0) 40%, rgba(34,31,32,.08) 100%);
}

/* Contact shadow on the ground — JS narrows it as the book turns edge-on */
.book3d__shadow {
  position: absolute;
  left: 50%;
  bottom: -6%;
  width: calc(var(--bw) * .92);
  height: calc(var(--bw) * .16);
  transform: translateX(-50%) scaleX(var(--shadow-scale, 1));
  background: radial-gradient(50% 50% at 50% 50%, rgba(34,31,32,.34) 0%, rgba(34,31,32,.14) 45%, rgba(34,31,32,0) 72%);
  filter: blur(7px);
  pointer-events: none;
  z-index: -1;
}

/* Controls appear only once the script is running */
.book3d__controls,
.book3d__hint { display: none; }
.book3d.is-interactive .book3d__controls { display: flex; }
.book3d.is-interactive .book3d__hint { display: block; }

/* The control is both a set of buttons and a slider: the thumb tracks the
   book continuously, and dragging it scrubs the rotation from front to back. */
.book3d__controls {
  position: relative;
  gap: 0;
  padding: .3rem;
  border: 1px solid var(--stone-200);
  border-radius: 999px;
  background: rgba(255, 255, 255, .82);
  cursor: grab;
  touch-action: pan-y;
  /* user-select: none is handled site-wide for .book3d and its descendants
     in section 2, alongside every other non-text control. */
}
.book3d__controls:active { cursor: grabbing; }

.book3d__thumb {
  position: absolute;
  top: .3rem;
  bottom: .3rem;
  left: .3rem;
  width: calc((100% - .6rem) / 3);
  border-radius: 999px;
  background: var(--ink);
  transform: translateX(calc(var(--slider-t, 0) * 200%));
  transition: transform .45s var(--ease);
  pointer-events: none;
}
.book3d.is-dragging .book3d__thumb,
.book3d.is-spinning .book3d__thumb,
.book3d.is-scrubbing .book3d__thumb { transition: none; }
.book3d.is-settling .book3d__thumb { transition: transform .5s cubic-bezier(.18, .89, .32, 1.06); }

.book3d__view {
  position: relative;
  z-index: 1;
  flex: 1 1 0;
  min-height: 38px;
  padding: .45em .7em;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-70);
  font: 600 .72rem/1 var(--font-sans);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  cursor: inherit;
  transition: color .2s var(--ease);
}
.book3d__view:hover { color: var(--ink); }
/* Whichever stop the thumb is currently sitting under */
.book3d__view--lit,
.book3d__view--lit:hover { color: #fff; }

/* Comfortable tap targets for the slider on touch screens — 48px, the same
   floor as every other control, not the 44px this used to stop at. */
@media (max-width: 700px) {
  .book3d__view { min-height: 48px; }
}

.book3d__hint {
  margin: 0;
  font: 500 .72rem/1.4 var(--font-sans);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-55);
}
.book3d__hint svg { vertical-align: -2px; margin-right: .45em; }
.book3d.has-turned .book3d__hint { opacity: 0; transition: opacity .5s var(--ease); }

.book3d__caption {
  margin: 0;
  text-align: center;
  font: 500 .75rem/1.5 var(--font-sans);
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-55);
}

/* On the book page the object is the hero, so it runs larger */
.book3d--lg { --bw: clamp(190px, 26vw, 340px); }

@media (prefers-reduced-motion: reduce) {
  .book3d__book { transition: none; }
}

/* --------------------------------------------------------------------------
   23. "More in the book" cross-reference
   -------------------------------------------------------------------------- */
.book-note {
  display: grid;
  gap: clamp(1.25rem, 3vw, 2.25rem);
  align-items: center;
  grid-template-columns: 1fr;
  margin: 2.5rem 0;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: var(--paper-alt);
  border: 1px solid var(--stone-200);
  border-left: 3px solid var(--oxblood);
  border-radius: var(--radius);
}
@media (min-width: 620px) { .book-note { grid-template-columns: 108px minmax(0, 1fr); } }
.book-note__cover {
  width: 108px; height: auto; border-radius: 2px;
  box-shadow: var(--shadow-md), 0 0 0 1px rgba(34, 31, 32, .08);
  justify-self: start;
}
.book-note h2 { margin: 0; }

/* ==========================================================================
   24. Photography
   --------------------------------------------------------------------------
   The source photographs come from different rooms — a grey studio backdrop,
   a warm interior, and stage shots under blue wash lighting. Rather than
   faking a fade to the page colour, every image gets the same frame, the same
   aspect discipline and a light warm grade, so the set reads as one family
   alongside the jacket palette.
   ========================================================================== */
.photo {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--stone-100);
  box-shadow: var(--shadow-md), 0 0 0 1px rgba(34, 31, 32, .06);
}
.photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  filter: saturate(.95) contrast(1.02);
}
/* A whisper of the jacket's warmth over everything, to pull the greys in */
.photo::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(158deg, rgba(232, 210, 188, .20), rgba(102, 52, 61, .10));
  mix-blend-mode: soft-light;
}

/* Stage photography is lit blue and needs a firmer hand to join the set */
.photo--stage img {
  /* Shot from the floor, so the subject sits low in the frame */
  object-position: 50% 68%;
  filter: saturate(.55) contrast(1.07) brightness(1.05) sepia(.10);
}
.photo--stage::after {
  background: linear-gradient(150deg, rgba(232, 210, 188, .40), rgba(179, 98, 52, .22));
}

.photo--portrait { aspect-ratio: 3 / 4; }
.photo--tall     { aspect-ratio: 4 / 5; }
.photo--square   { aspect-ratio: 1 / 1; }
.photo--wide     { aspect-ratio: 3 / 2; }
.photo--pano     { aspect-ratio: 16 / 9; }

/* The spectrum hairline ties a photo back to the jacket */
.photo--marked::before {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0; height: 4px;
  background: var(--spectrum);
  z-index: 2;
}

figure.photo-figure { margin: 0; }
figure.photo-figure figcaption {
  margin-top: .9rem;
  font: 500 .75rem/1.5 var(--font-sans);
  letter-spacing: .04em;
  color: var(--ink-55);
}

/* Photo used as a section background, with a scrim for legible text over it */
.photo-band {
  position: relative;
  overflow: hidden;
  background: var(--ink);
}
.photo-band__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: saturate(.45) contrast(1.05) brightness(.82) sepia(.14);
}
.photo-band::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(100deg, rgba(34, 31, 32, .90) 0%, rgba(34, 31, 32, .74) 42%, rgba(74, 48, 52, .52) 100%);
}
.photo-band > .wrap { position: relative; z-index: 1; }

/* --------------------------------------------------------------------------
   25. Row-completing cards
   Shown when a filter matches fewer lessons than the row holds, so the grid
   never ends in dead space.
   -------------------------------------------------------------------------- */
.card--promo {
  background: var(--paper-alt);
  border-color: var(--stone-300);
}
.card--promo .card__title em { font-style: italic; }
.card__cover {
  width: 74px; height: auto;
  margin-bottom: 1.25rem;
  border-radius: 2px;
  box-shadow: var(--shadow-md), 0 0 0 1px rgba(34, 31, 32, .08);
}
.card--quiet {
  background: transparent;
  border-style: dashed;
  border-color: var(--stone-400);
}
.card--quiet:hover { background: #fff; border-style: solid; }

/* ==========================================================================
   26. Podcast player
   Plays the episode here rather than sending the visitor to the host. The
   original episode is credited and linked underneath.
   ========================================================================== */
.podcast {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  grid-template-columns: 1fr;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: #fff;
  border: 1px solid var(--stone-200);
  border-radius: var(--radius);
}
@media (min-width: 720px) { .podcast { grid-template-columns: 168px minmax(0, 1fr); } }

/* A typographic plate in the brand palette, rather than borrowing the show's
   artwork — it identifies the episode without hotlinking someone else's asset */
.podcast__art {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius);
  background: linear-gradient(150deg, var(--plum), var(--ink));
  overflow: hidden;
}
.podcast__art::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 4px;
  background: var(--spectrum);
}
.podcast__bars { display: flex; align-items: flex-end; gap: 5px; height: 46px; }
.podcast__bars i {
  display: block; width: 5px; border-radius: 3px;
  background: var(--gold-line);
  height: 32%;
  transform-origin: bottom;
}
.podcast__bars i:nth-child(1) { height: 34%; }
.podcast__bars i:nth-child(2) { height: 62%; }
.podcast__bars i:nth-child(3) { height: 92%; }
.podcast__bars i:nth-child(4) { height: 48%; }
.podcast__bars i:nth-child(5) { height: 78%; }
.podcast__bars i:nth-child(6) { height: 40%; }
.podcast__bars i:nth-child(7) { height: 58%; }
.podcast.is-playing .podcast__bars i { animation: pod-bar 1.1s ease-in-out infinite alternate; }
.podcast.is-playing .podcast__bars i:nth-child(2) { animation-delay: .12s; }
.podcast.is-playing .podcast__bars i:nth-child(3) { animation-delay: .24s; }
.podcast.is-playing .podcast__bars i:nth-child(4) { animation-delay: .36s; }
.podcast.is-playing .podcast__bars i:nth-child(5) { animation-delay: .48s; }
.podcast.is-playing .podcast__bars i:nth-child(6) { animation-delay: .60s; }
.podcast.is-playing .podcast__bars i:nth-child(7) { animation-delay: .72s; }
@keyframes pod-bar { from { transform: scaleY(.45); } to { transform: scaleY(1.25); } }

.podcast__title {
  font-family: var(--font-serif); font-weight: 600;
  font-size: clamp(1.35rem, 1.1rem + 1vw, 1.75rem);
  line-height: 1.2; margin: 0 0 .5rem;
}
.podcast__show {
  display: flex; flex-wrap: wrap; align-items: center; gap: .45rem;
  margin: 0 0 .9rem;
  font: 600 .6875rem/1.5 var(--font-sans);
  letter-spacing: var(--track-caps); text-transform: uppercase; color: var(--ink-55);
}
.podcast__show .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--stone-400); }
.podcast__desc { color: var(--ink-70); font-size: .9375rem; line-height: 1.65; margin: 0 0 var(--sp-4); }

.podcast__player {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .9rem 1.1rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--stone-200);
}
.podcast__transport { display: flex; align-items: center; gap: .35rem; flex: none; }
.podcast__play {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; flex: none;
  border: 0; border-radius: 50%;
  background: var(--oxblood); color: #fff;
  cursor: pointer;
  transition: background-color .2s var(--ease), transform .2s var(--ease);
}
.podcast__play:hover { background: var(--oxblood-dark); transform: scale(1.05); }
.podcast__play:active { background: var(--oxblood-dark); transform: scale(.97); }
.podcast__play:focus-visible { outline-offset: 3px; border-radius: 50%; }
.podcast__play svg { width: 18px; height: 18px; margin-left: 1px; }
.podcast.is-playing .podcast__play svg { margin-left: 0; }
.podcast.is-loading .podcast__play { opacity: .6; }

.podcast__track { flex: 1 1 200px; min-width: 0; }

/* Skip: heavy arc, solid arrowhead, bold numeral low inside the loop.
   48px, not the 44px it measured at — the icon stays the same size, only
   the tap area around it grows. */
.podcast__skip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; flex: none;
  padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: var(--ink-70);
  cursor: pointer;
  transition: color .2s var(--ease), background-color .2s var(--ease);
}
.podcast__skip:hover { color: var(--oxblood); background: var(--oxblood-soft); }
.podcast__skip:active { color: var(--oxblood-dark); background: var(--oxblood-soft); }
.podcast__skip:focus-visible { outline-offset: 2px; border-radius: 50%; }
.podcast__skip-icon { width: 32px; height: 32px; }
.podcast__skip-num {
  /* Checked by rendering both numerals at 32x32: 10px overlapped the arc at
     both the "1" of 15 and the "3" of 30, at their top corners as well as
     the outer edges — the old comment measured only one axis. 8px is the
     largest that clears the 2.15 stroke on every side, for both numerals. */
  font: 700 8px/1 var(--font-sans);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.03em;
  fill: currentColor;
}

.podcast__rate {
  flex: none;
  min-width: 48px; min-height: 48px;
  padding: .35em .9em;
  border: 1px solid var(--stone-200); border-radius: 999px;
  background: transparent; color: var(--ink-70);
  font: 600 .75rem/1 var(--font-sans);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: border-color .2s var(--ease), color .2s var(--ease), background-color .2s var(--ease);
}
.podcast__rate:hover { border-color: var(--stone-400); color: var(--ink); background: var(--paper-alt); }
.podcast__rate:active { background: var(--stone-100); }
.podcast__rate:focus-visible { outline-offset: 2px; border-radius: 999px; }

/* Range input styled as a progress bar; --played is set by the script */
.podcast__seek {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 18px; margin: 0;
  background: transparent; cursor: pointer;
}
.podcast__seek::-webkit-slider-runnable-track {
  height: 6px; border-radius: 999px;
  background: linear-gradient(90deg, var(--oxblood) var(--played, 0%), var(--stone-200) var(--played, 0%));
}
.podcast__seek::-moz-range-track {
  height: 6px; border-radius: 999px;
  background: linear-gradient(90deg, var(--oxblood) var(--played, 0%), var(--stone-200) var(--played, 0%));
}
.podcast__seek::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 15px; height: 15px; margin-top: -4.5px;
  border-radius: 50%; border: 2px solid #fff;
  background: var(--oxblood);
  box-shadow: 0 1px 4px rgba(34, 31, 32, .32);
}
.podcast__seek::-moz-range-thumb {
  width: 15px; height: 15px;
  border-radius: 50%; border: 2px solid #fff;
  background: var(--oxblood);
  box-shadow: 0 1px 4px rgba(34, 31, 32, .32);
}
.podcast__seek:focus-visible { outline: 2px solid var(--ring); outline-offset: 4px; border-radius: 999px; }

.podcast__times {
  display: flex; justify-content: space-between;
  margin: .3rem 0 0;
  font: 500 .75rem/1 var(--font-sans);
  font-variant-numeric: tabular-nums;
  color: var(--ink-55);
}

.podcast__foot { margin: 1.35rem 0 0; }

/* If the host's file will not play, say so, but leave the controls working:
   most failures are a passing network blip, and another tap on play retries. */
.podcast.is-failed .podcast__foot::before {
  content: "The episode didn't load. Tap play to try again, or listen on the original episode page below.";
  display: block; margin-bottom: .75rem;
  font-size: .875rem; color: #8E2F2A;
}

@media (prefers-reduced-motion: reduce) {
  .podcast.is-playing .podcast__bars i { animation: none; }
}

/* ==========================================================================
   27. The page peeling back, left to right
   --------------------------------------------------------------------------
   The artwork is printed under the page, not laid on top of it. One sheet of
   the page's own stock covers it and is peeled away left to right as the
   section scrolls, so the women arrive one after another rather than all at
   once, in a single continuous motion, the way pulling a sheet of paper off
   something underneath actually looks.

   What makes it read as the page itself rather than a panel:
     - the sheet is filled with var(--paper), the exact colour the body is
       painted, so before the tear reaches a given point there is nothing
       there to see
     - the sheet overhangs the frame on every side, so its own edges are
       never on screen, only the torn one
     - the artwork's own edges are dissolved by a mask on every side, so no
       rectangle survives anywhere once the sheet has passed

   The torn edge is vertical, 85 points wandering between -3.8% and +3.5% of
   the sheet's width, built from five sine waves so it carries slow lean,
   undulation, tooth, fibre and fluff at once, not a mechanical wipe.

   Depth is almost nothing on purpose: a white hairline for the pale lip torn
   paper leaves, and one soft shadow cast left, onto the artwork already
   revealed, so the sheet reads as lifting rather than sliding flat.

   --rip runs 0 to 1, driven by js/main.js, and defaults to 1 so the artwork
   shows in full with JavaScript off. The artwork itself never moves; only
   the sheet does.
   ========================================================================== */
.rip { --rip: 1; }

.rip__frame {
  position: relative;
  overflow: hidden;
  /* Feathered on every edge: the artwork is darker than the page, so once
     the sheet has passed a hard boundary would read as a pasted card. */
  -webkit-mask-image:
    linear-gradient(to right,  transparent 0, #000 7%, #000 93%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 9%, #000 91%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(to right,  transparent 0, #000 7%, #000 93%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 9%, #000 91%, transparent 100%);
          mask-composite: intersect;
}

.rip__frame img { display: block; width: 100%; height: auto; }

.rip__page {
  position: absolute;
  /* 120% of the frame's width, so translating it one full multiple of its
     own width clears the frame completely including the overhang. */
  top: -20%; bottom: -20%; left: -10%; right: -10%;
  background: var(--paper);
  pointer-events: none;
  will-change: transform;
  filter:
    drop-shadow(1px 0 0 rgba(255, 255, 255, .92))
    drop-shadow(4px 1px 5px rgba(34, 31, 32, .13));
  clip-path: polygon(
    2.11% 0%, 2.24% 1.28%, 2.18% 2.56%, 1.55% 3.85%, 2.28% 5.13%, 2.5% 6.41%, 1.75% 7.69%, 1.17% 8.97%, -0.229% 10.3%, -0.451% 11.5%, 0.47% 12.8%, 0.595% 14.1%, 1.2% 15.4%, 1.43% 16.7%, 1.53% 17.9%, 2.85% 19.2%, 3.06% 20.5%, 2.54% 21.8%, 2.05% 23.1%, 0.896% 24.4%, 1.19% 25.6%, 1.85% 26.9%, 1.5% 28.2%, 1.55% 29.5%, 0.899% 30.8%, 0.458% 32.1%, 0.868% 33.3%, -0.179% 34.6%, -1.43% 35.9%, -2.55% 37.2%, -3.75% 38.5%, -3.13% 39.7%, -2.59% 41%, -2.72% 42.3%, -2.28% 43.6%, -2.48% 44.9%, -1.97% 46.2%, -1.04% 47.4%, -1.64% 48.7%, -2% 50%, -2.34% 51.3%, -2.42% 52.6%, -0.956% 53.8%, -0.381% 55.1%, -0.4% 56.4%, -0.144% 57.7%, -0.669% 59%, -0.358% 60.3%, -0.314% 61.5%, -1.69% 62.8%, -2.42% 64.1%, -3.12% 65.4%, -3.05% 66.7%, -1.71% 67.9%, -1.57% 69.2%, -1.5% 70.5%, -1.15% 71.8%, -1.26% 73.1%, -0.276% 74.4%, -0.00196% 75.6%, -0.669% 76.9%, -0.369% 78.2%, -0.116% 79.5%, 1.12% 80.8%, 2.87% 82.1%, 3.01% 83.3%, 3.25% 84.6%, 3.34% 85.9%, 3.04% 87.2%, 3.54% 88.5%, 2.76% 89.7%, 1.49% 91%, 1.24% 92.3%, 0.899% 93.6%, 1.69% 94.9%, 2.36% 96.2%, 1.55% 97.4%, 1.34% 98.7%, 0.951% 100%,
    100% 100%, 100% 0%
  );
  /* The sheet is 120% of the frame's own width (the -10%/-10% overhang),
     so translateX's percentages are relative to that wider box, not the
     frame: 21% of the sheet lands the torn edge at (-10 + 21*1.2) = 15.2% of
     the FRAME, which is the ~15% head start actually intended. 100% of the
     sheet lands it at 110% of the frame, safely past the far edge. Checked
     against the live DOM, not just worked out on paper. */
  transform: translateX(calc(21% + var(--rip) * 79%));
}

/* Stillness for anyone who has asked for it: the artwork is simply
   uncovered, and the sheet is not present to animate. */
@media (prefers-reduced-motion: reduce) {
  .rip { --rip: 1 !important; }
}

/* ==========================================================================
   27b. Waitlist card
   --------------------------------------------------------------------------
   Sits in the "Get the book" card on book.html. The QR is a vector, drawn on
   its own white tile with the 4-module quiet zone baked in, so it scans
   whatever the card behind it is painted. Dark on white, not tinted: a
   coloured or low-contrast code is the one decorative choice that makes
   scanning fail.
   ========================================================================== */
.waitlist {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--sp-4) var(--sp-5);
  margin-top: var(--sp-3);
}
.waitlist__qr { margin: 0; flex: none; text-align: center; }
.waitlist__qr img {
  display: block; width: 168px; height: 168px; margin-inline: auto;
  background: #fff;
  border: 1px solid var(--stone-200);
  border-radius: 6px;
  padding: 6px;
  box-shadow: var(--shadow-sm, 0 1px 3px rgba(34, 31, 32, .08));
}
.waitlist__qr figcaption {
  margin-top: .55rem;
  font: 600 .6875rem/1.4 var(--font-sans);
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--ink-55);
}
.waitlist__copy { flex: 1 1 14rem; min-width: 0; }
.waitlist__copy p { margin: 0 0 .85rem; }
.waitlist__copy p:last-child { margin-bottom: 0; }

/* ==========================================================================
   28. Touch screens (phones and tablets)
   --------------------------------------------------------------------------
   iOS fires :hover on tap and then leaves it on until something else is
   tapped, so a card that lifts on hover stays lifted after the visitor has
   already moved on. On devices with no real hover the lift is dropped; the
   :active states above still give immediate feedback under the finger.
   ========================================================================== */
@media (hover: none) {
  .btn:hover,
  .card:hover,
  .cta-tile:hover,
  .podcast__play:hover { transform: none; }
  .card:hover,
  .cta-tile:hover { box-shadow: none; }
  .link-arrow:hover svg,
  .card:hover .link-arrow svg { transform: none; }
  .card--accent:hover::before { transform: scaleX(0); }
  .card--accent:focus-within::before { transform: scaleX(1); }
  .card--quiet:hover { background: transparent; border-style: dashed; }
}

/* Double-tapping a control (skip 15s twice, the book slider, a filter pill)
   made iOS zoom the page instead of registering two taps. "manipulation"
   turns off double-tap zoom on these controls only; pinch-to-zoom stays
   available everywhere, because people with low vision rely on it.
   (The 3D book and its slider are already covered: their pan-y rules in
   section 22 rule out double-tap zoom too.) */
a, button, summary, label, input, select, textarea { touch-action: manipulation; }

/* iOS zooms into any form control under 16px when it receives focus. */
.podcast__seek { font-size: 16px; }

@media (pointer: coarse) {
  /* Arrow links are 19px of text; pad them out to a 44px tap area without
     changing where they sit on the page. */
  .link-arrow { padding-block: .8rem; margin-block: -.8rem; }
}

/* Very narrow phones: 320px is the iPhone SE, and any iPhone with Display
   Zoom turned on. Here a single-line button label ("See inside the book")
   and the full brand lockup are both wider than the screen, which is what
   let iOS zoom out and stay there. Labels wrap instead, and the brand
   tightens so the menu button keeps its place on screen. */
@media (max-width: 380px) {
  .btn { white-space: normal; text-align: center; letter-spacing: .1em; }
  .nav { gap: var(--sp-2); }
  .brand { gap: .5rem; min-width: 0; }
  .brand img { width: 36px; height: 36px; }
  .brand__name { font-size: 1rem; letter-spacing: .07em; }
  .brand__tag { font-size: .5625rem; letter-spacing: .08em; }
}
