/* ==========================================================================
   FLUXERA OS — experience layer
   Loaded after fluxera.css. The base file keeps the tokens, the fluid scale,
   the measured WCAG colours and the form/layout primitives. This file turns
   the surface into an instrument panel: volumetric light, holographic glass,
   kinetic type, scroll-linked depth and a boot sequence.

   Contents
     0   Registered properties + extended tokens
     1   Stage: shader canvas, grain, scanlines, vignette, HUD chrome
     2   Boot sequence
     3   Page-transition curtain
     4   Custom cursor
     5   Kinetic typography
     6   Holographic surfaces
     7   Buttons — magnetic, light-bled
     8   Navigation — floating capsule
     9   Section architecture + dividers
     10  Media — clip reveals, frames, comparator
     11  Data viz: workflow canvas, HUD rail, counters
     12  Tabs, accordion, forms — restyled
     13  Footer
     14  Scroll-linked utilities
     15  Reduced motion + performance tiers
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Registered properties + extended tokens
   -------------------------------------------------------------------------- */
@property --ang   { syntax: '<angle>';     initial-value: 0deg; inherits: false; }
@property --shine { syntax: '<percentage>'; initial-value: 0%;  inherits: false; }
@property --hue   { syntax: '<number>';    initial-value: 0;    inherits: false; }

:root {
  /* Self-hosted variable faces (see fluxera-fonts.css). Restated here because
     this sheet loads last and must win over the base file's stack. */
  --font-display: 'GroteskVar', 'Space Grotesk', ui-sans-serif, system-ui, sans-serif;
  --font-body:    'InterVar', 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-mono:    'MonoVar', ui-monospace, 'SFMono-Regular', Menlo, monospace;

  /* Glass */
  --glass:        rgba(11, 18, 34, .55);
  --glass-lit:    rgba(16, 26, 46, .72);
  --glass-brd:    rgba(140, 190, 205, .13);
  --glass-brd-lit:rgba(0, 200, 200, .42);
  --blur:         18px;

  /* Volumetric light */
  --lume-1: rgba(0, 200, 200, .55);
  --lume-2: rgba(13, 59, 94, .45);
  --lume-3: rgba(77, 159, 255, .32);
  --halo:   0 0 0 1px rgba(0, 200, 200,.16), 0 0 34px -6px rgba(0, 200, 200,.30);
  --halo-lg:0 0 0 1px rgba(0, 200, 200,.24), 0 0 70px -10px rgba(0, 200, 200,.42);

  /* Depth ladder */
  --lift-1: 0 1px 0 rgba(255,255,255,.05) inset, 0 10px 30px -18px rgba(0,0,0,.9);
  --lift-2: 0 1px 0 rgba(255,255,255,.07) inset, 0 24px 60px -28px rgba(0,0,0,.95);
  --lift-3: 0 1px 0 rgba(255,255,255,.09) inset, 0 40px 90px -34px rgba(0,0,0,1);

  /* Motion physics */
  --spring:  linear(0,.0033,.0132,.0292,.0511,.0787,.1116,.1495,.192,.2388,.2895,.3437,.401,.4611,.5236,.5881,.6542,.7215,.7896,.8582,.9268,.9951,1.0628,1.1295,1.1949,1.2586,1.3204,1.3799,1.4369,1.4912,1.5426,1.5908,1.6357,1.6772,1.7152,1.7495,1.7801,1.807,1.8302,1.8497,1.8656,1.8779,1.8867,1.8922,1.8945,1.8938,1.8902,1.884,1.8754,1.8646,1.8518,1.8373,1.8213,1.804,1.7857,1.7666,1.7469,1.7268,1.7065,1.6863,1.6662,1.6465,1.6273,1.6088,1.5911,1.5743,1.5585,1.5438,1.5302,1.5178,1.5066,1.4966,1.4879,1.4804,1.4741,1.469,1.4651,1.4622,1.4604,1.4596,1.4597,1.4606,1.4623,1.4646,1.4676,1.471,1.4749,1.4791,1.4835,1.4881,1.4928,1.4974,1.502,1.5064,1.5106,1.5145,1.518,1.5212,1.5239,1.5262,1.528,1.5293);
  --ease-out:  cubic-bezier(.16, 1, .3, 1);
  --ease-in-out: cubic-bezier(.76, 0, .24, 1);
  --ease-back: cubic-bezier(.34, 1.56, .64, 1);

  /* Scroll-driven values written by JS */
  --scroll: 0;
  --vel: 0;
  --mx-page: 50vw;
  --my-page: 50vh;
}

html {
  scroll-padding-top: 7.5rem;
  /* Belt and braces against horizontal scroll. Decorative layers and
     pre-animation transforms extend past the viewport by design; clipping at
     the root means none of them can ever produce a sideways scrollbar. */
  overflow-x: clip;
}

body {
  background: #071120;
  overflow-x: clip;
}

/* Everything real sits above the stage.
   The nav is deliberately absent from this rule — it is position:fixed and
   setting position:relative here would drop it out of the viewport. */
main, .footer { position: relative; z-index: 2; }
.fx-hud, .fx-cursor, .fx-curtain, .fx-boot { position: fixed; }

/* --------------------------------------------------------------------------
   1. Stage — the light behind the page
   -------------------------------------------------------------------------- */
.fx-stage {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
}

/* WebGL / canvas field */
#fxCanvas {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
  opacity: 0; transition: opacity 1.4s var(--ease-out);
}
#fxCanvas.is-live { opacity: 1; }

/* Neural field — nodes, links and travelling signals.
   Sits in front of the shader but behind grain, scanlines and the vignette,
   because the vignette is the scrim that guarantees text contrast and nothing
   may paint above it. */
#fxNet {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
  opacity: 0; transition: opacity 1.8s var(--ease-out);
}
#fxNet.is-live { opacity: 1; }

/* Bounded panel — the same engine inside a framed box, used where a real
   product still does not exist yet. */
.neuralpanel {
  position: relative;
  background:
    radial-gradient(120% 140% at 50% 0%, rgba(0, 200, 200, .10), transparent 62%),
    linear-gradient(180deg, #08182b, #061020 70%);
  overflow: hidden;
}
.neuralpanel__c {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
}
/* A slow sweep of light across the panel so it has a pulse of its own even
   between signal arrivals. */
.neuralpanel__glow {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(38% 60% at 50% 50%, rgba(0, 200, 200, .16), transparent 70%);
  animation: npGlow 9s var(--ease-in-out, ease-in-out) infinite;
}
@keyframes npGlow {
  0%, 100% { transform: translateX(-16%) scale(1);    opacity: .55 }
  50%      { transform: translateX(16%)  scale(1.08); opacity: .95 }
}

/* CSS fallback field — always present, sits under the canvas so a
   WebGL failure still leaves a lit page rather than a flat one. */
.fx-field {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(58vw 58vw at 18% 6%,  rgba(0, 138, 168,.20), transparent 62%),
    radial-gradient(46vw 46vw at 86% 14%, rgba(0, 200, 200,.14), transparent 62%),
    radial-gradient(70vw 50vw at 50% 96%, rgba(13, 59, 94,.16), transparent 68%),
    #071120;
}

/* Engineered grid — perspective floor that drifts with scroll */
.fx-grid {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(0, 200, 200,.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 200, 200,.055) 1px, transparent 1px);
  background-size: 72px 72px;
  background-position: 0 calc(var(--scroll) * -180px);
  mask-image: radial-gradient(ellipse 90% 70% at 50% 30%, #000 5%, transparent 72%);
  -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 30%, #000 5%, transparent 72%);
}

/* Pointer spotlight — a soft cone of light that follows the cursor */
.fx-spot {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(420px circle at var(--mx-page) var(--my-page),
              rgba(0, 200, 200,.075), transparent 62%);
  transition: opacity .5s var(--ease-out);
}

/* Film grain */
.fx-grain {
  position: fixed; inset: -100%; z-index: 1; pointer-events: none;
  opacity: .05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 1.1s steps(6) infinite;
  will-change: transform;
}
@keyframes grain {
  0%   { transform: translate3d(0,0,0) }
  20%  { transform: translate3d(-3%,2%,0) }
  40%  { transform: translate3d(2%,-3%,0) }
  60%  { transform: translate3d(-2%,-2%,0) }
  80%  { transform: translate3d(3%,3%,0) }
  100% { transform: translate3d(0,0,0) }
}

/* CRT scanlines — barely there, but it reads as "signal" */
.fx-scan {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  opacity: .38;
  background: repeating-linear-gradient(
    180deg, transparent 0 2px, rgba(6, 26, 44, .30) 2px 3px);
}

/* Edge vignette keeps focus centre-screen, and a flat scrim guarantees the
   text contrast ratios hold no matter how bright the field gets underneath.
   Without it, a light passage in the shader could drop body copy below AA. */
.fx-vignette {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(ellipse 76% 62% at 50% 46%, rgba(3,6,13,.62), rgba(3,6,13,.18) 62%, transparent 82%),
    radial-gradient(ellipse 100% 80% at 50% 50%, transparent 38%, rgba(0,0,0,.72) 100%),
    linear-gradient(180deg, rgba(3,6,13,.42), rgba(3,6,13,.30) 40%, rgba(3,6,13,.58));
}

/* --- HUD chrome ------------------------------------------------------------ */
.fx-hud { position: fixed; inset: 0; z-index: 90; pointer-events: none; }

.fx-hud__corner {
  position: absolute; width: 26px; height: 26px;
  border: 1px solid rgba(0, 200, 200,.30);
}
.fx-hud__corner--tl { top: 14px;  left: 14px;  border-right: 0; border-bottom: 0; }
.fx-hud__corner--tr { top: 14px;  right: 14px; border-left: 0;  border-bottom: 0; }
.fx-hud__corner--bl { bottom: 14px; left: 14px; border-right: 0; border-top: 0; }
.fx-hud__corner--br { bottom: 14px; right: 14px; border-left: 0; border-top: 0; }

/* Vertical scroll spine on the right edge */
.fx-spine {
  position: absolute; right: 26px; top: 22vh; bottom: 22vh; width: 1px;
  background: linear-gradient(180deg, transparent, rgba(0, 200, 200,.16) 12%, rgba(0, 200, 200,.16) 88%, transparent);
}
.fx-spine__fill {
  position: absolute; inset: 0 auto 0 0; width: 1px;
  background: linear-gradient(180deg, var(--accent), var(--blue));
  transform-origin: 50% 0; transform: scaleY(var(--scroll));
  box-shadow: 0 0 10px 1px rgba(0, 200, 200,.65);
}
.fx-spine__pct {
  position: absolute; right: 10px; top: calc(var(--scroll) * 100%);
  transform: translateY(-50%);
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .14em;
  color: var(--accent); white-space: nowrap; opacity: .85;
  text-shadow: 0 0 12px rgba(0, 200, 200,.6);
}

/* Telemetry readout, bottom-left */
.fx-telemetry {
  position: absolute; left: 26px; bottom: 22px;
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .16em;
  text-transform: uppercase; color: rgba(117,144,168,.62); line-height: 1.9;
}
.fx-telemetry b { color: var(--accent); font-weight: 500; }
.fx-telemetry span { display: block; }

/* The HUD chrome lives in the margin beside the container, so the breakpoint
   has to track the container width — 1360px plus roughly 150px of clearance
   either side. It was pinned to the old 1180px container, which is why the
   telemetry readout started printing straight over the body copy the moment
   the container was widened. */
@media (max-width: 1660px) { .fx-spine, .fx-telemetry, .fx-hud__corner { display: none; } }

/* Top progress hairline stays, but reads as a light beam */
.scroll-progress {
  height: 2px;
  background: linear-gradient(90deg, var(--blue) 0%, var(--accent) 55%, #9ef1ff 100%);
  box-shadow: 0 0 16px 1px rgba(0, 200, 200,.8), 0 0 3px rgba(255,255,255,.7);
  z-index: 210;
}

/* --------------------------------------------------------------------------
   2. Boot sequence
   -------------------------------------------------------------------------- */
.fx-boot {
  position: fixed; inset: 0; z-index: 9999;
  background: #071120;
  display: grid; place-items: center;
  transition: opacity .7s var(--ease-out);
}
.fx-boot[hidden] { display: none; }
.fx-boot.is-done { opacity: 0; pointer-events: none; }

.fx-boot__inner { display: grid; justify-items: center; gap: 1.6rem; width: min(420px, 82vw); }

.fx-boot__mark { width: 74px; height: 74px; overflow: visible; }
.fx-boot__mark path, .fx-boot__mark polygon, .fx-boot__mark rect, .fx-boot__mark circle {
  fill: none; stroke: var(--accent); stroke-width: 2.2;
  stroke-dasharray: var(--len, 400); stroke-dashoffset: var(--len, 400);
  animation: draw 1.5s var(--ease-out) forwards, glowpulse 2.4s ease-in-out .9s infinite;
  filter: drop-shadow(0 0 8px rgba(0, 200, 200,.8));
}
@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes glowpulse {
  0%,100% { filter: drop-shadow(0 0 6px rgba(0, 200, 200,.55)); }
  50%     { filter: drop-shadow(0 0 18px rgba(0, 200, 200,.95)); }
}

.fx-boot__log {
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .1em;
  color: rgba(117,144,168,.8); line-height: 2; text-align: left;
  width: 100%; min-height: 5.5rem;
}
.fx-boot__log span { display: block; opacity: 0; animation: bootline .3s var(--ease-out) forwards; }
.fx-boot__log b { color: var(--success); font-weight: 500; float: right; }
@keyframes bootline { from { opacity:0; transform: translateX(-6px) } to { opacity:1; transform:none } }

.fx-boot__bar { width: 100%; height: 2px; background: rgba(0, 200, 200,.14); overflow: hidden; }
.fx-boot__bar i {
  display: block; height: 100%; width: 100%;
  background: linear-gradient(90deg, var(--blue), var(--accent));
  transform-origin: 0 50%; transform: scaleX(0);
  animation: bootbar 1.9s var(--ease-out) forwards;
  box-shadow: 0 0 14px rgba(0, 200, 200,.8);
}
@keyframes bootbar { to { transform: scaleX(1) } }

/* Iris wipe out of the boot screen */
.fx-boot.is-done { clip-path: circle(0% at 50% 50%); transition: clip-path .9s var(--ease-in-out), opacity .5s .4s linear; }

/* --------------------------------------------------------------------------
   3. Page-transition curtain
   -------------------------------------------------------------------------- */
.fx-curtain {
  position: fixed; inset: 0; z-index: 9000; pointer-events: none;
  display: grid; grid-template-columns: repeat(6, 1fr);
}
.fx-curtain i {
  background: linear-gradient(180deg, #0E2740, #071120);
  border-right: 1px solid rgba(0, 200, 200,.10);
  transform: scaleY(0); transform-origin: 50% 100%;
  transition: transform .5s var(--ease-in-out);
}
.fx-curtain.is-in  i { transform: scaleY(1); transform-origin: 50% 100%; }
.fx-curtain.is-out i { transform: scaleY(0); transform-origin: 50% 0; }
.fx-curtain i:nth-child(1) { transition-delay: 0s;    }
.fx-curtain i:nth-child(2) { transition-delay: .04s;  }
.fx-curtain i:nth-child(3) { transition-delay: .08s;  }
.fx-curtain i:nth-child(4) { transition-delay: .12s;  }
.fx-curtain i:nth-child(5) { transition-delay: .16s;  }
.fx-curtain i:nth-child(6) { transition-delay: .20s;  }

@media (max-width: 720px) { .fx-curtain { grid-template-columns: repeat(3, 1fr); } }

/* --------------------------------------------------------------------------
   4. Custom cursor
   -------------------------------------------------------------------------- */
/* Hidden until the pointer actually moves, so it never sits parked in the
   middle of the viewport on a page the user hasn't touched yet. */
.fx-cursor {
  position: fixed; top: 0; left: 0; z-index: 9500; pointer-events: none;
  mix-blend-mode: screen; opacity: 0; transition: opacity .3s var(--ease-out);
}
.fx-cursor.is-awake { opacity: 1; }
.fx-cursor__dot,
.fx-cursor__ring {
  position: absolute; top: 0; left: 0; border-radius: 50%;
  transform: translate(-50%, -50%); will-change: transform;
}
.fx-cursor__dot  { width: 5px; height: 5px; background: var(--accent); box-shadow: 0 0 10px rgba(0, 200, 200,.9); }
.fx-cursor__ring {
  width: 34px; height: 34px;
  border: 1px solid rgba(0, 200, 200,.55);
  transition: width .3s var(--ease-out), height .3s var(--ease-out),
              border-color .3s var(--ease-out), background .3s var(--ease-out);
}
.fx-cursor.is-hot .fx-cursor__ring {
  width: 62px; height: 62px;
  border-color: rgba(0, 200, 200,.85);
  background: rgba(0, 200, 200,.08);
}
.fx-cursor.is-down .fx-cursor__ring { width: 24px; height: 24px; }

@media (hover: none), (pointer: coarse) { .fx-cursor { display: none; } }
html.has-fxcursor, html.has-fxcursor a, html.has-fxcursor button { cursor: none; }
html.has-fxcursor input, html.has-fxcursor textarea, html.has-fxcursor select { cursor: auto; }

/* --------------------------------------------------------------------------
   5. Kinetic typography
   -------------------------------------------------------------------------- */
.kinetic { display: block; }
.kinetic .ln { display: block; overflow: hidden; padding-bottom: .06em; margin-bottom: -.06em; }
/* Words are the wrapping unit. Characters are inline-block for the animation,
   which would otherwise let a line break fall inside a word. */
.kinetic .wd { display: inline-block; white-space: nowrap; }
.kinetic .sp { display: inline; white-space: normal; }
.kinetic .ch {
  display: inline-block; white-space: pre;
  transform: translateY(105%) rotateX(-70deg);
  opacity: 0; filter: blur(6px);
  transform-origin: 50% 100%;
  transition:
    transform .95s var(--ease-out) var(--d, 0s),
    opacity   .7s  var(--ease-out) var(--d, 0s),
    filter    .7s  var(--ease-out) var(--d, 0s);
}
.kinetic.is-in .ch { transform: none; opacity: 1; filter: none; }

/* Second line onwards in the accent. fx.js measures which words fall below
   the first line and tags them, because the visual lines come from ordinary
   wrapping inside a single .ln box — there is no element to select.
   -webkit-text-fill-color has to be reset explicitly: .display and .h1 set it
   transparent for their gradient, and it wins over `color`. */
.kinetic .wd--alt {
  color: #3FDCDC;
  -webkit-text-fill-color: #3FDCDC;
  background: none;
  filter: drop-shadow(0 0 20px rgba(0, 200, 200, .32));
}
.kinetic .wd--alt .ch { color: inherit; -webkit-text-fill-color: inherit; }

/* Display headline gets chromatic depth */
.display, .h1 {
  background: linear-gradient(178deg, #ffffff 6%, #d8ecff 38%, #7FD9E0 92%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
/* The accent gradient stays inside the bright half of the brand ramp.
   Running it down to --blue (#0D3B5E) put the tail of a headline at 3.4:1,
   which fails AA for large text on this ground. */
.display em, .h1 em, h1 em, h2 em {
  background: linear-gradient(100deg, #00C8C8 0%, #9DF0F0 42%, #00B4C9 100%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  font-style: normal;
  filter: drop-shadow(0 0 22px rgba(0, 200, 200,.42));
}

/* Eyebrow becomes a status readout */
.eyebrow {
  font-family: var(--font-mono);
  letter-spacing: .28em;
  position: relative;
  padding-left: 0;
}
.eyebrow::before {
  width: 2.2em; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent));
  box-shadow: 0 0 8px rgba(0, 200, 200,.6);
}

/* Long unbroken technical strings — hashes, URLs, function signatures — have
   to be allowed to break, or a single one pushes the whole page wider than a
   phone viewport and every section inherits the horizontal scroll. */
.mono, code, .ticks li, .row__body, .card__body { overflow-wrap: anywhere; }

/* A section intro caps its width at --measure so the body copy stays readable.
   The trouble is that `ch` resolves against the element it is declared on — the
   wrapper, at body size — while the heading inside renders at three times that.
   A 36ch cap on the wrapper is about 400px, and a 57px headline squeezed into
   400px is how a four-word title ended up on four lines.

   A child can never be wider than its parent, so capping the heading is no use:
   the cap has to come off the wrapper and go onto the elements individually.
   The paragraph keeps the readable measure; the heading is freed, and fx.js
   then decides its width by measuring — aiming for two lines.

   This applies to every .measure intro, centred or not. Scoping it to
   .center.measure fixed the home page and left every left-aligned section
   heading on the inner pages still crushed into a 26ch column, which is how
   "Where the hours actually go." ended up on three lines. */
.section .measure:has(> h1, > h2, > h3, > .h1, > .h2, > .h3) { max-width: none; }
.section .measure > p,
.section .measure > .lead,
.section .measure > .text-muted,
.section .measure > ul,
.section .measure > ol {
  max-width: var(--measure);
}
.section .center.measure > p,
.section .center.measure > .lead,
.section .center.measure > .text-muted { margin-inline: auto; }

.section .measure > h1, .section .measure > h2,
.section .measure > h3, .section .measure > .h1,
.section .measure > .h2, .section .measure > .h3 {
  max-width: 26ch;
}
.section .center.measure > h1, .section .center.measure > h2,
.section .center.measure > h3, .section .center.measure > .h1,
.section .center.measure > .h2, .section .center.measure > .h3 {
  margin-inline: auto;
}

/* :has() is well supported now, but a browser without it would get an
   uncapped intro paragraph running the full container width — unreadable.
   This restores the cap for those, at the cost of the heading fix they were
   never going to get anyway. */
@supports not selector(:has(*)) {
  .section .measure { max-width: var(--measure); }
}

/* Section index numeral, set by [data-index] */
.section[data-index]::before {
  content: attr(data-index);
  position: absolute; top: var(--sp-l); right: var(--gutter);
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .3em;
  color: rgba(0, 200, 200,.30); z-index: 1;
}

/* --------------------------------------------------------------------------
   6. Holographic surfaces
   -------------------------------------------------------------------------- */
.card,
.holo {
  position: relative;
  background:
    linear-gradient(168deg, rgba(23,38,64,.62), rgba(9,15,28,.72));
  border: 1px solid var(--glass-brd);
  border-radius: 18px;
  backdrop-filter: blur(var(--blur)) saturate(150%);
  -webkit-backdrop-filter: blur(var(--blur)) saturate(150%);
  box-shadow: var(--lift-1);
  isolation: isolate;
  overflow: hidden;
  transition:
    transform .55s var(--ease-out),
    border-color .4s var(--ease-out),
    box-shadow .55s var(--ease-out),
    background .45s var(--ease-out);
}

/* Specular sheen tracking the pointer */
.card::before,
.holo::before {
  content: ''; position: absolute; inset: -1px; z-index: -1; pointer-events: none;
  border-radius: inherit; opacity: 0;
  background: radial-gradient(380px circle at var(--mx, 50%) var(--my, 50%),
              rgba(0, 200, 200,.16), rgba(13, 59, 94,.06) 42%, transparent 68%);
  transition: opacity .45s var(--ease-out);
}
.card:hover::before,
.holo:hover::before { opacity: 1; }

/* Rotating conic edge light */
.card::after,
.holo::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  border-radius: inherit; padding: 1px; opacity: 0;
  background: conic-gradient(from var(--ang),
    transparent 0deg, rgba(0, 200, 200,.95) 42deg, transparent 96deg,
    transparent 190deg, rgba(13, 59, 94,.85) 232deg, transparent 288deg);
  -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;
  transition: opacity .45s var(--ease-out);
  animation: spinang 5s linear infinite paused;
}
.card:hover::after,
.holo:hover::after { opacity: 1; animation-play-state: running; }
@keyframes spinang { to { --ang: 360deg; } }

.card:hover,
.holo:hover {
  border-color: var(--glass-brd-lit);
  box-shadow: var(--lift-2), 0 0 46px -14px rgba(0, 200, 200,.42);
  background: linear-gradient(168deg, rgba(28,48,80,.68), rgba(11,19,35,.78));
}
.card--link:hover { transform: translateY(-6px); }

/* Corner notch — a machined bevel that reads as hardware */
.card--notch { border-radius: 18px 4px 18px 4px; }
.card--notch::marker { content: none; }

/* Feature surface with an internal light bar */
.card--feature { padding: var(--sp-l); }
.card--feature > .card__inner { position: relative; z-index: 2; }

/* Kicker becomes a chip */
.card__kicker {
  display: inline-flex; align-items: center; gap: .5em;
  font-family: var(--font-mono); letter-spacing: .2em;
  color: var(--accent);
}
.card__kicker::before {
  content: ''; width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; box-shadow: 0 0 8px currentColor;
}

/* Numbered step becomes a node on a line */
.step { padding-top: var(--sp-s); }
.step::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, var(--accent), transparent 70%);
  opacity: .5;
}
.step__num {
  font-family: var(--font-mono); font-size: var(--fs--1);
  letter-spacing: .2em; opacity: .85;
}
.step__num::after {
  content: ''; display: inline-block; vertical-align: middle;
  width: 6px; height: 6px; margin-left: .7em; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 10px var(--accent);
}

/* Chips read as machined tags */
.chip {
  background: rgba(11,18,34,.6);
  border-color: rgba(140, 190, 205,.14);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-radius: 4px;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .1em;
  transition: border-color .3s var(--ease-out), color .3s var(--ease-out),
              background .3s var(--ease-out), transform .3s var(--ease-out);
}
.chip:hover {
  border-color: var(--glass-brd-lit); color: var(--accent);
  background: rgba(0, 200, 200,.07); transform: translateY(-2px);
}

.pill {
  border-radius: 4px;
  background: rgba(0, 200, 200,.06);
  border-color: rgba(0, 200, 200,.30);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  font-family: var(--font-mono); letter-spacing: .2em;
  box-shadow: 0 0 26px -8px rgba(0, 200, 200,.55), inset 0 0 20px -12px rgba(0, 200, 200,.9);
}
.pill__dot--live {
  box-shadow: 0 0 10px 2px currentColor;
  animation: livepulse 2s ease-in-out infinite;
}
@keyframes livepulse {
  0%,100% { opacity: 1;  box-shadow: 0 0 10px 2px currentColor; }
  50%     { opacity: .4; box-shadow: 0 0 3px 0 currentColor; }
}

/* Divider rows become a data table */
.rows { border-top-color: var(--glass-brd); }
.row  { border-bottom-color: var(--glass-brd); position: relative; transition: background .35s var(--ease-out); }
.row::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--accent); transform: scaleY(0); transform-origin: 50% 50%;
  transition: transform .4s var(--ease-out); box-shadow: 0 0 12px var(--accent);
}
.row:hover::before { transform: scaleY(1); }
.row:hover { background: linear-gradient(90deg, rgba(0, 200, 200,.05), transparent 60%); }
.row__label { font-family: var(--font-display); }

/* --------------------------------------------------------------------------
   7. Buttons
   -------------------------------------------------------------------------- */
.btn {
  border-radius: 6px;
  font-family: var(--font-mono);
  letter-spacing: .1em; text-transform: uppercase; font-size: .74rem; font-weight: 500;
  padding: clamp(.85rem, .7rem + .4vw, 1.05rem) clamp(1.3rem, 1rem + 1vw, 2.1rem);
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out),
              border-color .3s var(--ease-out), color .3s var(--ease-out),
              background .3s var(--ease-out);
  will-change: transform;
}
.btn--lg { font-size: .82rem; padding: 1.1rem 2.2rem; }

.btn--primary {
  background: linear-gradient(115deg, var(--accent-dark) 0%, var(--accent-deep) 48%, var(--accent) 100%);
  background-size: 200% 100%;
  color: #04121b;
  box-shadow: 0 0 0 1px rgba(0, 200, 200,.5), 0 10px 40px -12px rgba(0, 200, 200,.75),
              inset 0 1px 0 rgba(255,255,255,.35);
  animation: bgshift 7s ease-in-out infinite alternate;
}
@keyframes bgshift { to { background-position: 100% 0; } }
.btn--primary:hover {
  color: #04121b;
  transform: translateY(-2px);
  box-shadow: 0 0 0 1px rgba(0, 200, 200,.85), 0 18px 55px -12px rgba(0, 200, 200,.95),
              inset 0 1px 0 rgba(255,255,255,.5);
}
/* Sweep already exists in the base file; make it faster and brighter */
.btn--primary::before {
  background: linear-gradient(110deg, transparent 25%, rgba(255,255,255,.75) 48%, transparent 72%);
  transition: transform .6s var(--ease-out);
}

.btn--ghost {
  border-color: rgba(140, 190, 205,.22);
  color: var(--text);
  background: rgba(11,18,34,.5);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  position: relative; overflow: hidden;
}
.btn--ghost::after {
  content: ''; position: absolute; inset: 0; opacity: 0;
  background: radial-gradient(140px circle at var(--mx,50%) var(--my,50%), rgba(0, 200, 200,.22), transparent 70%);
  transition: opacity .35s var(--ease-out);
}
.btn--ghost:hover {
  border-color: var(--glass-brd-lit); color: var(--accent);
  background: rgba(0, 200, 200,.05);
  transform: translateY(-2px);
  box-shadow: 0 0 34px -10px rgba(0, 200, 200,.7);
}
.btn--ghost:hover::after { opacity: 1; }

.btn--quiet {
  text-transform: none; letter-spacing: .02em;
  font-family: var(--font-body); font-size: var(--fs--1); font-weight: 600;
  padding-inline: 0;
}
.btn--quiet::after { content: '⟶'; transition: transform .35s var(--ease-out); }
.btn--quiet:hover::after { transform: translateX(6px); }

/* Magnetic wrapper written by JS */
.magnet { display: inline-flex; will-change: transform; }

/* --------------------------------------------------------------------------
   8. Navigation — floating capsule
   -------------------------------------------------------------------------- */
.nav {
  background: transparent; border-bottom: 0;
  backdrop-filter: none; -webkit-backdrop-filter: none;
  padding-top: .7rem;
  transition: padding .45s var(--ease-out);
}
.nav__inner {
  border-radius: 14px;
  padding-inline: clamp(1rem, .6rem + 1vw, 1.5rem);
  border: 1px solid transparent;
  transition: background .45s var(--ease-out), border-color .45s var(--ease-out),
              box-shadow .45s var(--ease-out), padding .45s var(--ease-out);
}
.nav.is-scrolled { padding-top: .45rem; }
.nav.is-scrolled .nav__inner {
  background: rgba(6, 11, 22, .72);
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  border-color: var(--glass-brd);
  box-shadow: var(--lift-2), 0 0 44px -20px rgba(0, 200, 200,.5);
}
.nav__links a {
  font-family: var(--font-mono); font-size: .7rem;
  letter-spacing: .12em; text-transform: uppercase;
}
.nav__links a::after {
  height: 1px; box-shadow: 0 0 8px var(--accent);
}
.nav__links a.is-flagship {
  color: var(--accent);
  text-shadow: 0 0 16px rgba(0, 200, 200,.5);
}
.nav__cta .btn { padding-block: .7rem; }
.brand__tag { font-family: var(--font-mono); letter-spacing: .22em; }

@media (max-width: 940px) {
  .nav__inner { background: rgba(6,11,22,.8); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-color: var(--glass-brd); }
  .nav__links, .nav__cta {
    background: rgba(6,11,22,.96);
    backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
    border: 1px solid var(--glass-brd); border-radius: 14px;
    margin-top: .5rem; border-top: 0;
  }
  .nav__links a { border-bottom-color: var(--glass-brd); font-size: .8rem; }
}

/* --------------------------------------------------------------------------
   9. Section architecture
   -------------------------------------------------------------------------- */
.section { padding-block: clamp(4rem, 2.5rem + 6vw, 7.5rem); }
.section--tight { padding-block: clamp(3rem, 2rem + 4vw, 5rem); }

/* Hairline dividers that run edge to edge with a bright node in the middle */
.section + .section::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(0, 200, 200,.22) 22%, rgba(0, 200, 200,.22) 78%, transparent);
  z-index: 1;
}

/* Hero occupies real estate */
.hero { min-height: min(94svh, 900px); display: flex; align-items: center; }
.hero .container { width: 100%; }

/* The old aurora is superseded by the shader; keep it as a soft under-layer */
.aurora span { filter: blur(110px); opacity: .30; }

/* Grid background is now global — drop the per-section one */
.grid-bg::before { display: none; }

/* Frosted panel used for full-width feature bands */
.band {
  position: relative; overflow: hidden;
  border-block: 1px solid var(--glass-brd);
  background: linear-gradient(180deg, rgba(8,14,27,.55), rgba(4,8,17,.75));
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}

/* Hero scroll cue */
.hero__scroll {
  display: grid; justify-items: center; gap: .6rem;
  margin-top: clamp(2.5rem, 1rem + 5vw, 5rem);
}
.hero__scroll-line {
  width: 1px; height: 54px; position: relative; overflow: hidden;
  background: rgba(0, 200, 200,.16);
}
.hero__scroll-line::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent, var(--accent));
  animation: scrollcue 2.2s var(--ease-in-out) infinite;
}
@keyframes scrollcue {
  0%   { transform: translateY(-100%) }
  60%,100% { transform: translateY(100%) }
}
.hero__scroll-text {
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .34em;
  color: var(--muted);
}

/* Tick list used inside service cards */
.ticks { list-style: none; padding: 0; margin: 0; font-size: var(--fs--1); color: var(--muted); }
.ticks li { position: relative; padding-left: 1.35em; margin-bottom: .42em; line-height: 1.5; }
.ticks li::before {
  content: ''; position: absolute; left: 0; top: .62em;
  width: 6px; height: 6px; border-radius: 1px;
  background: var(--accent); opacity: .55;
  transform: rotate(45deg);
  transition: opacity .3s var(--ease-out), box-shadow .3s var(--ease-out);
}
.card:hover .ticks li::before { opacity: 1; box-shadow: 0 0 8px var(--accent); }
/* Prohibition list — same rhythm, opposite signal */
.ticks--no li::before { background: var(--danger); }
.card:hover .ticks--no li::before { box-shadow: 0 0 8px var(--danger); }

/* Spec rail — key/value pairs as an instrument readout */
.specrail {
  display: grid; gap: 1px;
  /* 180px rather than 150px so a four-item rail inside a half-width card
     breaks to a balanced 2x2 instead of an awkward 3 + 1 with a blank cell. */
  grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  background: var(--glass-brd);
  border: 1px solid var(--glass-brd); border-radius: 10px; overflow: hidden;
}
.specrail > div { background: rgba(6,11,22,.75); padding: .7rem .9rem; }
.specrail span {
  display: block; font-family: var(--font-mono); font-size: .66rem;
  letter-spacing: .18em; text-transform: uppercase; color: var(--muted);
}
.specrail b {
  display: block; margin-top: .18em; font-size: var(--fs--1);
  color: var(--text); font-weight: 600;
}

/* Feature cell inside a tab panel */
.feature { position: relative; padding-left: var(--sp-s); }
.feature::before {
  content: ''; position: absolute; left: 0; top: .3em; bottom: .3em; width: 1px;
  background: linear-gradient(180deg, var(--accent), transparent);
  opacity: .45;
}

/* Data-stream divider */
.stream { position: relative; height: 60px; overflow: hidden; }
.stream i {
  position: absolute; top: 0; bottom: 0; width: 1px;
  background: linear-gradient(180deg, transparent, var(--accent), transparent);
  opacity: .35;
  animation: streamfall 3.4s linear infinite;
}
@keyframes streamfall { from { transform: translateY(-100%) } to { transform: translateY(100%) } }

/* --------------------------------------------------------------------------
   10. Media
   -------------------------------------------------------------------------- */
.media {
  border-radius: 16px;
  border-color: var(--glass-brd);
  background: rgba(8,14,27,.6);
  box-shadow: var(--lift-2);
}
/* Clip-path reveal, driven by .is-visible */
.media--reveal img, .media--reveal .media__ph {
  clip-path: inset(0 0 100% 0);
  transition: clip-path 1.1s var(--ease-in-out), transform 1.4s var(--ease-out);
  transform: scale(1.08);
}
.reveal.is-visible .media--reveal img,
.media--reveal.is-visible img,
.reveal.is-visible .media--reveal .media__ph,
.media--reveal.is-visible .media__ph { clip-path: inset(0 0 0 0); transform: scale(1); }

/* Bezel — a HUD frame with corner ticks and a sweeping scanline */
.media--bezel { padding: 0; }
.media--bezel::before {
  content: ''; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  border-radius: inherit;
  background:
    linear-gradient(90deg, var(--accent) 0 18px, transparent 18px) 0 0/100% 1px no-repeat,
    linear-gradient(90deg, var(--accent) 0 18px, transparent 18px) 0 100%/100% 1px no-repeat,
    linear-gradient(180deg, var(--accent) 0 18px, transparent 18px) 0 0/1px 100% no-repeat,
    linear-gradient(180deg, var(--accent) 0 18px, transparent 18px) 100% 0/1px 100% no-repeat;
  opacity: .55;
}
.media--bezel::after {
  content: ''; position: absolute; left: 0; right: 0; height: 30%; z-index: 2;
  background: linear-gradient(180deg, transparent, rgba(0, 200, 200,.10), transparent);
  animation: sweep 5.5s var(--ease-in-out) infinite;
  pointer-events: none;
}
@keyframes sweep { 0% { top: -30% } 55%,100% { top: 100% } }

.media__ph {
  background:
    linear-gradient(135deg, rgba(0, 200, 200,.06), transparent 55%),
    repeating-linear-gradient(45deg, transparent 0 12px, rgba(0, 200, 200,.03) 12px 24px);
  font-family: var(--font-mono); letter-spacing: .16em;
}
.media__ph b { font-family: var(--font-display); letter-spacing: .02em; }

/* Looping showcase video */
.videoloop { position: relative; overflow: hidden; }
.videoloop__el { width: 100%; height: 100%; object-fit: cover; display: block; background: #071120; }
.videoloop__cap {
  position: absolute; left: 14px; bottom: 14px; z-index: 4;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--body);
  background: rgba(3,7,15,.72); border: 1px solid var(--glass-brd);
  padding: .35em .8em; border-radius: 3px;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
/* When motion is reduced the clip is paused and given controls by fx.js —
   make room for them so they aren't clipped by object-fit. */
.videoloop__el[controls] { object-fit: contain; }

/* Before / after comparator (Fluxera 5.0) */
.compare {
  position: relative; overflow: hidden; border-radius: 16px;
  border: 1px solid var(--glass-brd); box-shadow: var(--lift-3);
  touch-action: pan-y; user-select: none; cursor: ew-resize;
}
.compare { margin: 0; }
.compare--21x9 { aspect-ratio: 21 / 9; }
.compare--16x9 { aspect-ratio: 16 / 9; }
.compare__pane { position: absolute; inset: 0; }
/* The panes hold whatever img() produced — a real <figure> or a placeholder.
   Either way it must fill the frame exactly, or the split line won't line up. */
.compare__pane > .media {
  position: absolute; inset: 0; width: 100%; height: 100%;
  aspect-ratio: auto; border: 0; border-radius: 0; margin: 0;
}
.compare__pane img, .compare__pane .media__ph { width: 100%; height: 100%; object-fit: cover; }
.compare__pane--before .media__ph { background: linear-gradient(135deg, rgba(120,140,170,.09), transparent 60%), #0E2740; }
/* Offset the two placeholder captions so they don't sit on top of each other
   before the real captures are dropped in. */
.compare__pane--before .media__ph { align-content: start; padding-top: 18%; }
.compare__pane--after  .media__ph { align-content: end;   padding-bottom: 18%; }
.compare__pane--after { clip-path: inset(0 0 0 var(--split, 50%)); }
.compare__handle {
  position: absolute; top: 0; bottom: 0; left: var(--split, 50%);
  width: 2px; background: var(--accent); box-shadow: 0 0 22px 2px rgba(0, 200, 200,.85);
  z-index: 4; transform: translateX(-50%);
}
.compare__handle::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 44px; height: 44px; transform: translate(-50%,-50%);
  border-radius: 50%; border: 1px solid var(--accent);
  background: rgba(4,10,20,.75); backdrop-filter: blur(8px);
  box-shadow: 0 0 26px -4px rgba(0, 200, 200,.8);
}
.compare__handle::before {
  content: '‹ ›'; position: absolute; top: 50%; left: 50%;
  transform: translate(-50%,-50%); z-index: 1;
  font-family: var(--font-mono); font-size: .8rem; color: var(--accent);
  letter-spacing: .1em;
}
.compare__tag {
  position: absolute; bottom: 14px; z-index: 5;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .2em;
  text-transform: uppercase; color: var(--text);
  background: rgba(3,7,15,.72); border: 1px solid var(--glass-brd);
  padding: .35em .8em; border-radius: 3px; backdrop-filter: blur(8px);
}
.compare__tag--l { left: 14px; }
.compare__tag--r { right: 14px; }

/* --------------------------------------------------------------------------
   11. Data viz
   -------------------------------------------------------------------------- */
/* Self-drawing workflow canvas */
.flowmap { width: 100%; height: auto; overflow: visible; }
.flowmap .fm-link {
  fill: none; stroke: rgba(0, 200, 200,.35); stroke-width: 1.5;
  stroke-dasharray: var(--l, 300); stroke-dashoffset: var(--l, 300);
  transition: stroke-dashoffset 1.2s var(--ease-out) var(--d, 0s);
}
.flowmap.is-in .fm-link { stroke-dashoffset: 0; }
.flowmap .fm-node {
  fill: rgba(11,18,34,.9); stroke: rgba(0, 200, 200,.5); stroke-width: 1;
  opacity: 0; transform-origin: center;
  transition: opacity .5s var(--ease-out) var(--d, 0s);
}
.flowmap.is-in .fm-node { opacity: 1; }
.flowmap .fm-label {
  fill: var(--body); font-family: var(--font-mono); font-size: 9px;
  letter-spacing: .1em; text-transform: uppercase;
  opacity: 0; transition: opacity .5s var(--ease-out) var(--d, 0s);
}
.flowmap.is-in .fm-label { opacity: 1; }
.flowmap .fm-pulse {
  fill: #9DF0F0;
  filter: drop-shadow(0 0 7px rgba(0, 200, 200,1));
  opacity: 0; transition: opacity .6s var(--ease-out) 1.1s;
}
.flowmap.is-in .fm-pulse { opacity: .95; }
.flowmap .fm-node--ai  { stroke: rgba(0, 200, 200,.95); fill: rgba(10, 48, 66,.92); }
.flowmap .fm-node--in,
.flowmap .fm-node--out { stroke: rgba(46, 214, 160,.75); fill: rgba(6, 44, 40,.9); }
.flowmap .fm-dot {
  fill: var(--accent); opacity: 0;
  transition: opacity .5s var(--ease-out) var(--d, .4s);
}
.flowmap.is-in .fm-dot { opacity: .8; }
.flowmap .fm-node--ai + .fm-label { fill: var(--text); }

/* The canvas sits in a machined frame with a live status strip */
.flowframe {
  position: relative; overflow: hidden;
  border: 1px solid var(--glass-brd); border-radius: 16px;
  background: linear-gradient(168deg, rgba(10,18,34,.72), rgba(4,8,17,.86));
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  box-shadow: var(--lift-3);
  padding: var(--sp-m) var(--sp-m) var(--sp-s);
}
.flowframe::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(0, 200, 200,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 200, 200,.05) 1px, transparent 1px);
  background-size: 28px 28px;
  mask-image: radial-gradient(ellipse 80% 80% at 50% 50%, #000, transparent 82%);
  -webkit-mask-image: radial-gradient(ellipse 80% 80% at 50% 50%, #000, transparent 82%);
}
.canvas-head {
  display: flex; flex-wrap: wrap; gap: var(--sp-m) var(--sp-xl);
  align-items: end; justify-content: space-between;
}
.flowframe__bar {
  display: flex; flex-wrap: wrap; gap: 1rem 1.6rem; align-items: center;
  padding-bottom: var(--sp-s); margin-bottom: var(--sp-s);
  border-bottom: 1px solid var(--glass-brd);
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--muted);
  position: relative; z-index: 1;
}
.flowframe__bar b { color: var(--accent); font-weight: 500; }
.flowscroll { position: relative; z-index: 1; }
.flowscroll__hint { display: none; }

@media (max-width: 900px) {
  /* Pan the canvas instead of shrinking the labels past legibility. */
  .flowscroll {
    overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: rgba(0, 200, 200,.4) transparent;
    padding-bottom: .5rem;
    mask-image: linear-gradient(90deg, #000 0 92%, transparent);
    -webkit-mask-image: linear-gradient(90deg, #000 0 92%, transparent);
  }
  .flowscroll::-webkit-scrollbar { height: 4px; }
  .flowscroll::-webkit-scrollbar-thumb { background: rgba(0, 200, 200,.4); border-radius: 2px; }
  .flowscroll .flowmap { width: 860px; max-width: none; flex: none; }
  .flowscroll__hint {
    display: block; margin-top: .5rem;
    font-family: var(--font-mono); font-size: .68rem; letter-spacing: .18em;
    text-transform: uppercase; color: var(--muted);
  }
}
@media (max-width: 720px) { .flowframe { padding-inline: var(--sp-s); } }

/* HUD stat rail */
.hudrail {
  display: grid; gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(min(160px,100%), 1fr));
  background: var(--glass-brd);
  border: 1px solid var(--glass-brd); border-radius: 12px; overflow: hidden;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.hudrail > * {
  background: rgba(6,11,22,.7); padding: var(--sp-m) var(--sp-s);
  position: relative; transition: background .4s var(--ease-out);
}
.hudrail > *:hover { background: rgba(0, 200, 200,.06); }
.hudrail > *::before {
  content: ''; position: absolute; top: 0; left: 0; width: 22px; height: 1px;
  background: var(--accent); box-shadow: 0 0 8px var(--accent);
}
.stat__value {
  font-variant-numeric: tabular-nums;
  background: linear-gradient(180deg, #ffffff, #7FD9E0);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
.stat__label { font-family: var(--font-mono); font-size: .68rem; letter-spacing: .18em; text-transform: uppercase; }

/* Marquee gets velocity skew from JS */
.marquee__track { will-change: transform; }
.marquee { --skew: 0deg; }

/* --------------------------------------------------------------------------
   12. Tabs, accordion, forms
   -------------------------------------------------------------------------- */
[role="tablist"] {
  display: flex; flex-wrap: wrap; gap: .4rem;
  padding: .35rem; border-radius: 12px;
  background: rgba(6,11,22,.6); border: 1px solid var(--glass-brd);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
[role="tab"] {
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
  padding: .7rem 1.1rem; border-radius: 8px; border: 1px solid transparent;
  transition: color .3s var(--ease-out), background .3s var(--ease-out),
              border-color .3s var(--ease-out), box-shadow .3s var(--ease-out);
}
[role="tab"]:hover { color: var(--text); }
[role="tab"][aria-selected="true"] {
  color: var(--accent);
  background: rgba(0, 200, 200,.08);
  border-color: rgba(0, 200, 200,.35);
  box-shadow: inset 0 0 24px -12px rgba(0, 200, 200,.9), 0 0 22px -10px rgba(0, 200, 200,.8);
}
[role="tabpanel"] { animation: panelin .55s var(--ease-out); }
@keyframes panelin { from { opacity: 0; transform: translateY(10px) } to { opacity: 1; transform: none } }

/* The question and the chevron are laid out as a grid rather than flex.
   A bare text node inside a flex row becomes an anonymous item with an
   implicit min-width of auto, so on a narrow screen it refuses to shrink and
   pushes the chevron 6px past the edge. `minmax(0, 1fr)` gives the text a
   column that is allowed to be narrower than its longest line, so it wraps. */
.faq summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-s);
}
.faq summary::after { justify-self: end; }

.faq, .faq details { border-color: var(--glass-brd); }
.faq details { position: relative; transition: background .35s var(--ease-out); }
.faq details[open] { background: linear-gradient(90deg, rgba(0, 200, 200,.045), transparent 55%); }
.faq summary { font-family: var(--font-display); }
.faq summary::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--accent); transform: scaleY(0); transform-origin: 50% 50%;
  transition: transform .4s var(--ease-out); box-shadow: 0 0 12px var(--accent);
}
.faq details[open] summary::before { transform: scaleY(1); }

.input, .select, .textarea {
  background: rgba(6,11,22,.6);
  border-color: var(--glass-brd);
  border-radius: 8px;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  transition: border-color .3s var(--ease-out), box-shadow .3s var(--ease-out), background .3s var(--ease-out);
}
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--accent);
  background: rgba(0, 200, 200,.04);
  box-shadow: 0 0 0 3px rgba(0, 200, 200,.12), 0 0 34px -12px rgba(0, 200, 200,.8);
}
.field__label { font-family: var(--font-mono); letter-spacing: .18em; }

:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 3px;
  box-shadow: 0 0 0 4px rgba(0, 200, 200,.14), 0 0 26px -8px rgba(0, 200, 200,.9);
  border-radius: 6px;
}

/* --------------------------------------------------------------------------
   13. Footer
   -------------------------------------------------------------------------- */
.footer {
  background: linear-gradient(180deg, rgba(6,11,22,.55), rgba(3,6,13,.92));
  border-top: 1px solid var(--glass-brd);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  position: relative; overflow: hidden;
}
.footer::before {
  content: ''; position: absolute; top: -1px; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  opacity: .5;
}
.footer h4 { font-family: var(--font-mono); letter-spacing: .2em; }
.footer nav a { font-family: var(--font-mono); font-size: .7rem; letter-spacing: .08em; position: relative; width: fit-content; }
.footer nav a::after {
  content: ''; position: absolute; left: 0; right: 100%; bottom: -2px; height: 1px;
  background: var(--accent); transition: right .3s var(--ease-out);
}
.footer nav a:hover::after { right: 0; }
.footer__bottom { border-top-color: var(--glass-brd); font-family: var(--font-mono); letter-spacing: .1em; }

/* --------------------------------------------------------------------------
   14. Scroll-linked utilities
   -------------------------------------------------------------------------- */
/* Depth layers — JS writes --p (0..1 progress through viewport) */
.depth { will-change: transform; }
.depth--1 { transform: translate3d(0, calc(var(--p, 0) * -30px), 0); }
.depth--2 { transform: translate3d(0, calc(var(--p, 0) * -62px), 0); }
.depth--3 { transform: translate3d(0, calc(var(--p, 0) * -96px), 0); }

/* Richer default reveal */
.reveal {
  opacity: 0;
  transform: translateY(34px) scale(.985);
  filter: blur(8px);
  transition: opacity .9s var(--ease-out), transform 1s var(--ease-out), filter .9s var(--ease-out);
}
.reveal.is-visible { opacity: 1; transform: none; filter: none; }
.reveal-d1 { transition-delay: .09s } .reveal-d2 { transition-delay: .18s }
.reveal-d3 { transition-delay: .27s } .reveal-d4 { transition-delay: .36s }
.reveal-d5 { transition-delay: .45s } .reveal-d6 { transition-delay: .54s }

/* Sliding reveals for split layouts.
   Only above 900px: on a narrow screen the columns already sit close to the
   edges, so a 46px pre-animation offset pushes the page wider than the
   viewport and the whole document picks up a horizontal scrollbar until the
   element animates in. Below that width they rise vertically instead. */
@media (min-width: 901px) {
  .reveal--l { transform: translateX(-46px); }
  .reveal--r { transform: translateX(46px); }
  .reveal--l.is-visible, .reveal--r.is-visible { transform: none; }
}

/* Glitch text effect for the 404 and flagship badges */
.glitch { position: relative; display: inline-block; }
.glitch::before, .glitch::after {
  content: attr(data-text); position: absolute; inset: 0;
  -webkit-text-fill-color: currentColor; color: currentColor;
  background: none; clip-path: inset(0 0 0 0);
}
.glitch::before { color: #00C8C8; animation: glitchA 3.2s steps(2) infinite; }
.glitch::after  { color: #ff4f9a; animation: glitchB 2.7s steps(2) infinite; }
@keyframes glitchA {
  0%,92%,100% { transform: none; opacity: 0 }
  93% { transform: translate(-2px,1px); opacity: .8; clip-path: inset(12% 0 62% 0) }
  96% { transform: translate(2px,-1px); opacity: .8; clip-path: inset(58% 0 18% 0) }
}
@keyframes glitchB {
  0%,90%,100% { transform: none; opacity: 0 }
  91% { transform: translate(2px,-1px); opacity: .55; clip-path: inset(38% 0 42% 0) }
  95% { transform: translate(-2px,2px); opacity: .55; clip-path: inset(72% 0 8% 0) }
}

/* Oversized error numeral behind the 404 message */
.err-code {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(6rem, 3rem + 20vw, 16rem); line-height: .85;
  letter-spacing: -.05em; color: rgba(0, 200, 200,.10);
  margin-bottom: calc(var(--sp-m) * -0.4);
  user-select: none;
}
.err-code .glitch::before { color: rgba(0, 200, 200,.5); }
.err-code .glitch::after  { color: rgba(255,79,154,.35); }

/* Skip link matches the system */
.skip-link { border-radius: 0 0 6px 6px; font-family: var(--font-mono); letter-spacing: .12em; text-transform: uppercase; }

/* --------------------------------------------------------------------------
   15. Reduced motion + tiers
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .fx-grain, .fx-scan, .stream, .fx-curtain, .fx-cursor { display: none !important; }
  #fxCanvas { display: none !important; }
  .fx-boot { display: none !important; }
  .kinetic .ch { transform: none !important; opacity: 1 !important; filter: none !important; }
  .reveal { opacity: 1 !important; transform: none !important; filter: none !important; }
  .card::after, .holo::after { animation: none !important; }
  .btn--primary { animation: none !important; }
  .media--bezel::after { animation: none !important; display: none; }
  .media--reveal img, .media--reveal .media__ph { clip-path: none !important; transform: none !important; }
  /* The network itself stays — JS paints one static frame. Only the sweeping
     glow is animation for its own sake, so only that goes. */
  .neuralpanel__glow { animation: none !important; opacity: .7 !important; transform: none !important; }
  .flowmap .fm-link { stroke-dashoffset: 0 !important; }
  .flowmap .fm-node, .flowmap .fm-label { opacity: 1 !important; }
  .depth { transform: none !important; }
  html.has-fxcursor, html.has-fxcursor a, html.has-fxcursor button { cursor: auto; }
}

/* Low-power tier — JS sets html.fx-lite when the device can't hold 60fps */
html.fx-lite #fxCanvas { display: none; }
/* The network stays on the lite tier — fx.js thins it instead. Hiding it here
   removed the one effect the page is actually built around on exactly the
   machines least likely to have anything else going on. */
html.fx-lite #fxNet { opacity: .78; }
html.fx-lite .fx-grain,
html.fx-lite .fx-scan { display: none; }
/* Panels stay on the lite tier: a panel stands in for page content, so losing
   it leaves a visible hole, unlike the background field. */
html.fx-lite .neuralpanel__glow { animation-duration: 16s; }
html.fx-lite .card,
html.fx-lite .holo,
html.fx-lite .nav.is-scrolled .nav__inner,
html.fx-lite .input, html.fx-lite .textarea, html.fx-lite .select,
html.fx-lite [role="tablist"], html.fx-lite .footer, html.fx-lite .chip {
  backdrop-filter: none; -webkit-backdrop-filter: none;
  background: rgba(9,15,28,.94);
}
html.fx-lite .card::after, html.fx-lite .holo::after { display: none; }

/* Coarse pointer: no hover-only effects, larger touch targets */
@media (hover: none) {
  .card::before, .holo::before, .card::after, .holo::after { display: none; }
  .btn { padding-block: 1rem; }
  .fx-spot { display: none; }

  /* Email and phone links are things people actually tap, and as inline text
     they inherit the line height — around 17px, well under the 44px the WCAG
     target-size guidance asks for. Give them a real hit area without
     disturbing the surrounding paragraph. */
  a[href^="mailto:"], a[href^="tel:"] {
    display: inline-block;
    padding-block: .55rem;
    min-height: 44px;
    line-height: 1.9;
  }
  /* Footer links sit in a tight column; space them for thumbs. */
  .footer nav a { padding-block: .45rem; }
  .footer__bottom a { display: inline-block; padding: .5rem .25rem; }
}

@media print {
  .fx-stage, .fx-hud, .fx-cursor, .fx-curtain, .fx-boot, #fxCanvas, #fxNet,
  .fx-field, .fx-grid, .fx-grain, .fx-scan, .fx-vignette, .fx-spot { display: none !important; }
}
