/* ============================================================================
   Levcore website — design-system stylesheet (dark-first marketing)
   Mirrors brand-assets/levcore-design-system.css + the concept's marketing
   layer, self-contained for the website deploy. Real components: gradient-wash
   cards, glass, the single glow, mono kickers, the orange-stripe highlights,
   pill CTAs, warm-dark mesh. Display face = Clash Display.
   ========================================================================== */

/* ---- self-hosted brand faces ----------------------------------------------
   All four families are served from this origin. There are no third-party font
   stylesheets: they were render-blocking and cost ~2150ms of modelled FCP/LCP.

   Regenerate with `node scripts/build-website-fonts.mjs`; provenance, licences
   and the per-family rules are in website/fonts/README.md. The rules are NOT
   uniform - Clash Display and IBM Plex Mono ship verbatim because their
   licences require it, Manrope and Sora are subset.

   Do NOT switch these to font-display:optional/fallback, and do NOT load them
   non-blocking from a stylesheet. Measured 2026-08-02: the media="print" trick
   dropped performance 84 -> 79 by pushing CLS 0.008 -> 0.274. What keeps the
   swap free is the metric-adjusted fallback block further down.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Clash Display";
  src: url("fonts/clash-display-variable.woff2") format("woff2");
  font-weight: 200 700;   /* pages ask for 800; CSS matching resolves it to 700 */
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Manrope";
  src: url("fonts/manrope-variable.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Sora";
  src: url("fonts/sora-variable.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/ibm-plex-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/ibm-plex-mono-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/ibm-plex-mono-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
/* IBM's Latin1 split stops at U+00FF, but the Google slice this replaced also
   carried the up/down arrows. This face restores exactly those two codepoints
   and nothing else. MUST stay after the 400 face above: for an overlapping
   unicode-range the later rule wins, and Latin1 does not contain these.
   No page currently uses U+2191/U+2193 (the platform rebuild removed the last
   one), so this is a safety net: unicode-range means it is never fetched. */
@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/ibm-plex-mono-400-pi.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+2191, U+2193;
}

/* ---- metric-adjusted fallbacks --------------------------------------------
   THIS is what makes font-display:swap free of layout shift. Each face bends a
   universally installed font to the brand face's own geometry, so the swap is a
   no-op rather than a reflow.

   Numbers are MEASURED, not guessed (scripts/build-website-fonts.mjs documents
   the method): size-adjust is the ratio of average advance width weighted by
   English letter frequency; the overrides are the brand face's real ascent /
   descent / lineGap divided by (unitsPerEm x size-adjust). Each was taken at
   that family's dominant rendered weight. Re-measure if a family changes.

   unicode-range keeps them to Latin + typographic punctuation, i.e. only the
   text they are standing in for. Symbols the brand faces never had (checks,
   arrows) keep falling through to the generic exactly as before.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Clash Display Fallback";
  src: local("Arial"), local("Helvetica"), local("Liberation Sans");
  size-adjust: 110.22%;
  ascent-override: 80.75%;
  descent-override: 22.68%;
  line-gap-override: 8.17%;
  unicode-range: U+0000-00FF, U+2013, U+2014, U+2018, U+2019, U+201C, U+201D, U+2026;
}
@font-face {
  font-family: "Manrope Fallback";
  src: local("Arial"), local("Helvetica"), local("Liberation Sans");
  size-adjust: 103.85%;
  ascent-override: 102.65%;
  descent-override: 28.89%;
  line-gap-override: 0%;
  unicode-range: U+0000-00FF, U+2013, U+2014, U+2018, U+2019, U+201C, U+201D, U+2026;
}
@font-face {
  font-family: "Sora Fallback";
  src: local("Arial"), local("Helvetica"), local("Liberation Sans");
  size-adjust: 115.59%;
  ascent-override: 83.92%;
  descent-override: 25.09%;
  line-gap-override: 0%;
  unicode-range: U+0000-00FF, U+2013, U+2014, U+2018, U+2019, U+201C, U+201D, U+2026;
}
@font-face {
  font-family: "IBM Plex Mono Fallback";
  src: local("Courier New"), local("Liberation Mono");
  size-adjust: 99.98%;
  ascent-override: 102.52%;
  descent-override: 27.50%;
  line-gap-override: 0%;
  unicode-range: U+0000-00FF, U+2013, U+2014, U+2018, U+2019, U+201C, U+201D, U+2026;
}

/* Marketing-page root size: 17px (106.25%), raised from the browser-default 16px on
   2026-08-13 after independent readability feedback asked for ~10% larger body text.
   Everything rem-based (type scale, spacing written in rem) scales together. Website
   scope only — the app sets its own root; do not port this line with the tokens. */
html { font-size: 106.25%; }

:root {
  --brand-300:#ffa875; --brand-400:#ff8442; --brand-500:#f26522; --brand-600:#dd4e0a; --brand-700:#b23e08;
  --cool-300:#86b2f8; --cool-400:#5c92ee; --cool-500:#3b74da;

  --bg:#0a0e1a; --bg-2:#0b1220; --surface:#111c32; --surface-2:#16233c;
  --border:#1b2a47; --border-2:#243650; --fg:#f1f5f9; --muted:#94a3b8; --muted-2:#7e90a8; /* muted-2 was #64748b (3.3–4.05:1 on dark, failed AA); 4.8:1 worst case now — 2026-08-13 */
  --accent:#ff8442; --accent-deep:#f26522;

  --w-brand:#ff8442; --w-cool:#3b74da; --w-amber:#f59e0b; --w-green:#22c55e;
  --w-blue:#3b82f6; --w-cyan:#06b6d4; --w-rose:#f43f5e; --w-purple:#a855f7;

  /* Each stack is brand face -> its metric-adjusted fallback -> generic. The
     middle entry is what holds layout still during the swap; see the @font-face
     block above. Do not drop it when editing a stack. */
  --font-display:"Clash Display","Clash Display Fallback", ui-sans-serif, system-ui, sans-serif;
  --font-sans:"Manrope","Manrope Fallback", ui-sans-serif, system-ui, sans-serif;
  --font-mono:"IBM Plex Mono","IBM Plex Mono Fallback", ui-monospace, SFMono-Regular, monospace;
  --font-app:"Sora","Sora Fallback", ui-sans-serif, system-ui, sans-serif;   /* the app's own face: product chrome only */

  --radius-card:18px; --radius-pill:999px;
  --ease:cubic-bezier(.2,.7,.2,1); --ease-out:cubic-bezier(.16,1,.3,1);
  --shadow-glow:0 30px 80px -24px rgba(242,101,34,.45);
  --shadow-glow-sm:0 12px 34px -12px rgba(242,101,34,.5);
  --shadow-soft:0 8px 30px -12px rgba(15,29,64,.18);         /* light cards, inside .band-light */
}

/* ---- base ---- */
*{ -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility; }
html{ scroll-behavior:smooth; }
@media (prefers-reduced-motion:reduce){ html{ scroll-behavior:auto; } }
body{ font-family:var(--font-sans); background:var(--bg); color:var(--fg); line-height:1.6; overflow-x:hidden; }
::selection{ background:rgba(242,101,34,.28); color:#fff; }
.font-display{ font-family:var(--font-display); }
.font-mono,.mono{ font-family:var(--font-mono); }
h1,h2,h3,h4{ font-family:var(--font-display); letter-spacing:-.02em; }

/* ---- focus ----
   PRODUCT.md commits to a visible focus indicator. Before this, every surface
   fell through to the UA ring: visible, but unbranded and inconsistent between
   the glass nav and the dark cards. :focus-visible only, so pointer users never
   see it. Two-tone so it holds on both the dark page and inside .band-light. */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
.btn:focus-visible, .pill:focus-visible { outline-offset: 3px; }

/* ---- type ---- */
.display{ font-family:var(--font-display); font-weight:600; letter-spacing:-.02em; line-height:.98; text-wrap:balance; }
.t-hero{ font-size:clamp(2.6rem,6.4vw + .5rem,5.5rem); line-height:.95; }
.t-h2{ font-size:clamp(1.9rem,3.2vw + .6rem,3.3rem); line-height:1; }
.t-lead{ font-size:clamp(1.02rem,.55vw + .85rem,1.25rem); line-height:1.6; color:var(--muted); }
.kicker{ font-family:var(--font-mono); font-size:.72rem; letter-spacing:.26em; text-transform:uppercase; color:var(--brand-300); font-weight:500; }
.kicker-num{ color:var(--muted-2); }
.text-grad{ background:linear-gradient(112deg,#ffb27a,#ff8442 40%,#f26522 72%,#dd4e0a); -webkit-background-clip:text; background-clip:text; color:transparent; }

/* orange-stripe highlights */
.u-stripe{ background-image:linear-gradient(90deg,color-mix(in oklab,var(--accent) 85%,transparent),color-mix(in oklab,var(--accent) 35%,transparent));
  background-repeat:no-repeat; background-position:0 92%; background-size:100% .26em; padding-inline:.04em; }
.link-u{ position:relative; color:var(--fg); text-decoration:none; }
.link-u::after{ content:""; position:absolute; left:0; bottom:-2px; height:2px; width:100%;
  background:linear-gradient(90deg,var(--accent),transparent); transform:scaleX(0); transform-origin:left; transition:transform .4s var(--ease); }
.link-u:hover::after{ transform:scaleX(1); }
/* persistent orange underline (replaces old text underlines) */
.u-on{ background-image:linear-gradient(90deg,var(--accent),color-mix(in oklab,var(--accent) 30%,transparent));
  background-repeat:no-repeat; background-position:0 100%; background-size:100% 2px; padding-bottom:1px; }

/* ---- surfaces ---- */
.mesh{ background:
  radial-gradient(48% 40% at 82% 6%,rgba(242,101,34,.26) 0%,transparent 64%),
  radial-gradient(46% 46% at 4% 18%,rgba(59,116,218,.16) 0%,transparent 60%),
  radial-gradient(60% 50% at 50% 108%,rgba(255,132,66,.10) 0%,transparent 70%),
  linear-gradient(180deg,var(--bg) 0%,var(--bg-2) 100%); }
.mesh-soft{ background:
  radial-gradient(50% 60% at 88% 0%,rgba(242,101,34,.12) 0%,transparent 62%),
  radial-gradient(50% 60% at 0% 100%,rgba(59,116,218,.10) 0%,transparent 62%); }
/* structural blue-only wash: no orange, for sections that must stay quiet */
.mesh-cool{ background:
  radial-gradient(46% 52% at 90% 0%,rgba(59,116,218,.13) 0%,transparent 62%),
  radial-gradient(42% 52% at 2% 96%,rgba(59,116,218,.09) 0%,transparent 60%); }
/* breathing mesh: one slow composited glow drift (hero + closing band). Host
   must be position:relative; the layer is pointer-events:none at z-index 0, so
   content inside needs z-index 1 or higher. */
.mesh-breathe::after{ content:""; position:absolute; inset:-20%; pointer-events:none; z-index:0;
  background:radial-gradient(38% 32% at 68% 22%,rgba(242,101,34,.10) 0%,transparent 66%);
  animation:lw-breathe 46s ease-in-out infinite alternate; will-change:transform,opacity; }
@keyframes lw-breathe{ from{ transform:translate3d(-2.5%,1.5%,0); opacity:.65; } to{ transform:translate3d(2.5%,-1.5%,0); opacity:1; } }
/* Softened 2026-08-02: a hairline grid field is a generated-UI tell, so the
   texture is dialled back to a hint (3% lines, mask dying by 58%) rather than
   removed. Keep it to ONE masked instance per page, behind real content. */
.grid-overlay{ background-image:linear-gradient(rgba(148,163,184,.03) 1px,transparent 1px),linear-gradient(90deg,rgba(148,163,184,.03) 1px,transparent 1px);
  background-size:46px 46px; -webkit-mask-image:radial-gradient(110% 70% at 50% 0%,#000 18%,transparent 58%); mask-image:radial-gradient(110% 70% at 50% 0%,#000 18%,transparent 58%); }
.glass{ background:rgba(17,28,50,.55); backdrop-filter:blur(16px) saturate(140%); -webkit-backdrop-filter:blur(16px) saturate(140%); border:1px solid rgba(255,255,255,.08); }
.hairline{ border:1px solid var(--border); }
.divider{ height:1px; background:linear-gradient(90deg,transparent,var(--border-2),transparent); }
/* signature gradient rule — orange→blue. Use SPARINGLY (it's an accent, not a
   default divider): top-edge of ONE "pillar" section per page (e.g. the moat /
   "why us"), or a single problem→solution seam. Everyday separation = .divider.
   Rule of thumb: max ~1–2 per page or it loses its weight. */
.rule-grad{ height:3px; border:0; background:linear-gradient(90deg,var(--accent-deep),var(--accent) 45%,var(--cool-500)); }

/* ---- ★ gradient-wash cards ---- */
.gcard{ position:relative; isolation:isolate; border:1px solid var(--border); background:var(--surface); border-radius:var(--radius-card);
  padding:clamp(1.2rem,2vw,1.6rem); overflow:hidden; --wash:var(--accent);
  transition:transform .5s var(--ease), border-color .5s var(--ease), box-shadow .5s var(--ease); }
.gcard::before{ content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:linear-gradient(135deg,color-mix(in oklab,var(--wash) 16%,transparent) 0%,transparent 56%); opacity:.85; transition:opacity .5s var(--ease); }
.gcard::after{ content:""; position:absolute; inset:0 0 auto 0; height:1px; z-index:1;
  background:linear-gradient(90deg,transparent,color-mix(in oklab,var(--wash) 70%,transparent),transparent); opacity:.45; transition:opacity .5s var(--ease); }
.gcard:hover{ transform:translateY(-5px); border-color:color-mix(in oklab,var(--wash) 38%,var(--border)); box-shadow:0 26px 60px -30px color-mix(in oklab,var(--wash) 60%,transparent); }
.gcard:hover::before,.gcard:hover::after{ opacity:1; }
.gcard--brand{--wash:var(--w-brand)} .gcard--cool{--wash:var(--w-cool)} .gcard--amber{--wash:var(--w-amber)} .gcard--green{--wash:var(--w-green)}
.gcard--blue{--wash:var(--w-blue)} .gcard--cyan{--wash:var(--w-cyan)} .gcard--rose{--wash:var(--w-rose)} .gcard--purple{--wash:var(--w-purple)}

.glyph{ display:inline-flex; align-items:center; justify-content:center; width:2.75rem; height:2.75rem; border-radius:14px;
  background:color-mix(in oklab,var(--wash) 16%,var(--surface-2)); color:color-mix(in oklab,var(--wash) 86%,#fff); border:1px solid color-mix(in oklab,var(--wash) 28%,transparent); }

/* ---- form fields · consent banner · gate veil (graduated 2026-08-04) ----
   The site had no input component, no dialog pattern and no way to obscure
   content behind a value exchange; all three now come from the design system.
   Never set outline:none on .field — the :focus-visible ring above is the a11y
   commitment. The veil is presentation, not a security boundary: the content
   under it must also be made inert (pointer-events + aria-hidden). */
.field{ width:100%; border-radius:10px; padding:.7rem .9rem; background:rgba(11,18,32,.6); border:1px solid var(--border-2);
  color:var(--fg); font:inherit; font-size:.92rem; transition:border-color .3s var(--ease), background .3s var(--ease); }
.field::placeholder{ color:var(--muted-2); }
.field:hover{ border-color:color-mix(in oklab,var(--accent) 30%,var(--border-2)); }
.field:focus{ border-color:var(--brand-400); }
.field-label{ display:block; font-size:.78rem; font-weight:600; color:var(--fg); margin-bottom:.3rem; }
.field-hint{ font-size:.72rem; color:var(--muted); }
.field-error{ font-size:.78rem; color:var(--w-rose); }

.consent-banner{ position:fixed; z-index:80; left:1rem; right:1rem; bottom:1rem; max-width:30rem;
  border-radius:var(--radius-card); padding:1rem 1.1rem; display:flex; flex-direction:column; gap:.75rem;
  box-shadow:0 24px 60px -30px rgba(0,0,0,.7); }
.consent-copy{ font-size:.8rem; line-height:1.55; color:var(--muted); margin:0; }
.consent-actions{ display:flex; flex-wrap:wrap; align-items:center; gap:.5rem; }
.consent-actions .btn{ padding:.45rem .9rem; font-size:.8rem; }
/* Decline is a quiet text control, not a third pill: a real reachable choice (that is
   what makes the banner consent) that does not compete with Accept. Uses --muted
   (7.5:1 here), NOT --muted-2 (which sat at 4.05:1 until the 2026-08-13 token fix). */
.consent-decline{ margin-left:auto; background:none; border:0; padding:.45rem .2rem; cursor:pointer;
  font:inherit; font-size:.78rem; font-weight:600; color:var(--muted); transition:color .3s var(--ease); }
.consent-decline:hover{ color:var(--fg); }

.gate-veil{ position:relative; filter:blur(7px) saturate(.85); opacity:.5; pointer-events:none; user-select:none;
  transition:filter .6s var(--ease), opacity .6s var(--ease); }
.gate-veil--lifted{ filter:none; opacity:1; pointer-events:auto; user-select:auto; }

/* ---- pills / badges ---- */
.pill{ display:inline-flex; align-items:center; gap:.45rem; border-radius:var(--radius-pill); padding:.3rem .7rem; font-size:.72rem; font-weight:600;
  border:1px solid var(--border-2); background:rgba(148,163,184,.06); color:var(--muted); }
.dot{ width:.45rem; height:.45rem; border-radius:999px; background:var(--accent); }
.dot-live{ background:#34d399; box-shadow:0 0 0 0 rgba(52,211,153,.6); animation:lw-pulse 2.4s var(--ease) infinite; }
@keyframes lw-pulse{ 70%{box-shadow:0 0 0 7px rgba(52,211,153,0)} 100%{box-shadow:0 0 0 0 rgba(52,211,153,0)} }

/* ---- trust marks: seals, context-aware cards, the data-flow track ---- */
/* engraved assurance chip: hairline plate, faint vertical gradient, inset top
   highlight, accent tick. Short proof statements only, not a generic badge. */
.seal{ display:inline-flex; align-items:center; gap:.5rem; border-radius:10px; padding:.55rem .85rem;
  border:1px solid var(--border-2); background:linear-gradient(180deg,rgba(148,163,184,.07),rgba(148,163,184,.02));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05); font-size:.74rem; font-weight:600; color:var(--fg); }
.seal svg{ color:var(--brand-400); }
/* context-aware containers: dark surface by default, white inside .band-light */
.lt-card{ background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-card); }
.lt-node{ background:var(--surface-2); border:1px solid var(--border); border-radius:10px; padding:.8rem 1rem; text-align:center; }
.lt-muted{ color:var(--muted); }
/* build-status chips (light-band values live in the light-band layer) */
.lt-chip-beta{ color:var(--w-amber); background:rgba(245,158,11,.10); }
.lt-chip-ok{ color:var(--w-green); background:rgba(34,197,94,.10); }
/* data-flow track: hairline rail + ONE travelling accent dot. The host sets
   --tw (run distance = track width minus dot width) so the dot lands on the end. */
.flow-track{ position:relative; height:2px; background:linear-gradient(90deg,transparent,var(--border-2) 12%,var(--border-2) 88%,transparent); }
.flow-dot{ position:absolute; left:0; top:50%; margin-top:-5px; width:10px; height:10px; border-radius:var(--radius-pill);
  background:var(--accent); box-shadow:0 0 0 4px rgba(242,101,34,.15); animation:flow-run 12s linear infinite; will-change:transform; }
@keyframes flow-run{ from{ transform:translateX(0); } to{ transform:translateX(var(--tw,600px)); } }

/* ---- buttons ---- */
.btn{ display:inline-flex; align-items:center; gap:.55rem; border-radius:12px; padding:.7rem 1.1rem; font-weight:600; font-size:.92rem;
  cursor:pointer; border:1px solid transparent; white-space:nowrap; transition:transform .3s var(--ease), background .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease); }
.btn:active{ transform:translateY(1px) scale(.96); }   /* press feedback (soft-motion spec) */
.btn-pill{ border-radius:var(--radius-pill); padding-inline:1.4rem; }
.btn-primary{ background:var(--accent-deep); color:#fff; box-shadow:var(--shadow-glow-sm); }
.btn-primary:hover{ background:var(--brand-400); transform:translateY(-2px); }
.btn-ghost{ border-color:var(--border-2); color:var(--fg); background:rgba(148,163,184,.04); }
.btn-ghost:hover{ border-color:var(--accent); color:#fff; }
.btn-dark{ background:var(--surface-2); color:var(--fg); border-color:var(--border); }
.btn-dark:hover{ border-color:var(--accent); }
.btn-arrow svg{ transition:transform .3s var(--ease); }
.btn-arrow:hover svg{ transform:translateX(3px); }

/* ---- marquee ---- */
.marquee-mask{ -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent); mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent); }
.marquee{ display:flex; width:max-content; animation:lw-marquee 38s linear infinite; }
.marquee:hover{ animation-play-state:paused; }
@keyframes lw-marquee{ to{ transform:translateX(-50%); } }

/* ---- nav ---- */
.nav{ transition:background .4s var(--ease), border-color .4s var(--ease), backdrop-filter .4s var(--ease); }
.nav.scrolled{ background:rgba(10,14,26,.72); backdrop-filter:blur(14px); border-bottom-color:var(--border); }
.nav-link{ color:var(--muted); font-weight:600; transition:color .25s var(--ease); }
.nav-link:hover{ color:var(--fg); }

/* ---- product chrome: app-window frames ---- */
/* Only when depicting the product's own UI. Per DESIGN.md the app display face
   (Sora, via .chrome) applies inside chrome, so the page keeps Clash Display
   for its own voice. Never the reverse: no Clash inside a frame. */
.chrome{ font-family:var(--font-app); }
.frame{ border-radius:var(--radius-card); border:1px solid var(--border); background:var(--surface);
  outline:1px solid rgba(255,255,255,.06); outline-offset:-1px;   /* top-edge highlight */
  overflow:hidden; box-shadow:0 30px 80px -40px rgba(3,7,18,.9); }
.frame-bar{ display:flex; align-items:center; gap:.6rem; padding:.65rem .9rem;
  background:color-mix(in oklab,var(--bg-2) 85%,transparent); border-bottom:1px solid var(--border); }
.frame-dots span{ display:inline-block; width:.55rem; height:.55rem; border-radius:var(--radius-pill); background:var(--border-2); margin-right:.3rem; }

/* ---- light band: the alternating white section treatment ---- */
/* A band of daylight inside an otherwise dark page. It re-asserts the LIGHT
   semantic tokens locally, so token-driven components (cards, glyphs, pills,
   dividers) flip on their own; only what tokens can't express is restated.
   The accent tokens are deliberately NOT reset: the band instead overrides the
   few places where dark-page orange reads wrong on white. */
.band-light{ --bg:#ffffff; --surface:#ffffff; --surface-2:#f1f5f9;
  --border:#e2e8f0; --border-2:#cbd5e1; --fg:#0b1220; --muted:#475569; --muted-2:#64748b;
  background:linear-gradient(180deg,#ffffff 0%,#f6f8fc 100%); color:var(--fg);
  border-top:1px solid var(--border); border-bottom:1px solid var(--border);
  box-shadow:inset 0 26px 50px -40px rgba(11,18,32,.35), inset 0 -26px 50px -44px rgba(11,18,32,.25); }
.band-light .kicker{ color:var(--brand-700); }                     /* brand-700: AA on white at kicker size */
.band-light .u-stripe{ background-image:linear-gradient(90deg,color-mix(in oklab,var(--accent-deep) 55%,transparent),color-mix(in oklab,var(--accent-deep) 22%,transparent)); }
.band-light .u-on{ background-image:linear-gradient(90deg,var(--accent-deep),color-mix(in oklab,var(--accent-deep) 30%,transparent)); }
.band-light .lt-card,.band-light .lt-node,.band-light .gcard{ box-shadow:var(--shadow-soft); }
.band-light .gcard:hover{ border-color:var(--border-2); }
.band-light .glyph{ background:var(--surface-2); border-color:var(--border); }
.band-light .pill{ background:rgba(15,29,64,.04); }
.band-light .lt-chip-beta{ color:#92400e; background:rgba(245,158,11,.16); }
.band-light .lt-chip-ok{ color:#166534; background:rgba(34,197,94,.15); }
.band-light .flow-track{ background:linear-gradient(90deg,var(--border),var(--border-2) 20%,var(--border-2) 80%,var(--border)); }
.band-light .flow-dot{ background:var(--accent-deep); }
/* the site's Tailwind ink utilities, re-pointed for the band */
.band-light .text-ink-100{ color:#0b1220; } .band-light .text-ink-200{ color:#334155; }
.band-light .text-ink-300{ color:#475569; } .band-light .text-ink-400{ color:#64748b; }
.band-light .border-ink-700,.band-light .border-ink-600{ border-color:#e2e8f0; }

/* ---- motion: soft-motion spec ---- */
/* entrances          ~850ms --ease-out, 10px translate + blur(6px) to 0
                      (page headers + the hero only, once, on load)
   scroll-reveals     .9s --ease-out, 90ms stagger after a 150ms lead-in breath
                      (the host sets --rd: 150ms + i*90ms, capped)
   micro-interactions 200-250ms, press feedback scale(.96) */
/* entrance layer, JS-gated: <html> gets .js, then <body> gets .entered on the
   first frame. Without .js nothing hides, so the content is simply there. */
.js .enter{ opacity:0; transform:translateY(10px); filter:blur(6px); }
.js .entered .enter{ animation:lw-rise .85s var(--ease-out) both; animation-delay:var(--d,0ms); }
@keyframes lw-rise{ from{ opacity:0; transform:translateY(10px); filter:blur(6px); } to{ opacity:1; transform:none; filter:blur(0); } }

.reveal{ opacity:0; transform:translateY(20px); transition:opacity .9s var(--ease-out), transform .9s var(--ease-out); transition-delay:var(--rd,0ms); }
.reveal.in,.no-js .reveal{ opacity:1; transform:none; }
@media (prefers-reduced-motion:reduce){
  .reveal{ opacity:1!important; transform:none!important; }
  .js .enter,.js .entered .enter{ opacity:1; transform:none; filter:none; animation:none; }
  .marquee,.dot-live{ animation:none!important; }
  .mesh-breathe::after,.flow-dot{ animation:none; }
  .flow-dot{ transform:translateX(calc(var(--tw,600px) * .62)); }   /* parked mid-run */
  .btn:active{ transform:none; }
}
