/* Cinema: the two set-pieces injected into the main page.
   #scenes — a dark, full-bleed sticky sequence: one screen stays, the story scrolls past it.
   #rail   — a poster row you drag through, the way a streaming service shows its catalogue.
   Both are self-contained; nothing above them is restyled. */

/* ── the dark act ───────────────────────────────────────────────────────── */
/* Backgrounds do the cinematography here: a deep base, two slow light sources moving
   through it, a fine grain so the gradients never band, and a vignette on top. Cheap in
   pixels, and it is what makes a flat green page feel like a room with lights in it. */
.cinema{position:relative;background:#050d09;color:#eaf5ee;overflow:clip;
  padding:0;margin:0;border-block:1px solid rgba(255,255,255,.08)}
/* blur 46px, not 70: the blur radius is the cost here, and at this opacity the difference is
   invisible while the compositing work is roughly halved. */
.reel .lights{position:absolute;inset:-20% -10%;z-index:0;pointer-events:none;filter:blur(46px)}
.reel .lights span{position:absolute;display:block;border-radius:50%;mix-blend-mode:screen}
.reel .lights .l1{width:56vw;height:56vw;left:-12vw;top:-14vw;background:rgba(52,209,122,.22);
  animation:lightDrift1 34s ease-in-out infinite}
.reel .lights .l2{width:44vw;height:44vw;right:-10vw;top:32%;background:rgba(18,161,80,.18);
  animation:lightDrift2 46s ease-in-out infinite}
.reel .lights .l3{width:38vw;height:38vw;left:26%;bottom:-16vw;background:rgba(245,166,35,.10);
  animation:lightDrift3 56s ease-in-out infinite}
@keyframes lightDrift1{0%,100%{transform:translate3d(0,0,0) scale(1)}50%{transform:translate3d(9vw,7vh,0) scale(1.16)}}
@keyframes lightDrift2{0%,100%{transform:translate3d(0,0,0) scale(1)}50%{transform:translate3d(-8vw,-6vh,0) scale(1.1)}}
@keyframes lightDrift3{0%,100%{transform:translate3d(0,0,0) scale(1)}50%{transform:translate3d(6vw,-8vh,0) scale(1.2)}}
/* Film grain — a static SVG noise tile, so it costs one small data URI and no requests. */
.reel .grain{position:absolute;inset:0;z-index:1;pointer-events:none;opacity:.055;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
  background-size:140px 140px}
/* A faint horizon line where the dark act begins and ends, like a letterbox edge. */
.cinema::after{content:"";position:absolute;left:0;right:0;top:0;height:1px;z-index:4;
  background:linear-gradient(90deg,transparent,rgba(92,228,155,.5),transparent)}
/* Anchored to the REEL, not the section: on a section four screens tall this gradient slid
   past the sticky picture, so every beat looked like it added another layer of shadow. */
.reel::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:2;
  background:radial-gradient(120% 70% at 50% 0%,transparent 45%,rgba(0,0,0,.45) 100%)}
.cinema .wrap{position:relative;z-index:3}

.cinema-intro{padding:88px 0 26px;text-align:center}
.cinema-intro .eyebrow{display:block;font-size:11.5px;font-weight:800;letter-spacing:2.4px;
  text-transform:uppercase;color:#5ce49b;margin-bottom:14px}
.cinema-intro h2{font-size:clamp(30px,5vw,58px);line-height:1.04;letter-spacing:-1.6px;
  font-weight:850;margin:0;color:#fff}
.cinema-intro p{max-width:58ch;margin:16px auto 0;color:#9db3a6;font-size:17px}

/* THE REEL — the room fills the screen and the story walks over it. A person at 1400px reads
   as a person; the same face in a card reads as an icon, which is the whole difference between
   a feature list and something you feel. */
.reel{position:sticky;top:0;height:100vh;width:100%;overflow:hidden;background:#050d09}
.reel .frame{position:absolute;inset:0;opacity:0;transition:opacity .7s ease;will-change:opacity}
.reel .frame.on{opacity:1}
.reel .frame img.bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:center;transform:scale(1.04);filter:saturate(.95);will-change:opacity}
/* The slow push-in was removed: a 7s transform on a full-screen 2.5MB plate, restarted on every
   frame swap, is what made the scroll stutter. The reel crossfades; it does not also zoom. */
.reel .frame img.screen{position:absolute;right:5vw;bottom:16vh;width:min(46vw,760px);
  border-radius:12px;z-index:3;opacity:0;transform:translateY(28px) scale(.98);
  transition:opacity .9s cubic-bezier(.16,.84,.44,1) .15s,transform 1.1s cubic-bezier(.16,.84,.44,1) .15s;
  box-shadow:0 60px 120px -30px rgba(0,0,0,.95),0 0 0 1px rgba(255,255,255,.16),
             0 0 140px -30px rgba(52,209,122,.5);filter:saturate(1.05) brightness(1.05)}
.reel .frame.on img.screen{opacity:1;transform:none}
/* Legible text over any photograph: dark from the left and from the bottom, nowhere else. */
.reel .scrim{position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(90deg,rgba(5,13,9,.92),rgba(5,13,9,.55) 42%,rgba(5,13,9,.1) 70%),
             linear-gradient(0deg,rgba(5,13,9,.9),transparent 45%)}
.reel .vignette{position:absolute;inset:0;z-index:2;pointer-events:none;
  box-shadow:inset 0 0 220px 60px rgba(0,0,0,.6)}

@media(max-width:900px){
  .reel .frame img.screen{right:auto;left:5vw;bottom:10vh;width:82vw}
  .reel .scrim{background:linear-gradient(0deg,rgba(5,13,9,.94),rgba(5,13,9,.35) 55%,rgba(5,13,9,.5))}
}
.stage .plate{position:absolute;inset:0;opacity:0;transform:scale(1.04);
  transition:opacity .85s cubic-bezier(.16,.84,.44,1),transform 1.2s cubic-bezier(.16,.84,.44,1)}
.stage .plate.on{opacity:1;transform:none}
.stage .plate img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block}
/* A person in the frame, when a photo is supplied — the screen sits over it. */
.stage .plate.has-person img.person{position:absolute;inset:0;object-position:center;filter:saturate(.92) contrast(1.02)}
/* The photo is the room; the screen sits in the quiet left side of it, so the person stays
   visible on the right. The prompts are written to leave exactly that space. */
/* Order matters: the room is darkened UNDER the screen, never over it. With the veil on top
   the product looked switched off — which is the one thing this section must not do. */
.stage .plate.has-person img.person{z-index:0}
.stage .plate.has-person::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  background:linear-gradient(90deg,rgba(5,13,9,.62),rgba(5,13,9,.15) 58%,transparent 78%),
             radial-gradient(85% 65% at 28% 42%,transparent,rgba(5,13,9,.45))}
.stage .plate.has-person img.screen{position:absolute;left:5%;top:15%;width:58%;height:auto;z-index:2;
  border-radius:9px;object-fit:contain;filter:saturate(1.04) brightness(1.06);
  box-shadow:0 40px 80px -18px rgba(0,0,0,.95),0 0 0 1px rgba(255,255,255,.16),
             0 0 90px -20px rgba(52,209,122,.45)}
.stage .glow{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(70% 50% at 50% -10%,rgba(52,209,122,.22),transparent 70%)}
.stage .time{position:absolute;left:16px;bottom:14px;z-index:4;font-size:12px;font-weight:800;
  letter-spacing:1.4px;text-transform:uppercase;color:#eaf5ee;opacity:.9;
  padding:5px 11px;border-radius:100px;background:rgba(5,13,9,.6);border:1px solid rgba(255,255,255,.16);
  backdrop-filter:blur(8px)}

/* The beats scroll OVER the reel: each is a screen tall, the words sit low-left where the
   scrim is darkest. Pulled up by one viewport so the first beat lands on the first frame. */
.beats{position:relative;z-index:4;margin-top:-100vh}
.beat{min-height:100vh;display:flex;align-items:flex-end;padding:0 0 16vh}
/* opacity 0, not .12: a ghost of the next paragraph sliding up behind the live one is exactly
   the "smeared" feeling — two texts on screen at once, neither readable. */
.beat > .inner{width:min(560px,86vw);margin-left:max(6vw,calc((100vw - 1180px)/2));
  opacity:0;transform:translateY(16px);will-change:opacity,transform;
  transition:opacity .45s cubic-bezier(.16,.84,.44,1),transform .45s cubic-bezier(.16,.84,.44,1)}
/* In the goals reel the words share the screen with the ring, so they keep to their own column
   and sit centred rather than at the bottom edge. */
#goals .beat{align-items:center;padding-bottom:0}
#goals .beat > .inner{width:min(40vw,520px)}
@media(max-width:900px){#goals .beat > .inner{width:min(560px,86vw)}}
.beat.on > .inner{opacity:1;transform:none}
@media(max-width:900px){
  .beats{margin-top:-100vh}
  .beat{padding-bottom:8vh}
  .beat > .inner{margin-left:6vw;opacity:1;transform:none}
}
.beat .when{display:block;font-size:12.5px;font-weight:800;letter-spacing:2.4px;text-transform:uppercase;
  color:#5ce49b;margin-bottom:12px}
.beat h3{font-size:clamp(30px,4.4vw,54px);line-height:1.04;letter-spacing:-1.6px;font-weight:850;margin:0;
  color:#fff;text-shadow:0 2px 30px rgba(0,0,0,.5)}
.beat p{margin:16px 0 0;color:rgba(234,245,238,.85);font-size:17px;max-width:42ch;
  text-shadow:0 1px 20px rgba(0,0,0,.6)}
.beat .who{margin-top:16px;display:flex;align-items:center;gap:10px;font-size:13px;color:#7d9488}
.beat .who i{width:28px;height:28px;border-radius:50%;background:rgba(52,209,122,.16);
  border:1px solid rgba(52,209,122,.3);display:grid;place-items:center;font-style:normal;
  font-weight:800;color:#5ce49b;font-size:12px}

/* ── the goals reel ─────────────────────────────────────────────────────────
   Same grammar as the week, one level up: the room changes per GOAL and the ring of tools
   stays, turning slowly around whatever that goal is. The point of the section is that the
   circle never changes — only its centre does. */
#goals .reel .frame img.bg{object-position:center 42%}
/* Directional, not radial. A radial scrim centred at 50% 50% put its darkest ring of shadow
   straight over the circle — the tools looked like they were behind glass. The words are on the
   left, so the darkness belongs on the left; the right half stays clear for the ring. */
#goals .reel .scrim{background:
  linear-gradient(90deg,rgba(5,13,9,.93),rgba(5,13,9,.72) 34%,rgba(5,13,9,.34) 56%,rgba(5,13,9,.22) 78%,rgba(5,13,9,.4)),
  linear-gradient(0deg,rgba(5,13,9,.82),transparent 46%)}
/* The corner vignette is enough on this section; the inner shadow closed in on the ring. */
#goals .reel .vignette{box-shadow:inset 0 0 180px 30px rgba(0,0,0,.45)}

/* The ring owns the RIGHT half of the stage, the words own the left. Centred on the whole
   viewport it sat straight under the text — with labels on every satellite the two were
   printing over each other, which is unreadable at any font size. */
/* The right inset is not decoration: a satellite label is wider than its icon, so without it
   "Booking & appointments" ran off the edge of the screen. */
.ring-stage{position:absolute;inset:0 5vw 0 46%;z-index:4;display:grid;place-items:center;pointer-events:none}
@media(max-width:1100px){.ring-stage{inset:0 4vw 0 38%}}
/* --r is the orbit radius. Percentages cannot be used for it: a percentage in translateY
   resolves against the SATELLITE's own height, not the circle, which is what put every icon
   in a heap in the middle. */
/* Sized against the half it lives in, so the labels stay inside the frame. */
.ring-holder{position:relative;width:min(55vh,450px);aspect-ratio:1;--r:min(27.5vh,225px);
  animation:ringSpin 120s linear infinite}
.ring-holder .orbit{position:absolute;inset:0;border-radius:50%;border:1px dashed rgba(92,228,155,.34)}
.ring-holder .orbit.inner{inset:24%;border-style:solid;border-color:rgba(92,228,155,.16)}
/* Placement lives on the satellite; the counter-rotation that keeps the icon upright lives on
   the span INSIDE it — an animation on the same element would overwrite the placement. */
.ring-sat{position:absolute;left:50%;top:50%;width:54px;height:54px;margin:-27px 0 0 -27px;
  transform:rotate(var(--a)) translateY(calc(-1 * var(--r))) rotate(calc(-1 * var(--a)))}
.ring-sat span{display:grid;place-items:center;width:100%;height:100%;border-radius:16px;
  background:rgba(5,13,9,.82);border:1px solid rgba(92,228,155,.38);
  box-shadow:0 14px 34px -10px rgba(0,0,0,.85),0 0 30px -12px rgba(52,209,122,.5);
  animation:ringSpin 120s linear infinite reverse}
.ring-sat svg{width:23px;height:23px;fill:none;stroke:#5ce49b;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}

/* A tool that matters for THIS goal steps forward and says what it is; the rest recede so the
   circle still reads as one set rather than a menu. */
.ring-sat{transition:opacity .6s}
.ring-sat:not(.hot){opacity:.34}
.ring-sat.hot span{background:rgba(5,13,9,.8);border-color:rgba(92,228,155,.85);
  box-shadow:0 16px 40px -10px rgba(0,0,0,.9),0 0 44px -8px rgba(52,209,122,.85)}
.ring-sat.hot svg{stroke:#7dffb9}
.sat-label{position:absolute;left:50%;top:calc(100% + 9px);transform:translateX(-50%);
  display:none;text-align:center;white-space:nowrap;font-style:normal;pointer-events:none}
.ring-sat.hot .sat-label{display:block}
.sat-label b{display:block;font-size:14.5px;font-weight:820;letter-spacing:-.2px;color:#fff;
  text-shadow:0 2px 14px rgba(0,0,0,.95),0 0 30px rgba(0,0,0,.8)}
.sat-label i{display:block;font-style:normal;font-size:10.5px;font-weight:700;letter-spacing:1.1px;
  text-transform:uppercase;color:#5ce49b;text-shadow:0 1px 10px rgba(0,0,0,.9)}
@media(max-width:760px){
  .sat-label b{font-size:12px}
  .sat-label i{font-size:9px;letter-spacing:.8px}
}
@keyframes ringSpin{from{transform:rotate(0)}to{transform:rotate(360deg)}}

/* The goal itself sits dead centre and does not turn. A soft disc behind it so the name is
   readable over whatever is in the photograph. */
.goal-centre{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:5;
  text-align:center;width:min(46vh,380px);min-height:min(30vh,240px)}
/* Just enough to carry the words. At 400px this disc reached out under the satellites, so the
   icons sat on a dark blob instead of on the photograph. */
.goal-centre::before{content:"";position:absolute;left:50%;top:50%;width:min(30vh,250px);aspect-ratio:1;
  transform:translate(-50%,-50%);border-radius:50%;
  background:radial-gradient(circle,rgba(5,13,9,.78) 22%,rgba(5,13,9,.42) 55%,transparent 72%)}
/* Only the active goal is in the middle; the others are stacked underneath it, invisible. */
.goal-centre-item{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) scale(.94);
  width:min(46vh,380px);opacity:0;transition:opacity .7s cubic-bezier(.16,.84,.44,1),transform .7s cubic-bezier(.16,.84,.44,1)}
.goal-centre-item.on{opacity:1;transform:translate(-50%,-50%)}
.goal-centre .eyebrow{display:block;font-size:11.5px;font-weight:800;letter-spacing:2.4px;
  text-transform:uppercase;color:#5ce49b;margin-bottom:10px}
.goal-centre h3{margin:0;font-size:clamp(22px,3vw,36px);line-height:1.06;letter-spacing:-1.2px;
  font-weight:850;color:#fff;text-shadow:0 2px 34px rgba(0,0,0,.85)}
.goal-centre p{margin:12px 0 0;font-size:14.5px;color:rgba(234,245,238,.82);text-shadow:0 1px 18px rgba(0,0,0,.8)}

/* Under ~1100px the ring and the words can no longer share a row — measured: at 1024 the
   satellites printed straight over the paragraph. Below that they stack: ring in the upper
   half, words underneath. The ring also has to shrink, because a LABEL is far wider than the
   icon it belongs to and neighbours start colliding long before the icons do. */
@media(max-width:1100px){
  /* The ring steps aside. Stacking it above the words does not work: the text TRAVELS the full
     height as its beat scrolls (measured at 800px: text 260-486 crossing a ring at 51-453), and
     it cannot be pinned out of the way either, because .cinema has overflow:clip and therefore
     owns any sticky inside it. So on narrow screens the circle goes and the same five tools are
     said as chips under the text — the content survives, the collision cannot happen. */
  .ring-stage{display:none}
  #goals .beat{align-items:flex-end;padding-bottom:9vh}
  #goals .beat > .inner{width:min(560px,86vw)}
  .goal-chips{display:flex}
}

/* The narrow-screen stand-in for the ring: the goal's tools, in the goal's own words. */
.goal-chips{display:none;flex-wrap:wrap;gap:7px;margin-top:18px}
.goal-chips span{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:100px;
  background:rgba(5,13,9,.6);border:1px solid rgba(92,228,155,.4);backdrop-filter:blur(8px);
  font-size:12.5px;font-weight:750;color:#eaf5ee}
.goal-chips span i{font-style:normal;font-size:10px;font-weight:700;letter-spacing:.8px;
  text-transform:uppercase;color:#5ce49b}

/* ── the poster rail ────────────────────────────────────────────────────── */
.rail-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:16px}
.rail-head h2{font-size:clamp(22px,2.6vw,30px);letter-spacing:-.7px;font-weight:830;margin:0}
.rail-head a{font-size:13.5px;font-weight:700;color:var(--accent-text,#0f8f4c)}
.rail-wrap{position:relative}
.rail{display:flex;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;padding:6px 2px 18px;
  scrollbar-width:none;-ms-overflow-style:none}
.rail::-webkit-scrollbar{display:none}
.poster{position:relative;flex:0 0 268px;height:352px;border-radius:16px;overflow:hidden;
  scroll-snap-align:start;background:#0b1610;border:1px solid var(--glass-line-2,rgba(16,48,32,.14));
  box-shadow:var(--shadow-sm,0 16px 40px -20px rgba(15,50,33,.28));
  transition:transform .35s cubic-bezier(.16,.84,.44,1),box-shadow .35s,border-color .35s}
.poster:hover{transform:translateY(-8px) scale(1.02);box-shadow:0 40px 70px -24px rgba(0,0,0,.55);
  border-color:var(--accent-line,rgba(18,161,80,.34));z-index:2}
.poster img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top left;
  transition:transform .7s cubic-bezier(.16,.84,.44,1);opacity:.92}
.poster:hover img{transform:scale(1.07)}
.poster .veil{position:absolute;inset:0;background:linear-gradient(180deg,rgba(5,13,9,.05) 22%,rgba(5,13,9,.72) 62%,rgba(5,13,9,.95) 100%)}
.poster .txt{position:absolute;left:0;right:0;bottom:0;padding:18px 17px}
.poster .kicker{display:block;font-size:10.5px;font-weight:800;letter-spacing:1.6px;text-transform:uppercase;
  color:#5ce49b;margin-bottom:6px}
.poster h3{margin:0;font-size:19px;line-height:1.2;font-weight:830;color:#fff;letter-spacing:-.4px}
.poster p{margin:7px 0 0;font-size:13px;line-height:1.45;color:rgba(234,245,238,.78);
  max-height:0;opacity:0;overflow:hidden;transition:max-height .4s ease,opacity .3s ease}
.poster:hover p{max-height:80px;opacity:1}
.poster .no-shot{position:absolute;inset:0;background:
  radial-gradient(90% 70% at 30% 10%,rgba(52,209,122,.28),transparent 60%),
  linear-gradient(160deg,#0e2018,#050d09)}
.poster .ic-big{position:absolute;top:18px;left:17px;width:42px;height:42px;border-radius:13px;
  display:grid;place-items:center;background:rgba(52,209,122,.14);border:1px solid rgba(52,209,122,.3)}
.poster .ic-big svg{width:21px;height:21px;fill:none;stroke:#5ce49b;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.rail-nav{position:absolute;top:50%;transform:translateY(-50%);width:42px;height:42px;border-radius:50%;
  display:grid;place-items:center;cursor:pointer;z-index:5;border:1px solid var(--glass-line-2,rgba(16,48,32,.14));
  background:var(--glass-2,rgba(255,255,255,.78));backdrop-filter:blur(10px);
  box-shadow:var(--shadow-sm,0 16px 40px -20px rgba(15,50,33,.28));transition:transform .2s,opacity .2s}
.rail-nav:hover{transform:translateY(-50%) scale(1.08)}
.rail-nav[hidden]{display:none}
.rail-nav svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.rail-nav.prev{left:-14px}
.rail-nav.next{right:-14px}
@media(max-width:760px){.rail-nav{display:none}.poster{flex-basis:220px;height:300px}}

/* ── a photograph behind the hero ───────────────────────────────────────── */
header.has-photo{position:relative;isolation:isolate;overflow:clip}
header.has-photo .hero-photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:60% 35%;z-index:-2;animation:heroPush 24s ease-out both}
@keyframes heroPush{from{transform:scale(1.14)}to{transform:scale(1)}}
/* Readability first: the photograph is a room, not a background image to fight the type. */
header.has-photo .hero-photo__scrim{position:absolute;inset:0;z-index:-1;
  background:linear-gradient(90deg,var(--bg) 6%,rgba(238,243,239,.82) 38%,rgba(238,243,239,.42) 62%,rgba(238,243,239,.55)),
             linear-gradient(0deg,var(--bg),transparent 42%)}
:root[data-theme="dark"] header.has-photo .hero-photo__scrim{
  background:linear-gradient(90deg,var(--bg) 6%,rgba(7,17,12,.86) 38%,rgba(7,17,12,.5) 62%,rgba(7,17,12,.6)),
             linear-gradient(0deg,var(--bg),transparent 42%)}
header.has-photo .hero-grid{position:relative;z-index:1}

/* ── full-bleed photographic bands ──────────────────────────────────────── */
.bleed{position:relative;min-height:64vh;display:grid;align-items:center;overflow:clip;isolation:isolate;
  padding:70px 0;color:#fff}
.bleed--tall{min-height:80vh}
.bleed-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;z-index:-2;
  transform:scale(1.14);will-change:transform}
.bleed-scrim{position:absolute;inset:0;z-index:-1;
  background:linear-gradient(90deg,rgba(5,13,9,.9),rgba(5,13,9,.55) 45%,rgba(5,13,9,.25)),
             linear-gradient(0deg,rgba(5,13,9,.85),transparent 55%)}
.bleed-scrim--center{background:radial-gradient(90% 80% at 50% 50%,rgba(5,13,9,.55),rgba(5,13,9,.88))}
.bleed-body .big{font-size:clamp(26px,4.2vw,50px);line-height:1.12;letter-spacing:-1.4px;font-weight:850;
  max-width:20ch;margin:0;text-shadow:0 2px 40px rgba(0,0,0,.5)}
.bleed-body .attrib{display:block;margin-top:18px;font-size:13.5px;font-weight:700;letter-spacing:1.4px;
  text-transform:uppercase;color:#5ce49b}
/* The immersive section carries more than a line, so it gets a readable measure and its own
   three-column stand instead of the centred single sentence the other bleeds use. */
/* var(--maxw), not none. 'none' was meant to release the 20ch measure that .big carries, but
   .bleed-body IS the .wrap, so it released the page width too — this was the one section on the
   page whose text ran edge to edge while every other section stayed in the column. */
.bleed--split .bleed-body{max-width:var(--maxw);width:min(var(--maxw),100%);justify-self:center}
.bleed--split .eyebrow{display:block;font-size:11.5px;font-weight:800;letter-spacing:2.6px;
  text-transform:uppercase;color:#5ce49b;margin-bottom:14px}
.bleed--split h2{font-size:clamp(28px,4.4vw,54px);line-height:1.05;letter-spacing:-1.6px;font-weight:850;
  margin:0;text-shadow:0 2px 40px rgba(0,0,0,.6)}
.imm-lead{max-width:56ch;margin:18px 0 0;font-size:17px;color:rgba(234,245,238,.88);
  text-shadow:0 1px 22px rgba(0,0,0,.7)}
.imm-points{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:16px;margin:30px 0 28px;
  max-width:1000px}
.imm-point{padding:17px 18px;border-radius:15px;background:rgba(5,13,9,.55);
  border:1px solid rgba(92,228,155,.28);backdrop-filter:blur(9px)}
.imm-point h3{margin:0 0 7px;font-size:15.5px;font-weight:820;color:#fff;letter-spacing:-.2px}
.imm-point p{margin:0;font-size:13.5px;line-height:1.5;color:rgba(234,245,238,.8)}
/* "To grow. To gather." — the second half in the accent, because the whole point of the line is
   that the two words were one word all along. Same treatment as the act titles on the list. */
.bleed--grow .grow-em{color:#5ce49b}
/* Three scales, numbered like chapters rather than bulleted like a spec sheet. */
.grow-scales{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:18px;margin-top:30px;max-width:1060px}
.grow-scale{position:relative;padding:22px 20px 20px;border-radius:16px;
  background:rgba(5,13,9,.55);border:1px solid rgba(92,228,155,.26)}
.grow-scale .n{position:absolute;top:-14px;left:20px;width:30px;height:30px;border-radius:50%;
  display:grid;place-items:center;font-size:13px;font-weight:850;color:#04140a;
  background:linear-gradient(140deg,#34d17a,#12a150);box-shadow:0 10px 24px -8px rgba(18,161,80,.9)}
.grow-scale .k{display:block;margin-top:6px;font-size:10.5px;font-weight:800;letter-spacing:1.6px;
  text-transform:uppercase;color:#5ce49b}
.grow-scale h3{margin:6px 0 8px;font-size:19px;font-weight:830;color:#fff;letter-spacing:-.3px}
.grow-scale p{margin:0;font-size:14px;line-height:1.55;color:rgba(234,245,238,.82)}

/* ── the product tour ───────────────────────────────────────────────────────
   One browser window, the real screens moving through it. Cross-fade with a small drift, so a
   screen ARRIVES rather than blinking into place. */
.tour{display:grid;gap:16px}
.tour-window{border-radius:18px;overflow:hidden;border:1px solid var(--glass-line-2,rgba(16,48,32,.14));
  box-shadow:var(--shadow,0 30px 70px -26px rgba(15,50,33,.35));background:var(--surface-2,#fff)}
.tour-window .bar{display:flex;align-items:center;gap:7px;padding:10px 14px;
  background:var(--glass-2,rgba(255,255,255,.78));border-bottom:1px solid var(--glass-line,rgba(255,255,255,.85))}
.tour-window .bar i{width:9px;height:9px;border-radius:50%;background:var(--track-bg,rgba(16,48,32,.09));display:block}
.tour-window .bar .u{margin-left:8px;font-size:11.5px;color:var(--muted-2,#8aa294)}
.tour-window .live-dot{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-size:11px;
  font-weight:750;color:var(--accent-text,#0f8f4c)}
.tour-window .live-dot span{width:7px;height:7px;border-radius:50%;background:var(--accent,#34d17a);
  box-shadow:0 0 0 0 rgba(52,209,122,.7);animation:tourPulse 2.4s ease-out infinite}
@keyframes tourPulse{0%{box-shadow:0 0 0 0 rgba(52,209,122,.6)}70%{box-shadow:0 0 0 9px rgba(52,209,122,0)}100%{box-shadow:0 0 0 0 rgba(52,209,122,0)}}
.tour-stage{position:relative;aspect-ratio:16/10;background:var(--surface-2,#fff)}
.tour-slide{position:absolute;inset:0;margin:0;opacity:0;transform:scale(1.02) translateY(8px);
  transition:opacity .8s cubic-bezier(.16,.84,.44,1),transform .9s cubic-bezier(.16,.84,.44,1)}
.tour-slide.on{opacity:1;transform:none}
.tour-slide img{width:100%;height:100%;object-fit:contain;object-position:top center;display:block}

.tour-tabs{display:flex;flex-wrap:wrap;gap:8px}
.tour-tab{position:relative;display:inline-flex;align-items:center;gap:8px;padding:8px 14px;border-radius:100px;
  cursor:pointer;font-family:inherit;font-size:13px;font-weight:700;overflow:hidden;
  background:var(--glass,rgba(255,255,255,.55));color:var(--muted,#5b7365);
  border:1px solid var(--glass-line-2,rgba(16,48,32,.14));transition:color .2s,border-color .2s}
.tour-tab:hover{color:var(--text,#0d1a12)}
.tour-tab.on{color:var(--text,#0d1a12);border-color:var(--accent-line,rgba(18,161,80,.34))}
.tour-tab .ic{width:22px;height:22px;border-radius:7px;display:grid;place-items:center;
  background:var(--accent-soft,rgba(52,209,122,.14));border:1px solid var(--accent-line,rgba(18,161,80,.34))}
.tour-tab .ic svg{width:13px;height:13px;fill:none;stroke:var(--accent-text,#0f8f4c);stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
/* The bar fills while this screen is on show — the page saying how long it will stay. */
.tour-tab .bar{position:absolute;left:0;bottom:0;height:2px;width:0;
  background:linear-gradient(90deg,var(--accent-2,#12a150),var(--accent,#34d17a))}
.tour-tab.on .bar{animation:tourFill 5s linear forwards}
@keyframes tourFill{from{width:0}to{width:100%}}
.tour-cta{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:20px}
.tour-hint{font-size:13px;color:var(--muted-2,#8aa294)}
@media (prefers-reduced-motion:reduce){
  .tour-slide{transition:none}
  .tour-tab.on .bar{animation:none;width:100%}
  .tour-window .live-dot span{animation:none}
}

/* ── title cards ────────────────────────────────────────────────────────────
   A held black frame with one line on it, between acts. It costs a screen of scrolling and
   buys the thing a feature list can never have: a pause before the next idea. */
.titlecard{position:relative;min-height:78vh;display:grid;place-items:center;text-align:center;
  background:#050d09;color:#fff;overflow:clip;padding:60px 0}
.titlecard::before{content:"";position:absolute;inset:0;
  background:radial-gradient(70% 60% at 50% 50%,rgba(52,209,122,.14),transparent 70%)}
.titlecard .wrap{position:relative;z-index:2}
.titlecard .rule{width:44px;height:2px;margin:0 auto 22px;border-radius:2px;
  background:linear-gradient(90deg,#12a150,#34d17a)}
.titlecard h2{margin:0;font-size:clamp(28px,5.2vw,62px);line-height:1.05;letter-spacing:-2px;font-weight:850;
  max-width:20ch;margin-inline:auto}
.titlecard p{margin:20px auto 0;max-width:52ch;font-size:17px;color:#9db3a6}
.titlecard .big-num{display:block;font-size:clamp(60px,12vw,150px);line-height:.92;font-weight:850;
  letter-spacing:-4px;background:linear-gradient(120deg,#12a150,#34d17a 55%,#5ce49b);
  -webkit-background-clip:text;background-clip:text;color:transparent;margin-bottom:6px}

.bleed-body--center{text-align:center}
.bleed-body--center h2{font-size:clamp(27px,4.4vw,52px);line-height:1.08;letter-spacing:-1.5px;font-weight:850;
  margin:0;text-shadow:0 2px 40px rgba(0,0,0,.55)}
.bleed-body--center p{margin:16px 0 26px;font-size:17px;color:rgba(234,245,238,.9)}
.bleed-btn{display:inline-flex;align-items:center;gap:9px;padding:15px 32px;border-radius:100px;
  background:linear-gradient(140deg,var(--accent,#34d17a),var(--accent-2,#12a150));color:#04140a;
  font-weight:850;font-size:16px;box-shadow:0 20px 44px -12px rgba(18,161,80,.8);transition:transform .2s}
.bleed-btn:hover{transform:translateY(-2px)}

/* ── the light act ──────────────────────────────────────────────────────────
   The rest of the page keeps its glass look, but the bands underneath it get the same
   treatment at a whisper: a soft top light, a grain, and a hairline between sections so
   the page reads as scenes rather than as a stack of boxes. */
body{background-attachment:fixed}
section{position:relative}
section + section::before{content:"";position:absolute;left:12%;right:12%;top:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--glass-line-2,rgba(16,48,32,.14)),transparent)}
#stack,#cocentric,#product,#compare{isolation:isolate}
#stack::after,#cocentric::after,#product::after,#compare::after{content:"";position:absolute;inset:0;
  z-index:-1;pointer-events:none;
  background:radial-gradient(75% 45% at 50% 0%,var(--accent-soft,rgba(52,209,122,.14)),transparent 70%)}
/* One grain for the whole light half — fixed, so it does not swim while scrolling. */
body::after{content:"";position:fixed;inset:0;z-index:2;pointer-events:none;opacity:.035;display:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
  background-size:140px 140px;mix-blend-mode:multiply}
:root[data-theme="dark"] body::after{mix-blend-mode:screen;opacity:.05}

@media (prefers-reduced-motion:reduce){
  .stage .plate{transition:none}
  .beat{opacity:1}
  .poster,.poster img,.poster p{transition:none}
  .reel .lights span{animation:none}
}

/* Every other satellite carries its label a little further out, so two lit neighbours cannot
   print over each other. */
.ring-sat--far .sat-label{top:calc(100% + 26px)}
.ring-sat--far .sat-label::before{content:"";position:absolute;left:50%;top:-22px;width:1px;height:18px;
  background:linear-gradient(180deg,transparent,rgba(92,228,155,.5))}
