/* ==========================================================================
   Tara Yog Drishti — ad landing page
   ==========================================================================
   ONE stylesheet, hand-maintained, no build step. Edit it directly.

   This page used to share five stylesheets with the website and have a script
   bundle them; that meant a CSS edit could reach the website but not this page
   (or the reverse) with no error anywhere. Now nothing is shared: this file is
   the whole stylesheet, and the website's files cannot affect this page.

   The cost is duplication — the tokens and the reset also exist under the
   website's assets/. That is the deal independence buys, and it is the right
   deal for a page that runs paid traffic: it must not break because someone
   restyled a card on the website.

   Comments are kept in the shipped file on purpose. Stripping them saves 4.7 KB
   after brotli, which is about 24 ms of a 2-second load on a slow phone — not
   worth reintroducing a build step you have to remember to run.

   Contents
     1. Fonts
     2. Design tokens
     3. Reset, typography, utilities
     4. Reveals, keyframes, reduced motion
     5. Page background
     6. Shell and section furniture
     7. Buttons and chips
     8. Top bar
     9. Hero
    10. Cards
    11. Proof band
    12. Steps
    13. Marquee
    14. Booking CTA panel
    15. Sticky action bar and footer
    16. Curved cuts, lenses and layered cards
    17. Pinned CTA and intent page
    18. Enquiry form and desktop rail
    19. Founder
    20. Video stories
    21. Fallback for engines without color-mix()
    22. Reduced motion

   21 and 22 must stay last: both work by overriding what comes above them.
   New sections go in front of 21.
   ========================================================================== */



/* ==========================================================================
   1. FONTS
   ========================================================================== */

/* ==========================================================================
   Self-hosted webfonts. Built by tools/build-fonts.py — do not hand-edit the
   files in assets/fonts/, regenerate them instead.

   Self-hosting rather than linking Google Fonts saves two third-party DNS + TLS
   round trips on the critical path, and lets the files be cached immutably.
   ========================================================================== */

/* Display face. The variable weight axis covers headings (500) and the large
   figures in the trust bar, stats and prices (600); `opsz` is left to the
   browser so large headings pick up Fraunces' high-contrast display cut. */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("../fonts/fraunces.woff2") format("woff2");
}

/* Italic is only used for accent words inside 500-weight headings, so it ships
   as a single weight. */
@font-face {
  font-family: "Fraunces";
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/fraunces-italic.woff2") format("woff2");
}

/* UI / body face. */
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/manrope.woff2") format("woff2");
}

/* ==========================================================================
   2. DESIGN TOKENS
   ========================================================================== */

/* ==========================================================================
   Tara Yog Drishti — Design tokens
   Palette: warm Himalayan sand + deep forest ink + marigold clay + river teal.
   Every colour, radius, shadow and type step used on the page lives here.
   ========================================================================== */

:root {
  /* --- Surfaces: warm paper, never pure white --------------------------- */
  --sand-50: #fdfbf7;
  --sand-100: #f7f2e9;
  --sand-200: #efe6d7;
  --sand-300: #e2d4bd;
  --sand-400: #cdb997;

  /* --- Ink: deep forest, used for dark sections and all body copy ------- */
  --ink-900: #0f1e19;
  --ink-800: #162c25;
  --ink-700: #1f3d34;
  --ink-600: #2d5247;
  --ink-400: #4f6c62; /* muted body copy: 5.09:1 on the darkest warm surface */
  --ink-300: #8ba39a;

  /* --- Accent: marigold clay (primary CTA + highlights) ----------------- */
  --clay-700: #97430f;
  --clay-600: #a84a15; /* eyebrow / accent text: 5.09:1 on warm surfaces */
  --clay-500: #cd6a24;
  --clay-400: #e08b45;
  --clay-300: #eeb078;
  --clay-100: #f8e6d2;

  /* --- Accent: river teal (secondary, echoes the Ganga photography) ----- */
  --river-700: #16504a;
  --river-600: #1e6960;
  --river-500: #2c8378;
  --river-200: #a9d3cc;
  --river-100: #dcefec;

  /* --- Utility ---------------------------------------------------------- */
  --whatsapp: #25d366;
  --whatsapp-dark: #128c7e;
  --gold: #e2a53c;

  /* --- Semantic roles (light sections) ---------------------------------- */
  --bg: var(--sand-100);
  --bg-raised: #fffdf9;
  --text: var(--ink-800);
  --text-muted: var(--ink-400);
  --text-inverse: var(--sand-100);
  --hairline: color-mix(in srgb, var(--ink-800) 12%, transparent);
  --hairline-strong: color-mix(in srgb, var(--ink-800) 20%, transparent);

  /* --- Radii ------------------------------------------------------------ */
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 24px;
  --r-xl: 32px;
  --r-pill: 999px;

  /* --- Shadows: soft, warm-tinted, layered ------------------------------ */
  --shadow-sm: 0 1px 2px rgba(15, 30, 25, 0.04), 0 2px 8px rgba(15, 30, 25, 0.04);
  --shadow-md: 0 2px 4px rgba(15, 30, 25, 0.04), 0 8px 24px rgba(15, 30, 25, 0.07);
  --shadow-lg: 0 4px 8px rgba(15, 30, 25, 0.05), 0 18px 48px rgba(15, 30, 25, 0.11);
  --shadow-cta: 0 6px 18px color-mix(in srgb, var(--clay-600) 32%, transparent);

  /* --- Type ------------------------------------------------------------- */
  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-body: "Manrope", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  /* No Devanagari webfont: two words are not worth 39 KB, and every target
     platform ships a good default (Nirmala UI, Noto Sans Devanagari). */
  --font-deva: "Nirmala UI", "Noto Sans Devanagari", "Kohinoor Devanagari", serif;

  --t-eyebrow: 0.75rem;
  --t-xs: 0.8125rem;
  --t-sm: 0.9375rem;
  --t-base: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
  --t-lg: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  --t-h4: clamp(1.0625rem, 1rem + 0.4vw, 1.25rem);
  --t-h3: clamp(1.3rem, 1.15rem + 0.7vw, 1.75rem);
  --t-h2: clamp(1.85rem, 1.45rem + 2vw, 3.05rem);
  --t-h1: clamp(2.35rem, 1.7rem + 3.6vw, 4.5rem);
  --t-stat: clamp(2.1rem, 1.6rem + 2.2vw, 3.25rem);

  /* --- Rhythm ----------------------------------------------------------- */
  --gap-xs: 0.5rem;
  --gap-sm: 0.875rem;
  --gap-md: 1.5rem;
  --gap-lg: 2.5rem;
  --gap-xl: 4rem;
  --section-y: clamp(4.5rem, 3rem + 7vw, 8.5rem);
  --shell: 1200px;
  --shell-narrow: 780px;
  --edge: clamp(1.125rem, 0.6rem + 2.4vw, 2.5rem);

  /* Height of the persistent mobile action bar, so content never hides. */
  --bottom-nav-h: 68px;

  /* --- Motion ----------------------------------------------------------- */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  /* Retimed to be quick. These were roughly a third slower, which on a landing
     page reads as the site thinking rather than as polish: the hero's last
     element did not settle for about 940ms after it came into view, and paid
     traffic is deciding whether to stay in about that long. Motion still has
     to be *visible* — under ~150ms an entrance stops reading as movement and
     starts reading as a flicker — so these are shortened, not removed. */
  --dur-fast: 130ms;
  --dur: 220ms;
  --dur-slow: 460ms;
}

/* Dark sections opt in by setting these role tokens rather than restyling. */
.on-ink {
  --bg: var(--ink-900);
  --bg-raised: color-mix(in srgb, var(--ink-800) 88%, var(--river-700));
  --text: var(--sand-100);
  --text-muted: var(--ink-300);
  --hairline: color-mix(in srgb, var(--sand-100) 14%, transparent);
  --hairline-strong: color-mix(in srgb, var(--sand-100) 26%, transparent);
  color: var(--text);
  background-color: var(--bg);
}

/* ==========================================================================
   3. RESET, TYPOGRAPHY, UTILITIES
   ========================================================================== */

/* ==========================================================================
   Reset, document defaults, typography and small utilities.
   ========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchor targets clear the sticky header. */
  scroll-padding-top: 84px;
}

body {
  font-family: var(--font-body);
  font-size: var(--t-base);
  line-height: 1.65;
  color: var(--text);
  background-color: var(--sand-100);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  /* Leave room for the persistent mobile action bar. */
  padding-bottom: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom, 0px));
}

@media (min-width: 900px) {
  body { padding-bottom: 0; }
}

img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
  height: auto;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

button { cursor: pointer; }

/* The UA rule for [hidden] is `display: none` at the lowest specificity, so ANY
   class that sets a display beats it — .field is display:flex, .start__badge is
   inline-flex. Both are toggled by the `hidden` property in JS, and both stayed
   on screen without this. Everything the enquiry form and the thank-you page
   show conditionally depends on it. */
[hidden] { display: none !important; }

a {
  color: inherit;
  text-decoration: none;
}

ul, ol { list-style: none; padding: 0; }

:where(:focus-visible) {
  outline: 2px solid var(--clay-500);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection {
  background: var(--clay-300);
  color: var(--ink-900);
}

/* --- Headings ----------------------------------------------------------- */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.06;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); line-height: 1.16; }
h4 { font-size: var(--t-h4); line-height: 1.25; letter-spacing: -0.012em; }

p { text-wrap: pretty; }

strong { font-weight: 700; }

/* Emphasised word inside a display heading. */
.accent {
  color: var(--clay-600);
  font-style: italic;
}

.on-ink .accent { color: var(--clay-300); }

/* --- Utilities ---------------------------------------------------------- */







.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-size: var(--t-eyebrow);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--clay-600);
}

.on-ink .eyebrow { color: var(--clay-300); }

.eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 1px;
  background: currentColor;
  opacity: 0.55;
}

.lede {
  font-size: var(--t-lg);
  color: var(--text-muted);
  max-width: 56ch;
}








.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  z-index: 200;
  padding: 0.6rem 1rem;
  border-radius: var(--r-sm);
  background: var(--ink-900);
  color: var(--sand-100);
  font-size: var(--t-sm);
  font-weight: 700;
  transform: translateY(-160%);
  transition: transform var(--dur-fast) var(--ease-out);
}

.skip-link:focus-visible { transform: translateY(0); }

/* ==========================================================================
   4. REVEALS, KEYFRAMES, REDUCED MOTION
   ========================================================================== */

/* ==========================================================================
   Scroll reveals, micro-interactions and keyframes.
   Everything here degrades to "already visible" when JS is off, and is
   switched off entirely under prefers-reduced-motion.
   ========================================================================== */

/* --- Scroll reveal -------------------------------------------------------- */
/* The .js class is set by main.js, so no-JS visitors never see hidden copy. */

.js [data-reveal] {
  opacity: 0;
  /* Shorter travel as well as shorter duration: a 22px slide at 620ms and a
     14px slide at 380ms cover the same idea, but the second one is over before
     the reader has finished the first line. */
  transform: translateY(14px);
  transition: opacity 380ms var(--ease-out), transform 380ms var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

.js [data-reveal="left"] { transform: translateX(-16px); }
.js [data-reveal="right"] { transform: translateX(16px); }
.js [data-reveal="scale"] { transform: scale(0.972); }

.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Staggered children: the delay is written by reveal.js as a CSS variable. */
.js [data-reveal-group] > * {
  opacity: 0;
  transform: translateY(13px);
  transition: opacity 340ms var(--ease-out), transform 340ms var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js [data-reveal-group].is-visible > * { opacity: 1; transform: none; }

/* --- Hero parallax ------------------------------------------------------- */
/* nav.js writes --parallax (a px value) on scroll; the transform is GPU-only. */

.lp-hero__media img { transform: translate3d(0, var(--parallax, 0px), 0) scale(1.06); }

/* --- Keyframes ----------------------------------------------------------- */

@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* Opacity only: animating scale would re-rasterise the 70px blur every frame. */


@keyframes pulse-ring {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--whatsapp) 55%, transparent); }
  70% { box-shadow: 0 0 0 14px color-mix(in srgb, var(--whatsapp) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--whatsapp) 0%, transparent); }
}


.wa-float { animation: pulse-ring 2.6s ease-out 3 2s; }







/* --- Reduced motion ------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  .js [data-reveal],
  .js [data-reveal-group] > * {
    opacity: 1 !important;
    transform: none !important;
  }

  .lp-hero__media img { transform: scale(1.02); }
  .marquee__track { animation: none; }
}

/* ==========================================================================
   Ad landing page (/lp/) — "Golden Hour"
   ==========================================================================
   A separate, single-purpose page for paid traffic. It shares the design
   tokens, fonts, reset and reveal keyframes with the main site, but none of
   its layout: no sticky section nav, no rails, no twelve programme cards.
   One scroll, one goal — a WhatsApp conversation.

   Everything the page needs beyond tokens.css / base.css / animations.css
   lives in this one file, so the LP can never be broken by an edit to the
   website's components.
   ========================================================================== */

:root {
  /* Warm "sun" gradient — the one thing this page adds to the palette. It is
     built from existing brand colours so the LP still reads as Tara Yog
     Drishti, just turned up. */
  --sun: linear-gradient(118deg, var(--clay-500) 0%, var(--clay-400) 42%, var(--gold) 100%);
  /* The same warmth, lifted into the range that still passes contrast when it
     is painted onto glyphs instead of behind them. --sun's clay end measures
     3.5:1 on the hero veil; this one holds above 5:1 across the whole ramp. */
  --sun-text: linear-gradient(118deg, var(--clay-300) 0%, var(--gold) 52%, var(--clay-300) 100%);
  --lp-nav-h: 68px;
  --lp-shell: 1240px;

  /* --- Two tokens re-pointed for this page only ---------------------------
     The website's muted greys were measured against flat sand. This page lays a
     drifting colour field behind the same copy, and measured on the composited
     result --ink-400 drops to 3.5:1 and --clay-600 to 3.6:1 where the blooms
     overlap — both under AA. These two are dark enough to hold up over the
     worst tint the background can produce, and are still clearly secondary
     against the ink-800 body copy. */
  --text-muted: #3a544a; /* 4.8:1 over the darkest measured tint, 7.1:1 on sand */
  --clay-600: #8a3c0d;   /* 4.7:1 / 6.7:1 for those same two cases */
}

/* ==========================================================================
   5. BACKGROUND
   The page sits on one fixed, GPU-composited layer: a warm base wash, three
   slowly drifting colour blooms, and a pre-rendered grain tile.

   The blooms are plain radial gradients, never filter: blur() — a radial
   gradient is already a soft falloff, and blur would have to be re-rasterised
   on every frame of the drift. Only transform and opacity animate here, so the
   whole layer stays on the compositor.
   ========================================================================== */

.lp-atmos {
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  overflow: hidden;
  background: linear-gradient(175deg, var(--sand-50) 0%, var(--sand-100) 38%, var(--sand-200) 100%);
}

.lp-atmos__blob {
  position: absolute;
  width: 60rem;
  aspect-ratio: 1;
  border-radius: 50%;
  will-change: transform;
}

.lp-atmos__blob--a {
  top: -22rem;
  left: -16rem;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--clay-300) 30%, transparent) 0%,
    color-mix(in srgb, var(--clay-300) 13%, transparent) 38%,
    transparent 70%);
  animation: lp-drift-a 34s var(--ease-in-out) infinite alternate;
}

.lp-atmos__blob--b {
  top: 28%;
  right: -24rem;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--river-200) 34%, transparent) 0%,
    color-mix(in srgb, var(--river-200) 15%, transparent) 38%,
    transparent 70%);
  animation: lp-drift-b 44s var(--ease-in-out) infinite alternate;
}

.lp-atmos__blob--c {
  bottom: -26rem;
  left: 18%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--gold) 18%, transparent) 0%,
    color-mix(in srgb, var(--gold) 8%, transparent) 40%,
    transparent 70%);
  animation: lp-drift-c 38s var(--ease-in-out) infinite alternate;
}

.lp-atmos__grain {
  position: absolute;
  inset: 0;
  opacity: 0.26;
  background-image: url("../img/grain.png");
  background-repeat: repeat;
  background-size: 64px 64px;
}

@keyframes lp-drift-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(9vw, 6vh, 0) scale(1.14); }
}

@keyframes lp-drift-b {
  from { transform: translate3d(0, 0, 0) scale(1.08); }
  to   { transform: translate3d(-11vw, -8vh, 0) scale(0.94); }
}

@keyframes lp-drift-c {
  from { transform: translate3d(0, 0, 0) scale(0.96); }
  to   { transform: translate3d(7vw, -7vh, 0) scale(1.12); }
}

/* --- Floating decorative glyphs ------------------------------------------
   The "hovering" marks: a lotus, a sprig, a ring and an Om, drifting slowly
   behind the content. Purely decorative, so they are aria-hidden in the HTML
   and never intercept a tap. */

.float {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  color: var(--clay-500);
  opacity: 0.16;
  will-change: transform;
  animation: lp-hover 14s var(--ease-in-out) infinite alternate;
}

.float svg { width: 100%; height: auto; }

.float--slow  { animation-duration: 21s; }
.float--slower { animation-duration: 27s; }
.float--teal  { color: var(--river-500); opacity: 0.2; }
.float--warm  { color: var(--gold); opacity: 0.24; }

.on-ink .float { opacity: 0.13; color: var(--clay-300); }
.on-ink .float--teal { color: var(--river-200); opacity: 0.14; }

/* --- The small marks below the fold -------------------------------------
   Dew drops, petals, a slow chakra. They sit behind everything at very low
   opacity and drift on their own clocks so the page never looks like it is
   pulsing in time with itself. Transform and opacity only — nothing here can
   trigger a layout — and section 21 stops all of it under reduced motion. */

.float--tiny {
  opacity: 0.22;
  animation: lp-drift 19s var(--ease-in-out) infinite alternate;
}

.on-ink .float--tiny { opacity: 0.17; }

/* A second path, so two marks near each other never travel together. */
.float--drift { animation: lp-drift-two 24s var(--ease-in-out) infinite alternate; }

@keyframes lp-drift {
  from { transform: translate3d(0, 0, 0) rotate(-10deg); }
  to   { transform: translate3d(6px, -22px, 0) rotate(12deg); }
}

@keyframes lp-drift-two {
  from { transform: translate3d(0, -6px, 0) rotate(8deg); }
  to   { transform: translate3d(-8px, 18px, 0) rotate(-9deg); }
}

/* The chakra turns rather than drifts: one revolution every two minutes, which
   is slow enough to read as stillness until you look straight at it. */
.float--chakra {
  opacity: 0.1;
  color: var(--gold);
  animation: lp-spin 120s linear infinite;
}

.on-ink .float--chakra { opacity: 0.12; color: var(--clay-300); }

/* --- Falling petals -----------------------------------------------------
   Two narrow columns, one down each edge, so nothing ever drifts across a line
   of text or over the form. The middle of the screen — where everything that
   matters lives — stays completely clear.

   Every petal animates `transform` and `opacity` and nothing else, so the
   compositor handles the whole layer and it never touches layout. Each one
   carries its own --x, --delay, --dur and --drift, which is what stops a dozen
   petals falling in lockstep and reading as a screensaver.

   Hidden entirely under reduced motion: this is decoration, and for anyone who
   asked not to see movement it has no business existing. */

/* Absolute INSIDE a section, not fixed over the page. A fixed layer sits below
   every opaque section background — the hero photograph, the ink proof band —
   so it is painted and then immediately covered. Measured before this changed:
   zero painted pixels anywhere. Inside the section it lands above the
   background and below the copy, which is where the existing drifting marks
   have always been. */
.petal-field {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

.petal {
  position: absolute;
  top: -10%;
  left: var(--x, 6%);
  width: var(--size, 15px);
  height: auto;
  /* Mid-warm on purpose. The layer is FIXED, so a single petal crosses the
     dark hero, the sand sections and the ink proof band during one fall — it
     cannot re-colour itself per section the way .on-ink content does. Light
     clay vanished on sand; dark clay vanished on the hero. This reads on both.
     The soft-light blend does the rest: it lifts the petal on dark ground and
     settles it on light, so neither extreme swallows it. */
  /* Light warm, and NO blend mode. soft-light made these read on both light and
     dark ground, but a blend forces the compositor to re-blend the whole layer
     every frame: measured at 3-4 dropped frames per scroll where everything
     else on this page holds a clean 60fps. A colour that works plainly is worth
     more than one that works cleverly. */
  color: var(--clay-300);
  opacity: 0;
  /* No will-change. It promotes every petal to its own compositor layer, and
     eight extra layers on a low-end phone cost more in memory pressure than
     they save: 7 dropped frames per scroll at 6x CPU with it, 0 without. The
     animation is transform and opacity only, so the compositor handles it
     regardless — will-change was buying a promotion that was already coming. */
  animation: petal-fall var(--dur, 17s) linear var(--delay, 0s) infinite;
}

/* fill is set here, not left to the mark's own fill="currentColor". Inside a
   <use> shadow tree that attribute resolved to the SVG root's default black
   against a near-black hero, so the petals were painting and were simply
   invisible — measured: zero warm pixels in the bounding box. Setting it on the
   svg makes the shadow content inherit the span's colour, which is the point. */
.petal svg {
  width: 100%;
  height: auto;
  display: block;
  fill: currentColor;
  stroke: none;
}

.petal--teal { color: var(--river-200); }
.petal--gold { color: var(--gold); }

/* Falls the height of the viewport and a little past it, swaying as it goes.
   The opacity ramp keeps it from appearing or vanishing abruptly at either
   edge, which is what would give the trick away. */
/* --fall is a LENGTH, never a percentage. A percentage inside translate3d
   resolves against the element's own box — 105% of a 20px petal is 21px — so
   the first version travelled about a finger's width and sat clipped at the top
   of the section. Each field sets its own distance to suit its height. */
@keyframes petal-fall {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg); opacity: 0; }
  10%  { opacity: var(--peak, 0.5); }
  50%  { transform: translate3d(var(--drift, 14px), calc(var(--fall, 100vh) * 0.5), 0) rotate(180deg); }
  90%  { opacity: var(--peak, 0.5); }
  100% { transform: translate3d(calc(var(--drift, 14px) * -0.6), var(--fall, 100vh), 0) rotate(360deg); opacity: 0; }
}

/* On a phone the columns would be most of the screen, so the layer thins out
   and hugs the very edges. */
@media (max-width: 640px) {
  /* A phone has no side column to spare, so half the petals go and the rest
     hug the very edges — something drifting past the form is the last thing
     this page needs.
     
     The blend goes too. Almost the whole first screen here is the dark hero,
     and soft-light has nothing to lift a mid clay against near-black; the
     petals were invisible exactly where they most needed to be seen. They
     paint normally in a light warm tone instead, which reads on the hero and
     stays quiet over the sections below it. */
  .petal {
    --peak: 0.4;
  }

  .petal--teal { color: var(--river-200); }
  .petal--wide { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .petal-field { display: none; }
}

/* On the dark thank-you page they read as embers rather than petals, so they
   are warmer and a touch brighter. */
.start .petal { color: var(--clay-300); }
.start-body .petal--teal { color: var(--river-200); }

/* Om glyph, set as text so it costs no extra request. */
.float--om {
  font-family: var(--font-deva);
  font-size: clamp(4rem, 12vw, 9rem);
  line-height: 1;
  opacity: 0.09;
}

@keyframes lp-hover {
  from { transform: translate3d(0, 0, 0) rotate(-6deg); }
  to   { transform: translate3d(0, -28px, 0) rotate(6deg); }
}

/* ==========================================================================
   6. SHELL + SECTION FURNITURE
   ========================================================================== */

.lp-shell {
  width: 100%;
  max-width: var(--lp-shell);
  margin-inline: auto;
  padding-inline: var(--edge);
  position: relative;
  z-index: 1;
}

.lp-section {
  position: relative;
  padding-block: clamp(4rem, 2.5rem + 6vw, 7rem);
  overflow: clip;
}

/* Dark band. The big radius on the leading edge is what makes the page read as
   stacked layers rather than stacked rectangles. */
.lp-section--ink {
  background: linear-gradient(168deg, var(--ink-900) 0%, var(--ink-800) 58%, var(--ink-700) 100%);
  border-radius: clamp(28px, 5vw, 48px);
  margin-block: clamp(1rem, 3vw, 2rem);
}

.lp-head { max-width: 46rem; margin-bottom: clamp(2rem, 1rem + 3vw, 3.25rem); }
.lp-head > * + * { margin-top: 0.85rem; }
.lp-head--center { margin-inline: auto; text-align: center; }
.lp-head--center .lede { margin-inline: auto; }

/* ==========================================================================
   7. BUTTONS + CHIPS
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  min-height: 52px;
  padding: 0.85rem 1.5rem;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font-size: var(--t-sm);
  font-weight: 700;
  letter-spacing: 0.005em;
  text-align: center;
  cursor: pointer;
  transition:
    transform var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out),
    background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}

.btn svg { width: 1.15em; height: 1.15em; flex: none; }

.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--wa {
  background: var(--whatsapp);
  color: #06301b;
  box-shadow: 0 8px 22px color-mix(in srgb, var(--whatsapp) 38%, transparent);
}

.btn--wa:hover {
  background: color-mix(in srgb, var(--whatsapp) 88%, white);
  box-shadow: 0 12px 28px color-mix(in srgb, var(--whatsapp) 46%, transparent);
}

/* Outline button. On the hero it sits on the photo, so it carries its own
   translucent ink fill rather than relying on the page background. */
.btn--line {
  background: color-mix(in srgb, var(--sand-100) 12%, transparent);
  border-color: color-mix(in srgb, var(--sand-100) 46%, transparent);
  color: var(--sand-100);
}

.btn--line:hover {
  background: color-mix(in srgb, var(--sand-100) 20%, transparent);
  border-color: var(--sand-100);
}

.btn--ink {
  background: var(--ink-800);
  color: var(--sand-100);
  box-shadow: var(--shadow-md);
}

.btn--ink:hover { background: var(--ink-700); }

.btn--block { width: 100%; }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

@media (max-width: 419px) {
  .btn-row--stack { flex-direction: column; align-items: stretch; }
}

/* --- Chips --------------------------------------------------------------- */

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.42rem 0.8rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--hairline-strong);
  background: color-mix(in srgb, var(--bg-raised) 70%, transparent);
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--text);
}

.chip svg { width: 0.95em; height: 0.95em; color: var(--clay-600); flex: none; }
.chip b { font-weight: 800; }

/* On the hero photo the chips need their own dark ground. */
.chip--glass {
  background: rgba(15, 30, 25, 0.42);
  border-color: rgba(247, 242, 233, 0.34);
  color: var(--sand-100);
}

.chip--glass svg { color: var(--gold); }

@media (max-width: 479px) {
  .chip { padding: 0.36rem 0.65rem; font-size: 0.75rem; gap: 0.35em; }
}

/* Scoped to the hero. This drops the third of the three glass chips sitting on
   the hero photograph, where at under 420px they wrapped to a third line and
   pushed the form down the screen. Unscoped, it reached into every other chip
   row on the page and silently deleted one item — the founder's list of styles
   taught simply was not there on a small phone, with no error anywhere. */
@media (max-width: 419px) {
  .lp-hero .chips > li:nth-child(3) { display: none; }
}

.stars { color: var(--gold); letter-spacing: 0.05em; }

/* ==========================================================================
   8. TOP BAR
   Transparent over the hero photo, then an opaque sand bar once the page
   scrolls. nav.js writes .is-stuck.
   ========================================================================== */

.lp-bar {
  position: fixed;
  isolation: isolate;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 60;
  height: var(--lp-nav-h);
  display: flex;
  align-items: center;
  transition: background-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}

/* Before the page scrolls, the bar sits on the top of the hero photo — which
   is pale sky, not dark rock. Without its own ramp the white wordmark and nav
   links drop to about 1.6:1 there. */
.lp-bar::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to bottom,
    rgba(15, 30, 25, 0.78), rgba(15, 30, 25, 0.3) 62%, transparent);
  transition: opacity var(--dur) var(--ease-out);
}

.lp-bar.is-stuck::before { opacity: 0; }

.lp-bar.is-stuck {
  background: color-mix(in srgb, var(--sand-50) 92%, transparent);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  backdrop-filter: blur(16px) saturate(1.3);
  box-shadow: 0 1px 0 var(--hairline-strong), var(--shadow-sm);
}

.lp-bar__inner {
  width: 100%;
  max-width: var(--lp-shell);
  margin-inline: auto;
  padding-inline: var(--edge);
  display: flex;
  align-items: center;
  gap: var(--gap-md);
}

.lp-bar__brand { margin-inline-end: auto; display: flex; align-items: center; }
.lp-bar__brand img { width: 132px; height: auto; }

/* Two logo files: the white one reads on the photo, the colour one on sand. */
.lp-bar__brand .is-light { display: block; }
.lp-bar__brand .is-dark { display: none; }
.lp-bar.is-stuck .lp-bar__brand .is-light { display: none; }
.lp-bar.is-stuck .lp-bar__brand .is-dark { display: block; }

.lp-bar__nav { display: none; gap: 1.5rem; font-size: var(--t-sm); font-weight: 600; }

.lp-bar__nav a { color: var(--sand-100); opacity: 0.86; transition: opacity var(--dur-fast); }
.lp-bar__nav a:hover { opacity: 1; }
.lp-bar.is-stuck .lp-bar__nav a { color: var(--text); }

@media (min-width: 900px) {
  .lp-bar__nav { display: flex; }
}

.lp-bar .btn { min-height: 44px; padding: 0.55rem 1.15rem; font-size: var(--t-xs); }

/* The bar's WhatsApp button is redundant on phones — the sticky action bar at
   the bottom of the screen is always within thumb reach. */
.lp-bar__cta { display: none; }

@media (min-width: 600px) {
  .lp-bar__cta { display: inline-flex; }
}

/* ==========================================================================
   9. HERO
   One cinematic photograph. Full-bleed behind the copy on phones; from 900px
   it bleeds off the right edge with an ink panel carrying the copy on the
   left. The copy is white at every width, so there is a single colour scheme
   to keep legible rather than two.
   ========================================================================== */

.lp-hero {
  position: relative;
  isolation: isolate;
  display: grid;
  align-content: end;
  /* Not a full screen any more, and NOT a fixed height either. The form is the
     first thing this page wants anyone to do, so the hero makes its promise and
     then gets out of the way — sized by its own content, with a floor so the
     photograph still reads as a photograph. A fixed min-height here meant
     shortening the copy moved nothing. */
  min-height: 470px;
  padding-block: calc(var(--lp-nav-h) + 1.25rem) 4rem;
  color: var(--sand-100);
  overflow: clip;
}

.lp-hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}

.lp-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 26%;
}

/* Two stacked veils: a full-frame warm darkening that keeps the photo from
   fighting the type, and a bottom-weighted ink ramp under the copy itself. */
.lp-hero__veil {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    /* Re-tuned when the hero was shortened for the form. The copy block did not
       move, but the hero did — so the same lines now sit higher up as a
       PERCENTAGE of it, and the eyebrow landed on lit hillside instead of on
       ink: measured 3.21:1. The dark end of the ramp is carried further up to
       follow it. Re-measure this if the hero's height changes again; the stops
       are tied to where the copy falls, not to anything about the photograph. */
    linear-gradient(to top,
      color-mix(in srgb, var(--ink-900) 95%, transparent) 0%,
      color-mix(in srgb, var(--ink-900) 93%, transparent) 34%,
      color-mix(in srgb, var(--ink-900) 90%, transparent) 58%,
      color-mix(in srgb, var(--ink-900) 78%, transparent) 72%,
      color-mix(in srgb, var(--ink-900) 40%, transparent) 85%,
      color-mix(in srgb, var(--ink-900) 6%, transparent) 100%),
    /* Sits under the ink ramp, so it warms the shadows and glows where the
       frame is still open. This is what makes the crop read as sunrise rather
       than as a photo someone turned the lights down on. */
    radial-gradient(72% 46% at 82% 6%,
      color-mix(in srgb, var(--gold) 22%, transparent), transparent 72%);
}

.lp-hero__copy { max-width: 34rem; }
.lp-hero__copy > * + * { margin-top: clamp(0.9rem, 0.6rem + 1vw, 1.35rem); }

.lp-hero .eyebrow { color: var(--gold); }

.lp-hero h1 {
  font-size: clamp(2.5rem, 1.9rem + 4.4vw, 4.4rem);
  letter-spacing: -0.03em;
  text-shadow: 0 2px 30px rgba(15, 30, 25, 0.45);
}

.lp-hero h1 .accent {
  color: transparent;
  background-image: var(--sun-text);
  -webkit-background-clip: text;
  background-clip: text;
}

.lp-hero__lede {
  font-size: var(--t-lg);
  color: color-mix(in srgb, var(--sand-100) 88%, transparent);
  max-width: 32rem;
}

.lp-hero__lede b { color: var(--sand-100); font-weight: 700; }

.lp-hero .chips { margin-top: clamp(1.1rem, 0.8rem + 1.5vw, 1.75rem); }

/* Scroll hint: a slim line that runs down and fades, the only ornament that
   points past the fold. */
.lp-hero__hint {
  display: none;
  position: absolute;
  bottom: 1.25rem;
  left: 50%;
  width: 1px;
  height: 3.5rem;
  background: linear-gradient(to bottom, transparent, var(--sand-300));
  opacity: 0.6;
  animation: lp-hint 2.6s var(--ease-in-out) infinite;
}

@keyframes lp-hint {
  0%, 100% { transform: scaleY(0.5); opacity: 0.25; transform-origin: top; }
  50% { transform: scaleY(1); opacity: 0.7; transform-origin: top; }
}

@media (min-width: 900px) {
  .lp-hero {
    align-content: center;
    min-height: 0;
    min-height: min(76svh, 600px);
    padding-block: calc(var(--lp-nav-h) + 2rem) 3rem; /* no action bar here */
  }

  /* The photo stops being a background and becomes the right half of a split.
     Darkening alone left a hard vertical seam where the image began, so the
     image itself is masked away at its leading edge and dissolves into the ink
     panel instead of butting against it. */
  .lp-hero__media {
    inset-inline-start: 38%;
    mask-image: linear-gradient(to right, transparent, #000 26%);
    -webkit-mask-image: linear-gradient(to right, transparent, #000 26%);
  }

  .lp-hero__media img { object-position: 50% 22%; }

  .lp-hero__veil {
    background:
      linear-gradient(to right,
        var(--ink-900) 0%,
        var(--ink-900) 30%,
        color-mix(in srgb, var(--ink-900) 80%, transparent) 43%,
        color-mix(in srgb, var(--ink-900) 32%, transparent) 58%,
        color-mix(in srgb, var(--ink-900) 8%, transparent) 76%,
        transparent 90%),
      linear-gradient(to top, color-mix(in srgb, var(--ink-900) 58%, transparent), transparent 40%),
      radial-gradient(58% 52% at 84% 10%,
        color-mix(in srgb, var(--gold) 22%, transparent), transparent 70%);
  }

  .lp-hero__copy { max-width: 38rem; }

  /* Line up with the copy column rather than the viewport edge. */
  .lp-hero__hint {
    display: block;
    inset-inline-start: max(var(--edge), calc(50% - var(--lp-shell) / 2 + var(--edge)));
  }
}

@media (min-width: 1100px) {
  .lp-hero__media { inset-inline-start: 44%; }
}

/* ==========================================================================
   10. CARDS
   ========================================================================== */

.grid-4 {
  display: grid;
  gap: clamp(0.85rem, 0.5rem + 1.2vw, 1.35rem);
  grid-template-columns: 1fr;
}

@media (min-width: 560px) { .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .grid-4 { grid-template-columns: repeat(4, 1fr); } }

/* Deliberately no backdrop-filter: on a page whose whole background is an
   animated layer, blurring it behind eight cards costs real frames on the
   low-end Android hardware that ad traffic actually arrives on. A translucent
   warm fill over the same background looks the same and composites free. */
.tile {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(1.25rem, 1rem + 1vw, 1.75rem);
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--bg-raised) 82%, transparent);
  box-shadow: var(--shadow-sm);
  transition:
    transform var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out);
}

/* A hairline that lights up along the top edge on hover. */
.tile::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 15%;
  height: 1px;
  background-image: var(--sun);
  transform: scaleX(0);
  transition: transform var(--dur-slow) var(--ease-out);
}

/* Pointer spotlight. lp.js writes --mx/--my; without JS this stays invisible. */
.tile::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0;
  background: radial-gradient(14rem circle at var(--mx, 50%) var(--my, 0%),
    color-mix(in srgb, var(--clay-400) 16%, transparent), transparent 68%);
  transition: opacity var(--dur) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .tile:hover {
    transform: translateY(-6px);
    box-shadow: var(--shadow-lg);
    border-color: color-mix(in srgb, var(--clay-400) 42%, transparent);
  }

  .tile:hover::before { transform: scaleX(1); }
  .tile:hover::after { opacity: 1; }
  .tile:hover .tile__icon { transform: rotate(-8deg) scale(1.08); }
}

.tile__icon {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  margin-bottom: 1rem;
  border-radius: 14px;
  background: color-mix(in srgb, var(--clay-100) 76%, transparent);
  color: var(--clay-700);
  transition: transform var(--dur) var(--ease-out);
}

.tile__icon svg { width: 1.5rem; height: 1.5rem; }

.tile h3 { font-size: var(--t-h4); margin-bottom: 0.5rem; }

.tile p { font-size: var(--t-sm); color: var(--text-muted); }

.on-ink .tile {
  background: color-mix(in srgb, var(--ink-800) 82%, transparent);
  border-color: var(--hairline);
}

.on-ink .tile__icon {
  background: color-mix(in srgb, var(--river-700) 52%, transparent);
  color: var(--clay-300);
}

/* ==========================================================================
   11. PROOF BAND
   ========================================================================== */

.proof {
  display: grid;
  gap: clamp(1.5rem, 1rem + 3vw, 3rem);
}

@media (min-width: 900px) {
  .proof { grid-template-columns: 0.95fr 1.05fr; align-items: center; }
}

/* --- Rating block -------------------------------------------------------- */

.rating {
  display: flex;
  align-items: baseline;
  gap: 0.65rem;
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1;
}

.rating__value { font-size: clamp(3.4rem, 2.4rem + 5vw, 5.5rem); letter-spacing: -0.04em; }

.rating__stars { font-size: clamp(1.1rem, 0.9rem + 1vw, 1.6rem); }

.rating__note { font-family: var(--font-body); font-size: var(--t-sm); font-weight: 500; color: var(--text-muted); }

/* --- Stat strip ---------------------------------------------------------- */

.stat-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
  margin-top: clamp(1.5rem, 1rem + 2vw, 2.25rem);
  padding-top: clamp(1.25rem, 1rem + 1.5vw, 1.75rem);
  border-top: 1px solid var(--hairline);
}

.stat-strip__value {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.6rem, 1.3rem + 1.4vw, 2.3rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--clay-300);
}

.stat-strip__label {
  display: block;
  margin-top: 0.4rem;
  font-size: var(--t-xs);
  color: var(--text-muted);
  text-wrap: balance;
}

/* --- Quotes -------------------------------------------------------------- */

.quotes { display: grid; gap: clamp(0.85rem, 0.5rem + 1vw, 1.25rem); }

.quote {
  position: relative;
  padding: clamp(1.25rem, 1rem + 1vw, 1.6rem);
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--ink-800) 74%, transparent);
  transition: transform var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .quote:hover {
    transform: translateY(-4px);
    border-color: color-mix(in srgb, var(--clay-300) 40%, transparent);
  }
}

.quote__topic {
  display: inline-block;
  margin-bottom: 0.7rem;
  padding: 0.24rem 0.6rem;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--clay-500) 26%, transparent);
  color: var(--clay-300);
  font-size: 0.6875rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.quote p { font-size: var(--t-sm); color: color-mix(in srgb, var(--sand-100) 84%, transparent); }

.quote footer {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  margin-top: 0.9rem;
}

.quote__avatar {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  flex: none;
  border-radius: 50%;
  background-image: var(--sun);
  color: #2b1403;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-sm);
}

.quote__who { font-size: var(--t-xs); line-height: 1.4; }
.quote__who strong { display: block; font-weight: 700; }
.quote__who span { color: var(--text-muted); }

/* --- Photo card ---------------------------------------------------------- */

.shot {
  position: relative;
  border-radius: var(--r-xl);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
}

.shot img { width: 100%; height: 100%; object-fit: cover; }

.shot figcaption {
  position: absolute;
  inset-inline: 0.75rem;
  inset-block-end: 0.75rem;
  padding: 0.7rem 0.95rem;
  border-radius: var(--r-md);
  background: rgba(15, 30, 25, 0.72);
  color: var(--sand-100);
  font-size: var(--t-xs);
  line-height: 1.45;
}

.shot--cap-top figcaption { inset-block-start: 0.75rem; inset-block-end: auto; }

.shot figcaption strong { display: block; font-weight: 700; }
.shot figcaption span { color: var(--sand-300); }

/* ==========================================================================
   12. STEPS + PRICE ROW
   ========================================================================== */

.steps {
  display: grid;
  gap: clamp(0.85rem, 0.5rem + 1vw, 1.25rem);
  counter-reset: step;
}

@media (min-width: 760px) { .steps { grid-template-columns: repeat(3, 1fr); } }

.step {
  position: relative;
  padding: clamp(1.1rem, 0.9rem + 1vw, 1.5rem);
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--bg-raised) 78%, transparent);
}

.step__num {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  margin-bottom: 0.75rem;
  border-radius: 50%;
  background-image: var(--sun);
  color: #2b1403;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-sm);
}

.step h3 { font-size: var(--t-h4); margin-bottom: 0.35rem; }
.step p { font-size: var(--t-sm); color: var(--text-muted); }

/* Stands where the price cards used to. Centred and narrow so it reads as a
   note rather than as a paragraph of body copy. */
.start-note {
  max-width: 46rem;
  margin: clamp(1.5rem, 1rem + 2vw, 2.25rem) auto 0;
  padding: clamp(1rem, 0.85rem + 0.8vw, 1.35rem) clamp(1.1rem, 1rem + 1vw, 1.6rem);
  border-radius: var(--r-lg);
  border: 1px dashed var(--hairline-strong);
  background: color-mix(in srgb, var(--bg-raised) 62%, transparent);
  font-size: var(--t-sm);
  color: var(--text-muted);
  text-align: center;
}

/* ==========================================================================
   13. MARQUEE
   ========================================================================== */

.marquee {
  position: relative;
  overflow: hidden;
  padding-block: 0.9rem;
  border-block: 1px solid var(--hairline);
  /* Fade both ends so the loop never shows a hard cut. */
  mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent);
}

.marquee__track {
  display: flex;
  gap: 2.25rem;
  width: max-content;
  animation: marquee 34s linear infinite;
}

.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--t-sm);
  font-weight: 600;
  white-space: nowrap;
  color: var(--text-muted);
}

.marquee__item svg { width: 0.95em; height: 0.95em; color: var(--clay-600); }

.on-ink .marquee__item svg { color: var(--clay-300); }

/* ==========================================================================
   14. BOOKING CTA PANEL
   ========================================================================== */

.lead {
  display: grid;
  gap: clamp(1.5rem, 1rem + 3vw, 3rem);
  align-items: start;
}

@media (min-width: 900px) { .lead { grid-template-columns: 1fr 1fr; } }

.lead__panel {
  padding: clamp(1.35rem, 1rem + 2vw, 2.25rem);
  border-radius: var(--r-xl);
  border: 1px solid var(--hairline-strong);
  background: linear-gradient(168deg, var(--ink-800), var(--ink-900));
  box-shadow: var(--shadow-lg);
}

.lead__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.3rem 0.75rem;
  margin-bottom: 0.75rem;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--whatsapp) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--whatsapp) 32%, transparent);
  color: var(--whatsapp);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.lead__badge svg { width: 1em; height: 1em; }

.lead__benefits {
  display: grid;
  gap: 0.85rem;
  margin-block: 1rem;
  text-align: start;
}

.lead__benefits li {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
}

.lead__check {
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  flex: none;
  margin-top: 0.15rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--river-500) 24%, transparent);
  color: var(--river-200);
}

.lead__check svg { width: 0.85rem; height: 0.85rem; }

.lead__benefits strong { display: block; font-size: var(--t-sm); color: var(--sand-100); }
.lead__benefits span { display: block; font-size: var(--t-xs); color: var(--text-muted); }

.lead__note { margin-top: 0.75rem; font-size: var(--t-xs); color: var(--text-muted); text-align: center; }

.ticks { display: grid; gap: 0.55rem; margin-top: 1.35rem; }

.ticks li {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-size: var(--t-sm);
  color: var(--text-muted);
}

.ticks svg { width: 1.05em; height: 1.05em; flex: none; margin-top: 0.35em; color: var(--river-500); }

.on-ink .ticks svg { color: var(--river-200); }

/* ==========================================================================
   15. STICKY ACTION BAR + FOOTER
   ========================================================================== */

.actionbar {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem var(--edge) calc(0.6rem + env(safe-area-inset-bottom, 0px));
  background: color-mix(in srgb, var(--sand-50) 97%, transparent);
  border-top: 1px solid var(--hairline);
  box-shadow: 0 -6px 24px rgba(15, 30, 25, 0.1);
}

.actionbar .btn { flex: 1; min-height: 48px; }

.actionbar__call {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  flex: none;
  border-radius: var(--r-pill);
  border: 1px solid var(--hairline-strong);
  color: var(--text);
}

.actionbar__call svg { width: 1.25rem; height: 1.25rem; }

@media (min-width: 900px) {
  .actionbar { display: none; }
}

/* Desktop gets a floating WhatsApp button instead of the bar. */
.wa-float {
  position: fixed;
  inset-block-end: 1.75rem;
  inset-inline-end: 1.75rem;
  z-index: 70;
  display: none;
  place-items: center;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  background: var(--whatsapp);
  color: #06301b;
  box-shadow: 0 10px 30px color-mix(in srgb, var(--whatsapp) 45%, transparent);
  transition: transform var(--dur) var(--ease-out);
}

.wa-float:hover { transform: scale(1.07); }
.wa-float svg { width: 1.75rem; height: 1.75rem; }

@media (min-width: 900px) { .wa-float { display: grid; } }

/* --- Footer -------------------------------------------------------------- */

.lp-footer {
  padding-block: clamp(2rem, 1.5rem + 2vw, 3rem);
  border-top: 1px solid var(--hairline);
  font-size: var(--t-xs);
  color: var(--text-muted);
}

.lp-footer__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
}

.lp-footer img { width: 116px; height: auto; }
.lp-footer__links { margin-inline-start: auto; display: flex; flex-wrap: wrap; gap: 1rem; }
.lp-footer a { font-weight: 600; color: var(--text); }
.lp-footer a:hover { color: var(--clay-600); }

.disclaimer {
  max-width: 62ch;
  margin-top: clamp(1.5rem, 1rem + 2vw, 2.25rem);
  font-size: var(--t-xs);
  line-height: 1.6;
  color: var(--text-muted);
}

/* On the ink band this sits at the very bottom of a 168deg gradient that runs
   ink-900 -> ink-700, so the ground under it is the LIGHTEST part of the
   section — and it got lighter still when the band grew taller. Measured at
   4.46:1 there, just under AA. --ink-300 is the band's own muted tone and
   clears it with room, so the fix is a token swap rather than a new colour. */
.on-ink .disclaimer { color: var(--sand-300); }

/* --- FAQ Section -------------------------------------------------------- */

.faq {
  display: grid;
  gap: 0.85rem;
  max-width: 48rem;
  margin-inline: auto;
  margin-top: clamp(2rem, 1.5rem + 2vw, 3rem);
  text-align: start;
}

.faq__item {
  border-radius: var(--r-lg);
  border: 1px solid var(--hairline-strong);
  background: var(--bg-raised);
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
  overflow: hidden;
}

.faq__item[open] {
  border-color: var(--clay-400);
  box-shadow: var(--shadow-sm);
}

.faq__summary {
  padding: 1.1rem 1.35rem;
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 700;
  font-size: var(--t-sm);
  color: var(--text);
  user-select: none;
}

.faq__summary::-webkit-details-marker { display: none; }

.faq__icon {
  width: 1.25rem;
  height: 1.25rem;
  flex: none;
  color: var(--clay-500);
  transition: transform var(--dur-fast);
}

.faq__item[open] .faq__icon {
  transform: rotate(180deg);
}

.faq__answer {
  padding: 0 1.35rem 1.15rem;
  font-size: var(--t-xs);
  line-height: 1.6;
  color: var(--text-muted);
}

.lp-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 600px;
}

.enq--highlight {
  animation: enq-glow 1.2s var(--ease-out);
}

@keyframes enq-glow {
  0%, 100% { box-shadow: 0 16px 45px rgba(15, 30, 25, 0.16); }
  50% { box-shadow: 0 0 0 4px var(--clay-400), 0 20px 55px rgba(184, 84, 16, 0.35); }
}





/* ==========================================================================
   16. CURVED CUTS, LENSES AND LAYERED CARDS
   ==========================================================================
   Composition ideas taken from a yoga template the client liked, rebuilt in
   this page's own type and palette rather than its cyan-and-lavender one:

     - section boundaries that arc instead of ruling straight across
     - a soft "lens" band sitting behind a row of cards
     - cards that protrude past the block they belong to
     - icons on tinted discs with a halo, alternating warm and cool

   All of it is border-radius and position — no SVG, no extra requests, and
   nothing that animates, so none of it costs a frame.
   ========================================================================== */

/* --- Arc-topped section --------------------------------------------------
   Two 50%-wide elliptical corners meet in the middle, which makes one smooth
   dome across the whole width rather than two visible corner curves. The
   negative margin pulls the dome up over the section above; that section
   carries matching extra bottom padding so nothing is covered. */
.lp-section--arc-top {
  border-start-start-radius: 50% clamp(1.25rem, 3vw, 3.25rem);
  border-start-end-radius: 50% clamp(1.25rem, 3vw, 3.25rem);
  margin-top: calc(clamp(1.25rem, 3vw, 3.25rem) * -1);
  padding-top: clamp(4rem, 2.5rem + 6vw, 7.5rem);
}

.lp-section--arc-bottom {
  border-end-start-radius: 50% clamp(1.25rem, 3vw, 3.25rem);
  border-end-end-radius: 50% clamp(1.25rem, 3vw, 3.25rem);
  padding-bottom: clamp(5rem, 3rem + 8vw, 9rem);
}

/* The ink band no longer needs its own rounded-rectangle treatment: the arcs
   are the shape now. */
.lp-section--ink.lp-section--arc-top { border-radius: 0; }

.lp-section--ink.lp-section--arc-top {
  border-start-start-radius: 50% clamp(1.25rem, 3vw, 3.25rem);
  border-start-end-radius: 50% clamp(1.25rem, 3vw, 3.25rem);
  border-end-start-radius: 50% clamp(1.25rem, 3vw, 3.25rem);
  border-end-end-radius: 50% clamp(1.25rem, 3vw, 3.25rem);
  margin-bottom: calc(clamp(1.25rem, 3vw, 3.25rem) * -1);
  padding-bottom: clamp(5rem, 3rem + 8vw, 9rem);
  position: relative;
  z-index: 1;
}

/* The section that follows an arc-bottomed one has to start underneath it. */
.lp-section--after-arc { padding-top: clamp(4.5rem, 3rem + 6vw, 8rem); }

/* --- Lens band ----------------------------------------------------------
   A full-bleed shape with domed top and bottom, sitting behind a row of
   cards. Bleeds past both edges so the curve never pinches into a point at
   the viewport sides. */
/* Scopes the lens to the row it sits behind. */
.row-lens { position: relative; }

.lens {
  position: absolute;
  inset-block: clamp(-3.25rem, -2vw, -1.75rem);
  inset-inline: -8vw;
  z-index: -1;
  border-radius: 50% / clamp(2.5rem, 7vw, 7rem);
  background: linear-gradient(168deg, var(--river-100) 0%, var(--clay-100) 100%);
  /* A hairline makes the curve legible where the tint alone is too close to the
     page. Without it the band reads as one of the background blooms. */
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--river-500) 12%, transparent);
  pointer-events: none;
}

/* --- Icon discs ---------------------------------------------------------
   A circle with a wider, fainter ring around it. The ring is a box-shadow
   rather than a second element, so it costs nothing and cannot be clipped. */
/* Sitting on the lens band, the cards need to read as lifted off it. */
.lens ~ .grid-4 .tile { background: var(--bg-raised); box-shadow: var(--shadow-md); }

.tile__icon {
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  background: var(--clay-100);
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--clay-300) 26%, transparent);
}

.grid-4 .tile:nth-child(2n) .tile__icon {
  background: var(--river-100);
  color: var(--river-700);
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--river-200) 42%, transparent);
}

/* --- Protruding cards --------------------------------------------------- */

/* Photo card that slides in behind the panel beside it. Kept inside the
   section, never across a section boundary — the sections clip their overflow
   so the decorative glyphs cannot widen the page.
   
   The stacking order is stated on both elements on purpose. Left implicit, the
   photo sat behind the panel only because the reveal animation's `will-change`
   was making each column its own stacking context — and that is removed once
   the animation finishes, at which point the photo would jump in front. */
.shot--offset { position: relative; z-index: 1; }

.lead__panel { position: relative; z-index: 2; }

@media (min-width: 900px) {
  /* No negative margin. At -3.5rem the figure finished 8px under the opaque
     booking panel — 1.3% of the photograph permanently hidden, which read as
     two elements accidentally touching rather than as a layered composition.
     Flush is honest: the whole frame is visible and the panel's own shadow
     still separates them. */
  .shot--offset { margin-inline-end: 0; }
}

/* --- Hand-drawn marks -------------------------------------------------- */
.mark {
  position: absolute;
  z-index: 0;
  color: var(--clay-500);
  opacity: 0.5;
  pointer-events: none;
}

.mark svg { width: 100%; height: auto; }
.on-ink .mark { color: var(--clay-300); opacity: 0.45; }

/* --- Big geometric mark behind a headline ------------------------------- */
.halo {
  position: absolute;
  z-index: -1;
  width: clamp(16rem, 42vw, 30rem);
  aspect-ratio: 1;
  color: var(--sand-100);
  opacity: 0.07;
  pointer-events: none;
}

.halo svg { width: 100%; height: auto; }

@media (prefers-reduced-motion: no-preference) {
  .halo { animation: lp-spin 90s linear infinite; }
}

@keyframes lp-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* ==========================================================================
   17. PINNED CTA (LEFT SIDE) + INTENT PAGE
   ==========================================================================
   Every conversion goes through start/, so that one page view is the number
   this site is measured by. These are the styles for the way in — a card pinned
   bottom-left once the visitor is reading — and for the page itself.
   ========================================================================== */

/* --- Pinned CTA (Left-hand side) -----------------------------------------
   Appears only after the page has scrolled, so it never competes with the top
   bar's own button while the hero is still on screen. nav.js puts .is-scrolled
   on the root element. */
.pin-cta { display: none; }

@media (min-width: 900px) {
  .pin-cta {
    display: flex;
    position: fixed;
    inset-block-end: clamp(1.75rem, 3.5vh, 2.75rem);
    inset-inline-start: clamp(1.25rem, 2.5vw, 2.5rem);
    inset-inline-end: auto;
    inset-block-start: auto;
    z-index: 55;
    align-items: center;
    gap: 0.85rem;
    max-width: 19.5rem;
    padding: 0.85rem 1.2rem;
    border-radius: var(--r-lg);
    border: 1px solid color-mix(in srgb, var(--sand-100) 18%, transparent);
    background: linear-gradient(150deg, var(--ink-800), var(--ink-900));
    box-shadow: 0 10px 32px rgba(15, 30, 25, 0.42), 0 0 0 1px rgba(255, 255, 255, 0.06);
    color: var(--sand-100);
    opacity: 0;
    transform: translateX(-1.25rem);
    pointer-events: none;
    transition:
      opacity var(--dur) var(--ease-out),
      transform var(--dur) var(--ease-out),
      border-color var(--dur) var(--ease-out),
      box-shadow var(--dur) var(--ease-out);
  }

  .is-scrolled .pin-cta {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }

  .pin-cta:hover {
    border-color: color-mix(in srgb, var(--whatsapp) 65%, transparent);
    box-shadow: 0 12px 36px rgba(15, 30, 25, 0.5), 0 0 24px color-mix(in srgb, var(--whatsapp) 32%, transparent);
    transform: translateY(-3px);
  }
}

.pin-cta__mark {
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  flex: none;
  border-radius: 50%;
  background: var(--whatsapp);
  color: #06301b;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--whatsapp) 26%, transparent);
}

.pin-cta__mark svg { width: 1.35rem; height: 1.35rem; }

.pin-cta__text { display: grid; gap: 0.1rem; line-height: 1.35; text-align: start; }
.pin-cta__text strong { font-size: var(--t-sm); font-weight: 700; }
.pin-cta__text span { font-size: var(--t-xs); color: var(--ink-300); }

/* --- Intent page shell (Single Screen, Non-Scrollable) ------------------- */

html.is-thanks,
html.is-ready,
body.start-body {
  height: 100%;
  overflow: hidden;
  padding-bottom: 0;
}

.start {
  position: relative;
  isolation: isolate;
  height: 100vh;
  height: 100svh;
  max-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  padding: clamp(0.65rem, 1.8vh, 1.5rem) var(--edge);
  background: linear-gradient(165deg, var(--ink-900) 0%, var(--ink-800) 54%, var(--ink-700) 100%);
  text-align: center;
  box-sizing: border-box;
}

/* One warm bloom from the top right */
.start::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(58% 46% at 82% 4%,
    color-mix(in srgb, var(--gold) 20%, transparent), transparent 70%);
}

.start__shell {
  width: 100%;
  max-width: 35rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(0.3rem, 1vh, 0.7rem);
  box-sizing: border-box;
}

.halo--start {
  top: clamp(2rem, 10vh, 6rem);
  left: 50%;
  width: clamp(16rem, 50vw, 30rem);
  translate: -50% 0;
  opacity: 0.045;
}

.start__brand img {
  width: clamp(100px, 18vw, 130px);
  height: auto;
}

/* --- Badge -------------------------------------------------------------- */

.start__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.22rem 0.75rem;
  border-radius: var(--r-pill);
  border: 1px solid color-mix(in srgb, var(--whatsapp) 32%, transparent);
  background: color-mix(in srgb, var(--whatsapp) 14%, var(--ink-900));
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--whatsapp);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  box-shadow: 0 2px 10px rgba(37, 211, 102, 0.12);
}

.start__badge-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--whatsapp);
  box-shadow: 0 0 6px var(--whatsapp);
  animation: pulse-dot 2.2s infinite;
}

@keyframes pulse-dot {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.35); opacity: 0.5; }
}

/* --- Copy --------------------------------------------------------------- */

.start__greeting {
  font-family: var(--font-display);
  font-size: var(--t-base);
  font-weight: 500;
  color: var(--clay-300);
}

.start__title {
  font-size: clamp(1.35rem, 1.05rem + 1.8vw, 2.15rem);
  letter-spacing: -0.025em;
  line-height: 1.18;
}

.start__title .accent {
  color: transparent;
  background-image: var(--sun-text);
  -webkit-background-clip: text;
  background-clip: text;
}

.start__lede {
  max-width: 31rem;
  font-size: clamp(0.8125rem, 0.76rem + 0.25vw, 0.9375rem);
  line-height: 1.4;
  color: color-mix(in srgb, var(--sand-100) 84%, transparent);
}

.start__push {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(0.95rem, 0.88rem + 0.4vw, 1.15rem);
  line-height: 1.2;
  color: var(--clay-300);
}

/* --- The arrow and the button ------------------------------------------- */

.start__cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  width: 100%;
}

.arrow {
  width: clamp(3.5rem, 10vw, 4.5rem);
  margin-inline-end: clamp(3.5rem, 12vw, 6rem);
  margin-block-end: -0.35rem;
  color: var(--clay-300);
  opacity: 0.85;
  pointer-events: none;
}

.arrow svg { width: 100%; height: auto; overflow: visible; }

.arrow__tail {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: arrow-draw 0.62s var(--ease-out) 0.2s forwards;
}

.arrow__head {
  opacity: 0;
  animation: arrow-head 0.22s var(--ease-out) 0.78s forwards;
}

.start__cta .arrow { animation: arrow-nudge 2.2s var(--ease-in-out) 1.1s infinite; }

@keyframes arrow-draw { to { stroke-dashoffset: 0; } }
@keyframes arrow-head { to { opacity: 1; } }

@keyframes arrow-nudge {
  0%, 100% { translate: 0 0; }
  50% { translate: 0 4px; }
}

.btn--huge {
  width: 100%;
  max-width: 23rem;
  min-height: 48px;
  padding: 0.75rem 1.4rem;
  font-size: clamp(0.95rem, 0.9rem + 0.25vw, 1.05rem);
  font-weight: 700;
  letter-spacing: -0.005em;
  border-radius: var(--r-pill);
}

.btn--huge svg { width: 1.25em; height: 1.25em; }

@media (prefers-reduced-motion: no-preference) {
  .btn--huge { animation: btn-breathe 3.4s var(--ease-in-out) 0.7s infinite; }
}

.start__alt {
  font-size: 0.75rem;
  color: color-mix(in srgb, var(--sand-100) 72%, transparent);
}

.start__alt a {
  font-weight: 700;
  color: var(--sand-100);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* --- Message preview ---------------------------------------------------- */

.start__peek-card {
  width: 100%;
  max-width: 28rem;
  padding: 0.45rem 0.85rem;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--whatsapp-dark) 20%, var(--ink-900));
  border: 1px solid var(--hairline);
  text-align: start;
}

.start__peek-tag {
  display: block;
  font-size: 0.6875rem;
  font-weight: 700;
  color: var(--whatsapp);
  margin-bottom: 0.12rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.start__preview {
  font-size: 0.8125rem;
  line-height: 1.35;
  color: var(--sand-100);
  white-space: pre-line;
}

/* --- Reassurance and exit ---------------------------------------------- */

.start__assure {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.3rem 0.85rem;
  font-size: 0.72rem;
  color: var(--text-muted);
}

.start__assure li { display: inline-flex; align-items: center; gap: 0.3rem; }
.start__assure svg { width: 0.9em; height: 0.9em; color: var(--river-200); }

.start__back {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--text-muted);
  text-decoration: none;
}

.start__back:hover { color: var(--sand-100); }
.start__back svg { width: 0.95em; height: 0.95em; }

.start__legal { font-size: 0.6875rem; color: var(--ink-300); }

/* ==========================================================================
   18. ENQUIRY FORM + DESKTOP RAIL
   ==========================================================================
   One form element, two homes. On a phone it sits inline in the "How to start"
   section, which is where it is in the HTML. From 1120px up, rail.js moves that
   same node into a panel pinned to the right-hand edge and puts .has-rail on
   <html>; the page then gives up that strip of its width so nothing is ever
   covered by it.

   Keyed to .has-rail rather than to the media query alone, so a browser with no
   JavaScript — which never gets the move — also never gets the empty rail or
   the reserved margin.
   ========================================================================== */

:root {
  --rail-w: clamp(21rem, 26vw, 25rem);
  --rail-gap: clamp(1rem, 1.6vw, 1.75rem);
  /* Total width the page gives up on the right so the pinned card never
     covers a line of copy. The hero is the one section that reclaims it. */
  --rail-column: calc(var(--rail-w) + var(--rail-gap) * 2);

  /* 0 = glass, over the photograph. 1 = solid, once the hero has gone.
     nav.js writes it on scroll; this value is what a browser with no
     JavaScript keeps, and it is the safe one — solid is always readable. */
  --form-veil: 1;
}

/* --- Fields -------------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: 0.35rem; }

.field + .field { margin-top: 0.85rem; }

.field label {
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* "optional" reads as part of the sentence, not as another shouted label.
   0.85 rather than 0.75: at three-quarters it measured 4.48:1 on the glass. */
.field__opt {
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  opacity: 0.85;
}

.field input,
.field select {
  width: 100%;
  min-height: 50px;
  padding: 0.7rem 0.95rem;
  border: 1px solid var(--hairline-strong);
  border-radius: var(--r-md);
  background: var(--bg-raised);
  color: var(--text);
  font-size: var(--t-base);
  transition:
    border-color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

.field input::placeholder { color: var(--text-muted); opacity: 0.72; }

.field select {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235b7a6e' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.95rem center;
  background-size: 1.1rem;
  padding-inline-end: 2.6rem;
}

.field input:focus,
.field select:focus {
  outline: none;
  border-color: var(--clay-500);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--clay-300) 45%, transparent);
}

/* --- Errors -------------------------------------------------------------- */

/* Not the usual #c0392b: measured 6.0:1 on the form's warm card and 4.8:1 on
   the glass version over the photograph, where the softer red came in at
   3.3:1. Validation messages only ever appear when something is already wrong,
   so they are the last text on the page that can afford to be marginal. */
.field input[aria-invalid="true"],
.field select[aria-invalid="true"] { border-color: #99200f; }

/* Keep the error colour on focus instead of half-reverting to the accent. */
.field input[aria-invalid="true"]:focus,
.field select[aria-invalid="true"]:focus {
  border-color: #99200f;
  box-shadow: 0 0 0 3px rgba(179, 36, 26, 0.26);
}

/* No reserved height: an always-present empty line under every field pushes
   the submit button below the fold on a small phone, and these messages are
   announced by role="alert" whether or not space was kept for them. */
.field__error:empty { display: none; }

.field__error {
  margin-top: 0.1rem;
  font-size: var(--t-xs);
  font-weight: 600;
  line-height: 1.4;
  color: #99200f;
}

.field__hint { font-size: var(--t-xs); color: var(--text-muted); }
.field__hint:empty { display: none; }

/* --- The form card ------------------------------------------------------- */

.enq {
  position: relative;
  padding: clamp(1.25rem, 0.9rem + 1.6vw, 1.85rem);
  border-radius: var(--r-xl);
  border: 1px solid var(--hairline-strong);
  background: linear-gradient(168deg, var(--bg-raised), var(--sand-100));
  box-shadow: var(--shadow-lg);
  text-align: start;
}

/* A thin clay edge along the top, the same accent the eyebrows use — enough to
   read as the page's primary action without shouting. */
.enq::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: clamp(1.5rem, 8%, 3rem);
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: linear-gradient(to right, var(--clay-400), var(--gold), var(--river-500));
}

.formhost {
  display: flex;
  justify-content: center;
  /* Its own gutter: it is a direct child of <main> now, not of a .lp-shell. */
  padding-inline: var(--edge);
  /* Pulled up over the hero's lower edge so the top of the card is already on
     screen when the page loads. Someone who lands here should not have to
     wonder whether there is anything below the fold — they can see the form
     starting. */
  margin-block: -3.25rem clamp(1.5rem, 0.9rem + 2.4vw, 2.75rem);
  position: relative;
  z-index: 3;
  /* The bottom action bar's "Book your classes" jumps here. The global
     scroll-padding clears the header but lands the card's top edge tight
     against it; this gives the badge room to breathe. */
  scroll-margin-top: calc(var(--lp-nav-h) + 1rem);
}

/* Inline, the card must not stretch to the full 1200px shell — a name field a
   metre wide reads as a mistake. */
.formhost .enq { width: min(100%, 34rem); }

.has-rail .formhost { display: none; }

/* Off-screen rather than display:none — a hidden input is not submitted, and
   an empty honeypot is the whole signal. */
.enq__pot {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.enq__head { margin-bottom: 1.15rem; }

.enq__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-bottom: 0.7rem;
  padding: 0.28rem 0.7rem;
  border-radius: var(--r-pill);
  border: 1px solid color-mix(in srgb, var(--river-500) 34%, transparent);
  background: color-mix(in srgb, var(--river-500) 12%, transparent);
  color: var(--river-700);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.enq__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--river-500);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--river-500) 24%, transparent);
  animation: pulse-dot 2.4s var(--ease-in-out) infinite;
}

@keyframes pulse-dot {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

/* An h2, because the form is a top-level part of the page now rather than a
   card inside the "How to start" section — going straight from the hero's h1 to
   an h3 skipped a level. Its size is set here, so the change is semantic only. */
.enq__title { font-size: var(--t-h3); margin-bottom: 0.3rem; }

.enq__sub {
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--text-muted);
}

.enq__actions { margin-top: 1.15rem; }

/* One screen matters more than roominess here: at 390px the form has to show
   its heading, its first two fields and its button together, or it reads as
   longer than it is. */
@media (max-width: 560px) {
  /* Clears the permanent action bar. Without it the submit button can come to
     rest directly underneath the bar, which looks like the form is missing its
     button. */
  .formhost { padding-bottom: calc(var(--bottom-nav-h) + 0.5rem); }

  .enq { padding: 1.15rem 1.1rem 1.25rem; }
  .enq__head { margin-bottom: 0.95rem; }
  .enq__sub { font-size: var(--t-xs); }
  .field input, .field select { min-height: 48px; padding-block: 0.6rem; }
  .field + .field { margin-top: 0.7rem; }
}

.enq__submit:disabled {
  opacity: 0.62;
  cursor: progress;
  transform: none;
}

.enq__note {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  margin-top: 0.85rem;
  font-size: var(--t-xs);
  line-height: 1.5;
  color: var(--text-muted);
}

.enq__note svg { width: 1.05em; height: 1.05em; flex: none; margin-top: 0.28em; color: var(--river-500); }

/* Inline — on a phone — the big "Prefer to just talk?" WhatsApp panel sits
   directly above this form, so repeating the same offer at the foot of the card
   reads as an oversight rather than as a second chance. In the rail the panel is
   far away down the page, and there this is the only WhatsApp exit. */
.formhost .enq__alt { display: none; }

.enq__alt {
  margin-top: 0.85rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--hairline);
  font-size: var(--t-xs);
  color: var(--text-muted);
  text-align: center;
}

.enq__alt a {
  font-weight: 700;
  color: var(--river-700);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.enq__alt a:hover { color: var(--clay-700); }

/* --- The primary (non-WhatsApp) button ----------------------------------- */

/* Green is WhatsApp's colour on this page and means "open a chat". The form
   does something different, so it gets the brand's clay instead — the two are
   never mistaken for each other even when they sit in the same card. */
.btn--cta {
  /* Written out rather than built from --clay-500, which measured 4.28:1 under
     this 15px bold label — under AA, and this is the button the whole page is
     for. The light end of this ramp measures 4.9:1 against white. */
  background: linear-gradient(140deg, #b85410, #8f3d0c);
  color: #fff;
  box-shadow: var(--shadow-cta);
}

/* Deepens on hover rather than brightening. The obvious move — a lighter clay —
   takes white text back down to 4.3:1, and a hover state is held long enough to
   have to be readable. The lift and the wider shadow carry the feedback. */
.btn--cta:hover {
  background: linear-gradient(140deg, #a94a0d, #7d340a);
  box-shadow: 0 12px 30px color-mix(in srgb, var(--clay-700) 45%, transparent);
}

/* --- Clearing the way to the form --------------------------------------- */

/* Below the rail breakpoint the form is a scrolling part of the page, sitting
   directly under the hero. Two things were standing between the visitor and it,
   and both have to go for the page to do its one job.
   
   1. A full-width WhatsApp button immediately above the form offered a way to
      convert WITHOUT leaving an email address — which is the single thing the
      form exists to capture. WhatsApp is still one tap away: in the form's own
      footer, and in the action bar. The call button stays, smaller: someone who
      wants to speak to a person now will not fill a form instead. */
@media (max-width: 1119px) {
  /* The hero's primary button scrolls to the form — which, below this width, is
     the very next thing on the page and already partly on screen. It duplicated
     the form's own submit button a few hundred pixels away and pushed the
     fields further down. The call button stays: someone who wants to speak to a
     person now will not fill a form instead. */
  /* The whole row goes. Below this width the form is the very next thing on
     the page and already partly on screen, and the action bar at the foot of
     the window carries both actions permanently — so every button here was a
     third copy of something already in front of the visitor, pushing the form
     further down for nothing. */
  .lp-hero .btn-row { display: none; }


}

/* 2. The action bar's own "Book your classes" scrolls to the form — so while
      the form is on screen it is both redundant and, worse, parked on top of
      the fields being filled in. It drops away and comes back. */
.actionbar {
  transition:
    transform var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out);
}

/* The bar used to drop away while the form was on screen, on the grounds that
   its button pointed at something already visible. That was wrong for this
   page: the CALL half is not a duplicate of anything, and a visitor who has
   scrolled past the form has nothing to act on until they scroll back. It
   stays put now, from the first paint to the last. */

/* --- The rail (Fixed on Right Hand Side) --------------------------------- */

.rail { display: none; }

@media (min-width: 960px) {
  /* A compact, beautiful translucent card pinned to the top right. It stays
     fixed as the user scrolls so it is always instantly available without scrolling. */
  .has-rail .rail {
    display: block;
    position: fixed;
    inset-block-start: calc(var(--lp-nav-h) + 0.75rem);
    inset-inline-end: var(--rail-gap);
    inset-inline-start: auto;
    z-index: 58;
    width: var(--rail-w);
    max-height: calc(100svh - var(--lp-nav-h) - 1.5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .rail__inner { display: block; }

  .has-rail .rail {
    transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                opacity 0.35s ease;
  }

  /* COMPACT, SHORT & TRANSLUCENT IN THE RAIL */
  /* The accent bar is a card's top edge. Pinned, it read as a loose line
     hanging above the badge, so it goes — the card's own border does that job
     here. */
  .has-rail .rail .enq::before { display: none; }

  .has-rail .rail .enq {
    width: 100%;
    padding: 0.95rem 1.15rem 1rem;
    border-radius: var(--r-xl);
    background: rgb(253 251 247 / calc(0.82 + 0.14 * var(--form-veil)));
    -webkit-backdrop-filter: blur(20px) saturate(1.35);
    backdrop-filter: blur(20px) saturate(1.35);
    border: 1px solid rgb(255 255 255 / calc(0.6 - 0.25 * var(--form-veil)));
    box-shadow:
      0 16px 45px rgba(15, 30, 25, calc(0.16 + 0.1 * var(--form-veil))),
      0 2px 6px rgba(15, 30, 25, 0.06),
      inset 0 1px 0 rgb(255 255 255 / 0.65);
    transition: padding 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                box-shadow 0.35s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .has-rail .rail .enq__body {
    max-height: 520px;
    opacity: 1;
    overflow: hidden;
    transition: max-height 0.38s cubic-bezier(0.16, 1, 0.3, 1),
                opacity 0.26s ease,
                margin 0.35s ease;
  }

  .has-rail .rail .enq__head {
    margin-bottom: 0.55rem;
    transition: margin-bottom 0.35s ease;
  }

  .has-rail .rail .enq__badge {
    margin-bottom: 0.3rem;
    padding: 0.18rem 0.55rem;
    font-size: 0.6875rem;
  }
  .has-rail .rail .enq__title {
    font-size: clamp(1.1rem, 1.05rem + 0.3vw, 1.28rem);
    margin-bottom: 0.15rem;
    line-height: 1.25;
  }
  .has-rail .rail .enq__sub {
    display: block;
    font-size: 0.78rem;
    line-height: 1.35;
    margin-bottom: 0.55rem;
    color: var(--text-muted);
  }

  .has-rail .rail .field { gap: 0.22rem; }
  .has-rail .rail .field + .field { margin-top: 0.45rem; }
  .has-rail .rail .field label {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.03em;
  }
  .has-rail .rail .field input,
  .has-rail .rail .field select {
    min-height: 40px;
    padding: 0.4rem 0.75rem;
    font-size: 0.84rem;
    border-radius: var(--r-sm);
    background: rgb(255 255 255 / 0.75);
  }

  .has-rail .rail .enq__actions {
    margin-top: 0.65rem;
  }
  .has-rail .rail .enq__submit {
    min-height: 42px;
    padding: 0.6rem 1.15rem;
    font-size: 0.84rem;
    border-radius: var(--r-pill);
    box-shadow: 0 4px 14px rgba(166, 69, 13, 0.35);
  }

  .has-rail .rail .enq__note {
    margin-top: 0.45rem;
    font-size: 0.6875rem;
    gap: 0.35rem;
    line-height: 1.35;
  }
  .has-rail .rail .enq__alt {
    margin-top: 0.4rem;
    padding-top: 0.4rem;
    font-size: 0.6875rem;
  }

  /* --- COLLAPSED STATE ON SCROLL DOWN ------------------------------------- */
  .has-rail.rail--collapsed .rail {
    cursor: pointer;
    /* Shrink to the label. At the full rail width the collapsed pill kept a
       374px box for a 180px label, which put the badge and the title at
       opposite ends with a gulf between them — and forced the badge to wrap
       onto two lines, so the "pill" was neither pill-shaped nor tidy. */
    width: auto;
    max-width: var(--rail-w);
    overflow: visible;
  }

  .has-rail.rail--collapsed .rail .enq {
    padding: 0.6rem 0.95rem 0.65rem;
    background: rgb(253 251 247 / 0.94);
    box-shadow:
      0 12px 30px rgba(15, 30, 25, 0.22),
      0 0 0 1.5px color-mix(in srgb, var(--clay-500) 45%, transparent);
    transform: translateY(2px);
  }

  .has-rail.rail--collapsed .rail .enq:hover {
    box-shadow:
      0 16px 36px rgba(15, 30, 25, 0.28),
      0 0 0 2px var(--clay-500);
    transform: translateY(0);
  }

  .has-rail.rail--collapsed .rail .enq__head {
    margin-bottom: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
  }

  /* Two labels in a pill this size is one too many, and this is the one that
     can go: the title already says what the card is. It comes straight back
     when the card expands. */
  .has-rail.rail--collapsed .rail .enq__badge { display: none; }

  .has-rail.rail--collapsed .rail .enq__title {
    font-size: 0.875rem;
    margin-bottom: 0;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
  }

  .has-rail.rail--collapsed .rail .enq__title::after {
    content: " ▾";
    font-size: 0.85rem;
    color: var(--clay-500);
  }

  .has-rail.rail--collapsed .rail .enq__sub {
    display: none;
  }

  .has-rail.rail--collapsed .rail .enq__body {
    max-height: 0;
    opacity: 0;
    margin: 0;
    pointer-events: none;
    /* Out of flow, not merely flattened. max-height stops it being TALL but it
       still contributes its intrinsic WIDTH, so the shrink-to-fit pill above
       kept sizing itself to the widest form field and stayed 374px wide for a
       180px label. Absolutely positioned, it contributes nothing. */
    position: absolute;
    visibility: hidden;
    inset-inline: 0;
  }

  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .has-rail .rail .enq { background: rgb(253 251 247 / 0.97); }
    .has-rail .rail .enq__actions { background: rgb(253 251 247 / 0.99); }
  }

  /* The hero copy occupies the left side cleanly leaving the right open for the pinned form */
  .has-rail .lp-hero__copy { max-width: min(100%, 38rem); }

  .has-rail .lp-hero__media {
    inset-inline-start: 28%;
    mask-image: linear-gradient(to right, transparent, #000 20%);
    -webkit-mask-image: linear-gradient(to right, transparent, #000 20%);
  }

  .has-rail .lp-hero__media img { object-position: 32% 22%; }
  .has-rail .rail { scrollbar-width: thin; }

  .has-rail .formhost { display: none; }
  .has-rail .pin-cta { display: none; }
}

/* --- Thank-you page additions -------------------------------------------- */

.start__badge--done {
  border-color: color-mix(in srgb, var(--whatsapp) 42%, transparent);
  background: color-mix(in srgb, var(--whatsapp) 15%, transparent);
  color: var(--whatsapp);
}

.start__badge--done svg { width: 0.95em; height: 0.95em; }

.start__mail {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.9rem;
  border-radius: var(--r-pill);
  border: 1px solid color-mix(in srgb, var(--sand-100) 20%, transparent);
  font-size: var(--t-sm);
  color: var(--sand-200);
}

.start__mail svg { width: 1.05em; height: 1.05em; flex: none; color: var(--clay-300); }

/* ==========================================================================
   19. FOUNDER
   ========================================================================== */

/* The only section on this page with a face in it.

   Everything else here argues from categories — "certified teachers",
   "postgraduate degrees in Yogic Science". True, and completely abstract. This
   is where that becomes one man you could picture arriving at your door, which
   is the actual decision a visitor is making.

   Three frames from one shoot rather than one, at three distances: a still
   portrait, a gesture, and a close one mid-sentence. A single photograph of a
   teacher reads as a headshot. Three read as a class that was happening while
   someone took a picture — and the difference costs 60 KB.
   ========================================================================== */

.founder {
  display: grid;
  gap: clamp(1.75rem, 1rem + 3.5vw, 3.5rem);
  align-items: start;
}

/* 900, not 960: the photo cluster and the copy each still have room at 900,
   and holding the stack together until 960 wastes the widest part of a tablet
   in landscape on one very tall column. */
@media (min-width: 900px) {
  .founder { grid-template-columns: 0.92fr 1.08fr; }
}

/* --- The photographs ----------------------------------------------------- */

.founder__figure { position: relative; }

/* A warm bloom behind the cluster so the arch reads as lit rather than cut
   out of the page. Purely decorative and behind everything. */
.founder__glow {
  position: absolute;
  inset: -10% -6% -4%;
  z-index: 0;
  border-radius: 50%;
  background: radial-gradient(
    58% 48% at 42% 38%,
    color-mix(in srgb, var(--clay-400) 62%, transparent) 0%,
    color-mix(in srgb, var(--clay-300) 26%, transparent) 46%,
    transparent 74%
  );
  filter: blur(34px);
  opacity: 0.55;
  pointer-events: none;
}

/* ONE arrangement at every width — no phone variant.

   There was one: the portrait ran full-bleed with the two squares in a row
   beneath it. It looked like a different composition rather than a smaller one.
   A 352px arch above two 171px squares has no proportion in common with the
   desktop cluster, so the shapes stopped reading as a set and the block looked
   assembled at random. The same grid, scaled, keeps the relationship intact.

   The direction of the sizing matters and is easy to get backwards. The two
   square frames set the row heights; the portrait then STRETCHES to whatever
   the pair comes to. Giving the portrait a fixed 4:5 instead left it short of
   the column beside it, because a grid item with an aspect ratio states its own
   height rather than taking the row's.

   1.6fr is not a taste call either: at that split the height the two squares
   produce lands within ~4% of the portrait's own 4:5 at every width from 320px
   up, so the photograph is shown essentially uncropped on a phone and on a
   desktop alike. */
.founder__stack {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: clamp(0.5rem, 0.35rem + 0.7vw, 0.95rem);
}

.founder__portrait {
  grid-column: 1;
  grid-row: 1 / span 2;
  align-self: stretch;
}

.founder__still { aspect-ratio: 1; }

/* The arch. The two top radii are exactly 50% horizontally, so they meet at
   the centre line and the top edge is one continuous dome instead of two
   corners — and because they sum to exactly 100% the browser never scales the
   whole set down, which is what happens if you reach for a big pixel value.

   38% vertical is measured against the photograph, not chosen: the top of his
   head sits at 24% of the frame, and at the widest point his head reaches the
   dome has already descended to under 2%. Deepening this much past 40 starts
   cutting hair. */
.founder__portrait {
  position: relative;
  overflow: hidden;
  border-radius: 50% 50% var(--r-lg) var(--r-lg) / 38% 38% var(--r-lg) var(--r-lg);
  box-shadow: var(--shadow-lg);
  background: var(--sand-300);
}

.founder__still {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  background: var(--sand-300);
}

.founder__portrait img,
.founder__still img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The name plate. Deliberately NOT backdrop-filtered: a blur here would make
   the section a backdrop root and cost frames on exactly the scroll this page
   was tuned to keep clean, for an effect nobody would name. A flat ink veil
   reads the same and costs nothing. */
.founder__plate {
  position: absolute;
  inset-inline: 0.65rem;
  inset-block-end: 0.65rem;
  padding: 0.7rem 0.95rem;
  border-radius: var(--r-md);
  background: rgba(15, 30, 25, 0.8);
  color: var(--sand-100);
  font-size: var(--t-xs);
  line-height: 1.45;
}

.founder__plate strong {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(0.98rem, 0.9rem + 0.3vw, 1.15rem);
  letter-spacing: -0.01em;
}

.founder__plate span { color: var(--sand-300); }

/* The plate has to shrink with the photograph it sits on.

   Now that the cluster keeps its proportions down to 320px, the portrait is
   ~212px wide on a phone rather than the full 352px it used to have. At the
   desktop type sizes the name wrapped onto three lines and the plate covered
   the middle of the frame — his face included. These sizes are measured to keep
   both lines unwrapped inside the narrowest portrait the grid can produce, so
   the plate stays a caption instead of becoming a banner. */
/* On a phone the plate carries the NAME only.

   Fitting both lines onto a 212px-wide photograph meant taking the second down
   to 10.3px, and this school teaches a lot of people with arthritis, blood
   pressure and back pain — 10px type is the wrong thing to ask of them. The
   line that goes is the redundant one: "M.A. Yogic Science" is stated again in
   the paragraph immediately below and a third time in the chips, both at full
   size, within one screen of scrolling. Nothing is lost and the name gets to be
   legible.

   Scaled continuously rather than stepped, because a single step sized for
   390px still wrapped at 320px where the portrait is only 170px wide — and a
   wrapped plate covered 36% of the photograph. Above 560 both lines return. */
@media (max-width: 559px) {
  .founder__plate {
    inset-inline: 0.4rem;
    inset-block-end: 0.4rem;
    padding: 0.5rem 0.6rem;
    border-radius: var(--r-sm);
  }

  .founder__plate span { display: none; }

  .founder__plate strong {
    /* The floor is 11.2px, not 12: at 320px the name needs 134px and the plate
       offers 138, so 12px wrapped and left "ji" alone on a second line. */
    font-size: clamp(0.7rem, 0.5rem + 1.1vw, 0.95rem);
    line-height: 1.3;
    /* If a narrower viewport or a larger default font size ever does force a
       wrap, break it evenly rather than orphaning the honorific. */
    text-wrap: balance;
  }
}

/* --- The copy ------------------------------------------------------------ */

.founder__copy > * + * { margin-top: clamp(0.8rem, 0.6rem + 0.7vw, 1.1rem); }
.founder__copy p { max-width: 54ch; }
.founder__copy strong { font-weight: 800; }

.founder__deva {
  font-family: var(--font-deva);
  font-size: clamp(1.1rem, 0.95rem + 0.6vw, 1.45rem);
  line-height: 1.4;
  color: var(--clay-600);
}

.founder__lead { font-size: var(--t-lg); }

.founder__chips,
.founder__cta { margin-top: clamp(1.2rem, 0.9rem + 1.2vw, 1.75rem); }

/* ==========================================================================
   20. VIDEO STORIES
   ========================================================================== */

/* A snapping row of portrait cards inside the dark reviews band.

   Portrait, because these are clips people recorded on their phones and a 16:9
   frame would letterbox every one of them into a thin strip with grey above and
   below. 9:16 is the shape the footage already is.

   The rail scrolls rather than wraps: a grid of six videos pushes the form and
   the next call to action off the bottom of the page, and this is supporting
   evidence, not the point of the page. One and a bit cards visible on a phone
   is also the thing that tells you it scrolls, without needing to be told.
   ========================================================================== */

.vstories {
  margin-top: clamp(2rem, 1.5rem + 2.5vw, 3.25rem);
  position: relative;
}

/* Stacked by default, side by side only when there is room. Pushed apart on a
   phone, "In their own words" and "Shared with permission" each wrapped onto
   two lines and interleaved into something that read as one broken sentence. */
.vstories__head {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin-bottom: clamp(1rem, 0.75rem + 1vw, 1.5rem);
}

@media (min-width: 560px) {
  .vstories__head {
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
  }
}

.vstories__head h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--t-h3);
  letter-spacing: -0.01em;
}

.vstories__note { font-size: var(--t-sm); color: var(--text-muted); }

.vstories__rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: clamp(11.5rem, 58vw, 15rem);
  gap: clamp(0.65rem, 0.45rem + 0.8vw, 1rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* The cards have a shadow and a focus ring; without room they are clipped by
     the scroll container on the leading edge. */
  padding: 0.35rem 0.35rem 1rem;
  margin: -0.35rem -0.35rem -1rem;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--sand-100) 30%, transparent) transparent;
  overscroll-behavior-x: contain;
}

.vstories__rail::-webkit-scrollbar { height: 6px; }
.vstories__rail::-webkit-scrollbar-track { background: transparent; }
.vstories__rail::-webkit-scrollbar-thumb {
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--sand-100) 26%, transparent);
}

/* The card is the frame PLUS its caption. Only the frame carries the 9:16 and
   the clipping; putting them on the card itself cropped the name off. */
.vstory {
  scroll-snap-align: start;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.vstory__frame {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--ink-800);
  box-shadow: var(--shadow-md);
}

.vstory__caption {
  display: block;
  padding-inline: 0.15rem;
  min-width: 0;
}

.vstory__name {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(0.9rem, 0.84rem + 0.26vw, 1.05rem);
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--text);
  /* The rail scrolls, so a long name must wrap rather than widen its card and
     break the snap rhythm. */
  overflow-wrap: anywhere;
}

.vstory__about {
  display: block;
  margin-top: 0.12rem;
  font-size: var(--t-xs);
  color: var(--text-muted);
}

.vstory__video,
.vstory__poster {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The whole card is the button. A small play icon floating over a photograph is
   a target people miss on a phone; the card is 180px wide and every pixel of it
   starts the video. */
.vstory__cover {
  position: absolute;
  inset: 0;
  display: block;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  color: var(--sand-100);
  text-align: left;
  font: inherit;
}

/* The scrim. Two stops rather than one: a flat 50% wash over the whole card
   greys out the face, which is the only thing on it worth looking at. */
/* A light wash only. The heavy foot this used to have existed to make an
   overlaid name readable; the name lives below the picture now, so the only job
   left is to keep the white play button from floating on a pale frame. */
.vstory__cover::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(10, 20, 17, 0.4) 0%,
    rgba(10, 20, 17, 0.1) 32%,
    rgba(10, 20, 17, 0.04) 60%,
    rgba(10, 20, 17, 0.18) 100%
  );
}

.vstory__play {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  translate: -50% -50%;
  z-index: 1;
  display: grid;
  place-items: center;
  width: clamp(2.9rem, 2.4rem + 2vw, 3.6rem);
  aspect-ratio: 1;
  border-radius: 50%;
  background: color-mix(in srgb, var(--sand-100) 92%, transparent);
  color: var(--ink-900);
  box-shadow: 0 6px 20px rgba(10, 20, 17, 0.4);
  transition: transform var(--dur) var(--ease-out),
              background var(--dur) var(--ease-out);
}

.vstory__play svg { width: 55%; height: 55%; fill: currentColor; }

.vstory__cover:hover .vstory__play { transform: scale(1.08); }
.vstory__cover:active .vstory__play { transform: scale(0.97); }

.vstory__len {
  position: absolute;
  inset-block-start: 0.6rem;
  inset-inline-end: 0.6rem;
  z-index: 1;
  padding: 0.18rem 0.5rem;
  border-radius: var(--r-pill);
  background: rgba(10, 20, 17, 0.7);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* --- Arrows, for pointers that cannot swipe ------------------------------ */

.vstories__nav {
  display: none;
  gap: 0.5rem;
  justify-content: flex-end;
  margin-top: 0.9rem;
}

@media (hover: hover) and (pointer: fine) {
  .vstories__nav { display: flex; }
}

.vstories__arrow {
  display: grid;
  place-items: center;
  /* 44px, not 40. These only appear for a fine pointer, but the cost of making
     a control comfortably clickable is nothing and the audit is right to ask. */
  width: 2.75rem;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1px solid var(--hairline-strong);
  background: color-mix(in srgb, var(--bg-raised) 26%, transparent);
  color: var(--text);
  cursor: pointer;
  transition: background var(--dur) var(--ease-out), opacity var(--dur) var(--ease-out);
}

.vstories__arrow svg { width: 1.1rem; height: 1.1rem; }
.vstories__arrow--prev svg { rotate: 180deg; }
.vstories__arrow:hover:not(:disabled) {
  background: color-mix(in srgb, var(--bg-raised) 48%, transparent);
}
.vstories__arrow:disabled { opacity: 0.32; cursor: default; }

/* --- Telephone links ----------------------------------------------------- */

/* A tel: link inside a paragraph inherits the line box and ends up ~18px tall.
   On the one page whose job is getting someone to call, that is a target most
   thumbs miss. Padding alone would not help — an inline box ignores vertical
   padding for hit testing — so these are inline-block, which makes the padding
   real. Negative inline margin keeps the sentence spacing unchanged. */
.lead__note a[href^="tel:"],
.enq__alt a[href^="tel:"],
.lp-footer__links a[href^="tel:"] {
  display: inline-block;
  padding-block: 0.7rem;
  margin-block: -0.7rem;
  padding-inline: 0.15rem;
  margin-inline: -0.15rem;
}

/* ==========================================================================
   21. FALLBACK for engines without color-mix() (iOS <= 15, Chrome < 111)
   Without this the translucent fills above resolve to nothing, leaving
   borderless, transparent cards over the animated background.

   This block and the next are deliberately LAST in the file. Both work by
   overriding rules defined above them, so anything appended after them would
   silently escape the fallback and the reduced-motion switch-off. New sections
   go BEFORE this one, as section 18 did.
   ========================================================================== */

@supports not (color: color-mix(in srgb, red, blue)) {
  :root { --hairline: rgba(22, 44, 37, 0.12); --hairline-strong: rgba(22, 44, 37, 0.2); }
  .on-ink { --hairline: rgba(247, 242, 233, 0.14); --hairline-strong: rgba(247, 242, 233, 0.26); }

  /* background-color, never the `background` shorthand: several of these
     elements carry a background-image that survives on its own (the select's
     CSS chevron, the sun-gradient badges), and the shorthand would reset it. */
  .tile, .step, .chip, .start-note { background-color: var(--bg-raised); }
  .on-ink .tile, .quote { background-color: var(--ink-800); }
  .tile__icon { background-color: var(--clay-100); }
  .on-ink .tile__icon { background-color: var(--river-700); }
  .field input, .field select { background-color: var(--bg-raised); }
  .field input:focus, .field select:focus { box-shadow: 0 0 0 3px rgba(238, 176, 120, 0.45); }
  .quote__topic { background-color: var(--clay-700); }
  .lp-bar.is-stuck, .actionbar { background-color: var(--sand-50); }

  /* Must come after the generic .chip rule above, which would otherwise turn
     the pills on the hero photograph near-white under near-white text. */
  .chip--glass { background-color: rgba(15, 30, 25, 0.42); }

  .btn--line { background-color: rgba(247, 242, 233, 0.14); border-color: rgba(247, 242, 233, 0.5); }
  .btn--wa { box-shadow: 0 8px 22px rgba(37, 211, 102, 0.38); }
  .wa-float { box-shadow: 0 10px 30px rgba(37, 211, 102, 0.45); }

  .lp-hero__lede { color: var(--sand-200); }
  .quote p { color: var(--sand-200); }

  /* The atmosphere would otherwise vanish entirely. Same colours, written out. */
  .lp-atmos__blob--a { background: radial-gradient(circle, rgba(238, 176, 120, 0.30) 0%, rgba(238, 176, 120, 0.13) 38%, rgba(238, 176, 120, 0) 70%); }
  .lp-atmos__blob--b { background: radial-gradient(circle, rgba(169, 211, 204, 0.34) 0%, rgba(169, 211, 204, 0.15) 38%, rgba(169, 211, 204, 0) 70%); }
  .lp-atmos__blob--c { background: radial-gradient(circle, rgba(226, 165, 60, 0.18) 0%, rgba(226, 165, 60, 0.08) 40%, rgba(226, 165, 60, 0) 70%); }

  /* The full ramp, not an approximation of it: with a shorter fallback the
     eyebrow and the trust pills sat on bright hillside instead of on ink.
     Gradients end on a zero-alpha version of their own colour rather than on
     `transparent`, which old WebKit interpolates through grey. */
  .lp-hero__veil {
    background:
      linear-gradient(to top,
        rgba(15, 30, 25, 0.95) 0%,
        rgba(15, 30, 25, 0.93) 34%,
        rgba(15, 30, 25, 0.90) 58%,
        rgba(15, 30, 25, 0.78) 72%,
        rgba(15, 30, 25, 0.40) 85%,
        rgba(15, 30, 25, 0.06) 100%),
      radial-gradient(72% 46% at 82% 6%, rgba(226, 165, 60, 0.22), rgba(226, 165, 60, 0) 72%);
  }

  @media (min-width: 900px) {
    .lp-hero__veil {
      background:
        linear-gradient(to right,
          rgb(15, 30, 25) 0%,
          rgb(15, 30, 25) 30%,
          rgba(15, 30, 25, 0.80) 43%,
          rgba(15, 30, 25, 0.32) 58%,
          rgba(15, 30, 25, 0.08) 76%,
          rgba(15, 30, 25, 0) 90%),
        linear-gradient(to top, rgba(15, 30, 25, 0.58), rgba(15, 30, 25, 0) 40%),
        radial-gradient(58% 52% at 84% 10%, rgba(226, 165, 60, 0.22), rgba(226, 165, 60, 0) 70%);
    }
  }

  /* Section 14 decoration. Without these the lens band disappears entirely and
     the icon discs lose their halo ring. */
  .lens { background: linear-gradient(170deg, rgba(220, 239, 236, 0.72), rgba(248, 230, 210, 0.56)); }
  .tile__icon { box-shadow: 0 0 0 6px rgba(238, 176, 120, 0.26); }
  .grid-4 .tile:nth-child(2n) .tile__icon { box-shadow: 0 0 0 6px rgba(169, 211, 204, 0.42); }

  /* Section 18. The form is the one thing on this page that has to work on
     every browser that can reach it, so its card, its badge and its button all
     get written-out colours rather than degrading to transparent. */
  .enq { background-color: var(--bg-raised); }
  .enq__badge { background-color: var(--river-100); border-color: rgba(44, 131, 120, 0.34); }
  .enq__dot { box-shadow: 0 0 0 3px rgba(44, 131, 120, 0.24); }
  .btn--cta { box-shadow: 0 6px 18px rgba(168, 74, 21, 0.32); }
  .btn--cta:hover { box-shadow: 0 12px 30px rgba(151, 67, 15, 0.45); }
  .start__badge--done { background-color: rgba(37, 211, 102, 0.15); border-color: rgba(37, 211, 102, 0.42); }
  .start__mail { border-color: rgba(247, 242, 233, 0.2); }

  /* Section 17. The intent page must never render as dark text on dark. */
  .pin-cta { border-color: rgba(247, 242, 233, 0.16); }
  .start__lede { color: var(--sand-200); }
  .start__preview { background: #123028; }
  .start::before { background: radial-gradient(58% 46% at 82% 4%, rgba(226, 165, 60, 0.2), rgba(226, 165, 60, 0) 70%); }
  .btn--huge { animation: none; box-shadow: 0 10px 30px rgba(37, 211, 102, 0.45); }
  .start__alt { color: var(--sand-200); }
}

/* ==========================================================================
   22. REDUCED MOTION
   Section 4 already kills durations globally; these are the decorative
   layers that should simply not be there at all.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .lp-atmos__blob { animation: none; }
  .float,
  .float--tiny,
  .float--drift,
  .float--chakra { animation: none; }
  .marquee__track { animation: none; }
  .lp-hero__hint { display: none; }

  /* The arrow is the point of the intent page, so it is shown finished rather
     than removed: drawn, head visible, not moving. */
  .arrow__tail { stroke-dashoffset: 0; animation: none; }
  .arrow__head { opacity: 1; animation: none; }
  .start__cta .arrow { animation: none; }
  .halo--start { animation: none; }

  /* Section 18. A blinking dot beside a form is decoration, not information. */
  .enq__dot { animation: none; }
}
