/* ==========================================================================
   Slaney — shared design system
   Tokens taken verbatim from slaney.html. Every page reads from here, so a
   brand change is a one-file change. Don't fork these values into pages.
   ========================================================================== */

:root{
  --bg:#F5F7F6; --surface:#FFFFFF; --ink:#0F1A17; --muted:#56635E; --line:#DCE3E0;
  --accent:#0E7A55; --accent-ink:#FFFFFF; --accent-soft:#E2F2EA;
  --band:#0F1A17; --band-ink:#EAF1EE; --band-muted:#9FB0A9;
  /* The band inverts between modes, so its accent must invert too — the
     page accent on a band background is ~2.6:1 and fails WCAG. */
  --band-accent:#3FC48F;
  /* Darker than --accent on purpose: the eyebrow IS accent-coloured, so an
     accent-tinted background attacks its own contrast. 6.07:1 vs 4.96:1. */
  --eyebrow:#0C6B4A;
  --star:15 26 23; --star-opacity:.55;
  --danger:#C2321F;
  --f-display:"Bricolage Grotesque", "Helvetica Neue", Arial, sans-serif;
  --f-body:"Figtree", system-ui, -apple-system, "Segoe UI", sans-serif;
  --f-mono:"JetBrains Mono", ui-monospace, Menlo, monospace;
  --nav-h:76px;
  --shadow:0 24px 48px -28px rgba(15,26,23,.35)}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]){
  --bg:#0C1311; --surface:#141E1B; --ink:#E8EFEC; --muted:#9AAAA4; --line:#24332E;
  --accent:#3FC48F; --accent-ink:#06120D; --accent-soft:#16302A;
  --band:#E8EFEC; --band-ink:#0F1A17; --band-muted:#4F5E58;
  --band-accent:#0E7A55;
  --eyebrow:#3FC48F;
  --star:232 239 236; --star-opacity:.72;
  --danger:#FF8C7A;
  --shadow:0 24px 48px -28px rgba(0,0,0,.6);
  color-scheme:dark}}
:root[data-theme="dark"]{
  --bg:#0C1311; --surface:#141E1B; --ink:#E8EFEC; --muted:#9AAAA4; --line:#24332E;
  --accent:#3FC48F; --accent-ink:#06120D; --accent-soft:#16302A;
  --band:#E8EFEC; --band-ink:#0F1A17; --band-muted:#4F5E58;
  --band-accent:#0E7A55;
  --eyebrow:#3FC48F;
  --star:232 239 236; --star-opacity:.72;
  --danger:#FF8C7A;
  --shadow:0 24px 48px -28px rgba(0,0,0,.6);
  color-scheme:dark}


/* --- smooth scroll (Lenis) -----------------------------------------------
   These rules ship with Lenis's stylesheet, which we don't load separately.
   The scroll-behavior override matters: our own html{scroll-behavior:smooth}
   would fight Lenis for control of anchor jumps. */
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto!important}
.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain}
.lenis.lenis-stopped{overflow:hidden}
.lenis.lenis-smooth iframe{pointer-events:none}

/* --- base ---------------------------------------------------------------- */
*{box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:calc(var(--nav-h) + 16px)}
body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--f-body);
  font-size:17px;line-height:1.6;-webkit-font-smoothing:antialiased}
.wrap{max-width:1080px;margin:0 auto;
  padding-left:max(16px,env(safe-area-inset-left,0px));
  padding-right:max(16px,env(safe-area-inset-right,0px))}
h1,h2,h3,h4{font-family:var(--f-display);line-height:1.05;margin:0;
  text-wrap:balance;letter-spacing:-.02em}
p{margin:0}
img{max-width:100%;height:auto;display:block}
a{color:inherit}
:focus-visible{outline:3px solid var(--accent);outline-offset:3px;border-radius:4px}

.skip{position:absolute;left:-9999px;top:0;background:var(--accent);
  color:var(--accent-ink);padding:12px 20px;border-radius:0 0 10px 0;
  font-weight:600;text-decoration:none;z-index:200}
.skip:focus{left:0}

/* --- nav ----------------------------------------------------------------- */
.nav{position:fixed;top:0;left:0;right:0;z-index:100;
  background:color-mix(in srgb,var(--bg) 88%,transparent);
  backdrop-filter:saturate(180%) blur(14px);
  border-bottom:1px solid transparent;
  /* Same curve WeMonetise uses (easeOutQuint): fast out, soft landing. */
  transition:transform .5s cubic-bezier(.22,1,.36,1),
             border-color .3s ease, background .3s ease}
.nav.is-stuck{border-bottom-color:var(--line)}
/* Hidden while scrolling down, returns the moment you scroll up. 101% so the
   border edge clears too. */
.nav.is-hidden{transform:translateY(-101%)}
/* The nav is out of flow now, so the page needs its height back. */
body{padding-top:var(--nav-h)}
.nav .wrap{display:flex;align-items:center;justify-content:space-between;
  min-height:var(--nav-h);gap:16px}
.logo{display:inline-flex;align-items:center;gap:8px;font-family:var(--f-display);
  font-weight:800;font-size:28px;letter-spacing:-.04em;text-decoration:none;flex:none}
.tick{width:22px;height:22px;border-radius:50%;background:var(--accent);
  color:var(--accent-ink);display:inline-grid;place-items:center;flex:none}
.tick svg{width:12px;height:12px}

.navlinks{display:flex;gap:22px;align-items:center;font-weight:500;font-size:15px}
.navlinks a{text-decoration:none;color:var(--muted);padding-block:6px;
  border-bottom:2px solid transparent;transition:color .15s ease}
.navlinks a:hover{color:var(--ink)}
.navlinks a[aria-current="page"]{color:var(--ink);border-bottom-color:var(--accent)}
.navlinks .btn{border-bottom:0;padding:10px 18px;font-size:14px;color:var(--accent-ink)}

.navtoggle{display:none;width:44px;height:44px;border:1.5px solid var(--line);
  border-radius:12px;background:transparent;color:var(--ink);cursor:pointer;
  align-items:center;justify-content:center;flex:none}
.navtoggle svg{width:20px;height:20px}
.navtoggle .ic-close{display:none}
.navtoggle[aria-expanded="true"] .ic-close{display:block}
.navtoggle[aria-expanded="true"] .ic-open{display:none}

@media (max-width:860px){
  .navtoggle{display:inline-flex}
  .navlinks{position:fixed;inset:var(--nav-h) 0 auto 0;flex-direction:column;
    align-items:stretch;gap:0;background:var(--surface);
    border-bottom:1px solid var(--line);padding:8px 16px 20px;
    box-shadow:var(--shadow);font-size:17px;display:none}
  .navlinks.is-open{display:flex}
  .navlinks a{padding:15px 4px;border-bottom:1px solid var(--line)}
  .navlinks a[aria-current="page"]{border-bottom-color:var(--line);color:var(--accent)}
  .navlinks .btn{margin-top:16px;justify-content:center;border-bottom:0}
}

/* --- buttons ------------------------------------------------------------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;
  background:var(--accent);color:var(--accent-ink)!important;font-weight:600;
  text-decoration:none;padding:13px 22px;border-radius:999px;font-size:16px;
  border:0;cursor:pointer;font-family:inherit;min-height:44px;
  transition:transform .15s ease,filter .15s ease}
.btn:hover{transform:translateY(-1px);filter:brightness(1.06)}
.btn:active{transform:translateY(0)}
.btn.ghost{background:transparent;color:var(--ink)!important;
  box-shadow:inset 0 0 0 1.5px var(--line)}
.btn.ghost:hover{filter:none;box-shadow:inset 0 0 0 1.5px var(--accent)}
.cta-row{display:flex;flex-wrap:wrap;gap:12px;margin-top:32px}

/* --- section furniture --------------------------------------------------- */
section{padding-block:80px}
.eyebrow{font-family:var(--f-mono);font-size:12px;text-transform:uppercase;
  letter-spacing:.12em;color:var(--eyebrow);margin-bottom:14px}
h2{font-size:clamp(32px,4.6vw,52px);font-weight:700;max-width:18ch}
.sub{margin-top:16px;color:var(--muted);max-width:60ch;font-size:18px}
/* The band carries a generated texture, held back by a scrim so the headline
   keeps its contrast. The scrim is hardcoded to the light-mode band colour
   because the texture only ever shows in light mode — in dark mode the band
   inverts to a pale surface and a dark texture would be wrong on it. */
.band{background:var(--band);color:var(--band-ink);
  background-image:
    linear-gradient(105deg, rgba(15,26,23,.90) 0%, rgba(15,26,23,.74) 45%, rgba(15,26,23,.94) 100%),
    url("../../Media/texture-dark.webp");
  background-size:cover;background-position:center;background-repeat:no-repeat}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .band{background-image:none}}
:root[data-theme="dark"] .band{background-image:none}
.band .sub,.band .list li p span,.band .muted{color:var(--band-muted)}
.band .eyebrow{color:var(--band-accent)}
.band .btn.ghost{color:var(--band-ink)!important;
  box-shadow:inset 0 0 0 1.5px var(--band-muted)}

/* --- founder ------------------------------------------------------------- */
.founder{display:grid;grid-template-columns:1.2fr .8fr;gap:56px;align-items:center}
@media (max-width:820px){.founder{grid-template-columns:1fr;gap:36px}}
.portrait{margin:0;border-radius:18px;overflow:hidden;
  border:1px solid color-mix(in srgb,var(--band-ink) 22%,transparent);
  box-shadow:var(--shadow)}
.portrait img{width:100%;aspect-ratio:4/5;object-fit:cover;object-position:center top}
/* Full-width at 4:5 is overbearing on a phone — cap it and keep it left. */
@media (max-width:820px){.portrait{max-width:360px}}

/* --- ambient background ---------------------------------------------------
   ONE fixed, page-wide layer behind everything — deliberately not per-section.
   An earlier version attached orbs to each <section> with overflow:clip, which
   sliced them at every section boundary and gave each orb a timeline only as
   long as its own section (so a tall section meant ~2000px of scrolling for
   90px of drift, i.e. no visible movement). A single fixed layer has no
   boundaries to cut against and reads the whole document's scroll.

   Orb gradients peak at 16/16/14%. Modelling the three overlapping orbs
   through the 80px blur across the whole scroll puts the real rendered
   maximum at 0.157 — under the ~0.185 ceiling where muted body text drops
   below 4.5:1. Raise these and re-run that check; the blur dilutes far less
   than you would expect, because the orbs are huge relative to it.
   -------------------------------------------------------------------------- */
.ambient-bg{position:fixed;inset:0;z-index:0;pointer-events:none;
  overflow:hidden;contain:strict}
.ambient-bg .orb{position:absolute;border-radius:50%;
  /* Heavy blur on top of an already-soft gradient: kills the banding that
     large low-alpha gradients show on 8-bit displays. */
  filter:blur(58px);will-change:transform}

.orb-1{width:min(86vw,980px);aspect-ratio:1;left:-24vw;top:-26vh;
  background:radial-gradient(closest-side circle,
    color-mix(in srgb,var(--accent) 16.00%,transparent) 0%,
    color-mix(in srgb,var(--accent) 15.78%,transparent) 8%,
    color-mix(in srgb,var(--accent) 15.12%,transparent) 17%,
    color-mix(in srgb,var(--accent) 14.06%,transparent) 25%,
    color-mix(in srgb,var(--accent) 12.64%,transparent) 33%,
    color-mix(in srgb,var(--accent) 10.93%,transparent) 42%,
    color-mix(in srgb,var(--accent) 9.00%,transparent) 50%,
    color-mix(in srgb,var(--accent) 6.96%,transparent) 58%,
    color-mix(in srgb,var(--accent) 4.94%,transparent) 67%,
    color-mix(in srgb,var(--accent) 3.06%,transparent) 75%,
    color-mix(in srgb,var(--accent) 1.49%,transparent) 83%,
    color-mix(in srgb,var(--accent) 0.41%,transparent) 92%,
    transparent 100%)}
.orb-2{width:min(70vw,820px);aspect-ratio:1;right:-26vw;top:28vh;
  background:radial-gradient(closest-side circle,
    color-mix(in srgb,var(--accent) 16.00%,transparent) 0%,
    color-mix(in srgb,var(--accent) 15.78%,transparent) 8%,
    color-mix(in srgb,var(--accent) 15.12%,transparent) 17%,
    color-mix(in srgb,var(--accent) 14.06%,transparent) 25%,
    color-mix(in srgb,var(--accent) 12.64%,transparent) 33%,
    color-mix(in srgb,var(--accent) 10.93%,transparent) 42%,
    color-mix(in srgb,var(--accent) 9.00%,transparent) 50%,
    color-mix(in srgb,var(--accent) 6.96%,transparent) 58%,
    color-mix(in srgb,var(--accent) 4.94%,transparent) 67%,
    color-mix(in srgb,var(--accent) 3.06%,transparent) 75%,
    color-mix(in srgb,var(--accent) 1.49%,transparent) 83%,
    color-mix(in srgb,var(--accent) 0.41%,transparent) 92%,
    transparent 100%)}
.orb-3{width:min(62vw,720px);aspect-ratio:1;left:14vw;top:86vh;
  background:radial-gradient(closest-side circle,
    color-mix(in srgb,var(--accent) 14.00%,transparent) 0%,
    color-mix(in srgb,var(--accent) 13.81%,transparent) 8%,
    color-mix(in srgb,var(--accent) 13.23%,transparent) 17%,
    color-mix(in srgb,var(--accent) 12.30%,transparent) 25%,
    color-mix(in srgb,var(--accent) 11.06%,transparent) 33%,
    color-mix(in srgb,var(--accent) 9.56%,transparent) 42%,
    color-mix(in srgb,var(--accent) 7.88%,transparent) 50%,
    color-mix(in srgb,var(--accent) 6.09%,transparent) 58%,
    color-mix(in srgb,var(--accent) 4.32%,transparent) 67%,
    color-mix(in srgb,var(--accent) 2.68%,transparent) 75%,
    color-mix(in srgb,var(--accent) 1.31%,transparent) 83%,
    color-mix(in srgb,var(--accent) 0.36%,transparent) 92%,
    transparent 100%)}


/* Starfield. Tiled gradients rather than DOM nodes, so it repeats forever and
   the whole layer moves as one composited transform. Light mode uses a dark
   star at low alpha so it reads as faint texture, not dust on the screen. */
.ambient-bg .stars{position:absolute;inset:-120% -20%;background-repeat:repeat;
  will-change:transform,translate;opacity:var(--star-opacity,1)}

/* Idle drift. Scroll motion uses `transform`; this uses the separate
   `translate` property, and the two compose — so the stars keep moving when
   the page is still without either animation clobbering the other. It is
   time-based, so it also runs in browsers with no scroll-timeline support. */
@media (prefers-reduced-motion:no-preference){
  .stars-1{animation:star-float-1 34s ease-in-out infinite alternate}
  .stars-2{animation:star-float-2 27s ease-in-out infinite alternate}
  .stars-3{animation:star-float-3 21s ease-in-out infinite alternate}
}
/* ~1.5-2.5 px/sec. The first attempt moved 29px over 190s (0.15 px/sec),
   which is far below what the eye registers as motion. */
@keyframes star-float-1{from{translate:0 0}   to{translate:9vw 4.5vh}}
@keyframes star-float-2{from{translate:0 0}   to{translate:-12vw 6vh}}
@keyframes star-float-3{from{translate:0 0}   to{translate:15vw -7vh}}
.stars-1{background-image:
    radial-gradient(1.45px 1.45px at 171px 83px, rgb(var(--star) / 0.57) 0%, rgb(var(--star) / 0.57) 55%, transparent 100%),
    radial-gradient(1.43px 1.43px at 280px 54px, rgb(var(--star) / 0.57) 0%, rgb(var(--star) / 0.57) 55%, transparent 100%),
    radial-gradient(1.16px 1.16px at 265px 115px, rgb(var(--star) / 0.72) 0%, rgb(var(--star) / 0.72) 55%, transparent 100%),
    radial-gradient(1.2px 1.2px at 41px 129px, rgb(var(--star) / 0.72) 0%, rgb(var(--star) / 0.72) 55%, transparent 100%),
    radial-gradient(1.65px 1.65px at 69px 120px, rgb(var(--star) / 0.78) 0%, rgb(var(--star) / 0.78) 55%, transparent 100%),
    radial-gradient(1.17px 1.17px at 37px 209px, rgb(var(--star) / 0.64) 0%, rgb(var(--star) / 0.64) 55%, transparent 100%),
    radial-gradient(1.36px 1.36px at 291px 74px, rgb(var(--star) / 0.61) 0%, rgb(var(--star) / 0.61) 55%, transparent 100%),
    radial-gradient(1.59px 1.59px at 66px 163px, rgb(var(--star) / 0.82) 0%, rgb(var(--star) / 0.82) 55%, transparent 100%),
    radial-gradient(1.43px 1.43px at 58px 102px, rgb(var(--star) / 0.77) 0%, rgb(var(--star) / 0.77) 55%, transparent 100%),
    radial-gradient(1.17px 1.17px at 38px 294px, rgb(var(--star) / 0.63) 0%, rgb(var(--star) / 0.63) 55%, transparent 100%),
    radial-gradient(1.77px 1.77px at 278px 224px, rgb(var(--star) / 0.74) 0%, rgb(var(--star) / 0.74) 55%, transparent 100%),
    radial-gradient(1.37px 1.37px at 238px 191px, rgb(var(--star) / 0.87) 0%, rgb(var(--star) / 0.87) 55%, transparent 100%),
    radial-gradient(1.6px 1.6px at 130px 47px, rgb(var(--star) / 0.76) 0%, rgb(var(--star) / 0.76) 55%, transparent 100%),
    radial-gradient(1.36px 1.36px at 181px 235px, rgb(var(--star) / 0.94) 0%, rgb(var(--star) / 0.94) 55%, transparent 100%),
    radial-gradient(1.47px 1.47px at 66px 268px, rgb(var(--star) / 0.85) 0%, rgb(var(--star) / 0.85) 55%, transparent 100%),
    radial-gradient(1.47px 1.47px at 83px 256px, rgb(var(--star) / 0.93) 0%, rgb(var(--star) / 0.93) 55%, transparent 100%),
    radial-gradient(1.6px 1.6px at 45px 291px, rgb(var(--star) / 0.9) 0%, rgb(var(--star) / 0.9) 55%, transparent 100%),
    radial-gradient(1.7px 1.7px at 166px 180px, rgb(var(--star) / 0.79) 0%, rgb(var(--star) / 0.79) 55%, transparent 100%),
    radial-gradient(1.82px 1.82px at 239px 41px, rgb(var(--star) / 0.93) 0%, rgb(var(--star) / 0.93) 55%, transparent 100%),
    radial-gradient(1.18px 1.18px at 248px 39px, rgb(var(--star) / 0.83) 0%, rgb(var(--star) / 0.83) 55%, transparent 100%);
  background-size:300px 300px}
.stars-2{background-image:
    radial-gradient(2.59px 2.59px at 337px 301px, rgb(var(--star) / 0.72) 0%, rgb(var(--star) / 0.72) 55%, transparent 100%),
    radial-gradient(1.92px 1.92px at 151px 372px, rgb(var(--star) / 0.66) 0%, rgb(var(--star) / 0.66) 55%, transparent 100%),
    radial-gradient(1.89px 1.89px at 17px 242px, rgb(var(--star) / 0.64) 0%, rgb(var(--star) / 0.64) 55%, transparent 100%),
    radial-gradient(1.74px 1.74px at 258px 36px, rgb(var(--star) / 0.52) 0%, rgb(var(--star) / 0.52) 55%, transparent 100%),
    radial-gradient(1.94px 1.94px at 384px 132px, rgb(var(--star) / 0.75) 0%, rgb(var(--star) / 0.75) 55%, transparent 100%),
    radial-gradient(1.68px 1.68px at 260px 47px, rgb(var(--star) / 0.56) 0%, rgb(var(--star) / 0.56) 55%, transparent 100%),
    radial-gradient(2.4px 2.4px at 148px 76px, rgb(var(--star) / 0.73) 0%, rgb(var(--star) / 0.73) 55%, transparent 100%),
    radial-gradient(1.96px 1.96px at 148px 367px, rgb(var(--star) / 0.55) 0%, rgb(var(--star) / 0.55) 55%, transparent 100%),
    radial-gradient(1.67px 1.67px at 200px 124px, rgb(var(--star) / 0.48) 0%, rgb(var(--star) / 0.48) 55%, transparent 100%),
    radial-gradient(1.76px 1.76px at 124px 343px, rgb(var(--star) / 0.59) 0%, rgb(var(--star) / 0.59) 55%, transparent 100%),
    radial-gradient(1.79px 1.79px at 307px 99px, rgb(var(--star) / 0.42) 0%, rgb(var(--star) / 0.42) 55%, transparent 100%),
    radial-gradient(1.91px 1.91px at 220px 279px, rgb(var(--star) / 0.62) 0%, rgb(var(--star) / 0.62) 55%, transparent 100%),
    radial-gradient(2.45px 2.45px at 70px 359px, rgb(var(--star) / 0.76) 0%, rgb(var(--star) / 0.76) 55%, transparent 100%),
    radial-gradient(2.31px 2.31px at 341px 352px, rgb(var(--star) / 0.58) 0%, rgb(var(--star) / 0.58) 55%, transparent 100%);
  background-size:400px 400px}
.stars-3{background-image:
    radial-gradient(2.52px 2.52px at 407px 413px, rgb(var(--star) / 0.33) 0%, rgb(var(--star) / 0.33) 55%, transparent 100%),
    radial-gradient(2.22px 2.22px at 416px 69px, rgb(var(--star) / 0.6) 0%, rgb(var(--star) / 0.6) 55%, transparent 100%),
    radial-gradient(2.11px 2.11px at 457px 172px, rgb(var(--star) / 0.48) 0%, rgb(var(--star) / 0.48) 55%, transparent 100%),
    radial-gradient(2.76px 2.76px at 110px 6px, rgb(var(--star) / 0.46) 0%, rgb(var(--star) / 0.46) 55%, transparent 100%),
    radial-gradient(2.05px 2.05px at 378px 32px, rgb(var(--star) / 0.36) 0%, rgb(var(--star) / 0.36) 55%, transparent 100%),
    radial-gradient(2.86px 2.86px at 391px 158px, rgb(var(--star) / 0.59) 0%, rgb(var(--star) / 0.59) 55%, transparent 100%),
    radial-gradient(2.13px 2.13px at 378px 491px, rgb(var(--star) / 0.55) 0%, rgb(var(--star) / 0.55) 55%, transparent 100%),
    radial-gradient(2.64px 2.64px at 483px 497px, rgb(var(--star) / 0.33) 0%, rgb(var(--star) / 0.33) 55%, transparent 100%),
    radial-gradient(3.01px 3.01px at 110px 356px, rgb(var(--star) / 0.44) 0%, rgb(var(--star) / 0.44) 55%, transparent 100%);
  background-size:540px 540px}


/* Dither. A 16% gradient spread over ~490px only has ~28 distinct 8-bit
   values to work with, so it quantises into flat rings the eye reads as
   contour lines. Fine noise breaks the steps up. This is the actual fix for
   the banding — more blur only smears it. */
.ambient-bg::after{content:"";position:absolute;inset:0;pointer-events:none;
  background-image:url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20width='200'%20height='200'><filter%20id='n'%20x='0'%20y='0'%20width='100%'%20height='100%'><feTurbulence%20type='fractalNoise'%20baseFrequency='0.8'%20numOctaves='4'%20stitchTiles='stitch'%20result='t'/><feColorMatrix%20in='t'%20type='saturate'%20values='0'%20result='g'/><feComponentTransfer%20in='g'><feFuncR%20type='linear'%20slope='2'%20intercept='-0.83'/><feFuncG%20type='linear'%20slope='2'%20intercept='-0.83'/><feFuncB%20type='linear'%20slope='2'%20intercept='-0.83'/><feFuncA%20type='linear'%20slope='0'%20intercept='1'/></feComponentTransfer></filter><rect%20width='200'%20height='200'%20filter='url%28%23n%29'/></svg>");
  background-repeat:repeat;opacity:.03}

/* Content sits above the layer. The layer is z-index 0, not negative, so it
   can't end up behind the body background on any engine.
   .nav is deliberately NOT in this list — it is position:fixed with its own
   z-index, and including it here silently overrode that. */
main,.site-foot{position:relative;z-index:1}

/* --- photo band ----------------------------------------------------------
   A full-bleed section with a photograph behind it.

   Unlike .band this does NOT invert with the theme: its colours are fixed
   dark because a photo backdrop is dark in both themes, and inverting the
   text over it would make the section unreadable in dark mode. The scrim is
   heavy on purpose — the photo is there to give the section depth, not to
   compete with the words on top of it.
   -------------------------------------------------------------------------- */
.photo-band{position:relative;isolation:isolate;color:#EAF1EE;background:transparent;
  --band-line:color-mix(in srgb,var(--accent) 60%,transparent);
  /* Band height drove how much of the photo survived `cover`. Left to their
     content these ranged 541-990px, so the shortest band showed barely half
     its image (a squished-looking strip) while the tallest scaled its image
     up 127%. A floor plus centred content keeps the crop in a sane range. */
  padding-block:104px;min-height:min(660px,80vh);
  display:flex;align-items:center}
/* flow-root is defensive only: it keeps a child's top margin from
   collapsing out through .wrap now that .wrap is a flex item. */
.photo-band>.wrap{width:100%;display:flow-root}

/* The founder band is excluded from the line, as requested — so it keeps the
   edge fade instead. A hard cut with no line marking it is exactly the
   "visible cutoff" that started this. Every band is one or the other. */
.photo-band.ph-about{--band-line:transparent}
.photo-band.ph-about::before,.photo-band.ph-about::after{
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 72px,
    #000 calc(100% - 72px),transparent 100%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 72px,
    #000 calc(100% - 72px),transparent 100%)}
@media (max-width:760px){
  .photo-band{padding-block:72px;min-height:0;display:block}
}
/* The backdrop (base colour + photo + scrim) lives entirely on ::before so it
   can be masked. Masking the element itself would mask its text too.

   The mask is what removes the seam. Previously the band painted an opaque
   background and a gradient faded to a flat var(--bg): the flat colour never
   matched the real page above it (which carries the orb tint and stars), and
   the orbs and stars stopped dead at the band's edge. Masking to transparent
   instead lets the actual page — ambient layer included — run straight
   through, so there is nothing left to mismatch.

   The fade completes at 72px, inside the band's 80px padding, so text always
   sits on a fully opaque backdrop. */
.photo-band::before{content:"";position:absolute;inset:0;z-index:-1;
  background-color:#0A120F;
  /* The two 1px layers are FIRST because the first background layer paints on
     top. They have to live here, not on .photo-band itself: this pseudo is
     z-index:-1, which paints above the element's own background, so a line set
     there is hidden behind the photo. */
  background-image:
    linear-gradient(var(--band-line),var(--band-line)),
    linear-gradient(var(--band-line),var(--band-line)),
    linear-gradient(100deg, rgba(10,18,15,.94) 0%, rgba(10,18,15,.86) 50%, rgba(10,18,15,.93) 100%),
    var(--band-photo,none);
  background-size:100% 1px,100% 1px,cover,cover;
  background-position:top left,bottom left,center,center;
  background-repeat:no-repeat,no-repeat,no-repeat,no-repeat}

/* The ambient dither sits behind <main>, so it cannot reach a band's own
   scrim. That scrim only varies 8% in alpha across the width, which bands
   badly by itself. Same noise, same mask so it stops where the band does. */
.photo-band::after{content:"";position:absolute;inset:0;z-index:-1;
  pointer-events:none;background-image:url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20width='200'%20height='200'><filter%20id='n'%20x='0'%20y='0'%20width='100%'%20height='100%'><feTurbulence%20type='fractalNoise'%20baseFrequency='0.8'%20numOctaves='4'%20stitchTiles='stitch'%20result='t'/><feColorMatrix%20in='t'%20type='saturate'%20values='0'%20result='g'/><feComponentTransfer%20in='g'><feFuncR%20type='linear'%20slope='2'%20intercept='-0.83'/><feFuncG%20type='linear'%20slope='2'%20intercept='-0.83'/><feFuncB%20type='linear'%20slope='2'%20intercept='-0.83'/><feFuncA%20type='linear'%20slope='0'%20intercept='1'/></feComponentTransfer></filter><rect%20width='200'%20height='200'%20filter='url%28%23n%29'/></svg>");
  background-repeat:repeat;opacity:.04}
.photo-band .wrap{position:relative}
/* Anything directly after a band needs its own breathing room; several
   sections carry an inline padding-top:0 for tight stacking, which is wrong
   straight after a band. */
.photo-band + section{padding-top:72px!important}
/* ...and room before one. Several sections end flush against the band's top
   line — the homepage stat row actually overlapped it by 46px, because its
   inline padding-block:0 left nothing between the labels and the edge. */
section:has(+ .photo-band){padding-bottom:120px}
@media (max-width:760px){
  section:has(+ .photo-band){padding-bottom:72px}
}
.photo-band .eyebrow{color:#3FC48F}
.photo-band .sub,
.photo-band .list li p span,
.photo-band .step p,
.photo-band .step .n,
.photo-band .stat span,
.photo-band .muted{color:#A9BAB3}
.photo-band .how{border-top-color:#EAF1EE}
.photo-band .stats{border-top-color:rgba(234,241,238,.3)}
.photo-band .btn.ghost{color:#EAF1EE!important;
  box-shadow:inset 0 0 0 1.5px rgba(234,241,238,.45)}
.photo-band .btn.ghost:hover{box-shadow:inset 0 0 0 1.5px #3FC48F}
/* The terms card keeps its own surface, so it needs the page's own tokens
   back rather than the fixed dark ones above. */
.photo-band .terms{background:var(--surface);color:var(--ink);
  border-color:var(--line)}
.photo-band .terms .term span:first-child{color:var(--muted)}
.photo-band .portrait{border-color:rgba(234,241,238,.28)}

/* Cards sitting on a photo band go glassy: a translucent wash plus a blur,
   so the photo still reads through but the card stays legible. Colours are
   fixed dark here for the same reason the band's are — a photo backdrop is
   dark in both themes. */
.photo-band .card{background:rgba(255,255,255,.07);
  border-color:rgba(234,241,238,.16);backdrop-filter:blur(8px);color:#EAF1EE}
.photo-band .card h3{color:#EAF1EE}
.photo-band .card p{color:#A9BAB3}
.photo-band .card .more{color:#3FC48F}
.photo-band .card-ico{background:rgba(255,255,255,.10);color:#3FC48F}

.photo-band.ph-what{--band-photo:url("../../Media/services-backdrop.webp")}
.photo-band.ph-home{--band-photo:url("../../Media/desk-phone.webp")}
.photo-band.ph-services{--band-photo:url("../../Media/workspace.webp")}
.photo-band.ph-about{--band-photo:url("../../Media/melbourne.webp")}
.photo-band.ph-join{--band-photo:url("../../Media/remote-desk.webp")}

/* --- page header (inner pages) ------------------------------------------- */
.page-head{padding-block:64px 48px;border-bottom:1px solid var(--line)}
.page-head h1{font-size:clamp(40px,6vw,68px);font-weight:800;max-width:16ch}
.page-head .sub{font-size:20px;max-width:56ch}

/* --- hero ---------------------------------------------------------------- */
.hero .wrap{display:grid;grid-template-columns:1.15fr .85fr;gap:56px;
  align-items:center;padding-block:48px 80px}
.hero h1{font-size:clamp(44px,7vw,84px);font-weight:800}
.hero h1 em{font-style:normal;color:var(--accent)}
.lede{margin-top:22px;font-size:20px;color:var(--muted);max-width:34ch}
@media (max-width:820px){
  .hero .wrap{grid-template-columns:1fr;gap:40px;padding-block:24px 56px}
}

/* --- calendar slip ------------------------------------------------------- */
.slip{background:var(--surface);border:1px solid var(--line);border-radius:18px;
  padding:22px;box-shadow:var(--shadow);font-family:var(--f-mono);
  font-size:13px;min-width:0}
.slip-head{display:flex;justify-content:space-between;color:var(--muted);
  text-transform:uppercase;letter-spacing:.08em;font-size:11px;
  padding-bottom:14px;border-bottom:1px dashed var(--line)}
.slot{display:grid;grid-template-columns:62px 1fr;gap:14px;padding:12px 0;
  border-bottom:1px dashed var(--line);align-items:center;
  font-variant-numeric:tabular-nums}
.slot:last-of-type{border-bottom:0}
.slot .t{color:var(--muted)}
.slot .ev{border-radius:10px;padding:10px 12px;background:var(--bg);color:var(--muted)}
.slot .ev.booked{background:var(--accent-soft);color:var(--ink);
  font-family:var(--f-body);font-size:14px;display:flex;
  justify-content:space-between;align-items:center;gap:10px}
.slot .ev.booked b{display:block;font-weight:600}
.slot .ev.booked small{color:var(--muted);font-size:12.5px}
.badge{display:inline-flex;align-items:center;gap:5px;background:var(--accent);
  color:var(--accent-ink);border-radius:999px;padding:4px 9px;
  font-family:var(--f-mono);font-size:11px;white-space:nowrap}
.badge svg{width:10px;height:10px}
.slip-note{margin-top:12px;color:var(--muted);font-size:11px}

/* --- steps --------------------------------------------------------------- */
.how{display:grid;grid-template-columns:repeat(4,1fr);gap:0;margin-top:48px;
  border-top:1.5px solid var(--ink)}
.band .how{border-top-color:var(--band-ink)}
.step{padding:22px 22px 0 0;min-width:0}
.step .n{font-family:var(--f-mono);font-size:13px;color:var(--muted)}
.band .step .n,.band .step p{color:var(--band-muted)}
.step h3{font-size:22px;margin:10px 0 8px;font-weight:700}
.step p{color:var(--muted);font-size:15.5px}
@media (max-width:860px){.how{grid-template-columns:1fr 1fr;row-gap:28px}}
@media (max-width:480px){.how{grid-template-columns:1fr}}

/* --- split / lists ------------------------------------------------------- */
.split{display:grid;grid-template-columns:1fr 1fr;gap:48px;margin-top:40px}
@media (max-width:760px){.split{grid-template-columns:1fr;gap:28px}}
.list{list-style:none;margin:0;padding:0;display:grid;gap:14px}
.list li{display:grid;grid-template-columns:22px 1fr;gap:12px;align-items:start}
.list li .tick{margin-top:3px;width:20px;height:20px}
.list li b{font-weight:600}
/* Scoped to the text span: `.list li span` also matches the tick's own
   span and would override .tick's colour, washing the checkmark out. */
.list li p span{color:var(--muted)}

/* --- terms table --------------------------------------------------------- */
.terms{background:var(--surface);border:1px solid var(--line);border-radius:18px;
  padding:28px;display:grid;gap:18px;align-content:start}
.terms h3{font-size:26px}
.term{display:flex;justify-content:space-between;gap:16px;
  border-top:1px solid var(--line);padding-top:14px;font-size:15.5px}
.term span:first-child{color:var(--muted)}
.term span:last-child{font-weight:600;text-align:right}

/* --- niche chips --------------------------------------------------------- */
.niches{display:flex;flex-wrap:wrap;gap:10px;margin-top:28px}
.niches span{border:1.5px solid var(--line);border-radius:999px;padding:8px 16px;
  font-size:15px;font-weight:500}

/* --- cards --------------------------------------------------------------- */
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:48px}
@media (max-width:880px){.cards{grid-template-columns:1fr 1fr}}
@media (max-width:560px){.cards{grid-template-columns:1fr}}
.card{background:var(--surface);border:1px solid var(--line);border-radius:18px;
  padding:26px;display:flex;flex-direction:column;gap:12px;min-width:0}
.card-ico{width:42px;height:42px;border-radius:12px;background:var(--accent-soft);
  color:var(--accent);display:grid;place-items:center;flex:none}
.card-ico svg{width:21px;height:21px}
.card h3{font-size:21px;font-weight:700}
.card p{color:var(--muted);font-size:15.5px}
.card .more{margin-top:auto;padding-top:8px;color:var(--accent);font-weight:600;
  font-size:15px;text-decoration:none}
.card .more:hover{text-decoration:underline}

/* --- stat row ------------------------------------------------------------ */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:24px;margin-top:44px;
  border-top:1px solid var(--line);padding-top:28px}
.band .stats{border-top-color:var(--band-muted)}
@media (max-width:720px){.stats{grid-template-columns:1fr 1fr;gap:28px}}
.stat b{display:block;font-family:var(--f-display);font-weight:800;
  font-size:clamp(30px,4vw,42px);line-height:1;letter-spacing:-.03em}
.stat span{display:block;margin-top:8px;color:var(--muted);font-size:15px}
.band .stat span{color:var(--band-muted)}

/* --- quotes -------------------------------------------------------------- */
.quotes{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:44px}
@media (max-width:880px){.quotes{grid-template-columns:1fr}}
.quote{background:var(--surface);border:1px solid var(--line);border-radius:18px;
  padding:26px;display:grid;gap:16px;align-content:start;margin:0}
.quote blockquote{margin:0;font-size:17px}
.quote figcaption{display:flex;align-items:center;gap:12px;
  border-top:1px solid var(--line);padding-top:16px}
.avatar{width:40px;height:40px;border-radius:50%;background:var(--accent-soft);
  color:var(--accent);display:grid;place-items:center;font-weight:700;
  font-family:var(--f-display);flex:none}
.quote cite{font-style:normal;font-weight:600;font-size:15px;display:block}
.quote figcaption small{color:var(--muted);font-size:13.5px}

/* A single testimonial presented as a feature, not as one-of-three with gaps.
   One quote given room reads as a highlight; a grid with holes in it
   advertises what is missing. */
.quote-lead{max-width:760px;margin:44px auto 0;background:var(--surface);
  border:1px solid var(--line);border-radius:22px;padding:44px 44px 36px;
  display:grid;gap:22px;box-shadow:var(--shadow)}
@media (max-width:620px){.quote-lead{padding:30px 26px 26px;margin-top:32px}}
.quote-lead .mark{width:34px;height:34px;color:var(--accent);opacity:.9}
.quote-lead blockquote{margin:0;font-family:var(--f-display);font-weight:500;
  font-size:clamp(20px,2.5vw,27px);line-height:1.35;letter-spacing:-.015em}
.quote-lead figcaption{display:flex;align-items:center;gap:14px;
  border-top:1px solid var(--line);padding-top:22px}
.quote-lead .avatar{width:46px;height:46px;font-size:15px}
.quote-lead cite{font-style:normal;font-weight:600;font-size:16px;display:block}
.quote-lead figcaption small{color:var(--muted);font-size:14px}

/* Placeholder treatment — dashed outline reads as "swap this out", so an
   unfinished section can never be mistaken for a real claim. */
.is-placeholder{border-style:dashed;border-width:1.5px;background:transparent}
.ph-tag{font-family:var(--f-mono);font-size:10.5px;text-transform:uppercase;
  letter-spacing:.1em;color:var(--muted);border:1px solid var(--line);
  border-radius:999px;padding:3px 9px;justify-self:start}

/* --- FAQ ----------------------------------------------------------------- */
.faq{margin-top:44px;border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{list-style:none;cursor:pointer;padding:22px 44px 22px 0;
  position:relative;font-family:var(--f-display);font-weight:700;
  font-size:20px;letter-spacing:-.01em}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:8px;top:50%;
  width:11px;height:11px;border-right:2px solid var(--muted);
  border-bottom:2px solid var(--muted);
  transform:translateY(-70%) rotate(45deg);transition:transform .2s ease}
.faq details[open] summary::after{transform:translateY(-30%) rotate(-135deg)}
.faq details p{color:var(--muted);padding-bottom:24px;max-width:70ch;font-size:16.5px}

/* --- book card ----------------------------------------------------------- */
.book .wrap{display:grid;grid-template-columns:1.2fr .8fr;gap:48px;align-items:center}
@media (max-width:760px){.book .wrap{grid-template-columns:1fr}}
.book-card{background:var(--accent);color:var(--accent-ink);border-radius:22px;
  padding:32px;display:grid;gap:14px}
.book-card .big{font-family:var(--f-display);font-weight:800;font-size:40px;
  line-height:1;letter-spacing:-.03em}
.book-card p{opacity:.9;font-size:15.5px}
.book-card .btn{background:var(--accent-ink);color:var(--accent)!important;
  justify-self:start}

/* --- forms --------------------------------------------------------------- */
.form{background:var(--surface);border:1px solid var(--line);border-radius:18px;
  padding:28px;display:grid;gap:20px}
.field{display:grid;gap:7px}
.field label{font-weight:600;font-size:15px}
.field .hint{color:var(--muted);font-size:13.5px}
.field input,.field select,.field textarea{font-family:inherit;font-size:16px;
  color:var(--ink);background:var(--bg);border:1.5px solid var(--line);
  border-radius:12px;padding:13px 14px;min-height:48px;width:100%;
  transition:border-color .15s ease}
.field textarea{min-height:130px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{
  border-color:var(--accent);outline:0}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:3px solid var(--accent);outline-offset:2px}
.field .err{color:var(--danger);font-size:14px;font-weight:500;display:none}
.field.is-invalid input,.field.is-invalid select,.field.is-invalid textarea{
  border-color:var(--danger)}
.field.is-invalid .err{display:block}
.two-up{display:grid;grid-template-columns:1fr 1fr;gap:20px}
@media (max-width:600px){.two-up{grid-template-columns:1fr}}
.errsum{display:none;border:1.5px solid var(--danger);border-radius:14px;
  padding:18px 20px}
.errsum.is-shown{display:block}
.errsum h2{font-size:18px;margin-bottom:10px;color:var(--danger);max-width:none}
.errsum ul{margin:0;padding-left:20px;display:grid;gap:6px;font-size:15px}
.errsum a{color:var(--danger)}
.form-ok{display:none;background:var(--accent-soft);border:1px solid var(--accent);
  border-radius:14px;padding:18px 20px;font-size:16px}
.form-ok.is-shown{display:block}
.form-err{display:none;border:1.5px solid var(--danger);border-radius:14px;
  padding:18px 20px;font-size:16px}
.form-err.is-shown{display:block}
.form-err b{color:var(--danger)}

/* Sending state. Keep the cursor honest and stop double-submits. */
.btn[disabled]{opacity:.65;cursor:progress;transform:none}
.btn[disabled]:hover{transform:none;filter:none}

/* Honeypot: hidden from sighted users and assistive tech alike, but still
   submitted, so a bot that fills everything gives itself away. */
.vh{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;
  border:0}

/* --- contact details ----------------------------------------------------- */
.contact-grid{display:grid;grid-template-columns:1fr 1fr;gap:48px;margin-top:40px;
  align-items:start}
@media (max-width:860px){.contact-grid{grid-template-columns:1fr;gap:32px}}
.details{margin:0}
.detail{display:grid;grid-template-columns:40px 1fr;gap:0 14px;align-items:start;
  padding-block:18px;border-bottom:1px solid var(--line)}
.detail:last-child{border-bottom:0}
.detail .card-ico{grid-row:span 2;width:40px;height:40px}
.detail dt{font-weight:600;font-size:15px;grid-column:2}
.detail dd{margin:0;grid-column:2;color:var(--muted);font-size:16px}
/* Tapping the phone number is the point of this list on a phone, so the link
   gets a full-size target rather than a 19px line box. */
.detail dd a{color:var(--accent);font-weight:500;display:inline-flex;
  align-items:center;min-height:44px}

/* --- figure / media ------------------------------------------------------ */
.figure{border-radius:18px;overflow:hidden;border:1px solid var(--line);
  box-shadow:var(--shadow);margin:0}
.figure img{width:100%;aspect-ratio:3/2;object-fit:cover}
/* Full content width needs a letterbox crop; 3:2 would be 720px tall here. */
.figure-wide img{aspect-ratio:2.4/1}
@media (max-width:640px){.figure-wide img{aspect-ratio:3/2}}
.figure figcaption{padding:14px 18px;color:var(--muted);font-size:14px;
  background:var(--surface);border-top:1px solid var(--line)}

/* --- footer -------------------------------------------------------------- */
.site-foot{border-top:1px solid var(--line);padding-block:56px 32px}
.foot-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:40px}
@media (max-width:860px){.foot-grid{grid-template-columns:1fr 1fr;gap:32px}}
@media (max-width:520px){.foot-grid{grid-template-columns:1fr}}
.foot-grid p{color:var(--muted);font-size:15px;margin-top:14px;max-width:34ch}
.foot-col h3{font-family:var(--f-mono);font-size:11.5px;text-transform:uppercase;
  letter-spacing:.12em;color:var(--muted);font-weight:500;margin-bottom:14px}
.foot-col ul{list-style:none;margin:0;padding:0;display:grid;gap:10px}
/* min-height clears WCAG 2.5.8's 24px target minimum; the 10px row gap then
   keeps adjacent links from crowding each other. */
.foot-col a{color:var(--ink);text-decoration:none;font-size:15px;
  display:inline-flex;align-items:center;min-height:24px}
.foot-col a:hover{color:var(--accent);text-decoration:underline}
.foot-base{display:flex;flex-wrap:wrap;justify-content:space-between;gap:12px;
  margin-top:44px;padding-top:24px;border-top:1px solid var(--line);
  color:var(--muted);font-size:14px}

/* --- scroll-driven intro -------------------------------------------------
   Scroll-linked animation, not a JS scroll handler: these run off the main
   thread, so the motion can't stutter the scroll itself.

   Double-guarded. @supports means browsers without scroll timelines (Firefox
   today) render the page completely static rather than stuck at opacity 0,
   and the reduced-motion query means anyone who has asked for less movement
   gets none of it.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion:no-preference){

  /* --- preferred path: CSS scroll-driven animation --------------------- */
  @supports (animation-timeline:view()){

    /* Hero: copy and calendar slip climb at very different rates, so the two
       pull apart as you scroll. The gap between -70 and -170 is the effect —
       an earlier version used -28/-64 and was too small to notice. */
    .hero-copy{
      animation:hero-copy-out linear both;
      animation-timeline:scroll(root block);
      animation-range:0 75vh}
    @keyframes hero-copy-out{
      to{transform:translateY(-105px);opacity:.22}
    }

    .hero .slip{
      animation:hero-slip-out linear both;
      animation-timeline:scroll(root block);
      animation-range:0 75vh}
    @keyframes hero-slip-out{
      to{transform:translateY(-250px) scale(.93);opacity:.38}
    }

    .reveal{
      animation:reveal-in linear both;
      animation-timeline:view();
      animation-range:entry 0% entry 50%}

    .stats .stat{
      animation:reveal-in linear both;
      animation-timeline:view();
      animation-range:entry 0% entry 55%}
    .stats .stat:nth-child(2){animation-range:entry 8% entry 63%}
    .stats .stat:nth-child(3){animation-range:entry 16% entry 71%}
    .stats .stat:nth-child(4){animation-range:entry 24% entry 79%}

    /* Driven by the WHOLE document's scroll, so the drift is continuous from
       top to bottom of the page instead of restarting at each section. */
    .orb-1{animation:orb-1-drift linear both}
    .orb-2{animation:orb-2-drift linear both}
    .orb-3{animation:orb-3-drift linear both}
    .ambient-bg .orb{animation-timeline:scroll(root block);animation-range:normal}
    /* ~3 viewport heights of travel across the page: at 62vh the orbs moved
       about 9px per 100px scrolled, which read as static. */
    @keyframes orb-1-drift{
      from{transform:translate3d(0,-40vh,0)}
      to  {transform:translate3d(16vw,185vh,0)}
    }
    @keyframes orb-2-drift{
      from{transform:translate3d(0,60vh,0)}
      to  {transform:translate3d(-14vw,-175vh,0)}
    }
    @keyframes orb-3-drift{
      from{transform:translate3d(0,50vh,0)}
      to  {transform:translate3d(12vw,-210vh,0)}
    }

    /* Starfield: each layer drifts at a different rate for parallax depth. */
    .stars-1{animation-name:star-float-1,stars-1-drift}
    .stars-2{animation-name:star-float-2,stars-2-drift}
    .stars-3{animation-name:star-float-3,stars-3-drift}
    /* Two animations per layer: the idle float keeps its own timing, the
       scroll drift is driven by the root scroll timeline. */
    .ambient-bg .stars{
      animation-duration:var(--float-dur),1s;
      animation-timing-function:ease-in-out,linear;
      animation-iteration-count:infinite,1;
      animation-direction:alternate,normal;
      animation-fill-mode:none,both;
      animation-timeline:auto,scroll(root block);
      animation-range:normal,normal}
    .stars-1{--float-dur:34s}
    .stars-2{--float-dur:27s}
    .stars-3{--float-dur:21s}
    @keyframes stars-1-drift{from{transform:translate3d(0,0,0)}   to{transform:translate3d(0,-70vh,0)}}
    @keyframes stars-2-drift{from{transform:translate3d(0,0,0)}   to{transform:translate3d(0,-150vh,0)}}
    @keyframes stars-3-drift{from{transform:translate3d(0,0,0)}   to{transform:translate3d(0,-260vh,0)}}
  }

  @keyframes reveal-in{
    from{opacity:0;transform:translateY(56px)}
    to{opacity:1;transform:none}
  }

  /* --- fallback: browsers without scroll timelines (Firefox today) ------
     The `js-reveal` class is added by site.js, and ONLY on this path. That
     matters: without it a JS failure would leave every .reveal stranded at
     opacity 0, which is far worse than having no animation at all. */
  .js-reveal .reveal,
  .js-reveal .stats .stat{
    opacity:0;transform:translateY(56px);
    transition:opacity .7s ease, transform .7s cubic-bezier(.2,.7,.3,1)}
  .js-reveal .reveal.is-in,
  .js-reveal .stats .stat.is-in{opacity:1;transform:none}
  .js-reveal .stats .stat:nth-child(2){transition-delay:.08s}
  .js-reveal .stats .stat:nth-child(3){transition-delay:.16s}
  .js-reveal .stats .stat:nth-child(4){transition-delay:.24s}
}

@media (prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important}
  html{scroll-behavior:auto}
}
