/* ============================================================================
   Sky Green Energy 'N' Power — Design System
   Style:      Organic Biophilic  (light, daylight-lit)
   Palette:    sampled from the company logo —
               navy #142664 · emerald #00A859 · leaf #3CB44A · lime #B6DD26
   Type:       Outfit (display) · Work Sans (body) · Space Mono (technical)
   Dials:      variance 7 · motion 9 · density 4
   ========================================================================= */

/* ---------- 1. Tokens --------------------------------------------------- */
:root {
  /* Surfaces — 900 is the page itself, each step down is more raised */
  --ink-900:#ffffff; --ink-850:#f5f9f3; --ink-800:#ebf2e7; --ink-700:#dfead9;
  --ink-600:#d2e0ca; --ink-500:#c3d5b9;

  /* Brand navy — straight off the wordmark */
  --navy-900:#0b1638; --navy-800:#142664; --navy-700:#1d3585; --navy-600:#2b47a6;

  /* Foreground */
  --fg:#2b3a46; --fg-strong:#142664; --fg-muted:#4e5f6d; --fg-faint:#64798a;

  /* Brand green — 500 is the logo emerald, 400 the wordmark leaf */
  --brand-300:#b6dd26; --brand-400:#3cb44a; --brand-500:#00a859;
  --brand-600:#00874c; --brand-700:#00733d; --brand-900:#014a29;
  --lime-400:#b6dd26; --lime-300:#cde95c;

  /* --brand-ink is "green that is safe to set text in on this surface".
     Dark islands (.ctaband, .footer) re-point it at the lime. */
  --brand-ink:#00733d;

  /* Solar — the light itself. 300/400 are fills, 600/700 are text-safe. */
  --solar-200:#fde68a; --solar-300:#fcd34d; --solar-400:#fbbf24; --solar-500:#f59e0b;
  --solar-600:#a66b00; --solar-700:#8a5a00;

  --danger:#c0271a; --danger-ink:#7f1d1d; --danger-soft:#fef2f2;

  /* Lines & tints — navy at low alpha keeps every edge in the same family */
  --line:rgba(20,38,100,.12);
  --line-strong:rgba(20,38,100,.24);
  --glass:rgba(20,38,100,.028);
  --glass-2:rgba(0,168,89,.06);

  /* Type */
  --font-display:'Outfit',system-ui,-apple-system,'Segoe UI',sans-serif;
  --font-body:'Work Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  --font-mono:'Space Mono',ui-monospace,SFMono-Regular,Menlo,monospace;

  /* The mono micro-label tier: breadcrumbs, stat keys, legends, footer heads.
     These had drifted into five hand-written sizes between .64 and .7rem, i.e.
     10.2-11.2px, which is below a comfortable floor for real words. One token,
     12px and up, keeps them a system instead of a habit. */
  --fs-label:clamp(.75rem,.73rem + .1vw,.8rem);
  --fs-kicker:clamp(.75rem,.72rem + .16vw,.82rem);
  --fs-body:clamp(1rem,.97rem + .16vw,1.075rem);
  --fs-lead:clamp(1.1rem,1.03rem + .42vw,1.35rem);
  --fs-h4:clamp(1.1rem,1.04rem + .3vw,1.3rem);
  --fs-h3:clamp(1.35rem,1.2rem + .7vw,1.85rem);
  --fs-h2:clamp(1.9rem,1.5rem + 2vw,3.1rem);
  --fs-h1:clamp(2.6rem,1.75rem + 4.1vw,5.4rem);
  --fs-mega:clamp(3.2rem,1.9rem + 6vw,7.5rem);

  /* Space — density 4/10 (standard) */
  --s-1:4px;  --s-2:8px;  --s-3:12px; --s-4:16px; --s-5:24px;
  --s-6:32px; --s-7:48px; --s-8:64px; --s-9:96px; --s-10:128px;

  /* Organic radii */
  --r-xs:8px; --r-sm:12px; --r-md:18px; --r-lg:24px; --r-xl:32px; --r-pill:999px;

  /* Elevation — light and diffuse, tinted navy rather than black */
  --sh-1:0 1px 2px rgba(20,38,100,.07);
  --sh-2:0 10px 28px -14px rgba(20,38,100,.18);
  --sh-3:0 26px 60px -30px rgba(20,38,100,.26);
  --glow-brand:0 0 0 1px rgba(0,168,89,.3),0 16px 40px -20px rgba(0,168,89,.4);
  --glow-solar:0 0 0 1px rgba(251,191,36,.55),0 16px 40px -18px rgba(245,158,11,.45);

  /* Motion */
  --e-out:cubic-bezier(.22,1,.36,1);
  --e-in-out:cubic-bezier(.65,0,.35,1);
  --e-back:cubic-bezier(.34,1.4,.64,1);
  --t-fast:140ms; --t-mid:260ms; --t-slow:520ms;

  --shell:1240px;
  --header-h:76px;
  color-scheme:light;
}

/* ---------- 2. Reset --------------------------------------------------- */
*,*::before,*::after{box-sizing:border-box}
*{margin:0}
/* The reveal offsets translate elements up to 30px sideways before they play,
   and a transform still counts toward the scrollable overflow area — the
   /solutions/ gallery handed phones 10px of sideways scroll until it revealed.
   The fix has to be clip, not hidden: hidden on body makes BODY the scroll
   container, and a sticky element whose scroll container never scrolls never
   sticks — measured, and it silently killed the cinema pin. clip creates no
   scroll container, so the pin survives. (Safari 15 has no clip; there it
   scrolls the 10px rather than losing the pin, which is the better trade.) */
html{-webkit-text-size-adjust:100%;overflow-x:clip}
html:focus-within{scroll-behavior:smooth}
body{
  font-family:var(--font-body);
  font-size:var(--fs-body);
  line-height:1.65;
  color:var(--fg);
  background:var(--ink-900);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:clip;
}
img,svg,video,canvas{display:block;max-width:100%}
img{height:auto}
button,input,select,textarea{font:inherit;color:inherit}
a{color:inherit;text-decoration:none}
ul[class],ol[class]{list-style:none;padding:0}
h1,h2,h3,h4,h5{font-family:var(--font-display);line-height:1.06;font-weight:600;letter-spacing:-.02em;text-wrap:balance}
p{text-wrap:pretty}
:target{scroll-margin-top:calc(var(--header-h) + 24px)}

/* Focus — always visible (never removed) */
:focus-visible{
  outline:3px solid var(--brand-500);
  outline-offset:3px;
  border-radius:6px;
}
::selection{background:rgba(0,168,89,.22);color:var(--navy-800)}

/* ---------- 3. Layout helpers ------------------------------------------ */
.shell{width:100%;max-width:var(--shell);margin-inline:auto;padding-inline:clamp(20px,5vw,40px)}
.shell--wide{max-width:1500px}
.shell--narrow{max-width:820px}
.section{position:relative;padding-block:clamp(64px,9vw,var(--s-10))}
.section--tight{padding-block:clamp(48px,6vw,var(--s-8))}
.stack>*+*{margin-top:var(--s-4)}
.grid{display:grid;gap:var(--s-5)}
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.skip-link{
  position:fixed;top:10px;left:10px;z-index:200;
  padding:12px 20px;border-radius:var(--r-pill);
  background:var(--solar-300);color:#231600;font-weight:600;
  transform:translateY(-160%);transition:transform var(--t-mid) var(--e-out);
}
.skip-link:focus-visible{transform:translateY(0)}

/* ---------- 4. Type utilities ------------------------------------------ */
.kicker{
  font-family:var(--font-mono);font-size:var(--fs-kicker);
  letter-spacing:.22em;text-transform:uppercase;color:var(--brand-ink);
  display:inline-flex;align-items:center;gap:10px;
  /* tracked-out mono in a narrow column has to be allowed to wrap, or it
     simply runs off the side of a phone */
  flex-wrap:wrap;max-width:100%;
}
@media (max-width:560px){ .kicker{letter-spacing:.13em} }
.kicker::before{
  content:"";width:26px;height:1px;background:linear-gradient(90deg,transparent,var(--brand-400));
}
.kicker--solar{color:var(--solar-700)}
.kicker--solar::before{background:linear-gradient(90deg,transparent,var(--solar-400))}
.h1{font-size:var(--fs-h1)}
.h2{font-size:var(--fs-h2)}
.h3{font-size:var(--fs-h3)}
.h4{font-size:var(--fs-h4);letter-spacing:-.01em}
.lead{font-size:var(--fs-lead);color:var(--fg-muted);line-height:1.55;max-width:62ch}
.muted{color:var(--fg-muted)}
.faint{color:var(--fg-faint)}
.tabular{font-variant-numeric:tabular-nums}
.sun-text{
  background:linear-gradient(96deg,var(--solar-600),var(--brand-600) 52%,var(--navy-800));
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.leaf-text{
  background:linear-gradient(96deg,var(--brand-600),var(--navy-800));
  -webkit-background-clip:text;background-clip:text;color:transparent;
}

/* ---------- 5. Buttons -------------------------------------------------- */
.btn{
  --btn-bg:var(--brand-700);
  --btn-fg:#ffffff;
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  gap:10px;min-height:52px;padding:14px 28px;
  /* a label is a label: never stack "Get a free site survey" into three lines */
  white-space:nowrap;
  font-family:var(--font-display);font-size:1rem;font-weight:600;letter-spacing:.01em;
  color:var(--btn-fg);background:var(--btn-bg);
  border:1px solid transparent;border-radius:var(--r-pill);
  cursor:pointer;isolation:isolate;overflow:hidden;
  transition:transform var(--t-mid) var(--e-out),box-shadow var(--t-mid) var(--e-out),
             background-color var(--t-mid) var(--e-out),color var(--t-mid) var(--e-out),
             border-color var(--t-mid) var(--e-out);
  will-change:transform;
}
.btn::after{ /* sheen */
  content:"";position:absolute;inset:0;z-index:-1;
  background:linear-gradient(120deg,transparent 35%,rgba(255,255,255,.55) 50%,transparent 65%);
  transform:translateX(-120%);transition:transform 700ms var(--e-out);
}
.btn:hover{box-shadow:var(--glow-brand);transform:translateY(-2px)}
.btn:hover::after{transform:translateX(120%)}
.btn:active{transform:translateY(0) scale(.985)}
/* Icons ship as bare 24x24 symbols. In a nowrap flex line a shrinkable SVG
   collapses to nothing, and in a text flow it takes its intrinsic size, so each
   context states the size it wants and nothing is ever allowed to shrink. */
.btn svg,.kicker svg,.stage-hint svg{flex:0 0 auto}
.btn svg{width:18px;height:18px}
.kicker svg{width:14px;height:14px}
.stage-hint svg{width:13px;height:13px}
.btn__ico{width:18px;height:18px;flex:0 0 auto;transition:transform var(--t-mid) var(--e-out)}
.btn:hover .btn__ico{transform:translateX(3px)}

.btn--solar{--btn-bg:var(--solar-300);--btn-fg:#231600}
.btn--solar:hover{box-shadow:var(--glow-solar);--btn-bg:var(--solar-200)}
.btn--ghost{--btn-bg:transparent;--btn-fg:var(--fg);border-color:var(--line-strong)}
.btn--ghost:hover{--btn-bg:var(--glass-2);border-color:var(--brand-400);box-shadow:none}
.btn--sm{min-height:44px;padding:10px 20px;font-size:.94rem}
.btn--block{width:100%}

.link-arrow{
  display:inline-flex;align-items:center;gap:8px;min-height:44px;
  font-family:var(--font-display);font-weight:600;color:var(--brand-ink);
  cursor:pointer;transition:color var(--t-fast) var(--e-out);
}
.link-arrow svg{width:16px;height:16px;transition:transform var(--t-mid) var(--e-out)}
.link-arrow:hover{color:var(--solar-700)}
.link-arrow:hover svg{transform:translateX(4px)}

/* ---------- 6. Header / nav -------------------------------------------- */
.progress{
  position:fixed;inset:0 0 auto 0;height:3px;z-index:120;
  background:linear-gradient(90deg,var(--brand-400),var(--solar-300));
  transform:scaleX(0);transform-origin:0 50%;
  will-change:transform;pointer-events:none;
}
.header{
  position:fixed;inset:0 0 auto 0;z-index:110;
  height:var(--header-h);display:flex;align-items:center;
  transition:background-color var(--t-mid) var(--e-out),backdrop-filter var(--t-mid),
             border-color var(--t-mid);
  border-bottom:1px solid transparent;
}
.header.is-stuck{
  background:rgba(255,255,255,.84);
  -webkit-backdrop-filter:blur(16px) saturate(140%);backdrop-filter:blur(16px) saturate(140%);
  border-bottom-color:var(--line);
}
.header__inner{display:flex;align-items:center;justify-content:space-between;gap:var(--s-5);width:100%}
.brand{display:inline-flex;align-items:center;min-height:44px}
/* The logo is a fixed-ratio raster (960x253). Height drives it; width:auto keeps
   the ratio, and the intrinsic attributes on the <img> reserve the box so the
   header never shifts while it decodes. */
.brand__logo{
  height:clamp(30px,3.4vw,40px);width:auto;display:block;
  transition:transform var(--t-slow) var(--e-back);
}
.brand:hover .brand__logo{transform:scale(1.035)}
.brand__logo--onnavy{height:clamp(34px,4vw,46px)}

.nav{display:flex;align-items:center;gap:var(--s-1)}
.nav__link{
  position:relative;display:inline-flex;align-items:center;
  min-height:44px;padding:0 14px;border-radius:var(--r-pill);
  font-family:var(--font-display);font-weight:500;font-size:.96rem;color:var(--fg-muted);
  transition:color var(--t-fast) var(--e-out),background-color var(--t-fast) var(--e-out);
}
.nav__link::after{
  content:"";position:absolute;left:14px;right:14px;bottom:8px;height:2px;border-radius:2px;
  background:linear-gradient(90deg,var(--brand-400),var(--solar-300));
  transform:scaleX(0);transform-origin:0 50%;transition:transform var(--t-mid) var(--e-out);
}
.nav__link:hover{color:var(--fg)}
.nav__link:hover::after,.nav__link[aria-current="page"]::after{transform:scaleX(1)}
.nav__link[aria-current="page"]{color:var(--fg-strong)}
.header__cta{display:flex;align-items:center;gap:10px}

/* place-content:center, not place-items:center. Grid's default align-content is
   normal, which stretches auto rows -- so the three 2px bars sat in 16px rows,
   16px apart, and the open state's translateY(7px) could not bring the outer two
   onto the middle one: the X rendered as a chevron. Centring the row group keeps
   the 7px pitch the transform is written against. */
.burger{
  display:none;width:48px;height:48px;place-content:center;justify-items:center;
  background:var(--glass);border:1px solid var(--line);border-radius:14px;cursor:pointer;
  transition:border-color var(--t-fast),background-color var(--t-fast);
}
.burger:hover{border-color:var(--brand-400);background:var(--glass-2)}
.burger span{display:block;width:20px;height:2px;border-radius:2px;background:var(--fg);transition:transform var(--t-mid) var(--e-out),opacity var(--t-fast)}
.burger span+span{margin-top:5px}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* A column, not a two-row grid. The drawer has exactly two children, so
   grid-template-rows:var(--header-h) 1fr put the links in the 68px header row --
   five 64px links overflowing it, across the logo -- and handed the footer the
   whole 1fr, which stretched one button to 300px tall. The header row is padding
   now, and the column scrolls when a short landscape viewport cannot fit five
   links plus the footer. */
.drawer{
  position:fixed;inset:0;z-index:105;
  display:flex;flex-direction:column;
  padding-top:var(--header-h);
  overflow-y:auto;overscroll-behavior:contain;
  background:rgba(255,255,255,.97);
  -webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);
  /* visibility is stepped, not interpolated: 0s on open so the panel is focusable
     the moment the class lands (site.js focuses the first link, and focus() is
     refused on a visibility:hidden element), and delayed by the fade on close so
     it does not vanish before it has faded. */
  opacity:0;visibility:hidden;
  transition:opacity var(--t-mid) var(--e-out),visibility 0s linear var(--t-mid);
}
.drawer.is-open{opacity:1;visibility:visible;transition-delay:0s,0s}
.drawer__body{flex:1 0 auto;display:flex;flex-direction:column;justify-content:center;
  gap:var(--s-2);padding:var(--s-5) clamp(20px,5vw,40px) var(--s-6)}
.drawer__link{
  display:flex;align-items:center;justify-content:space-between;
  min-height:64px;padding:8px 4px;border-bottom:1px solid var(--line);
  font-family:var(--font-display);font-size:clamp(1.5rem,7vw,2.1rem);font-weight:600;
  color:var(--fg);opacity:0;transform:translateY(18px);
}
.drawer.is-open .drawer__link{animation:drawerIn 520ms var(--e-out) forwards}
.drawer__link i{font-family:var(--font-mono);font-size:var(--fs-label);font-style:normal;color:var(--brand-ink)}
.drawer__foot{flex:0 0 auto;display:grid;gap:var(--s-3);align-content:start;
  padding:0 clamp(20px,5vw,40px) calc(var(--s-7) + env(safe-area-inset-bottom,0px))}
@keyframes drawerIn{to{opacity:1;transform:none}}

/* ---------- 7. Canvas stage ------------------------------------------- */
.stage{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0}
/* The fallback gradient is the sky: the renderer clears with alpha 0 and draws
   over it. Both live in one stacking context and the fallback is positioned,
   so a static canvas paints *underneath* it — which hid every scene on the
   page behind its own gradient and made the hero look like it ignored drags. */
.stage canvas{position:relative;z-index:1;width:100%;height:100%;display:block}
.stage__fallback{
  position:absolute;inset:0;
  background:
    radial-gradient(120% 78% at 76% 8%,rgba(251,191,36,.5),transparent 56%),
    radial-gradient(90% 62% at 12% 92%,rgba(0,168,89,.2),transparent 62%),
    linear-gradient(178deg,#dbeefb 0%,#eef7ee 46%,#f8fbf6 100%);
}
/* A page-head scene is scenery behind a headline, not a picture of its own. At
   full strength its dark modules ran straight through 700-weight display type,
   so it is faded and masked away from the text column: present at the top right,
   gone by the words. The hero card is excluded — there it *is* the picture. */
.stage:not(.stage--card) canvas{
  opacity:.4;
  -webkit-mask-image:radial-gradient(115% 96% at 80% 26%,#000 24%,rgba(0,0,0,.42) 58%,transparent 84%);
          mask-image:radial-gradient(115% 96% at 80% 26%,#000 24%,rgba(0,0,0,.42) 58%,transparent 84%);
}
@media (max-width:719px){
  /* one column: the words sit under the whole scene, so it drops back further */
  .stage:not(.stage--card) canvas{opacity:.26}
}
.stage:not(.stage--card)::after{ /* atmospheric vignette + horizon lift */
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:
    radial-gradient(74% 54% at 50% 46%,transparent,rgba(255,255,255,.28) 80%,rgba(255,255,255,.6)),
    linear-gradient(to bottom,rgba(255,255,255,.35) 0%,transparent 20% 64%,var(--ink-900) 100%);
}

/* The hero stage is not a backdrop — it is a thing on the page you can grab.
   Hence its own box: raised, clipped, and pointer-interactive. */
.stage--card{
  position:relative;inset:auto;z-index:1;pointer-events:auto;
  aspect-ratio:1/1;width:100%;
  border:1px solid var(--line);border-radius:var(--r-xl);
  background:linear-gradient(178deg,#dbeefb,#f2f9f0 62%,#ffffff);
  box-shadow:var(--sh-3);
  cursor:grab;touch-action:pan-y;
}
.stage--card:active{cursor:grabbing}
.stage--card canvas{border-radius:inherit}
.stage--card canvas:focus-visible{outline:3px solid var(--brand-500);outline-offset:-3px;border-radius:inherit}
/* a hairline of brand light along the top edge, so the card reads as glass */
.stage--card::before{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  border-radius:inherit;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9),inset 0 0 0 1px rgba(20,38,100,.05);
}

.hero__viz{position:relative;display:grid;gap:var(--s-3)}
.stage__legend{
  display:flex;flex-wrap:wrap;gap:var(--s-2) var(--s-4);list-style:none;padding:0;margin:0;
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.13em;text-transform:uppercase;
  color:var(--fg-faint);
}
.stage__legend li{display:inline-flex;align-items:center;gap:7px}
.stage__legend i{width:9px;height:9px;border-radius:50%;flex:0 0 auto;background:var(--brand-500)}
.stage__legend li:nth-child(2) i{background:var(--solar-400)}
.stage__legend li:nth-child(3) i{background:var(--navy-800)}
.stage-hint{
  /* Centred by auto margins inside a full-width inset box, not by left:50%. With
     only a left edge an absolute box shrink-wraps to the space *right* of that
     edge -- half the card -- so the sentence broke into three lines at 820 while
     max-width sat unused. Insetting both sides gives it the whole width to size
     against, and drops the translateX() that state rules kept having to restore. */
  position:absolute;left:14px;right:14px;bottom:16px;margin-inline:auto;
  width:-webkit-max-content;width:max-content;max-width:100%;
  z-index:3;display:flex;align-items:center;gap:9px;
  padding:9px 16px;border-radius:var(--r-pill);
  background:rgba(255,255,255,.8);border:1px solid var(--line);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.14em;text-transform:uppercase;
  color:var(--fg-muted);pointer-events:none;text-align:center;
  transition:opacity var(--t-mid) var(--e-out),transform var(--t-mid) var(--e-out);
  animation:hintPulse 3.4s var(--e-in-out) infinite;
}
.stage-hint svg{width:14px;height:14px;color:var(--solar-600)}
@keyframes hintPulse{0%,100%{opacity:.5}50%{opacity:1}}

/* ---------- 8. Hero ---------------------------------------------------- */
.hero{
  position:relative;display:grid;align-items:center;
  min-height:clamp(620px,100svh,1000px);
  padding-top:calc(var(--header-h) + var(--s-7));
  padding-bottom:var(--s-8);
  isolation:isolate;
}
.hero__inner{position:relative;z-index:2}
.hero__grid{display:grid;gap:var(--s-6);align-items:center}
@media (min-width:1000px){
  .hero__grid{grid-template-columns:1.05fr .95fr;gap:clamp(32px,4vw,var(--s-8))}
  .hero__viz{align-self:center}
}
@media (max-width:999px){
  .hero__viz{max-width:520px;margin-inline:auto;width:100%}
}
.hero h1{font-size:var(--fs-h1);letter-spacing:-.035em;font-weight:700}
.hero__title-line{display:block;overflow:hidden}
.hero__lead{margin-top:var(--s-5);max-width:54ch}
.hero__actions{display:flex;flex-wrap:wrap;gap:var(--s-3);margin-top:var(--s-6)}
.hero__meta{
  display:flex;flex-wrap:wrap;gap:var(--s-5) var(--s-6);
  margin-top:var(--s-7);padding-top:var(--s-5);border-top:1px solid var(--line);
}
.hero__meta div{display:flex;flex-direction:column;gap:2px}
.hero__meta b{font-family:var(--font-display);font-size:clamp(1.5rem,1.2rem + 1.1vw,2.2rem);font-weight:700;letter-spacing:-.03em;color:var(--fg-strong)}
.hero__meta small{font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.18em;text-transform:uppercase;color:var(--fg-faint)}

/* Char-split animation target. The word wrapper is what keeps a headline from
   breaking mid-word: characters may only wrap where a real space is. */
.split-word{display:inline-block;white-space:nowrap}
.split-char{display:inline-block;will-change:transform,opacity}

/* Page header (inner pages) */
.pagehead{
  position:relative;isolation:isolate;
  min-height:clamp(400px,62svh,600px);
  display:grid;align-items:end;
  padding-top:calc(var(--header-h) + var(--s-8));padding-bottom:var(--s-8);
}
.pagehead__inner{position:relative;z-index:2;display:grid;gap:var(--s-4)}
.pagehead h1{font-size:var(--fs-h1);letter-spacing:-.035em;font-weight:700;max-width:22ch}
.crumbs{display:flex;flex-wrap:wrap;align-items:center;gap:8px;font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.12em;text-transform:uppercase;color:var(--fg-faint)}
.crumbs a{transition:color var(--t-fast)}
.crumbs a:hover{color:var(--brand-ink)}
.crumbs li{display:flex;align-items:center;gap:8px}
.crumbs li+li::before{content:"/";color:var(--brand-600)}
.crumbs ol{display:flex;flex-wrap:wrap;gap:8px;list-style:none;padding:0;margin:0}

/* ---------- 9. Cards --------------------------------------------------- */
.card{
  position:relative;display:flex;flex-direction:column;gap:var(--s-4);
  padding:clamp(22px,2.6vw,34px);
  background:linear-gradient(168deg,#ffffff,var(--ink-850));
  border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--sh-1);
  overflow:hidden;isolation:isolate;
  transition:border-color var(--t-mid) var(--e-out),transform var(--t-mid) var(--e-out),
             box-shadow var(--t-mid) var(--e-out);
}
.card::before{ /* cursor spotlight */
  content:"";position:absolute;inset:-1px;z-index:-1;opacity:0;
  background:radial-gradient(320px circle at var(--mx,50%) var(--my,0%),rgba(0,168,89,.14),transparent 62%);
  transition:opacity var(--t-mid) var(--e-out);
}
.card:hover{border-color:rgba(0,135,76,.4);transform:translateY(-4px);box-shadow:var(--sh-3)}
.card:hover::before{opacity:1}
.card__ico{
  width:56px;height:56px;display:grid;place-items:center;flex:0 0 auto;
  border-radius:var(--r-md);
  background:radial-gradient(120% 120% at 30% 20%,rgba(0,168,89,.16),rgba(0,135,76,.05));
  border:1px solid var(--line-strong);color:var(--brand-600);
  transition:transform var(--t-slow) var(--e-back),color var(--t-mid),border-color var(--t-mid);
}
.card__ico svg{width:26px;height:26px}
.card:hover .card__ico{transform:translateY(-3px) rotate(-6deg);color:var(--solar-600);border-color:rgba(245,158,11,.55)}
.card h3{font-size:var(--fs-h3)}
.card p{color:var(--fg-muted)}
.card__num{
  position:absolute;top:14px;right:20px;
  font-family:var(--font-display);font-size:3.6rem;font-weight:700;line-height:1;
  color:rgba(20,38,100,.055);letter-spacing:-.05em;pointer-events:none;user-select:none;
}
.card--tilt{transform-style:preserve-3d;will-change:transform}
.card--feature{gap:var(--s-5)}
.card--solar .card__ico{background:radial-gradient(120% 120% at 30% 20%,rgba(251,191,36,.26),rgba(245,158,11,.1));color:var(--solar-600);border-color:rgba(245,158,11,.42)}

.chips{display:flex;flex-wrap:wrap;gap:8px}
.chip{
  display:inline-flex;align-items:center;gap:7px;
  padding:7px 14px;border-radius:var(--r-pill);
  background:var(--glass);border:1px solid var(--line);
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.08em;
  color:var(--fg-muted);white-space:nowrap;
  transition:border-color var(--t-fast),color var(--t-fast),background-color var(--t-fast);
}
.chip svg{width:13px;height:13px;color:var(--brand-600);flex:0 0 auto}
.chip:hover{border-color:var(--brand-500);color:var(--fg)}

.ticklist{display:grid;gap:var(--s-3)}
.ticklist li{display:grid;grid-template-columns:22px 1fr;gap:12px;align-items:start;color:var(--fg-muted)}
.ticklist svg{width:22px;height:22px;color:var(--brand-600);margin-top:2px}
.ticklist strong{color:var(--fg);font-weight:600}

/* Cols */
.cols-2,.cols-3,.cols-4{display:grid;gap:var(--s-4)}
.cols-2{grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr))}
.cols-3{grid-template-columns:repeat(auto-fit,minmax(min(100%,290px),1fr))}
.cols-4{grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr))}
.split{display:grid;gap:clamp(32px,5vw,72px);align-items:center}
@media (min-width:900px){
  .split{grid-template-columns:1.05fr .95fr}
  .split--wide-left{grid-template-columns:1.25fr .75fr}
  .split--reverse>*:first-child{order:2}
}

/* ---------- 10. Section headings --------------------------------------- */
.sechead{display:grid;gap:var(--s-4);max-width:70ch;margin-bottom:clamp(36px,4.5vw,var(--s-8))}
.sechead--center{margin-inline:auto;text-align:center;justify-items:center}
.sechead--split{max-width:none}
@media (min-width:900px){
  .sechead--split{grid-template-columns:1fr auto;align-items:end;gap:var(--s-6)}
  .sechead--split .sechead__copy{max-width:60ch}
}
.sechead__copy{display:grid;gap:var(--s-4)}

/* ---------- 11. Stats -------------------------------------------------- */
.stats{
  display:grid;gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr));
}
.stat{
  display:grid;gap:6px;padding:clamp(24px,3vw,var(--s-6));
  background:var(--ink-850);position:relative;overflow:hidden;
  transition:background-color var(--t-mid) var(--e-out);
}
.stat::after{
  content:"";position:absolute;inset:auto 0 0 0;height:2px;
  background:linear-gradient(90deg,var(--brand-500),var(--solar-400));
  transform:scaleX(0);transform-origin:0 50%;transition:transform var(--t-slow) var(--e-out);
}
.stat:hover{background:var(--ink-800)}
.stat:hover::after{transform:scaleX(1)}
.stat__val{
  font-family:var(--font-display);font-weight:700;letter-spacing:-.04em;line-height:1;
  font-size:clamp(2.3rem,1.7rem + 2.4vw,3.6rem);color:var(--fg-strong);
  font-variant-numeric:tabular-nums;
}
.stat__val em{font-style:normal;font-size:.5em;color:var(--solar-700);margin-left:2px}
.stat__key{font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.16em;text-transform:uppercase;color:var(--fg-faint)}
.stat__note{font-size:.86rem;color:var(--fg-muted)}

/* ---------- 12. Marquee ------------------------------------------------ */
.marquee{
  position:relative;overflow:hidden;
  padding-block:var(--s-4);
  border-block:1px solid var(--line);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 9%,#000 91%,transparent);
}
.marquee__track{display:flex;width:max-content;gap:var(--s-6);animation:slide 42s linear infinite}
.marquee:hover .marquee__track,.marquee:focus-within .marquee__track{animation-play-state:paused}
.marquee__item{
  display:inline-flex;align-items:center;gap:12px;
  font-family:var(--font-display);font-size:clamp(1rem,.9rem + .5vw,1.3rem);
  font-weight:500;color:var(--fg-muted);white-space:nowrap;
}
.marquee__item svg{width:18px;height:18px;color:var(--brand-500);flex:0 0 auto}
@keyframes slide{from{transform:translateX(0)}to{transform:translateX(-50%)}}
.marquee__ctl{
  position:absolute;right:10px;top:50%;transform:translateY(-50%);z-index:2;
  width:44px;height:44px;display:grid;place-items:center;cursor:pointer;
  background:rgba(255,255,255,.86);border:1px solid var(--line);border-radius:var(--r-pill);
  color:var(--fg-muted);transition:color var(--t-fast),border-color var(--t-fast);
}
.marquee__ctl:hover{color:var(--fg);border-color:var(--brand-400)}
.marquee__ctl svg{width:16px;height:16px}
.marquee.is-paused .marquee__track{animation-play-state:paused}

/* ---------- 13. Tabs + 3D system explorer ------------------------------ */
.explorer{
  position:relative;border:1px solid var(--line);border-radius:var(--r-xl);
  background:linear-gradient(170deg,var(--ink-800),var(--ink-900));
  overflow:hidden;
}
.explorer__tabs{
  display:flex;flex-wrap:wrap;gap:6px;padding:var(--s-4);
  border-bottom:1px solid var(--line);background:rgba(20,38,100,.03);
}
.tab{
  display:inline-flex;align-items:center;gap:9px;min-height:48px;padding:10px 20px;
  border-radius:var(--r-pill);border:1px solid transparent;background:transparent;
  font-family:var(--font-display);font-weight:600;font-size:.96rem;color:var(--fg-muted);
  cursor:pointer;transition:all var(--t-mid) var(--e-out);
}
.tab svg{width:18px;height:18px}
.tab:hover{color:var(--fg);background:var(--glass-2)}
.tab[aria-selected="true"]{
  color:var(--navy-800);background:linear-gradient(100deg,var(--solar-300),var(--brand-300));
  border-color:transparent;box-shadow:var(--glow-solar);
}
.explorer__stage{
  position:relative;isolation:isolate;
  /* Height-led, not aspect-led: with aspect-ratio:16/10 and max-height:600 the
     box stopped growing at 902px inside a 1090px column and sat left-aligned
     with a pale strip beside it, which reads as a bug rather than a frame. */
  height:clamp(340px,50vw,600px);
  /* An instrument viewport, deliberately dark: the diagram is drawn with
     additive glow, which would simply vanish against a white page. Same
     dark-island trick as .ctaband — re-point the tokens the descendants
     already read, and the labels invert with it. */
  background:
    radial-gradient(72% 62% at 50% 22%,rgba(0,168,89,.22),transparent 64%),
    radial-gradient(60% 70% at 8% 92%,rgba(251,191,36,.12),transparent 62%),
    linear-gradient(168deg,var(--navy-800),var(--navy-900));
  /* inheritance, not just tokens: a heading with no color of its own would
     otherwise inherit the light theme ink and vanish into this surface */
  color:var(--fg);
  --fg:#edf2ff; --fg-strong:#ffffff; --fg-muted:#bfcae8; --fg-faint:#9fb0d6;
  --brand-ink:var(--lime-400);
  --line:rgba(255,255,255,.16); --line-strong:rgba(255,255,255,.3);
  --glass:rgba(255,255,255,.07);
  cursor:grab;touch-action:pan-y;
}
.explorer__stage:active{cursor:grabbing}
.explorer__stage canvas{width:100%;height:100%}
.explorer__labels{position:absolute;inset:0;pointer-events:none;overflow:clip}
.node-label{
  position:absolute;transform:translate(-50%,-50%);
  display:flex;flex-direction:column;align-items:center;gap:3px;
  padding:7px 13px;border-radius:var(--r-pill);
  background:rgba(11,22,56,.72);border:1px solid var(--line-strong);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.1em;text-transform:uppercase;
  color:var(--fg);white-space:nowrap;
  transition:opacity var(--t-mid) var(--e-out);
}
.node-label b{font-family:var(--font-display);font-size:.82rem;letter-spacing:0;text-transform:none;font-weight:600}
.node-label[data-dim="true"]{opacity:.44}   /* a ghosted component still has to be readable, not a rumour */
.explorer__panel{padding:clamp(22px,3vw,var(--s-6));border-top:1px solid var(--line);display:grid;gap:var(--s-4)}
.explorer__panel[hidden]{display:none}
.explorer__hint{
  /* inline-flex, not the default block: the arrow is an svg, the reset gives it
     display:block, and in a block parent it took a line of its own above the
     words instead of sitting beside them. */
  position:absolute;left:16px;bottom:14px;z-index:2;
  display:inline-flex;align-items:center;gap:9px;
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.14em;text-transform:uppercase;
  color:var(--fg-faint);pointer-events:none;
}
.explorer__hint svg{width:14px;height:14px;flex:0 0 auto}
.explorer__flow{display:flex;flex-wrap:wrap;gap:10px}
.flowtag{
  display:inline-flex;align-items:center;gap:7px;padding:6px 13px;border-radius:var(--r-pill);
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.1em;text-transform:uppercase;
  background:rgba(0,168,89,.09);border:1px solid rgba(0,135,76,.28);color:var(--brand-ink);
}
.flowtag--off{background:var(--glass);border-color:var(--line);color:var(--fg-faint)}
.flowtag svg{width:13px;height:13px}
/* the edge tags float over the dark viewport, so they need their own weight */
.explorer__labels .flowtag{
  background:rgba(11,22,56,.66);border-color:rgba(182,221,38,.42);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
}
/* An off conduit is not drawn at all, so its tag has nothing to label. Greying
   it left EXPORT and IMPORT floating beside an unconnected grid in off-grid. */
.explorer__labels .flowtag--off{display:none}
/* Twelve pills — six nodes, six edges — in a 313px square stage collide into an
   unreadable pile; measured on a 390px phone. The edge tags are the ones the
   page already says in words (the mode panel and its flow row sit directly
   below), so they are the ones that go, and the node labels get tighter so the
   six that remain clear each other. */
/* Words need room. At 820 the stage is ~780x410 and twelve word pills still
   piled on each other, so the numbered treatment runs up to 900, not 720. */
@media (max-width:899px){
  .explorer__labels .flowtag{display:none}
  .node-label{
    width:26px;height:26px;padding:0;place-content:center;border-radius:50%;
    letter-spacing:0;font-size:.8rem;color:var(--fg-strong);
  }
  .node-label i{display:none}
  .node-label::before{content:attr(data-i)}
  /* the chips under the stage are the key to those numbers */
  .explorer__panel .chip[data-n]::before{
    content:attr(data-n);margin-right:7px;color:var(--brand-ink);
    font-family:var(--font-mono);font-size:.9em;
  }
}
.node-label i{font-style:normal}

/* ---------- 14. Accordion ---------------------------------------------- */
.acc{display:grid;gap:var(--s-3)}
.acc__item{border:1px solid var(--line);border-radius:var(--r-md);background:var(--glass);overflow:hidden;transition:border-color var(--t-mid)}
.acc__item:has(.acc__btn[aria-expanded="true"]){border-color:var(--line-strong);background:var(--glass-2)}
.acc__btn{
  display:flex;align-items:center;justify-content:space-between;gap:var(--s-4);
  width:100%;min-height:64px;padding:18px 22px;
  background:transparent;border:0;text-align:left;cursor:pointer;
  font-family:var(--font-display);font-size:var(--fs-h4);font-weight:600;color:var(--fg);
  transition:color var(--t-fast)}
.acc__btn:hover{color:var(--brand-ink)}
.acc__btn i{
  flex:0 0 auto;width:30px;height:30px;display:grid;place-items:center;
  border:1px solid var(--line-strong);border-radius:50%;
  transition:transform var(--t-mid) var(--e-out),background-color var(--t-mid),border-color var(--t-mid);
}
.acc__btn i svg{width:14px;height:14px}
.acc__btn[aria-expanded="true"] i{transform:rotate(180deg);background:var(--brand-600);border-color:transparent;color:#fff}
.acc__panel{overflow:hidden;height:0}
.acc__panel>div{padding:0 22px 22px;color:var(--fg-muted);display:grid;gap:var(--s-3)}

/* ---------- 15. Timeline ----------------------------------------------- */
.timeline{position:relative;display:grid;gap:var(--s-6);padding-left:var(--s-6)}
.timeline__line{
  position:absolute;left:7px;top:8px;bottom:8px;width:2px;
  background:linear-gradient(180deg,var(--brand-500),var(--solar-400),transparent);
  transform-origin:50% 0;
}
.timeline:not(:has(.timeline__line))::before{
  content:"";position:absolute;left:7px;top:8px;bottom:8px;width:2px;
  background:linear-gradient(180deg,var(--brand-500),var(--solar-400),transparent);
}
.timeline__item{position:relative;display:grid;gap:8px}
.timeline__item::before{
  content:"";position:absolute;left:calc(-1 * var(--s-6) + 1px);top:9px;
  width:14px;height:14px;border-radius:50%;
  background:var(--ink-900);border:2px solid var(--brand-400);
  box-shadow:0 0 0 4px rgba(0,168,89,.16);
}
.timeline__yr{font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.16em;color:var(--solar-700)}
.timeline__item h3{font-size:var(--fs-h4)}
.timeline__item p{color:var(--fg-muted)}

/* ---------- 16. Gallery ------------------------------------------------ */
.gallery{display:grid;gap:var(--s-4);grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr))}
.shot{
  position:relative;display:block;overflow:hidden;
  border-radius:var(--r-lg);border:1px solid var(--line);
  background:linear-gradient(160deg,var(--ink-700),var(--ink-850));
  aspect-ratio:4/3;isolation:isolate;
}
.shot--tall{aspect-ratio:3/4}
.shot--wide{aspect-ratio:16/9;grid-column:span 2}
@media (max-width:640px){.shot--wide{grid-column:span 1}}
.shot img{width:100%;height:100%;object-fit:cover;transition:transform 900ms var(--e-out),filter var(--t-slow)}
.shot:hover img{transform:scale(1.06)}
/* A third dark island (see .ctaband): the caption sits on a dark scrim over the
   photo, so it re-points the tokens its own children already read rather than
   overriding each one. Without this the caption inherits the light theme's dark
   --fg and goes dark-on-dark the moment a real photo is behind it. */
.shot__body{
  position:absolute;inset:auto 0 0 0;z-index:2;
  display:grid;gap:4px;padding:var(--s-5) var(--s-4) var(--s-4);
  background:linear-gradient(to top,rgba(4,20,15,.93),rgba(4,20,15,.55) 55%,transparent);
  --fg:#edf2ff; --fg-strong:#ffffff; --brand-ink:var(--lime-400);
  color:var(--fg);text-shadow:0 1px 12px rgba(2,12,9,.55);
}
.shot__body b{font-family:var(--font-display);font-weight:600;font-size:1.05rem;color:var(--fg-strong)}
.shot__body span{font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.14em;text-transform:uppercase;color:var(--brand-ink)}
.shot__ph{
  position:absolute;inset:0;display:grid;place-items:center;
  background:
    linear-gradient(115deg,rgba(0,168,89,.1),transparent 55%),
    repeating-linear-gradient(60deg,rgba(20,38,100,.05) 0 1px,transparent 1px 14px),
    repeating-linear-gradient(-60deg,rgba(20,38,100,.05) 0 1px,transparent 1px 14px);
  color:rgba(20,38,100,.2);
}
.shot__ph svg{width:64px;height:64px}

/* ---------- 17. Forms -------------------------------------------------- */
.form{display:grid;gap:var(--s-4)}
.field{display:grid;gap:7px;align-content:start}
.field label{font-family:var(--font-display);font-size:.9rem;font-weight:600;color:var(--fg)}
.field label .req{color:var(--danger);margin-left:2px}
.field .help{font-size:.82rem;color:var(--fg-faint)}
.field input,.field select,.field textarea{
  width:100%;min-height:52px;padding:14px 16px;
  background:var(--ink-850);color:var(--fg);
  border:1px solid var(--line);border-radius:var(--r-sm);
  transition:border-color var(--t-fast),box-shadow var(--t-fast),background-color var(--t-fast);
}
.field textarea{min-height:132px;resize:vertical}
.field select{
  cursor:pointer;appearance:none;-webkit-appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%234e5f6d%22 stroke-width=%222%22 stroke-linecap=%22round%22%3E%3Cpath d=%22m6 9 6 6 6-6%22/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 14px center;background-size:18px;padding-right:44px;
}
.field input::placeholder,.field textarea::placeholder{color:var(--fg-faint)}
.field input:hover,.field textarea:hover,.field select:hover{border-color:var(--line-strong)}
.field input:focus,.field textarea:focus,.field select:focus{
  outline:none;border-color:var(--brand-400);
  box-shadow:0 0 0 3px rgba(0,168,89,.2);background:var(--ink-900);
}
.field .err{display:none;align-items:center;gap:7px;font-size:.84rem;font-weight:500;color:var(--danger)}
.field .err svg{width:15px;height:15px;flex:0 0 auto}
.field[data-invalid="true"] .err{display:flex}
.field[data-invalid="true"] input,.field[data-invalid="true"] textarea,.field[data-invalid="true"] select{
  border-color:var(--danger);box-shadow:0 0 0 3px rgba(192,39,26,.14);
}
/* align-items:start on the row and align-content:start in the field: a .field is
   a grid, and two side-by-side fields stretch to the taller one -- the one with a
   .help line under it. The stretched field's auto rows then absorbed the slack,
   so "Your name" and "Mobile number" carried labels on the same line but inputs
   at two different heights. */
.form__row{display:grid;gap:var(--s-4);align-items:start}
@media (min-width:640px){.form__row{grid-template-columns:1fr 1fr}}
.form__status{display:none;gap:11px;align-items:flex-start;padding:16px 18px;border-radius:var(--r-sm);font-size:.94rem;line-height:1.5}
.form__status[data-state="ok"]{display:flex;background:rgba(0,168,89,.1);border:1px solid rgba(0,135,76,.3);color:var(--brand-ink)}
.form__status[data-state="err"]{display:flex;background:var(--danger-soft);border:1px solid rgba(192,39,26,.3);color:var(--danger)}
.form__status svg{width:19px;height:19px;flex:0 0 auto;margin-top:2px}
.honeypot{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* ---------- 18. Contact rail ------------------------------------------- */
.contactrail{display:grid;gap:var(--s-3)}
/* align-items:center, not start: the icon tile is 52px and the text beside it runs
   to three lines, so a top-aligned tile sat level with the label and read as
   drifted upward. Centre both against the card. */
.contactcard{
  display:grid;grid-template-columns:52px 1fr;gap:var(--s-4);align-items:center;
  padding:20px;border:1px solid var(--line);border-radius:var(--r-md);
  background:var(--glass);
  transition:border-color var(--t-mid),transform var(--t-mid) var(--e-out),background-color var(--t-mid);
}
a.contactcard:hover{border-color:var(--brand-400);transform:translateX(4px);background:var(--glass-2)}
.contactcard__ico{
  width:52px;height:52px;display:grid;place-items:center;border-radius:14px;
  background:radial-gradient(120% 120% at 30% 20%,rgba(0,168,89,.15),rgba(0,135,76,.04));
  border:1px solid var(--line-strong);color:var(--brand-600);
}
.contactcard__ico svg{width:22px;height:22px}
.contactcard b{display:block;font-family:var(--font-display);font-size:1.02rem;font-weight:600}
.contactcard span{display:grid;color:var(--fg-muted);font-size:.94rem;word-break:break-word}
.contactcard small{
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.14em;text-transform:uppercase;
  color:var(--fg-faint);display:block;margin-bottom:3px;
}
.mapframe{
  margin-top:var(--s-5);   /* it sits under the contact rail, not welded to it */
  position:relative;border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;background:var(--ink-800);aspect-ratio:16/10;
}
.mapframe iframe{width:100%;height:100%;border:0;filter:saturate(.88) contrast(1.03)}

/* ---------- 19. CTA band ----------------------------------------------- */
.ctaband{
  position:relative;overflow:hidden;isolation:isolate;
  border:1px solid rgba(20,38,100,.4);border-radius:var(--r-xl);
  padding:clamp(32px,5.5vw,var(--s-9));
  background:
    radial-gradient(90% 130% at 88% 4%,rgba(251,191,36,.3),transparent 58%),
    radial-gradient(80% 120% at 6% 96%,rgba(0,168,89,.34),transparent 60%),
    linear-gradient(160deg,var(--navy-700),var(--navy-900));
  box-shadow:var(--sh-3);
  /* dark island: re-point the tokens its own rules already read, so every
     descendant inverts without a single per-rule override */
  /* inheritance, not just tokens: a heading with no color of its own would
     otherwise inherit the light theme ink and vanish into this surface */
  color:var(--fg);
  --fg:#edf2ff; --fg-strong:#ffffff; --fg-muted:#bfcae8; --fg-faint:#93a2ca;
  --brand-ink:var(--lime-400);
  --line:rgba(255,255,255,.14); --line-strong:rgba(255,255,255,.24);
  --glass:rgba(255,255,255,.06); --glass-2:rgba(255,255,255,.1);
  --sh-1:0 1px 2px rgba(0,0,0,.28);
  --sh-2:0 12px 30px -14px rgba(0,0,0,.5);

  text-align:center;display:grid;justify-items:center;gap:var(--s-5);
}
.ctaband::before{
  content:"";position:absolute;inset:0;z-index:-1;opacity:.5;
  background-image:
    repeating-linear-gradient(90deg,rgba(182,221,38,.1) 0 1px,transparent 1px 62px),
    repeating-linear-gradient(0deg,rgba(182,221,38,.1) 0 1px,transparent 1px 62px);
  -webkit-mask-image:radial-gradient(70% 70% at 50% 50%,#000,transparent);
  mask-image:radial-gradient(70% 70% at 50% 50%,#000,transparent);
}
.ctaband h2{font-size:var(--fs-h2);max-width:24ch}
.ctaband p{max-width:56ch;color:var(--fg-muted)}
.ctaband__actions{display:flex;flex-wrap:wrap;gap:var(--s-3);justify-content:center}

/* ---------- 20. Footer ------------------------------------------------- */
.footer{
  position:relative;overflow:hidden;
  border-top:1px solid rgba(20,38,100,.4);background:var(--navy-800);
  /* dark island: re-point the tokens its own rules already read, so every
     descendant inverts without a single per-rule override */
  /* inheritance, not just tokens: a heading with no color of its own would
     otherwise inherit the light theme ink and vanish into this surface */
  color:var(--fg);
  --fg:#edf2ff; --fg-strong:#ffffff; --fg-muted:#bfcae8; --fg-faint:#93a2ca;
  --brand-ink:var(--lime-400);
  --line:rgba(255,255,255,.14); --line-strong:rgba(255,255,255,.24);
  --glass:rgba(255,255,255,.06); --glass-2:rgba(255,255,255,.1);
  --sh-1:0 1px 2px rgba(0,0,0,.28);
  --sh-2:0 12px 30px -14px rgba(0,0,0,.5);
}
.footer__glow{
  position:absolute;inset:auto 0 -60% 0;height:100%;pointer-events:none;
  background:radial-gradient(60% 100% at 50% 100%,rgba(0,168,89,.32),transparent 70%);
}
.footer__top{position:relative;display:grid;gap:var(--s-7);padding-block:clamp(48px,6vw,var(--s-8))}
@media (min-width:900px){.footer__top{grid-template-columns:1.5fr .8fr .8fr 1.1fr}}
.footer h4{
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.2em;text-transform:uppercase;
  color:var(--brand-ink);font-weight:400;margin-bottom:var(--s-4);
}
.footer__links{display:grid;gap:2px}
.footer__links a{display:inline-flex;align-items:center;min-height:40px;color:var(--fg-muted);transition:color var(--t-fast),transform var(--t-fast)}
.footer__links a:hover{color:var(--fg);transform:translateX(3px)}
.footer__blurb{color:var(--fg-muted);max-width:44ch;margin-top:var(--s-4)}
.footer__bottom{
  position:relative;display:flex;flex-wrap:wrap;gap:var(--s-3) var(--s-5);
  align-items:center;justify-content:space-between;
  padding-block:var(--s-5);border-top:1px solid var(--line);
  font-size:.86rem;color:var(--fg-faint);
}
.social{display:flex;gap:10px}
.social a{
  width:44px;height:44px;display:grid;place-items:center;border-radius:var(--r-pill);
  background:var(--glass);border:1px solid var(--line);color:var(--fg-muted);
  transition:all var(--t-mid) var(--e-out);
}
.social a:hover{color:#ffffff;background:var(--brand-600);border-color:transparent;transform:translateY(-3px)}
.social svg{width:18px;height:18px}

/* ---------- 21. Sticky mobile action bar ------------------------------- */
.actionbar{
  position:fixed;inset:auto 0 0 0;z-index:100;display:none;
  grid-template-columns:1fr 1fr;gap:1px;background:var(--line);
  padding-bottom:env(safe-area-inset-bottom,0);
  border-top:1px solid var(--line);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
}
.actionbar a{
  display:flex;align-items:center;justify-content:center;gap:9px;
  min-height:56px;background:rgba(255,255,255,.96);
  font-family:var(--font-display);font-weight:600;font-size:.95rem;color:var(--fg);
}
.actionbar a svg{width:18px;height:18px}
.actionbar a:first-child svg{color:var(--brand-600)}
.actionbar a:last-child svg{color:var(--solar-600)}
.actionbar a:active{background:var(--ink-700)}

/* ---------- 22. Reveal / motion primitives ----------------------------- */
/* Reveals only hide themselves once JS has confirmed it is running, so a
   script failure leaves every section fully readable instead of blank. */
.js [data-reveal],.js [data-reveal-x]{
  opacity:0;
  transition:opacity .72s var(--e-out),transform .72s var(--e-out);
  will-change:opacity,transform;
}
.js [data-reveal]{transform:translateY(26px)}
.js [data-reveal="down"]{transform:translateY(-22px)}
.js [data-reveal="left"]{transform:translateX(-30px)}
.js [data-reveal="right"]{transform:translateX(30px)}
.js [data-reveal="scale"]{transform:scale(.94)}
.js [data-reveal="blur"]{filter:blur(9px);transform:none}
.js [data-reveal-x]{transform:translateX(-28px)}
.js [data-reveal].is-in,.js [data-reveal-x].is-in{
  opacity:1;transform:none;filter:none;will-change:auto;
}

.divider-glow{
  height:1px;border:0;margin:0;
  background:linear-gradient(90deg,transparent,var(--line-strong) 18%,rgba(251,191,36,.32) 50%,var(--line-strong) 82%,transparent);
}
.blob{position:absolute;border-radius:50%;filter:blur(72px);pointer-events:none;z-index:-1;opacity:.62}
.blob--brand{background:radial-gradient(circle,rgba(0,168,89,.3),transparent 68%)}
.blob--solar{background:radial-gradient(circle,rgba(251,191,36,.42),transparent 68%)}

/* Custom cursor — pointer:fine only */
.cursor,.cursor-dot{
  position:fixed;top:0;left:0;z-index:150;pointer-events:none;
  border-radius:50%;opacity:0;
  will-change:transform;
}
.cursor{width:34px;height:34px;border:1.5px solid rgba(0,135,76,.6);margin:-17px 0 0 -17px;transition:opacity .3s,width .3s var(--e-out),height .3s var(--e-out),margin .3s var(--e-out),background-color .3s}
.cursor-dot{width:5px;height:5px;background:var(--solar-500);margin:-2.5px 0 0 -2.5px;transition:opacity .3s}
.cursor.is-active{width:56px;height:56px;margin:-28px 0 0 -28px;background:rgba(0,168,89,.1)}
@media (hover:hover) and (pointer:fine){
  body.has-cursor .cursor,body.has-cursor .cursor-dot{opacity:1}
}

/* ---------- 23. Responsive -------------------------------------------- */
@media (max-width:1080px){
  .nav,.header__cta .btn--desk{display:none}
  .burger{display:grid}
}
@media (max-width:900px){
  :root{--header-h:68px}
  .hero{min-height:auto;padding-top:calc(var(--header-h) + var(--s-8));padding-bottom:var(--s-9)}
  .hero__meta{gap:var(--s-5) var(--s-5)}
  .timeline{padding-left:var(--s-5)}
  .timeline__item::before{left:calc(-1 * var(--s-5) + 1px)}
}
@media (max-width:768px){
  .actionbar{display:grid}
  body{padding-bottom:56px}
  .explorer__stage{height:min(84vw,380px)}
  .stats{border-radius:var(--r-md)}
  .card__num{font-size:2.6rem}
}
@media (max-width:420px){
  .hero__actions .btn{width:100%}
  .explorer__tabs{padding:10px}
  .tab{padding:10px 14px;font-size:.9rem;flex:1 1 auto;justify-content:center}
}

/* ---------- 24. Reduced motion ---------------------------------------- */
@media (prefers-reduced-motion:reduce){
  html:focus-within{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
  [data-reveal],[data-reveal-x]{opacity:1 !important;transform:none !important}
  .marquee__track{animation:none;transform:none;flex-wrap:wrap;width:auto;justify-content:center}
  .marquee{-webkit-mask-image:none;mask-image:none}
  .marquee__ctl{display:none}
  .stage-hint{animation:none;opacity:.85}
  .drawer.is-open .drawer__link{opacity:1;transform:none;animation:none}
  .cursor,.cursor-dot{display:none}
  .btn::after{display:none}
}

/* ---------- 25. Print ------------------------------------------------- */
@media print{
  .stage,.header,.progress,.actionbar,.cursor,.cursor-dot,.marquee,.explorer__stage{display:none !important}
  body{background:#fff;color:#000}
  .card,.stat,.ctaband{border:1px solid #ccc;background:none}
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:.8em;color:#555}
}

/* ---------- 26. JS hooks + late overrides ------------------------------ */
/* Accordion panels are toggled with the `hidden` attribute so collapsed
   copy is genuinely out of the accessibility tree. Height animation is
   handled by the reveal of the inner div instead of the panel itself. */
.acc__panel{height:auto}
.acc__panel[hidden]{display:none}
.acc__item.is-open{border-color:var(--line-strong);background:var(--glass-2)}
.acc__item.is-open .acc__panel>div{animation:accIn .42s var(--e-out) both}
@keyframes accIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}

/* current page marker */
.nav__link.is-here,.drawer__link.is-here{color:var(--fg)}
.nav__link.is-here::after{transform:scaleX(1)}
.drawer__link.is-here{color:var(--brand-ink)}

/* inline field errors */
.field__err{
  display:flex;align-items:flex-start;gap:6px;
  margin:0;font-size:.82rem;line-height:1.45;color:var(--danger);
}
.field__err:empty{display:none}
.field__err::before{
  content:"!";flex:0 0 auto;
  width:16px;height:16px;margin-top:1px;border-radius:50%;
  display:grid;place-items:center;
  background:rgba(192,39,26,.1);border:1px solid rgba(192,39,26,.4);
  font-family:var(--font-mono);font-size:var(--fs-label);font-weight:700;color:var(--danger);
}

/* savings estimator */
.estimator{
  display:grid;gap:var(--s-5);padding:clamp(22px,3vw,var(--s-6));
  border:1px solid var(--line);border-radius:var(--r-lg);
  background:linear-gradient(165deg,var(--ink-800),var(--ink-900));
}
.estimator__out{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s-4)}
.estimator__cell{
  display:grid;gap:4px;padding:16px 18px;
  border:1px solid var(--line);border-radius:var(--r-md);background:var(--glass);
}
.estimator__cell b{
  font-family:var(--font-display);font-size:clamp(1.35rem,3vw,1.85rem);
  font-weight:700;line-height:1.05;color:var(--brand-700);font-variant-numeric:tabular-nums;
}
.estimator__cell span{
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.12em;
  text-transform:uppercase;color:var(--fg-faint);
}
.estimator__note{font-size:.82rem;color:var(--fg-faint);max-width:62ch}
.range{position:relative;display:grid;gap:10px}
.range input[type="range"]{
  -webkit-appearance:none;appearance:none;width:100%;height:44px;
  background:transparent;cursor:pointer;
}
.range__track{
  position:absolute;left:0;right:0;top:30px;height:6px;
  border-radius:var(--r-pill);background:var(--ink-850);
  border:1px solid var(--line);overflow:hidden;pointer-events:none;
}
.range__fill{
  height:100%;width:35%;
  background:linear-gradient(90deg,var(--brand-500),var(--solar-300));
}
.range input[type="range"]::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;position:relative;z-index:2;
  width:26px;height:26px;border-radius:50%;
  background:var(--solar-300);border:3px solid var(--ink-900);
  box-shadow:var(--glow-solar);cursor:grab;
}
.range input[type="range"]::-moz-range-thumb{
  width:26px;height:26px;border:3px solid var(--ink-900);border-radius:50%;
  background:var(--solar-300);box-shadow:var(--glow-solar);cursor:grab;
}
.range__ends{
  display:flex;justify-content:space-between;
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.1em;color:var(--fg-faint);
}

/* explorer drag feedback + label fades */
.explorer.is-dragging .explorer__stage{cursor:grabbing}
.explorer.is-dragging .explorer__hint{opacity:0}
.explorer__hint{transition:opacity var(--t-mid)}
.node-label,.flowtag[data-edge]{transition:opacity var(--t-mid),background-color var(--t-mid),border-color var(--t-mid),color var(--t-mid)}
.flowtag[data-edge]{position:absolute;white-space:nowrap}
.explorer:not(.is-live) .explorer__labels{display:none}

/* the hero hint retires once the visitor has actually moved the sun */
/* keep the centring transform: a bare translateY here replaced translateX(-50%)
   and the pill jumped half its own width to the right as it faded */
/* On a phone the card is ~330px wide and the whole sentence broke into three
   centred lines that sat on top of the plot. Two words are enough there; the
   legend under the card already says the panels track the sun. */
@media (max-width:640px){ .stage-hint__more{display:none} }
.stage.has-steered .stage-hint{opacity:0;transform:translateY(8px)}

@media (max-width:768px){
  .estimator__out{grid-template-columns:repeat(2,1fr)}
}
@media (prefers-reduced-motion:reduce){
  .acc__item.is-open .acc__panel>div{animation:none}
}

/* character-split headline entrance (delays are set inline by site.js) */
.js .split-char{
  opacity:0;transform:translateY(.55em) rotate(3deg);
  animation:charIn .82s var(--e-out) both;
}
@keyframes charIn{to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .js .split-char{opacity:1;transform:none;animation:none}
}

/* ---------- 27. Legal / long-form prose -------------------------------- */
.prose{display:grid;gap:var(--s-4);max-width:70ch}
.prose h2{font-family:var(--font-display);font-weight:600;font-size:clamp(1.25rem,2.4vw,1.6rem);color:var(--fg-strong);margin-top:var(--s-5)}
.prose h2:first-child{margin-top:0}
.prose h3{font-family:var(--font-display);font-weight:600;font-size:1.06rem;color:var(--fg)}
.prose p,.prose li{color:var(--fg-muted)}
.prose ul{display:grid;gap:var(--s-3);padding-left:1.15rem;list-style:disc}
.prose a{color:var(--brand-ink);text-decoration:underline;text-underline-offset:3px}
.prose a:hover{color:var(--solar-700)}
.prose strong{color:var(--fg);font-weight:600}
.prose .updated{font-family:var(--font-mono);font-size:.82rem;color:var(--fg-faint);letter-spacing:.04em}

/* ---------- 28. 404 ---------------------------------------------------- */
.notfound{min-height:68vh;display:grid;place-items:center;text-align:center;padding:var(--s-8) 0}
.notfound__code{
  font-family:var(--font-display);font-weight:700;line-height:.9;
  font-size:clamp(5rem,18vw,12rem);
  background:linear-gradient(180deg,var(--solar-500),var(--brand-600));
  -webkit-background-clip:text;background-clip:text;color:transparent;
}
.pagehead--plain{min-height:auto;padding-bottom:var(--s-6)}
.pagehead--plain::after{
  content:"";position:absolute;inset:0;z-index:-1;
  background:radial-gradient(60% 90% at 12% 0%,rgba(0,168,89,.11),transparent 70%);
}
.footer__contact li{display:grid;grid-template-columns:18px 1fr;gap:10px;align-items:start;color:var(--fg-muted);min-height:0;padding:4px 0}
.footer__contact li svg{width:18px;height:18px;margin-top:3px;color:var(--brand-ink)}
.footer__contact a{display:inline;min-height:0;word-break:break-word}
.footer__legal{display:flex;flex-wrap:wrap;gap:var(--s-4)}
.footer__legal a{color:var(--fg-faint);min-height:40px;display:inline-flex;align-items:center;transition:color var(--t-fast)}
.footer__legal a:hover{color:var(--brand-ink)}
.explorer__hint svg{width:12px;height:12px;vertical-align:-2px;margin-right:4px}
.explorer__stage canvas:focus-visible{outline:3px solid var(--lime-400);outline-offset:-3px}
.notfound .kicker,.notfound h1{justify-self:center}
.notfound .shell{display:grid;gap:var(--s-4);justify-items:center}
.section--blob,.hero{overflow:clip}

/* ---------- 29. Cinema — the four-act scroll sequence -------------------- *
 * Three layouts from one markup. Without .js it is an ordinary section: a
 * gradient banner and four cards in a grid, all readable, nothing pinned.
 * With .js the section grows a scroll track and its viewport sticks, so the
 * canvas holds still while the page scrolls through it. With reduced motion
 * it goes back to being the ordinary section.                              */
.cinema{position:relative;background:var(--ink-900)}
.cinema__view{
  position:relative;overflow:clip;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
}
/* the sky is CSS, not WebGL: it is the fallback and the backdrop at once, and
   the canvas is drawn over it with a transparent clear colour */
.cinema__sky{
  position:absolute;inset:0;
  background:
    radial-gradient(58% 42% at 78% 16%,rgba(255,214,102,.5),transparent 66%),
    linear-gradient(180deg,#d9e9fb 0%,#e9f3ff 38%,#fff6e4 76%,#ffffff 100%);
}
.cinema__sky::after{
  content:"";position:absolute;inset:auto 0 0 0;height:34%;
  background:linear-gradient(180deg,transparent,rgba(255,255,255,.85) 62%,#fff);
}
.cinema canvas{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  opacity:0;transition:opacity 900ms var(--e-out);
}
.cinema.is-live canvas{opacity:1}
.cinema__view{padding:var(--s-8) 0}
.cinema__inner{position:relative;display:grid;gap:var(--s-5)}
.cinema__head{max-width:44ch}
.cinema__head .h2{font-size:clamp(1.7rem,1.25rem + 1.9vw,2.9rem)}
.cinema__lead{color:var(--fg-muted);max-width:46ch;margin-top:var(--s-3)}

/* the four act cards. Glass over a pale sky, so the fill is white at .72 and
   the text stays navy — a tinted glass would have cost contrast for nothing. */
.cinema__cards{display:grid;gap:var(--s-4);grid-template-columns:repeat(auto-fit,minmax(min(100%,240px),1fr))}
.cinema__card{
  position:relative;padding:var(--s-5);border-radius:var(--r-lg);
  background:rgba(255,255,255,.74);border:1px solid rgba(255,255,255,.9);
  box-shadow:var(--sh-3),inset 0 1px 0 rgba(255,255,255,.9);
  backdrop-filter:blur(16px) saturate(1.15);
  -webkit-backdrop-filter:blur(16px) saturate(1.15);
}
.cinema__card h3{font-size:var(--fs-h4);margin-bottom:var(--s-2)}
.cinema__card p{color:var(--fg-muted)}
.cinema__act{
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.2em;
  text-transform:uppercase;color:var(--brand-ink);display:block;margin-bottom:var(--s-2);
}
.cinema__stat{
  display:flex;flex-wrap:wrap;gap:var(--s-2) var(--s-4);margin-top:var(--s-4);
  padding-top:var(--s-3);border-top:1px solid var(--line);
}
.cinema__stat b{font-family:var(--font-display);font-size:1.15rem;color:var(--fg-strong)}
.cinema__stat span{display:block;font-size:.78rem;color:var(--fg-faint)}

/* the rail: four buttons that name the acts and scroll to them */
.cinema__rail{display:flex;gap:var(--s-2);flex-wrap:wrap;list-style:none;padding:0}
.cinema__rail button{
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.14em;text-transform:uppercase;
  min-height:44px;padding:0 var(--s-4);border-radius:var(--r-pill);cursor:pointer;
  border:1px solid var(--line-strong);background:rgba(255,255,255,.7);color:var(--fg-muted);
  transition:color var(--t-fast),border-color var(--t-fast),background var(--t-fast);
}
.cinema__rail button:hover{color:var(--brand-ink);border-color:var(--brand-500)}
.cinema__rail button.is-on{
  color:#fff;background:var(--brand-700);border-color:var(--brand-700);
}
.cinema__hint{
  font-family:var(--font-mono);font-size:var(--fs-label);letter-spacing:.1em;
  color:var(--fg-faint);display:none;align-items:center;gap:8px;
}
.cinema__hint svg{width:13px;height:13px;flex:0 0 auto}

/* --- with JavaScript: the track, the pin, and one card at a time --------- */
.js .cinema{height:440vh}
.js .cinema:not(.is-flat) .cinema__view{
  position:sticky;top:0;height:100vh;height:100svh;
  padding:0;border-top:0;border-bottom:0;
}
.js .cinema:not(.is-flat) .cinema__inner{
  height:100%;align-content:space-between;
  /* the header is fixed and translucent, so the pinned frame has to start below
     it — the act rail was rendering underneath it at desktop widths */
  padding:calc(var(--header-h) + var(--s-4)) 0 var(--s-7);
}
.js .cinema__hint{display:inline-flex}
.js .cinema__cards{
  position:relative;display:block;min-height:clamp(210px,26vh,270px);
}
.js .cinema__card{
  position:absolute;inset:auto 0 0 0;max-width:min(100%,440px);
  opacity:0;transform:translateY(28px) scale(.985);pointer-events:none;
  transition:opacity 620ms var(--e-out),transform 620ms var(--e-out);
}
.js .cinema__card.is-on{opacity:1;transform:none;pointer-events:auto}
/* the heading is the title card: it dims once the plant starts building, so the
   act cards own the frame from act II on */
.js .cinema__head{
  position:relative;
  transition:opacity 700ms var(--e-out),transform 700ms var(--e-out);
}
/* Panels fly across this text in act II. The scrim is a wash, not a card: it
   lifts contrast where the words are and disappears before the edge. */
.js .cinema__head::before{
  content:"";position:absolute;z-index:-1;
  inset:calc(var(--s-4) * -1) -8% calc(var(--s-5) * -1) calc(var(--s-4) * -1);
  background:radial-gradient(70% 100% at 22% 40%,rgba(255,255,255,.9),rgba(255,255,255,.55) 58%,transparent 100%);
  filter:blur(2px);pointer-events:none;
}
.js .cinema[data-act="1"] .cinema__head,
.js .cinema[data-act="2"] .cinema__head{opacity:.5;transform:translateY(-8px)}

@media (min-width:940px){
  .js .cinema__inner{
    grid-template-columns:minmax(0,1fr) minmax(0,420px);
    grid-template-areas:"head rail" "cards cards";
    align-content:space-between;
  }
  .js .cinema__head{grid-area:head}
  .js .cinema__rail{grid-area:rail;justify-content:flex-end;align-self:start}
  .js .cinema__cards{grid-area:cards}
}
@media (max-width:939px){
  .js .cinema{height:400vh}
  .js .cinema:not(.is-flat) .cinema__inner{padding:calc(var(--header-h) + var(--s-4)) 0 var(--s-6)}
  .js .cinema:not(.is-flat) .cinema__cards{min-height:clamp(230px,34vh,300px)}
  .cinema__head .h2{font-size:clamp(1.5rem,1.2rem + 2.2vw,2rem)}
  .cinema__lead{display:none}
  .js .cinema__rail button{padding:0 var(--s-3);min-height:40px}
  /* Head and rail at the top, card pinned to the bottom, scene in the band
     between them. align-content:start alone moved the card up under the head,
     because the card is absolute inside the cards row — the row itself has to
     be the one that stretches. */
  .js .cinema:not(.is-flat) .cinema__inner{
    grid-template-areas:"head" "rail" "cards";
    grid-template-rows:auto auto minmax(0,1fr);
    align-content:stretch;gap:var(--s-4);
  }
  .js .cinema:not(.is-flat) .cinema__head{grid-area:head}
  .js .cinema:not(.is-flat) .cinema__rail{grid-area:rail;align-self:start}
  .js .cinema:not(.is-flat) .cinema__cards{grid-area:cards;align-self:stretch}
}
@media (max-width:719px){
  .js .cinema__hint{display:none}          /* no pointer to lean with */
  .js .cinema:not(.is-flat) .cinema__inner{padding-bottom:var(--s-4)}
  .js .cinema__card{padding:var(--s-4);max-width:none}
  .js .cinema__card p{font-size:.88rem;line-height:1.55}
  .js .cinema__card h3{font-size:1.02rem}
  .js .cinema__cards{min-height:clamp(250px,36svh,320px)}
  /* two stats, side by side: left to flex-wrap they took a row each and pushed
     the card over the scene */
  .js .cinema__card .cinema__stat{gap:var(--s-2) var(--s-3)}
  .js .cinema__card .cinema__stat > *{flex:1 1 40%;min-width:0}
  .js .cinema__card .cinema__stat span{font-size:var(--fs-label)}
  /* the phone action bar is fixed at the bottom; the card sits above it */
  .js .cinema:not(.is-flat) .cinema__card{inset:auto 0 var(--s-5) 0}
}

/* --- without WebGL: the sky alone has to carry the section --------------- *
 * .is-flat is set by the module itself when there is no context to render
 * into, so the tall track is the default and only a real failure reflows.   */
.js .cinema.is-flat{height:auto}
/* Two columns where there is room, one where there is not. Letting the four
   cards fall into four ~280px columns at 1280 wrapped every heading onto four
   lines — measured, so the minimum is a reading measure, not a card width. */
.js .cinema.is-flat .cinema__cards{
  display:grid;min-height:0;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,26rem),1fr));
}
.js .cinema.is-flat .cinema__card{
  position:relative;inset:auto;max-width:none;opacity:1;transform:none;pointer-events:auto;
  transition:none;
}
.js .cinema.is-flat .cinema__rail,
.js .cinema.is-flat .cinema__hint{display:none}

/* --- reduced motion: no pin, no flight, everything at once -------------- */
@media (prefers-reduced-motion:reduce){
  /* These have to carry :not(.is-flat) to outweigh the pin rules above: a
     media query adds no specificity, so `.js .cinema__view` would lose to
     `.js .cinema:not(.is-flat) .cinema__view` and the section would stay
     pinned at 100vh with the cards clipped out of sight — measured. */
  .js .cinema{height:auto}
  .js .cinema:not(.is-flat) .cinema__view{position:relative;height:auto;padding:var(--s-8) 0}
  .js .cinema:not(.is-flat) .cinema__inner{height:auto;padding:var(--s-8) 0}
  .js .cinema:not(.is-flat) .cinema__cards{
    display:grid;min-height:0;
    grid-template-columns:repeat(auto-fit,minmax(min(100%,26rem),1fr));
  }
  .js .cinema__card{
    position:relative;inset:auto;max-width:none;opacity:1;transform:none;pointer-events:auto;
    transition:none;
  }
  .js .cinema__rail,.js .cinema__hint{display:none}
  .js .cinema[data-act] .cinema__head{opacity:1;transform:none}
}
