/* ════════════════════════════════════════════════════════════════════
   Core layer — tokens, chrome (nav/footer), the shared section recipe,
   buttons, sticky CTA, global FX. Every body section consumes --pg-*
   tokens.

   THEME SYSTEM — FULL THEMING. Night is the default canvas;
   html[data-theme="light"] flips EVERYTHING to day, scenes included
   (hero dive, relay, worldmap, final CTA). The .zone-night re-pin
   mechanism below is KEPT for future intentional dark objects: the
   NIGHT palette is declared once under
   `:root, html[data-theme="light"] .zone-night` so the same tokens
   re-pin to dark for everything inside a night zone. No page currently
   ships a .zone-night wrapper (the cinema-panel zoning was superseded
   July 2026); in dark mode a wrapper would be a visual no-op anyway
   (its background equals the body background), so dark rendering is
   pixel-identical to the pre-theme build.

   Override patterns (fan-out agents: follow these exactly):
   · Pattern A (default): anything painted with var(--pg-*) needs
     NOTHING — the zone re-pin swaps the values.
   · Pattern B (literals that can occur in BOTH zones): always write the
     rule PAIR — `html[data-theme="light"] .foo{light literal}` +
     `html[data-theme="light"] .zone-night .foo{dark literal restored}`.
     .sec__badge is the canonical case (see below). NEVER write a bare
     light override for anything that can sit inside .zone-night.
   Intentionally-dark mini-cards (.net__cloud, .net__card,
   .rail__card--invert, .worth__out, .fx-code) keep their dark literals
   in both themes — no overrides, that is the design.
   ════════════════════════════════════════════════════════════════════ */
/* Display face is deliberately mapped ONE WEIGHT DOWN (declared weight →
   next-lighter file) for a lighter editorial voice. To revert, change the
   src files back (Regular→Medium, Medium→Semibold, Semibold→Bold) — do
   not touch the font-weight rules or the markup. */
@font-face{font-family:"General Sans";font-weight:500;font-style:normal;font-display:swap;src:url("/fonts/general-sans/GeneralSans-Regular.woff2") format("woff2")}
@font-face{font-family:"General Sans";font-weight:600;font-style:normal;font-display:swap;src:url("/fonts/general-sans/GeneralSans-Medium.woff2") format("woff2")}
@font-face{font-family:"General Sans";font-weight:700;font-style:normal;font-display:swap;src:url("/fonts/general-sans/GeneralSans-Semibold.woff2") format("woff2")}
/* Body face, self-hosted (was Google Fonts). The remote sheet cost a
   render-blocking round trip to a second origin before a single glyph could
   resolve, and Jakarta is a VARIABLE font — one file per unicode subset spans
   200→800, so the five weights we use were never five downloads. Local +
   preloaded, the whole face lands with the CSS instead of arriving late and
   reflowing the document under the hero animation. Italic is deliberately not
   shipped: nothing in v2 sets font-style:italic. */
@font-face{font-family:"Plus Jakarta Sans";font-weight:200 800;font-style:normal;font-display:swap;
  src:url("/fonts/plus-jakarta-sans/PlusJakartaSans-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
/* latin-ext carries ₹ (U+20B9) — the geo money copy needs it */
@font-face{font-family:"Plus Jakarta Sans";font-weight:200 800;font-style:normal;font-display:swap;
  src:url("/fonts/plus-jakarta-sans/PlusJakartaSans-latin-ext.woff2") format("woff2");
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
body{margin:0;background:#0b1018}
html[data-theme="light"] body{background:#ffffff}
:root{color-scheme:dark}
html[data-theme="light"]{color-scheme:light}
html[data-theme="light"] .zone-night{color-scheme:dark}

/* NIGHT palette — the site default AND the re-pin for dark cinema panels
   when the room is light. Values byte-identical to the dark-only build. */
:root,
html[data-theme="light"] .zone-night{
  --pg-bg:#0b1018;
  --pg-bg-2:#10161f;
  --pg-surface:#141b25;
  --pg-ink:#eef2f6;
  --pg-ink-soft:#cfd6dd;
  --pg-mute:#9aa3ad;
  --pg-faint:#7a8390;  /* 2026-09-02: was #6b7480 (3.66:1 on --pg-surface); lightest step at 4.5:1 on surface, 4.74 on bg-2 */
  --pg-hairline:rgba(255,255,255,.08);
  --pg-hairline-soft:rgba(255,255,255,.05);
  --pg-emerald:#15b87f;
  --pg-emerald-hi:#2ed49a;
  --pg-red:#e23b34;
  --pg-red-hover:#ec4640;
  /* CTA system — deep emerald (decided 2026-08-21): booking reads as
     "go / it's live", the same family as the LIVE badge and guests-online
     accents, and brand red retreats to the logo + true error states —
     where scarcity makes it pop harder. #0d8659 holds 4.6:1 with white
     text — the lightest step that keeps white text AA; brighter greens
     need ink text instead. --pg-red stays for genuine errors. */
  --pg-cta:#0d8659;
  --pg-cta-hover:#0f9160;
  --pg-glass:rgba(13,17,23,.6);
  --pg-marker:rgba(255,216,77,.55);
  --pg-shadow:0 24px 60px rgba(0,0,0,.35);
  --pg-ease:cubic-bezier(.16,1,.3,1);
  --pg-font:"Plus Jakarta Sans",system-ui,-apple-system,sans-serif;
  --pg-display:"General Sans","Plus Jakarta Sans",system-ui,sans-serif;
  --pg-glow:0 0 60px rgba(21,184,127,.14);
  --pg-dim:rgba(11,16,24,.78);
}
/* DAY palette — production pg.css values. --pg-red and --pg-cta are NOT
   remapped: the emerald CTA and error-red read identically in both themes. */
html[data-theme="light"]{
  --pg-bg:#ffffff;
  --pg-bg-2:#f5f6f8;
  --pg-surface:#ffffff;
  --pg-ink:#101016;
  --pg-ink-soft:#2a2f36;
  --pg-mute:#565d68;
  --pg-faint:#6c717b;  /* 2026-09-02: was #8b9099 (2.97:1 on --pg-bg-2); lightest step at 4.5:1 on bg-2, 4.9 on white */
  --pg-hairline:rgba(16,16,22,.1);
  --pg-hairline-soft:rgba(16,16,22,.06);
  --pg-emerald:#0f9e6c;
  --pg-emerald-hi:#0b7550;  /* 2026-09-02: was #0f9e6c (3.43:1 on white, 3.17 on bg-2). Text-size emerald; dots and fills keep --pg-emerald */
  --pg-glass:rgba(255,255,255,.74);
  --pg-marker:rgba(255,216,77,.55);
  --pg-shadow:0 24px 60px rgba(16,16,22,.12);
  --pg-glow:0 0 54px rgba(15,158,108,.12);
  --pg-dim:rgba(16,16,22,.5);
}
body{background:var(--pg-bg);color:var(--pg-ink-soft);font-family:var(--pg-font);-webkit-font-smoothing:antialiased}
/* skip link: first focusable element on every page; off-canvas until focused */
.skip-link{position:absolute;left:16px;top:-120px;z-index:1000;padding:10px 16px;border-radius:999px;background:var(--pg-cta);color:#fff;font:700 14px/1 var(--pg-font);text-decoration:none;transition:none}
.skip-link:focus{top:16px;outline:2px solid #fff;outline-offset:2px}
main#main{outline:none}
/* screen-reader-only text, site-wide (scenes.css carries a copy for the home variant only) */
.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}
.page-body{position:relative;z-index:1}
.page-body [hidden]{display:none!important}   /* hidden-not-deleted set pieces stay hidden despite display rules */
.page-body :focus-visible{outline:2px solid var(--pg-emerald);outline-offset:3px;border-radius:4px}

/* ── floating white pill nav (lives outside the hero, so its vars are
   inlined as literals) ── */
.nav{
  position:fixed;
  top:18px;left:50%;
  width:min(1320px,calc(100% - 36px));
  height:55px;box-sizing:border-box;   /* the 1px border sits inside the 55 */
  display:flex;align-items:center;justify-content:space-between;
  padding:0 14px 0 22px;
  background:rgba(255,255,255,.92);
  backdrop-filter:blur(18px) saturate(1.4);
  -webkit-backdrop-filter:blur(18px) saturate(1.4);
  border:1px solid rgba(16,16,22,.06);
  border-radius:15px;   /* a long bar with crisp corners (2026-09-07: 62/24 → 55/15) */
  /* rest: a quiet lift. Content scrolling behind the pill deepens it via
     .is-scrolled (page.js / sub.js toggle it past 12px) so the bar
     separates from whatever passes underneath. */
  box-shadow:0 8px 24px -14px rgba(16,16,22,.28),0 1px 2px rgba(16,16,22,.06);
  transition:box-shadow .35s cubic-bezier(.16,1,.3,1);
  z-index:120;
  opacity:0;
  transform:translateX(-50%) translateY(-14px);
  animation:rise-in 1s cubic-bezier(.16,1,.3,1) .1s forwards;
  font-family:"Plus Jakarta Sans",system-ui,-apple-system,sans-serif;
}
@keyframes rise-in{to{opacity:1;transform:translateX(-50%) translateY(0)}}
.nav.is-scrolled{box-shadow:0 18px 50px -20px rgba(0,0,0,.55),0 1px 2px rgba(16,16,22,.08)}
.nav__logo{display:inline-flex;align-items:center;min-height:44px}
/* wordmark only, 22px (2026-09-07: 27 → 24 with the 55px pill, then 22 on Kumar's call); the hairline "WiFi" strokes still read */
.nav__logo img{display:block;height:22px;width:auto}
.nav__links{display:flex;align-items:center;gap:6px;list-style:none;margin:0;padding:0}
.nav__links a{
  display:block;padding:9px 15px;
  font-size:15px;font-weight:500;color:#3c3f49;
  border-radius:999px;text-decoration:none;
  transition:color .25s,background-color .25s;
}
.nav__links a:hover{color:#101016;background:rgba(16,16,22,.05)}
.nav__right{display:flex;align-items:center;gap:10px}
.nav__cloud{
  display:inline-flex;align-items:center;gap:8px;
  padding:9px 18px;
  font-size:14.5px;font-weight:600;color:#101016;
  border:1px solid rgba(16,16,22,.14);
  border-radius:999px;text-decoration:none;
  transition:border-color .25s,background-color .25s,transform .25s cubic-bezier(.16,1,.3,1);
}
.nav__cloud:hover{border-color:rgba(16,16,22,.32);background:#fff;transform:translateY(-1px)}
.nav__cloud svg{width:17px;height:17px;stroke:#101016;fill:none}   /* mono: the demo CTA is the nav's one colour */
.nav__cloud[hidden]{display:none}
.nav__demo{
  display:inline-flex;align-items:center;height:38px;padding:0 18px;border-radius:999px;
  background:var(--pg-cta);color:#fff;font-size:14.5px;font-weight:700;text-decoration:none;
  box-shadow:0 10px 24px -10px rgba(13,134,89,.5);
  transition:background-color .25s,transform .25s cubic-bezier(.16,1,.3,1);
}
.nav__demo:hover{background:var(--pg-cta-hover);transform:translateY(-1px)}
.nav__burger{
  display:flex;flex-direction:column;justify-content:center;gap:5px;
  width:42px;height:42px;align-items:center;border-radius:999px;
  border:0;background:none;cursor:pointer;padding:0;
  transition:background-color .25s;
}
.nav__burger:hover{background:rgba(16,16,22,.05)}
.nav__burger span{display:block;width:18px;height:1.6px;background:#101016;border-radius:2px;transition:transform .25s cubic-bezier(.16,1,.3,1)}
/* theme toggle — sun shows in dark ("go light"), moon in light. The pill
   is white in both themes, so the ink literal is theme-safe. */
.nav__theme{
  width:42px;height:42px;
  display:flex;align-items:center;justify-content:center;
  border-radius:999px;color:#101016;
  border:0;background:none;cursor:pointer;padding:0;
  transition:background-color .25s;
}
.nav__theme:hover{background:rgba(16,16,22,.06)}

/* ── Touch targets (WCAG 2.2 / Apple HIG 44x44) ────────────────────────────
   The nav pills read at 42px by design; a centred transparent ::before takes
   the hit area to 44 without moving a pixel of the visual. The pseudo is
   pointer-events:auto on a control that already accepts pointers, so it only
   widens what the finger can land on. Applied to the shared chrome here, so
   every page inherits it. Inline links inside sentences are deliberately NOT
   expanded: WCAG 2.2 exempts text links in a block of prose, and stretching
   them would make neighbouring lines overlap. ── */
.nav__theme,.nav__burger{position:relative}
.nav__theme::before,.nav__burger::before{
  content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:44px;height:44px;border-radius:inherit;
}
.nav__theme svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.nav__theme .moon{display:none}
html[data-theme="light"] .nav__theme .moon{display:block}
html[data-theme="light"] .nav__theme .sun{display:none}
.no-anim .nav{animation:none;opacity:1;transform:translateX(-50%)}
/* burger sheet → premium panel: same glass language, but the card lands
   with a settle (opacity + lift + micro-scale) and the rows rise in a
   stagger once it does. Closed state is class-driven — JS clears [hidden]
   once and .is-open drives both directions, so the exit animates too.
   (This block is MIRRORED in hero.css, which wins on index — edit both.) */
.nav__menu{
  position:absolute;top:calc(100% + 10px);left:10px;right:10px;
  background:rgba(255,255,255,.96);
  backdrop-filter:blur(18px) saturate(1.4);
  -webkit-backdrop-filter:blur(18px) saturate(1.4);
  border:1px solid rgba(16,16,22,.06);
  border-radius:15px;   /* follows the pill */
  box-shadow:0 30px 70px -28px rgba(0,0,0,.55);
  padding:14px 12px 12px;
  opacity:0;transform:translateY(-12px) scale(.98);transform-origin:top center;
  pointer-events:none;
  transition:opacity .3s cubic-bezier(.16,1,.3,1),transform .42s cubic-bezier(.16,1,.3,1);
}
.nav__menu.is-open{opacity:1;transform:none;pointer-events:auto}
.nav__menu ul{list-style:none;margin:0;padding:0}
.nav__menu ul a{
  display:flex;align-items:center;justify-content:space-between;
  padding:15px 18px;border-radius:18px;
  font-size:19px;font-weight:600;letter-spacing:-.01em;color:#101016;text-decoration:none;
  transition:background-color .25s;
}
.nav__menu ul a::after{
  content:"→";font-size:15px;color:rgba(16,16,22,.3);
  transform:translateX(-4px);opacity:0;
  transition:transform .3s cubic-bezier(.16,1,.3,1),opacity .3s;
}
.nav__menu ul a:hover,.nav__menu ul a[aria-current="page"]{background:rgba(16,16,22,.05)}
.nav__menu ul a:hover::after,.nav__menu ul a[aria-current="page"]::after{transform:none;opacity:1}
/* the stagger: delays exist only on the open state, so closing is crisp */
.nav__menu li{
  opacity:0;transform:translateY(10px);
  transition:opacity .45s cubic-bezier(.16,1,.3,1),transform .45s cubic-bezier(.16,1,.3,1);
}
.nav__menu.is-open li{opacity:1;transform:none}
.nav__menu.is-open li:nth-child(1){transition-delay:.06s}
.nav__menu.is-open li:nth-child(2){transition-delay:.11s}
.nav__menu.is-open li:nth-child(3){transition-delay:.16s}
.nav__menu.is-open li:nth-child(4){transition-delay:.21s}
.nav__menu.is-open li:nth-child(5){transition-delay:.26s}
/* the panel's own ask: ≤560 hides .nav__demo and the homepage has no docked
   bar, so the menu carries the CTA — full-width tap target, riding the same
   stagger last in line. Two classes: .btn-red's inline-flex sits later in
   this file and would win a single-class tie. */
.nav__menu .nav__menu-demo{
  display:flex;justify-content:center;margin:12px 6px 4px;
  opacity:0;transform:translateY(10px);
  transition:opacity .45s cubic-bezier(.16,1,.3,1),transform .45s cubic-bezier(.16,1,.3,1);
}
.nav__menu.is-open .nav__menu-demo{opacity:1;transform:none;transition-delay:.31s}
.nav__burger.is-open span:first-child{transform:translateY(3.3px) rotate(45deg)}
.nav__burger.is-open span:last-child{transform:translateY(-3.3px) rotate(-45deg)}
@media (min-width:901px){.nav__burger,.nav__menu{display:none}}
@media (max-width:900px){.nav__links{display:none}}
/* phone: the nav pill carries NO demo button at all — the hero's own CTA is
   in the first viewport, the docked bar takes over once you scroll, and the
   menu carries its own. The pill slims to logo + theme + burger. */
@media (max-width:560px){.nav__cloud span{display:none}.nav__cloud{padding:9px 12px}.nav__demo{display:none}}
/* phone: the pill keeps logo + demo + burger inside its own bounds
   (same compaction as hero.css; subpages load core only, so it rides here too) */
@media (max-width:480px){
  .nav{padding:0 10px 0 14px}
  .nav__logo img{height:21px}
  .nav__right{gap:8px}
  .nav__demo{height:34px;padding:0 14px;font-size:13.5px}
  .nav__logo,.nav__demo,.nav__burger{flex:none}
}
@media (max-width:360px){
  .nav__logo img{height:21px}
  .nav__demo{padding:0 12px;font-size:13px}
}

/* ── global FX layer: hero trust line, pings, beams, bitmap world ── */
.dhero__trust{margin:14px 0 0;font-size:12.5px;letter-spacing:.02em;color:rgba(238,242,246,.5);max-width:30em}
/* phone: the line sits closer to the canvas seam, so it reads brighter */
@media (max-width:480px){
  .dhero__trust{color:rgba(238,242,246,.78)}
}

/* live eyebrow dot — radiating ping */
.dhero__eyebrow .dot{position:relative}
.dhero__eyebrow .dot::after{
  content:"";position:absolute;inset:-4px;border-radius:50%;
  border:1px solid rgba(21,184,127,.7);
  animation:eyebrow-ping 2.8s ease-out infinite;
}
@keyframes eyebrow-ping{
  0%{transform:scale(.5);opacity:.9}
  70%,100%{transform:scale(2.1);opacity:0}
}
.no-anim .dhero__eyebrow .dot::after{animation:none;opacity:0}

/* pin landing ripple (one-shot, GSAP-driven) */
.pin__land{fill:none;stroke:var(--emerald);stroke-width:1.6;opacity:0;pointer-events:none}

/* sonar ping on the chosen pin, right before the dive */
.ping{fill:none;stroke:var(--emerald);stroke-width:2;opacity:0;pointer-events:none}

/* data beams: router → analytics cards (drawn on arrival, pulsing at rest) */
.beams{position:absolute;left:0;top:0;width:2px;height:2px;overflow:visible;pointer-events:none}
.beam{fill:none;stroke:var(--emerald);stroke-width:1.3;opacity:0}
.beam-pulse{fill:#2ed49a;opacity:0;filter:drop-shadow(0 0 6px rgba(46,212,154,.8))}
.is-ff .beam-pulse{filter:none}

/* "+1" counter burst on live connects */
.bump{
  position:absolute;right:16px;top:12px;
  font-size:12px;font-weight:700;color:#2ed49a;
  font-variant-numeric:tabular-nums;
  pointer-events:none;opacity:0;
}

/* minimap camera frame — shows where the dive took you */
#mini-cam{fill:none;stroke:rgba(238,242,246,.5);stroke-width:7;pointer-events:none}

/* Firefox bitmap world: the geometry is baked to a canvas (scaled by the
   compositor, Chrome-style) and the vector geometry retires; freeze the
   remaining always-on repainters too */
.world-bitmap{position:absolute;inset:0}
.world-bitmap canvas{display:block;width:100%;height:100%}
.geo-off #geo,.geo-off > .mp-water{display:none}
html.is-ff .pin__halo{animation:none;opacity:.22;transform:scale(1.1)}
html.is-ff .pin__halo--2{opacity:0}
html.is-ff .plan__slab{filter:none}
/* The Gaussian-blurred ripple never plays on Firefox (gated in JS), but its
   mere presence makes Gecko re-evaluate the filter on every frame of the
   plan's intro scale — measured ~3.2s of main-thread stalls at open.
   Remove it from the render tree entirely. */
html.is-ff .plan__ripple{display:none}
html.is-ff .dhero__eyebrow .dot::after{animation:none;opacity:0}

/* ── footer ── */
.pg-footer{border-top:1px solid var(--pg-hairline);background:var(--pg-bg-2);margin-top:40px}
.pg-footer__inner{max-width:1180px;margin:0 auto;padding:72px 24px 0}
.pg-footer__top{display:grid;grid-template-columns:1.2fr 2fr;gap:60px;padding-bottom:56px}
/* h2 since 2026-09-08: the footer is a landmark, so its heading sits at h2
   whatever the page body used. Visual size is unchanged — the selector moved
   with the tag. */
.pg-footer__nl h2{margin:0;font-size:21px;font-weight:700;letter-spacing:-.015em;color:var(--pg-ink)}
.pg-footer__nl p{margin:10px 0 18px;font-size:14px;line-height:1.6;color:var(--pg-mute);max-width:38ch}
.nl-row{display:flex;gap:10px}
/* 44px controls: the WCAG / HIG touch target, and the scale of the nav's own
   buttons. (2026-09-07: the field was content-box, so its min-height:44 had
   rendered 72px with padding and border, and the button stretched to match.) */
.nl-row input[type="email"]{
  flex:1 1 auto;min-width:0;height:44px;box-sizing:border-box;   /* basis auto: the phone column keeps the 44 (flex:1 collapsed it to 20) */
  font:500 14.5px/1 var(--pg-font);color:var(--pg-ink);
  background:var(--pg-surface);border:1px solid var(--pg-hairline);border-radius:12px;
  padding:0 15px;
}
.nl-row input[type="email"]::placeholder{color:var(--pg-faint)}
.nl-row input[type="email"]:focus{outline:none;border-color:var(--pg-emerald)}
.nl-row button{
  flex:none;height:44px;appearance:none;cursor:pointer;border:0;
  font:700 14px/1 var(--pg-font);color:var(--pg-bg);background:var(--pg-ink);
  border-radius:12px;padding:0 20px;
  transition:opacity .25s;
}
.nl-row button:disabled{opacity:.4;cursor:not-allowed}
.pg-footer__gdpr{display:flex;align-items:flex-start;gap:8px;margin-top:12px;font-size:12px;color:var(--pg-faint)}
/* the box itself renders at 13px; the pseudo gives the finger 44x44 centred on
   it. The <label> wraps the text too, so the sentence stays clickable as well. */
.pg-footer__gdpr input{margin-top:2px;accent-color:var(--pg-emerald);position:relative}
.pg-footer__gdpr input::before{
  content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:44px;height:44px;
}
.pg-footer__status{margin:10px 0 0;font-size:12.5px;color:var(--pg-mute);min-height:1.2em}
.pg-footer__status.is-error{color:var(--pg-red)}
/* ── Subscribed: a card lands over the whole form for a few seconds
   (NewsletterForm.vue flips .nl-done in and out, 8s or a click). The status
   line underneath carries the same sentence for screen readers, and stays
   once the card has gone. ── */
#halo-newsletter-form{position:relative}
.nl-done{
  position:absolute;inset:0;z-index:2;box-sizing:border-box;
  display:flex;align-items:center;gap:14px;padding:14px 16px;
  background:var(--pg-surface);
  border:1px solid color-mix(in srgb,var(--pg-emerald) 45%,transparent);
  border-radius:14px;
  box-shadow:0 18px 40px -22px rgba(0,0,0,.45),0 0 0 4px color-mix(in srgb,var(--pg-emerald) 9%,transparent);
  cursor:pointer;
}
.nl-done__mark{flex:none;width:36px;height:36px;border-radius:50%;background:var(--pg-emerald);display:grid;place-items:center}
.nl-done__mark svg{width:18px;height:18px;fill:none;stroke:#fff;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:24;stroke-dashoffset:0}
.nl-done__title{margin:0;font-size:15px;font-weight:700;letter-spacing:-.01em;color:var(--pg-ink)}
.nl-done__sub{margin:3px 0 0;font-size:12.5px;line-height:1.45;color:var(--pg-mute)}
.nl-done__sub b{font-weight:600;color:var(--pg-ink);overflow-wrap:anywhere}
/* settle in, draw the check, lift out */
.nl-done-enter-active{transition:opacity .45s cubic-bezier(.16,1,.3,1),transform .55s cubic-bezier(.16,1,.3,1)}
.nl-done-leave-active{transition:opacity .3s ease,transform .3s ease}
.nl-done-enter-from{opacity:0;transform:translateY(10px) scale(.985)}
.nl-done-leave-to{opacity:0;transform:translateY(-8px)}
.nl-done-enter-active .nl-done__mark svg{animation:nl-check .5s cubic-bezier(.16,1,.3,1) .18s both}
@keyframes nl-check{from{stroke-dashoffset:24}to{stroke-dashoffset:0}}
@media (prefers-reduced-motion:reduce){
  .nl-done-enter-active,.nl-done-leave-active{transition:none}
  .nl-done-enter-active .nl-done__mark svg{animation:none}
}
.pg-footer__cols{display:grid;grid-template-columns:repeat(4,1fr);gap:24px}
/* h3 since 2026-09-08: sits under the footer's h2, so h4 skipped a level. */
.pg-footer__col h3{margin:0 0 16px;font-size:12px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--pg-faint)}
.pg-footer__col ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:11px}
/* 44px tap targets on the footer's link columns. These are stacked navigation
   links, not prose. The list gap shrinks from 11px to 0 and each link grows to
   44px tall instead: the visual rhythm is preserved (18px text + 26px of
   breathing room ~ the old 18+11) while neighbouring targets sit edge to edge
   rather than OVERLAPPING — a negative margin here made adjacent links overlap
   by 12px, which fails the target-spacing half of the guideline. */
.pg-footer__col ul{gap:0}
.pg-footer__col a{font-size:14px;color:var(--pg-mute);text-decoration:none;transition:color .2s;
  display:inline-flex;align-items:center;min-height:44px;min-width:44px}
.pg-footer__col a:hover{color:var(--pg-ink)}
.pg-footer__bottom{
  display:flex;align-items:center;gap:22px;flex-wrap:wrap;
  border-top:1px solid var(--pg-hairline);padding:24px 0 28px;
}
.pg-footer__brand{display:flex;align-items:center;gap:14px;margin-right:auto}
/* 23px (2026-09-07): both brand SVGs are trimmed to the same 715×132 ink box; the retired white PNG
   carried ~12% padding at 26px, and 23px keeps the wordmark at that optical height */
.pg-footer__brand img{display:block;height:23px;width:auto}
.pg-footer__brand span{font-size:12.5px;color:var(--pg-faint)}
.pg-footer__social{display:flex;gap:8px}
.pg-footer__social a{
  width:36px;height:36px;border-radius:50%;display:grid;place-items:center;
  border:1px solid var(--pg-hairline);color:var(--pg-mute);transition:color .2s,border-color .2s;
}
.pg-footer__social a{position:relative}
.pg-footer__social a::before{
  content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:44px;height:44px;border-radius:50%;
}
.pg-footer__social a:hover{color:var(--pg-ink);border-color:var(--pg-mute)}
.pg-footer__social svg{width:15px;height:15px;fill:currentColor}
.pg-footer__demo{font-size:13.5px;font-weight:600;color:var(--pg-mute);text-decoration:none;border-bottom:1px solid var(--pg-hairline);padding-bottom:2px}
.pg-footer__demo:hover{color:var(--pg-cta);border-color:var(--pg-cta)}
/* 44px hit area without disturbing the underline baseline (see the note by
   .nav__theme::before): the link keeps its text box, the pseudo takes the tap. */
.pg-footer__demo{position:relative;display:inline-block}
.pg-footer__demo::before{
  content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);
  min-height:44px;height:100%;
}

/* ── shared section recipe ── */
.sec{position:relative;max-width:1180px;margin:0 auto;padding:112px 24px 96px}
.sec__head{max-width:860px;margin:0 0 64px}
.sec__head--center{margin-inline:auto;text-align:center}
.sec__badge{
  display:inline-flex;align-items:center;gap:9px;
  padding:8px 15px;border-radius:999px;
  font-size:11px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--badge-ink,#cfd6dd);margin:0 0 22px;
  background-image:var(--badge-grad,linear-gradient(191deg,rgba(238,242,246,.12) 0%,rgba(238,242,246,.07) 100%));
}
.sec__badge i{display:none}
.badge-murk{--badge-grad:linear-gradient(191deg,rgba(247,229,198,.16) 0%,rgba(239,211,215,.12) 100%);--badge-ink:#f2ddc9}
.badge-solution{--badge-grad:linear-gradient(29deg,rgba(21,184,127,.2) 0%,rgba(21,184,127,.1) 100%);--badge-ink:#a9e8d3}
.badge-results{--badge-grad:linear-gradient(204deg,rgba(220,238,254,.14) 0%,rgba(210,216,249,.1) 100%);--badge-ink:#c7d3f5}
.badge-products{--badge-grad:linear-gradient(165deg,rgba(247,220,198,.15) 0%,rgba(240,201,201,.11) 100%);--badge-ink:#f3d4c4}
.badge-stories{--badge-grad:linear-gradient(210deg,rgba(232,220,246,.14) 0%,rgba(243,215,228,.1) 100%);--badge-ink:#ddc9f0}
.sec__title{
  margin:0;font-family:var(--pg-display);font-size:clamp(40px,6.4vw,76px);line-height:1.02;font-weight:500;
  letter-spacing:-.02em;color:var(--pg-ink);max-width:14ch;
}
.sec__head--center .sec__title{margin-inline:auto}
/* signature highlighter stroke (same recipe as .p-hero__title strong in
   sub.css): background-size draws 0→100% on entrance; default resolved */
.sec__title strong{
  font-weight:700;
  background-image:linear-gradient(transparent 70%, var(--pg-marker) 70%, var(--pg-marker) 94%, transparent 94%);
  background-repeat:no-repeat;background-position:0 0;background-size:100% 100%;
}
.sec__blurb{margin:18px 0 0;font-size:17px;line-height:1.65;color:var(--pg-mute);max-width:56ch}
.sec__cta{
  display:inline-flex;align-items:center;gap:8px;margin-top:26px;
  font-size:15px;font-weight:600;color:var(--pg-ink);text-decoration:none;
  border-bottom:1px solid var(--pg-hairline);padding-bottom:3px;
  transition:color .25s,border-color .25s;
}
.sec__cta:hover{color:var(--pg-emerald-hi);border-color:var(--pg-emerald)}
/* 44px hit area, underline kept where it is (touch-target note above). These
   are standalone section CTAs, not links inside a sentence, so expanding them
   cannot overlap neighbouring prose. */
.sec__cta{position:relative}
.sec__cta::before{
  content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);
  min-height:44px;height:100%;
}

/* cards */
.grid6{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.card{
  position:relative;display:flex;flex-direction:column;gap:10px;
  background:var(--pg-surface);border:1px solid var(--pg-hairline);
  border-radius:20px;padding:26px 26px 24px;
  transition:transform .35s var(--pg-ease),border-color .35s,box-shadow .35s;
}
.card:hover{transform:translateY(-3px);border-color:rgba(21,184,127,.35);box-shadow:0 18px 44px -22px rgba(0,0,0,.5)}
.card__title{margin:0;font-size:19px;font-weight:700;letter-spacing:-.01em;color:var(--pg-ink)}
.card__blurb{margin:0;font-size:14.5px;line-height:1.6;color:var(--pg-mute)}
/* typographic vignettes */
.vig{margin-top:auto;padding-top:20px}
.vig__fig{
  display:block;font-size:clamp(34px,3.4vw,46px);font-weight:700;letter-spacing:-.03em;
  color:var(--pg-ink);font-variant-numeric:tabular-nums;line-height:1;
}
.vig__fig small{font-size:15px;font-weight:600;color:var(--pg-mute);letter-spacing:0;margin-left:4px}
.vig__fig .usd{font-size:13px;font-weight:600;color:var(--pg-faint);letter-spacing:0;margin-left:8px}
.vig__label{display:block;margin-top:7px;font-size:12.5px;font-weight:600;letter-spacing:.02em;color:var(--pg-faint)}
.vig--good .vig__fig{color:var(--pg-emerald-hi)}
.vig--list{display:flex;flex-wrap:wrap;gap:7px}
.vig--list span{
  font-size:12px;font-weight:600;color:var(--pg-mute);
  border:1px solid var(--pg-hairline);border-radius:999px;padding:6px 11px;white-space:nowrap;
}
.vig--quote blockquote{
  margin:0;font-size:19px;font-weight:700;letter-spacing:-.01em;color:var(--pg-ink);
  font-style:normal;
}
.vig--quote .vig__label{margin-top:9px}

/* buttons */
/* .btn-red is named for its v2-era paint; it is the primary CTA and wears
   the emerald CTA system now. Renaming the class touches 11 pages' markup —
   a dedicated sweep, not a repaint rider. */
.btn-red{
  display:inline-flex;align-items:center;gap:10px;
  padding:15px 28px;border-radius:999px;
  font-size:15.5px;font-weight:700;color:#fff;text-decoration:none;
  background:var(--pg-cta);
  box-shadow:0 18px 40px -14px rgba(13,134,89,.55);
  transition:transform .3s var(--pg-ease),box-shadow .3s,background-color .3s;
}
.btn-red:hover{transform:translateY(-2px);background:var(--pg-cta-hover);box-shadow:0 24px 50px -14px rgba(13,134,89,.65)}
.btn-red svg{width:16px;height:16px;stroke:#fff;stroke-width:2.2;fill:none;stroke-linecap:round;stroke-linejoin:round}
.btn-quiet{
  display:inline-flex;align-items:center;gap:8px;
  padding:14px 24px;border-radius:999px;
  font-size:15px;font-weight:600;color:var(--pg-ink);text-decoration:none;
  border:1px solid var(--pg-hairline);
  transition:border-color .25s,background-color .25s;
}
.btn-quiet:hover{border-color:rgba(21,184,127,.45);background:rgba(21,184,127,.06)}

/* demo line — quiet per-section conversion affordance */
.demo-line{
  margin:44px 0 0;text-align:center;font-size:15px;color:var(--pg-mute);
}
.demo-line a{
  color:var(--pg-ink);font-weight:600;text-decoration:none;
  border-bottom:1px solid var(--pg-hairline);padding-bottom:2px;
  transition:color .25s,border-color .25s;
}
.demo-line a:hover{color:var(--pg-cta);border-color:var(--pg-cta)}

/* hairline seam between sections */
.seam{max-width:1180px;margin:0 auto;padding:0 24px}
.seam::before{content:"";display:block;height:1px;background:var(--pg-hairline-soft)}

/* ── statement interludes ── */
.statement{max-width:940px;margin:0 auto;padding:104px 24px;text-align:center}
.statement p{margin:0;font-size:clamp(34px,5vw,64px);font-weight:500;line-height:1.08;letter-spacing:-.02em;color:var(--pg-ink)}
.statement small{display:block;margin-top:16px;font-size:16px;font-weight:500;color:var(--pg-mute)}
/* closing variant (pricing, compare, api): the statement as a two-cell ledger
   before the final ask — the line left, the aside right — so a page ends on
   two different shapes (a left-anchored slab, then the centred ask) instead of
   two centred display lines. Doubled class beats the phone padding rule below. */
.statement.statement--close{max-width:980px;padding:64px 24px 24px;text-align:left}
.statement__slab{
  display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);
  border:1px solid var(--pg-hairline);border-radius:20px;overflow:hidden;background:var(--pg-surface);
}
.statement--close p{padding:30px 32px;font-family:var(--pg-display);font-size:clamp(26px,3vw,38px);line-height:1.1;border-right:1px solid var(--pg-hairline)}
.statement--close small{display:flex;align-items:center;margin:0;padding:26px 32px;font-size:15px;line-height:1.55;color:var(--pg-mute)}
@media (max-width:760px){
  .statement.statement--close{padding:48px 20px 16px}
  .statement__slab{grid-template-columns:1fr}
  .statement--close p{padding:26px 24px;border-right:0;border-bottom:1px solid var(--pg-hairline)}
  .statement--close small{padding:20px 24px}
}

/* ── bridge: a quiet hand-off line whose stem points into the next scene ── */
.bridge{max-width:940px;margin:0 auto;padding:40px 24px 0;text-align:center}
.bridge p{margin:0;font-size:clamp(17px,1.9vw,22px);font-weight:600;color:var(--pg-ink-soft)}
.bridge__stem{display:block;width:1px;height:56px;margin:18px auto 0;
  background:linear-gradient(var(--pg-hairline), var(--pg-emerald))}

/* ── sticky conversion bar ── */
.sticky-cta{
  position:fixed;left:50%;bottom:18px;z-index:1200;
  transform:translateX(-50%) translateY(140%);
  display:flex;align-items:center;gap:18px;
  width:min(720px,calc(100% - 32px));   /* 720 (2026-09-07, was 680): the platform-first line "Venue networking, with guest WiFi built in. See it live." needs a 341px slot; 680 gave it 324 and an ellipsis */
  padding:12px 12px 12px 22px;border-radius:999px;
  background:var(--pg-glass);border:1px solid var(--pg-hairline);
  backdrop-filter:blur(16px) saturate(1.3);-webkit-backdrop-filter:blur(16px) saturate(1.3);
  box-shadow:0 22px 44px -18px rgba(0,0,0,.62);
  transition:transform .5s var(--pg-ease);
}
.sticky-cta.is-shown{transform:translateX(-50%) translateY(0)}
.sticky-cta p{margin:0;flex:1;min-width:0;font-size:13.5px;font-weight:600;color:var(--pg-ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.halo-sticky-cta__btn{
  flex:none;display:inline-flex;align-items:center;
  padding:11px 20px;border-radius:999px;
  font-size:14px;font-weight:700;color:#fff;text-decoration:none;background:var(--pg-cta);
  transition:background .25s,transform .25s var(--pg-ease);
}
.halo-sticky-cta__btn:hover{background:var(--pg-cta-hover);transform:translateY(-1px)}
.sticky-cta button{
  flex:none;appearance:none;border:0;background:none;cursor:pointer;
  width:34px;height:34px;border-radius:50%;color:var(--pg-mute);font-size:17px;line-height:1;
}
.sticky-cta button:hover{color:var(--pg-ink)}
.is-ff .sticky-cta{backdrop-filter:none;-webkit-backdrop-filter:none;background:var(--pg-bg-2)}
.sticky-cta__calc{flex:none;font-size:13px;font-weight:600;color:var(--pg-mute);text-decoration:none;
  white-space:nowrap;border-bottom:1px solid var(--pg-hairline);padding-bottom:1px;transition:color .25s,border-color .25s}
/* 44px hit area (touch-target note in core.css). */
.sticky-cta__calc{position:relative;display:inline-flex;align-items:center;min-height:44px}
.sticky-cta__calc:hover{color:var(--pg-emerald-hi);border-color:var(--pg-emerald)}
.sticky-cta__wa{display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:38px;height:38px;border-radius:50%;background:rgba(21,184,127,.14);color:var(--pg-emerald)}
.sticky-cta__wa:hover{background:rgba(21,184,127,.24)}
.sticky-cta__wa svg{width:20px;height:20px;fill:currentColor}

/* ── responsive ── */
@media (max-width:1024px){
  .grid6{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:900px){
  /* one primary ask per viewport: while the burger menu is open (it has its
     own CTA), the sticky capsule/bar stands down. Pure CSS via :has(). */
  html:has(#nav-menu.is-open) .sticky-cta{transform:translateX(-50%) translateY(140%)}
  .sec{padding:76px 20px 64px}
  .pg-footer__top{grid-template-columns:1fr;gap:44px}
  .pg-footer__cols{grid-template-columns:repeat(2,1fr);gap:36px 20px}
}
@media (max-width:560px){
  .grid6{grid-template-columns:1fr}
  .statement{padding:72px 20px}
  .sec__head{margin-bottom:36px}
  .sticky-cta p,.sticky-cta__calc{display:none}
  /* phone: slim docked bar, not a floating capsule. Edge-to-edge at the
     very bottom, hairline top edge, red CTA stretched inside — reads as
     part of the page chrome instead of a banner over content. No dismiss
     on phone: the bar stands down by itself wherever the page shows its
     own red ask (the IntersectionObservers in page.js), so it never needs
     manual closing. Both transforms are re-declared because the desktop
     base carries translateX(-50%), which has no business on a bar pinned
     by left:0/right:0. */
  .sticky-cta{
    left:0;right:0;bottom:0;width:auto;
    transform:translateY(110%);
    gap:10px;
    padding:10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
    border-radius:0;border:0;border-top:1px solid var(--pg-hairline);
    box-shadow:0 -16px 36px -24px rgba(0,0,0,.5);
  }
  .sticky-cta.is-shown{transform:translateY(0)}
  .halo-sticky-cta__btn{flex:1;justify-content:center;padding:13px 20px}
  #halo-sticky-dismiss{display:none}
  /* one primary ask per viewport, phone edition: the nav demo button is
     gone entirely at this width (see the nav block above), and while the
     menu is open (its CTA showing) the docked bar stands down. Old
     browsers without :has() keep the bar — graceful. */
  html:has(#nav-menu.is-open) .sticky-cta{transform:translateY(110%)}
  .nl-row{flex-direction:column}
  .nl-row button{padding:13px 20px}
}

@media (prefers-reduced-motion: reduce){
  .nav{animation:none;opacity:1;transform:translateX(-50%)}
  .dhero__eyebrow .dot::after{animation:none;opacity:0}
  .sticky-cta{transition:none}
  .nav__menu,.nav__menu li,.nav__menu ul a::after{transition:none}
}

/* ════════════════════════════════════════════════════════════════════
   DAY THEME — zone recipes + light companions. Everything geometric is
   scoped under html[data-theme="light"]: in dark mode a .zone-night
   wrapper is a plain div whose background equals the body background,
   so dark rendering never moves by a pixel at any viewport width.
   ════════════════════════════════════════════════════════════════════ */

/* ── night zone recipe — full-bleed dark band in BOTH themes. Currently
   unused (full theming shipped, no zones on any page); kept with the
   token re-pin above for future intentional dark objects. ── */
.zone-night{background:var(--pg-bg)}

/* ── dual brand logos (sitewide convention): where the white wordmark
   (halowifi-logo-dark.svg) appears, a sibling colour mark (HaloWiFi-Logo.svg)
   sits next to it; the theme shows exactly one via display toggling. Both
   since 2026-09-07; brand/halowifi-logo@2x.png remains only as the
   Organization schema logo. NEVER lift a logo with a filter. ── */
html[data-theme="light"] .logo-on-dark{display:none}
html:not([data-theme="light"]) .logo-on-light{display:none}

/* ── badges (Pattern B: literal gradients occur in BOTH zones) ── */
html[data-theme="light"] .sec__badge{
  background-image:var(--badge-grad-lt,linear-gradient(191deg,#e9e6df 0%,#dfdbd2 100%));
  color:var(--badge-ink-lt,rgba(16,16,22,.72));
}
html[data-theme="light"] .zone-night .sec__badge{
  background-image:var(--badge-grad,linear-gradient(191deg,rgba(238,242,246,.12) 0%,rgba(238,242,246,.07) 100%));
  color:var(--badge-ink,#cfd6dd);
}
/* per-variant light gradients (production pg.css values); light ink is
   the shared rgba(16,16,22,.72) fallback for every variant */
.badge-murk{--badge-grad-lt:linear-gradient(191deg,#f7e5c6 0%,#efd3d7 100%)}
.badge-solution{--badge-grad-lt:linear-gradient(29deg,#b9e8de 0%,#d9f4ec 100%)}
.badge-results{--badge-grad-lt:linear-gradient(204deg,#dceefe 0%,#d2d8f9 100%)}
.badge-products{--badge-grad-lt:linear-gradient(165deg,#f7dcc6 0%,#f0c9c9 100%)}
.badge-stories{--badge-grad-lt:linear-gradient(210deg,#e8dcf6 0%,#f3d7e4 100%)}

/* ── shadow companions (Pattern B pair for .card — cards can sit inside
   night zones on subpages; .sticky-cta is fixed chrome, never zoned) ── */
html[data-theme="light"] .card:hover{box-shadow:0 18px 44px -24px rgba(16,16,22,.25)}
html[data-theme="light"] .zone-night .card:hover{box-shadow:0 18px 44px -22px rgba(0,0,0,.5)}
html[data-theme="light"] .sticky-cta{box-shadow:0 22px 44px -18px rgba(16,16,22,.18)}

/* ── hero global-FX daylight companions (the hero dive themes light;
   production-ported values, emerald accents deepen to read on white) ── */
html[data-theme="light"] .dhero__trust{color:rgba(18,22,28,.5)}
@media (max-width:480px){
  html[data-theme="light"] .dhero__trust{color:rgba(18,22,28,.78)}
}
html[data-theme="light"] .beam-pulse{fill:#0f9e6c}
html[data-theme="light"] .bump{color:#0f9e6c}
html[data-theme="light"] #mini-cam{stroke:rgba(16,16,22,.4)}

/* ── small-print legibility on white: faint reads fine as labels, but
   sentence-length small copy needs the mute step (footer chrome is never
   zoned, and the token re-pins itself if that ever changes). The error
   line takes the darker red-text value reserved for small red copy on
   light surfaces (modal.css --red-text). ── */
html[data-theme="light"] .pg-footer__gdpr{color:var(--pg-mute)}
html[data-theme="light"] .final__reassure{color:var(--pg-mute)}
html[data-theme="light"] .pg-footer__status.is-error{color:#b01a20}

/* ── Horizontal containment (STRUCTURAL — both themes, never theme-scoped).
   Full-bleed 100vw pseudos and any decorative overhang are held inside the
   page here. This was once html[data-theme="light"] body{overflow-x:clip},
   which meant the LIGHT THEME CHANGED PAGE GEOMETRY: on /case-studies the
   scene numeral escaped and pushed scrollWidth 8px past the viewport in
   light only. A theme rule may change colour, never layout. ── */
body{overflow-x:clip}

/* ════════════════════════════════════════════════════════════════════
   DAYLIGHT ROOMS (light only). The dark theme tells its story in tinted
   rooms; by day each act keeps its hue as a faint tinted AIR on the
   white page: a wash anchored to the top of the section, fading to
   white well before the next section (hard seams stay, the air lives
   inside the section). Full bleed comes from the 100vw pseudo; the
   z-index:-1 drop puts the air behind every card and figure inside the
   .page-body stacking context; the structural body clip above keeps the
   100vw sheet from widening the page on classic-scrollbar platforms.
   Alpha discipline: every tint starts near .05-.09 so text contrast is
   untouched. Dark mode never sees any of this.
   ════════════════════════════════════════════════════════════════════ */
html[data-theme="light"] .page-home #stack::before,
html[data-theme="light"] .page-home #dashboard::before,
html[data-theme="light"] .page-home #network::before,
html[data-theme="light"] .page-home #wifi-worth::before,
html[data-theme="light"] .page-home #products::before,
html[data-theme="light"] .page-home #stories::before,
html[data-theme="light"] .page-home #get-started::before{
  content:"";position:absolute;top:0;bottom:0;left:50%;width:100vw;
  transform:translateX(-50%);z-index:-1;pointer-events:none;
}
/* the murk act: warmed amber air behind the relay boards */
html[data-theme="light"] .page-home #stack::before{
  background:
    radial-gradient(740px 560px at 50% 0%, rgba(255,203,90,.1), rgba(255,203,90,0) 74%),
    linear-gradient(180deg, rgba(255,216,77,.055), rgba(255,216,77,.028) 52%, rgba(255,216,77,0) 78%);
}
/* the solution act: emerald air around the one screen */
html[data-theme="light"] .page-home #dashboard::before{
  background:
    radial-gradient(880px 560px at 50% 16%, rgba(15,158,108,.065), rgba(15,158,108,0) 76%),
    linear-gradient(180deg, rgba(15,158,108,.045), rgba(15,158,108,0) 72%);
}
/* proof stays in the emerald room, quieter */
html[data-theme="light"] .page-home #network::before{
  background:
    radial-gradient(780px 500px at 50% 0%, rgba(15,158,108,.055), rgba(15,158,108,0) 72%),
    linear-gradient(180deg, rgba(15,158,108,.04), rgba(15,158,108,0) 62%);
}
/* the console: a neutral whisper band between the tinted rooms */
html[data-theme="light"] .page-home #wifi-worth::before{
  background:#f5f6f8;
}
/* the hardware act: warm paper air, near uniform so the pinned ride
   never falls back to bare white mid-scrub */
html[data-theme="light"] .page-home #products::before{
  background:
    radial-gradient(920px 620px at 50% 6%, rgba(240,176,106,.07), rgba(240,176,106,0) 76%),
    linear-gradient(180deg, rgba(240,176,106,.045), rgba(240,176,106,.028) 60%, rgba(240,176,106,0) 96%);
}
/* the stories act: soft purple air */
html[data-theme="light"] .page-home #stories::before{
  background:
    radial-gradient(920px 620px at 50% 0%, rgba(213,154,240,.12), rgba(213,154,240,0) 78%),
    linear-gradient(180deg, rgba(213,154,240,.04), rgba(213,154,240,0) 68%);
}
/* the last light: emerald whisper behind the final ask */
html[data-theme="light"] .page-home #get-started::before{
  background:radial-gradient(680px 460px at 50% 36%, rgba(15,158,108,.06), rgba(15,158,108,0) 78%);
}
