/* ==========================================================================
   Julia Arbuckle — design version 2
   --------------------------------------------------------------------------
   Same voice as v1 (warm paper, one signature flower, editorial serif), built
   with more craft: the hero photograph is masked into the page instead of being
   veiled with a white scrim, and every surface stays light — depth comes from
   layered radial washes, warm shadows and hairlines rather than from dark bands.

   This stylesheet is a complete replacement for main.css. It styles the v2
   homepage AND every existing inner page, so the review routes under /v2/ are
   produced by swapping the stylesheet link — no duplicated page markup.

   Fonts: Newsreader (editorial serif) + Manrope (quiet sans), self-hosted.
   ========================================================================== */

/* ---------- Fonts ---------- */

@font-face {
  font-family: "Newsreader";
  src: url("/assets/fonts/newsreader-var.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Newsreader";
  src: url("/assets/fonts/newsreader-italic-var.woff2") format("woff2");
  font-weight: 200 800;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Manrope";
  src: url("/assets/fonts/manrope-var.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

/* ---------- Tokens ---------- */

:root {
  /* canvas — a half-step warmer than v1 so the paper reads like paper */
  --paper: #fffdf8;
  --pure: #ffffff;
  --ivory: #f7f2e8;
  --butter-wash: #fbf3dc;
  --butter-card: #fdfaf0;

  /* deep green — the primary button's hover state */
  --forest: #1e2825;

  /* ink */
  --ink: #23262a;
  --ink-2: #4f555a;
  --ink-3: #767c81;
  --rule: rgba(35, 38, 42, 0.16);
  --rule-soft: rgba(35, 38, 42, 0.085);

  /* botanicals — artwork and small accents, never body text */
  --coral: #d3928c;
  --coral-soft: #eed3cf;
  --coral-ink: #9c4f47;   /* text-capable coral */
  --lavender: #b8aec8;
  --butter: #e5d38f;
  --lake: #9bb6c0;
  --sage: #8d9d8c;
  --sage-ink: #55684f;    /* text-capable sage */

  /* type */
  --serif: "Newsreader", "Iowan Old Style", Georgia, serif;
  --sans: "Manrope", "Avenir Next", "Segoe UI", sans-serif;

  --size-display: clamp(2.55rem, 1.5rem + 3.5vw, 4.1rem);
  --size-h2: clamp(1.95rem, 1.4rem + 1.8vw, 2.75rem);
  --size-h3: clamp(1.32rem, 1.15rem + 0.6vw, 1.62rem);
  --size-lede: clamp(1.12rem, 1.02rem + 0.45vw, 1.34rem);
  --size-body: 1.09rem;
  --size-ui: 0.95rem;
  --size-meta: 0.83rem;
  --size-label: 0.71rem;

  /* rhythm */
  --space-section: clamp(4.75rem, 4rem + 5vw, 8.5rem);
  --space-section-sm: clamp(3.25rem, 2.75rem + 2.5vw, 5rem);
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --container: 76rem;
  --container-text: 42rem;

  --r-sm: 7px;
  --r: 13px;
  --r-lg: 20px;
  --r-pill: 999px;

  /* shadows are warm — a neutral black shadow turns warm paper grey */
  --shadow-1: 0 1px 2px rgba(63, 48, 34, 0.04), 0 3px 10px -5px rgba(63, 48, 34, 0.07);
  --shadow-2: 0 2px 4px rgba(63, 48, 34, 0.04), 0 14px 32px -16px rgba(63, 48, 34, 0.16);
  --shadow-3: 0 4px 10px rgba(63, 48, 34, 0.05), 0 30px 64px -30px rgba(63, 48, 34, 0.24);

  --header-h: 4.75rem;
  --ease: cubic-bezier(0.25, 0.4, 0.2, 1);
}

/* ---------- Reset & base ---------- */

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-optical-sizing: auto;
  font-size: var(--size-body);
  line-height: 1.66;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* A whisper of paper grain over the whole page. It is what stops large flat
   areas of warm white from reading as flat screen white. Kept far below the
   threshold where it could touch text contrast. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

h1, h2, h3, h4, p, figure, blockquote, dl, dd { margin: 0; }

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

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  text-decoration-color: var(--coral);
  transition: color 0.2s var(--ease), text-decoration-color 0.2s var(--ease);
}
a:hover { color: var(--coral-ink); }

::selection { background: rgba(211, 146, 140, 0.3); }

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

[id] { scroll-margin-top: calc(var(--header-h) + 1.5rem); }

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

.skip-link {
  position: fixed;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 200;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--sans);
  font-size: var(--size-ui);
  padding: 0.6em 1em;
  border-radius: 6px;
  transform: translateY(-300%);
  transition: transform 0.25s var(--ease);
}
.skip-link:focus-visible {
  transform: none;
  color: var(--paper);
}

/* ---------- Type helpers ---------- */

.display {
  font-family: var(--serif);
  font-weight: 400;
  font-size: var(--size-display);
  line-height: 1.06;
  letter-spacing: -0.019em;
  text-wrap: balance;
}
.display em { font-style: italic; }
.display--book { font-style: italic; font-weight: 420; }

.h2 {
  font-family: var(--serif);
  font-weight: 420;
  font-size: var(--size-h2);
  line-height: 1.14;
  letter-spacing: -0.014em;
  text-wrap: balance;
}

.h3 {
  font-family: var(--serif);
  font-weight: 460;
  font-size: var(--size-h3);
  line-height: 1.24;
  letter-spacing: -0.008em;
}

/* A small label above a heading. The homepage sections used to carry numerals
   here as well — "01 A clear way to begin" — but the chapter numbering was
   scaffolding the reader did not need, so the headings now stand on their own. */
.eyebrow {
  font-family: var(--sans);
  font-weight: 700;
  font-size: var(--size-label);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sage-ink);
}
.eyebrow--coral { color: var(--coral-ink); }

.lede {
  font-size: var(--size-lede);
  line-height: 1.5;
  color: var(--ink-2);
  text-wrap: pretty;
}

.prose { max-width: var(--container-text); }
.prose p { margin-bottom: 1.35em; text-wrap: pretty; }
.prose p:last-child { margin-bottom: 0; }
.prose em { font-style: italic; }
.prose .h2 { margin-bottom: 1.4rem; }
.prose .h2:not(:first-child) { margin-top: 2.6rem; }
.prose + .notebook { margin-top: 3.5rem; }

.meta {
  font-family: var(--sans);
  font-size: var(--size-meta);
  font-weight: 500;
  color: var(--ink-3);
}

/* ---------- Layout primitives ---------- */

.container {
  width: min(100% - 2 * var(--gutter), var(--container));
  margin-inline: auto;
}

.section { padding-block: var(--space-section); }
.section--sm { padding-block: var(--space-section-sm); }

.section-head {
  max-width: 46rem;
  margin-bottom: clamp(2.5rem, 2rem + 2.5vw, 4rem);
}
.section-head .eyebrow { display: block; margin-bottom: 1.15rem; }
.section-head .h2 + p {
  margin-top: 1.1rem;
  color: var(--ink-2);
  max-width: 38rem;
  text-wrap: pretty;
}

.band { background: var(--ivory); }

/* Washes are radial light rather than horizontal bands: warmth pools in a
   corner and falls away, so two adjacent sections never meet on a hard seam. */
.wash-sun,
.wash-butter,
.wash-lake {
  position: relative;
  isolation: isolate;
}
.wash-sun::before,
.wash-butter::before,
.wash-lake::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}
.wash-sun::before,
.wash-butter::before {
  background:
    radial-gradient(58% 70% at 82% 4%, var(--butter-wash), transparent 64%),
    radial-gradient(64% 62% at 4% 96%, rgba(229, 211, 143, 0.24), transparent 62%);
}
.wash-lake::before {
  background:
    radial-gradient(58% 70% at 84% 6%, rgba(155, 182, 192, 0.24), transparent 64%),
    radial-gradient(60% 60% at 6% 94%, rgba(155, 182, 192, 0.16), transparent 62%);
}

/* ---------- Buttons & links ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-family: var(--sans);
  font-size: var(--size-ui);
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1;
  text-decoration: none;
  border-radius: var(--r-pill);
  padding: 1.05em 1.75em;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 0.22s var(--ease), color 0.22s var(--ease),
    border-color 0.22s var(--ease), transform 0.22s var(--ease),
    box-shadow 0.22s var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn--primary {
  background: var(--ink);
  color: var(--paper);
  box-shadow: var(--shadow-1);
}
.btn--primary:hover {
  background: var(--forest);
  color: var(--paper);
  box-shadow: var(--shadow-2);
}

.btn--ghost {
  border-color: var(--rule);
  color: var(--ink);
  background: transparent;
}
.btn--ghost:hover {
  border-color: var(--coral);
  color: var(--coral-ink);
  background: rgba(211, 146, 140, 0.07);
}

.text-link {
  font-family: var(--sans);
  font-size: var(--size-ui);
  font-weight: 600;
  text-decoration: none;
  color: var(--ink);
  border-bottom: 1px solid var(--coral);
  padding-bottom: 0.18em;
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}
.text-link:hover { color: var(--coral-ink); }
.text-link .arrow { display: inline-block; transition: transform 0.25s var(--ease); }
.text-link:hover .arrow { transform: translateX(4px); }

/* .actions is the v2 name; .hero-actions is kept for the existing inner pages */
.actions,
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.4rem;
  margin-top: 2.3rem;
}

/* ---------- Header ---------- */

/* Fixed, so the homepage photograph can run all the way to the top of the
   screen and the header can sit on it as a thin, quiet bar. */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease);
}

/* The navigation has to stay readable over sky, water and paper alike, so it
   carries its own light. A soft white scrim sits behind the bar and fades out
   below it — legible like a solid header, without cutting a hard pale band
   across the top of the photograph. */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0 0 -2.5rem;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.97) 0 58%,
    rgba(255, 255, 255, 0.72) 76%,
    rgba(255, 255, 255, 0) 100%
  );
  pointer-events: none;
  transition: background 0.3s var(--ease);
}
/* Once the hero is behind us the bar can be a plain surface again. */
.site-header.is-scrolled::before {
  inset: 0;
  background: rgba(255, 253, 248, 0.94);
  -webkit-backdrop-filter: blur(16px) saturate(120%);
  backdrop-filter: blur(16px) saturate(120%);
}
.site-header.is-scrolled { border-bottom-color: var(--rule-soft); }

.site-header .container {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.62rem;
  font-family: var(--serif);
  font-size: 1.32rem;
  font-weight: 500;
  text-decoration: none;
  color: var(--ink);
}
.wordmark:hover { color: var(--ink); }
.wordmark img {
  width: 1.45rem;
  height: 1.45rem;
  transition: transform 0.5s var(--ease);
}
.wordmark:hover img { transform: rotate(24deg); }

.site-nav {
  display: flex;
  align-items: center;
  gap: clamp(1.4rem, 2.5vw, 2.3rem);
}
.site-nav a:not(.btn) {
  position: relative;
  font-family: var(--sans);
  font-size: var(--size-ui);
  font-weight: 600;
  text-decoration: none;
  color: var(--ink);
  padding-bottom: 0.25em;
}
.site-nav a:not(.btn)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--coral);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.28s var(--ease);
}
.site-nav a:not(.btn):hover { color: var(--ink); }
.site-nav a:not(.btn):hover::after,
.site-nav a:not(.btn)[aria-current="page"]::after { transform: none; }
.site-nav a:not(.btn)[aria-current="page"] { color: var(--ink); }
.site-nav .btn { padding: 0.8em 1.5em; }

.nav-toggle {
  display: none;
  appearance: none;
  background: none;
  border: 0;
  padding: 0.55rem;
  margin-right: -0.55rem;
  cursor: pointer;
  z-index: 130;
}
.nav-toggle .bars,
.nav-toggle .bars::before,
.nav-toggle .bars::after {
  content: "";
  display: block;
  width: 1.4rem;
  height: 2px;
  border-radius: 2px;
  background: var(--ink);
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}
.nav-toggle .bars { position: relative; }
.nav-toggle .bars::before { position: absolute; top: -7px; }
.nav-toggle .bars::after { position: absolute; top: 7px; }
.nav-toggle[aria-expanded="true"] .bars { transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] .bars::before { transform: rotate(-90deg) translateX(-7px); }
.nav-toggle[aria-expanded="true"] .bars::after { opacity: 0; }

@media (max-width: 900px) {
  .nav-toggle { display: block; }

  /* On a phone the hero copy leads and the photograph follows, so the bar has
     nothing to float over and no reason to be a scrim. A plain surface reads
     better here: the fading version washed a pale haze across the top of the
     picture as it scrolled underneath. */
  .site-header { border-bottom-color: var(--rule-soft); }
  .site-header::before {
    inset: 0;
    background: rgba(255, 253, 248, 0.94);
    -webkit-backdrop-filter: blur(16px) saturate(120%);
    backdrop-filter: blur(16px) saturate(120%);
  }

  .site-nav {
    /* the header's backdrop-filter makes it the containing block for this
       fixed overlay, so inset: 0 would only cover the header bar. Explicit
       viewport units cover the screen from the header's top-left origin. */
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    z-index: 120;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 2.1rem;
    background: var(--paper);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.32s var(--ease), visibility 0.32s var(--ease);
  }
  .site-nav.is-open { opacity: 1; visibility: visible; }
  .site-nav a:not(.btn) {
    font-family: var(--serif);
    font-size: 1.9rem;
    font-weight: 420;
    color: var(--ink);
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
  }
  .site-nav .btn {
    font-size: 1.05rem;
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.4s var(--ease), transform 0.4s var(--ease), background-color 0.22s var(--ease);
  }
  .site-nav.is-open a:not(.btn),
  .site-nav.is-open .btn { opacity: 1; transform: none; }
  .site-nav.is-open a:nth-child(1) { transition-delay: 0.06s; }
  .site-nav.is-open a:nth-child(2) { transition-delay: 0.11s; }
  .site-nav.is-open a:nth-child(3) { transition-delay: 0.16s; }
  .site-nav.is-open a:nth-child(4) { transition-delay: 0.21s; }
}

/* ---------- Home hero (v2) ----------
   The photograph is masked into the paper: it stays fully saturated where
   Julia is, then dissolves toward the copy and toward the section below. The
   headline therefore sits on real paper — no white scrim over the photo, which
   is what made the v1 hero read slightly grey and made small type hard to see. */

.hero-v2 {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: min(100svh, 54rem);
  padding-bottom: clamp(1.5rem, 3vw, 2.75rem);
  /* The photograph dissolves into clean white rather than warm paper: the lake
     is cool, and fading it into a cream field turned the whole right-hand side
     beige. The warmth returns further down the page, where the washes live. */
  background: var(--pure);
  overflow: clip;
}

.hero-media {
  position: absolute;
  inset: 0 auto 0 0;
  width: 58%;
  z-index: 0;
}
.hero-photo {
  width: 100%;
  height: 100%;
  max-width: none;
  /* Restore the original edge-to-edge composition while the 4000px source in
     the responsive image set keeps the enlarged crop crisp on dense screens. */
  object-fit: cover;
  object-position: 50% 36%;
  -webkit-mask-image:
    linear-gradient(90deg, #000 0 62%, rgba(0, 0, 0, 0.88) 72%, rgba(0, 0, 0, 0.36) 88%, transparent 100%),
    linear-gradient(180deg, #000 0 58%, rgba(0, 0, 0, 0.55) 84%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(90deg, #000 0 62%, rgba(0, 0, 0, 0.88) 72%, rgba(0, 0, 0, 0.36) 88%, transparent 100%),
    linear-gradient(180deg, #000 0 58%, rgba(0, 0, 0, 0.55) 84%, transparent 100%);
  mask-composite: intersect;
}
/* a breath of light across the top of the frame — white, not cream, so the
   fade on the right stays clean */
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.32), transparent 30%);
  pointer-events: none;
}

.hero-inner {
  position: relative;
  z-index: 1;
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 36rem);
  align-items: center;
  gap: clamp(1.5rem, 4vw, 4rem);
  padding-top: calc(var(--header-h) + 1.5rem);
}

.hero-panel { grid-column: 2; }

/* The identity line: who Julia is, before what she offers. Set as a quiet
   italic line in the headline's own serif, so it reads as part of the same
   voice (like a book's byline) rather than a tagged label over the artwork. */
.role-line {
  margin-bottom: 1.1rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.12rem, 1rem + 0.35vw, 1.3rem);
  line-height: 1.35;
  color: var(--ink-2);
}

.hero-panel .lede {
  margin-top: 1.6rem;
  max-width: 32rem;
}

/* Credential rail: the trust facts, grounded on the hero's bottom edge where
   the photograph has already faded to paper. */
.hero-rail {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0 clamp(1rem, 3vw, 2.5rem);
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: 1.4rem;
  border-top: 1px solid var(--rule-soft);
}
.hero-rail dt {
  font-family: var(--sans);
  font-weight: 700;
  font-size: var(--size-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.hero-rail dd {
  margin-top: 0.45rem;
  font-family: var(--serif);
  font-size: 1.16rem;
  line-height: 1.3;
  color: var(--ink);
}

@media (max-width: 900px) {
  /* On a phone the hero reads top to bottom: who Julia is and what she offers,
     then her portrait, then the credential rail.
     Putting the photograph first — the desktop arrangement, stacked — meant that
     the moment the page scrolled, the fixed header slid straight over her face.
     Leading with the copy also puts the message on screen first, which is what a
     phone reader needs. */
  .hero-v2 {
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding-top: var(--header-h);
  }
  .hero-inner { order: 1; }
  .hero-media { order: 2; }
  .hero-rail-wrap { order: 3; }

  .hero-media {
    position: relative;
    inset: auto;
    width: 100%;
    margin-top: clamp(2.25rem, 7vw, 3.25rem);
  }
  .hero-photo {
    /* Tall and cropped close, so Julia reads at portrait size rather than as a
       small figure in a wide landscape. */
    height: clamp(26rem, 118vw, 37rem);
    object-position: 50% 38%;
    /* Now that the picture sits between paper above and paper below, it dissolves
       at both edges instead of only the bottom. */
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 10%, #000 82%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0, #000 10%, #000 82%, transparent 100%);
    -webkit-mask-composite: source-over;
    mask-composite: add;
  }
  /* The mask handles the blend on a phone; a wash over the top would only grey it. */
  .hero-media::after { display: none; }

  .hero-inner {
    display: block;
    padding-top: clamp(1.75rem, 6vw, 2.75rem);
  }
  .hero-panel { grid-column: 1; }
  .hero-rail { margin-top: clamp(1.5rem, 4vw, 2.25rem); }
  .hero-rail {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.4rem clamp(1rem, 4vw, 2rem);
  }
}

/* Desktop. The edge-to-edge photograph grows with the window while the copy
   stays in a fixed column, so on wide screens the cover crop zoomed in until
   Julia's face was several times life-size and her dissolving arms read as a
   floating torso. From laptop width up, the portrait moves into the grid's left
   column instead: framed head to hip, sharing the copy's alignment, and set
   against a pale sky-and-lake background so the photograph reads as a window
   onto the same view rather than a print laid on the page. */
@media (min-width: 1100px) {
  .hero-v2 {
    --hero-gap: 3rem;
    /* the portrait fills the grid's first column: the container, as .container
       sizes it, less the 36rem copy column and the gap */
    --portrait-w: calc(min(100% - 2 * var(--gutter), var(--container)) - 36rem - var(--hero-gap));
    /* The same width in viewport units, for the background maths below, where
       a percentage would mean a share of the hero's height. It can differ from
       the real width by a scrollbar, which moves the horizon by about 2px. */
    --portrait-vw: calc(min(100vw - 2 * var(--gutter), var(--container)) - 36rem - var(--hero-gap));
    /* never taller than the photo's own 2:3 shape, so it always fills the frame
       by width and the horizon maths holds */
    --portrait-h: min(clamp(32rem, 100svh - var(--header-h) - 12rem, 45rem), 1.5 * var(--portrait-vw));

    /* Sky above, lake below, split level with the portrait's own horizon. The
       tints are the photo's edge colours taken most of the way to white: the sky
       blue at the top, paling into haze toward the horizon, and the water
       darkest just below it, as in the picture.

       The horizon sits 38.6% down the source photo. The photo is cover-fitted
       by width (drawn 1.5 × portrait width tall) and cropped at object-position
       30%, which puts the horizon 0.386 × drawn − 0.3 × (drawn − portrait
       height), or 0.129 × width + 0.3 × height, below the portrait's top. */
    --horizon: calc(var(--header-h) + 1.5rem + 0.129 * var(--portrait-vw) + 0.3 * var(--portrait-h));
    background: linear-gradient(
      180deg,
      #e6eef5 0,
      #f1f4f6 calc(var(--horizon) - 1px),
      #dfe7ee var(--horizon),
      #ebf0f4 calc(var(--horizon) + 12rem),
      #ffffff 100%
    );
  }
  /* The pale sky is quiet enough to carry the navigation on its own, so the
     header's white scrim (there for the old full-bleed photo) would only cut a
     white band across it. It returns once the page scrolls. */
  .v2 .site-header:not(.is-scrolled)::before { background: none; }
  .hero-media {
    top: calc(var(--header-h) + 1.5rem);
    bottom: auto;
    left: calc((100% - min(100% - 2 * var(--gutter), var(--container))) / 2);
    width: var(--portrait-w);
    height: var(--portrait-h);
    overflow: hidden;
    /* no shadow and a tight corner: an opening onto the lake, not a print */
    border-radius: var(--r-sm);
  }
  .hero-photo {
    object-position: 50% 30%;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .hero-media::after { display: none; }
  .hero-inner {
    gap: var(--hero-gap);
    min-height: calc(var(--header-h) + 1.5rem + var(--portrait-h));
  }
}
@media (min-width: 1320px) {
  .hero-v2 { --hero-gap: 4rem; }
}

/* ---------- Affiliation strip ---------- */

.affiliation {
  padding-block: clamp(2.5rem, 4vw, 3.75rem);
  background: var(--pure);
}
.affiliation-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(1.75rem, 4vw, 4rem);
}
.affiliation p {
  max-width: 44rem;
  font-family: var(--sans);
  font-size: var(--size-ui);
  font-weight: 500;
  line-height: 1.7;
  color: var(--ink-2);
  text-wrap: pretty;
}
.affiliation strong { font-weight: 700; color: var(--ink); }

.affiliation-logos {
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 3vw, 2.5rem);
}
.affiliation-logos img {
  width: auto;
  height: clamp(2.1rem, 3.4vw, 2.8rem);
  /* the two partner marks arrive in different colourways; muting them keeps
     the strip quiet and stops them competing with Julia's own coral flower */
  opacity: 0.62;
  filter: grayscale(1);
  transition: opacity 0.3s var(--ease), filter 0.3s var(--ease);
}
.affiliation-logos img:hover { opacity: 1; filter: none; }

@media (max-width: 860px) {
  .affiliation-inner { grid-template-columns: 1fr; }
}

/* ---------- Begin: numbered step cards ---------- */

.step-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}

.step-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
  padding: clamp(1.9rem, 3vw, 2.6rem);
  overflow: hidden;
  background: var(--pure);
  border: 1px solid var(--rule-soft);
  border-radius: var(--r);
  box-shadow: var(--shadow-1);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease),
    border-color 0.35s var(--ease);
}
/* an accent edge that grows on hover — the card's only moving part */
.step-card::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: linear-gradient(180deg, var(--coral), var(--butter));
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.45s var(--ease);
}
.step-card:hover {
  transform: translateY(-4px);
  border-color: var(--coral-soft);
  box-shadow: var(--shadow-3);
}
.step-card:hover::before { transform: none; }

.step-num {
  position: absolute;
  top: clamp(1.1rem, 2vw, 1.6rem);
  right: clamp(1.3rem, 2.4vw, 2rem);
  font-family: var(--serif);
  font-size: clamp(2.4rem, 4vw, 3.2rem);
  line-height: 1;
  color: var(--butter);
  opacity: 0.6;
  pointer-events: none;
}

.step-card p {
  color: var(--ink-2);
  font-size: 1.03rem;
  line-height: 1.6;
  text-wrap: pretty;
}
.step-card .text-link { margin-top: auto; }

.begin-note {
  margin-top: clamp(2.25rem, 4vw, 3.25rem);
  text-align: center;
  font-family: var(--sans);
  font-size: var(--size-ui);
  color: var(--ink-2);
}

/* ---------- Story ---------- */

.story-v2 {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: center;
}

/* The portrait stands on its own — the offset coral hairline that used to sit
   behind it read as a stray brown line rather than as a frame. */
.story-figure img {
  border-radius: var(--r);
  box-shadow: var(--shadow-2);
}

.story-copy .h2 { margin-bottom: 1.4rem; }
.story-copy .prose { color: var(--ink-2); }
.story-copy .text-link { margin-top: 1.9rem; display: inline-block; }

@media (max-width: 900px) {
  .story-v2 { grid-template-columns: 1fr; gap: 3rem; }
  .story-figure { max-width: 24rem; }
}

/* ---------- Book ---------- */

.book-v2 {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2.5rem, 5vw, 5.5rem);
  align-items: center;
}

.book-title {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 420;
  font-size: clamp(2.6rem, 1.8rem + 2.8vw, 4rem);
  line-height: 1.03;
  letter-spacing: -0.016em;
}
.book-status {
  margin-top: 0.9rem;
  font-family: var(--sans);
  font-size: var(--size-meta);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--coral-ink);
}
.book-copy .prose { margin-top: 1.6rem; color: var(--ink-2); }

.book-praise {
  margin-top: 2rem;
  padding-left: 1.5rem;
  border-left: 2px solid var(--coral);
}
.book-praise blockquote p {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.24rem;
  line-height: 1.45;
  color: var(--ink);
}
.book-praise figcaption {
  margin-top: 0.75rem;
  font-family: var(--sans);
  font-size: var(--size-meta);
  font-weight: 700;
  color: var(--ink-2);
}
.book-praise figcaption span {
  display: block;
  margin-top: 0.15rem;
  font-weight: 500;
  color: var(--ink-3);
}
.book-praise figcaption em { font-style: italic; }

/* The beat's right-hand column is just the cover now — it sizes and centres
   itself (see Book cover below). The drawn cosmos that used to tuck beside the
   old photograph is gone: against printed artwork it read as a sticker stuck on
   the cover rather than as part of the page. */

@media (max-width: 900px) {
  .book-v2 { grid-template-columns: 1fr; gap: 3rem; }
}

/* ---------- Book cover ---------- */

/* The cover is presented as a printed object rather than a flat image: a spine
   shaded down the binding edge, corners that are nearly square — a card-sized
   radius is what makes a cover read as a screenshot — and a warm shadow that
   sets it on the page instead of floating it above one. Everything is drawn in
   CSS over the artwork, so the treatment holds for whatever cover file the
   publisher supplies next. */
.book-cover {
  position: relative;
  display: block;
  max-width: 23rem;
  margin-inline: auto;
  isolation: isolate;
}
.book-cover img {
  display: block;
  width: 100%;
  border-radius: 2px 4px 4px 2px;
  box-shadow:
    0 1px 2px rgba(63, 48, 34, 0.14),
    0 10px 20px -10px rgba(63, 48, 34, 0.28),
    0 32px 56px -26px rgba(63, 48, 34, 0.32);
  transition: box-shadow 0.35s var(--ease);
}

/* The binding edge: shade where the cover wraps the spine, one lit line at the
   fold itself. */
.book-cover::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 7.5%;
  border-radius: 2px 0 0 2px;
  background: linear-gradient(
    90deg,
    rgba(28, 20, 12, 0.28) 0,
    rgba(28, 20, 12, 0.1) 24%,
    rgba(255, 255, 255, 0.16) 47%,
    rgba(28, 20, 12, 0.05) 74%,
    transparent 100%
  );
  pointer-events: none;
  z-index: 1;
}

/* A hairline keeps the printed area crisp where pale sky meets warm paper. */
.book-cover::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 2px 4px 4px 2px;
  box-shadow: inset 0 0 0 1px rgba(63, 48, 34, 0.18);
  pointer-events: none;
  z-index: 2;
}

/* Covers get clicked, so where one links onward it lifts like a book picked up. */
a.book-cover { transition: transform 0.35s var(--ease); }
a.book-cover:hover { transform: translateY(-5px); }
a.book-cover:hover img {
  box-shadow:
    0 1px 2px rgba(63, 48, 34, 0.14),
    0 16px 28px -12px rgba(63, 48, 34, 0.3),
    0 44px 70px -30px rgba(63, 48, 34, 0.36);
}

@media (max-width: 900px) {
  .book-cover { max-width: 19rem; }
}

/* ---------- Voices ---------- */

.voice-stack {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  gap: clamp(1.5rem, 3vw, 2.25rem);
}

.voice {
  position: relative;
  padding: clamp(2.25rem, 3.5vw, 3rem);
  background: var(--pure);
  border: 1px solid var(--rule-soft);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
}
/* an oversized quotation mark, set as artwork rather than punctuation */
.voice::before {
  content: "\201C";
  position: absolute;
  top: 0.16em;
  left: 0.3em;
  font-family: var(--serif);
  font-size: 5.5rem;
  line-height: 1;
  color: var(--coral);
  opacity: 0.24;
  pointer-events: none;
}
.voice p {
  position: relative;
  font-family: var(--serif);
  font-size: clamp(1.2rem, 1.05rem + 0.5vw, 1.4rem);
  line-height: 1.5;
  letter-spacing: -0.006em;
  text-wrap: pretty;
}
.voice footer {
  margin-top: 1.5rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--rule-soft);
  font-family: var(--sans);
  font-size: var(--size-meta);
  font-weight: 700;
  color: var(--ink);
}
.voice cite { font-style: normal; }
.voice .role {
  display: block;
  margin-top: 0.2rem;
  font-weight: 500;
  color: var(--ink-3);
}

/* Pull quotes on the inner pages keep the simpler rule-and-text treatment. */
.quote-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: clamp(2.5rem, 5vw, 5rem);
}
.pull-quote {
  border-top: 2px solid var(--ink);
  padding-top: 1.9rem;
}
.pull-quote p {
  font-family: var(--serif);
  font-size: clamp(1.26rem, 1.1rem + 0.6vw, 1.52rem);
  line-height: 1.5;
  text-wrap: pretty;
}
.pull-quote p::before { content: "\201C"; color: var(--coral-ink); }
.pull-quote p::after { content: "\201D"; color: var(--coral-ink); }
.pull-quote footer {
  margin-top: 1.4rem;
  font-family: var(--sans);
  font-size: var(--size-meta);
  font-weight: 600;
  color: var(--ink-2);
}
.pull-quote footer::before {
  content: "";
  display: inline-block;
  width: 1.35rem;
  height: 1px;
  background: var(--coral);
  vertical-align: middle;
  margin-right: 0.65rem;
}
.pull-quote cite { font-style: normal; }
.pull-quote .role { color: var(--ink-3); font-weight: 500; }
.pull-quote .role em { font-style: italic; }

/* Endorsements run different lengths, so praise reads best as one column. */
.praise-list {
  display: grid;
  gap: clamp(2.4rem, 4vw, 3.4rem);
  max-width: 46rem;
}

/* ---------- Invitation / signup ---------- */

.invite { text-align: center; }
.invite-inner { max-width: 40rem; margin-inline: auto; }
.invite-flower {
  width: 3.4rem;
  margin-inline: auto;
  margin-bottom: 1.7rem;
  color: var(--coral);
}
.invite-flower--lake { color: var(--lake); }
.invite .eyebrow { display: block; margin-bottom: 1.15rem; }
.invite .h2 { margin-bottom: 1.2rem; }
.invite p.support { color: var(--ink-2); text-wrap: pretty; }

/* The closing moment stays light. Its presence comes from layered radial light
   and a raised white card holding the form, not from a dark band — three washes
   pooling from different corners give it depth that a flat tint cannot. */
.invite--soft {
  position: relative;
  overflow: clip;
  isolation: isolate;
  padding-block: clamp(5rem, 8vw, 8rem);
  background: var(--paper);
}
.invite--soft::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(44% 62% at 50% -6%, var(--butter-wash), transparent 66%),
    radial-gradient(48% 58% at 90% 104%, rgba(211, 146, 140, 0.2), transparent 64%),
    radial-gradient(46% 56% at 6% 96%, rgba(155, 182, 192, 0.16), transparent 62%);
  /* feathered at the top, so the glow rises out of the section above instead
     of starting on a hard edge */
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 9rem);
  mask-image: linear-gradient(180deg, transparent, #000 9rem);
  pointer-events: none;
}

.invite-card {
  max-width: 33rem;
  margin: clamp(2.25rem, 4vw, 3rem) auto 0;
  padding: clamp(1.6rem, 3vw, 2.1rem) clamp(1.4rem, 3vw, 2.1rem) clamp(1.4rem, 2.5vw, 1.75rem);
  background: var(--pure);
  border: 1px solid var(--rule-soft);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
}
.invite-card .form-note { margin-top: 0.9rem; }
.invite-card .form-consent { margin-top: 0.9rem; }

.signup-form {
  display: flex;
  gap: 0.6rem;
  max-width: 30rem;
  margin: 0 auto;
}
.signup-form input[type="email"] {
  flex: 1;
  min-width: 0;
  font-family: var(--sans);
  font-size: var(--size-ui);
  color: var(--ink);
  background: var(--pure);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  padding: 0 1.35rem;
}
.signup-form input[type="email"]::placeholder { color: var(--ink-3); }
.signup-form input[type="email"]:focus {
  outline: none;
  border-color: var(--ink-2);
  box-shadow: 0 0 0 3px rgba(211, 146, 140, 0.25);
}

.form-consent {
  margin-top: 1.1rem;
  font-family: var(--sans);
  font-size: 0.8rem;
  color: var(--ink-3);
}
.form-note {
  margin-top: 1.2rem;
  font-family: var(--sans);
  font-size: var(--size-ui);
  font-weight: 600;
  color: var(--sage-ink);
  min-height: 1.4em;
}
.form-note.is-error { color: var(--coral-ink); }

@media (max-width: 560px) {
  .signup-form { flex-direction: column; }
  .signup-form input[type="email"] { padding: 1rem 1.35rem; }
}

/* ---------- Footer ---------- */

.site-footer {
  background: var(--ivory);
  border-top: 1px solid var(--rule-soft);
  color: var(--ink-2);
  padding-block: clamp(3.5rem, 6vw, 5.5rem) 2.25rem;
  font-family: var(--sans);
}
/* After the homepage's closing invitation the change of paper already marks
   the footer, so the hairline would only double it. */
main:has(> .invite--soft:last-child) + .site-footer {
  border-top: 0;
}

.footer-top {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 2.5rem 4rem;
}

.footer-id .wordmark { font-size: 1.28rem; }
.footer-id p {
  margin-top: 1rem;
  font-size: var(--size-ui);
  color: var(--ink-2);
  max-width: 22rem;
  line-height: 1.65;
}

/* Julia's own signature closes the page. A row of drawn flowers here read as
   decoration with no job to do; the signature is the same warmth with meaning
   behind it, and the flower already lives in the wordmark above. */
.footer-signature {
  width: clamp(9rem, 15vw, 11.5rem);
  margin-top: 1.75rem;
  opacity: 0.72;
  mix-blend-mode: multiply;
}

/* kept for the inner pages, which still ship the drawn flower cluster */
.footer-cluster {
  display: flex;
  align-items: flex-end;
  margin-top: 1.5rem;
  opacity: 0.9;
}

/* The v2 footer groups links under headings; the existing inner pages ship a
   flat list of links, so both shapes have to lay out sensibly. */
.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem 3.5rem;
}
.footer-nav > div {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.footer-nav h2 {
  font-size: var(--size-label);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sage-ink);
  margin-bottom: 0.2rem;
}
.footer-nav a {
  font-size: var(--size-ui);
  font-weight: 550;
  color: var(--ink-2);
  text-decoration: none;
}
.footer-nav a:hover { color: var(--coral-ink); }

.footer-note {
  margin-top: clamp(2.5rem, 4vw, 3.5rem);
  padding-top: 1.6rem;
  border-top: 1px solid var(--rule-soft);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem 2.5rem;
  font-size: 0.82rem;
  color: var(--ink-3);
}
.footer-note p { max-width: 46rem; line-height: 1.7; }
.footer-note a { color: var(--ink-2); }

/* ---------- Inner page shared ---------- */

.page-hero {
  /* clears the fixed header */
  padding-top: calc(var(--header-h) + clamp(3rem, 5vw, 5rem));
}
.page-hero .eyebrow { display: block; margin-bottom: 1.2rem; }
.page-hero .lede { margin-top: 1.5rem; max-width: 38rem; }

.page-hero--split .container {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: clamp(2.5rem, 5vw, 5rem);
  align-items: center;
}
/* A photograph in a page hero is treated as a framed image. The book cover is
   excluded: it brings its own printed-object treatment and its own size. */
.page-hero--split figure:not(.book-cover) img {
  border-radius: var(--r);
  box-shadow: var(--shadow-2);
}

@media (max-width: 900px) {
  .page-hero--split .container { grid-template-columns: 1fr; }
  .page-hero--split figure:not(.book-cover) { max-width: 24rem; }
}

/* ---------- About page ---------- */

.about-layout {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: start;
}

.about-story h2 {
  font-family: var(--serif);
  font-weight: 460;
  font-size: 1.55rem;
  letter-spacing: -0.008em;
  margin: 2.6rem 0 1rem;
}
.about-story h2:first-child { margin-top: 0; }
.about-story p { color: var(--ink-2); margin-bottom: 1.3em; text-wrap: pretty; }
.about-story .pull-quote { margin-top: 2.8rem; }

.fact-card {
  position: sticky;
  top: calc(var(--header-h) + 2rem);
  border: 1px solid rgba(229, 211, 143, 0.55);
  border-radius: var(--r);
  padding: 2rem;
  background: var(--butter-card);
  box-shadow: var(--shadow-1);
}
.fact-card h2 {
  font-family: var(--sans);
  font-size: var(--size-label);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sage-ink);
  margin-bottom: 1.25rem;
}
.fact-card ul {
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--sans);
  font-size: 0.94rem;
  color: var(--ink-2);
}
.fact-card li {
  padding: 0.75rem 0;
  border-top: 1px solid var(--rule-soft);
  line-height: 1.55;
}
.fact-card li:first-child { border-top: 0; padding-top: 0; }
.fact-card li:last-child { padding-bottom: 0; }

.image-duo {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  gap: clamp(1.25rem, 2.5vw, 2rem);
  align-items: end;
}
.image-duo img { border-radius: var(--r); box-shadow: var(--shadow-1); }
.image-duo figcaption {
  margin-top: 0.85rem;
  font-family: var(--sans);
  font-size: var(--size-meta);
  color: var(--ink-3);
}

@media (max-width: 900px) {
  .about-layout { grid-template-columns: 1fr; }
  .fact-card { position: static; }
  .image-duo { grid-template-columns: 1fr; }
  .image-duo figure { max-width: 26rem; }
}

/* ---------- Notebook excerpt ---------- */

.notebook { max-width: 46rem; }
.notebook .eyebrow { display: block; margin-bottom: 1.4rem; }
.notebook-quote {
  font-family: var(--serif);
  font-size: clamp(1.35rem, 1.15rem + 0.8vw, 1.75rem);
  font-style: italic;
  line-height: 1.5;
  text-wrap: pretty;
}
.notebook-source {
  margin-top: 1.5rem;
  font-family: var(--sans);
  font-size: var(--size-meta);
  font-weight: 600;
  color: var(--ink-3);
}

.signature-block { margin-top: 3rem; }
.signature-block .closing {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.2rem;
  color: var(--ink-2);
}
.signature-block img {
  width: 15rem;
  mix-blend-mode: multiply;
  margin-top: 0.4rem;
}

/* ---------- Programs page ---------- */

.upcoming-panel {
  background: var(--butter-wash);
  border: 1px solid rgba(229, 211, 143, 0.6);
  border-radius: var(--r);
  padding: clamp(2rem, 4vw, 3.25rem);
  display: grid;
  grid-template-columns: minmax(0, 8fr) minmax(0, 4fr);
  gap: 2rem;
  align-items: center;
  box-shadow: var(--shadow-1);
}
.upcoming-panel .h3 { margin-bottom: 0.9rem; }
.upcoming-panel p { color: var(--ink-2); font-size: 1.04rem; }
.upcoming-panel .actions,
.upcoming-panel .hero-actions {
  margin-top: 0;
  justify-content: flex-end;
}

@media (max-width: 900px) {
  .upcoming-panel { grid-template-columns: 1fr; }
  .upcoming-panel .actions,
  .upcoming-panel .hero-actions { justify-content: flex-start; }
}

.program-group { margin-top: var(--space-section-sm); }
.program-group > .eyebrow {
  display: block;
  padding-bottom: 1.2rem;
  border-bottom: 2px solid var(--ink);
}

.program-row {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  gap: 1.5rem 3rem;
  padding-block: clamp(1.9rem, 3vw, 2.6rem);
  border-bottom: 1px solid var(--rule-soft);
  transition: background-color 0.3s var(--ease);
}
.program-row h3 { margin-bottom: 0.35rem; }
.program-row .who {
  font-family: var(--sans);
  font-size: var(--size-meta);
  font-weight: 600;
  color: var(--sage-ink);
}
.program-row .desc {
  color: var(--ink-2);
  font-size: 1.04rem;
  line-height: 1.6;
  text-wrap: pretty;
}
.program-row .actions,
.program-row .hero-actions {
  margin-top: 1.2rem;
  gap: 1.6rem;
}

@media (max-width: 700px) {
  .program-row { grid-template-columns: 1fr; gap: 0.8rem; }
}

/* ---------- Full-bleed image band ---------- */

.photo-band { margin-block: var(--space-section-sm); }
.photo-band img {
  width: 100%;
  max-height: 34rem;
  object-fit: cover;
  border-radius: var(--r);
  box-shadow: var(--shadow-1);
}
.photo-band figcaption {
  margin-top: 0.9rem;
  font-family: var(--sans);
  font-size: var(--size-meta);
  color: var(--ink-3);
}

/* ---------- Connect page ---------- */

.connect-section { padding-bottom: var(--space-section); }
.contact-form .actions,
.contact-form .hero-actions { margin-top: 0.4rem; }

.connect-layout {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: start;
}

.contact-form { display: grid; gap: 1.35rem; }
.contact-form label {
  display: block;
  font-family: var(--sans);
  font-size: var(--size-meta);
  font-weight: 700;
  margin-bottom: 0.5rem;
  color: var(--ink);
}
.contact-form .optional { font-weight: 500; color: var(--ink-3); }
.contact-form input,
.contact-form select,
.contact-form textarea {
  width: 100%;
  font-family: var(--sans);
  font-size: var(--size-ui);
  color: var(--ink);
  background: var(--pure);
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  padding: 0.9rem 1.05rem;
}
.contact-form select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%234f555a' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1.05rem center;
  padding-right: 2.6rem;
}
.contact-form textarea { resize: vertical; min-height: 9.5rem; }
.contact-form input:focus,
.contact-form select:focus,
.contact-form textarea:focus {
  outline: none;
  border-color: var(--ink-2);
  box-shadow: 0 0 0 3px rgba(211, 146, 140, 0.25);
}

.connect-aside {
  position: sticky;
  top: calc(var(--header-h) + 2rem);
  display: grid;
  gap: 1.5rem;
}
.aside-card {
  border: 1px solid var(--rule-soft);
  border-radius: var(--r);
  padding: 1.9rem;
  background: var(--pure);
  box-shadow: var(--shadow-1);
}
.aside-card h2 {
  font-family: var(--serif);
  font-size: 1.28rem;
  font-weight: 460;
  margin-bottom: 0.7rem;
}
.aside-card p { font-size: 1rem; color: var(--ink-2); line-height: 1.6; }
.aside-card p + p { margin-top: 0.7em; }
.aside-card .text-link { margin-top: 1rem; display: inline-block; }

@media (max-width: 900px) {
  .connect-layout { grid-template-columns: 1fr; }
  .connect-aside { position: static; }
}

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

.cta-band {
  position: relative;
  isolation: isolate;
  text-align: center;
  background: var(--ivory);
}
.cta-band::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(52% 66% at 50% 0%, rgba(211, 146, 140, 0.16), transparent 68%);
  pointer-events: none;
}
.cta-band .h2 { margin-bottom: 1.1rem; }
.cta-band p {
  color: var(--ink-2);
  max-width: 36rem;
  margin-inline: auto;
  text-wrap: pretty;
}
.cta-band .actions,
.cta-band .hero-actions { justify-content: center; }

/* ---------- 404 ---------- */

.lost {
  text-align: center;
  padding-block: calc(var(--header-h) + clamp(5rem, 10vw, 9rem)) clamp(6rem, 12vw, 10rem);
}
.lost .invite-flower { width: 4.2rem; color: var(--sage); }
.lost .display { margin-bottom: 1.2rem; }
.lost p { color: var(--ink-2); max-width: 30rem; margin-inline: auto; }
.lost .actions,
.lost .hero-actions { justify-content: center; }

/* ---------- Breathwork challenge teaser ----------
   A wide card for the homepage's "Start where you are" section, ready for when
   the challenge is linked from the homepage. The challenge page itself is
   styled by css/challenge.css. */

/* Homepage teaser: one wide card under the two first steps. */
.challenge-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 1.5rem clamp(2rem, 5vw, 4rem);
  align-items: center;
  margin-top: clamp(1.25rem, 2.5vw, 2rem);
  padding: clamp(1.9rem, 3vw, 2.6rem);
  background: var(--butter-card);
  border: 1px solid rgba(229, 211, 143, 0.6);
  border-radius: var(--r);
  box-shadow: var(--shadow-1);
}
.challenge-card .eyebrow { display: block; margin-bottom: 0.8rem; }
.challenge-card .h3 { margin-bottom: 0.6rem; }
.challenge-card p {
  color: var(--ink-2);
  font-size: 1.03rem;
  line-height: 1.6;
  max-width: 40rem;
  text-wrap: pretty;
}

@media (max-width: 700px) {
  .challenge-card { grid-template-columns: 1fr; }
}

/* ---------- Reveal on scroll ----------
   Gated behind html.js (set inline in <head>) so content never stays hidden
   if JavaScript is unavailable or fails to load. */

html.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}
html.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}
html.js .reveal[data-reveal-delay="1"] { transition-delay: 0.09s; }
html.js .reveal[data-reveal-delay="2"] { transition-delay: 0.18s; }
html.js .reveal[data-reveal-delay="3"] { transition-delay: 0.27s; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  html.js .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .wordmark:hover img { transform: none; }
  .step-card,
  .step-card::before,
  .site-nav,
  .site-nav a,
  .site-nav .btn,
  a.book-cover,
  .book-cover img { transition: none; }
  .step-card:hover { transform: none; }
  a.book-cover:hover { transform: none; }
}
