/* Sthira Me &mdash; Brand 3.3 tokens.
   Georgia Bold (display) + Arial (body), web-safe OS fonts, no @font-face.
   Palette: Sandstone / Sunset / Ink + pillar colours. */

:root {
  --sandstone: #F5EFE6;
  --sunset:    #E85D2F;
  --ink:       #1F2428;
  --russet:    #B5583F;
  --teal:      #14B8A6;
  --lime:      #A8C26B;  /* Soft sage per Brief 1.5 §3 (was #84CC16 Tailwind lime, founder 28k: "not the right green"). */
  --sky:       #4EA6C6;
  --marigold:  #F59E0B;
  --plum:      #6E3E6B;
  --stone:     #6B6B6B;
  --hairline:  rgba(31, 36, 40, 0.10);

  /* Spacing scale */
  --s-xs: .5rem;
  --s-s:  .875rem;
  --s-m:  1.25rem;
  --s-l:  2rem;
  --s-xl: 3rem;
  --s-xxl: 5rem;

  --container: 960px;
}

/* Reset */
* { box-sizing: border-box; margin: 0; padding: 0; }

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

body {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 1.0625rem;
  line-height: 1.55;
  color: var(--ink);
  background: var(--sandstone);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  line-height: 1.2;
  color: var(--ink);
}

p { max-width: 62ch; }

a {
  color: var(--russet);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color 120ms ease-out;
}
a:hover { color: var(--sunset); }

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

/* Site header — mark top-left per Brand §8.2.
   28i: full-viewport sticky white bar so the nav follows the member
   down the page. Inner content (lockup + nav) stays aligned to the
   container grid via padding-inline: max(...). Logo bumped from 48 to
   56 for a slightly stronger brand presence. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: #fff;
  border-bottom: 1px solid color-mix(in srgb, var(--ink) 8%, transparent);
  padding: var(--s-s) max(var(--s-m), calc((100% - var(--container)) / 2));
  max-width: none;
  margin: 0;
  width: 100%;
}
.brand-lockup {
  display: inline-flex;
  align-items: center;
  gap: .625rem;
  text-decoration: none;
  color: var(--ink);
}
.brand-lockup:hover { color: var(--ink); }
.pebble-mark {
  display: block;
  height: 56px;
  width: 56px;
  user-select: none;
}
.brand-wordmark {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 1.35rem;
  letter-spacing: 0.01em;
  color: var(--ink);
}

/* Main */
main {
  flex: 1;
  width: 100%;
}

/* ------------ HERO ------------ */
.hero {
  max-width: var(--container);
  margin: 0 auto;
  padding: var(--s-xl) var(--s-m) var(--s-xxl);
  text-align: center;
}

.wordmark {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  color: var(--ink);
  font-size: clamp(2.5rem, 8vw, 4.25rem);
  line-height: 1;
  letter-spacing: 0.005em;
  margin: var(--s-l) 0 var(--s-s);
  display: inline-block;
}
/* Sunset dot over the dotless-i (&#305;) &mdash; the single typographic flourish. */
.wordmark-i {
  position: relative;
  display: inline-block;
}
.wordmark-i::before {
  content: '';
  position: absolute;
  left: 50%;
  top: -0.04em;
  width: 0.2em;
  height: 0.2em;
  background: var(--sunset);
  border-radius: 50%;
  transform: translateX(-50%);
}

.eyebrow {
  color: var(--russet);
  font-size: 1rem;
  margin: 0 auto var(--s-m);
}

/* Larger eyebrow for section openers where it carries more weight
   (e.g. "Our story." on /story.html). */
.eyebrow--lg {
  font-size: clamp(1.25rem, 2.4vw, 1.625rem);
  letter-spacing: 0.005em;
}

.hero-headline {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  color: var(--ink);
  margin: var(--s-m) auto var(--s-s);
  max-width: 22ch;
  letter-spacing: -0.005em;
}

.hero-sub {
  font-size: 1.0625rem;
  color: var(--ink);
  margin: 0 auto var(--s-l);
  max-width: 42ch;
}

.whisper {
  font-size: 0.9rem;
  color: var(--stone);
  margin-top: var(--s-m);
}

/* Waitlist form */
.waitlist-form {
  max-width: 520px;
  margin: 0 auto;
}
.waitlist-row {
  display: flex;
  gap: .5rem;
  flex-wrap: wrap;
  justify-content: center;
}
.waitlist-form input[type="email"],
.waitlist-form input[type="text"] {
  /* iOS Safari otherwise overrides border-radius, applies inner shadow,
     and renders a different background. Explicit appearance reset +
     16px font-size keeps the pill shape and prevents focus auto-zoom. */
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  -webkit-tap-highlight-color: transparent;
  background-clip: padding-box;

  flex: 1 1 220px;
  min-width: 0;
  height: 48px;                     /* explicit height: padding alone renders unevenly on iOS */
  padding: 0 1.1rem;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 16px;                  /* never below 16px on iOS — triggers zoom-on-focus */
  line-height: 1.2;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  outline: none;
  transition: border-color 120ms ease-out, box-shadow 120ms ease-out;
}
.waitlist-form input[type="email"]::placeholder,
.waitlist-form input[type="text"]::placeholder {
  color: var(--stone);
}
.waitlist-form input[type="email"]:focus,
.waitlist-form input[type="text"]:focus {
  border-color: var(--sunset);
  box-shadow: 0 0 0 3px rgba(232, 93, 47, 0.18);
}
/* Name field sits on its own row above the email + button row.
   Inherits the pill/font/colour from the shared input rule above;
   only the layout differs — full-width, .5rem above the email row. */
.waitlist-form .waitlist-name-input {
  display: block;
  width: 100%;
  margin-bottom: .5rem;
  flex: none;                       /* override the shared `flex: 1 1 220px` */
}

/* When the form has a name input, stack the email + button vertically
   too so all three controls render as equal-width pills (name → email
   → button), each 520px (or full mobile width). Without this override
   the email pill looks visibly narrower than the name pill above it
   because the email row splits between input and button — the rhythm
   reads as a width mismatch. The :has() guard preserves the original
   inline email-plus-button layout on any other forms that don't carry
   a name field. */
.waitlist-form:has(.waitlist-name-input) .waitlist-row {
  flex-direction: column;
  align-items: stretch;
}
.waitlist-form:has(.waitlist-name-input) .waitlist-row input[type="email"] {
  flex: none;
  width: 100%;
}
.waitlist-form:has(.waitlist-name-input) .waitlist-row .btn-primary {
  width: 100%;
}

.btn-primary {
  /* Same appearance reset as the input — keeps button + input visually
     paired on iOS and ensures the pill border-radius isn't overridden. */
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  -webkit-tap-highlight-color: transparent;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 16px;
  color: #fff;
  background: var(--sunset);
  border: none;
  height: 48px;                     /* match input height for inline pairing */
  padding: 0 1.35rem;
  border-radius: 999px;
  cursor: pointer;
  text-decoration: none;            /* needed when used as <a> */
  transition: background 120ms ease-out, transform 120ms ease-out;
  letter-spacing: 0.01em;
}
.btn-primary:hover:not(:disabled)  { background: var(--russet); }
.btn-primary:active:not(:disabled) { transform: translateY(1px); }
.btn-primary:disabled              { opacity: .6; cursor: not-allowed; }

.form-status {
  min-height: 1.4em;
  margin-top: var(--s-s);
  font-size: .95rem;
  color: var(--stone);
  text-align: center;
}
.form-status.success { color: #1c7a4f; }
.form-status.error   { color: var(--russet); }

/* ------------ PILLARS BAND ------------ */
/* The "Seven practices, one practice" section. Lives between .peek and
   .programmes-preview as part of the Sandstone block in §8's rhythm.
   Was painted with a Sunset → Russet 135° gradient until 2026-04-27 —
   that's the gradient Brand v3.3 §2.3 reserves for Act 7 (Final CTA)
   only, and it caused the Mobility (Sunset) and Strength (Russet)
   per-pillar accent edges to vanish into the section background. Now
   transparent so it inherits the body Sandstone, with cards earning
   their separation via shadow rather than chroma. */
.pillars-band {
  background: transparent;
  padding: var(--s-xxl) var(--s-m);
}
.pillars-inner {
  max-width: var(--container);
  margin: 0 auto;
}
.pillars-title {
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  text-align: center;
  margin-bottom: var(--s-s);
}
.pillars-sub {
  font-size: 1.0625rem;
  color: var(--stone);
  text-align: center;
  margin: 0 auto var(--s-m);
  max-width: 50ch;
}
/* The "v1.0 ships at launch…" caption beneath .pillars-sub. Quiet
   meta-line that decodes the v-badges on each pillar card without
   competing with the section's "Seven practices, one practice."
   headline. Italic <em>vN.M</em> spans inherit ink colour by default
   for legibility (the .why-inner em rule that Inks Sandstone-cream
   italics is scoped to .why-inner, so it doesn't leak here). */
.pillars-note {
  font-size: 0.95rem;
  color: var(--stone);
  text-align: center;
  margin: 0 auto var(--s-xl);
  max-width: 60ch;
  font-style: italic;
}
.pillars-note em {
  color: var(--ink);
  font-style: italic;
  font-weight: bold;
}

.pillar-grid {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  /* All seven cards equal height — every row in the auto-flow gets
     the same track height as the tallest row (founder feedback
     2026-04-28: "make sure they're always the same boxes"). Without
     this, blurb-length differences between Mobility / Hypnosis /
     Sleep render visibly different card heights inside the same
     row. */
  grid-auto-rows: 1fr;
  gap: var(--s-m);
}

/* Orphan-centring rule for any 3-column grid on desktop. Founder
   direction 2026-04-28d: "where you've got three going across and
   then another line, those should be centred — should always be
   coherent, every time." Lock the grid at exactly 3 cols above
   880px so the orphan-position selector below is predictable
   (auto-fit can otherwise settle on 2 / 3 / 4 / 5 cols depending
   on viewport, which makes :nth-child(3n+1) unreliable). The
   :last-child:nth-child(3n+1) pair matches an item that is BOTH
   the last item AND positioned at col 1 of its row — i.e. alone
   in its row in a 3-col layout. Push it to col 2 so it lands under
   the centre column of the row above. Applies to both .pillar-grid
   (7 cards → 3+3+1, lone Sleep) and .programme-grid (4 cards →
   3+1, lone fourth programme). */
@media (min-width: 880px) {
  .pillar-grid,
  .programme-grid {
    grid-template-columns: repeat(3, 1fr);
  }
  .pillar-grid > :last-child:nth-child(3n+1),
  .programme-grid > :last-child:nth-child(3n+1) {
    grid-column: 2;
  }
}

.pillar-card {
  /* Section bg = body Sandstone (the .pillars-band section is
     transparent). Card bg flips to white so the card sits cleanly
     against the page. The 4px coloured border replaces the prior
     "one-edge stripe" pattern with a full surround that matches the
     relevant pillar — founder direction 2026-04-28.
     28g: cards are now anchors (<a class="pillar-card">) on the home
     pillars-band AND on /practices/ — full-card click target, hover
     lift matching .programme-card. Founder direction 2026-04-28g:
     "If I click the box mobility, it should be the same style with
     the same hover motion. And allow me to click, not just the
     text". Pillar-grid LIs are now empty wrappers around the anchor
     so equal-height stretching still works through the flex layer. */
  background: #fff;
  color: var(--ink);
  text-decoration: none;
  border: 4px solid var(--stone);   /* fallback; per-pillar colour set below */
  border-radius: 1rem;
  padding: var(--s-m);
  display: flex;
  flex-direction: column;
  gap: .6rem;
  position: relative;
  min-height: 180px;
  box-shadow: 0 1px 0 rgba(31, 36, 40, 0.06), 0 4px 16px rgba(0, 0, 0, 0.06);
  transition: transform 140ms ease-out, box-shadow 140ms ease-out;
}
.pillar-card:hover,
.pillar-card:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.10);
  color: var(--ink);
  text-decoration: none;
}
/* When pillar-card is an <a>, equal-height stretching needs the LI to
   participate as a flex container around it (same trick we use on
   .programme-grid > li). Both home + /practices/ index now use this. */
.pillar-grid > li {
  display: flex;
}
.pillar-grid > li > .pillar-card {
  flex: 1;
  width: 100%;
}
/* Inner anchor child (<h3>) — was an inline link inside the pillar
   name. Now the whole card is the link, so the h3 just renders text
   in Ink without any anchor-styling leak. */
.pillar-card .pillar-name a,
.pillar-card .pillar-name a:hover {
  color: inherit;
  text-decoration: none;
}
.pillar-card.pillar--mobility   { border-color: var(--sunset); }
.pillar-card.pillar--yoga       { border-color: var(--teal); }
.pillar-card.pillar--strength   { border-color: var(--russet); }
.pillar-card.pillar--breath     { border-color: var(--sky); }
.pillar-card.pillar--meditation { border-color: var(--lime); }
.pillar-card.pillar--sleep      { border-color: var(--marigold); }
.pillar-card.pillar--hypnosis   { border-color: var(--plum); }

/* 28n / 2026-04-29w — Pillar icons (Lucide MIT). Single SVG file
   per pillar in /assets/pillars/<slug>.svg, recoloured at render
   time via CSS mask-image so each card pulls in its pillar colour
   without needing inline SVG duplication. Source: PILLAR-ICONS.md
   handoff from Mac (2026-04-29 09:30). The seven Lucide icons are:
   stretch-horizontal (mobility), flower-2 (yoga), dumbbell
   (strength), wind (breath), leaf (meditation), moon-star (sleep),
   hexagon (hypnosis). Lucide ships at 24×24 viewBox with 2px
   stroke="currentColor" — the mask-image trick converts the
   stroke to a fill that picks up `background-color` from the
   parent's `color`, so each pillar card recolours its own icon
   via the per-pillar `--pillar-icon-url` + `color` pair below.
   Founder direction 2026-04-29: "for pillar icons I want to use
   the icons" + "I want to make sure that we're using the lucid
   ones there in the app because I don't want different app icons"
   — iOS will switch from SF Symbols to these same Lucide icons in
   a follow-up Mac round so iOS = web visual parity. */
.pillar-icon {
  display: block;
  width: 40px;
  height: 40px;
  margin: 0 0 var(--s-s);
  background-color: currentColor;
  -webkit-mask-image: var(--pillar-icon-url, none);
          mask-image: var(--pillar-icon-url, none);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-size: contain;
          mask-size: contain;
  -webkit-mask-position: center;
          mask-position: center;
}
.pillar-card.pillar--mobility   { --pillar-icon-url: url('/assets/pillars/mobility.svg?v=2026-04-29w'); }
.pillar-card.pillar--mobility   .pillar-icon { color: var(--sunset); }
.pillar-card.pillar--yoga       { --pillar-icon-url: url('/assets/pillars/yoga.svg?v=2026-04-29w'); }
.pillar-card.pillar--yoga       .pillar-icon { color: var(--teal); }
.pillar-card.pillar--strength   { --pillar-icon-url: url('/assets/pillars/strength.svg?v=2026-04-29w'); }
.pillar-card.pillar--strength   .pillar-icon { color: var(--russet); }
.pillar-card.pillar--breath     { --pillar-icon-url: url('/assets/pillars/breath.svg?v=2026-04-29w'); }
.pillar-card.pillar--breath     .pillar-icon { color: var(--sky); }
.pillar-card.pillar--meditation { --pillar-icon-url: url('/assets/pillars/meditation.svg?v=2026-04-29w'); }
.pillar-card.pillar--meditation .pillar-icon { color: var(--lime); }
.pillar-card.pillar--sleep      { --pillar-icon-url: url('/assets/pillars/sleep.svg?v=2026-04-29w'); }
.pillar-card.pillar--sleep      .pillar-icon { color: var(--marigold); }
.pillar-card.pillar--hypnosis   { --pillar-icon-url: url('/assets/pillars/hypnosis.svg?v=2026-04-29w'); }
.pillar-card.pillar--hypnosis   .pillar-icon { color: var(--plum); }

.pillar-badge {
  position: absolute;
  top: var(--s-m);
  right: var(--s-m);
  font-family: Arial, Helvetica, sans-serif;
  /* Was .7rem bold uppercase pill on a 6% Ink background — read as a
     UI control rather than a quiet meta-tag, which is why "the
     numbers for versions look too big" landed even though .7rem
     isn't large per se. Now a plain caption: smaller, medium weight,
     no background, no padding, no pill shape. Information without
     volume. */
  font-size: .65rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--stone);
}
.pillar-name {
  font-size: 1.5rem;
  margin-right: 4rem;   /* breathing room for the .pillar-badge caption */
}
.pillar-blurb {
  font-size: 0.95rem;
  color: var(--ink);
  max-width: none;
}

/* The .pillar--<name> classes are now wired to per-card border colour
   above (Sunset / Teal / Russet / Sky / Lime / Marigold / Plum). */

/* ------------ CONTACT ------------ */
.contact {
  max-width: var(--container);
  margin: 0 auto;
  padding: var(--s-xxl) var(--s-m) var(--s-xl);
  text-align: center;
}
.contact h2 {
  font-size: 1.5rem;
  margin-bottom: var(--s-s);
}
.contact-email {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 1.25rem;
  color: var(--sunset);
  text-decoration: none;
}
.contact-email:hover {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  color: var(--sunset);
}

/* ------------ LEGAL PAGES ------------ */
.legal {
  max-width: 720px;
  margin: 0 auto;
  padding: var(--s-xl) var(--s-m) var(--s-xxl);
}
.legal h1 {
  font-size: 2.25rem;
  margin-bottom: var(--s-xs);
}
.legal .updated {
  color: var(--stone);
  font-size: 0.9rem;
  margin-bottom: var(--s-l);
}
.legal h2 {
  font-size: 1.2rem;
  margin-top: var(--s-l);
  margin-bottom: var(--s-s);
  color: var(--sunset);
}
.legal p {
  margin-bottom: var(--s-m);
  max-width: 65ch;
}
.legal .note {
  margin-top: var(--s-xl);
  padding-top: var(--s-m);
  border-top: 1px solid var(--hairline);
  font-size: 0.9rem;
  color: var(--stone);
  font-style: italic;
}

/* ------------ FOOTER ------------
   Founder direction 2026-04-28: footer was "quite shit" — too quiet,
   too cream, no social. New treatment is Ink-on-Sandstone-page so the
   footer reads as the closing band of the site. Multi-column with
   brand block, site links, legal, and four social icons matching the
   /share page SVG pattern. No email — the address gets spammed and
   hello@sthira.me already lives on /privacy + /terms for GDPR reach.
   Per Creative Brief 1.5 §7: "Sthira Me Ltd · London, UK · Privacy ·
   Terms" ties out the legal footprint. */
.site-footer {
  background: var(--ink);
  color: var(--sandstone);
  padding: var(--s-xxl) var(--s-m) var(--s-l);
  width: 100%;
}
.site-footer-inner {
  max-width: var(--container);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: var(--s-xl) var(--s-l);
  align-items: start;
}
.footer-col {
  display: flex;
  flex-direction: column;
  gap: var(--s-s);
}
.footer-brand {
  display: inline-flex;
  align-items: center;
  gap: .65rem;
  text-decoration: none;
  color: var(--sandstone);
}
/* Footer lockup is the canonical SVG file (assets/lockup-on-ink.svg)
   — no manual span/dot construction. Founder direction 2026-04-28e:
   "the logo on the footer should just be the image file. You don't
   need to have a hover element to it. You've manually done that
   where you should have just used the SVG file." The on-ink variant
   has the Sandstone bg rect removed and the wordmark re-coloured
   from Ink to Sandstone so it reads on the charcoal footer. Sunset
   pebbles + dot are unchanged. Width auto + max-width keeps the
   wide 2:1 viewbox legible without dominating the column. */
.footer-lockup {
  height: 44px;
  width: auto;
  max-width: 100%;
  display: block;
}
.footer-tag {
  font-size: 0.95rem;
  color: var(--stone);
  font-style: italic;
  max-width: 28ch;
  margin: 0;
}
.footer-h {
  font-family: Arial, Helvetica, sans-serif;
  font-size: .72rem;
  font-weight: bold;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sandstone);
  margin: 0 0 var(--s-xs);
}
.footer-col ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}
/* Regular footer text links (Story / Programmes / Pricing / etc.).
   The :not(.footer-social) is critical: without it, .footer-social
   inherits this rule and `color: var(--sunset)` on hover wins on
   specificity over `.footer-social a:hover { color: #fff }` further
   down — leaving the social SVG icon Sunset-on-Sunset, which renders
   as the disappear-on-hover bug founder reported 2026-04-28d. */
.footer-col ul:not(.footer-social) a {
  color: var(--sandstone);
  text-decoration: none;
  font-size: 0.95rem;
  opacity: .82;
  transition: opacity 140ms ease-out, color 140ms ease-out;
}
.footer-col ul:not(.footer-social) a:hover,
.footer-col ul:not(.footer-social) a:focus-visible {
  opacity: 1;
  color: var(--sunset);
  text-decoration: underline;
}
.footer-social {
  display: flex !important;
  flex-direction: row !important;
  gap: .6rem;
  flex-wrap: wrap;
}
.footer-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(245, 239, 230, 0.06);
  color: var(--sandstone);
  text-decoration: none;
  opacity: 1;
  transition: background 140ms ease-out, color 140ms ease-out, transform 140ms ease-out;
}
.footer-social a:hover,
.footer-social a:focus-visible {
  /* White icon on Sunset disc — keeps the glyph fully legible against
     the warm hover background (founder feedback 2026-04-28: "it goes
     completely orange... the icon itself disappears, they should still
     remain"). Pre-fix: color: var(--ink) gave Ink-on-Sunset, which read
     as a low-contrast smudge at 18×18px. */
  background: var(--sunset);
  color: #fff;
  transform: translateY(-1px);
  text-decoration: none;
}
.footer-social-icon {
  width: 18px;
  height: 18px;
  display: block;
}
.site-footer-base {
  max-width: var(--container);
  margin: var(--s-xl) auto 0;
  padding-top: var(--s-m);
  border-top: 1px solid rgba(245, 239, 230, 0.12);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--s-s);
  font-size: 0.85rem;
  color: var(--stone);
}
.site-footer-base p {
  margin: 0;
}
@media (max-width: 880px) {
  .site-footer-inner {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 540px) {
  .site-footer-inner {
    grid-template-columns: 1fr;
    gap: var(--s-l);
  }
  .site-footer {
    padding: var(--s-xl) var(--s-s) var(--s-m);
  }
}

/* Legacy bare-<footer> selector retained for any not-yet-migrated
   page; the new pages use <footer class="site-footer"> + the grid
   above. Keep the old rules narrow so they don't bleed into the
   new structure. */
footer:not(.site-footer) {
  padding: var(--s-l) var(--s-m);
  max-width: var(--container);
  margin: 0 auto;
  width: 100%;
  border-top: 1px solid var(--hairline);
}
footer:not(.site-footer) nav {
  display: flex;
  gap: 1.5rem;
  margin-bottom: var(--s-s);
  flex-wrap: wrap;
}
footer:not(.site-footer) nav a {
  color: var(--ink);
  text-decoration: none;
  font-size: 0.9rem;
}
footer:not(.site-footer) nav a:hover {
  color: var(--sunset);
  text-decoration: underline;
}
footer:not(.site-footer) .copy {
  font-size: 0.85rem;
  color: var(--stone);
}

/* ------------ RESPONSIVE ------------ */
@media (max-width: 640px) {
  .site-header   { padding-block: var(--s-xs); padding-inline: var(--s-s); }
  .hero          { padding: var(--s-l) var(--s-s) var(--s-xl); }
  .pillars-band  { padding: var(--s-xl) var(--s-s); }
  .contact       { padding: var(--s-xl) var(--s-s) var(--s-l); }
  .legal         { padding: var(--s-l) var(--s-s) var(--s-xl); }
  footer:not(.site-footer) { padding: var(--s-m) var(--s-s); }
  .pebble-mark   { height: 48px; width: 48px; }
  .brand-wordmark { font-size: 1.15rem; }
  .waitlist-row  { flex-direction: column; }
  .waitlist-form input[type="email"],
  .waitlist-form .btn-primary { width: 100%; }
}

/* ============== PROBLEM (ACT 2) ==============
   Ink-on-Sandstone mood shift right after the hero. Empathy beat:
   four research stats framed as scale-of-pain, not mechanism. The
   Sandstone-to-Ink shift is the deliberate "going deeper" signal
   per Creative Brief 1.5 §6 Act 2. */
.problem {
  background: var(--ink);
  color: var(--sandstone);
  padding: var(--s-xxl) var(--s-m);
}
.problem-inner {
  max-width: var(--container);
  margin: 0 auto;
}
.problem-title {
  color: var(--sandstone);
  font-size: clamp(1.75rem, 4.5vw, 2.5rem);
  text-align: center;
  margin: 0 auto var(--s-l);
  letter-spacing: -0.005em;
  max-width: 22ch;
}
.problem-lead {
  font-size: 1.125rem;
  color: rgba(245, 239, 230, 0.92);
  text-align: center;
  margin: 0 auto var(--s-xl);
  max-width: 50ch;
  line-height: 1.6;
}
.problem-stats {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s-m);
  margin: 0 0 var(--s-xl);
  padding: 0;
}
.problem-stats li {
  border-left: 3px solid var(--sunset);
  padding: var(--s-s) var(--s-m);
  display: flex;
  flex-direction: column;
  gap: .35rem;
}
.problem-stat {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 2rem;
  color: var(--sunset);
  line-height: 1.1;
  margin: 0;
  max-width: none;
}
.problem-claim {
  font-size: 0.95rem;
  color: var(--sandstone);
  line-height: 1.55;
  margin: 0;
  max-width: none;
}
.problem-cite {
  font-size: 0.8rem;
  color: rgba(245, 239, 230, 0.55);
  font-style: italic;
  margin: 0;
  max-width: none;
}
.problem-tail {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  text-align: center;
  font-size: 1.125rem;
  color: var(--sunset);
  max-width: 38ch;
  margin: var(--s-l) auto 0;
}

/* ============== WHY SECTION ============== */
.why {
  max-width: var(--container);
  margin: 0 auto;
  padding: var(--s-xxl) var(--s-m);
}
.why-inner {
  max-width: 60ch;
  margin: 0 auto;
}
.why-title {
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  margin-bottom: var(--s-l);
  text-align: center;
  letter-spacing: -0.005em;
}
.why-inner p {
  font-size: 1.125rem;
  line-height: 1.65;
  margin: 0 auto var(--s-m);
  max-width: 58ch;
}
.why-inner em {
  /* The "sthira sukham asanam" Sanskrit phrase. Was Russet on Sandstone
     until 2026-04-27 — that's a warm-on-warm pairing that reads dim at
     body-text size (passes WCAG AA at ~5:1 but barely). Italic alone is
     enough emphasis here; let the typography do the work and keep the
     full Ink contrast for readability. */
  color: var(--ink);
  font-style: italic;
}

/* Devanagari display of the Yoga Sutra source phrase. Sat above the
   English why-paragraph from 2026-04-27 onward, per founder request to
   "show the origin story like the brand doc has." Renders via system
   Devanagari fonts on every modern OS (macOS / iOS / Android ship Noto
   Sans Devanagari preinstalled; Windows ships Nirmala UI). No web-font
   download — Brief §9 keeps fonts to system stacks for FCP <1.2s. The
   transliteration line below it stays in Georgia italic for continuity
   with .why-inner em. */
.sthira-script {
  font-family: 'Noto Serif Devanagari', 'Tiro Devanagari Sanskrit',
               'Sanskrit 2003', 'Mukti', 'Lohit Devanagari',
               'Nirmala UI', 'Kohinoor Devanagari',
               Georgia, "Times New Roman", serif;
  font-size: clamp(1.65rem, 4.4vw, 2.25rem);
  text-align: center;
  color: var(--ink);
  line-height: 1.4;
  margin: 0 auto var(--s-xs);
  letter-spacing: 0.02em;
  /* 28v: founder direction "the Sanskrit text should be more bolder" —
     bump from 400 (regular) to 700 (bold). Some Devanagari system
     fonts (Noto Serif Devanagari, Tiro Devanagari Sanskrit) carry a
     genuine bold weight; older ones (Lohit Devanagari) synth-bold.
     Either way the canonical Sutra phrase reads with more weight on
     the page, matching its anchor role at the top of /story.html. */
  font-weight: 700;
}
.sthira-script-translit {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 1rem;
  text-align: center;
  color: var(--stone);
  margin: 0 auto var(--s-l);
  letter-spacing: 0.04em;
}

/* ============== HOW IT WORKS ============== */
.how {
  background: #fff;
  padding: var(--s-xxl) var(--s-m);
}
.how-inner {
  max-width: var(--container);
  margin: 0 auto;
}
.how-title {
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  text-align: center;
  margin-bottom: var(--s-xl);
  letter-spacing: -0.005em;
}
/* Optional lead paragraph between .how-title and .how-steps. Used on
   /story.html "What ships, and when" to explain the v1.0 / v1.1 /
   v1.2 markers (founder feedback 2026-04-28: "write something that
   explains what that means"). Italic <em>vN.M</em> spans get Ink colour
   + bold so the version markers read as anchors inside the prose. */
.how-lead {
  text-align: center;
  font-size: 1rem;
  color: var(--stone);
  font-style: italic;
  margin: calc(0px - var(--s-l)) auto var(--s-xl);
  max-width: 56ch;
}
.how-lead em {
  color: var(--ink);
  font-style: italic;
  font-weight: bold;
}
.how-steps {
  /* Was display: grid with auto-fit columns. Switched to flex so
     incomplete trailing rows centre their orphans automatically — the
     share-page ladder (1, 3, 5, 10, 25) was rendering 3-across with
     "10" and "25" left-aligned in row 2 instead of centred together
     (founder direction 2026-04-28g: "if it's a 1 it needs to be in
     the middle, and if it's two they need to be centred"). Flex with
     justify-content: center handles 1-orphan AND 2-orphan cases at
     once — cleaner than grid + nth-child column-shift gymnastics.
     Affects: /share/ ladder (5 items → 3+2 centred), /story.html
     "Six things we believe" (6 items → 3+3 even), home /how/ (3
     items, single row), any future 5- or 8-item how-steps list. */
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-l);
}
.how-step {
  flex: 0 1 calc((100% - 2 * var(--s-l)) / 3);
  min-width: 240px;
  max-width: 34ch;
}
@media (max-width: 720px) {
  .how-step { flex-basis: 100%; }
}
.how-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.25rem;
  font-weight: bold;
  color: #fff;
  background: var(--sunset);
  border-radius: 50%;
  margin-bottom: var(--s-s);
}
/* Version-pill variant — for "What ships, and when" on /story.html
   where the step-num holds "V1.0" / "V1.1" / "V1.2" rather than a
   single digit. The 2.5rem circle was sized for 1-character glyphs;
   four characters overflowed visibly (founder feedback 2026-04-28).
   This variant widens to a pill, drops the font-size, and tightens
   the letter-spacing so the version reads cleanly inside the chip. */
.how-step-num--version {
  width: auto;
  min-width: 3.5rem;
  height: 2rem;
  padding: 0 .65rem;
  font-size: .85rem;
  letter-spacing: 0.02em;
  border-radius: 999px;
}
.how-step h3 {
  font-size: 1.25rem;
  margin-bottom: var(--s-xs);
}
.how-step p {
  font-size: 1rem;
  color: var(--ink);
  line-height: 1.55;
  max-width: none;
}

/* ============== PEEK (APP SCREENSHOT) ============== */
.peek {
  /* Warm Sunset-tinted backdrop. History:
       28b: Sandstone — phone read as one uniform block.
       28c: #ECF2F5 — "too pale, doesn't look like one of our colours".
       28d→28e: 0.18→0.10 Sky gradient — STILL too pale.
       28f: flat 0.32 Sky over Sandstone — founder rejected blue
            entirely 2026-04-28 ("where does that blue come from?
            it's not part of our branding, is it?"). Sky IS in the
            palette (Breath pillar) but reads as cold-and-foreign in
            this band; the whole rest of the page is warm (Sunset
            buttons, Russet accents, Sandstone body) so a cold-blue
            island broke the brand temperature.
       28g: switched to a flat Sunset wash over Sandstone — same
            primary brand colour as the hero CTA, the footer pebble
            and the contact-email accent, just at low alpha. Reads
            unambiguously "of the brand" without competing with the
            phone-screenshot's own Box-breath Sky card.
            Brand 3.3 §2.3 keeps Sky for in-app pillar accents only;
            chrome (web bands, footer, buttons) stays on the warm
            Sunset/Russet axis. */
  padding: var(--s-xxl) var(--s-m);
  background: linear-gradient(rgba(232, 93, 47, 0.16), rgba(232, 93, 47, 0.16)), var(--sandstone);
}
.peek-inner {
  max-width: var(--container);
  margin: 0 auto;
  text-align: center;
}
.peek-title {
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  margin: 0 auto var(--s-s);
  letter-spacing: -0.005em;
  max-width: 24ch;
}
.peek-sub {
  font-size: 1.0625rem;
  color: var(--stone);
  margin: 0 auto var(--s-xl);
  max-width: 44ch;
}
.phone-frame {
  margin: 0 auto;
  max-width: 320px;
  padding: 14px 12px;
  background: var(--ink);
  border-radius: 48px;
  box-shadow:
    0 32px 64px -20px rgba(31, 36, 40, 0.35),
    0 10px 24px -8px rgba(232, 93, 47, 0.18);
}
.phone-screenshot {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 34px;
}

/* ============== PROGRAMMES PREVIEW ============== */
.programmes-preview {
  padding: var(--s-xxl) var(--s-m);
  background: #fff;
}
.programmes-inner {
  max-width: var(--container);
  margin: 0 auto;
}
.programmes-title {
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  text-align: center;
  margin: 0 auto var(--s-s);
  letter-spacing: -0.005em;
  max-width: 26ch;
}
.programmes-sub {
  font-size: 1.0625rem;
  color: var(--stone);
  text-align: center;
  margin: 0 auto var(--s-xl);
  max-width: 46ch;
}
.programme-grid {
  list-style: none;
  display: grid;
  /* Mobile: 1-column. Tablet+: 2×2 grid (founder direction 2026-04-28g:
     "the four starter programmes doing by 2 by 2. The 3 in 1 doesn't
     look that good"). Desktop tablet breakpoint at 720px. */
  grid-template-columns: 1fr;
  gap: var(--s-m);
  /* Equal-height tracks. Each <li> stretches to the tallest sibling
     (grid default). To make the inner anchor card actually inherit
     that height — instead of collapsing to its own content — we
     turn the <li> into a flex container so the .programme-card
     can flex: 1 to fill its parent. Without this rule the four
     cards rendered visibly different heights when the per-card
     copy length differed (founder feedback 2026-04-28). */
  align-items: stretch;
}
.programme-grid > li {
  display: flex;
}
.programme-grid > li > .programme-card {
  flex: 1;
}
@media (min-width: 720px) {
  .programme-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.programme-card {
  /* Section bg = white (.programmes-preview). Card bg = Sandstone
     so it sits distinct from the page. 4px coloured border in the
     relevant pillar colour replaces the prior "one-edge stripe"
     pattern — founder direction 2026-04-28. */
  background: var(--sandstone);
  border: 4px solid var(--stone);   /* fallback; per-pillar colour set below */
  padding: var(--s-m);
  border-radius: 1rem;
  display: flex;
  flex-direction: column;
  gap: .55rem;
  box-shadow: 0 1px 0 rgba(31, 36, 40, 0.06), 0 4px 16px rgba(0, 0, 0, 0.06);
  text-decoration: none;
  color: var(--ink);
  transition: transform 140ms ease-out, box-shadow 140ms ease-out;
}
.programme-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(0,0,0,0.10);
  color: var(--ink);
}
/* Per-pillar border colours. Programme → pillar map:
     Desk Reset Breathing  → Breath  (Sky)
     Desk Reset Mobility   → Mobility (Sunset)
     Wind Down             → Sleep   (Marigold)
     Runner's Reset        → Strength (Russet)
   Apply via .programme-card.pillar--<name> in the markup. */
.programme-card.pillar--mobility   { border-color: var(--sunset); }
.programme-card.pillar--yoga       { border-color: var(--teal); }
.programme-card.pillar--strength   { border-color: var(--russet); }
.programme-card.pillar--breath     { border-color: var(--sky); }
.programme-card.pillar--meditation { border-color: var(--lime); }
.programme-card.pillar--sleep      { border-color: var(--marigold); }
.programme-card.pillar--hypnosis   { border-color: var(--plum); }
.programme-tag {
  font-family: Arial, Helvetica, sans-serif;
  font-size: .7rem;
  font-weight: bold;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--stone);
}
.programme-card h3 {
  font-size: 1.2rem;
  line-height: 1.25;
}
.programme-stat {
  font-size: 0.95rem;
  color: var(--ink);
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  max-width: none;
}
.programme-why {
  font-size: 0.95rem;
  color: var(--ink);
  max-width: none;
}
.programme-card .arrow {
  align-self: flex-start;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.85rem;
  color: var(--sunset);
  margin-top: auto;
  padding-top: var(--s-xs);
  text-decoration: underline;
}

/* ============== EVIDENCE ============== */
.evidence {
  padding: var(--s-xxl) var(--s-m);
  background: var(--sandstone);
}
.evidence-inner {
  max-width: var(--container);
  margin: 0 auto;
}
.evidence-title {
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  text-align: center;
  margin: 0 auto var(--s-s);
  letter-spacing: -0.005em;
  max-width: 26ch;
}
.evidence-sub {
  font-size: 1.0625rem;
  color: var(--stone);
  text-align: center;
  margin: 0 auto var(--s-xl);
  max-width: 46ch;
}
.evidence-grid {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s-m);
}
.evidence-card {
  /* Section bg = Sandstone (.evidence). Card bg = white so it sits
     distinct. 4px coloured border all around — the four cards cycle
     Sunset / Teal / Sky / Russet to mirror the four V1.0 movement
     pillars. Founder direction 2026-04-28: replace prior border-left
     stripe with a full surround. */
  background: #fff;
  padding: var(--s-m);
  border-radius: 1rem;
  border: 4px solid var(--sunset);
}
.evidence-card:nth-child(2) { border-color: var(--teal); }
.evidence-card:nth-child(3) { border-color: var(--sky); }
.evidence-card:nth-child(4) { border-color: var(--russet); }
.evidence-stat {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 1.75rem;
  color: var(--sunset);
  margin: 0 0 var(--s-xs);
  line-height: 1.1;
  max-width: none;
}
.evidence-card:nth-child(2) .evidence-stat { color: var(--teal); }
.evidence-card:nth-child(3) .evidence-stat { color: var(--sky); }
.evidence-card:nth-child(4) .evidence-stat { color: var(--russet); }
.evidence-claim {
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--ink);
  max-width: none;
  margin: 0;
}
.evidence-cite {
  font-size: 0.8rem;
  color: var(--stone);
  margin-top: var(--s-xs);
  max-width: none;
}

/* ============== FOUNDER ============== */
.founder {
  padding: var(--s-xxl) var(--s-m);
  background: #fff;
}
.founder-inner {
  max-width: 58ch;
  margin: 0 auto;
}
.founder-title {
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  text-align: center;
  margin: 0 auto var(--s-l);
  letter-spacing: -0.005em;
}
.founder-inner p {
  font-size: 1.125rem;
  line-height: 1.65;
  margin: 0 auto var(--s-m);
  max-width: 56ch;
}
.founder-sig {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  color: var(--russet);
  font-size: 1rem;
  margin-top: var(--s-l);
}

/* ============== CTA TAIL ============== */
.cta-tail {
  background: linear-gradient(135deg, var(--sunset) 0%, var(--russet) 100%);
  padding: var(--s-xxl) var(--s-m);
  color: #fff;
  text-align: center;
}
.cta-tail-inner {
  max-width: var(--container);
  margin: 0 auto;
}
.cta-tail h2 {
  color: #fff;
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  margin: 0 auto var(--s-s);
  max-width: 24ch;
}
.cta-tail p {
  color: rgba(255,255,255,0.92);
  font-size: 1.0625rem;
  margin: 0 auto var(--s-m);
  max-width: 48ch;
}
.cta-tail .btn-primary {
  /* Just override colours + spacing — base .btn-primary already
     supplies the inline-flex layout, 48px height, font-size etc.
     so the pill matches the hero form button perfectly. */
  background: #fff;
  color: var(--sunset);
  margin-top: var(--s-xs);
  margin-bottom: var(--s-m);
  transition: background 120ms ease-out, color 120ms ease-out, transform 120ms ease-out;
}
.cta-tail .btn-primary:hover {
  background: var(--sandstone);
  color: var(--russet);
}
.cta-tail .btn-primary:active {
  transform: translateY(1px);
}
.cta-tail .whisper {
  color: rgba(255,255,255,0.72);
  font-size: 0.9rem;
  margin-top: var(--s-m);
}

/* M-156-followup-AE first-1,000 founder-cap canonical scarcity device.
   Footnote-weight paragraph below the main CTA paragraph naming the cap
   alongside the existing deadline. Slightly de-emphasised vs body so it
   reads as a clarifying clause, not a lead claim. Inherits white-on-
   gradient base from .cta-tail p; reduces font-size + opacity + adds a
   touch of letter-spacing to settle it as supportive copy. */
.cta-tail .cta-cap-note {
  color: rgba(255,255,255,0.78);
  font-size: 0.875rem;
  font-style: italic;
  margin-top: calc(-1 * var(--s-s));
  margin-bottom: var(--s-m);
  max-width: 52ch;
  line-height: 1.5;
}
/* 28x.16 — canonical 5-tier value stack inside .cta-tail. Lives on
   the Sunset→Russet gradient bg with white text; tier-step pills are
   semi-transparent white; the 5-share anchor row inverts to white-bg
   + Russet-text so the £59.99 reward visually anchors. Per Style
   Guide v1.0 §1 (no single-side accent borders) + brand-consistency
   sweep doc (irresistible value stack, calm voice). */
.cta-tail .cta-lede {
  color: rgba(255,255,255,0.95);
  font-size: 1.0625rem;
  font-weight: 600;
  margin: 0 auto var(--s-s);
  max-width: 48ch;
}
.cta-tail .cta-gratitude {
  color: rgba(255,255,255,0.85);
  font-size: 0.95rem;
  font-style: italic;
  font-weight: 400;
  margin: 0 auto var(--s-m);
  max-width: 48ch;
}
.cta-tail .cta-ladder {
  list-style: none;
  padding: 0;
  margin: 0 auto var(--s-l);
  max-width: 56ch;
  text-align: left;
  display: grid;
  gap: 0.6rem;
}
.cta-tail .cta-ladder li {
  color: rgba(255,255,255,0.95);
  font-size: 0.95rem;
  line-height: 1.55;
  padding: 0.4rem 0.65rem;
  border: 1.5px solid rgba(255,255,255,0.20);
  border-radius: 12px;
  background: rgba(255,255,255,0.04);
}
.cta-tail .cta-step {
  display: inline-block;
  min-width: 6.25rem;
  padding: 0.15rem 0.55rem;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.95);
  background: rgba(255,255,255,0.14);
  border: 1px solid rgba(255,255,255,0.30);
  border-radius: 999px;
  text-align: center;
  margin-right: 0.6rem;
  vertical-align: 1px;
}
/* Anchor tier (5 shares — £59.99 lock) inverts so the row visually
   leads. Whole row gains a stronger background; pill goes solid
   white with Russet text; reward text in white-strong. */
.cta-tail .cta-ladder li:has(.cta-step--anchor) {
  background: rgba(255,255,255,0.10);
  border-color: rgba(255,255,255,0.45);
}
.cta-tail .cta-step--anchor {
  background: #fff;
  color: var(--russet);
  border-color: #fff;
}
.cta-tail .cta-ladder li strong {
  color: #fff;
  font-weight: 700;
}

/* ============== NAV LINKS IN HEADER ============== */
.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.site-nav {
  display: flex;
  gap: var(--s-m);
  align-items: center;
}
.site-nav a {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.95rem;
  color: var(--ink);
  text-decoration: none;
  padding: .5rem .75rem;
  /* 28o.1 hotfix 2026-04-29: removed border-radius: 999px (pill clip)
     and the hover background rgba(31,36,40,0.05). On iOS Safari the
     combination rendered as faint round/oval halos behind every nav
     link in the mobile dropdown panel — founder direction
     2026-04-29: "on my iPhone I see these weird round buttons. I
     don't want any of that". Replaced with a flat colour-only
     hover/focus state. -webkit-tap-highlight-color: transparent
     also kills the iOS tap-flash overlay. */
  -webkit-tap-highlight-color: transparent;
  transition: color 120ms ease-out;
}
.site-nav a:hover,
.site-nav a:focus-visible {
  color: var(--sunset);
  outline: none;
}
/* Current page — Sunset colour + weight so the active link reads as
   "you are here". No background, no pill, just colour + weight. */
.site-nav a[aria-current="page"] {
  color: var(--sunset);
  font-weight: bold;
}

/* ============== RESPONSIVE (additions) ============== */
@media (max-width: 640px) {
  .why, .how, .peek, .programmes-preview, .evidence, .founder, .cta-tail, .problem {
    padding: var(--s-xl) var(--s-s);
  }
  .problem-stat {
    font-size: 1.75rem;
  }
  .phone-frame {
    max-width: 280px;
    padding: 10px 8px;
    border-radius: 40px;
  }
  .phone-screenshot {
    border-radius: 30px;
  }
  .evidence-stat {
    font-size: 1.5rem;
  }
  .site-nav {
    gap: var(--s-xs);
  }
  .site-nav a {
    font-size: 0.85rem;
    padding: .4rem .55rem;
  }
}

/* ============== COOKIE BANNER (consent) ==============
   Bottom-fixed banner. Ink @95% / Sandstone text / two equal pill
   buttons (Sunset accept, transparent essentials). Spec: Analytics
   Tracking Strategy 1.3 §8.1. No dark patterns — both buttons same
   size, same prominence. Banner dismisses to whichever choice the
   user clicks; preference saved in localStorage. */
.cookie-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(31, 36, 40, 0.95);
  color: var(--sandstone);
  padding: var(--s-m);
  z-index: 1000;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--s-m);
  font-size: 0.95rem;
  line-height: 1.5;
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.18);
}
.cookie-banner-copy {
  margin: 0;
  max-width: 56ch;
  color: var(--sandstone);
}
.cookie-banner-copy a {
  color: var(--sunset);
  text-decoration: underline;
}
.cookie-banner-copy a:hover {
  color: #fff;
}
.cookie-banner-actions {
  display: flex;
  gap: var(--s-s);
  flex-wrap: wrap;
}
.btn-cookie {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  -webkit-tap-highlight-color: transparent;
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 0.95rem;
  border: 1px solid var(--sandstone);
  height: 40px;
  padding: 0 1.25rem;
  border-radius: 999px;
  cursor: pointer;
  transition: background 120ms ease-out, color 120ms ease-out;
  white-space: nowrap;
}
.btn-cookie--essentials {
  background: transparent;
  color: var(--sandstone);
}
.btn-cookie--essentials:hover {
  background: var(--sandstone);
  color: var(--ink);
}
.btn-cookie--accept {
  background: var(--sunset);
  color: #fff;
  border-color: var(--sunset);
}
.btn-cookie--accept:hover {
  background: var(--russet);
  border-color: var(--russet);
}
@media (max-width: 640px) {
  .cookie-banner {
    flex-direction: column;
    text-align: center;
    padding: var(--s-s);
    font-size: 0.9rem;
  }
  .cookie-banner-actions {
    width: 100%;
    justify-content: center;
  }
  .btn-cookie {
    flex: 1 1 0;
  }
}

/* ============== FOOTER SOCIAL — 4×2 GRID (28g) ==============
   Founder direction 2026-04-28g: footer social row was 4 icons in
   a single line, "everything being the light colour white, then the
   light colour white", monotone Sandstone-on-Ink. Asks were:
     - add TikTok, Threads, Pinterest, YouTube — 8 platforms total
     - lay them out 4 across in row 1 + 4 across in row 2
     - more colour variation in the footer overall
   Solution: switch the .footer-social ul from flex-wrap to an
   explicit 4-column grid so the visual rhythm is intentional (not
   "however many fit"). On hover, each platform-disc tints to the
   platform's own brand colour for instant recognition. The Sunset
   uniform-hover from 28e was readable but flat; the per-platform
   colour is more lively without breaking the calm of the rest of
   the footer (icons sit small, hover is the only chromatic moment). */
.footer-social {
  display: grid !important;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: .5rem;
  flex-wrap: unset;
  max-width: 220px;
}
.footer-social li {
  display: flex;
  justify-content: center;
}
/* Per-platform hover tinting. Each anchor gets a data-platform=""
   attribute; the rule below resolves to the platform's own brand
   colour. Falls back to the Sunset uniform hover if the data-attr
   is missing. Order matches the markup: Instagram, X, LinkedIn,
   Facebook (row 1) — TikTok, Threads, Pinterest, YouTube (row 2). */
.footer-social a[data-platform="instagram"]:hover,
.footer-social a[data-platform="instagram"]:focus-visible {
  background: linear-gradient(135deg, #f09433, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888);
  color: #fff;
}
.footer-social a[data-platform="x"]:hover,
.footer-social a[data-platform="x"]:focus-visible {
  background: #000; color: #fff;
}
.footer-social a[data-platform="linkedin"]:hover,
.footer-social a[data-platform="linkedin"]:focus-visible {
  background: #0a66c2; color: #fff;
}
.footer-social a[data-platform="facebook"]:hover,
.footer-social a[data-platform="facebook"]:focus-visible {
  background: #1877f2; color: #fff;
}
.footer-social a[data-platform="tiktok"]:hover,
.footer-social a[data-platform="tiktok"]:focus-visible {
  background: #010101; color: #fff;
}
.footer-social a[data-platform="threads"]:hover,
.footer-social a[data-platform="threads"]:focus-visible {
  background: #101010; color: #fff;
}
.footer-social a[data-platform="pinterest"]:hover,
.footer-social a[data-platform="pinterest"]:focus-visible {
  background: #e60023; color: #fff;
}
.footer-social a[data-platform="youtube"]:hover,
.footer-social a[data-platform="youtube"]:focus-visible {
  background: #ff0033; color: #fff;
}

/* Footer column heading (.footer-h) tints to Sunset for a quiet
   chromatic accent against the Sandstone columns — breaks the
   "everything light cream" monotony per founder feedback 28g
   without shouting. Just the small all-caps headers; body links
   stay Sandstone. */
.footer-h {
  color: var(--sunset);
}

/* ============== PRACTICE PAGES (body.practice — 28g) ==============
   Founder direction 2026-04-28g: practice sub-pages had "this
   orange and white banding ... no excitement about it ... text
   left, justified centre, justified, it just looks boring. It's
   not great. We need some icons, some imagery or something". The
   alternating .why (Sandstone) / .how (white) sections from the
   homepage shipped as-is on the practice pages, but on those pages
   each section is just a heading + 1-2 paragraphs of dense prose,
   so the rhythm read as monotone bands instead of contrasting
   beats.

   Fix: scope a body.practice modifier that
     (a) drops a large pillar-coloured pebble above the h1 in the
         hero — the visual anchor the page was missing
     (b) places a small pillar-coloured pebble glyph before each
         section h2 so the eye can scan vertically
     (c) centres section bodies (heading + paragraph) so the
         alignment varies from the homepage's left-aligned how-step
         columns
     (d) equalises paragraph type sizes across .why and .how so the
         font doesn't visibly shift when the bg colour does
     (e) tightens the inner column to a consistent 56ch on both
         band types so the rhythm is even, not jarring

   The pillar colour comes from a CSS custom property --pillar-accent
   set inline on the body element of each sub-page (e.g.
   <body class="practice" style="--pillar-accent: var(--sunset);">). */
body.practice .why-inner,
body.practice .how-inner {
  max-width: 56ch;
  margin: 0 auto;
  text-align: center;
}
body.practice .why-inner p,
body.practice .how-inner p {
  font-size: 1.0625rem;
  line-height: 1.7;
  margin: 0 auto var(--s-m);
  max-width: 56ch;
  text-align: left; /* paragraphs read left-aligned within the centred column */
}
body.practice .why-title,
body.practice .how-title {
  text-align: center;
  font-size: clamp(1.5rem, 3.5vw, 2rem);
  margin-bottom: var(--s-m);
}
/* ============== 28i — Practice sub-page anatomy ===========================
   Founder direction 2026-04-28i (verbatim): *"the practises folder, you
   need to have bands of the background colour in different variants. So
   what I was saying is don't have the light orange and then white and
   then light orange and then white. see how the homepage has different
   colours and different variants? That's what we want, and look that
   into your style guide and I think what you need to think about also is
   how you can bring some vibrancy to those, to those pages. Because all
   you've got is, blocks of text in different bands. So we need some
   other ways in which we can look at making the text more vibrant, more
   attractive to read. You know, you've got like other styles such as
   putting in boxes, blocks of text, sections or icons or something. They
   just look flat."*

   What was wrong (28g/28h): practice sub-pages were 5 alternating .why
   /.how prose blocks. The 28g pebble glyphs read as "green dots". The
   28h flat-Sandstone unification removed the bands entirely and went
   too far the other way (founder: "completely cooked that one up on
   the Mobility 1"). Both rounds undershot the actual ask: bring the
   homepage's structural variety to the practice pages.

   What 28i ships: six distinct section types per practice page, each
   with its own background colour AND its own visual content type
   (callout, stat grid, icon-card grid, evidence cards) — mirroring the
   homepage's 10-section variety in miniature.

   Section-type / band-colour map (locked in style guide v1.1 §9):

     1. .practice-hero        → Sandstone (--sandstone)            prose
     2. .practice-define      → Pillar wash 8% over Sandstone      prose + callout
     3. .practice-rationale   → Stone (#ebe2d2)                    prose + stat grid
     4. .practice-suits       → White (#fff)                       4-card audience grid
     5. .practice-evidence    → Pillar wash 12% over Sandstone     evidence cards
     6. .cta-tail             → Ink (existing site primitive)      CTA

   The pillar-coloured washes use color-mix() over Sandstone so the
   pillar identity reads on every practice page (Sunset on Mobility,
   Teal on Yoga, etc.) without ever going saturated enough to compete
   with the actual cards on the page.
   ========================================================================= */

/* --- 1. HERO ------------------------------------------------------- */
/* HERO band — REVERSED 28v (2026-04-29 evening) from the 28p
   charcoal direction back to solid pillar colour at full strength,
   per founder direction (same day, evening): "if I click on Mobility
   under Practises, that's orange. Why is the header in this charcoal".
   Founder explicitly approved the reversal: "yes, to reverse whatever
   I said earlier, and make sure it's written in" + "make sure you
   write that strictly into the style guides".

   The canonical rule (now captured in conventions-since-style-guide-
   1.3.md §6 + flagged for v1.4): every practice subpage hero band
   IS its pillar colour at full saturation, edge-to-edge. The pillar
   and the colour are linked in one beat — Mobility = Sunset, Yoga
   = Teal, etc. White text on the darker pillars (Russet, Plum) and
   the warm pillars (Sunset, Marigold, Lime) for AA contrast — see
   contrast overrides below. Sky + Teal keep Ink text. */
.practice-hero {
  background: var(--pillar-accent, var(--sunset));
  padding: var(--s-xxl) var(--s-m) var(--s-xl);
  color: var(--ink);
}
.practice-hero h1 { color: inherit; }
.practice-hero p { color: inherit; }
/* Asymmetric 2-col hero — text-left + Lottie-right at desktop, stacked
   on mobile. The .practice-hero-text column carries the eyebrow + h1 +
   intro prose flush-left (founder direction 2026-04-28: hero copy was
   centred in 28i, must read left). The .practice-hero-media column
   carries a per-pillar Lottie animation, replacing the photo treatment
   we never shipped. Inspired by the variant block layout we saw on the
   Mediclick yoga reference — not copied, just used as a touchstone for
   how to make the page feel less monolithic. */
.practice-hero-inner {
  max-width: var(--container);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-l);
  align-items: center;
}
@media (min-width: 880px) {
  .practice-hero-inner {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    gap: var(--s-xl);
  }
}
.practice-hero-text {
  text-align: left;
  max-width: 56ch;
}
.practice-hero h1 {
  font-size: clamp(1.75rem, 4.5vw, 2.5rem);
  margin-bottom: var(--s-m);
  text-align: left;
}
.practice-hero p {
  font-size: 1.0625rem;
  line-height: 1.7;
  text-align: left;
}
.practice-hero .eyebrow {
  /* 28v REVERSAL: hero is back to solid pillar colour, so the eyebrow
     should read in the contrasting body-text colour (Ink on light
     pillars, white on dark pillars — see overrides below). The
     28p direction (eyebrow in pillar-accent on charcoal hero) is
     reverted. */
  text-align: left;
  margin-bottom: var(--s-xs);
  color: inherit;
}
.practice-hero-media {
  display: flex;
  align-items: center;
  justify-content: center;
}
.practice-lottie {
  width: 100%;
  max-width: 420px;
  aspect-ratio: 1 / 1;
}
.practice-lottie svg { display: block; width: 100% !important; height: 100% !important; }

/* 28v REVERSAL — restored per-pillar contrast overrides because the
   hero is back to solid pillar colour. Russet (#B5583F), Plum
   (#6E3E6B), Sunset (#E85D2F), Marigold (#F59E0B), and Lime
   (#A8C26B) all need WHITE text for AA contrast at body size — Ink
   on those colours fails or borders fail. Sky (#4EA6C6) and Teal
   (#14B8A6) keep Ink (lighter pillars, Ink reads cleanly). The body
   inline-style attribute selector keeps each rule self-contained
   without per-page class changes. */
body.practice[style*="russet"] .practice-hero,
body.practice[style*="plum"] .practice-hero,
body.practice[style*="sunset"] .practice-hero,
body.practice[style*="marigold"] .practice-hero,
body.practice[style*="lime"] .practice-hero {
  color: #fff;
}

/* --- 2. DEFINE (what it is) --------------------------------------- */
/* DEFINE band drops back to plain Sandstone — a breather between the
   pillar-tinted hero above and the warm-beige rationale below. */
.practice-define {
  background: var(--sandstone);
  padding: var(--s-xxl) var(--s-m);
}
.practice-define-inner {
  max-width: 64ch;
  margin: 0 auto;
}
.practice-define h2 {
  text-align: center;
  font-size: clamp(1.5rem, 3.5vw, 2rem);
  margin-bottom: var(--s-m);
}
.practice-define p {
  font-size: 1.0625rem;
  line-height: 1.7;
  margin-bottom: var(--s-m);
}
/* Pull-quote callout — sits inside .practice-define as a vibrancy
   anchor. White card with a thick pillar left-bar, italic quote in
   the middle, attribution beneath. Borrows the family resemblance of
   .pillar-card / .programme-card (full-bound card discipline §1) but
   tilts it from a navigational tile to an editorial callout via the
   left-bar emphasis + italic copy. */
.practice-callout {
  /* Card discipline §1: full 4-side 4px coloured border around white
     card. 28i shipped a left-bar-only stripe; 28j restores the full
     surround per founder direction 2026-04-28 ("you've done no border,
     or a single border on the left"). */
  background: #fff;
  border-radius: 1rem;
  border: 4px solid var(--pillar-accent, var(--sunset));
  padding: var(--s-l) var(--s-l);
  margin: var(--s-l) auto 0;
  max-width: 56ch;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
}
.practice-callout p {
  font-style: italic;
  font-size: 1.125rem;
  line-height: 1.6;
  margin: 0 0 var(--s-s);
  text-align: left;
}
.practice-callout .practice-callout-attr {
  font-style: normal;
  font-size: .875rem;
  color: var(--stone);
  margin: 0;
}

/* --- 3. RATIONALE (why this practice + stat grid) ----------------- */
/* "Warm beige" = Sandstone darkened 6% with Ink. Renders ~#E8E2DA, a
   half-step darker than Sandstone so it reads as a distinct band
   without breaking brand temperature. NOT --stone (that token is a
   medium grey reserved for muted text colours, not backgrounds). */
.practice-rationale {
  background: color-mix(in srgb, var(--ink) 6%, var(--sandstone));
  padding: var(--s-xxl) var(--s-m);
}
.practice-rationale-inner {
  max-width: var(--container);
  margin: 0 auto;
}
.practice-rationale h2 {
  text-align: center;
  font-size: clamp(1.5rem, 3.5vw, 2rem);
  margin-bottom: var(--s-m);
}
.practice-rationale > .practice-rationale-inner > p {
  max-width: 56ch;
  margin: 0 auto var(--s-l);
  font-size: 1.0625rem;
  line-height: 1.7;
}
/* Stat grid — borrows the homepage .problem-stats / .evidence-grid
   pattern. Three callout cards across at desktop, stacking on mobile.
   Big stat number in pillar colour, claim, optional cite. */
.practice-stats {
  list-style: none;
  margin: var(--s-l) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-m);
}
@media (min-width: 720px) {
  .practice-stats {
    grid-template-columns: repeat(3, 1fr);
  }
}
.practice-stat-card {
  /* Card discipline §1: full 4-side 4px coloured border. The stat
     number takes Georgia bold to match the homepage .evidence-stat
     family — gives every stat-card the same editorial weight as the
     homepage cards, which the founder called out as "the styling was a
     bit better on those boxes". */
  background: #fff;
  border-radius: 1rem;
  padding: var(--s-l) var(--s-m);
  text-align: center;
  border: 4px solid var(--pillar-accent, var(--sunset));
}
.practice-stat-card .practice-stat {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: clamp(1.75rem, 3.5vw, 2.25rem);
  /* 28w (2026-04-29 evening): heading-inside-card flipped to Ink.
     Founder direction: "the text that's the header inside each one
     that should be in the black". §6.3 universal card-discipline
     rule applied — border = pillar, text = Ink. */
  color: var(--ink);
  margin: 0 0 var(--s-xs);
  line-height: 1.1;
}
.practice-stat-card .practice-stat-claim {
  font-size: 1rem;
  line-height: 1.55;
  margin: 0 0 var(--s-xs);
}
.practice-stat-card .practice-stat-cite {
  font-size: .8125rem;
  color: var(--stone);
  margin: 0;
}

/* --- 4. SUITS (who it suits + audience cards) --------------------- */
.practice-suits {
  background: #fff;
  padding: var(--s-xxl) var(--s-m);
}
.practice-suits-inner {
  max-width: var(--container);
  margin: 0 auto;
}
.practice-suits h2 {
  text-align: center;
  font-size: clamp(1.5rem, 3.5vw, 2rem);
  margin-bottom: var(--s-m);
}
.practice-suits > .practice-suits-inner > p {
  max-width: 56ch;
  margin: 0 auto var(--s-l);
  font-size: 1.0625rem;
  line-height: 1.7;
  text-align: center;
}
.practice-audience {
  list-style: none;
  margin: var(--s-l) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-m);
}
@media (min-width: 560px) {
  .practice-audience {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 880px) {
  .practice-audience {
    grid-template-columns: repeat(4, 1fr);
  }
}
.practice-audience-card {
  /* Card discipline §1: full 4-side 4px coloured border, white card on
     the white .practice-suits band. Title takes Georgia bold to give
     it editorial weight (founder direction 2026-04-28: "those boxes
     that you did before were better, the styling was a bit better on
     those boxes, he needed to use a Georgia font"). */
  background: #fff;
  border-radius: 1rem;
  padding: var(--s-l) var(--s-m);
  text-align: center;
  border: 4px solid var(--pillar-accent, var(--sunset));
}
.practice-audience-card h3 {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 1.0625rem;
  margin: 0 0 var(--s-xs);
  /* 28w (2026-04-29 evening): heading-inside-card flipped to Ink.
     §6.3 universal card-discipline rule. */
  color: var(--ink);
  line-height: 1.25;
}
.practice-audience-card p {
  font-size: .9375rem;
  line-height: 1.55;
  margin: 0;
  color: var(--stone);
}

/* --- 5. EVIDENCE (research-backed) -------------------------------- */
/* EVIDENCE band echoes the pillar colour again, lighter than the hero
   (8% vs 14%), so the page feels bookended by colour without
   repeating the same intensity. */
.practice-evidence {
  background: color-mix(in srgb, var(--pillar-accent, var(--sunset)) 8%, var(--sandstone));
  padding: var(--s-xxl) var(--s-m);
}
.practice-evidence-inner {
  max-width: var(--container);
  margin: 0 auto;
}
.practice-evidence h2 {
  text-align: center;
  font-size: clamp(1.5rem, 3.5vw, 2rem);
  margin-bottom: var(--s-m);
}
.practice-evidence > .practice-evidence-inner > p {
  max-width: 56ch;
  margin: 0 auto var(--s-l);
  font-size: 1.0625rem;
  line-height: 1.7;
  text-align: center;
}
/* Evidence card grid — auto-fit minimum 280px so 2-col at most
   desktops, stacking on narrower viewports. Mirrors the homepage
   .evidence-grid pattern but on the pillar-tinted band so it doesn't
   feel like a homepage clone. */
.practice-evidence-grid {
  list-style: none;
  margin: var(--s-l) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-m);
}
@media (min-width: 720px) {
  .practice-evidence-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
.practice-evidence-card {
  /* Card discipline §1: matches homepage .evidence-card — white card,
     full 4-side 4px coloured border around the card, Georgia-bold
     title in pillar colour. Founder direction 2026-04-28: "those
     boxes that you did before were better … he needed to use a
     Georgia font that's how you did it before for those boxes". */
  background: #fff;
  border-radius: 1rem;
  padding: var(--s-l);
  border: 4px solid var(--pillar-accent, var(--sunset));
}
.practice-evidence-card h3 {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 1.125rem;
  margin: 0 0 var(--s-xs);
  /* 28w (2026-04-29 evening): heading-inside-card flipped to Ink.
     §6.3 universal card-discipline rule. */
  color: var(--ink);
  line-height: 1.25;
}
.practice-evidence-card p {
  font-size: .9375rem;
  line-height: 1.6;
  margin: 0 0 var(--s-xs);
}
.practice-evidence-card .practice-evidence-cite {
  font-size: .8125rem;
  color: var(--stone);
  margin: 0;
}

/* --- LEGACY .why / .how on practice sub-pages --------------------- */
/* Practice sub-pages from 28g still ship a body.practice modifier on
   <body>. The new section classes above replace the old .why/.how
   blocks entirely on practice sub-pages, but if a future revision
   accidentally lands a stray .why/.how on a practice page, scope
   below brings them back into the new visual rhythm. Defensive belt. */
body.practice .why,
body.practice .how {
  padding: var(--s-xl) var(--s-m);
}
body.practice .why-inner,
body.practice .how-inner {
  max-width: 56ch;
  margin: 0 auto;
}

/* ============== STORY PAGE — mission + values (28j) ==============
   The story page mission and values sections were rendering as
   undifferentiated white .why/.how blocks. Founder direction
   2026-04-28: "our mission should be in its own colour … where it
   says our values it doesn't look the same as our mission … and the
   six things we believe. Did I not say not to use [Roman numerals]?"
   This block gives Mission its own Sky-tinted band, matches Values
   to the Mission treatment, and replaces the i–vi numerated list
   with a six-card box grid that cycles the V1.1 pillar palette. */
.story-mission {
  /* Sky 14% on Sandstone — soft pale-blue band that distinguishes the
     mission from the white intro above and the white values below
     without breaking brand temperature. */
  background: color-mix(in srgb, var(--sky) 14%, var(--sandstone));
  padding: var(--s-xxl) var(--s-m);
}
.story-mission-inner {
  max-width: 56ch;
  margin: 0 auto;
}
.story-mission .eyebrow {
  text-align: left;
  margin-bottom: var(--s-xs);
  color: var(--ink);
}
.story-mission h2 {
  font-size: clamp(1.75rem, 4vw, 2.25rem);
  margin: 0 0 var(--s-m);
  text-align: left;
  letter-spacing: -0.005em;
}
.story-mission p {
  font-size: 1.0625rem;
  line-height: 1.7;
  margin: 0 0 var(--s-m);
}

.story-values {
  /* White band so the six pillar-bordered cards pop against neutral
     ground. Eyebrow + h2 weight matches .story-mission for parity. */
  background: #fff;
  padding: var(--s-xxl) var(--s-m);
}
.story-values-inner {
  /* 28v: was max-width var(--container) with each child re-centred via
     auto margins — that approach left the eyebrow + h2 + grid each
     centred independently, which made the eyebrow drift slightly out
     of alignment with the h2 underneath (founder: "Six things we
     believe eyebrow should be more better aligned"). Match
     .story-mission's structure: single 56ch outer wrapper, all
     children inherit that constraint without per-element auto-margin
     gymnastics. The values-grid below remains full-width because it
     lives in its OWN inner block (see grid rules), so the constraint
     here only governs the heading region. */
  max-width: 56ch;
  margin: 0 auto;
}
.story-values .eyebrow {
  text-align: left;
  margin-bottom: var(--s-xs);
  color: var(--ink);
  max-width: none;
}
.story-values h2 {
  font-size: clamp(1.75rem, 4vw, 2.25rem);
  margin: 0 0 var(--s-l);
  text-align: left;
  letter-spacing: -0.005em;
  max-width: none;
}
.values-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-m);
}
@media (min-width: 640px) {
  .values-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 960px) {
  .values-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
.values-card {
  /* Card discipline §1: full 4-side 4px border. Six cards cycle the
     V1.1 pillar palette in display order — Sunset / Teal / Russet /
     Sky / Lime / Marigold (Plum is reserved for Hypnosis-only
     contexts and skipped here so the values sit in the calmer six). */
  background: #fff;
  padding: var(--s-l) var(--s-m);
  border-radius: 1rem;
  border: 4px solid var(--sunset);
}
.values-card:nth-child(2) { border-color: var(--teal); }
.values-card:nth-child(3) { border-color: var(--russet); }
.values-card:nth-child(4) { border-color: var(--sky); }
.values-card:nth-child(5) { border-color: var(--lime); }
.values-card:nth-child(6) { border-color: var(--marigold); }
.values-card h3 {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 1.125rem;
  margin: 0 0 var(--s-xs);
  color: var(--sunset);
  line-height: 1.25;
}
.values-card:nth-child(2) h3 { color: var(--teal); }
.values-card:nth-child(3) h3 { color: var(--russet); }
.values-card:nth-child(4) h3 { color: var(--sky); }
.values-card:nth-child(5) h3 { color: var(--lime); }
.values-card:nth-child(6) h3 { color: var(--marigold); }
.values-card p {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--ink);
  margin: 0;
}

/* ============== ROADMAP V→v cleanup (28g) ==============
   The roadmap-tag pills carried "V1.0", "V1.1", etc. uppercase —
   inconsistent with the lowercase v1.0/v1.1/v1.2 used everywhere
   else (pillar-badge, practice-page eyebrows, pricing copy, brand
   docs). Founder direction 2026-04-28g: lowercase across the
   board. The HTML in roadmap.html is updated separately; this rule
   is a defensive belt — if a future entry ships uppercase, the
   text-transform forces it lowercase visually. CSS only catches
   what's in the markup, so this is reinforcement, not the fix. */
.roadmap-tag {
  text-transform: lowercase;
}

/* ============== 28k ROUND — six fixes from founder feedback ==============
   Founder direction 2026-04-28k:

   1. "the logo still not soyed" → handled in /assets/logomark.svg
      (viewBox tightened to "310 310 1380 1380" so the pebble cluster
      fills the 56×56 lockup box rather than floating in 35% empty
      negative space).
   2. "the green isn't quite the right green" → --lime token softened
      from Tailwind #84CC16 to Brief 1.5 §3 sage #A8C26B at the top of
      this file.
   3. "text on orange / green should be in white, not in black" →
      practice-hero H1 + intro flip to white on the warm pillars
      (Sunset, Marigold, Lime) below.
   4. "in sleep the figure disappears in the border" → soft white halo
      behind the salmon-line-art Lottie on warm-pillar heroes (Sunset,
      Russet, Marigold) so the figure lifts off similar-temperature
      backgrounds.
   5. "borders in practises subfolders all yellow / all blue. Mix them
      up." → §15-style border variety inside practice-page card grids
      via :nth-child cycling.
   6. "the practises listing didn't change the background, and pick a
      practise should be a different colour" → body.practices-listing
      scoping: .why goes warm-beige, .pillars-band goes white, the
      "Pick a practice" headline picks up a pillar accent.
   7. "our mission should be in its own colour" → mission band swung
      from Sky 14% (cool tint on warm Sandstone) to Marigold 14%
      (warm tint, temperature-consistent with the rest of the page).
   8. "I like the orange-and-white-on-Ink on the home page — use that
      more" + "where's my founder photo" → new .story-founder block
      lifts the home Ink+Sunset+white hero treatment onto the story
      page and finally wires founder-headshot.jpg into the layout.
   9. "split sections into two, image in the middle" + "yoga benefits
      with person in the middle and left/right text" → new .split-2
      and .benefits-spoke vibrancy components, scaffolded for use
      across practices and story.

   The cascade rule (Style Guide §9 / §11): any change here must apply
   on every page that uses the pattern. Practice-hero rules are scoped
   via body.practice + style attribute selector; practices-listing
   scopes via body.practices-listing on practices/index.html. */

/* 28p (2026-04-29) — 28k.1 obsolete: warm-pillar text-flip rules
   were needed when each pillar painted its hero its own colour.
   With the universal Ink hero (28p), every pillar's white text
   inherits cleanly from `.practice-hero { color: #fff }`. Block
   removed.

   28k.2 → 28p universal halo → 28v rounded-square → 28w solid
   white card. Founder direction 2026-04-29 evening: "We may have
   a square box with no Halo effect that's in the same style as
   the boxes that we have already simple". The halo gradient is
   gone — the Lottie figure now sits in a clean white rounded-
   square card matching the audience/evidence/stat cards on the
   same page. No border because the pillar bg already provides
   high-contrast separation; adding a pillar-coloured border on
   a pillar-coloured hero would be invisible. The white card is
   the figure; the pillar hero is the surround. */
body.practice .practice-lottie {
  background: #fff;
  border-radius: 1rem;
}

/* 28w (2026-04-29 evening) — Mix-borders pattern KILLED. Founder
   direction: "if you've got a yoga all of the boxes should show
   the same. Curved corner with the same colour and the text that's
   the header inside each one that should be in the black and we
   do that seven times with the seven colours and that's it".
   Reverses 28k.3. Every card on a pillar page now shares ONE
   border colour — the page's pillar — so a Yoga page reads as
   uniformly Teal-bordered, Mobility uniformly Sunset-bordered,
   etc. Seven pillars × one colour each, no per-card cycling.
   This is the §6.3 universal card-discipline rule applied
   strictly — border = pillar, no mixing. */
.practice-audience > .practice-audience-card,
.practice-evidence-grid > .practice-evidence-card,
.practice-stats > .practice-stat-card {
  border-color: var(--pillar-accent, var(--sunset));
}

/* 28k.4 — practices-listing scoping. body.practices-listing on
   practices/index.html lets the listing page diverge from the
   homepage Sandstone-default while leaving every other page using
   .why and .pillars-band untouched. */
body.practices-listing .why {
  background: color-mix(in srgb, var(--ink) 6%, var(--sandstone));
  /* 28w (2026-04-29 evening): full-bleed override. The base .why
     rule sets max-width: var(--container) which constrained the
     warm Ink-tint background to the centre column; founder
     direction same evening: "still not got a complete width on
     the background on the first section". Same fix pattern as
     body.pricing .why from 28m morning. The inner .why-inner
     keeps text at 60ch readable width; only the section's
     background goes edge-to-edge. */
  max-width: none;
}
body.practices-listing .pillars-band {
  /* 28l revision (was `background: #fff` in 28k). Founder direction
     2026-04-28l: "why you change your style in practises to not have
     the background of that section. Go all across the page" — white
     was wrong, the section needs a coloured surround that differs
     from the home page Sandstone *and* extends edge-to-edge. Marigold
     14% on Sandstone is warm-on-warm (temperature-consistent with the
     rest of the page) and reads as a distinct surface from the
     Sandstone-on-default `.why` band above and the Sandstone home
     pillar grid. The .pillars-band section element is already
     full-width (no max-width on the section itself, only on .pillars-
     inner inside it), so the tint extends the full viewport. */
  background: color-mix(in srgb, var(--marigold) 14%, var(--sandstone));
}
body.practices-listing .pillars-title {
  /* "Pick a practice." picks up Sunset to flag the section as the
     active brand moment. Sandstone pillar-cards on Marigold-tinted
     band still read as distinct surfaces (light-on-warm contrast). */
  color: var(--sunset);
}
body.practices-listing .pillar-card {
  background: var(--sandstone);
}

/* 28k.5 — mission band colour. Was Sky 14% on Sandstone (cool tint
   on warm base — read as off-temperature against the page); now
   Marigold 14% (warm-on-warm, golden-hour read consistent with the
   rest of the story page). */
.story-mission {
  background: color-mix(in srgb, var(--marigold) 14%, var(--sandstone));
}

/* 28k.6 — STORY FOUNDER card. Lift the homepage Ink+Sunset+white
   editorial treatment onto the story page and finally place
   founder-headshot.jpg (785 KB asset that's been sitting unwired
   since 28j). Photo goes left, deep-Ink panel right, Sunset eyebrow
   + accents, white prose. Mirrors the homepage .founder-card
   visually but in a wider split-2 layout suited to the story
   page's narrative flow. */
.story-founder {
  background: var(--ink);
  padding: var(--s-xxl) var(--s-m);
  color: #fff;
}
.story-founder-inner {
  max-width: var(--container);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-l);
  align-items: center;
}
@media (min-width: 720px) {
  .story-founder-inner {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: var(--s-xl);
  }
}
.story-founder-photo {
  width: 100%;
  max-width: 360px;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 1rem;
  border: 4px solid var(--sunset);
  display: block;
  margin: 0 auto;
}
.story-founder-text { max-width: 56ch; }
.story-founder-text .eyebrow {
  color: var(--sunset);
  text-align: left;
  margin-bottom: var(--s-xs);
}
.story-founder h2 {
  color: #fff;
  font-size: clamp(1.75rem, 4vw, 2.25rem);
  margin: 0 0 var(--s-m);
  text-align: left;
  letter-spacing: -0.005em;
}
.story-founder p {
  color: #fff;
  font-size: 1.0625rem;
  line-height: 1.7;
  margin: 0 0 var(--s-m);
  max-width: none;
}
.story-founder strong { color: var(--sunset); font-weight: bold; }

/* 28k.7 — SPLIT-2 alternating image+text layout. Inspired by the
   Mediclick yoga reference variant blocks — not copied, used as a
   touchstone for breaking up monolithic prose with media. Use as
   `<section class="split-2">` (or `.split-2.split-2--reverse` to
   flip the order on alternate rows). At desktop the two columns
   are equal-width; on mobile they stack media-first. The media
   slot accepts a Lottie placeholder, an SVG icon, or a photo. */
.split-2 {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-l);
  align-items: center;
  padding: var(--s-xl) 0;
}
@media (min-width: 720px) {
  .split-2 {
    grid-template-columns: 1fr 1fr;
    gap: var(--s-xl);
  }
  .split-2.split-2--reverse > :first-child { order: 2; }
}
.split-2-media {
  width: 100%;
  max-width: 380px;
  margin: 0 auto;
}
.split-2-media img,
.split-2-media .practice-lottie {
  width: 100%;
  display: block;
}
.split-2-text { max-width: 56ch; }
.split-2-text .eyebrow { text-align: left; margin-bottom: var(--s-xs); }
.split-2-text h3 {
  font-size: clamp(1.25rem, 2.6vw, 1.5rem);
  margin: 0 0 var(--s-s);
  /* 28w (2026-04-29 evening): split-2 sub-heading flipped to Ink.
     Same §6.3 rule — text on practice pages reads as Ink, pillar
     colour is reserved for borders + accent strokes only. */
  color: var(--ink);
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
}
.split-2-text p {
  font-size: 1rem;
  line-height: 1.65;
  margin: 0 0 var(--s-s);
}

/* 28m: BENEFITS-SPOKE rules removed — section deleted from
   practices/index.html per founder direction "I thought change
   practises just lose that section". The 28k.8 block (figure in
   middle + flanking text spokes) and the 28l.2 centre Lottie
   sizing are both gone. .pebble-mark--xl is also dropped here
   because its only consumer was the benefits-spoke centre. If we
   reintroduce a similar pattern in future, lift the rules from
   git history at this commit. */

/* ============================================================
   28l ROUND — founder review of 28k shipping. Four corrections
   landed in one cut:

   1. "what's the logo on the top left? Still not changed to the
      one with the white background" → on coloured-hero pages the
      sticky white site-header was bleeding into the orange hero
      visually. Added a soft box-shadow under .site-header so the
      white edge is unambiguous on every page — particularly the
      practice pillar pages where the Sunset/Russet/Marigold hero
      sits directly under it.

   2. "why you change your style in practises to not have the
      background of that section. Go all across the page" → the
      28k.4 block was setting `body.practices-listing .pillars-band
      { background: #fff }`. White lost the surround the page
      needed. Reverted to Marigold-tint full-bleed (the change is in
      the 28k.4 block above, not duplicated here, so the rule lives
      with its sibling .practices-listing rules).

   3. "I don't know what this logo in the middle is ... we don't
      need a logo there" → the benefits-spoke centre on
      practices/index.html was showing the logomark; founder asked
      previously for "person in the middle" and the logomark was
      the wrong substitution. Swapped to body-front Lottie
      (`/assets/animations/body-front.json`) — the abstract human
      silhouette already used on body-checkin-demo. Sizing override
      below clamps the Lottie SVG into the 320px centre column.

   4. "if we do put a logo in put into our story as a section to
      explain why we're choosing three balanced stones" + "pricing
      hero header is a different colour, is blending in with the
      next section" → new .story-three-stones section on
      story.html (uses .split-2 from 28k §20 with a logomark on the
      left and the brand-mark explainer on the right) plus a new
      body.pricing scope that warm-tints the pricing hero so it
      visibly differs from the .evidence "Three plans" section
      below. Both styled in this block.

   Plus regression repair: the "Six things we believe" values
   section on story.html was an unnumbered card grid (28j shipped
   that by misreading "change Roman to numbers" as "remove
   numbers"). Now back to the canonical `<ol class="how-steps">`
   pattern with Arabic 1–6, no CSS change needed (the .how-steps
   rules from §3 above already handle layout). */

/* 28l.1 — site-header box-shadow for clearer white edge on
   coloured-hero pages. The header was already `background: #fff`
   and `border-bottom: 1px solid color-mix(in srgb, ink 8%, transparent)`,
   but on practice pillar pages with Sunset/Russet/Marigold heroes
   sitting directly under it, the eye couldn't easily catch where
   the white strip ended and the coloured hero began. A soft drop-
   shadow makes the surface change unambiguous without competing
   with the brand quietness. */
.site-header {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

/* 28l.2 REMOVED in 28m — benefits-spoke centre Lottie sizing
   followed the section into deletion. */

/* 28l.3 + 28m.1 — pricing-page hero scope. body.pricing on
   pricing.html warm-tints the `.why` hero so the pricing landing's
   hero band visibly differs from the `.evidence` Sandstone "Three
   plans" section below. Without this, both `.why` (default
   Sandstone) and `.evidence` (`background: var(--sandstone)`)
   shared the same surface and read as one continuous band — founder
   direction 2026-04-28l: "pricing the hero header be a different
   car [colour] is blending in with the next section". Marigold 14%
   on Sandstone keeps temperature-consistency with the rest of the
   marque.

   28m.1 fix: the 28l shipping had the right tint but the section
   was constrained to `max-width: var(--container)` from the base
   `.why` rule, so the background only coloured the centre column
   and stopped short of the viewport edges. Founder 2026-04-28m:
   "pricing doesn't have a full background across the width [like]
   practises". Override `max-width: none` on `body.pricing .why` so
   the tint goes edge-to-edge. The inner `.why-inner` (max-width
   60ch) keeps the text from running to the screen edges. */
body.pricing .why {
  background: color-mix(in srgb, var(--marigold) 14%, var(--sandstone));
  max-width: none;
}

/* 28l.4 — story.html "Why three stones" brand-mark explainer
   section. Uses `.split-2` from 28k §20 (logomark left, text right)
   with a small section-specific override for the centred logomark
   media column and the eyebrow + h2 + dual-paragraph text column.
   Section sits between the Founder card and the "Three things we
   refuse to do" principles list — so the reading flow becomes:
   founder bio → why the mark → what we refuse to do. */
.story-three-stones {
  background: color-mix(in srgb, var(--ink) 6%, var(--sandstone));
  /* 28v fix: was `padding: var(--s-2xl) var(--s-l)` — but `--s-2xl`
     is NOT a defined token (the scale is --s-xs / --s-s / --s-m /
     --s-l / --s-xl / --s-xxl). Browser fell back to 0 vertical
     padding → section sat flush to its neighbours with no
     breathing room. Founder direction 2026-04-29: "look at the
     gaps, the gaps between the section there's no space, it's
     rubbish we need to check for all of these things and set those
     rules in the parameters". Fixed to `var(--s-xxl) var(--s-m)`
     matching every other story-page section's padding (.story-
     mission, .story-values, .story-founder, .why all use
     var(--s-xxl) var(--s-m)). Sister rule: any new section's
     vertical padding MUST use a defined token, never an
     undefined fallback. */
  padding: var(--s-xxl) var(--s-m);
}
.story-three-stones .split-2-media {
  display: flex;
  align-items: center;
  justify-content: center;
}
.story-three-stones .split-2-media img {
  width: 100%;
  max-width: 320px;
  height: auto;
  display: block;
}
.story-three-stones .split-2-text .eyebrow { color: var(--sunset); }
.story-three-stones .split-2-text h2 {
  color: var(--ink);
  margin: 0 0 var(--s-m);
}
.story-three-stones .split-2-text p {
  color: var(--ink);
  font-size: 1.0625rem;
  line-height: 1.65;
  margin: 0 0 var(--s-m);
}
.story-three-stones .split-2-text p:last-child { margin-bottom: 0; }
.story-three-stones .split-2-text strong { color: var(--sunset); }

/* Dark mode &mdash; parked. Sandstone identity held across all surfaces
   per the app's default appearance. Full review in PARKED_WORK.md item A. */

/* ==================================================================
   BODY CHECK-IN (Act 4) — pinpoint demo embedded on /index.html.
   See Style Guide v1.3 §13 (silhouette / pinpoint UI), §14 (side-by-
   side comparison, no toggle), §15 (pillar-coloured card border by
   dominant pillar), §16 (single-target highlight + side-tag), §17
   (breathing-dot pattern), §18 (catch-all in white space), §19
   (mirror-view L/R convention), §20 (iOS parity).
   All selectors scoped to .body-checkin so they don't bleed onto
   other surfaces that reuse generic class names like .card, .zone.
   ================================================================== */
.body-checkin .body-checkin-sub {
  font-size: 0.95rem;
  color: var(--russet);
  text-align: center;
  margin: -0.5rem 0 var(--s-xl);
}
.body-checkin .wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  width: 100%;
  max-width: 840px;
  margin: 0 auto;
  /* M-156-followup-W (2026-05-05 founder catch — *"the scroll to box
     is not there now but what use is the box if I can't see it"*) —
     enable absolute-positioned popover children. Without this, the
     `.show-popover .cards` rule resolved up to the html root and the
     popover landed in unexpected positions. With `.wrap` relative,
     the popover anchors correctly within the figure-pair container. */
  position: relative;
}
/* Figure box wraps both bodies side-by-side */
.body-checkin .figure-box {
  background: #fff;
  border: 1.5px solid rgba(31,36,40,0.10);
  border-radius: 16px;
  box-shadow: 0 1px 10px rgba(31,36,40,0.06);
  overflow: hidden;
  flex-shrink: 0;
}
.body-checkin .figure-pair {
  display: flex;
  gap: 48px;
  padding: 18px 14px 14px;
  justify-content: center;
  position: relative;
}
.body-checkin .figure-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 0 0 auto;
  width: 180px;
}
@media (max-width: 480px) {
  .body-checkin .figure-col { width: 140px; }
  .body-checkin .figure-pair { padding: 14px 8px 10px; gap: 32px; }
}
/* Round 28x.14 founder direction: "I like this big style view on the
   mobile. On the desktop, it's actually smaller. So maybe we need to
   just move that tap a body on the information section below it and
   make this image for the front and back bigger." Desktop figures
   bumped from 180→280px; figure-pair gap widened to match the larger
   silhouettes. Placed AFTER the 480px mobile rule so source-order
   precedence makes this win on desktop viewports. */
@media (min-width: 720px) {
  .body-checkin .figure-col { width: 280px; }
  .body-checkin .figure-pair { gap: 64px; padding: 28px 24px 20px; }
}

/* 28q (2026-04-29) — body-diagram stacks vertically below 640 px so
   each figure can be MUCH bigger on mobile. Side-by-side at 320 +
   320 px viewport widths squeezed each figure to ~40% of available
   width — too small to read the breathing dots. Founder direction:
   "rather than have a front and back side by side it needs to be
   bigger. So you can only display the front and if you scroll then
   you get the back". This stacks FRONT first, BACK below; each
   figure takes ~85% of container width. The catch-all "Full Body"
   pin can no longer sit BETWEEN figures (no horizontal whitespace
   exists when stacked) — repositioned to fixed bottom-right of the
   FRONT figure's relative wrapper at this breakpoint. */
@media (max-width: 640px) {
  /* Round 28x.14 (2026-04-30) — figure-box was collapsing to its
     content's intrinsic width (~50px) on mobile because .body-checkin
     .wrap is `flex-direction: column; align-items: center` (no implicit
     stretch), and .figure-box had no width override. With figure-box
     stuck at ~50px, .figure-col `width: min(85%, 320px)` resolved
     against that — 85% of 50 = 43px. Founder verbatim: "completely
     rubbish. Not usable at all." Fix: stretch figure-box to full wrap
     width on mobile so the percentage-based figure-col sizing has a
     real parent to compute against.
     Also overflow:visible so zone tooltips (.tip positioned at top:-18px
     above each zone) aren't clipped by the figure-box edge — was fine
     on desktop where tooltips never reached the edge but at mobile
     larger figures push them past the box. */
  .body-checkin .figure-box {
    width: 100%;
    max-width: 480px;
    overflow: visible;
  }
  .body-checkin .figure-pair {
    flex-direction: column;
    gap: 24px;
    padding: 18px 0 14px;
    align-items: center;
  }
  .body-checkin .figure-col {
    width: min(85%, 320px);
  }
  /* Round 28x.14 followup — catch-all "Full Body" dot was at top:14px
     (above the figure, next to the "Front" label, "hanging in the air"
     per founder). Bump down so it sits inside the FRONT figure
     silhouette area, not on the label. Width-side positioning unchanged
     — calc puts it at the right edge of the centred figure-col. */
  .body-checkin .figure-pair .fb-center {
    position: absolute;
    left: auto;
    top: 64px;
    right: max(16px, calc((100% - 85%) / 2 + 8px));
    transform: none;
  }
}

/* Catch-all "Full Body" button — single instance in the white space
   between figures. Identical breathing-dot style as regional zones. */
.body-checkin .fb-center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 32px;
  height: 32px;
  border: none;
  background: transparent;
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  z-index: 6;
}
.body-checkin .fb-center::after {
  content: '';
  display: block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--sunset);
  opacity: 0.78;
  box-shadow: 0 0 0 3px rgba(245,239,230,0.78);
  animation: bc-pulse 2.6s ease-in-out infinite;
  transition: opacity 0.15s, transform 0.15s;
}
.body-checkin .fb-center:hover::after { transform: scale(1.45); opacity: 1; box-shadow: 0 0 0 4px rgba(245,239,230,0.95); }
.body-checkin .fb-center.on::after { opacity: 0.35; transform: scale(1); }
.body-checkin .fb-center .tip {
  position: absolute;
  top: -22px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 9px;
  font-weight: 700;
  color: var(--sunset);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.15s;
  pointer-events: none;
  background: rgba(245,239,230,0.95);
  padding: 1px 6px;
  border-radius: 8px;
  letter-spacing: 0.4px;
}
.body-checkin .fb-center:hover .tip,
.body-checkin .fb-center.on .tip { opacity: 1; }

/* Front + back labels — same Sunset, no underline */
.body-checkin .figure-label {
  /* Round 28x.14 founder feedback: "I don't like the front use of the
     front and back. Doesn't just quite hit it for me. Is it because
     it's in capitals, do reckon? Maybe it needs to be bigger and in
     normal case." Switched from uppercase tracked-out 11px → mixed-case
     16px Georgia for a softer, more human label. */
  font-family: Georgia, serif;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.005em;
  text-transform: none;
  margin-bottom: 8px;
  color: var(--ink);
}

/* Character area — fixed 1:2 aspect, Lottie fills it */
.body-checkin .char-area {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 2;
}
.body-checkin .lottie-view {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}
.body-checkin .lottie-view svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Zones — breathing dots */
.body-checkin .zone {
  position: absolute;
  border-radius: 8px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.body-checkin .zone::after {
  content: '';
  display: block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--sunset);
  opacity: 0.78;
  box-shadow: 0 0 0 3px rgba(245,239,230,0.78);
  animation: bc-pulse 2.6s ease-in-out infinite;
  transition: opacity 0.15s, transform 0.15s;
}
.body-checkin .zone:hover::after { transform: scale(1.45); opacity: 1; box-shadow: 0 0 0 4px rgba(245,239,230,0.95); }
.body-checkin .zone.on::after { opacity: 0.35; transform: scale(1); }

@keyframes bc-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.25); }
}

/* Tooltip */
.body-checkin .zone .tip {
  position: absolute;
  top: -18px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 9px;
  font-weight: 700;
  color: var(--sunset);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.15s;
  pointer-events: none;
  background: rgba(245,239,230,0.95);
  padding: 1px 6px;
  border-radius: 8px;
  z-index: 6;
}
.body-checkin .zone:hover .tip,
.body-checkin .zone.on .tip { opacity: 1; }

/* Cards — full-around border, colour by dominant pillar
 *
 * M-156-followup-U Burst 3.9 (2026-05-04 founder direction "go through
 * all the remainder of bursts" + ratified plan A from M-156-followup-P):
 * Cards-below-scroll → anchored hover-popover. Mirrors glossary popover
 * behaviour — popover floats over the figure (no page scroll), dismisses
 * on tap-outside or scroll. Same pattern shipped on iOS as Burst 3.6
 * (`Sthira/Views/BodyCheckIn/BodyCheckInPopoverContent.swift`).
 *
 * The .cards container becomes a fixed-position popover anchor at the
 * top of the body-checker section. Cards still exist at their original
 * positions for accessibility (semantic order preserved); when a card
 * gets .show, it pops out to a positioned overlay via .show-popover
 * class added by JS.
 */
.body-checkin .cards {
  position: relative;
  width: 100%;
  max-width: 340px;
  margin: 0 auto;
  /* min-height removed — popover-mode doesn't reserve space below the
     figure (the empty state was the only thing that needed it; now
     hidden when no zone is tapped, no reservation needed). */
}
.body-checkin .empty {
  /* Keep the empty-state hint visible at the top of the cards area
     when no zone is tapped. Once a zone is tapped + popover surfaces,
     the empty state hides via JS. */
  text-align: center;
  padding: 16px;
  color: var(--stone, #6E7375);
  font-size: 14px;
  font-style: italic;
}
.body-checkin .card {
  position: relative;
  background: #fff;
  /* M-141 — 2px → 1.5px to match canonical subtle-card weight site-wide.
     Per feedback_card_discipline_full_borders.md: only valid weights
     are 4px (accent) and 1.5px (subtle); 2px is non-canonical drift. */
  border: 1.5px solid rgba(31,36,40,0.10);
  border-radius: 12px;
  padding: 16px 16px 14px;
  box-shadow: 0 1px 10px rgba(31,36,40,0.06);
  display: none;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.25s, transform 0.25s, border-color 0.2s;
}

/* M-156-followup-W (2026-05-05 founder catch — *"the scroll to box is
 * not there now but what use is the box if I can't see it"*) — use
 * `position: fixed` viewport-anchored so the popover ALWAYS appears
 * at the bottom-centre of the user's screen when shown, regardless of
 * scroll position OR ancestor positioning. Founder's screenshots
 * showed the original Burst 3.9 `position: absolute` resolved to an
 * unexpected ancestor and the card landed off-screen. `position:
 * fixed` to the viewport eliminates the ancestor-positioning trap
 * entirely.
 *
 * Trade-off: the popover feels more like a toast notification than
 * an "anchored to figure" pop. Acceptable because (a) reliability
 * over visual nicety for V1.0; (b) the founder explicitly asked for
 * the card to be VISIBLE which fixed-position guarantees.
 *
 * Glossary parity: dismisses on outside-click / scroll via JS
 * listeners (existing). Safe-area-inset honoured for iOS Safari
 * with home-indicator gestures. */
.body-checkin.show-popover .cards {
  position: fixed;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;  /* above all page chrome */
  max-width: min(340px, calc(100% - 32px));
  width: 100%;
  pointer-events: none;  /* allow taps through .cards container */
}
.body-checkin.show-popover .card.show {
  pointer-events: auto;  /* but the actual visible card receives taps */
  border-width: 4px;     /* accent border per memory rule
                            feedback_card_discipline_full_borders.md */
  box-shadow: 0 8px 32px rgba(31,36,40,0.22),
              0 2px 8px rgba(31,36,40,0.12);
  /* Slide-up entrance honoured by existing .card transition
     (translateY(8px) → translateY(0) over 0.25s); popover positioning
     just shifts the absolute anchor without altering the fade-in. */
}
.body-checkin .card.show { opacity: 1; transform: translateY(0); }

/* 28x.17 — flash highlight on tap. JS adds .flash class after scroll-
   into-view so the visitor sees the result card pulse for ~1.2s,
   confirming their tap produced output. Without this, the result
   card update is silent — founder verbatim: "I click on neck, but
   I don't know what it's done." */
@keyframes bc-card-flash {
  0%   { box-shadow: 0 0 0 0 rgba(232,93,47,0.0); }
  20%  { box-shadow: 0 0 0 8px rgba(232,93,47,0.30); }
  60%  { box-shadow: 0 0 0 4px rgba(232,93,47,0.18); }
  100% { box-shadow: 0 0 0 0 rgba(232,93,47,0.0); }
}
.body-checkin .card.flash {
  animation: bc-card-flash 1.2s ease-out 1;
}
/* M-162 REVERT (2026-05-08 ~00:35): founder catch *"The website is
   perfect. It's this fucking phone that's fucked"* — M-159 FA-X37-
   followup unified-sunset change at commit 0467538 was WRONG; website
   was visually correct with per-pillar borders. iOS was the broken
   surface (separate fix; revert here doesn't touch iOS). Restored
   original per-pillar border-color rules. Lesson: founder direction
   "make iOS match website" was misread as "make website match iOS".
   Verified per §74.1 NEVER-ASSUME — checked website was actually
   perfect BEFORE proposing change next time. */
.body-checkin .card.pillar-mobility   { border-color: var(--sunset); }
.body-checkin .card.pillar-strength   { border-color: var(--russet); }
.body-checkin .card.pillar-yoga       { border-color: var(--teal); }
.body-checkin .card.pillar-breath     { border-color: #4EA6C6; }
.body-checkin .card.pillar-meditation { border-color: #8DA563; }
.body-checkin .card.pillar-sleep      { border-color: #6B5B8C; }
.body-checkin .card.pillar-hypnosis   { border-color: #C8A547; }
.body-checkin .card.pillar-all        { border-color: var(--ink); }

.body-checkin .lbl {
  font-size: 9px;
  font-weight: 700;
  color: var(--russet);
  letter-spacing: 0.7px;
  text-transform: uppercase;
  margin-bottom: 4px;
}
.body-checkin .card h3 {
  font-family: Georgia, serif;
  font-size: 17px;
  font-weight: 700;
  margin-bottom: 3px;
}
.body-checkin .badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 600;
  color: var(--sunset);
  background: rgba(232,93,47,0.08);
  padding: 2px 8px;
  border-radius: 14px;
  margin-bottom: 8px;
}
.body-checkin .side-tag {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  color: var(--russet);
  background: rgba(181,88,63,0.10);
  padding: 2px 8px;
  border-radius: 14px;
  margin-bottom: 8px;
  margin-left: 4px;
  letter-spacing: 0.6px;
}
.body-checkin .side-tag[hidden] { display: none; }

.body-checkin .ex { font-size: 12.5px; line-height: 1.55; margin-bottom: 6px; }
.body-checkin .sp { font-size: 11px; color: var(--russet); font-style: italic; }
.body-checkin .rg { font-size: 10px; color: #999; margin-top: 6px; }
.body-checkin .ft {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--sandstone);
  font-size: 11px;
  color: #aaa;
  line-height: 1.4;
}

.body-checkin .empty {
  height: 240px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  /* M-141 — 2px → 1.5px (canonical subtle-card weight) */
  border: 1.5px solid rgba(31,36,40,0.10);
  border-radius: 12px;
  box-shadow: 0 1px 10px rgba(31,36,40,0.06);
}
.body-checkin .empty p {
  font-size: 13px;
  color: var(--russet);
  text-align: center;
  line-height: 1.6;
  padding: 0 16px;
}

/* Body check-in heading sits below the 3-step .how-steps list, above the
   interactive figure pair. Same Georgia treatment as .how-step h3 but
   centred and a touch larger so it reads as a transition heading. */
.body-checkin .body-checkin-heading {
  font-family: Georgia, 'Times New Roman', serif;
  font-size: clamp(1.25rem, 3vw, 1.75rem);
  font-weight: 700;
  text-align: center;
  margin: var(--s-xxl) 0 0.5rem;
  letter-spacing: -0.005em;
}

/* Body check-in section — distinct warm-beige background per founder direction
   2026-04-29: "the how it works section to be another colour for background".
   Sits between the white .why section above and the next section's bg below,
   so the integrated section reads as its own band. */
/* "How it works" — homepage modifier (.how--home). Warm-beige band so the
   3-step section reads as its own band, distinct from the white .why band
   above and the white .body-checkin section below. .how on /story.html and
   the practice sub-pages keeps its existing white / inherited bg. */
.how--home {
  background: #F1E4CE;
}

/* Body check-in — its own section, white bg so the figure-pair card pops.
   Section-level padding matches other home sections. Heading + intro +
   figure-pair all centre-aligned. */
.body-checkin {
  background: #fff;
  padding: var(--s-xxl) var(--s-m);
}
.body-checkin .body-checkin-heading {
  text-align: center;
  margin-bottom: 0.5rem;
}
.body-checkin .body-checkin-sub {
  text-align: center;
  max-width: 36rem;
  margin: 0 auto var(--s-xl);
}
.body-checkin .wrap {
  margin-left: auto;
  margin-right: auto;
}

/* ============================================================
   28o (2026-04-29) — Batch 1 — quick-wins ship.
   ============================================================ */

/* 28o.1 — Mobile hamburger nav.
   Founder direction 2026-04-29: "the menu on the top for mobiles
   should be a hamburger type menu because if you look now, we've
   got so many things there. It's making the page go wider than
   the actual screen". The 5 nav items (Story / Practices /
   Programmes / Pricing / Roadmap) overflow the viewport on
   anything narrower than ~720 px. Solution: a 3-bar toggle button
   between the brand-lockup and the nav. Below 720 px, the nav is
   hidden by default; clicking the toggle slides it down as a
   panel beneath the header. Closes on link click + on Escape (JS
   in site.js).
   Inserted by template into every page via Python sweep — 18 of
   20 pages (privacy + terms have shortened legal-only headers
   without nav, so they don't get a toggle). */
.nav-toggle {
  display: none;
  background: none;
  border: 0;
  width: 44px;
  height: 44px;
  padding: 10px;
  cursor: pointer;
  position: relative;
  margin-left: auto;        /* push to right edge of header flex */
  align-self: center;
  border-radius: 6px;
}
.nav-toggle:hover,
.nav-toggle:focus-visible {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  outline: none;
}
.nav-toggle-bar {
  display: block;
  width: 24px;
  height: 2px;
  background: var(--ink);
  border-radius: 2px;
  margin: 4px auto;
  transition: transform 200ms ease, opacity 200ms ease;
  transform-origin: center;
}
/* Animate the 3 bars into an X when open */
.site-header.is-nav-open .nav-toggle-bar:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}
.site-header.is-nav-open .nav-toggle-bar:nth-child(2) {
  opacity: 0;
}
.site-header.is-nav-open .nav-toggle-bar:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

@media (max-width: 720px) {
  .nav-toggle { display: block; }
  /* Hide nav by default on mobile; reveal as a slide-down panel
     when .is-nav-open is on the parent header. */
  .site-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: #fff;
    border-bottom: 1px solid color-mix(in srgb, var(--ink) 8%, transparent);
    flex-direction: column;
    padding: var(--s-s) var(--s-m);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.08);
    z-index: 99;
  }
  .site-nav a {
    /* 28o.1 hotfix follow-up 2026-04-29: founder asked padding
       around each link in the mobile dropdown should match the
       desktop convention. Desktop uses `.5rem .75rem` per the
       base `.site-nav a` rule (~1366) — restoring that here so
       horizontal breathing room matches and the link doesn't run
       flush to the panel edges. Vertical padding stays `.5rem`
       too (matches desktop) — tightens the menu so 5 stacked
       items don't dominate the viewport. */
    display: block;
    padding: .5rem .75rem;
    font-size: 1.0625rem;
  }
  /* 28o.1 hotfix follow-up 2026-04-29: founder direction
     "I don't like the faint grey lines — remove those". The
     border-top on .site-nav a + a was drawing 1px Ink-tinted
     dividers between each link in the mobile dropdown panel.
     Removed entirely — clean stacked text, breathing room from
     the .5rem .75rem padding alone. */
  .site-header.is-nav-open .site-nav { display: flex; }
}

/* 28o.2 — Anchor scroll-padding so the sticky header doesn't clip
   the top of any in-page anchor target. Founder direction 2026-04-29:
   "when you click on anywhere in the website to join the wait list
   which could be on the bottom as a CTA you can see how it's being
   displayed. So the hashtag for the HTML is cutting off the top.
   We should have a little bit of space where we could put the name
   in." The site-header is ~88 px tall (56 px logomark + s-s × 2
   padding); adding 16 px breathing room → 104 px scroll-padding.
   Mobile is shorter (~72 px); 88 px on mobile. */
html {
  scroll-padding-top: 104px;
}
@media (max-width: 720px) {
  html { scroll-padding-top: 88px; }
}


/* ============================================================
   28s (2026-04-29) — JOURNAL surface (Batch 5).
   Listing page at /journal/ + per-article pages at /journal/<slug>/.
   Spec: Sthira Me Journal Strategy 1.2 §1–§4 + §6 image strategy.
   ============================================================ */

/* ----- Listing page ------------------------------------------- */
.journal-listing .why-title {
  text-align: left;
}
.journal-list-band {
  background: var(--sandstone);
  padding: var(--s-xxl) var(--s-m);
}
.journal-list-inner {
  max-width: var(--container);
  margin: 0 auto;
}
.journal-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: 1fr;
  /* 6b.6d — all rows same height regardless of text-length variance per
     row's content. Founder direction: "all of them should change to that
     same size as well." */
  grid-auto-rows: 1fr;
  gap: var(--s-l);
}
@media (min-width: 720px) {
  .journal-list { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1080px) {
  .journal-list { grid-template-columns: repeat(3, 1fr); }
}

/* ----- Card ---------------------------------------------------- */
/* 28v REVISIONS: (1) per-card pillar-coloured border per founder
   direction "On the main journal page, the charcoal colour should
   be changed to the relevant pillar colour" — overrides the
   default Ink border via [data-pillar] attribute selectors below.
   (2) Equal-height cards via `height: 100%` so all cards in a row
   stretch to the tallest. Previously cards sized to content. */
.journal-card {
  display: flex;
  flex-direction: column;
  gap: .55rem;
  background: #fff;
  border: 4px solid var(--ink);    /* fallback; per-pillar overrides below */
  border-radius: 1rem;
  padding: var(--s-m);
  text-decoration: none;
  color: var(--ink);
  transition: transform 140ms ease-out, box-shadow 140ms ease-out;
  box-shadow: 0 1px 0 rgba(31, 36, 40, 0.06), 0 4px 16px rgba(0, 0, 0, 0.06);
  position: relative;
  height: 100%;                    /* equal-height cards in flex-row grid */
}
.journal-card[data-pillar="mobility"]   { border-color: var(--sunset); }
.journal-card[data-pillar="yoga"]       { border-color: var(--teal); }
.journal-card[data-pillar="strength"]   { border-color: var(--russet); }
.journal-card[data-pillar="breath"]     { border-color: var(--sky); }
.journal-card[data-pillar="meditation"] { border-color: var(--lime); }
.journal-card[data-pillar="sleep"]      { border-color: var(--marigold); }
.journal-card[data-pillar="hypnosis"]   { border-color: var(--plum); }
.journal-card[data-pillar="founder"]    { border-color: var(--sunset); }   /* founder letter pillar */
.journal-card[data-pillar="family"]     { border-color: var(--lime); }     /* family pillar */
.journal-card[data-pillar="seasonal"]   { border-color: var(--sunset); }   /* seasonal pillar */

/* The grid item must also stretch to fill row height so .journal-card's
   height: 100% has a parent to fill against. Already set via flex on
   .journal-list above — make explicit for clarity. */
.journal-list > li {
  display: flex;
}
.journal-list > li > .journal-card {
  flex: 1;
  width: 100%;
}
/* Push meta-row to the bottom of each card so dates / status align
   across all cards in a row regardless of title + excerpt length. */
.journal-card .journal-card-meta {
  margin-top: auto;
}
.journal-card--live:hover,
.journal-card--live:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.10);
  color: var(--ink);
  text-decoration: none;
  outline: none;
}
.journal-card--coming {
  opacity: 0.78;
  cursor: default;
}
.journal-card-tag {
  display: inline-block;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--sunset);
  align-self: flex-start;
}
.journal-card-title {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 1.1875rem;
  line-height: 1.25;
  color: var(--ink);
  margin: 0;
}
.journal-card-excerpt {
  font-size: 0.95rem;
  color: var(--ink);
  line-height: 1.55;
  margin: 0;
  max-width: none;
}
.journal-card-meta {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.8rem;
  color: var(--stone);
  margin: var(--s-xs) 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
}
.journal-card-pillar {
  font-weight: 600;
  text-transform: capitalize;
}
.journal-card[data-pillar="mobility"]   .journal-card-pillar { color: var(--sunset); }
.journal-card[data-pillar="yoga"]       .journal-card-pillar { color: var(--teal); }
.journal-card[data-pillar="strength"]   .journal-card-pillar { color: var(--russet); }
.journal-card[data-pillar="breath"]     .journal-card-pillar { color: var(--sky); }
.journal-card[data-pillar="meditation"] .journal-card-pillar { color: var(--lime); }
.journal-card[data-pillar="sleep"]      .journal-card-pillar { color: var(--marigold); }
.journal-card[data-pillar="hypnosis"]   .journal-card-pillar { color: var(--plum); }
.journal-card-status {
  font-style: italic;
  color: var(--stone);
}
.journal-card-sep,
.journal-card-words {
  color: var(--stone);
}

/* ----- Article body ------------------------------------------- */
.journal-article {
  background: var(--sandstone);
}
.journal-article-body {
  max-width: 100%;
}

/* 6b.6 (2026-04-30) — full-width hero image band above the dark Ink header.
   Sits at top of every journal article. Image is the deterministically-
   rendered 1080x1350 social hero (Sandstone bg + canonical 3-pebble
   logomark + brand-canon text overlay; per METHODOLOGIES §29 hybrid →
   pure-SVG pivot). Same PNG also serves as og:image + twitter:image so
   social shares show this card. Per article: assets/journal-heroes/<slug>.png.
   6b.6c — Russet hairlines top + bottom so hero (Sandstone bg) doesn't
   blend with the page bg (also Sandstone) — founder caught this. */
/* 6b.6j (2026-05-01) — flush hero band: zero padding so the image sits
   directly against the dark Ink article header below. Founder direction:
   "the image finishes at a point and then there's a little bit of a gap.
   So I don't want this gap. the image should be there, and then there's
   no gaps." Removed Russet hairlines + box-shadow — they were the cause
   of the visible bottom edge. Image now flush-bottom against .journal-hero
   above. */
.journal-hero-image-band {
  margin: 0;
  background: var(--sandstone);
  display: flex;
  justify-content: center;
  padding: 0;
}
.journal-hero-image-band img {
  display: block;
  width: 100%;
  max-width: 720px;
  height: auto;
}

/* 6b.6d (2026-04-30) — journal listing card thumbnails. Per founder direction
   "you should have a picture of the hero in the actual clickable box. And that
   means that all of them should change to that same size as well. With just
   placeholders is fine." Uniform aspect 4:5 (matching the 1080:1350 hero PNGs)
   so live + coming-soon cards have identical dimensions. Live cards use the
   article's hero PNG; coming-soon cards use a Sandstone + pebble-mark
   placeholder via CSS background. */
.journal-card-thumb {
  margin: 0;
  width: 100%;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--sandstone);
  display: block;
}
.journal-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.journal-card-thumb--placeholder {
  background:
    var(--sandstone)
    url('/assets/logomark.svg') center / 30% no-repeat;
  opacity: 0.55;
}
.journal-card-body {
  padding: var(--s-m) var(--s-l) var(--s-l);
}
/* Override journal-card padding when it has a thumb — thumb is full-bleed,
   so card-body owns the padding. Older single-block cards keep their original
   padding via not-:has fallback. */
.journal-card:has(.journal-card-thumb) {
  padding: 0;
  overflow: hidden;
}

.journal-hero {
  background: var(--ink);
  color: #fff;
  padding: var(--s-xxl) var(--s-m) var(--s-xl);
}
.journal-hero-inner {
  max-width: 56ch;
  margin: 0 auto;
}
.journal-meta {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(245, 239, 230, 0.72);
  margin: 0 0 var(--s-m);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}
.journal-meta-category {
  color: var(--sunset);
  font-weight: 700;
}
.journal-meta-pillar {
  font-weight: 600;
}
.journal-hero h1 {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: clamp(1.75rem, 5vw, 2.75rem);
  line-height: 1.15;
  letter-spacing: -0.005em;
  margin: 0 0 var(--s-l);
  color: #fff;
}
.journal-lede {
  font-size: 1.125rem;
  line-height: 1.65;
  margin: 0 0 var(--s-m);
  color: rgba(245, 239, 230, 0.92);
}

.journal-section {
  background: var(--sandstone);
  padding: var(--s-xxl) var(--s-m);
}
.journal-section--science { background: color-mix(in srgb, var(--sky) 8%, var(--sandstone)); }
.journal-section--fix     { background: var(--sandstone); }
.journal-section--programme { background: color-mix(in srgb, var(--marigold) 14%, var(--sandstone)); }
.journal-section-inner {
  max-width: 56ch;
  margin: 0 auto;
}
.journal-section h2 {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: clamp(1.5rem, 4vw, 2rem);
  letter-spacing: -0.005em;
  color: var(--sunset);
  margin: 0 0 var(--s-m);
}
.journal-section p {
  font-size: 1.0625rem;
  line-height: 1.7;
  margin: 0 0 var(--s-m);
  color: var(--ink);
}

/* 6b.6g (2026-05-01) — .exercise-card is the renderer output (functions/api/
   admin/journal/_render.ts emits <div class="exercise-card"> for exercise-card
   blocks). Mirrors .journal-exercise visual treatment from the hand-coded
   phone-neck article. Founder caught the styling regression: "formatting is
   still wrong - what happened to the styling etc?" — class name mismatch
   left the renderer output unstyled. Style both class names so renderer +
   hand-coded both render identically. Per-card-discipline 4-side Ink border
   per Style Guide §1. */
.exercise-card,
.journal-exercise {
  background: #fff;
  border: 4px solid var(--ink);
  border-radius: 1rem;
  padding: var(--s-l);
  margin: 0 0 var(--s-l);
  box-shadow: 0 1px 0 rgba(31, 36, 40, 0.06);
}
.exercise-card:last-child {
  margin-bottom: 0;
}
.exercise-card-name,
.exercise-card h3 {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 1.25rem;
  color: var(--sunset);
  margin: 0 0 var(--s-s);
}
.exercise-card-description {
  margin: 0 0 var(--s-s);
  font-size: 1rem;
  line-height: 1.6;
}
.exercise-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: var(--s-s) 0 0;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.85rem;
}
.exercise-card-sets,
.exercise-card-reps {
  display: inline-flex;
  align-items: center;
  padding: 0.25rem 0.625rem;
  background: color-mix(in srgb, var(--sunset) 10%, var(--sandstone));
  color: var(--russet);
  border-radius: 999px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.exercise-card-sets::before { content: "Sets: "; opacity: 0.7; margin-right: 0.25rem; }
.exercise-card-reps::before { content: "Reps: "; opacity: 0.7; margin-right: 0.25rem; }

/* legacy hand-coded fallback (kept for any pages still using older block) */
.journal-exercise {
  background: #fff;
  border: 4px solid var(--ink);
  border-radius: 1rem;
  padding: var(--s-l);
  margin: 0 0 var(--s-l);
  box-shadow: 0 1px 0 rgba(31, 36, 40, 0.06);
}
.journal-exercise:last-child {
  margin-bottom: 0;
}
.journal-exercise h3 {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-size: 1.25rem;
  color: var(--sunset);
  margin: 0 0 var(--s-s);
}
.journal-why {
  background: color-mix(in srgb, var(--sunset) 8%, var(--sandstone));
  border-left: 4px solid var(--sunset);
  padding: var(--s-s) var(--s-m);
  margin: var(--s-s) 0 0;
  font-size: 0.9375rem;
  line-height: 1.6;
}
.journal-why strong {
  color: var(--sunset);
}

/* 28v: journal-cta-block wraps button + promise as a single centred
   unit at the bottom of the .journal-section--programme. Founder
   direction: "this bit at the bottom doesn't seem centred to the
   button" — fix is to constrain both children to the same centred
   max-width so they stack as a unified block, not two independently-
   centred elements at different widths. */
.journal-cta-block {
  text-align: center;
  max-width: 48ch;
  margin: var(--s-l) auto 0;
}
.journal-cta-row {
  text-align: center;
  margin: 0 auto var(--s-m);
}
/* 28v: ensure .btn-primary inside a journal section keeps its
   canonical Sunset background + white text. The journal-section--
   programme band has Marigold-tint bg which was making the
   .btn-primary appear washed against it; explicit override keeps
   the button reading as the canonical CTA pill on every page.
   Founder direction: "the actual white text should just stay white
   and ... if you go into any of the other pages [it's the right
   colour]". */
.journal-section .btn-primary,
.journal-cta-row .btn-primary {
  background: var(--sunset);
  color: #fff;
  border: none;
}
.journal-section .btn-primary:hover,
.journal-cta-row .btn-primary:hover {
  background: color-mix(in srgb, var(--sunset) 88%, black);
  color: #fff;
}
.journal-cta-promise {
  font-size: 0.875rem;
  color: var(--stone);
  text-align: center;
  font-style: italic;
  line-height: 1.6;
  max-width: 48ch;
  margin: 0 auto;
}

/* 28v: differentiate byline section from the footer (both were Ink
   bg, blending into one continuous dark band per founder feedback:
   "you've sort of mixed up the last bit, which blends the same
   colour for the background to the footer"). Switch to a warm
   Sandstone tint with Sunset accent — distinct from the footer
   below AND from the Marigold-tint programme section above. */
.journal-byline {
  background: color-mix(in srgb, var(--sunset) 6%, var(--sandstone));
  color: var(--ink);
  padding: var(--s-xl) var(--s-m);
  text-align: center;
}
.journal-byline-inner {
  max-width: 48ch;
  margin: 0 auto;
}
.journal-byline-author {
  font-size: 0.95rem;
  margin: 0 0 var(--s-s);
}
.journal-byline-author strong {
  color: var(--sunset);
}
/* 28v: byline now has light Sandstone-warm bg, so byline text reverts
   to Ink for contrast (was Sandstone-on-Ink rgba). */
.journal-byline-author {
  color: var(--ink);
}
.journal-byline-share {
  color: var(--ink);
  font-size: 0.95rem;
  line-height: 1.6;
  margin: 0;
}
.journal-byline-share a {
  color: var(--sunset);
  text-decoration: underline;
}
.journal-byline-share a:hover { text-decoration: none; }


/* ============================================================
   28t (2026-04-29) — Section heading icons (Batch 6).
   Founder direction 2026-04-29 (after prowess.qodeinteractive.com
   review): "I want the prowess style. But, according to our
   brand. Just the use of items that I like more than anything"
   + earlier: "I thought you were going to do icons elaborating
   the headings yesterday."

   Pattern reuses the §3 mask-image recolour from METHODOLOGIES
   §3 (pillar icons, 28n) — single Lucide SVG file, recoloured at
   render time via background-color: currentColor on a masked
   element. Single file serves every surface; colour comes from
   parent context.

   Restrained per brand: used on the most prominent recurring
   section H2s only (mission, values, evidence, audience,
   programmes, pricing, journal, roadmap), not every H2 sitewide.
   Future rounds may extend coverage; this round keeps it tight.
   ============================================================ */

.heading-icon {
  display: inline-flex;
  vertical-align: middle;
  align-items: center;
  justify-content: center;
  width: 1.1em;
  height: 1.1em;
  margin-right: 0.55em;
  margin-bottom: 0.08em;   /* nudge baseline alignment with Georgia caps */
  background-color: currentColor;
  -webkit-mask-image: var(--heading-icon-url, none);
          mask-image: var(--heading-icon-url, none);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-size: contain;
          mask-size: contain;
  -webkit-mask-position: center;
          mask-position: center;
  flex-shrink: 0;
}

/* Per-icon URL set via data-icon attribute on the span. The colour
   comes from the parent H2's `color` (which inherits from the
   surrounding section — Sunset on .why bands, Ink on Sandstone
   bands, etc.). */
.heading-icon[data-icon="compass"]         { --heading-icon-url: url('/assets/section-icons/compass.svg?v=2026-04-30j'); }
.heading-icon[data-icon="heart-handshake"] { --heading-icon-url: url('/assets/section-icons/heart-handshake.svg?v=2026-04-30j'); }
.heading-icon[data-icon="microscope"]      { --heading-icon-url: url('/assets/section-icons/microscope.svg?v=2026-04-30j'); }
.heading-icon[data-icon="users"]           { --heading-icon-url: url('/assets/section-icons/users.svg?v=2026-04-30j'); }
.heading-icon[data-icon="tag"]             { --heading-icon-url: url('/assets/section-icons/tag.svg?v=2026-04-30j'); }
.heading-icon[data-icon="book-open"]       { --heading-icon-url: url('/assets/section-icons/book-open.svg?v=2026-04-30j'); }
.heading-icon[data-icon="map"]             { --heading-icon-url: url('/assets/section-icons/map.svg?v=2026-04-30j'); }
.heading-icon[data-icon="sparkles"]        { --heading-icon-url: url('/assets/section-icons/sparkles.svg?v=2026-04-30j'); }

/* On centred-text bands (e.g. .pillars-band .pillars-title), keep
   the icon left of the heading even when text-align:center. */
.pillars-title .heading-icon,
.evidence-title .heading-icon,
.why-title .heading-icon {
  margin-right: 0.5em;
}

/* ============== M-073 P1: Hormozi value-equation patches ==============
   Three new patterns added 2026-05-01: hero-instant strip, value-stack
   section, risk-reversal section. Sit alongside existing .how / .evidence
   / .why / .cta-tail rhythm — same container width, same vertical
   padding, same Sandstone vs white background alternation. Per
   docs/decisions/2026-05-01-website-hormozi-pass.md and the brand-
   consistency sweep — Sthira voice (calm, gratitude-anchored,
   evidence-led), no manufactured urgency, no fabricated dollar values. */

/* P1.A — hero-instant offer strip. Sits between the form and the
   pre-existing whisper, with stronger weight than .whisper but
   calmer than .hero-headline. Names the immediate-gratification
   deliverable so the visitor's "what do I get for joining?" question
   is answered AT the form. */
.hero-instant {
  font-size: 1rem;
  color: var(--ink);
  margin-top: var(--s-m);
  max-width: 48ch;
  margin-left: auto;
  margin-right: auto;
  line-height: 1.55;
}
.hero-instant strong {
  display: block;
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ink);
  margin-bottom: 0.15rem;
}

/* P1.B — value-stack section. White background to break from
   Sandstone hero before the Sandstone problem section. Numbered
   list with hairline cards, similar in rhythm to .how-step but more
   vertical density (visitors can scan 4 items in one breath). */
.value-stack {
  background: #fff;
  padding: var(--s-xxl) var(--s-m);
}
.value-stack-inner {
  max-width: var(--container);
  margin: 0 auto;
}
.value-stack-title {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  color: var(--ink);
  text-align: center;
  margin: 0 auto var(--s-s);
  letter-spacing: -0.005em;
  max-width: 24ch;
}
.value-stack-lede {
  font-size: 1.05rem;
  color: var(--ink);
  line-height: 1.55;
  text-align: center;
  margin: 0 auto var(--s-l);
  max-width: 58ch;
}
.value-stack-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--s-m);
  max-width: 56ch;
  margin-left: auto;
  margin-right: auto;
  counter-reset: value-stack;
}
.value-stack-item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s-m);
  align-items: start;
  padding: var(--s-m) var(--s-l);
  background: var(--sandstone);
  border: 1.5px solid rgba(31, 36, 40, 0.10);
  border-radius: 12px;
}
.value-stack-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 999px;
  background: var(--sunset);
  color: #fff;
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: 1.05rem;
  flex-shrink: 0;
}
.value-stack-body h3 {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--ink);
  margin: 0 0 0.35rem;
  line-height: 1.3;
}
.value-stack-body p {
  font-size: 0.98rem;
  color: var(--ink);
  margin: 0;
  line-height: 1.55;
}

/* P1.C — risk-reversal section. Sandstone background (matches .why
   rhythm), six bulleted promises with bold lead phrase + plain
   continuation. No checkmarks — each bullet is a self-contained
   sentence-promise, not a feature list. */
.risk-reversal {
  background: var(--sandstone);
  padding: var(--s-xxl) var(--s-m);
}
.risk-reversal-inner {
  max-width: 60ch;
  margin: 0 auto;
}
.risk-reversal-title {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  color: var(--ink);
  text-align: center;
  margin: 0 auto var(--s-s);
  letter-spacing: -0.005em;
}
.risk-reversal-lede {
  font-size: 1.05rem;
  color: var(--ink);
  line-height: 1.55;
  text-align: center;
  margin: 0 auto var(--s-l);
  max-width: 56ch;
}
.risk-reversal-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--s-s);
}
.risk-reversal-list li {
  font-size: 1rem;
  color: var(--ink);
  line-height: 1.6;
  padding: var(--s-s) var(--s-m);
  background: #fff;
  border: 1.5px solid rgba(31, 36, 40, 0.10);
  border-radius: 10px;
}
.risk-reversal-list li strong {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  color: var(--ink);
}

/* ============== M-073 P1: Annual refund pledge panel ==============
   Founder direction 2026-05-01: lock the annual-only refund pledge in
   source NOW so it's held in the codebase before launch traffic hits.
   Sits on /pricing.html after the 3-tier grid. White card on Sandstone
   bg (matches .why rhythm). Sthira voice — quiet promise, not a
   money-back guarantee. Russet eyebrow chip + Georgia title + Arial
   bullet list + tail-clarification line. */
.refund-pledge {
  background: var(--sandstone);
  padding: var(--s-xxl) var(--s-m);
}
.refund-pledge-inner {
  max-width: 840px;
  margin: 0 auto;
  background: #fff;
  border: 1.5px solid rgba(31, 36, 40, 0.10);
  border-radius: 12px;
  padding: var(--s-l);
}
.refund-pledge-eyebrow {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--russet);
  margin: 0 0 0.4rem;
}
.refund-pledge-inner h2 {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(1.4rem, 3vw, 1.85rem);
  color: var(--ink);
  margin: 0 0 0.65rem;
  letter-spacing: -0.005em;
  line-height: 1.3;
}
.refund-pledge-lede {
  font-size: 1rem;
  color: var(--ink);
  line-height: 1.55;
  margin: 0 0 var(--s-m);
}
.refund-pledge-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--s-m);
  display: grid;
  gap: var(--s-s);
}
.refund-pledge-list li {
  font-size: 0.98rem;
  color: var(--ink);
  line-height: 1.6;
  padding: var(--s-s) var(--s-m);
  background: var(--sandstone);
  border: 1.5px solid rgba(31, 36, 40, 0.10);
  border-radius: 10px;
}
.refund-pledge-list li strong {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  color: var(--ink);
}
.refund-pledge-list li a {
  color: var(--russet);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.refund-pledge-list li a:hover { color: var(--sunset); }
.refund-pledge-tail {
  font-size: 0.92rem;
  color: var(--stone);
  line-height: 1.55;
  margin: 0;
}

/* ============== M-073 P1 expanded: Kern K1 + K5 + Kennedy DK1 ==============
   Try-this-right-now (Kern Results In Advance), worst-case-named lead
   (Kern), and quantified-equivalent line on value stack (Kennedy). All
   bound to the canonical Sthira Me Marketing Methodology 1.0 doc that
   locks the Hormozi+Kern+Kennedy synthesis as the canonical lever set
   for ALL future marketing. Sthira voice (calm, specific, no shout). */

/* Kern K1 — Try this right now. Sandstone bg (matches .why rhythm),
   numbered ordered list with Sunset numerals, italic eyebrow above
   the title to signal "before you sign up". Sits between hero and
   value-stack so the visitor can act, not just read. */
.try-now {
  background: var(--sandstone);
  padding: var(--s-xxl) var(--s-m);
}
.try-now-inner {
  max-width: 60ch;
  margin: 0 auto;
}
.try-now-eyebrow {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 1.05rem;
  color: var(--russet);
  text-align: center;
  margin: 0 auto 0.4rem;
}
.try-now-title {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  color: var(--ink);
  text-align: center;
  letter-spacing: -0.005em;
  margin: 0 auto var(--s-l);
}
.try-now-steps {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--s-l);
  display: grid;
  gap: var(--s-s);
}
.try-now-steps li {
  display: grid;
  grid-template-columns: 2.25rem 1fr;
  gap: var(--s-m);
  align-items: start;
  padding: var(--s-s) var(--s-m);
  background: #fff;
  border: 1.5px solid rgba(31, 36, 40, 0.10);
  border-radius: 10px;
  font-size: 1.02rem;
  color: var(--ink);
  line-height: 1.55;
}
.try-now-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 999px;
  background: var(--sunset);
  color: #fff;
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: 1.05rem;
  flex-shrink: 0;
}
.try-now-step-body {
  align-self: center;
}
.try-now-tail {
  font-size: 1rem;
  color: var(--ink);
  line-height: 1.6;
  margin: 0;
  text-align: center;
  max-width: 56ch;
  margin-left: auto;
  margin-right: auto;
}

/* Kern K5 — worst-case-named paragraph inside .risk-reversal. Tighter
   line-height than the bullet cards so it reads as the "headline
   answer" the bullets then expand. Sandstone-on-sandstone with a
   strong opening sentence. */
.risk-reversal-worst-case {
  font-size: 1.02rem;
  color: var(--ink);
  line-height: 1.6;
  text-align: center;
  margin: 0 auto var(--s-l);
  max-width: 56ch;
  padding: var(--s-m) var(--s-l);
  background: #fff;
  border: 1.5px solid rgba(31, 36, 40, 0.10);
  border-radius: 12px;
}
.risk-reversal-worst-case strong {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  color: var(--ink);
}

/* Kennedy DK1 — quantified-equivalent line on each value-stack card.
   Sits below the main blurb in the same card, italic + Russet to
   visually separate as "comparison context" not "feature line". */
.value-stack-equiv {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 0.92rem;
  color: var(--russet);
  margin: var(--s-xs) 0 0;
  line-height: 1.55;
}

/* ============== M-090 P2: Marketing Methodology L8/L9/L12 ==============
   Take-Away (self-selection) + Even-If (pre-empt) + Day-1/Week-1/Month-3
   timeline map. Per `Sthira Me Marketing Methodology 1.0.md` §2 canonical
   lever set + §3 voice rules + §10 NEVER-DO list. Sthira voice (calm,
   gratitude-anchored, no shouty bro-talk). Borders: 4-side uniform per
   Brand 3.6 §15 / Style Guide v1.0 §1 (no single-side accents). */

/* L12 — Day-1 / Week-1 / Month-3 timeline map. Sandstone bg (matches
   .why rhythm), ordered list with Sunset "when" markers + cited claims.
   Sits between Problem (cited stats) + Why (Sutra philosophy). */
.timeline {
  background: var(--sandstone);
  padding: var(--s-xxl) var(--s-m);
}
.timeline-inner {
  max-width: 60ch;
  margin: 0 auto;
}
.timeline-eyebrow {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 1.05rem;
  color: var(--russet);
  text-align: center;
  margin: 0 auto 0.4rem;
}
.timeline-title {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  color: var(--ink);
  text-align: center;
  letter-spacing: -0.005em;
  margin: 0 auto var(--s-m);
  max-width: 32ch;
  line-height: 1.25;
}
.timeline-lede {
  font-size: 1rem;
  color: var(--ink);
  line-height: 1.6;
  text-align: center;
  margin: 0 auto var(--s-l);
  max-width: 56ch;
}
.timeline-steps {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--s-m);
}
.timeline-step {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: var(--s-m);
  align-items: start;
  padding: var(--s-m) var(--s-l);
  background: #fff;
  border: 1.5px solid rgba(31, 36, 40, 0.10);
  border-radius: 12px;
}
.timeline-step--horizon {
  background: var(--sandstone);
  border-color: var(--sunset);
  border-width: 2px;
}
.timeline-step-when {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.25rem;
  padding: 0.35rem 0.6rem;
  border-radius: 999px;
  background: var(--sunset);
  color: #fff;
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  text-align: center;
  white-space: nowrap;
}
.timeline-step--horizon .timeline-step-when {
  background: var(--ink);
}
.timeline-step-body h3 {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--ink);
  margin: 0 0 0.4rem;
  line-height: 1.3;
}
.timeline-step-body p {
  font-size: 0.98rem;
  color: var(--ink);
  margin: 0 0 0.4rem;
  line-height: 1.55;
}
.timeline-step-body p:last-child { margin-bottom: 0; }
.timeline-step-cite {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 0.85rem;
  color: var(--stone);
  line-height: 1.5;
}

/* L8 — Take-Away / self-selection panel. White bg (alternates with
   Sandstone Founder section before it). Two-column NOT-FOR + IS-FOR
   reads as a clear filter; mobile collapses to single-column. */
.take-away {
  background: #fff;
  padding: var(--s-xxl) var(--s-m);
}
.take-away-inner {
  max-width: 60ch;
  margin: 0 auto;
}
.take-away-eyebrow {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 1.05rem;
  color: var(--russet);
  text-align: center;
  margin: 0 auto 0.4rem;
}
.take-away-title {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  color: var(--ink);
  text-align: center;
  letter-spacing: -0.005em;
  margin: 0 auto var(--s-l);
}
.take-away-not,
.take-away-is {
  background: var(--sandstone);
  border: 1.5px solid rgba(31, 36, 40, 0.10);
  border-radius: 12px;
  padding: var(--s-m) var(--s-l);
  margin: 0 0 var(--s-m);
}
.take-away-is {
  border-color: var(--sunset);
  border-width: 2px;
  background: #fff;
}
.take-away-not-lead,
.take-away-is-lead {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.05rem;
  color: var(--ink);
  margin: 0 0 var(--s-s);
}
.take-away-is-lead strong { color: var(--sunset); }
.take-away-not ul,
.take-away-is ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.4rem;
}
.take-away-not li,
.take-away-is li {
  font-size: 0.98rem;
  color: var(--ink);
  line-height: 1.55;
  padding-left: 1.4rem;
  position: relative;
}
.take-away-not li::before {
  content: "\2715"; /* × — gentle deny mark */
  position: absolute;
  left: 0;
  top: 0;
  color: var(--stone);
  font-weight: 700;
}
.take-away-is li::before {
  content: "\2713"; /* ✓ — affirm mark */
  position: absolute;
  left: 0;
  top: 0;
  color: var(--sunset);
  font-weight: 700;
}
.take-away-tail {
  font-size: 1rem;
  color: var(--ink);
  line-height: 1.6;
  text-align: center;
  margin: var(--s-m) auto 0;
  max-width: 56ch;
}

/* L9 — Even-If pre-empt panel. Sandstone bg (alternates with white
   take-away before it). Each "even if" stands on its own line; closes
   with the universal-truth line. */
.even-if {
  background: var(--sandstone);
  padding: var(--s-xxl) var(--s-m);
}
.even-if-inner {
  max-width: 60ch;
  margin: 0 auto;
}
.even-if-eyebrow {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 1.05rem;
  color: var(--russet);
  text-align: center;
  margin: 0 auto 0.4rem;
}
.even-if-title {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 700;
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  color: var(--ink);
  text-align: center;
  letter-spacing: -0.005em;
  margin: 0 auto var(--s-l);
  max-width: 28ch;
  line-height: 1.25;
}
.even-if-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--s-l);
  display: grid;
  gap: var(--s-s);
}
.even-if-list li {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 1.02rem;
  color: var(--ink);
  line-height: 1.55;
  padding: var(--s-s) var(--s-m);
  background: #fff;
  border: 1.5px solid rgba(31, 36, 40, 0.10);
  border-radius: 10px;
}
.even-if-tail {
  font-size: 1.05rem;
  color: var(--ink);
  line-height: 1.6;
  text-align: center;
  margin: 0 auto;
  max-width: 56ch;
}

/* ============== M-092 P2 (article-tier): journal L8 + L9 ==============
   Article-specific Take-Away (.journal-section--audience) + Even-If
   (.journal-section--objections) variants of the homepage L8/L9 panels.
   Used on /journal/phone-neck/ as the first journal article to apply
   the Marketing Methodology §2 levers. Pattern carries across the 6
   other planned articles when they ship.

   Voice rules: Sthira voice, gratitude-anchored. The audience section
   includes a medical-honesty caveat (see GP for diagnosed conditions);
   the even-if list closes with a "the body responds" reframe rather
   than a sales close. */

/* L8 — article-tier audience section. Sandstone-on-Sandstone with
   warmer Marigold tint (matches the .journal-section--programme
   rhythm but flipped for "who this is for" framing). */
.journal-section--audience {
  background: color-mix(in srgb, var(--sandstone) 92%, var(--sunset));
}
.journal-section--audience .journal-audience-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--s-m);
  display: grid;
  gap: 0.5rem;
}
.journal-section--audience .journal-audience-list li {
  font-size: 1rem;
  color: var(--ink);
  line-height: 1.6;
  padding-left: 1.4rem;
  position: relative;
}
.journal-section--audience .journal-audience-list li::before {
  content: "\2713";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--sunset);
  font-weight: 700;
}
.journal-audience-not {
  font-size: 0.95rem;
  color: var(--stone);
  font-style: italic;
  line-height: 1.6;
  margin: var(--s-m) 0 0;
  padding: var(--s-s) var(--s-m);
  border-left: 3px solid var(--stone);
  background: rgba(31, 36, 40, 0.04);
  border-radius: 0 8px 8px 0;
}
/* Card discipline note (Brand 3.4 §15): the .journal-audience-not is
   one place a left-only border is intentional — it's a quoted-aside
   stylistic device (think pull-quote indent), not a full card. The
   4-side rule applies to CARDS (visual containers); pull-quotes use
   the indent pattern. Founder confirmed the distinction in the
   2026-04-30 brand-consistency sweep. */

/* L9 — article-tier objections section. White-on-Sandstone for tonal
   contrast with the audience section above + the science section
   that just closed. The italic "Even if" pattern echoes the homepage
   L9 voice. */
.journal-section--objections {
  background: #fff;
  border-top: 1px solid rgba(31, 36, 40, 0.08);
  border-bottom: 1px solid rgba(31, 36, 40, 0.08);
}
.journal-section--objections .journal-evenif-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--s-m);
  display: grid;
  gap: var(--s-s);
}
.journal-section--objections .journal-evenif-list li {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 1.02rem;
  color: var(--ink);
  line-height: 1.55;
  padding: var(--s-s) var(--s-m);
  background: var(--sandstone);
  border: 1.5px solid rgba(31, 36, 40, 0.10);
  border-radius: 10px;
}
.journal-evenif-tail {
  font-size: 1rem;
  color: var(--ink);
  line-height: 1.6;
  margin: 0;
}

/* M-104 B10 / M-114 restyle — Anatomical glossary tooltips.
   Pattern: chip-style term (subtle Sunset-tinted bg + dashed Sunset
   underline), tap-to-popover with Sunset border so it reads against
   any background (light or dark). Per F-041 founder direction +
   M-114 founder catch on consistency + dark-bg contrast.
   V1.0 = text-only popover; V1.1 = with image (M-108 M3 scaffold). */
.glossary-term {
  /* Chip-style — subtle highlight that reads consistently regardless
     of parent context (body paragraph / heading / stat-card / hero copy /
     italic blockquote). M-141 founder catch: terms inherited italic
     when wrapped in <em>/<i> contexts; explicit font-style:normal +
     font-weight:normal forces uniform appearance across all hosts.
     Inline (white-space stays normal so the term wraps cleanly on
     narrow viewports). */
  display: inline;
  background: color-mix(in srgb, var(--sunset) 12%, transparent);
  padding: 0.05rem 0.3rem;
  border-radius: 3px;
  border-bottom: 1.5px dashed var(--sunset);
  color: var(--ink);
  font-style: normal;
  cursor: help;
  position: relative;
  /* Subtle transition for hover state */
  transition: background-color 120ms ease-out;
}

.glossary-term:hover,
.glossary-term:focus,
.glossary-term[aria-expanded="true"] {
  background: color-mix(in srgb, var(--sunset) 22%, transparent);
}

/* Dark-mode safety — when a glossary-term sits on a dark page section
   (or user has system dark mode), keep the chip readable: lift the
   chip bg fill + flip the term text colour to a light tone. The
   prefers-color-scheme media query covers system dark mode; the
   .on-dark class can be added to a parent section for explicit
   dark-bg hosting (e.g. iOS-app-style hero band, future page lifts). */
@media (prefers-color-scheme: dark) {
  .glossary-term {
    color: #fff;
    background: color-mix(in srgb, var(--sunset) 28%, transparent);
  }
}
.on-dark .glossary-term,
[data-bg="dark"] .glossary-term {
  color: #fff;
  background: color-mix(in srgb, var(--sunset) 28%, transparent);
}

.glossary-popover {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 50;
  max-width: 320px;
  min-width: 240px;
  padding: 16px 18px;
  /* M-137 — 4px border to match canonical accent-card weight.
     M-141 founder catch — explicit font-style:normal + font-weight:normal
     on the popover root: when a glossary term sits inside <em>/<i>/
     italic blockquote, the popover is appended as a CHILD of the term
     and was inheriting italic styling. Forcing normal here cascades
     to title + body + image regardless of host context. */
  background: #fff;
  color: var(--ink);
  border: 4px solid var(--sunset);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  font-family: Arial, Helvetica, sans-serif;
  font-style: normal;
  font-weight: normal;
  font-size: 0.9375rem;
  line-height: 1.5;
  display: none;
}

.glossary-term[aria-expanded="true"] .glossary-popover {
  display: block;
}

.glossary-popover::before {
  content: "";
  position: absolute;
  top: -9px;
  left: 16px;
  width: 14px;
  height: 14px;
  background: #fff;
  /* Two-tone arrow: bottom + right faces are Sunset (matches
     popover border); the visible top + left edges are white
     (matches popover bg). Achieved by border-only on two sides.
     M-137 — bumped to 4px to match popover border weight. */
  border-top: 4px solid var(--sunset);
  border-left: 4px solid var(--sunset);
  transform: rotate(45deg);
}

/* M-108 M3 (B10 V1.1) — optional anatomical illustration in the
   popover. Images live at /assets/glossary/<slug>.png (~480x320 PNG,
   transparent bg, line-art style per Brand 3.6 illustration tier).
   Sourced via data-glossary-image attribute on the .glossary-term
   span. When absent, popover stays text-only (V1.0 behaviour). */
.glossary-popover-image {
  display: block;
  width: 100%;
  height: auto;
  max-height: 200px;
  object-fit: contain;
  border-radius: 6px;
  margin: 0 0 10px 0;
  background: rgba(255, 255, 255, 0.08);
}

/* M-141 founder catch — title in ORANGE (Sunset), NORMAL (not italic),
   BOLD. Specificity boost via `.glossary-popover .glossary-popover-term`
   (0,2,0) is required to beat `.practice-hero p { color: inherit }`
   (0,1,1) which was forcing the title to inherit Ink from the
   .glossary-term host span. Same pattern applies for any `<section> p`
   rule that sets `color: inherit` (programmes-hero, journal-hero,
   pricing-hero, etc.). */
.glossary-popover .glossary-popover-term {
  font-family: Georgia, "Times New Roman", serif;
  font-weight: bold;
  font-style: normal;
  font-size: 1.0625rem;
  margin: 0 0 6px 0;
  color: var(--sunset);
}

/* M-114 — body text now Ink (was rgba(255,255,255,0.92)) since the
   popover bg flipped to white.
   M-141 — explicit font-style:normal + font-weight:normal + specificity
   boost via `.glossary-popover .glossary-popover-body` (0,2,0) to beat
   `.<section>-hero p { color: inherit }` rules that would otherwise
   force the body to inherit colour from the host glossary-term parent. */
.glossary-popover .glossary-popover-body {
  margin: 0;
  color: var(--ink);
  font-style: normal;
  font-weight: normal;
}

@media (max-width: 640px) {
  /* M-107 fix (founder catch via iPhone screenshot 2026-05-02 ~00:28):
     bottom-sheet pattern on mobile escapes the parent's coordinate
     system. M-114 update: white-bg + Sunset border (matches new
     desktop style); shadow angled upward since sheet sits at bottom.
     M-137 update: 2px → 4px to match canonical accent-card weight. */
  .glossary-popover {
    position: fixed;
    top: auto;
    bottom: 24px;
    left: 16px;
    right: 16px;
    max-width: none;
    width: auto;
    z-index: 9999;
    background: #fff;
    color: var(--ink);
    border: 4px solid var(--sunset);
    box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.18);
  }
  .glossary-popover::before {
    display: none;
  }
}

/* ============================================================
   M-123 — Programme outcomes section (expected-outcomes after schedule).
   Founder catch 2026-05-02 ~20:38: M-122 Phase F shipped using
   .schedule-day class which gave 9 stacked thick-Sunset-border cards
   on one page. This refactor uses .outcomes-* classes that are
   visually DISTINCT from .schedule-day — supporting-context tone
   (subtle 1.5px Stone border, italic eyebrow, no day-tag pill) so
   readers don't see "another schedule" but rather "what to expect".
   Per feedback_session_card_pattern.md + feedback_card_discipline_full_borders.md.
   ============================================================ */
.outcomes {
  background: var(--sandstone);
  padding: 60px 0;
}
.outcomes-inner {
  max-width: 720px;
  margin: 0 auto;
  padding: 0 24px;
}
.outcomes-title {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.875rem;
  color: var(--ink);
  margin: 0 0 8px 0;
  text-align: center;
}
.outcomes-eyebrow {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 1rem;
  color: var(--stone);
  text-align: center;
  margin: 0 0 32px 0;
}
.outcomes-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.outcomes-list li {
  background: rgba(255, 255, 255, 0.55);
  border: 1.5px solid rgba(107, 107, 107, 0.25); /* subtle Stone tint */
  border-radius: 10px;
  padding: 18px 22px;
}
.outcomes-list h3 {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.125rem;
  color: var(--ink);
  margin: 0 0 6px 0;
  font-weight: 700;
}
.outcomes-list p {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.95rem;
  color: var(--ink);
  margin: 0;
  line-height: 1.55;
}
.outcomes-disclaimer {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 0.85rem;
  color: var(--stone);
  font-style: italic;
  margin: 24px 0 0 0;
  text-align: center;
}
