/* components.css — nav, hero, proof, work, stats, forms, footer. */

/* ── nav ───────────────────────────────────────────────────────────── */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 60;
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.1rem clamp(1rem, 2.6vw, 1.9rem); /* v71 — tighter to the edges (logo left, CTAs right) */
  background: linear-gradient(180deg, rgba(5,7,13,0.72), transparent);
  backdrop-filter: blur(2px);
  pointer-events: none; /* v72 — empty strip is click-through to the scene; controls re-enabled in the scene block. Lives here (not the clobbering group below) so the nav STAYS position:fixed z-60 → the B logo floats on scroll. */
}
.nav__mark { display: flex; align-items: center; gap: 0.6rem; }
.nav__mark svg, .nav__mark img { width: 26px; height: 26px; }
.nav__word { font-family: var(--font-display); font-weight: 600; font-size: 1.02rem; letter-spacing: 0.01em; color: var(--text-000); }
.nav__links { display: flex; gap: clamp(1rem, 2.4vw, 2.4rem); align-items: center; }
.nav__links a { font-size: var(--step--1); color: var(--text-200); letter-spacing: 0.02em; transition: color .3s var(--ease); }
.nav__links a:hover { color: var(--text-000); }
.nav__cta { color: var(--signal) !important; border: 1px solid var(--signal-dim); padding: 0.5rem 0.9rem; border-radius: var(--radius); }
.nav__cta:hover { background: rgba(0,204,51,0.08); }
@media (max-width: 640px) { .nav__links a:not(.nav__cta) { display: none; } }

/* ── v71 NAV scroll-transform + burger + slide-in side menu ─────────────────
   On scroll-down (body.nav-hidden) the word + CTAs fade, the logo mark stays on top,
   and the burger appears → opens the side menu. (The whole-nav hide is neutralized below.) */
.nav__mark  { z-index: 62; pointer-events: auto; }
.nav__word  { transition: opacity .45s var(--ease-out), transform .45s var(--ease-out); }
.nav__links { transition: opacity .45s var(--ease-out), transform .45s var(--ease-out); }
body.nav-hidden .nav__word  { opacity: 0; transform: translateX(-10px); pointer-events: none; }
body.nav-hidden .nav__links { opacity: 0; transform: translateY(-10px); pointer-events: none; }

.nav__burger {
  /* v72 — OUT of the flex row (it was holding the far-right slot with flex:none and shoving the
     CTAs into the middle — the red-arrow gap). Absolute-anchored to the SAME right edge as the CTAs
     so they now reach the true edge; the burger overlays that edge and only shows on scroll-down. */
  position: absolute; right: clamp(1rem, 2.6vw, 1.9rem); top: 50%;
  z-index: 62; width: 33px; height: 33px; /* v73 — burger 25% smaller (Tyler) */
  border: 1px solid var(--signal-dim); border-radius: 8px; background: rgba(10,18,32,0.5);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  cursor: pointer; opacity: 0; pointer-events: none; transform: translateY(-50%) scale(0.9);
  transition: opacity .4s var(--ease-out), transform .4s var(--ease-out), border-color .3s var(--ease);
}
.nav__burger span { display: block; width: 14px; height: 1.5px; background: var(--text-000); border-radius: 2px; } /* v73 — 25% smaller bars */
.nav__burger:hover { border-color: var(--signal); }
body.nav-hidden .nav__burger { opacity: 1; pointer-events: auto; transform: translateY(-50%) scale(1); }

body.menu-open { overflow: hidden; }
.sidemenu { position: fixed; inset: 0; z-index: 200; visibility: hidden; }
.sidemenu.is-open { visibility: visible; }
.sidemenu__scrim { position: absolute; inset: 0; background: rgba(4,8,16,0.62);
  -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
  opacity: 0; transition: opacity .45s var(--ease-out); }
.sidemenu.is-open .sidemenu__scrim { opacity: 1; }
.sidemenu__panel {
  position: absolute; top: 0; right: 0; height: 100%; width: min(86vw, 400px);
  background: linear-gradient(200deg, rgba(14,22,40,0.97), rgba(6,10,20,0.985));
  border-left: 1px solid rgba(120,190,255,0.16); box-shadow: -30px 0 80px rgba(0,10,30,0.6);
  transform: translateX(100%); transition: transform .55s cubic-bezier(0.22,0.61,0.36,1);
  display: flex; flex-direction: column; padding: clamp(2rem,6vh,4rem) clamp(1.8rem,5vw,3rem);
}
.sidemenu.is-open .sidemenu__panel { transform: translateX(0); }
.sidemenu__close { align-self: flex-end; width: 40px; height: 40px; border: none; background: none;
  color: var(--text-200); font-size: 2rem; line-height: 1; cursor: pointer; transition: color .3s; margin-bottom: 1.6rem; }
.sidemenu__close:hover { color: var(--text-000); }
.sidemenu__links { display: flex; flex-direction: column; gap: 0.15rem; }
.sidemenu__links a { position: relative; font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.5rem, 4.5vw, 2.1rem); color: var(--text-100); padding: 0.78rem 0; overflow: hidden;
  border-bottom: 1px solid rgba(200,215,240,0.08);
  transition: color .3s var(--ease), padding-left .35s var(--ease); }
.sidemenu__links a span { display: inline-block; opacity: 0; transform: translateX(28px);
  transition: opacity .5s var(--ease-out), transform .5s var(--ease-out); }
.sidemenu.is-open .sidemenu__links a span { opacity: 1; transform: none; }
.sidemenu.is-open .sidemenu__links a:nth-child(1) span { transition-delay: .14s; }
.sidemenu.is-open .sidemenu__links a:nth-child(2) span { transition-delay: .20s; }
.sidemenu.is-open .sidemenu__links a:nth-child(3) span { transition-delay: .26s; }
.sidemenu.is-open .sidemenu__links a:nth-child(4) span { transition-delay: .32s; }
.sidemenu.is-open .sidemenu__links a:nth-child(5) span { transition-delay: .38s; }
.sidemenu__links a:hover { color: var(--signal); padding-left: 0.5rem; }
@media (prefers-reduced-motion: reduce) {
  .sidemenu__panel, .sidemenu__scrim, .sidemenu__links a span, .nav__burger { transition-duration: .2s; }
}

/* ── THE SCENE: fixed full-page WebGPU backdrop (whole site descends through it) ── */
/* pointer-events: auto → the scene receives click-hold drag (orbit) + the gravity well.
   Content above is click-THROUGH so events fall to the scene, EXCEPT real controls
   (links / buttons / FAQ toggles / inputs) — play with the particles in the empty
   space while nav + CTAs still work. (Trade-off: body text isn't selectable.) */
#hero-gl { position: fixed; inset: 0; z-index: 0; pointer-events: auto;
  background: radial-gradient(130% 100% at 68% 8%, #0a1424 0%, var(--ink-000) 60%); }
#hero-gl .scene-poster { position: absolute; inset: 0; }
#hero-gl .scene-poster img { width: 100%; height: 100%; object-fit: cover; opacity: 0.9; }
#hero-gl[data-hero="live"] .scene-poster { opacity: 0; transition: opacity 1.2s var(--ease-out); }

/* content floats above the scene, but is click-through so the scene stays interactive */
main, .footer { position: relative; z-index: 1; pointer-events: none; }
/* v72 — .nav pulled OUT of that group: it must keep position:fixed z-60 (base rule) so the B logo
   FLOATS on scroll instead of scrolling away with the page. Its pointer-events:none moved to the base rule. */
.nav a, .nav button, .nav__cta,
main a, main button, main summary, main input, main textarea, main label,
.footer a { pointer-events: auto; }
/* gmunk dust-condense canvas — above the hero text (z-5), never blocks clicks */
#hero-fx { position: fixed; inset: 0; z-index: 5; pointer-events: none; }
/* click-hold nav: don't rubber-band-select copy while dragging the scene (inputs stay selectable) */
body { -webkit-user-select: none; user-select: none; }
input, textarea { -webkit-user-select: text; user-select: text; }

/* ── hero (transparent content section over the scene) ────────────── */
/* The hero is a TALL descent track (340svh) so the 4 cinematic acts get real scroll
   room; .hero__inner is STICKY, pinning the headline in the viewport through the
   opening acts (COSMIC DUST / NEBULA) while the camera dives, then releasing it as
   content below (About…) scrolls up into SUPERNOVA / APOTHEOSIS. */
.hero { position: relative; min-height: 340svh; }
.hero__inner { position: sticky; top: 0; min-height: 100svh;
  display: flex; flex-direction: column; justify-content: flex-end;
  width: 100%; max-width: 1360px; margin-inline: auto; padding: 0 var(--gutter) clamp(2.5rem, 5vh, 4rem); }
.hero__title { max-width: 15ch; }
.hero__title .accent { color: var(--signal); }
.hero__sub { margin-top: 1.5rem; max-width: 64ch; font-size: var(--step-1); color: var(--text-100); }
@media (max-width: 640px) { .hero__sub { max-width: 34ch; } }
.hero__cta { display: flex; gap: 1rem; margin-top: 2.2rem; flex-wrap: wrap; }
/* cinematic reveal — VISIBLE BY DEFAULT (safe for no-JS / no-engine / low-power). The
   engine adds .hero-armed while the BLISS particles ARE the brand (upper frame), then
   .hero-revealed POPS the crisp DOM headline in BELOW them: each line blurs → overshoots
   → settles, staggered, with a glow flare on "signal". */
.hero__title .hl-line { display: block; }
.hero-armed .hero__title .hl-line, .hero-armed .hero__sub, .hero-armed .hero__cta { opacity: 0; }
@keyframes hlPop {
  0%   { opacity: 0; transform: translateY(26px) scale(0.93); filter: blur(16px); }
  58%  { opacity: 1; transform: translateY(-3px) scale(1.012); filter: blur(0); }
  100% { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes accentGlow {
  0%   { text-shadow: 0 0 0 rgba(0,204,51,0); }
  55%  { text-shadow: 0 0 38px rgba(0,204,51,0.82); }
  100% { text-shadow: 0 0 18px rgba(0,204,51,0.42); }
}
@keyframes hlRise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
/* the gmunk particlize module (hero-particlize.js) OWNS the h1 lines + sub reveal
   via inline opacity as the dust condenses. Keep only the accent glow-flare + a
   simple cta fade here (the cta isn't part of the particlize). */
.hero-revealed .hero__title .accent { animation: accentGlow 1.8s var(--ease-out) 0.55s both; }
.hero-revealed .hero__cta { opacity: 1; transition: opacity 0.9s var(--ease-out) 0.3s; }
.arrow--down { display: inline-block; }
.btn:hover .arrow--down { transform: translateY(3px); }
@media (prefers-reduced-motion: reduce) {
  .hero-armed .hero__title .hl-line, .hero-armed .hero__sub, .hero-armed .hero__cta { opacity: 1; }
  .hero-revealed .hero__title .hl-line, .hero-revealed .hero__sub, .hero-revealed .hero__cta, .hero-revealed .hero__title .accent { animation: none; }
}
.hero__telemetry { position: absolute; top: 40%; right: var(--gutter); z-index: 2;
  font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.16em; color: var(--text-300);
  text-align: right; line-height: 2; text-transform: uppercase; }
.hero__telemetry b { color: var(--signal); font-weight: 500; }
@media (max-width: 720px) { .hero__telemetry { display: none; } }
.hero__scrollcue { position: absolute; bottom: 1.6rem; left: var(--gutter); z-index: 2;
  font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.2em; color: var(--text-300); text-transform: uppercase; }

/* ── content legibility over the moving scene ─────────────────────── */
/* NO full-width scrim — the WebGPU descent shows through completely. Legibility
   comes from a cinematic text-shadow; only genuinely dense blocks get a BENTO
   card (.veil-card) that backs JUST the text, never the full section width. */
main > .section:not(.hero) { position: relative; }
main > .section:not(.hero) > .wrap { position: relative; z-index: 1; }
main .section:not(.hero) h2,
main .section:not(.hero) h3,
main .section:not(.hero) p,
main .section:not(.hero) .stat,
main .section:not(.hero) .rail__metric,
main .section:not(.hero) .case__metric,
main .section:not(.hero) .eyebrow {
  text-shadow: 0 2px 24px rgba(3,5,11,0.92), 0 0 3px rgba(3,5,11,0.8);
}
/* ── elite luxury glassmorphism bento — see-through, backs text over the scene ── */
.veil-card {
  position: relative;
  background: linear-gradient(158deg, rgba(22,30,48,0.34), rgba(9,12,20,0.26));
  backdrop-filter: blur(20px) saturate(1.25);
  -webkit-backdrop-filter: blur(20px) saturate(1.25);
  border: 1px solid rgba(180,210,255,0.13);
  border-radius: 18px;
  box-shadow: 0 28px 70px -24px rgba(0,0,0,0.65), inset 0 1px 0 rgba(255,255,255,0.09);
  padding: clamp(1.5rem, 3vw, 2.4rem);
  isolation: isolate;
}
.veil-card::before { /* top-edge sheen + faint aurora, like the reference glass */
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: -1;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.07), transparent 42%),
    radial-gradient(120% 60% at 15% -10%, rgba(0,204,51,0.10), transparent 60%);
}
.veil-card > :last-child { margin-bottom: 0; }
/* work cases as glass cards: drop the list borders, space them, keep the grid */
.case.veil-card { border-top: none; padding: clamp(1.4rem,2.6vw,2rem); margin-bottom: 1rem; }
.case.veil-card:last-child { border-bottom: none; margin-bottom: 0; }
.rail.veil-card h3 { margin-top: 0.2rem; }
.stats.veil-card { padding: clamp(1.6rem,3vw,2.4rem); }

/* ── buttons ───────────────────────────────────────────────────────── */
.btn { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.85rem 1.5rem;
  border-radius: var(--radius); font-size: var(--step-0); font-weight: 450; letter-spacing: 0.01em;
  transition: transform .25s var(--ease), background .25s var(--ease), border-color .25s var(--ease); }
.btn:hover { transform: translateY(-1px); }
.btn--primary { background: var(--signal); color: var(--ink-000); font-weight: 500; }
.btn--primary:hover { background: #7ce0f2; }
.btn--ghost { border: 1px solid var(--hair-strong); color: var(--text-000); }
.btn--ghost:hover { border-color: var(--text-200); background: rgba(210,220,236,0.04); }
.arrow { transition: transform .25s var(--ease); }
.btn:hover .arrow, .link:hover .arrow { transform: translateX(3px); }

/* ── thesis ────────────────────────────────────────────────────────── */
.thesis { display: grid; grid-template-columns: minmax(0,5fr) minmax(0,7fr); gap: clamp(2rem,5vw,5rem); align-items: start; }
.thesis__statement { font-size: var(--step-2); color: var(--text-000); font-family: var(--font-display); font-weight: 500; line-height: 1.14; letter-spacing: -0.01em; max-width: 16ch; }
.thesis__body p + p { margin-top: 1.1rem; }
.thesis__body em { font-style: normal; color: var(--signal); }
@media (max-width: 820px) { .thesis { grid-template-columns: 1fr; gap: 1.6rem; } }

/* ── offers ────────────────────────────────────────────────────────── */
.offers { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1rem,2vw,1.6rem); }
.offer {
  position: relative; display: flex; flex-direction: column;
  background: linear-gradient(158deg, rgba(22,30,48,0.34), rgba(9,12,20,0.26));
  backdrop-filter: blur(20px) saturate(1.25); -webkit-backdrop-filter: blur(20px) saturate(1.25);
  border: 1px solid rgba(180,210,255,0.13); border-radius: 18px;
  box-shadow: 0 28px 70px -24px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.09);
  padding: clamp(1.5rem,3vw,2.2rem); transition: border-color .3s var(--ease), transform .3s var(--ease);
}
.offer::before { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 0;
  background: linear-gradient(180deg, rgba(255,255,255,0.07), transparent 42%), radial-gradient(120% 60% at 15% -10%, rgba(0,204,51,0.10), transparent 60%); }
.offer > * { position: relative; z-index: 1; }
.offer:hover { border-color: rgba(180,210,255,0.28); transform: translateY(-3px); }
.offer__glyph { font-family: var(--font-mono); font-size: 1.2rem; margin-bottom: 1rem; }
.offer:nth-child(1) .offer__glyph { color: var(--resonance); }
.offer:nth-child(2) .offer__glyph { color: var(--signal); }
.offer:nth-child(3) .offer__glyph { color: #9db4ff; }
.offer:nth-child(4) .offer__glyph { color: var(--text-100); }
.offer h3 { margin-bottom: 0.7rem; font-size: 1.32rem; }
.offer p { color: var(--text-100); font-size: var(--step--1); }
.offer p strong { color: var(--text-000); font-weight: 500; }
.offer__ctas { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: auto; padding-top: 1.3rem; }
.btn--sm { padding: 0.5rem 0.85rem; font-size: 0.8rem; border-radius: 9px; }
.btn--sm b { color: var(--signal); font-weight: 600; }
@media (max-width: 720px) { .offers { grid-template-columns: 1fr; } }

/* ── proof rails: two rails, money + machinery ─────────────────────── */
.rails { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem,4vw,4rem); }
.rail__head { display: flex; align-items: baseline; gap: 0.8rem; margin-bottom: 1.6rem; }
.rail__head .tag { font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--text-300); }
.rail h3 { font-size: var(--step-2); }
.rail__list { margin-top: 1.4rem; display: flex; flex-direction: column; }
.rail__item { display: grid; grid-template-columns: auto 1fr; gap: 1rem 1.2rem; align-items: baseline; padding: 1rem 0; border-top: 1px solid var(--hair); }
.rail__metric { font-family: var(--font-display); font-weight: 600; font-size: var(--step-1); color: var(--text-000); white-space: nowrap; }
.rail--money .rail__metric { color: var(--resonance); }
.rail--machine .rail__metric { color: var(--signal); }
.rail__name { color: var(--text-000); font-weight: 500; }
.rail__desc { grid-column: 2; color: var(--text-200); font-size: var(--step--1); margin-top: 0.2rem; }
@media (max-width: 820px) { .rails { grid-template-columns: 1fr; gap: 3rem; } }

/* ── selected work ─────────────────────────────────────────────────── */
.work__head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 2.5rem; flex-wrap: wrap; gap: 1rem; }
.link { color: var(--signal); font-size: var(--step-0); display: inline-flex; gap: 0.4rem; align-items: center; }
.case { display: grid; grid-template-columns: minmax(0,3fr) minmax(0,5fr) auto; gap: clamp(1.5rem,4vw,4rem); align-items: center; padding: 2.4rem 0; border-top: 1px solid var(--hair); }
.case:last-child { border-bottom: 1px solid var(--hair); }
.case__id h3 { margin-bottom: 0.4rem; }
.case__id .sector { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-300); }
.case__desc { color: var(--text-200); font-size: var(--step-0); }
.case__desc strong { color: var(--text-000); font-weight: 500; }
.case__metric { text-align: right; font-family: var(--font-display); font-weight: 600; font-size: var(--step-2); color: var(--signal); white-space: nowrap; }
.case__metric .u { display: block; font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-300); margin-top: 0.3rem; font-weight: 400; }
@media (max-width: 820px) { .case { grid-template-columns: 1fr; gap: 1rem; } .case__metric { text-align: left; } }

/* ── career stat strip ─────────────────────────────────────────────── */
.stats { display: flex; flex-wrap: wrap; gap: clamp(1.5rem,5vw,4.5rem); }
.stat .n { font-family: var(--font-display); font-weight: 600; font-size: var(--step-4); line-height: 1; color: var(--text-000); }
.stat .n i { font-style: normal; color: var(--signal); }
.stat .l { color: var(--text-200); font-size: var(--step--1); margin-top: 0.5rem; max-width: 16ch; }

/* ── contact CTA band ──────────────────────────────────────────────── */
.cta-band h2 { font-size: var(--step-4); max-width: 16ch; }
.cta-band .mail { display: inline-block; margin-top: 1.8rem; font-size: var(--step-1); color: var(--text-000); border-bottom: 1px solid var(--signal); padding-bottom: 0.3rem; }
.cta-band .mail:hover { color: var(--signal); }

/* ── footer ────────────────────────────────────────────────────────── */
.footer { border-top: 1px solid var(--hair); padding-block: 2.6rem; }
.footer__grid { display: flex; justify-content: space-between; gap: 2rem; flex-wrap: wrap; color: var(--text-300); font-size: var(--step--1); }
.footer a { color: var(--text-200); }
.footer a:hover { color: var(--signal); }
/* build/version stamp — so we always know which version we're looking at */
.footer__build { margin-top: 1.5rem; padding-top: 1.2rem; border-top: 1px solid var(--hair);
  font-family: var(--font-mono); font-size: 0.64rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-300); }
.footer__build b { color: var(--signal); font-weight: 500; }

/* ── forms (contact) ───────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 1.3rem; }
.field label { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-200); }
.field input, .field textarea { background: var(--ink-100); border: 1px solid var(--hair-strong); border-radius: var(--radius); padding: 0.85rem 1rem; color: var(--text-000); transition: border-color .25s var(--ease); }
.field input:focus, .field textarea:focus { outline: none; border-color: var(--signal); }
.field textarea { min-height: 8rem; resize: vertical; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ── finale flight controls hint (shown when body.finale-live at the apotheosis) ── */
#finale-hint { position: fixed; left: 50%; bottom: 48px; transform: translateX(-50%) translateY(12px);
  z-index: 45; display: flex; flex-direction: column; align-items: center; gap: 12px;
  opacity: 0; pointer-events: none; transition: opacity 1s var(--ease), transform 1s var(--ease);
  font: 600 11px/1 var(--font-mono); letter-spacing: 0.28em; color: rgba(200,232,255,0.9); }
/* 2026-07-19 (Tyler: "make W A S D more visible and pulsate glow"): the keys used to fade
   to 28% after 11s, which fought the invitation — they ARE the call to action. They now
   stay lit and BREATHE, so the reader can't miss that the scene is flyable. The breath is
   staggered per key so it reads as a living instrument, not four synchronised blinkers. */
/* v18 reveal REMOVED 2026-07-19: finale-live turns on as the camera enters the apotheosis
   band (around the lab), so this showed the keycaps far too early. The only reveal is the
   .at-footer rule further down — footer 85% in view. */
.fh-keys { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.fh-row { display: flex; gap: 8px; }
.fh-key { display: grid; place-items: center; width: 44px; height: 44px;
  border: 1px solid rgba(140,215,255,0.62); border-radius: 9px; background: rgba(12,32,52,0.62);
  backdrop-filter: blur(8px);
  font: 700 16px/1 var(--font-mono); color: #f2fbff; text-shadow: 0 0 14px rgba(120,215,255,0.75);
  box-shadow: 0 0 26px rgba(70,190,255,0.30), inset 0 0 16px rgba(70,190,255,0.14);
  animation: fhPulse 2.6s var(--ease) infinite; }
.fh-row .fh-key:nth-child(1) { animation-delay: 0.20s; }
.fh-row .fh-key:nth-child(2) { animation-delay: 0.40s; }
.fh-row .fh-key:nth-child(3) { animation-delay: 0.60s; }
@keyframes fhPulse {
  0%, 100% { box-shadow: 0 0 22px rgba(70,190,255,0.24), inset 0 0 14px rgba(70,190,255,0.10);
             border-color: rgba(140,215,255,0.50); transform: translateY(0); }
  50%      { box-shadow: 0 0 46px rgba(110,215,255,0.62), inset 0 0 22px rgba(110,215,255,0.24);
             border-color: rgba(175,235,255,0.92); transform: translateY(-2px); }
}
.fh-label { opacity: 0.92; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.24em;
  text-shadow: 0 0 12px rgba(90,200,255,0.45); }
@media (prefers-reduced-motion: reduce) {
  #finale-hint, body.finale-live #finale-hint { transition: none; animation: none; }
  .fh-key { animation: none; }
}
/* flight.js mounts its own odyssey compass hint; hide it in the intro embed */
body.mode-intro #ody-compass { display: none !important; }

/* ── EXPLORE TAKEOVER (explore.js) ─────────────────────────────────────
   At the apotheosis the first flight input promotes the scene to the whole
   screen. The page doesn't hide — it EXHALES: content releases outward and
   dissolves, so the universe is revealed rather than switched to. ESC inhales
   it back. Somatic easings per the design law; never linear.
   #hero-gl is untouched (it is outside <main>, already fixed at z0) — that is
   what makes this a reveal instead of a re-render.                        */
:root { --exhale: cubic-bezier(0.55, 0.085, 0.68, 0.53);
        --inhale: cubic-bezier(0.25, 0.46, 0.45, 0.94); }
main, .footer, #finale-hint {
  transition: opacity 1.05s var(--exhale), transform 1.05s var(--exhale), filter 1.05s var(--exhale); }
body.exploring main,
body.exploring .footer {
  opacity: 0; pointer-events: none; transform: translateY(26px) scale(0.985); filter: blur(7px); }
body.exploring #finale-hint { opacity: 0; animation: none; }
/* the scene takes the whole viewport + the pointer while exploring.
   NOTE: #hero-gl's z-index is deliberately NOT raised here. It was, and that was the bug
   Tyler hit — "the text and page elements do not fade out, but on esc they fade back in."
   The z-index jump is INSTANT while the opacity fade is 1.05s, so the scene slammed in
   front of <main> and hid it before a single frame of the fade was visible. On ESC the
   z-index dropped instantly and the fade-in played in full view — hence the asymmetry.
   #hero-gl is already fixed at z0 with <main> scrolling over it, so fading <main> out
   reveals the scene on its own. Nothing needs to be raised. */
body.exploring { cursor: crosshair; }

/* ESC affordance — the ONLY chrome in explore mode. Inhales in late (2.4s) so it
   never competes with the reveal, then rests at low opacity. */
#explore-esc { position: fixed; top: 28px; right: 32px; z-index: 46;
  opacity: 0; pointer-events: none; transform: translateY(-8px);
  transition: opacity 0.9s var(--inhale), transform 0.9s var(--inhale);
  font: 600 10px/1 var(--font-mono); letter-spacing: 0.3em; text-transform: uppercase;
  color: rgba(200,232,255,0.82); display: flex; align-items: center; gap: 10px; }
#explore-esc .ee-key { display: grid; place-items: center; height: 26px; padding: 0 10px;
  border: 1px solid rgba(120,200,255,0.38); border-radius: 7px; background: rgba(10,26,42,0.5);
  backdrop-filter: blur(6px); box-shadow: 0 0 16px rgba(60,180,255,0.16);
  font: 700 11px/1 var(--font-mono); color: #dff2ff; letter-spacing: 0.12em; }
body.exploring #explore-esc { opacity: 0.72; transform: translateY(0); transition-delay: 2.4s; }

@media (prefers-reduced-motion: reduce) {
  main, .footer, #finale-hint, #explore-esc { transition: none; }
  body.exploring main, body.exploring .footer { transform: none; filter: none; }
  body.exploring #explore-esc { transition-delay: 0s; }
}

/* ── ABOUT (Tyler) — statement + bio glass + career stats ──────────── */
.about__grid { display: grid; grid-template-columns: minmax(0,5fr) minmax(0,7fr); gap: clamp(2rem,5vw,5rem); align-items: start; }
.about__statement { font-size: var(--step-2); color: var(--text-000); font-family: var(--font-display); font-weight: 500; line-height: 1.14; letter-spacing: -0.01em; max-width: 15ch; }
.about__statement em { font-style: normal; color: var(--signal); }
.about__bio p + p { margin-top: 1.05rem; }
.about__bio p { color: var(--text-100); }
.about__bio strong { color: var(--text-000); font-weight: 500; }
.about__stats { margin-top: clamp(2rem,5vw,3.2rem); }
@media (max-width: 820px) { .about__grid { grid-template-columns: 1fr; gap: 1.6rem; } }

/* ── LAB (live software) — grid of shipped apps ────────────────────── */
.lab__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(238px,1fr)); gap: clamp(1rem,2vw,1.4rem); margin-top: 2.6rem; }
.lab__app { position: relative; display: flex; flex-direction: column; gap: 0.55rem; z-index: 0;
  background: linear-gradient(158deg, rgba(22,30,48,0.34), rgba(9,12,20,0.26));
  backdrop-filter: blur(20px) saturate(1.25); -webkit-backdrop-filter: blur(20px) saturate(1.25);
  border: 1px solid rgba(180,210,255,0.13); border-radius: 16px;
  box-shadow: 0 28px 70px -24px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.09);
  padding: clamp(1.3rem,2.4vw,1.7rem); transition: border-color .3s var(--ease), transform .3s var(--ease); }
.lab__app::before { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: -1;
  background: linear-gradient(180deg, rgba(255,255,255,0.06), transparent 42%), radial-gradient(120% 60% at 15% -10%, rgba(0,204,51,0.09), transparent 60%); }
.lab__app:hover { border-color: rgba(180,210,255,0.28); transform: translateY(-3px); }
.lab__tag { font-family: var(--font-mono); font-size: 0.64rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--signal); }
.lab__app h3 { font-size: 1.1rem; }
.lab__app p { color: var(--text-100); font-size: var(--step--1); }

/* ── FAQ — native <details> glass accordion (zero JS, crawlable) ───── */
.faq__list { margin-top: 2.4rem; display: flex; flex-direction: column; gap: 0.8rem; max-width: 66rem; }
.faq__item { border-radius: 14px; overflow: hidden;
  background: linear-gradient(158deg, rgba(22,30,48,0.30), rgba(9,12,20,0.22));
  backdrop-filter: blur(16px) saturate(1.2); -webkit-backdrop-filter: blur(16px) saturate(1.2);
  border: 1px solid rgba(180,210,255,0.12); transition: border-color .3s var(--ease); }
.faq__item[open] { border-color: rgba(180,210,255,0.22); }
.faq__item summary { cursor: pointer; list-style: none; padding: 1.1rem 1.4rem;
  font-family: var(--font-display); font-weight: 500; font-size: var(--step-0); color: var(--text-000);
  display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after { content: "+"; font-family: var(--font-mono); color: var(--signal); font-size: 1.25rem; line-height: 1; transition: transform .3s var(--ease); }
.faq__item[open] summary::after { transform: rotate(45deg); }
.faq__item summary:hover { color: var(--signal); }
.faq__answer { padding: 0 1.4rem 1.25rem; color: var(--text-100); font-size: var(--step--1); max-width: 70ch; }

/* ── WebGPU engine embed: mount + suppress the engine's own injected chrome ── */
#hero-gl #gl-host { position: absolute; inset: 0; z-index: 1; }
#hero-gl #gl-host canvas { width: 100% !important; height: 100% !important; display: block; }
#hero-gl[data-hero="live"] { background: var(--ink-000); }
/* the living-background embed shows ONLY particles — hide every HUD/loader/gate the engine injects into <body> */
#hud, #bliss-loader, #start-gate, #intro-hero, #drop-veil, #fx-panel,
body.mode-intro #hud, body.mode-intro .controls, body.mode-intro .telemetry,
body.mode-intro .brand, body.mode-intro .act-block, body.mode-intro .hud-progress { display: none !important; }

/* ══════════════════════════════════════════════════════════════════════
   LIQUID-GLASS SYSTEM — ultra-realism refractive bento (Chrome-first).
   Supersedes the flat-frost declarations above via source order (additive).
   [0] safe frost floor · [1] rim/bevel + chromatic dispersion (box-shadow) ·
   [2] ::before specular sheen + caustic · [3] ::after live refraction (Chrome).
   ══════════════════════════════════════════════════════════════════════ */
.veil-card, .offer, .lab__app, .faq__item {
  /* v70 — more opaque base so the card reads as polished glass from frame 1, instead of a flat
     translucent rectangle until the WebGPU canvas renders behind it and backdrop-filter frosts
     (that ~1s delay was the "bg loads a second later" glitch). god-light still shines through. */
  --g-tint-1:    rgba(20,27,46,0.44);
  --g-tint-2:    rgba(9,13,24,0.64);
  --g-aura:      rgba(96,160,255,0.15);
  --g-inhale:    cubic-bezier(0.25,0.46,0.45,0.94);
  --g-exhale:    cubic-bezier(0.55,0.085,0.68,0.53);
  position: relative;
  isolation: isolate;
  background: linear-gradient(155deg, var(--g-tint-1), var(--g-tint-2));
  /* brightness UP → the cosmic particle light SHINES THROUGH the glass as god-light
     (Novu / GlassFlow register) instead of reading as a flat dark rectangle. */
  -webkit-backdrop-filter: blur(20px) saturate(1.3) brightness(1.14) contrast(1.02);
          backdrop-filter: blur(20px) saturate(1.3) brightness(1.14) contrast(1.02);
  border: 1px solid rgba(200,222,255,0.09);
  border-radius: 24px;
  box-shadow:
    0 0 64px -14px var(--g-aura),
    0 40px 90px -36px rgba(0,0,0,0.55),
    inset 0 1px 0 rgba(235,244,255,0.22);
  transition: transform .55s var(--g-exhale), box-shadow .55s var(--g-exhale), border-color .55s var(--g-exhale);
}
.veil-card { border-radius: 26px; }
.offer     { border-radius: 26px; }
.lab__app  { border-radius: 22px; }
.faq__item { border-radius: 16px; }
.veil-card::before, .offer::before, .lab__app::before, .faq__item::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  border-radius: inherit; mix-blend-mode: screen;
  /* GOD LIGHT — soft radial light sources bloom from the corners (like Novu), reading as
     cosmic light pooling through the glass; a whisper of top-edge sheen. */
  background:
    radial-gradient(130% 90% at 12% -12%, rgba(120,170,255,0.22), transparent 52%),
    radial-gradient(90% 70% at 100% 0%, rgba(170,140,255,0.12), transparent 55%),
    linear-gradient(158deg, rgba(255,255,255,0.10) 0%, rgba(255,255,255,0.02) 14%, transparent 32%);
}
/* refraction ::after REMOVED — the "god light" is the bg blooming THROUGH the translucent
   glass (brightness backdrop + the ::before radials), not a displacement warp (that read weird). */
.veil-card::after, .offer::after, .lab__app::after { display: none; }
.veil-card:hover, .offer:hover, .lab__app:hover {
  transform: translateY(-4px);
  border-color: rgba(200,222,255,0.18);
  transition-timing-function: var(--g-inhale);
  box-shadow:
    0 0 104px -6px rgba(120,180,255,0.30),
    0 48px 100px -32px rgba(0,0,0,0.6),
    inset 0 1px 0 rgba(235,244,255,0.34);
}
.faq__item:hover { border-color: rgba(200,224,255,0.26); transition-timing-function: var(--g-inhale); }
@media (prefers-reduced-motion: reduce) {
  .veil-card, .offer, .lab__app, .faq__item { transition: none; }
  .veil-card:hover, .offer:hover, .lab__app:hover { transform: none; }
}
@supports not ((backdrop-filter: blur(4px)) or (-webkit-backdrop-filter: blur(4px))) {
  .veil-card, .offer, .lab__app, .faq__item { background: linear-gradient(158deg, rgba(14,19,31,0.93), rgba(8,11,19,0.96)); }
  .veil-card::after, .offer::after, .lab__app::after { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════
   SELECTED WORK — hover-play reel grid (Method A). Static <article> cards
   (crawlable JS-off: poster + caption in the HTML); reels.js only DRIVES the
   <video> on hover / in-view. Glass rim over the live scene, somatic easing.
   ══════════════════════════════════════════════════════════════════════ */
.work-grid {
  --g-inhale: cubic-bezier(0.25,0.46,0.45,0.94);
  --g-exhale: cubic-bezier(0.55,0.085,0.68,0.53);
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem); margin-top: 2.6rem;
}
.reel {
  position: relative; aspect-ratio: 16 / 10; overflow: hidden; border-radius: 20px;
  pointer-events: auto; cursor: pointer; isolation: isolate;
  border: 1px solid rgba(200,222,255,0.10);
  box-shadow: 0 0 60px -16px rgba(96,160,255,0.16), 0 34px 80px -32px rgba(0,0,0,0.6),
              inset 0 1px 0 rgba(235,244,255,0.16);
  transition: transform .55s var(--g-exhale), box-shadow .55s var(--g-exhale);
}
.reel__vid { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  display: block; background: #0a1120; border-radius: inherit; }
.reel__tag { position: absolute; top: 12px; left: 12px; z-index: 3;
  font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.02em; color: #cfe0ff;
  padding: 5px 10px; border-radius: 8px; background: rgba(8,12,22,0.5);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid rgba(200,222,255,0.12); }
.reel__cap { position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  display: flex; justify-content: space-between; align-items: flex-end; gap: 0.7rem;
  padding: 1.1rem 1.15rem 1rem;
  background: linear-gradient(0deg, rgba(4,7,14,0.88), rgba(4,7,14,0.26) 62%, transparent); }
.reel__cap b { display: block; font-family: var(--font-display); font-weight: 600; font-size: 1.02rem; color: var(--text-000); }
.reel__cap .line { display: block; font-size: 0.72rem; color: var(--text-200); margin-top: 0.18rem; }
.reel__metric { font-family: var(--font-mono); font-size: 0.74rem; color: var(--signal); white-space: nowrap; }
.reel:hover { transform: translateY(-6px); transition-timing-function: var(--g-inhale);
  box-shadow: 0 0 100px -8px rgba(120,180,255,0.34), 0 46px 96px -30px rgba(0,0,0,0.66),
              inset 0 1px 0 rgba(235,244,255,0.30); }
@media (prefers-reduced-motion: reduce) { .reel { transition: none; } .reel:hover { transform: none; } }
@media (max-width: 480px) { .work-grid { grid-template-columns: 1fr; } }


/* ── v26 pass (2026-07-19 owner feedback) ───────────────────────────────── */

/* section labels: brand blue, no numbers. The grey was unreadable on the scene. */
main .section:not(.hero) .eyebrow { color: var(--signal); opacity: 1; }

/* offer icons: real SVG, not glyph characters */
.offer__glyph { width: 30px; height: 30px; color: var(--signal); }
.offer__glyph svg { width: 100%; height: 100%; display: block; }

/* FAQ: two per row + an EASED expansion instead of the native snap.
   <details> can't transition auto-height, so the answer animates on max-height —
   the pragmatic path that keeps the element semantic (and crawlable) rather than
   rebuilding it as JS-driven divs, which would cost the AEO win. */
.faq__list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.7rem, 1.6vw, 1.15rem); align-items: start; }
.faq__answer { overflow: hidden; max-height: 0; opacity: 0;
  transition: max-height 0.5s cubic-bezier(0.25,0.46,0.45,0.94), opacity 0.38s ease, margin 0.4s ease; }
.faq__item[open] .faq__answer { max-height: 70svh; opacity: 1; }
.faq__item summary { cursor: pointer; }
.faq__item summary::marker, .faq__item summary::-webkit-details-marker { color: var(--signal); }
@media (max-width: 780px) { .faq__list { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .faq__answer { transition: none; } }

/* work cards are now real <a> links (new tab) — keep the card look, kill link chrome */
a.reel { display: block; text-decoration: none; color: inherit; }
a.reel:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }

/* contact: email and phone stack on their own lines */
.cta-band .mail { display: inline-block; }

/* ── v33: scroll cue · lab 3-up with per-app aura ───────────────────────── */

/* animated scroll affordance — replaces the "See the work" button */
.scroll-cue { display: inline-flex; align-items: center; gap: 0.7rem; pointer-events: auto;
  font: 600 10px/1 var(--font-mono); letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--text-200); text-decoration: none; transition: color .4s var(--ease); }
.scroll-cue:hover { color: var(--signal); }
.scroll-cue__mouse { position: relative; width: 22px; height: 34px; border-radius: 11px;
  border: 1px solid rgba(150,205,255,0.5); display: block; }
.scroll-cue__mouse i { position: absolute; left: 50%; top: 7px; width: 3px; height: 7px;
  margin-left: -1.5px; border-radius: 2px; background: var(--signal);
  animation: scrollDot 1.9s cubic-bezier(0.25,0.46,0.45,0.94) infinite; }
@keyframes scrollDot {
  0%   { opacity: 0; transform: translateY(0); }
  30%  { opacity: 1; }
  70%  { opacity: 1; transform: translateY(11px); }
  100% { opacity: 0; transform: translateY(13px); }
}
@media (prefers-reduced-motion: reduce) { .scroll-cue__mouse i { animation: none; } }

/* THE LAB — three per row, each app carrying its own aura colour */
.lab__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.9rem, 1.8vw, 1.4rem); }
@media (max-width: 980px) { .lab__grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 640px) { .lab__grid { grid-template-columns: 1fr; } }
.lab__app { position: relative; display: flex; flex-direction: column; isolation: isolate;
  transition: transform .5s cubic-bezier(0.55,0.085,0.68,0.53), box-shadow .5s ease; }
.lab__app::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  opacity: 0.5; transition: opacity .5s ease;
  background: radial-gradient(120% 80% at 20% -10%, var(--aura), transparent 62%); }
.lab__app:hover { transform: translateY(-5px); transition-timing-function: cubic-bezier(0.25,0.46,0.45,0.94); }
.lab__app:hover::before { opacity: 1; }
.lab__app:hover { box-shadow: 0 0 60px -14px var(--aura); }
/* one hue per app — the same chakra spread the finale uses, applied to the lab */
.lab__app[data-aura="0"] { --aura: rgba(255,86,86,0.30); }
.lab__app[data-aura="1"] { --aura: rgba(255,158,64,0.30); }
.lab__app[data-aura="2"] { --aura: rgba(255,214,92,0.30); }
.lab__app[data-aura="3"] { --aura: rgba(86,226,150,0.30); }
.lab__app[data-aura="4"] { --aura: rgba(92,178,255,0.30); }
.lab__app[data-aura="5"] { --aura: rgba(178,124,255,0.32); }
/* per-app hue (Tyler 2026-07-26): optimizer green · data-viz purple · chakra yellow · webgpu blue */
#lab .lab__grid .lab__app:nth-of-type(1) { --auraS: #00CC33; --aura: rgba(0,204,51,0.30); }
#lab .lab__grid .lab__app:nth-of-type(2) { --auraS: #b27cff; --aura: rgba(178,124,255,0.32); }
#lab .lab__grid .lab__app:nth-of-type(3) { --auraS: #ffd65c; --aura: rgba(255,214,92,0.30); }
#lab .lab__grid .lab__app:nth-of-type(4) { --auraS: #5cb2ff; --aura: rgba(92,178,255,0.30); }
.lab__btn { margin-top: auto; align-self: flex-start; pointer-events: auto;
  display: inline-block; padding: 0.5rem 0.95rem; border-radius: var(--radius);
  border: 1px solid rgba(170,240,200,0.28); background: rgba(10,20,34,0.4);
  font: 600 0.72rem/1 var(--font-mono); letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-100); text-decoration: none; transition: all .35s var(--ease); }
.lab__btn:hover { color: #fff; border-color: var(--aura); background: var(--aura); }

/* ── v34: nav mark + full keycap control set ────────────────────────────── */
/* logo: 25% larger, lighter weight, wider tracking — modern luxury, not bold */
.nav__mark svg, .nav__mark img { width: 33px; height: 33px; }
.nav__word { font-size: 1.28rem; font-weight: 300; letter-spacing: 0.035em; }
.nav__cta--report { color: var(--ink-000) !important; background: var(--signal);
  border-color: var(--signal); font-weight: 600; }
.nav__cta--report:hover { background: #4de066; border-color: #4de066; }
.nav__links { gap: clamp(0.6rem, 1.4vw, 1rem); }

/* labelled keycaps (F / Shift / Space / Click / Esc) sit under W A S D */
.fh-row--wide { gap: 8px; margin-top: 2px; }
.fh-key--lbl { width: auto; min-width: 44px; height: auto; padding: 7px 11px 6px;
  flex-direction: column; gap: 3px; line-height: 1; }
.fh-key--wide { min-width: 62px; }
.fh-key--lbl em { font-style: normal; font-size: 7.5px; letter-spacing: 0.16em;
  text-transform: uppercase; opacity: 0.62; font-weight: 500; }
/* only W A S D breathe — labelled keys stay calm so the panel doesn't strobe */
.fh-key--lbl { animation: none; }

/* ── v37 final: lighter mark, centred scroll cue ────────────────────────── */
/* thinner luxury stroke on the wordmark */
.nav__word { font-weight: 200; letter-spacing: 0.05em; }
/* the scroll cue is now the only thing in the hero CTA row — centre it */
.hero__cta { justify-content: center; }
.scroll-cue { flex-direction: column; gap: 0.55rem; }

/* keycaps appear only at the FOOTER, not on approach. body.finale-live turns on as the
   camera enters the apotheosis band — well before the reader reaches the bottom — so the
   panel was showing early. .at-footer is set by explore.js on true footer contact. */
#finale-hint { visibility: hidden; }
body.finale-live.at-footer #finale-hint { visibility: visible; }

/* ── v39 final: liquid glass + eased keycap entrance ─────────────────────── */
/* Bento glass was tint 0.34/0.26 with blur(20px) saturate(1.25). Pushed toward
   LIQUID: heavier blur and saturation carry the frosted read, so the tint can drop
   and let more of the scene through — that combination is what makes glass look
   expensive rather than grey. Tint alphas are the dial if you want it heavier. */
.veil-card, .faq__item, .lab__app {
  background: linear-gradient(158deg, rgba(24,33,54,0.26), rgba(9,12,20,0.18)) !important;
  backdrop-filter: blur(34px) saturate(1.65) brightness(1.10) !important;
  -webkit-backdrop-filter: blur(34px) saturate(1.65) brightness(1.10) !important;
  border-color: rgba(190,220,255,0.16);
}

/* keycaps EASE in on footer contact — visibility alone was a hard snap */
#finale-hint { visibility: visible; opacity: 0; transform: translateX(-50%) translateY(16px);
  transition: opacity 1.1s cubic-bezier(0.25,0.46,0.45,0.94), transform 1.1s cubic-bezier(0.25,0.46,0.45,0.94);
  pointer-events: none; }
body.finale-live.at-footer #finale-hint { opacity: 0.8; transform: translateX(-50%) translateY(0); }
@media (prefers-reduced-motion: reduce) { #finale-hint { transition: none; } }

/* the "who's behind it" statement was capped at 15ch, forcing a narrow ragged column
   with a large empty gap beside it — let it use the space it has */
.about__statement { max-width: 28ch; }
@media (max-width: 900px) { .about__statement { max-width: 100%; } }

/* ── v42: the intro as animated statement lines ─────────────────────────── */
/* The bento paragraph read as a wall of body copy next to a headline that was doing all
   the work. Same words, promoted to statement scale, revealed with a CLIP-WIPE + lift —
   deliberately unlike the hero's particle-condense so the two reveals don't rhyme. */
.about__lines { display: flex; flex-direction: column; gap: clamp(0.85rem, 1.6vw, 1.3rem); }
.al { font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.15rem, 2.05vw, 1.72rem); line-height: 1.32; letter-spacing: -0.012em;
  color: var(--text-100); max-width: 30ch;
  clip-path: inset(0 0 110% 0); opacity: 0; transform: translateY(14px);
  transition: clip-path 1.05s cubic-bezier(0.25,0.46,0.45,0.94) calc(var(--i) * 130ms),
              opacity .8s ease calc(var(--i) * 130ms),
              transform 1.05s cubic-bezier(0.25,0.46,0.45,0.94) calc(var(--i) * 130ms); }
[data-reveal].in .al, .about__lines.in .al { clip-path: inset(0 0 -12% 0); opacity: 1; transform: none; }
.al b { font-weight: 600; color: var(--text-000); }
.al--turn { font-weight: 600; color: var(--text-000); font-size: clamp(1.35rem, 2.5vw, 2.1rem); }
.al--accent { color: var(--signal); font-weight: 500; }
.al--more { font-size: var(--step--1); font-family: var(--font-sans); margin-top: 0.4rem; }
@media (prefers-reduced-motion: reduce) {
  .al { clip-path: none; opacity: 1; transform: none; transition: none; }
}

/* elite services — larger description type, bigger animated icons */
.offer p { font-size: clamp(0.98rem, 1.25vw, 1.12rem); line-height: 1.5; }
.offer__glyph { width: 46px; height: 46px; }
.offer__glyph svg { transition: transform .6s cubic-bezier(0.25,0.46,0.45,0.94); transform-origin: 50% 50%;
  animation: glyphFloat 6s ease-in-out infinite; }
.offer:nth-child(2) .offer__glyph svg { animation-delay: -1.5s; }
.offer:nth-child(3) .offer__glyph svg { animation-delay: -3s; }
.offer:nth-child(4) .offer__glyph svg { animation-delay: -4.5s; }
@keyframes glyphFloat { 0%,100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-4px) rotate(-1.5deg); } }
.offer:hover .offer__glyph svg { transform: scale(1.12) rotate(2deg); animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .offer__glyph svg { animation: none; } }

/* ── v43: SIGNAL-LOCK reveal — worthy of sitting after a particle simulation ──
   A clip-wipe was too plain next to the hero. This is the site's own thesis as motion:
   each line arrives DE-TUNED — split into red/cyan ghosts, blurred, pushed off-axis —
   then the signal LOCKS: ghosts converge, blur clears, the line settles. Slower and
   further apart (1.5s, 420ms stagger) so every line is actually witnessed. */
.al {
  clip-path: none !important;
  opacity: 0; transform: translateY(18px) scale(0.985); filter: blur(9px);
  text-shadow: -7px 0 0 rgba(255,72,110,0.85), 7px 0 0 rgba(64,224,255,0.85);
  transition:
    opacity        .9s cubic-bezier(0.25,0.46,0.45,0.94) calc(var(--i) * 420ms),
    transform     1.5s cubic-bezier(0.25,0.46,0.45,0.94) calc(var(--i) * 420ms),
    filter        1.2s cubic-bezier(0.25,0.46,0.45,0.94) calc(var(--i) * 420ms),
    text-shadow   1.5s cubic-bezier(0.25,0.46,0.45,0.94) calc(var(--i) * 420ms);
}
[data-reveal].in .al, .about__lines.in .al {
  opacity: 1; transform: none; filter: blur(0);
  text-shadow: 0 0 0 rgba(255,72,110,0), 0 0 0 rgba(64,224,255,0);
}
/* body copy scale — readable at length, not headline-huge */
.al { font-size: clamp(1.02rem, 1.32vw, 1.18rem); line-height: 1.55; max-width: 46ch;
  font-family: var(--font-sans); font-weight: 400; letter-spacing: 0; }
.al--turn { font-family: var(--font-display); font-weight: 600; color: var(--text-000);
  font-size: clamp(1.3rem, 2.2vw, 1.85rem); line-height: 1.28; letter-spacing: -0.012em; }
.al--accent { color: var(--signal); font-weight: 500; }
/* lab copy matches the services scale */
.lab__app p { font-size: clamp(0.98rem, 1.25vw, 1.12rem); line-height: 1.5; }
@media (prefers-reduced-motion: reduce) {
  .al { opacity: 1; transform: none; filter: none; text-shadow: none; transition: none; }
}

/* ── v44: the About lines — statement scale, one-at-a-time signal lock ───── */
.about__lines { gap: clamp(1.15rem, 2.2vw, 1.9rem); }
.al {
  font-family: var(--font-display) !important;
  font-size: clamp(1.32rem, 2.35vw, 2.0rem) !important;
  line-height: 1.28 !important; letter-spacing: -0.014em !important;
  font-weight: 400 !important; max-width: 24ch !important; color: var(--text-100);
  opacity: 0; transform: translateY(20px) scale(0.985); filter: blur(11px);
  text-shadow: -8px 0 0 rgba(255,72,110,0.8), 8px 0 0 rgba(64,224,255,0.8);
  transition: opacity 1s ease, transform 1.6s cubic-bezier(0.25,0.46,0.45,0.94),
              filter 1.35s cubic-bezier(0.25,0.46,0.45,0.94),
              text-shadow 1.6s cubic-bezier(0.25,0.46,0.45,0.94);
}
.al.al-in { opacity: 1; transform: none; filter: blur(0);
  text-shadow: 0 0 0 rgba(255,72,110,0), 0 0 0 rgba(64,224,255,0); }
.al--turn { font-weight: 600 !important; color: var(--text-000);
  font-size: clamp(1.6rem, 3.1vw, 2.65rem) !important; }
.al--dim { color: var(--text-200); font-size: clamp(1.1rem, 1.75vw, 1.45rem) !important;
  max-width: 30ch !important; }
.al--quote { font-style: italic; color: var(--text-200); }
.al--accent { color: var(--signal); font-weight: 500 !important; }
.al--more { font-family: var(--font-sans) !important; font-size: var(--step--1) !important;
  margin-top: 0.6rem; }
@media (prefers-reduced-motion: reduce) {
  .al { opacity: 1; transform: none; filter: none; text-shadow: none; transition: none; }
}

/* ── v45: ONE COLUMN · per-character physics reveal ──────────────────────── */
.about__grid--single { display: block !important; }
.about__statement { max-width: 20ch; margin-bottom: clamp(2.2rem, 5vw, 3.6rem); }
.about__lines { max-width: 100%; }

/* no grey anywhere in this section — every line is full-strength */
.al { color: var(--text-000) !important; max-width: 26ch !important;
  /* the LINE no longer animates — its characters do */
  opacity: 1 !important; filter: none !important; text-shadow: none !important;
  transform: none !important; transition: none !important; }
.al--quote { font-style: italic; }
.al--accent { color: var(--signal) !important; }
.al--turn { font-weight: 600 !important; font-size: clamp(1.7rem, 3.3vw, 2.8rem) !important; }

/* THE PHYSICS: each glyph falls in from below with an X-tumble and blur, on a spring
   curve that overshoots ~8% before settling. 16ms apart, so a line resolves left-to-right
   like it is being struck into existence rather than faded in. */
.ch { display: inline-block;
  opacity: 0; filter: blur(10px);
  transform: translateY(0.62em) translateZ(0) rotateX(-82deg) scale(0.86);
  transform-origin: 50% 100%;
  transition:
    opacity   .46s ease                                calc(var(--c) * 16ms),
    filter    .62s cubic-bezier(0.22, 1, 0.32, 1)      calc(var(--c) * 16ms),
    transform .86s cubic-bezier(0.16, 1.28, 0.28, 1)   calc(var(--c) * 16ms);
}
/* v70 perf — will-change ONLY on glyphs still PENDING reveal, so a page full of split h2s
   doesn't hold hundreds of standing compositor layers after they settle. Invisible; frees VRAM. */
:where(.al, main h2):not(.al-in) .ch { will-change: transform, opacity; }
.al-in .ch { opacity: 1; filter: blur(0); transform: none; }
.al--more .ch { transition-duration: .4s, .5s, .6s; }
@media (prefers-reduced-motion: reduce) {
  .ch { opacity: 1; filter: none; transform: none; transition: none; }
}

/* ── v46 final: centred About · keyword highlights · god-light hover ─────── */
/* the whole section reads as one centred column */
.about__grid--single { text-align: center; }
.about__statement { max-width: 22ch; margin-inline: auto;
  font-size: clamp(2.1rem, 4.6vw, 3.6rem) !important; line-height: 1.1; letter-spacing: -0.02em; }
.about__lines { align-items: center; }
.al { margin-inline: auto; text-align: center; max-width: 30ch !important; }
.al--more { margin-inline: auto; margin-top: 1.4rem; }

/* keyword highlights — signal blue carries the emphasis, so no line is blue wholesale */
.al b { color: var(--signal); font-weight: 600; }
.al--accent { color: var(--text-000) !important; } /* last line back to white; its <b> carries the colour */

/* the link is NOT character-split (it looked mis-kerned) — plain, tight, normal spacing */
.al--more { font-family: var(--font-sans); font-size: var(--step--1); letter-spacing: normal; }
.al--more .ch { display: inline; opacity: 1; filter: none; transform: none; transition: none; }

/* GOD-LIGHT ON HOVER — every bento lifts into its own light source. A corner radial in
   screen blend so it reads as light ARRIVING through the glass, not a flat white overlay. */
.veil-card, .faq__item, .lab__app, .offer, .stats {
  transition: transform .55s cubic-bezier(0.25,0.46,0.45,0.94),
              box-shadow .55s cubic-bezier(0.25,0.46,0.45,0.94),
              border-color .55s ease;
  position: relative; isolation: isolate;
}
.veil-card::after, .faq__item::after, .lab__app::after, .offer::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: -1;
  pointer-events: none; opacity: 0; mix-blend-mode: screen;
  transition: opacity .55s cubic-bezier(0.25,0.46,0.45,0.94);
  background:
    radial-gradient(70% 55% at 12% -8%, rgba(120,200,255,0.30), transparent 68%),
    radial-gradient(60% 50% at 92% 108%, rgba(150,120,255,0.22), transparent 70%);
}
.veil-card:hover, .faq__item:hover, .lab__app:hover, .offer:hover {
  transform: translateY(-4px);
  border-color: rgba(190,225,255,0.32);
  box-shadow: 0 0 70px -18px rgba(110,190,255,0.42), 0 34px 80px -34px rgba(0,0,0,0.72),
              inset 0 1px 0 rgba(235,244,255,0.20);
}
.veil-card:hover::after, .faq__item:hover::after, .lab__app:hover::after, .offer:hover::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .veil-card, .faq__item, .lab__app, .offer { transition: none; }
  .veil-card:hover, .faq__item:hover, .lab__app:hover, .offer:hover { transform: none; }
}

/* ── v47: About = scrolling manifesto | pinned proof ─────────────────────────
   The centred single column read as a wall. This splits it the way the argument
   actually works: the STORY scrolls on the left, one line at a time, while the
   RECEIPTS hold pinned on the right — so the numbers are still in frame no matter
   which line of the manifesto you are reading. The claim and its proof share the
   screen for the entire section instead of taking turns. */
.about__grid--split { display: grid !important; text-align: left !important;
  grid-template-columns: minmax(0, 7fr) minmax(0, 4.4fr);
  gap: clamp(2rem, 5vw, 5.5rem); align-items: start; }
.about__grid--split .about__statement { max-width: 17ch; margin-inline: 0; text-align: left; }
.about__grid--split .about__lines { align-items: flex-start; }
.about__grid--split .al { margin-inline: 0; text-align: left; max-width: 34ch !important; }
.about__grid--split .al--more { margin-inline: 0; }

/* the pinned rail */
.about__rail { position: sticky; top: clamp(5rem, 14vh, 9rem); }
.about__rail .stats { margin-top: 0; }
/* stack the figures vertically in the rail so it reads as a column of proof */
.about__rail .stats { display: flex; flex-direction: column; gap: clamp(1.1rem, 2.4vw, 1.9rem); }
.about__rail .stat { text-align: left; }
.about__rail .stat .n { font-size: clamp(2.1rem, 3.6vw, 3.1rem); line-height: 1; }
.about__rail .stat .l { margin-top: 0.35rem; }

@media (max-width: 900px) {
  .about__grid--split { grid-template-columns: 1fr; }
  .about__rail { position: static; margin-top: 2.4rem; }
  .about__rail .stats { flex-direction: row; flex-wrap: wrap; }
}

/* ── v48: no mid-word breaks · rail spacing ──────────────────────────────── */
/* "Development" was splitting into "Dev / elopment". The character-splitter wraps every
   glyph in an inline-block, and a run of inline-blocks has a legal break point BETWEEN
   EACH ONE — so the browser treats every letter as its own word. Wrapping the whole line
   in normal word-break rules is not enough; the spans themselves must refuse to break. */
.al { overflow-wrap: normal !important; word-break: keep-all !important; hyphens: none !important; }
.al .ch { white-space: pre; }
/* a word = an unbroken run of .ch spans, so mark break opportunities only at real spaces */
.al { word-spacing: normal; }

/* the pinned proof rail — vertical rhythm + its own glass, not a naked stack */
.about__rail .stats { padding: clamp(1.4rem, 2.6vw, 2.1rem); }
.about__rail .stat + .stat { padding-top: clamp(1rem, 2vw, 1.5rem);
  border-top: 1px solid rgba(170,240,200,0.12); }
.about__rail .stat .l { color: var(--text-200); font-size: var(--step--1); line-height: 1.4; }
/* each word is one unbreakable box; lines wrap between words, never inside them */
.al .cw { display: inline-block; white-space: nowrap; }

/* ── v52: kill the headline FLASH on first paint ─────────────────────────────
   BUG (live only): the h1 rendered fully, then vanished, then animated in. The hero text
   is visible by default so it survives with JS off — but `hero-armed` (which hides it) is
   added by DEFERRED scripts, i.e. after first paint. Locally that gap is a frame; on a
   real connection it is a visible flash of the finished headline before its own reveal.

   Fixed at the earliest possible moment: head.partial.html already swaps `no-js` → `js`
   in a BLOCKING inline script, so `html.js` is on the element before the first paint.
   Keying the hidden state to that means the headline is never painted un-revealed, while
   a JS-off reader still gets it immediately (html keeps `no-js`, this rule never applies).
   reveal.js's 6s backstop force-shows it inline if the particlize module never runs, so a
   broken enhancement can't leave the hero blank. */
html.js .hero__title .hl-line,
html.js .hero__sub,
html.js .hero__cta { opacity: 0; }
/* the reveal paths win — particlize sets inline opacity, these cover the CSS routes */
html.js body.hero-revealed .hero__title .hl-line,
html.js body.hero-revealed .hero__sub,
html.js body.hero-revealed .hero__cta { opacity: 1; }

/* ── v53: About body at STATEMENT scale + elevated per-glyph physics (2026-07-24) ──
   Tyler: bigger body copy (same scale as the "One brain, holding the whole signal"
   statement) + fade-ins that read more elite, with real physics. The manifesto lines
   rise to statement scale; each glyph now falls further, tumbles harder, and lands on a
   springier curve — the big letters arrive with weight, struck into existence L→R. */
.about__grid--split .al {
  font-size: clamp(2.0rem, 4.4vw, 3.5rem) !important;   /* == the .about__statement scale */
  line-height: 1.16 !important; letter-spacing: -0.018em !important;
  max-width: 24ch !important;
}
.about__grid--split .al--turn {
  font-size: clamp(2.5rem, 5.2vw, 4.2rem) !important;   /* the emphasis beat, bigger still */
  line-height: 1.08 !important;
}
/* elevated per-glyph physics — heavier fall + springier landing + a longer staggered read */
.al .ch, main h2 .ch {
  transform: translateY(0.95em) translateZ(0) rotateX(-90deg) scale(0.76);
  transform-origin: 50% 118%;
  filter: blur(15px);
  transition:
    opacity   .50s ease                                  calc(var(--c) * 19ms),
    filter    .76s cubic-bezier(0.22, 1, 0.32, 1)        calc(var(--c) * 19ms),
    transform 1.06s cubic-bezier(0.16, 1.48, 0.22, 1)    calc(var(--c) * 19ms);
}
/* the reveal WINS — re-declared after the elevated hidden state so revealed glyphs settle */
.al-in .ch { opacity: 1 !important; filter: blur(0) !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
  .al .ch, main h2 .ch { opacity: 1; filter: none; transform: none; transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   v76 (2026-07-24) — BLISS AI APPS v2.0 + THE ORACLE MERKABA. The Chakra-Resume
   system ported into the cold-frontier tokens: the jerk-free 0fr->1fr fold, phase
   meters, status badges, telemetry pairs, the data-stream hover bar, and the
   counter-rotating floating merkaba as the Oracle's face. Cyan, never violet.
   LAWS: static-first (folds OPEN + meters TRUE by default; only body.labx-live
   collapses them), cheap layer (SVG + compositor only, idle loops pause off-screen),
   reduced-motion (loops stop, state shown via glow, typing takes a JS branch).
   ══════════════════════════════════════════════════════════════════════════ */

#lab, #oracle {
  --ease-inhale: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --ease-exhale: cubic-bezier(0.55, 0.085, 0.68, 0.53);
}

/* ── the node ── */
.labx { gap: 0.62rem; padding-bottom: calc(clamp(1.3rem, 2.4vw, 1.7rem) + 4px);
  transition: transform .55s var(--ease-exhale), box-shadow .55s var(--ease-exhale),
    border-color .55s var(--ease-exhale); }
.labx:hover, .labx:focus-within { transition-timing-function: var(--ease-inhale); }
.labx.is-open { border-color: color-mix(in srgb, var(--auraS, var(--signal)) 34%, transparent); }
.labx h3 { font-size: clamp(1.22rem, 1.6vw, 1.45rem); letter-spacing: -0.012em; line-height: 1.16; }

.labx__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; }
.labx__tele { text-align: right; padding-top: 0.3rem; }
.labx__tele-k { display: block; font-family: var(--font-mono); font-size: 0.6rem;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-300); }
.labx__tele-v { display: block; margin-top: 0.28rem; font-family: var(--font-mono);
  font-size: 0.74rem; color: var(--text-000); letter-spacing: 0.01em; }

.labx__meta { display: flex; align-items: center; justify-content: space-between; gap: 0.7rem; flex-wrap: wrap; }
.labx__badge { font-family: var(--font-mono); font-size: 0.58rem; letter-spacing: 0.17em;
  text-transform: uppercase; padding: 0.32rem 0.6rem; border-radius: 4px; white-space: nowrap;
  border: 1px solid rgba(180, 210, 255, 0.3);
  border-color: color-mix(in srgb, var(--auraS, var(--signal)) 42%, transparent);
  color: var(--auraS, var(--signal));
  background: color-mix(in srgb, var(--auraS, var(--signal)) 8%, transparent); }
.labx__badge[data-st="beta"] { animation: labxBeta 3.4s var(--ease-inhale) infinite; }
@keyframes labxBeta { 0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 14px -2px color-mix(in srgb, var(--auraS, var(--signal)) 55%, transparent); } }

/* ── phase meter ── */
.labx__phase { margin-top: 0.15rem; }
.labx__track { position: relative; height: 3px; border-radius: 2px; overflow: hidden;
  background: rgba(210, 220, 236, 0.11); }
.labx__fill { display: block; height: 100%; width: var(--phase, 0%); border-radius: 2px;
  background: var(--auraS, var(--signal));
  box-shadow: 0 0 10px color-mix(in srgb, var(--auraS, var(--signal)) 70%, transparent);
  transition: width 1.5s var(--ease-inhale); }
body.labx-live .labx:not(.is-lit) .labx__fill { width: 0; }
.labx__stops { display: flex; justify-content: space-between; margin-top: 0.42rem;
  font-family: var(--font-mono); font-size: 0.57rem; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--text-300); }
.labx__stops .is-now { color: var(--auraS, var(--signal));
  text-shadow: 0 0 12px color-mix(in srgb, var(--auraS, var(--signal)) 45%, transparent); }

/* ── the fold: grid 0fr->1fr ── */
.labx__toggle { display: none; align-items: center; gap: 0.45rem; align-self: flex-start;
  margin-top: 0.2rem; padding: 0.4rem 0.72rem 0.4rem 0.6rem; border-radius: 6px; cursor: pointer;
  font-family: var(--font-mono); font-size: 0.58rem; letter-spacing: 0.19em; text-transform: uppercase;
  color: var(--text-200); background: rgba(255, 255, 255, 0.022);
  border: 1px solid rgba(210, 220, 236, 0.13);
  transition: color .4s var(--ease-exhale), border-color .4s var(--ease-exhale), background .4s var(--ease-exhale); }
body.labx-live .labx__toggle { display: inline-flex; }
.labx__toggle:hover, .labx__toggle:focus-visible { color: var(--text-000);
  border-color: color-mix(in srgb, var(--auraS, var(--signal)) 55%, transparent);
  background: color-mix(in srgb, var(--auraS, var(--signal)) 9%, transparent);
  transition-timing-function: var(--ease-inhale); }
.labx__chev { width: 7px; height: 7px; border-right: 1.4px solid currentColor; border-bottom: 1.4px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px); transition: transform .5s var(--ease-inhale); }
.labx__toggle[aria-expanded="true"] .labx__chev { transform: rotate(-135deg) translate(-1px, -1px); }

.labx__fold { display: grid; grid-template-rows: 1fr; min-height: 0;
  transition: grid-template-rows .7s var(--ease-inhale); }
body.labx-live .labx__fold { grid-template-rows: 0fr; }
body.labx-live .labx__fold.is-open { grid-template-rows: 1fr; }
.labx__fold-i { overflow: hidden; min-height: 0; }
.labx__pad { padding-top: 0.55rem; opacity: 1; transform: none;
  transition: opacity .6s var(--ease-inhale) .18s, transform .8s var(--ease-inhale) .1s; }
body.labx-live .labx__fold:not(.is-open) .labx__pad { opacity: 0; transform: translateY(14px);
  transition: opacity .26s ease, transform .4s ease; }

.labx__row + .labx__row { margin-top: 0.95rem; }
.labx__k { font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--text-000); padding-bottom: 0.4rem; margin-bottom: 0.5rem;
  border-bottom: 1px solid rgba(210, 220, 236, 0.1); }
.labx__v { color: var(--text-200); font-size: 0.9rem; line-height: 1.62; }
.labx__tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 1rem; }
.labx__tag { font-family: var(--font-mono); font-size: 0.56rem; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-200); padding: 0.32rem 0.55rem; border-radius: 4px;
  background: rgba(255, 255, 255, 0.02); border: 1px solid rgba(210, 220, 236, 0.09);
  transition: color .45s var(--ease-exhale), border-color .45s var(--ease-exhale); }
.labx:hover .labx__tag { color: var(--text-000);
  border-color: color-mix(in srgb, var(--auraS, var(--signal)) 32%, transparent);
  transition-timing-function: var(--ease-inhale); }

/* ── the data-stream hover bar ── */
.labx__stream { position: absolute; left: 10px; right: 10px; bottom: 3px; height: 2px;
  width: 0; border-radius: 2px; pointer-events: none;
  background: var(--auraS, var(--signal));
  box-shadow: 0 0 11px color-mix(in srgb, var(--auraS, var(--signal)) 75%, transparent);
  transition: width 1s var(--ease-exhale); }
.labx:hover .labx__stream, .labx:focus-within .labx__stream {
  width: calc(100% - 20px); transition: width 1.5s var(--ease-inhale); }

/* ── the animated insignias ── */
.lxi { width: 100%; height: 100%; display: block; }
body.labx-live .labx:not(.is-near) .lx-a { animation-play-state: paused; }

@keyframes lxPing   { 0% { r: 8; opacity: .75; stroke-width: 1.6; } 100% { r: 34; opacity: 0; stroke-width: 0; } }
@keyframes lxSweep  { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes lxEng    { 0%, 72%, 100% { opacity: .35; } 12% { opacity: 1; } }
@keyframes lxScan   { 0%, 100% { transform: translateY(0); opacity: .18; } 50% { transform: translateY(66px); opacity: .72; } }
@keyframes lxCym    { 0% { transform: scale(.42); opacity: .9; } 100% { transform: scale(1.9); opacity: 0; } }
@keyframes lxSharp  { 0% { stroke-dasharray: 1.5 3.5; opacity: .4; } 58%, 100% { stroke-dasharray: 24 0; opacity: 1; } }
@keyframes lxCaret  { 0%, 46% { opacity: 1; } 50%, 96% { opacity: 0; } 100% { opacity: 1; } }
@keyframes lxOrbCw  { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes lxOrbCcw { from { transform: rotate(360deg); } to { transform: rotate(0deg); } }
@keyframes lxLat    { 0%, 100% { opacity: .34; transform: scale(.86); } 45% { opacity: 1; transform: scale(1.1); } }

.lx-sweep, .lx-cym, .lx-orb-cw, .lx-orb-ccw, .lx-lat circle { transform-box: view-box; transform-origin: 50% 50%; }
.lx-ping   { animation: lxPing 3s cubic-bezier(0.215, 0.61, 0.355, 1) infinite; }
.lx-sweep  { animation: lxSweep 5.5s linear infinite; }
.lx-eng circle { animation: lxEng 3.5s ease-in-out infinite; }
.lx-eng circle:nth-child(1) { animation-delay: 0s; }   .lx-eng circle:nth-child(2) { animation-delay: .18s; }
.lx-eng circle:nth-child(3) { animation-delay: .36s; } .lx-eng circle:nth-child(4) { animation-delay: .54s; }
.lx-eng circle:nth-child(5) { animation-delay: .72s; } .lx-eng circle:nth-child(6) { animation-delay: .9s; }
.lx-eng circle:nth-child(7) { animation-delay: 1.08s; }
.lx-scan   { animation: lxScan 3.4s ease-in-out infinite; }
.lx-cym    { animation: lxCym 3.2s var(--ease-exhale) infinite; }
.lx-cym--2 { animation-delay: 1.06s; } .lx-cym--3 { animation-delay: 2.12s; }
.lx-sharp  { animation: lxSharp 3.6s var(--ease-inhale) infinite; }
.lx-caret  { animation: lxCaret 1.35s steps(1) infinite; }
.lx-orb-cw  { animation: lxOrbCw 17s linear infinite; }
.lx-orb-ccw { animation: lxOrbCcw 27s linear infinite; }
.lx-lat circle { animation: lxLat 2.6s ease-in-out infinite; }
.lx-lat circle:nth-child(1) { animation-delay: 0s; }    .lx-lat circle:nth-child(2) { animation-delay: .1s; }
.lx-lat circle:nth-child(3) { animation-delay: .2s; }   .lx-lat circle:nth-child(4) { animation-delay: .1s; }
.lx-lat circle:nth-child(5) { animation-delay: .2s; }   .lx-lat circle:nth-child(6) { animation-delay: .3s; }
.lx-lat circle:nth-child(7) { animation-delay: .2s; }   .lx-lat circle:nth-child(8) { animation-delay: .3s; }
.lx-lat circle:nth-child(9) { animation-delay: .4s; }

@media (prefers-reduced-motion: reduce) {
  .lx-a, .labx__badge[data-st="beta"] { animation: none !important; }
  .labx__fold, .labx__fill, .labx__stream, .labx__pad, .labx__chev { transition: none !important; }
}
@media (max-width: 640px) {
  .labx__tele { text-align: left; }
  .labx__head { align-items: center; }
}

/* ── THE MERKABA — the Oracle's face ── */
.mkb { display: inline-grid; place-items: center; width: 54px; height: 54px; flex-shrink: 0;
  color: var(--signal); animation: mkbFloat 7s ease-in-out infinite;
  filter: drop-shadow(0 0 9px rgba(0, 204, 51, 0.35)); will-change: transform;
  transition: filter .7s var(--ease-inhale); }
.mkb__svg { width: 100%; height: 100%; display: block; overflow: visible; }
.mkb__up, .mkb__dn, .mkb__spin, .mkb__ping, .mkb__core { transform-box: view-box; transform-origin: 50% 50%; }
.mkb__up   { animation: mkbCw 26s linear infinite; }
.mkb__dn   { animation: mkbCcw 34s linear infinite; }
.mkb__spin { animation: none; }
.mkb__halo { opacity: .16; }
.mkb__ping { opacity: 0; }
.mkb__core { animation: mkbCore 4.4s ease-in-out infinite; }
@keyframes mkbFloat { 0%, 100% { transform: translate3d(0, 3px, 0) scale(.985); }
  50% { transform: translate3d(0, -3px, 0) scale(1.015); } }
@keyframes mkbCw   { from { transform: rotate(0deg); }   to { transform: rotate(360deg); } }
@keyframes mkbCcw  { from { transform: rotate(360deg); } to { transform: rotate(0deg); } }
@keyframes mkbCore { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }
@keyframes mkbPrec { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes mkbPing { 0% { r: 16; opacity: .55; stroke-width: 1.2; } 100% { r: 46; opacity: 0; stroke-width: 0; } }

.oracle[data-state="thinking"] .mkb { filter: drop-shadow(0 0 20px rgba(0, 204, 51, 0.85)); }
.oracle[data-state="thinking"] .mkb__spin { animation: mkbPrec 2.6s linear infinite; }
.oracle[data-state="thinking"] .mkb--bar .mkb__ping { opacity: 1; animation: mkbPing 2.1s cubic-bezier(0.215, 0.61, 0.355, 1) infinite; }
.oracle[data-state="speaking"] .mkb { filter: drop-shadow(0 0 15px rgba(0, 204, 51, 0.62)); }
.oracle[data-state="speaking"] .mkb__spin { animation: mkbPrec 9s linear infinite; }

.mkb--bar { width: 40px; height: 40px; margin-right: 0.15rem; }
.ochat__av--mkb { border: 0 !important; background: none !important; box-shadow: none !important;
  width: 54px !important; height: 54px !important; padding: 0; }
@media (max-width: 620px) { .ochat__av--mkb { width: 44px !important; height: 44px !important; } .mkb { width: 100%; height: 100%; } }

/* ── FLUID RESPONSE — per-word rise, rAF-paced by oracle.js ── */
.ow { display: inline-block; animation: owIn .44s var(--ease-inhale) both; will-change: transform, opacity; }
@keyframes owIn { from { opacity: 0; transform: translate3d(0, 0.4em, 0); } to { opacity: 1; transform: none; } }
.ocaret { display: inline-block; width: 2px; height: 1em; margin-left: 2px; vertical-align: -0.14em;
  background: var(--signal); box-shadow: 0 0 8px var(--signal); animation: ocaret 1s steps(1) infinite; }
@keyframes ocaret { 0%, 48% { opacity: 1; } 52%, 96% { opacity: .1; } 100% { opacity: 1; } }
.ochat { animation: ochatIn .55s var(--ease-inhale) both; }
@keyframes ochatIn { from { opacity: 0; transform: translate3d(0, 10px, 0); } to { opacity: 1; transform: none; } }

.ochat--thinking .ochat__msg { position: relative; overflow: hidden; display: inline-flex; gap: 6px;
  align-items: center; padding: 0.95rem 1.15rem; }
.ochat--thinking .ochat__msg::after { content: ""; position: absolute; inset: 0; transform: translateX(-120%);
  background: linear-gradient(105deg, transparent 25%, rgba(120, 220, 245, 0.18) 50%, transparent 75%);
  animation: othSheen 1.7s var(--ease-inhale) infinite; pointer-events: none; }
@keyframes othSheen { to { transform: translateX(120%); } }
.odot { width: 7px; height: 7px; border-radius: 50%; background: var(--signal); flex: none;
  animation: odotWave 1.15s var(--ease-inhale) infinite; }
.odot:nth-child(2) { animation-delay: .13s; }
.odot:nth-child(3) { animation-delay: .26s; }
@keyframes odotWave { 0%, 100% { transform: translateY(0) scale(.78); opacity: .32; }
  40% { transform: translateY(-6px) scale(1.15); opacity: 1; } }
.oracle[data-state="thinking"] .oracle__meta { animation: ometa 1.5s ease-in-out infinite; }
@keyframes ometa { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .mkb, .mkb__up, .mkb__dn, .mkb__spin, .mkb__core, .mkb__ping,
  .ow, .ocaret, .ochat, .odot, .ochat--thinking .ochat__msg::after, .oracle__meta { animation: none !important; }
  .ow { opacity: 1; transform: none; }
  .oracle[data-state="thinking"] .mkb { filter: drop-shadow(0 0 20px rgba(0, 204, 51, 0.9)); }
  .oracle[data-state="thinking"] .oracle__meta { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  html.js .hero__title .hl-line, html.js .hero__sub, html.js .hero__cta { opacity: 1; }
}

/* ── v53: the reveal REVERSES on scroll-up ──────────────────────────────────
   Exit runs faster than entry and staggers from the END of the line, so it reads as the
   words being pulled back out rather than a rewind at the same speed. */
.al .ch { transition-duration: .46s, .62s, .86s; }
.al:not(.al-in) .ch {
  transition-delay: calc((var(--c)) * 7ms);
  transition-duration: .3s, .34s, .44s;
}

/* ══════════════════════════════════════════════════════════════════════════
   v56 (2026-07-21 owner pass) — header fade-from-black · faster descent ·
   Contact breath-hover · animated story arrow. All additive; source-order wins.
   ══════════════════════════════════════════════════════════════════════════ */

/* [1] DESCENT — halve the "long empty scroll" from the header. The hero is a sticky
   descent track; 340svh made the opening acts crawl by with minimal change. Halved so
   the header→content transition reads about twice as fast (Tyler: "half this scroll time"). */
.hero { min-height: 180svh; }

/* [2] HEADER — the mark + both CTAs fade up out of the black on first load, staggered,
   so the top bar arrives as a composed reveal instead of just being there. Keyed to
   html.js (set pre-paint in head.partial) so a JS-off reader still gets it instantly. */
/* MATERIALIZE FROM BLACK — not a quick opacity nudge (too subtle to read): each item rises
   out of a soft blur into focus over ~1.7s, clearly staggered, so the top bar assembles
   itself from the dark on first load. (2026-07-22 — owner re-flagged; make it unmistakable.) */
/* CINEMATIC MATERIALIZE — smooth blur+scale fade only (2026-07-22: the old keyframe animated
   letter-spacing, which reflows every frame = the JERK Tyler saw). These are all compositor
   properties (opacity/transform/filter), so it glides — a soft focus-in out of the black. */
/* v70 fix for the "skip animating in": the old keyframe animated filter: blur(11px)→0, which
   re-rasters every frame and fires in the exact window the WebGPU engine compiles its pipelines
   (hero-boot import + initCompute). That boot spike starved the blur rasters → dropped frames →
   the entrance skipped. opacity + translate3d + scale run on the COMPOSITOR thread, so they keep
   gliding even while the main thread is blocked by boot — they physically cannot skip. scale
   (0.94→1) gives the soft "focus-in out of the black" the blur was for, for free. */
@keyframes navRise {
  0%   { opacity: 0; transform: translate3d(0, -14px, 0) scale(0.94); }
  55%  { opacity: 1; }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }
}
html.js .nav__mark      { animation: navRise 1.6s cubic-bezier(0.22, 0.61, 0.36, 1) 0.3s both; }
html.js .nav__links > a { animation: navRise 1.6s cubic-bezier(0.22, 0.61, 0.36, 1) both; }
html.js .nav__links > a:nth-child(1) { animation-delay: 0.58s; }
html.js .nav__links > a:nth-child(2) { animation-delay: 0.82s; }
html.js .nav__mark, html.js .nav__links > a { will-change: transform, opacity; }
@media (prefers-reduced-motion: reduce) {
  html.js .nav__mark, html.js .nav__links > a { animation: none; }
}

/* [3] CONTACT — a more complex, breathing hover. The button lifts, its border ignites
   to signal, and a soft aura pulses like a slow breath (somatic, never a flat glow). */
.nav__cta { transition: color .3s var(--ease), border-color .35s var(--ease),
  background .35s var(--ease), box-shadow .5s var(--ease), transform .4s var(--ease);
  position: relative; overflow: hidden; }
/* v73 — neat CTA rollover: a cold-light sheen sweeps across on hover (both buttons); the filled
   "report" button also lifts + deepens its glow. Single-pass sheen (not a loop) → premium, never
   busy. Compositor-only (transform/opacity). Pairs with the Contact ctaBreath below. */
.nav__cta::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: -75%; width: 55%;
  background: linear-gradient(100deg, transparent, rgba(180,235,255,0.55), transparent);
  transform: skewX(-18deg); pointer-events: none; opacity: 0;
}
.nav__cta:hover::after { animation: ctaSheen 0.72s var(--ease-out); }
@keyframes ctaSheen { 0% { left: -75%; opacity: 0; } 12% { opacity: 0.9; } 100% { left: 135%; opacity: 0; } }
.nav__cta--report:hover { transform: translateY(-1.5px); box-shadow: 0 8px 26px -6px rgba(0,204,51,0.6); }
@media (prefers-reduced-motion: reduce) { .nav__cta::after { display: none; } }
.nav__cta:not(.nav__cta--report):hover {
  border-color: var(--signal);
  background: rgba(0,204,51,0.12);
  /* an ORGANIC breath curve (sine-like), asymmetric: quick inhale, held peak, slow exhale */
  animation: ctaBreath 3.2s cubic-bezier(0.37, 0, 0.63, 1) infinite;
}
/* more complex than a single pulse: the button swells (scale), a bright ring blooms, and a
   soft outer halo expands — inhale to the held peak at ~55%, then a longer exhale back. */
@keyframes ctaBreath {
  0%   { transform: translateY(-1px) scale(1);
         box-shadow: 0 0 0 0 rgba(0,204,51,0), 0 0 14px -4px rgba(0,204,51,0.35); }
  35%  { transform: translateY(-1.5px) scale(1.015);
         box-shadow: 0 0 0 2px rgba(0,204,51,0.07), 0 0 26px -1px rgba(0,204,51,0.5); }
  55%  { transform: translateY(-2px) scale(1.03);
         box-shadow: 0 0 0 4px rgba(0,204,51,0.10), 0 0 42px 2px rgba(0,204,51,0.64); }
  100% { transform: translateY(-1px) scale(1);
         box-shadow: 0 0 0 0 rgba(0,204,51,0), 0 0 14px -4px rgba(0,204,51,0.35); }
}
@media (prefers-reduced-motion: reduce) {
  .nav__cta:not(.nav__cta--report):hover { animation: none; }
}

/* [4] STORY ARROW — the "Read the full story" arrow is now a drawn icon: on hover the
   shaft grows toward the head and the head advances, instead of a flat glyph nudge. */
.link--story { display: inline-flex; align-items: center; gap: 0.55rem; }
.arrow-i { display: inline-flex; align-items: center; }
.arrow-i svg { width: 32px; height: 11px; overflow: visible; }
.arrow-i__shaft { transform: scaleX(0.62); transform-origin: left center;
  transition: transform .55s var(--ease-out); }
.arrow-i__head { transition: transform .55s var(--ease-out); }
.link--story:hover .arrow-i__shaft { transform: scaleX(1); }
.link--story:hover .arrow-i__head { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) {
  .arrow-i__shaft, .arrow-i__head { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   v56 SERVICES — two pillars + the semantic spectrum (Chakra-resume design
   language ported: animated insignias, status-dot ping, igniting tech-tags,
   per-pillar aura radiance). Two crafts only (vibe-coding + paid retired).
   ══════════════════════════════════════════════════════════════════════════ */
.pillars { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1rem, 2.2vw, 1.7rem); margin-top: 2.6rem; }
@media (max-width: 820px) { .pillars { grid-template-columns: 1fr; } }

.pillar {
  --exh: cubic-bezier(0.55,0.085,0.68,0.53);
  --inh: cubic-bezier(0.25,0.46,0.45,0.94);
  position: relative; display: flex; flex-direction: column; gap: 1.1rem; isolation: isolate;
  padding: clamp(1.6rem, 3vw, 2.4rem); border-radius: 24px;
  background: linear-gradient(158deg, rgba(24,33,54,0.26), rgba(9,12,20,0.18));
  backdrop-filter: blur(34px) saturate(1.65) brightness(1.10);
  -webkit-backdrop-filter: blur(34px) saturate(1.65) brightness(1.10);
  border: 1px solid rgba(190,220,255,0.16);
  box-shadow: 0 0 64px -18px var(--p-aura), 0 40px 90px -36px rgba(0,0,0,0.55), inset 0 1px 0 rgba(235,244,255,0.18);
  transition: transform .55s var(--exh), box-shadow .55s ease, border-color .5s ease;
}
.pillar--web { --p-aura: rgba(124,157,255,0.34); --p-ink: #a9beff; }
.pillar--ai  { --p-aura: rgba(0,204,51,0.34);  --p-ink: #4de066; }
/* AURA RADIANCE — the pillar lifts into its own coloured light source on hover */
.pillar::after { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit;
  pointer-events: none; opacity: 0; mix-blend-mode: screen; transition: opacity .6s cubic-bezier(0.25,0.46,0.45,0.94);
  background: radial-gradient(80% 60% at 14% -8%, var(--p-aura), transparent 66%),
              radial-gradient(70% 55% at 92% 106%, var(--p-aura), transparent 70%); }
.pillar:hover { transform: translateY(-5px); border-color: rgba(200,224,255,0.32);
  transition-timing-function: var(--inh);
  box-shadow: 0 0 110px -10px var(--p-aura), 0 46px 100px -32px rgba(0,0,0,0.6), inset 0 1px 0 rgba(235,244,255,0.30); }
.pillar:hover::after { opacity: 1; }

.pillar__top { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; }
.insignia { width: 58px; height: 58px; flex-shrink: 0; color: var(--p-ink); }
.insignia__svg { width: 100%; height: 100%;
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--p-ink) 42%, transparent));
  transition: transform .8s var(--exh), filter .8s ease; }
.pillar:hover .insignia__svg { transform: scale(1.1);
  filter: drop-shadow(0 0 20px color-mix(in srgb, var(--p-ink) 72%, transparent)); }
.pillar__status { display: flex; align-items: center; gap: 0.55rem; padding-top: 0.4rem; }
.pillar__label { font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--text-300); white-space: nowrap; }
.sdot { position: relative; display: inline-flex; width: 9px; height: 9px; }
.sdot .ping { position: absolute; inset: 0; border-radius: 50%; background: var(--p-ink);
  opacity: 0.7; animation: sp-ping 2.6s cubic-bezier(0,0,0.2,1) infinite; }
.sdot .core { position: relative; width: 9px; height: 9px; border-radius: 50%;
  background: var(--p-ink); box-shadow: 0 0 10px var(--p-ink); }
@keyframes sp-ping { 75%, 100% { transform: scale(2.4); opacity: 0; } }
.pillar h3 { font-size: clamp(1.3rem, 2vw, 1.62rem); }
.pillar p { color: var(--text-100); font-size: clamp(0.98rem, 1.2vw, 1.1rem); line-height: 1.5; }

.spectrum-tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: auto; padding-top: 0.4rem; }
.stag { font-family: var(--font-mono); font-size: 0.61rem; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--text-200); padding: 0.32rem 0.6rem; border-radius: 6px;
  border: 1px solid rgba(190,220,255,0.10); background: rgba(255,255,255,0.02);
  transition: color .35s var(--ease), border-color .35s var(--ease), background .35s var(--ease),
    box-shadow .35s var(--ease), transform .35s var(--ease); }
.pillar:hover .stag { border-color: color-mix(in srgb, var(--p-ink) 28%, transparent); color: var(--text-100); }
.stag:hover { color: #fff; border-color: var(--p-ink); transform: translateY(-1px);
  background: color-mix(in srgb, var(--p-ink) 14%, transparent);
  box-shadow: 0 0 16px -2px var(--p-aura); }

.pillar__ctas { display: flex; flex-wrap: wrap; gap: 0.5rem; padding-top: 0.4rem; }

/* insignia animation primitives (sp- scoped so they never collide with the finale engine) */
@keyframes sp-scan { 0%, 100% { transform: translateY(0); opacity: 0.25; } 50% { transform: translateY(30px); opacity: 0.9; } }
@keyframes sp-orbit-cw  { from { transform: rotate(0); }      to { transform: rotate(360deg); } }
@keyframes sp-orbit-ccw { from { transform: rotate(360deg); } to { transform: rotate(0); } }
@keyframes sp-radar { 0% { r: 6; opacity: 0.8; } 100% { r: 40; opacity: 0; } }
.sp-scan { animation: sp-scan 3.4s ease-in-out infinite; }
.sp-orbit-cw  { transform-origin: 50px 50px; animation: sp-orbit-cw 22s linear infinite; }
.sp-orbit-ccw { transform-origin: 50px 50px; animation: sp-orbit-ccw 34s linear infinite; }
.sp-radar { animation: sp-radar 3s cubic-bezier(0.215,0.61,0.355,1) infinite; }
@media (prefers-reduced-motion: reduce) {
  .sp-scan, .sp-orbit-cw, .sp-orbit-ccw, .sp-radar, .sdot .ping { animation: none; }
  .pillar:hover { transform: none; }
}

/* THE SEMANTIC SPECTRUM — glass frame + interactive constellation canvas.
   A static dot-field CSS background makes the panel read as a "field" even with JS off. */
.spectrum { position: relative; margin-top: clamp(1.5rem, 3vw, 2.4rem); border-radius: 22px; overflow: hidden;
  border: 1px solid rgba(190,220,255,0.12);
  background:
    radial-gradient(rgba(150,190,255,0.10) 1px, transparent 1.4px) 0 0 / 34px 34px,
    linear-gradient(158deg, rgba(18,26,44,0.32), rgba(8,11,19,0.24));
  backdrop-filter: blur(20px) saturate(1.3); -webkit-backdrop-filter: blur(20px) saturate(1.3);
  box-shadow: 0 40px 90px -40px rgba(0,0,0,0.6), inset 0 1px 0 rgba(235,244,255,0.10); }
.spectrum__head { position: absolute; top: 0; left: 0; right: 0; z-index: 2;
  padding: clamp(1rem, 2vw, 1.5rem) clamp(1.2rem, 2.4vw, 1.9rem);
  display: flex; flex-direction: column; gap: 0.3rem; pointer-events: none;
  background: linear-gradient(180deg, rgba(6,9,16,0.62), transparent); }
.spectrum__eyebrow { font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--signal); }
.spectrum__hint { color: var(--text-200); font-size: var(--step--1); max-width: 46ch; }
.spectrum__hint em { font-style: normal; color: var(--text-100); }
.spectrum__canvas { display: block; width: 100%; height: clamp(340px, 42vw, 470px); }
@media (prefers-reduced-motion: reduce) { .spectrum__canvas { opacity: 0.9; } }

/* Bento + interactive surfaces capture the pointer so their hover/aura states and the
   spectrum constellation actually fire — main is otherwise click-through to the scene, so
   a full-card :hover never fired unless the pointer was over a child link. Generous empty
   space around every card still lets the reader play with the particle field behind. */
.offer, .lab__app, .veil-card, .pillar, .spectrum, .spectrum__canvas, .oracle { pointer-events: auto; }

/* ══════════════════════════════════════════════════════════════════════════
   v56 THE ORACLE — chat front end over the master record (replaces static FAQ).
   ══════════════════════════════════════════════════════════════════════════ */
.oracle { margin-top: 2.4rem; }
.oracle__frame { position: relative; border-radius: 20px; overflow: hidden; isolation: isolate;
  background: linear-gradient(158deg, rgba(20,28,46,0.34), rgba(8,11,19,0.26));
  backdrop-filter: blur(30px) saturate(1.5) brightness(1.08);
  -webkit-backdrop-filter: blur(30px) saturate(1.5) brightness(1.08);
  border: 1px solid rgba(190,220,255,0.16);
  box-shadow: 0 0 80px -26px rgba(0,204,51,0.30), 0 40px 90px -38px rgba(0,0,0,0.6), inset 0 1px 0 rgba(235,244,255,0.16); }

.oracle__bar { display: flex; align-items: center; gap: 0.6rem; padding: 0.85rem 1.2rem;
  border-bottom: 1px solid rgba(190,220,255,0.10);
  background: linear-gradient(180deg, rgba(0,204,51,0.07), transparent); }
.oracle__dot { position: relative; display: inline-flex; width: 9px; height: 9px; }
.oracle__dot .ping { position: absolute; inset: 0; border-radius: 50%; background: var(--signal); opacity: 0.7;
  animation: sp-ping 2.6s cubic-bezier(0,0,0.2,1) infinite; }
.oracle__dot .core { position: relative; width: 9px; height: 9px; border-radius: 50%; background: var(--signal); box-shadow: 0 0 10px var(--signal); }
.oracle__title { font-family: var(--font-display); font-weight: 500; color: var(--text-000); font-size: 0.98rem; letter-spacing: 0.01em; }
.oracle__meta { margin-left: auto; font-family: var(--font-mono); font-size: 0.58rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--text-300); }

.oracle__log { display: flex; flex-direction: column; gap: 0.85rem; padding: 1.3rem 1.2rem; min-height: 172px; max-height: 46svh; overflow-y: auto; }
.ochat { display: flex; gap: 0.7rem; align-items: flex-start; }
.ochat--me { flex-direction: row-reverse; }
.ochat__av { flex-shrink: 0; width: 28px; height: 28px; display: grid; place-items: center; border-radius: 8px;
  font-family: var(--font-mono); font-size: 0.82rem; color: var(--signal);
  border: 1px solid rgba(190,220,255,0.18); background: rgba(12,20,34,0.6); }
.ochat--me .ochat__av { color: var(--text-100); }
.ochat__body { max-width: 80%; }
.ochat--me .ochat__body { display: flex; justify-content: flex-end; }
.ochat__msg { display: inline-block; padding: 0.7rem 0.95rem; border-radius: 13px; font-size: var(--step--1); line-height: 1.5;
  color: var(--text-100); background: rgba(255,255,255,0.03); border: 1px solid rgba(190,220,255,0.10); }
.ochat--bot .ochat__msg { border-color: color-mix(in srgb, var(--signal) 22%, transparent);
  background: rgba(0,204,51,0.05); color: var(--text-000); }
.ochat--me .ochat__msg { background: rgba(150,175,235,0.09); color: var(--text-000); }

.odot { display: inline-block; width: 6px; height: 6px; margin: 0 2px; border-radius: 50%; background: var(--signal);
  opacity: 0.5; animation: oThink 1.1s ease-in-out infinite; }
.odot:nth-child(2) { animation-delay: 0.16s; }
.odot:nth-child(3) { animation-delay: 0.32s; }
@keyframes oThink { 0%, 100% { opacity: 0.3; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-3px); } }

.oracle__chips { display: flex; flex-wrap: wrap; gap: 0.45rem; padding: 0 1.2rem 0.3rem; }
.ochip { font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.02em; color: var(--text-200);
  padding: 0.4rem 0.72rem; border-radius: 999px; cursor: pointer;
  border: 1px solid rgba(190,220,255,0.14); background: rgba(255,255,255,0.02);
  transition: color .3s var(--ease), border-color .3s var(--ease), background .3s var(--ease), box-shadow .3s var(--ease); }
.ochip:hover { color: #fff; border-color: var(--signal); background: rgba(0,204,51,0.10); box-shadow: 0 0 16px -3px rgba(0,204,51,0.42); }

.oracle__ask { display: flex; gap: 0.6rem; padding: 0.9rem 1.2rem 1.2rem; align-items: center; }
.oracle__input { flex: 1; min-width: 0; background: rgba(8,12,22,0.62); border: 1px solid rgba(190,220,255,0.16);
  border-radius: 12px; padding: 0.8rem 1rem; color: var(--text-000); font-size: var(--step--1);
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease); }
.oracle__input::placeholder { color: var(--text-300); }
.oracle__input:focus { outline: none; border-color: var(--signal); box-shadow: 0 0 0 3px rgba(0,204,51,0.10); }
.oracle__send { flex-shrink: 0; width: 44px; height: 44px; display: grid; place-items: center; border-radius: 12px; cursor: pointer;
  background: var(--signal); color: var(--ink-000); border: 1px solid var(--signal);
  transition: background .3s var(--ease), box-shadow .3s var(--ease), transform .3s var(--ease); }
.oracle__send svg { width: 20px; height: 20px; }
.oracle__send:hover { background: #4de066; box-shadow: 0 0 22px -4px rgba(0,204,51,0.6); transform: translateY(-1px); }

.oracle__toggle { display: inline-flex; align-items: center; gap: 0.4rem; margin-top: 1.4rem; cursor: pointer;
  font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-200);
  background: none; border: none; padding: 0; transition: color .3s var(--ease); }
.oracle__toggle:hover { color: var(--signal); }
.oracle__toggle span { transition: transform .3s var(--ease); }
.oracle__toggle[aria-expanded="true"] span { transform: rotate(180deg); }

.oracle__record { margin-top: 1.4rem; display: flex; flex-direction: column; gap: 0.7rem; max-width: 70rem; }
.oracle__record-label { font-family: var(--font-mono); font-size: 0.64rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-300); margin-bottom: 0.3rem; }
.orec { padding: 1rem 1.2rem; border-radius: 12px; border: 1px solid rgba(190,220,255,0.10); background: rgba(255,255,255,0.015); }
.orec__q { font-family: var(--font-display); font-weight: 500; font-size: 1.02rem; color: var(--signal); margin-bottom: 0.4rem; }
.orec__a { color: var(--text-100); font-size: var(--step--1); line-height: 1.5; }
/* JS tucks the record behind the toggle; crawlers + JS-off keep it fully visible */
.oracle__record--tucked { display: none; }
.oracle__record--tucked.is-open { display: flex; }
@media (max-width: 620px) { .ochat__body { max-width: 84%; } }
@media (prefers-reduced-motion: reduce) { .odot, .oracle__dot .ping { animation: none; } }

/* ══════════════════════════════════════════════════════════════════════════
   v56 BLISS AI APPS — resume-language insignias per card, each in its aura hue.
   ══════════════════════════════════════════════════════════════════════════ */
.lab__glyph { width: 40px; height: 40px; margin: 0.1rem 0 0.15rem; color: var(--auraS, var(--signal));
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--auraS, var(--signal)) 40%, transparent));
  transition: transform .6s cubic-bezier(0.25,0.46,0.45,0.94), filter .6s ease; }
.lab__glyph svg { width: 100%; height: 100%; display: block; }
.lab__app:hover .lab__glyph { transform: scale(1.1);
  filter: drop-shadow(0 0 15px color-mix(in srgb, var(--auraS, var(--signal)) 72%, transparent)); }
/* solid companion to each app's --aura (which is rgba) so the glyph can carry the hue */
.lab__app[data-aura="0"] { --auraS: #ff7a7a; }
.lab__app[data-aura="1"] { --auraS: #ffb057; }
.lab__app[data-aura="2"] { --auraS: #ffe07a; }
.lab__app[data-aura="3"] { --auraS: #66e79a; }
.lab__app[data-aura="4"] { --auraS: #7fb6ff; }
.lab__app[data-aura="5"] { --auraS: #c39bff; }

@keyframes lg-radar { 0% { r: 6; opacity: 0.7; } 100% { r: 17; opacity: 0; } }
.lg-radar { animation: lg-radar 3s cubic-bezier(0.215,0.61,0.355,1) infinite; }
@keyframes lg-scan { 0%, 100% { transform: translateY(0); opacity: 0.2; } 50% { transform: translateY(17px); opacity: 0.7; } }
.lg-scan { animation: lg-scan 3.2s ease-in-out infinite; }
@keyframes lg-wave { 0% { transform: scale(0.55); opacity: 0.85; } 100% { transform: scale(1.7); opacity: 0; } }
.lg-wave { transform-origin: 20px 20px; animation: lg-wave 2.8s ease-out infinite; }
.lg-wave--2 { animation-delay: 1.1s; }
@keyframes lg-caret { 0%, 45% { opacity: 1; } 50%, 95% { opacity: 0; } 100% { opacity: 1; } }
.lg-caret { animation: lg-caret 1.4s steps(1) infinite; }
@keyframes lg-orbit { from { transform: rotate(0); } to { transform: rotate(360deg); } }
.lg-orbit { transform-origin: 20px 20px; animation: lg-orbit 15s linear infinite; }
@keyframes lg-grid { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }
.lg-grid circle { animation: lg-grid 3s ease-in-out infinite; }
.lg-grid circle:nth-child(2n) { animation-delay: 0.4s; }
.lg-grid circle:nth-child(3n) { animation-delay: 0.8s; }
@media (prefers-reduced-motion: reduce) {
  .lg-radar, .lg-scan, .lg-wave, .lg-caret, .lg-orbit, .lg-grid circle { animation: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   v56b (2026-07-22 owner pass) — work rest-opacity · nav hide-on-scroll ·
   hidden scrollbar. (Lenis/GSAP smoothing wired separately.)
   ══════════════════════════════════════════════════════════════════════════ */

/* [1] MARKETING WORK — reels rest at 80% and ignite to full on hover/focus (the lift +
   glow already read as the "highlighted" state; opacity now carries the rest→active read). */
.reel { opacity: 0.8; transition: transform .55s var(--g-exhale), box-shadow .55s var(--g-exhale), opacity .45s var(--g-exhale); }
.reel:hover, .reel:focus-visible { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .reel { opacity: 0.9; } }

/* [2] NAV — fades in from black on load (navRise), then fades OUT as the reader descends
   and back in on scroll-up (body.nav-hidden, toggled in reveal.js by scroll direction). */
.nav { transition: transform .55s var(--ease-out), opacity .55s var(--ease-out),
  background .3s var(--ease), backdrop-filter .3s var(--ease); }
/* v71 — nav no longer hides whole; the logo stays, word + CTAs fade, burger appears (see above). */
body.nav-hidden .nav { transform: none; opacity: 1; pointer-events: none;
  background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; } /* v72 — the dark bar dissolves on scroll-down; only the floating B logo + burger remain */
@media (prefers-reduced-motion: reduce) { .nav { transition: opacity .3s linear; }
  body.nav-hidden .nav { transform: none; } }

/* [3] SCROLLBAR — hidden (the descent should feel like one uninterrupted frame). Scroll
   still works via wheel/touch/keys. NOTE: a JS smooth-scroll (Lenis-style lerp) was tried
   and REVERTED 2026-07-22 — it broke the wheel; native scroll + the engine's own eased
   depth feed (main.js rate-4) is the smoothing, and it doesn't fight anything. */
html { scrollbar-width: none; -ms-overflow-style: none; }
html::-webkit-scrollbar, body::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* ══════════════════════════════════════════════════════════════════════════
   v57 (2026-07-22 owner pass) — icons 2× · bigger titles · EVERY h2 gets the
   per-character physics reveal · Oracle readability.
   ══════════════════════════════════════════════════════════════════════════ */

/* [1] ICONS — the resume-language animated icons, doubled (lab glyphs 40→80) and the
   services insignias enlarged to match. */
.lab__glyph { width: 80px; height: 80px; margin: 0.15rem 0 0.35rem; }
.insignia { width: 84px; height: 84px; }

/* [2] BIGGER SECTION TITLES — every headline scales up. */
main .section:not(.hero) h2 {
  font-size: clamp(2.2rem, 4.6vw, 3.5rem);
  line-height: 1.06; letter-spacing: -0.022em;
}

/* [3] EVERY h2 = the per-character physics reveal (reveal.js splits h2s into .ch spans; the
   .ch spring physics is class-based and already defined for the About manifesto). These rules
   just carry the word-grouping no-break to h2s (the "Development" split) and guard reduced-motion.
   No `perspective` on purpose — it matches the About lines' look exactly, as asked. */
.cw { display: inline-block; white-space: nowrap; }
main h2 { overflow-wrap: normal; word-break: keep-all; hyphens: none; }
main h2 .ch { white-space: pre; }
.about__statement em { color: var(--signal); font-style: normal; }
@media (prefers-reduced-motion: reduce) {
  main h2 .ch { opacity: 1 !important; filter: none !important; transform: none !important; }
}

/* [4] ORACLE READABILITY — the chat read too faint + too small. Brighter bubbles, larger
   type, more line-height and contrast so the answers actually read (Tyler: "hard to read"). */
.oracle__log { padding: 1.5rem 1.4rem; gap: 1rem; }
.ochat__msg { font-size: var(--step-0); line-height: 1.62; padding: 0.85rem 1.15rem; }
.ochat--bot .ochat__msg {
  background: rgba(0,204,51,0.11);
  border-color: color-mix(in srgb, var(--signal) 36%, transparent);
  color: var(--text-000);
}
.ochat--me .ochat__msg { background: rgba(150,175,235,0.16); color: var(--text-000); }
.ochat__av { width: 32px; height: 32px; font-size: 0.9rem; }
.oracle__title { font-size: 1.08rem; }
.oracle__meta { color: var(--text-200); }
.ochip { font-size: 0.7rem; padding: 0.48rem 0.9rem; color: var(--text-100); }
.ochip:hover { color: #fff; }
.oracle__input { font-size: var(--step-0); padding: 0.9rem 1.1rem; }
.orec__q { font-size: 1.1rem; }
.orec__a { font-size: var(--step-0); line-height: 1.6; color: var(--text-000); }

/* ══════════════════════════════════════════════════════════════════════════
   v58 (2026-07-22 owner pass) — Oracle chat icon 3× · footer social icons.
   ══════════════════════════════════════════════════════════════════════════ */

/* [1] ORACLE CHAT ICON — the bot/you avatar, tripled in presence: a real emblem, glowing. */
.ochat__av {
  width: 52px; height: 52px; border-radius: 13px;
  font-size: 1.7rem; flex-shrink: 0;
  border: 1px solid color-mix(in srgb, var(--signal) 34%, transparent);
  background: rgba(12,20,34,0.7);
  box-shadow: 0 0 20px -6px rgba(0,204,51,0.5), inset 0 0 12px -6px rgba(0,204,51,0.4);
}
.ochat--me .ochat__av { border-color: rgba(190,220,255,0.18); box-shadow: none; color: var(--text-100); }
@media (max-width: 620px) { .ochat__av { width: 44px; height: 44px; font-size: 1.45rem; } }

/* [2] FOOTER SOCIAL — LinkedIn + Instagram, bottom-right (footer__grid is space-between). */
.footer__social { display: flex; gap: 0.9rem; align-items: center; margin-left: auto; }
.footer__social a { color: var(--text-300); display: inline-flex; pointer-events: auto;
  transition: color .3s var(--ease), transform .3s var(--ease); }
.footer__social a:hover { color: var(--signal); transform: translateY(-2px); }
.footer__social svg { width: 22px; height: 22px; display: block; }

/* ══════════════════════════════════════════════════════════════════════════
   v58 — RAINBOW CHAKRA AURA on the two service pillars (hover). A conic-gradient
   of the 7 chakra hues, masked to a thin rim around the card and spun via an
   @property-animated angle — the flowing gradient-border effect from the ref.
   ══════════════════════════════════════════════════════════════════════════ */
@property --chakra-angle { syntax: "<angle>"; initial-value: 0deg; inherits: false; }
.pillar::before {
  content: ""; position: absolute; inset: -1.5px; z-index: -1; border-radius: inherit;
  padding: 2px; pointer-events: none;
  background: conic-gradient(from var(--chakra-angle),
    #ff3b5c, #ff8a00, #ffd60a, #3ddc84, #00d4c8, #3a86ff, #b15cff, #ff3b5c);
  /* mask to a ring: show only the padding band (the border), punch out the interior */
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  /* v68 — ALWAYS in motion (Tyler): a gentle constant rainbow spin at rest, hover intensifies.
     Cheap enough to run always-on because the per-frame drop-shadow re-rasters are gone (below). */
  opacity: 0.55; transition: opacity .5s var(--ease); animation: chakraSpin 6s linear infinite;
}
.pillar:hover::before, .pillar:focus-within::before {
  opacity: 1;
  animation-duration: 4.5s; /* hover speeds the SAME spin up (base 6s → 4.5s), no restart-jump */
  /* static composited glow (painted ONCE) replaces the two per-frame drop-shadow re-rasters —
     the biggest per-frame cost in the aura; a soft rounded-rect bleed reads near-identically. */
  box-shadow: 0 0 12px rgba(120,150,255,0.34), 0 0 5px rgba(255,90,140,0.22);
}
@keyframes chakraSpin { to { --chakra-angle: 360deg; } }
/* @property-animated angle; body.is-scrolling pauses this spin during a fast fling (see governor CSS). */
@media (prefers-reduced-motion: reduce) {
  .pillar::before, .pillar:hover::before, .pillar:focus-within::before { animation: none; }
}

/* ── v68 · "Who's behind" figures — units read WHITE like the number (not blue),
   labels read BLUE (signal) instead of grey; unit sized as a unit so "25 years"
   reads clean, not "25years" glued. Scoped to the about rail only. ── */
.about__stats .stat .n i {
  color: var(--text-000);
  font-size: 0.46em;
  font-weight: 600;
  margin-left: 0.16em;
  letter-spacing: 0.01em;
  vertical-align: baseline;
}
.about__stats .stat .l { color: var(--signal); }

/* ══════════════════════════════════════════════════════════════════════════
   v68 — FRAME GOVERNOR, CSS SIDE. The engine governor (main.js tune / fx.js)
   sheds GPU cost but is BLIND to main-thread PAINT — backdrop-blur re-blurring
   the always-animating canvas every frame is the real cause of the section /
   fast-scroll dips. These two classes give it eyes on that cost, transiently:
     • body.is-scrolling — set by reveal.js on a FAST fling ONLY (velocity-gated),
       cleared ~160ms after scroll settles; never trips on slow reading-scroll,
       so the render is byte-identical at rest.
     • body.gpu-pressure — toggled by main.js tune() only when smoothed frame time
       is genuinely over budget, lifted the instant it recovers.
   Instant swaps (no transition on backdrop-filter) so the shed itself is free.
   ══════════════════════════════════════════════════════════════════════════ */
body.is-scrolling .veil-card,
body.is-scrolling .offer,
body.is-scrolling .lab__app,
body.is-scrolling .faq__item,
body.is-scrolling .pillar {
  -webkit-backdrop-filter: blur(14px) saturate(1.2) !important;
          backdrop-filter: blur(14px) saturate(1.2) !important;
}
body.is-scrolling .pillar::before { animation-play-state: paused; }
/* v70 perf — close the always-on chakra-rim governor gaps: pause the per-frame conic re-raster
   when a pillar is offscreen (reveal.js toggles .rim-rest) and under sustained GPU pressure.
   Both transient — full-quality spin whenever a pillar is visible and the frame is healthy. */
.pillar.rim-rest::before          { animation-play-state: paused; }
body.gpu-pressure .pillar::before { animation-play-state: paused; }
body.is-scrolling .ch { filter: none !important; }

body.gpu-pressure .veil-card,
body.gpu-pressure .offer,
body.gpu-pressure .lab__app,
body.gpu-pressure .faq__item,
body.gpu-pressure .pillar {
  -webkit-backdrop-filter: blur(16px) saturate(1.3) !important;
          backdrop-filter: blur(16px) saturate(1.3) !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   v69 — Elite-services titles + animated CTA chips + the Bliss Architecture
   chakra spine + the Oracle holographic HUD.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── bigger service titles (both pillars balanced; immersive a touch larger) ── */
.pillar h3 { font-size: clamp(1.5rem, 2.5vw, 1.95rem); letter-spacing: -0.012em; }
.pillar__h3--big { font-size: clamp(1.75rem, 3.1vw, 2.5rem); letter-spacing: -0.018em; }

/* ── animated CTA chips (Contact me · Free report · Deep audit · Monthly) ──
   sheen sweep + lift + glow + arrow slide; the price/label pop on hover. ── */
.cta-chip {
  position: relative; overflow: hidden; isolation: isolate;
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: var(--font-mono); font-size: 0.74rem; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 0.72rem 1.1rem; border-radius: 10px;
  border: 1px solid rgba(190,220,255,0.22); color: var(--text-000); background: rgba(140,175,235,0.05);
  transition: transform .42s var(--ease), border-color .42s var(--ease), background .42s var(--ease), box-shadow .42s var(--ease);
}
.cta-chip::before {
  content: ""; position: absolute; inset: 0; z-index: -1; transform: translateX(-130%);
  background: linear-gradient(105deg, transparent 20%, rgba(195,228,255,0.22) 50%, transparent 80%);
  transition: transform .7s var(--ease); pointer-events: none;
}
.cta-chip:hover, .cta-chip:focus-visible {
  transform: translateY(-3px); border-color: var(--signal); background: rgba(140,175,235,0.1);
  box-shadow: 0 9px 26px rgba(16,34,68,0.42), 0 0 0 1px color-mix(in srgb, var(--signal) 42%, transparent);
}
.cta-chip:hover::before, .cta-chip:focus-visible::before { transform: translateX(130%); }
.cta-chip__price { font-weight: 700; color: var(--signal); letter-spacing: 0.02em; }
.cta-chip__arw { display: inline-block; transition: transform .42s var(--ease); }
.cta-chip:hover .cta-chip__arw, .cta-chip:focus-visible .cta-chip__arw { transform: translateX(5px); }
.cta-chip--primary {
  background: color-mix(in srgb, var(--signal) 15%, transparent);
  border-color: color-mix(in srgb, var(--signal) 52%, transparent);
}
.cta-chip--primary:hover, .cta-chip--primary:focus-visible {
  background: color-mix(in srgb, var(--signal) 25%, transparent);
  box-shadow: 0 10px 30px color-mix(in srgb, var(--signal) 30%, transparent);
}

/* ── THE BLISS ARCHITECTURE — the 7-phase chakra spine ────────────────────── */
.arc-spine { margin-top: clamp(2.4rem, 6vw, 4rem); }
.arc-phase {
  display: grid; grid-template-columns: minmax(140px, 210px) 48px 1fr; gap: 0;
  padding: clamp(1.5rem, 3.2vw, 2.4rem) 0; border-top: 1px solid rgba(200,215,240,0.1);
  align-items: start;
}
.arc-phase:last-child { border-bottom: 1px solid rgba(200,215,240,0.1); }
.arc-id { display: flex; flex-direction: column; gap: 0.5rem; padding-top: 0.15rem; }
.arc-ph { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--node); text-shadow: 0 0 14px color-mix(in srgb, var(--node) 45%, transparent); }
.arc-nm { font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--text-300); }
.arc-rail { position: relative; display: flex; justify-content: center; }
.arc-rail::before { content: ""; position: absolute; top: -2.4rem; bottom: -2.4rem; left: 50%; width: 1px;
  transform: translateX(-0.5px); background: rgba(200,215,240,0.14); }
.arc-phase:first-child .arc-rail::before { top: 0.55rem; }
.arc-phase:last-child .arc-rail::before { bottom: auto; height: 0.55rem; }
.arc-node { position: relative; z-index: 2; width: 12px; height: 12px; border-radius: 50%; margin-top: 0.4rem;
  background: var(--node);
  box-shadow: 0 0 10px color-mix(in srgb, var(--node) 70%, transparent), 0 0 22px color-mix(in srgb, var(--node) 42%, transparent);
  transition: transform .5s var(--ease), box-shadow .5s var(--ease); }
.arc-phase:hover .arc-node {
  transform: scale(1.45);
  box-shadow: 0 0 14px color-mix(in srgb, var(--node) 85%, transparent), 0 0 34px color-mix(in srgb, var(--node) 60%, transparent);
}
.arc-tag { display: inline-block; font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.17em;
  text-transform: uppercase; color: var(--text-300); margin-bottom: 0.7rem; }
.arc-body h3 { font-family: var(--font-display); font-weight: 500; font-size: clamp(1.3rem, 2.6vw, 1.95rem);
  line-height: 1.14; letter-spacing: -0.01em; margin-bottom: 0.6rem; color: var(--text-000); max-width: 24ch; }
.arc-body p { color: var(--text-200); max-width: 52ch; line-height: 1.72; font-size: var(--step--1); }
@media (max-width: 720px) {
  .arc-phase { grid-template-columns: 1fr; gap: 0.85rem; }
  .arc-rail { display: none; }
  .arc-id { flex-direction: row; align-items: center; gap: 0.7rem; }
  .arc-id::before { content: ""; width: 11px; height: 11px; border-radius: 50%; background: var(--node); flex: none;
    box-shadow: 0 0 12px color-mix(in srgb, var(--node) 60%, transparent); }
}

/* ── THE ORACLE — clean glass console (reverted from the v69 "gmunk" HUD per Tyler: the
   corner-brackets / scan-grid / terminal-input styling is removed; the base glass frame
   shows through). The live status readout (active model / "pulling…") sits in the bar. ── */
.oracle__bar { display: flex; align-items: center; gap: 0.65rem; }
.oracle__meta {
  margin-left: auto; font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--signal); white-space: nowrap; opacity: 0.85;
}
/* the Oracle chat must NOT hijack the page scroll — let the wheel scroll the PAGE, never trap
   it in the log. The log grows with content instead of being its own scroll container. */
.oracle__log { max-height: none !important; overflow: visible !important; overscroll-behavior: none; }

/* ── Bliss AI Apps "Explore" CTA — high-tech, not an afterthought. A real resting affordance
   (aura-tinted border + faint fill) + sheen sweep + lift + aura glow + tracking-expand on hover.
   Uses each app's own --aura hue. ── */
.lab__btn {
  position: relative; overflow: hidden; isolation: isolate;
  padding: 0.6rem 1.1rem !important; border-radius: 8px !important;
  border: 1px solid color-mix(in srgb, var(--aura, #7fd4ff) 45%, transparent) !important;
  background: color-mix(in srgb, var(--aura, #7fd4ff) 8%, rgba(10,20,34,0.5)) !important;
  color: var(--text-000) !important; box-shadow: 0 0 0 0 transparent;
  transition: transform .4s var(--ease), border-color .4s var(--ease), background .4s var(--ease),
    box-shadow .4s var(--ease), letter-spacing .4s var(--ease) !important;
}
.lab__btn::before {
  content: ""; position: absolute; inset: 0; z-index: -1; transform: translateX(-130%);
  background: linear-gradient(105deg, transparent 20%, color-mix(in srgb, var(--aura, #7fd4ff) 42%, transparent) 50%, transparent 80%);
  transition: transform .7s var(--ease); pointer-events: none;
}
.lab__btn:hover, .lab__btn:focus-visible {
  transform: translateY(-3px); letter-spacing: 0.17em !important;
  color: #fff !important;
  border-color: color-mix(in srgb, var(--aura, #7fd4ff) 90%, transparent) !important;
  background: color-mix(in srgb, var(--aura, #7fd4ff) 18%, rgba(10,20,34,0.5)) !important;
  box-shadow: 0 8px 24px color-mix(in srgb, var(--aura, #7fd4ff) 28%, transparent),
    0 0 18px color-mix(in srgb, var(--aura, #7fd4ff) 22%, transparent) !important;
}
.lab__btn:hover::before, .lab__btn:focus-visible::before { transform: translateX(130%); }

/* ── v74 THE CHAKRA COSMOS — pinned scroll-scrub · stardust dissolve · in-glyph cymatics ──
   Armed by chakra-cosmos.js (which hides the static spine; crawler HTML unchanged).
   --cosmo carries the active chakra hue. All motion compositor-only; the stage is
   pointer-transparent so the WebGPU scene's pointer play stays alive around the glyph. */
.arc.cosmos-live .arc-spine { display: none; }
.cosmos { position: relative; height: 430vh; margin-top: clamp(1rem, 3vw, 2rem); }
.cosmos__stage { position: sticky; top: 0; height: 100vh; overflow: hidden; pointer-events: none; }
.cosmos__canvas { position: absolute; inset: 0; pointer-events: none; }
.cosmos__sats { position: absolute; inset: 0; }
.cosmos__sat { position: absolute; left: 0; top: 0; width: 28px; height: 28px; padding: 0; border: none;
  background: none; cursor: pointer; pointer-events: auto; will-change: transform; }
.cosmos__sat::before { content: ""; position: absolute; inset: 9px; border-radius: 50%; background: var(--c);
  opacity: .5; box-shadow: 0 0 10px color-mix(in srgb, var(--c) 65%, transparent);
  transition: opacity .4s var(--ease), box-shadow .4s var(--ease); }
.cosmos__sat::after { content: ""; position: absolute; inset: 3px; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--c) 45%, transparent); opacity: .35;
  transition: opacity .4s var(--ease), transform .4s var(--ease); }
.cosmos__sat:hover::before, .cosmos__sat.is-on::before { opacity: 1;
  box-shadow: 0 0 12px var(--c), 0 0 28px color-mix(in srgb, var(--c) 60%, transparent); }
.cosmos__sat.is-on::after { opacity: .9; transform: scale(1.4); }
.cosmos__sat:focus-visible { outline: 1px solid var(--text-000); outline-offset: 3px; border-radius: 50%; }

.cosmos__meta { position: absolute; left: clamp(1.2rem, 4.5vw, 4.5rem); bottom: clamp(1.6rem, 6vh, 4.2rem);
  max-width: 36ch; z-index: 3; }
.cosmos__ph { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--cosmo, var(--signal)); text-shadow: 0 0 16px color-mix(in srgb, var(--cosmo, var(--signal)) 50%, transparent); }
.cosmos__tag { font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.17em; text-transform: uppercase;
  color: var(--text-300); margin-top: 0.55rem; }
.cosmos__title { font-family: var(--font-display); font-weight: 500; font-size: clamp(1.5rem, 3vw, 2.3rem);
  line-height: 1.14; margin-top: 0.7rem; color: var(--text-000); max-width: 22ch; }
.cosmos__body { color: var(--text-200); line-height: 1.65; font-size: var(--step--1); margin-top: 0.75rem; max-width: 44ch; }
.cosmos__meta.swap > * { animation: cosmoIn 0.7s cubic-bezier(0.25, 0.46, 0.45, 0.94) both; }
.cosmos__meta.swap > *:nth-child(2) { animation-delay: 0.05s; }
.cosmos__meta.swap > *:nth-child(3) { animation-delay: 0.1s; }
.cosmos__meta.swap > *:nth-child(4) { animation-delay: 0.16s; }
@keyframes cosmoIn { from { opacity: 0; transform: translate3d(0, 14px, 0); filter: blur(9px); }
  to { opacity: 1; transform: none; filter: blur(0); } } /* v75 — the Floating-Cycle blur-dissolve type swap (brief, text-only) */

.cosmos__count { position: absolute; right: clamp(1.2rem, 4vw, 4rem); bottom: clamp(1.6rem, 6vh, 4.2rem);
  text-align: right; z-index: 3; font-family: var(--font-mono); }
.cosmos__idx { font-size: 1.5rem; color: var(--cosmo, var(--signal));
  text-shadow: 0 0 18px color-mix(in srgb, var(--cosmo, var(--signal)) 45%, transparent); }
.cosmos__of { font-size: 0.8rem; letter-spacing: 0.12em; color: var(--text-300); }
.cosmos__sk { display: block; margin-top: 0.45rem; font-size: 0.62rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--text-300); }

.cosmos__rail { position: absolute; right: clamp(0.9rem, 2.6vw, 2.2rem); top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 0.85rem; z-index: 4; pointer-events: auto; }
.cosmos__dot { width: 10px; height: 10px; padding: 0; border: none; border-radius: 50%; cursor: pointer;
  background: color-mix(in srgb, var(--c) 38%, rgba(200, 215, 240, 0.18)); transition: all 0.35s var(--ease); }
.cosmos__dot:hover { background: var(--c); }
.cosmos__dot.is-on { background: var(--c); transform: scale(1.3);
  box-shadow: 0 0 10px var(--c), 0 0 22px color-mix(in srgb, var(--c) 55%, transparent); }
.cosmos__dot:focus-visible { outline: 1px solid var(--text-000); outline-offset: 3px; }

.cosmos__hint { position: absolute; left: 50%; bottom: 1.1rem; transform: translateX(-50%);
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.26em; text-transform: uppercase;
  color: var(--text-300); opacity: 0.7; transition: opacity 0.8s var(--ease); z-index: 3; white-space: nowrap; }
.cosmos__hint.gone { opacity: 0; }

@media (max-width: 760px) {
  .cosmos { height: 370vh; }
  .cosmos__sats { display: none; }
  .cosmos__meta { max-width: 82vw; bottom: 4.6rem; }
  .cosmos__title { font-size: 1.35rem; }
  .cosmos__body { font-size: 0.85rem; max-width: 40ch; }
  .cosmos__count { bottom: 1.2rem; }
  .cosmos__sk { display: none; }
  .cosmos__rail { right: 0.55rem; gap: 0.7rem; }
  .cosmos__dot { width: 8px; height: 8px; }
}

/* ── v75 cosmos additions — authentic-art preload + prev/next arrows ── */
.cosmos__srcs { position: absolute; width: 0; height: 0; overflow: hidden; visibility: hidden; }
.cosmos__arrow { position: absolute; top: 47%; transform: translateY(-50%); z-index: 5; width: 44px; height: 44px;
  border-radius: 50%; border: 1px solid rgba(200, 215, 240, 0.16); background: rgba(10, 18, 32, 0.35);
  color: var(--text-200); font-size: 1.5rem; line-height: 1; cursor: pointer; pointer-events: auto;
  display: grid; place-items: center; padding-bottom: 3px;
  transition: border-color 0.35s var(--ease), color 0.35s var(--ease), box-shadow 0.35s var(--ease);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.cosmos__prev { left: clamp(0.9rem, 3vw, 2.6rem); }
.cosmos__next { right: calc(clamp(0.9rem, 2.6vw, 2.2rem) + 24px); }
.cosmos__arrow:hover { border-color: var(--cosmo, var(--signal)); color: var(--text-000);
  box-shadow: 0 0 18px -6px var(--cosmo, var(--signal)); }
.cosmos__arrow:focus-visible { outline: 1px solid var(--text-000); outline-offset: 3px; }
@media (max-width: 760px) {
  .cosmos__arrow { width: 37px; height: 37px; font-size: 1.25rem; }
  .cosmos__prev { left: 0.65rem; }
  .cosmos__next { right: calc(0.55rem + 18px); }
}

/* ── THE BLISS ARCHITECTURE — the approved chakra bench (chakraprocess.html) as a SCROLL-DRIVEN act.
   The bench renders VERBATIM in an isolated frame; chakra-embed.js tunes it root→crown from PAGE
   scroll (dispatching the bench's OWN wheel handler — no bench edit, no wheel-trap). The frame is a
   sticky, pointer-events:none backdrop over a tall section, so the page scrolls freely and the hero
   universe (z-index:0) is covered. JS-off / reduced-motion / crawlers keep the static .arc-spine. ── */
#architecture.arc { position: relative; }
.chakra-frame { display: none; border: 0; }
#architecture.chakra-armed { height: 340vh; padding: 0; }   /* scroll-driven: sticky frame holds 100vh; the page scrolls normally like any section, the bench tunes root→crown gently */
#architecture.chakra-armed > .wrap {   /* keep the crawlable seven-phase spine, out of sight */
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); border: 0; white-space: nowrap; }
#architecture.chakra-armed > .chakra-frame {
  display: block; position: sticky; top: 0; height: 100vh; width: 100%;
  z-index: 1;                 /* above the hero universe (#hero-gl, z-index:0), below page content */
  background: transparent;    /* the bench renders transparent when embedded → hero space shows through */
  pointer-events: none;       /* the PAGE owns the wheel — no trap; JS tunes the bench from scroll */ }


/* ══════════════════════════════════════════════════════════════════════════
   v77 (2026-07-24) — BLISS AI APPS · ELITE FUI "OPERATIONS DECK"
   Supersedes the v76 expandable-card bento (append-only; v76 rules for the dropped
   .labx__head/meta/badge/toggle/fold/row classes simply go dead + harmless). FOUR
   self-contained HUD panels in a 2×2. Zero-UI / data-forward — terse mono readouts
   REPLACE the spec-fold prose, so static-first is automatic (every value legible with
   JS off = crawler-complete). Cheap layer only: compositor transform/opacity; idle
   loops run ONLY while a card is on-screen (the WebGPU hero owns the frame budget).
   Cyan --signal system + one warm --resonance outlier (the consciousness instrument).
   No purple, no rainbow, no accordion.

   REVEAL-LAG FIX (root cause): the animated-in state — gauge at scaleX(0), idle loops
   paused — is gated on the PRE-PAINT `html.js` class (head.partial:19), NOT the DEFERRED
   `body.labx-live` v76 used. So the design is correct on the FIRST painted frame; no snap.
   lab-nodes.js only wires interactivity after (fill-on-scroll via .is-lit, off-screen
   pause via .is-near). no-js paints every gauge full.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── grid: two bigger panels per row → one-up on phone ── */
#lab .lab__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(1rem, 2.2vw, 1.7rem); margin-top: 2.6rem; }
@media (max-width: 620px) { #lab .lab__grid { grid-template-columns: 1fr; } }

/* ── the panel: inherits .lab__app glass/aura/hover-lift base; retune to the cyan system ── */
#lab .labx { --aura: rgba(0,204,51,0.28); --auraS: var(--signal);
  gap: 0; padding: clamp(1.15rem, 2.1vw, 1.6rem); border-radius: 16px; }
#lab .labx.labx--warm { --aura: rgba(200,180,135,0.26); --auraS: var(--resonance); }

/* corner brackets (opposite pair, TL+BR) — the FUI frame; expand + ignite on hover */
.labx__frame { position: absolute; inset: 9px; pointer-events: none; z-index: 3; }
.labx__frame::before, .labx__frame::after { content: ""; position: absolute; width: 13px; height: 13px;
  border: 1px solid color-mix(in srgb, var(--auraS) 45%, transparent); opacity: 0.55;
  transition: width .5s var(--ease-out), height .5s var(--ease-out), opacity .5s var(--ease-out), border-color .5s var(--ease-out); }
.labx__frame::before { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.labx__frame::after  { bottom: 0; right: 0; border-left: 0; border-top: 0; }
.labx:hover .labx__frame::before, .labx:focus-within .labx__frame::before,
.labx:hover .labx__frame::after,  .labx:focus-within .labx__frame::after {
  width: 21px; height: 21px; opacity: 1; border-color: var(--auraS); }

/* module bar: index · category · status */
.labx__bar { display: flex; flex-wrap: nowrap; align-items: center; gap: 0.6rem; position: relative; z-index: 2; }
.labx__idx { flex: none; font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.2em; color: var(--text-300);
  padding: 0.18rem 0.42rem; border: 1px solid var(--hair-strong); border-radius: 3px; }
.labx__cat { min-width: 0; font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: color-mix(in srgb, var(--auraS) 75%, var(--text-100)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.labx__status { flex: none; margin-left: auto; display: inline-flex; align-items: center; gap: 0.44rem;
  font-family: var(--font-mono); font-size: 0.57rem; letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--text-200); white-space: nowrap; }
.labx__status[data-st="ship"] { color: var(--text-300); }
.labx__dot { position: relative; flex: none; width: 6px; height: 6px; border-radius: 50%;
  background: var(--auraS); box-shadow: 0 0 8px var(--auraS); }
.labx__dot::after { content: ""; position: absolute; inset: -3px; border-radius: 50%; border: 1px solid var(--auraS); opacity: 0; }
html.js .labx.is-near .labx__dot::after { animation: labxPing 2.8s cubic-bezier(0,0,0.2,1) infinite; }
html.js .labx.is-near .labx__status[data-st="beta"] .labx__dot::after { animation-duration: 1.7s; }
@keyframes labxPing { 0% { transform: scale(0.55); opacity: 0.7; } 80%, 100% { transform: scale(2.3); opacity: 0; } }

/* HUD viewport: the animated glyph + a headline readout, an idle scanline sweeping it */
.labx__view { position: relative; margin-top: 0.95rem; min-height: 84px; padding: 0.7rem 0.9rem; overflow: hidden;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; border-radius: 10px;
  border: 1px solid var(--hair);
  background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.005)),
    radial-gradient(130% 150% at 12% -25%, color-mix(in srgb, var(--auraS) 9%, transparent), transparent 60%); }
#lab .labx__view .lab__glyph { width: 60px; height: 60px; margin: 0; flex: none; }
.labx__vitals { text-align: right; display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.labx__vk { font-family: var(--font-mono); font-size: 0.54rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-300); }
.labx__vv { font-family: var(--font-mono); font-size: clamp(0.82rem, 1.4vw, 1rem); letter-spacing: 0.01em; color: var(--text-000);
  font-variant-numeric: tabular-nums; text-shadow: 0 0 14px color-mix(in srgb, var(--auraS) 32%, transparent); }
.labx__scan { position: absolute; left: 0; right: 0; top: 0; height: 1px; pointer-events: none; opacity: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--auraS) 72%, transparent), transparent); }
html.js .labx.is-near .labx__scan { animation: labxScan 4.4s var(--ease-inhale) infinite; }
.labx:hover .labx__scan { animation-duration: 1.9s; }
/* travel ≈ .labx__view min-height (84px) − 4; keep in step if that min-height changes */
@keyframes labxScan { 0% { transform: translateY(2px); opacity: 0; } 14% { opacity: 0.55; } 86% { opacity: 0.55; } 100% { transform: translateY(80px); opacity: 0; } }

/* name + a single bone-cut line (was four paragraphs) */
#lab .labx h3 { margin: 0.9rem 0 0; font-size: clamp(1.24rem, 1.7vw, 1.5rem); letter-spacing: -0.014em; line-height: 1.13; color: var(--text-000); }
.labx__line { margin: 0.5rem 0 0; color: var(--text-200); font-size: var(--step--1); line-height: 1.5; max-width: 44ch; }

/* the FUI data readouts that REPLACE the spec-fold prose — three mono cells, hairline-split */
.labx__read { margin-top: 1.05rem; display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; overflow: hidden;
  border: 1px solid var(--hair-strong); border-radius: 8px; background: var(--hair-strong); }
.labx__cell { display: flex; flex-direction: column; gap: 0.32rem; padding: 0.6rem 0.68rem; background: rgba(8,11,18,0.72); }
.labx__cell dt { font-family: var(--font-mono); font-size: 0.52rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--text-300); }
.labx__cell dd { margin: 0; font-family: var(--font-mono); font-size: 0.75rem; letter-spacing: 0.01em; color: var(--text-000); font-variant-numeric: tabular-nums; }
.labx:hover .labx__cell dd, .labx:focus-within .labx__cell dd { color: #fff; }
@media (max-width: 400px) { .labx__read { grid-template-columns: 1fr; }
  .labx__cell { flex-direction: row; justify-content: space-between; align-items: baseline; } }

/* telemetry gauge: current operating point. Fills on scroll — gated on html.js (pre-paint), never a deferred class.
   scaleX (compositor) not width/height → zero layout shift. width:100% neutralises the dead v76 width:var(--phase). */
#lab .labx__phase { margin-top: 1.05rem; margin-bottom: 1.15rem; }
#lab .labx__track { position: relative; height: 3px; border-radius: 2px; overflow: hidden; background: rgba(210,220,236,0.1); }
#lab .labx__track::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(90deg, transparent 0 calc(100%/14 - 1px), rgba(5,7,13,0.9) calc(100%/14 - 1px) calc(100%/14)); }
#lab .labx__fill { position: absolute; left: 0; top: 0; width: 100%; height: 100%; border-radius: 2px;
  transform-origin: left center; transform: scaleX(var(--fill, 1)); background: var(--auraS);
  box-shadow: 0 0 10px color-mix(in srgb, var(--auraS) 70%, transparent); }
html.js .labx:not(.is-lit) .labx__fill { transform: scaleX(0); }               /* pre-paint: empty under JS */
html.js .labx__fill { transition: transform 1.3s var(--ease-inhale); }         /* fills when .is-lit lands */
#lab .labx__stops { display: flex; justify-content: space-between; margin-top: 0.46rem;
  font-family: var(--font-mono); font-size: 0.55rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-300); }
#lab .labx__stops .is-now { color: var(--auraS); text-shadow: 0 0 12px color-mix(in srgb, var(--auraS) 45%, transparent); }

/* Explore CTA keeps the rich .lab__btn base (sheen + lift), now cyan-tinted; auto-margin bottom-aligns it across the row */
#lab .labx .lab__btn { margin-top: auto; }

/* perf: idle glyph loops run ONLY while a card is on-screen (re-gated off the deferred class onto html.js) */
html.js #lab .labx:not(.is-near) .lx-a { animation-play-state: paused; }

/* reduced-motion: freeze idle loops; the gauge shows its TRUE value immediately (never strands at 0) */
@media (prefers-reduced-motion: reduce) {
  .labx__scan, .labx__dot::after { animation: none !important; }
  .labx__frame::before, .labx__frame::after { transition: none !important; }
  html.js .labx__fill { transition: none !important; }
  html.js .labx:not(.is-lit) .labx__fill { transform: scaleX(var(--fill, 1)); }
}


/* ══════════════════════════════════════════════════════════════════════════
   v78 (2026-07-24) — BLISS AI APPS · REACTIVE MESH (ported from the physics lab, T2)
   Cursor force-field over the v77 2×2: lab-nodes.js sets a per-card --prox (0-1
   proximity) + an inline transform (3D tilt toward the pointer). Transform is
   excluded from the CSS transition so the rAF lerp owns the tilt (no double-smooth);
   border + corner brackets intensify with --prox so a card lights BEFORE hover.
   Fine-pointer + motion-OK only; degrades to the static v77 deck otherwise.
   ══════════════════════════════════════════════════════════════════════════ */
html.js #lab .lab__grid { perspective: 1200px; }
html.js #lab .labx {
  transform-style: preserve-3d;
  transition: border-color .45s var(--ease-out), box-shadow .45s var(--ease-out);
  border-color: color-mix(in srgb, var(--auraS) calc(16% + var(--prox, 0) * 42%), var(--hair-strong));
}
html.js #lab .labx .labx__frame::before, html.js #lab .labx .labx__frame::after {
  opacity: calc(.5 + var(--prox, 0) * .5);
  border-color: color-mix(in srgb, var(--auraS) calc(42% + var(--prox, 0) * 58%), transparent);
}
@media (prefers-reduced-motion: reduce) { html.js #lab .labx { transform: none !important; } }


/* ══════════════════════════════════════════════════════════════════════════
   v79 (2026-07-24) — ABOUT · PARTICLE MIC-DROP + MATRIX DECODE (ported from the
   about-particle test). Namespaced (pa-*) so nothing collides with the old .al
   reveal stack; reveal.js is filtered to skip #about. The supporting lines matrix-
   decode (green katakana → crisp text) as they scroll in; the mic-drop assembles
   from a WebGL particle field (blue additive glow). JS-off / reduced-motion → plain
   crisp text (crawler-complete). The particle module loads its own WebGL three (CDN,
   like the chakra bench) — the site's bare `three` importmap stays WebGPU.
   ══════════════════════════════════════════════════════════════════════════ */
#about .pa-stmt{font-family:var(--font-display);font-weight:600;font-size:clamp(1.9rem,4.2vw,3rem);line-height:1.12;letter-spacing:-.02em;color:var(--text-000);margin:0 0 1.3rem;max-width:20ch}
#about .pa-stmt .pa-sig{color:var(--signal);font-style:normal;font-weight:600}
#about .pa-stmt b{color:var(--signal);font-weight:600}
#about .pa-line{font-family:var(--font-display);font-weight:400;font-size:clamp(1.1rem,1.9vw,1.42rem);line-height:1.5;color:var(--text-100);margin:0;max-width:34ch}
#about .pa-line--lead,#about .pa-lead{color:var(--text-200)}
#about .pa-line b,#about .pa-line .pa-sig{color:var(--signal);font-weight:600}
#about .pa-line em{font-style:italic}
/* the particle mic-drop */
#about .pa-mic{position:relative;width:100%;height:clamp(150px,20vw,220px);margin:.5rem 0 1.4rem}
#about #pa-canvas{position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none}
#about .pa-mictext{position:absolute;inset:0;display:flex;align-items:center;font-family:var(--font-display);font-weight:600;font-size:clamp(2.2rem,5.6vw,3.8rem);letter-spacing:-.02em;color:var(--text-000);pointer-events:none;margin:0}
#about .pa-mictext b{color:var(--signal)}
html.js #about .pa-mictext{opacity:0}                       /* particles render it; DOM stays for crawl + JS-off */
html.js #about .dec:not(.done):not(.run){opacity:0}
#about .pa-mx{color:#00CC33;text-shadow:0 0 8px rgba(0,204,51,.55)}
#about .pa-mx.edge{color:#eafff4;text-shadow:0 0 12px rgba(0,204,51,.9)}
html.js #about .dec{transition:opacity .5s ease}
@media(prefers-reduced-motion:reduce){html.js #about .dec{opacity:1!important}html.js #about .pa-mictext{opacity:1!important}#about #pa-canvas{display:none}}


/* ══════════════════════════════════════════════════════════════════════════
   v80 (2026-07-24) — ABOUT decode = per-character matrix scramble → BLUR-DISSOLVE
   lock. NO particle box (v79's .pa-mic/.pa-canvas/.pa-mictext/.pa-mx now dead).
   Every .dec line (statement + lines + the mic-drop turn) shatters into stable
   per-char spans; each char cycles green katakana then LOCKS with a blur-dissolve
   (blur+opacity → sharp), sweeping left→right, slower. Pure DOM, crawler-safe.
   ══════════════════════════════════════════════════════════════════════════ */
#about .pa-turn{font-family:var(--font-display);font-weight:600;font-size:clamp(2rem,5vw,3.1rem);line-height:1.1;letter-spacing:-.02em;color:var(--text-000);margin:.4rem 0 1.1rem;max-width:16ch}
#about .pa-turn b{color:var(--signal)}
#about .pa-w{white-space:nowrap}
#about .pa-c{display:inline-block}
#about .pa-c.k{font-weight:600;color:var(--signal)}
#about .pa-c.e{color:var(--signal);font-weight:600;font-style:normal}
#about .pa-c.sc{color:#00CC33;text-shadow:0 0 7px rgba(0,204,51,.5);font-weight:400}   /* scramble overrides final colour */
#about .pa-c.in{animation:paIn .6s var(--ease-out) both}
@keyframes paIn{from{filter:blur(7px);opacity:.1}to{filter:blur(0);opacity:1}}
html.js #about .dec.run,html.js #about .dec.done{opacity:1}
@media(prefers-reduced-motion:reduce){#about .pa-c.in{animation:none}#about .pa-c.sc{color:inherit;text-shadow:none;font-weight:inherit}}


/* ══════════════════════════════════════════════════════════════════════════
   v81 (2026-07-24) — ABOUT · FULL MATRIX MODE. Every blue (--signal) → matrix
   green; faster decode (JS timing halved); better blur-dissolve physics — the
   letter condenses in with a bright green LOCK-FLASH (brightness 2.4→1) + a scale
   settle, on the somatic inhale curve. Overrides v79/v80 (appended later wins).
   ══════════════════════════════════════════════════════════════════════════ */
#about .eyebrow{color:#00CC33}
#about .pa-stmt{color:#63f3a0;text-shadow:0 0 12px rgba(0,204,51,.20)}
#about .pa-line{color:#50e58e}
#about .pa-turn{color:#8dffb9;text-shadow:0 0 18px rgba(0,204,51,.32)}
#about .pa-stmt b,#about .pa-line b,#about .pa-turn b,#about .pa-sig,
#about .pa-c.k,#about .pa-c.e{color:#c7ffdb !important;text-shadow:0 0 11px rgba(120,255,190,.55)}
#about .pa-c.sc{color:#00CC33;text-shadow:0 0 9px rgba(0,204,51,.65)}
#about .pa-c.in{animation:paIn .4s var(--ease-inhale) both}
@keyframes paIn{
  0%{filter:blur(6px) brightness(2.4);opacity:0;transform:scale(1.16)}
  70%{filter:blur(0) brightness(1.35);opacity:1;transform:scale(1)}
  100%{filter:blur(0) brightness(1);opacity:1;transform:scale(1)}
}

/* v82 (2026-07-24) — About: reverse green/white — WHITE readable text, GREEN keyword
   accents. Scramble rain stays matrix green (.sc). Overrides v81 (later wins). */
#about .pa-stmt{color:#f4f6fa;text-shadow:0 0 12px rgba(200,255,220,.14)}
#about .pa-line{color:#e9edf4}
#about .pa-turn{color:#ffffff;text-shadow:0 0 18px rgba(120,255,180,.20)}
#about .pa-stmt b,#about .pa-line b,#about .pa-turn b,#about .pa-sig,
#about .pa-c.k,#about .pa-c.e{color:#00CC33 !important;text-shadow:0 0 11px rgba(0,204,51,.6)}

/* v83 (2026-07-24) — About: EVERY sentence a STATEMENT. Big type, single column
   (the stats rail drops below), generous line spacing. Overrides the v79 small body. */
#about .about__grid--split{display:block}
#about .about__col{max-width:none}
#about .about__lines{max-width:none;display:flex;flex-direction:column;gap:clamp(1.3rem,2.6vw,2.1rem)}
#about .pa-stmt{font-size:clamp(2.2rem,5.2vw,3.8rem);max-width:18ch;line-height:1.08}
#about .pa-line{font-size:clamp(1.65rem,3.5vw,2.5rem);font-weight:500;line-height:1.18;max-width:24ch}
#about .pa-turn{font-size:clamp(2.6rem,6.2vw,4.3rem);max-width:12ch;line-height:1.04}
#about .about__rail{margin-top:clamp(2rem,4vw,3rem)}

/* v84 (2026-07-24) — About decode ADVANCED: scramble renders in a ::before pseudo
   (absolute → ZERO reflow + ZERO width-jitter; the real char under it holds the box).
   Brighter matrix glow. Blur is applied inline only to the wave-front chars (JS). */
#about .pa-c{position:relative;display:inline-block}
#about .pa-c.sc{color:transparent}
#about .pa-c.sc::before{content:attr(data-g);position:absolute;inset:0;display:grid;place-items:center;color:#4dff8f;text-shadow:0 0 8px rgba(77,255,143,.65),0 0 16px rgba(0,204,51,.28);pointer-events:none;overflow:visible}

/* v85 (2026-07-24) — hide the REAL char during scramble even for keywords (the .k/.e color !important was showing the real letter UNDER the ::before scramble = doubled glyphs). */
#about .pa-c.sc{color:transparent !important}

/* v86 (2026-07-24) — restore v99 textContent-morph scramble (green, NO ::before) + fixed-width cells so big text cannot jitter. Overrides v84/v85. */
#about .pa-c{display:inline-block;text-align:center}
#about .pa-c.sc{color:#00CC33 !important}
#about .pa-c.sc::before{content:none}
