/* =====================================================================
   VECTOR ABYSS · homepage theme  (html[data-theme="abyss"] only)
   ---------------------------------------------------------------------
   The deep sea reconstructed as pure line-mesh geometry — a scientific
   vector instrument, not an arcade. The page descends from a bright,
   densely-meshed surface into a near-black hadal zone where only faint
   sensor specks, slow currents (and one amber core) survive.

   CONTRAST CONTRACT — every zone owns its background AND its ink:
     z-surface   #F2F6F6  ink #0B2536            (~14.9:1)
     z-shallow   #E2EDEE→#C9DEE2  ink #0B2536    (~11.4:1 at darkest)
     z-thermo    gradient — labels pinned to the light TOP (dark ink)
                 and the dark BOTTOM (light ink); no text mid-gradient
     z-twilight  #15394E  ink #EAF4F2            (~12.4:1)
     z-midnight  #0C2638  ink #EAF4F2            (~14.6:1)
     z-deep      #07192A  ink #EAF4F2
     z-abyss     #040F1B  ink #EAF4F2
     z-hadal     #02070D  ink #EAF4F2
   Backgrounds are per-SECTION (scroll with content) — there is no fixed
   full-viewport wash behind scrolling text.
   ===================================================================== */

html[data-theme="abyss"] {
  --va-depth: 0; /* 0 = surface, 1 = abyss · set by the page script */

  --va-paper: #f2f6f6;
  --va-ink-deep: #0b2536;
  --va-light-ink: #eaf4f2;
  --va-amber: #e89b3c;
  --va-teal: #46c8af;

  scroll-behavior: smooth;
}

/* ── base type ──────────────────────────────────────────────────── */
html[data-theme="abyss"] body.va-body {
  font-family:
    "Instrument Sans",
    system-ui,
    -apple-system,
    sans-serif;
  background: var(--va-paper);
  color: var(--va-ink-deep);
  font-size: 16.5px;
  line-height: 1.6;
}

.va-display {
  font-family: "Bricolage Grotesque", "Instrument Sans", sans-serif;
  font-weight: 600;
  letter-spacing: -0.022em;
  line-height: 1.04;
  color: var(--ink, inherit);
}

.va-mono {
  font-family: "JetBrains Mono", ui-monospace, monospace;
}

.va-eyebrow {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink2);
}

/* section tag — the "01 — THE PROBLEM" mono index labels */
.va-depthtag {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink2);
  white-space: nowrap;
}
.va-depthtag::before {
  content: "";
  width: 2.2rem;
  height: 1px;
  background: var(--ink2);
  opacity: 0.7;
}

/* =====================================================================
   ZONES — each section paints its own water + carries its own ink
   ===================================================================== */
.vz {
  position: relative;
  background: var(--bg);
  color: var(--ink);
}
.vz-surface {
  --bg: #e7eff0;
  --ink: #0b2536;
  --ink2: #44617a;
  --line: #1c5570;
  --hair: rgba(11, 37, 54, 0.16);
  --card: rgba(255, 255, 255, 0.62);
  /* The hero is the first step of the descent, not a flat bright slab: hold
     the paper tone flat through the contour-chart band (its fade overlay
     paints solid #f2f6f6, so the surface must match there or the waves drift
     into a bright bar), then ease toward the shallows' tone so the seam into
     .vz-shallow is continuous. */
  background: linear-gradient(to bottom, #f2f6f6 0%, #f2f6f6 24%, #e7eff0 100%);
}
.vz-shallow {
  --bg: #e2edee;
  --ink: #0b2536;
  --ink2: #3c596e;
  --line: #1c5570;
  --hair: rgba(11, 37, 54, 0.18);
  --card: rgba(255, 255, 255, 0.55);
  /* Starts where .vz-surface ends (#e7eff0) — no tonal reset at the seam. */
  background: linear-gradient(to bottom, #e7eff0 0, #dde9ea 150px, #cbdfe3 100%);
}
.vz-thermo {
  --ink: #eaf4f2;
  --ink2: #a9c3cc;
  --line: #8fd9cc;
  --hair: rgba(234, 244, 242, 0.14);
  background: linear-gradient(
    to bottom,
    #cbdfe3 0%,
    #9dbfc9 26%,
    #557e93 54%,
    #2b5066 76%,
    #15394e 100%
  );
  color: #eaf4f2;
}
.vz-twilight {
  --bg: #15394e;
  --ink: #eaf4f2;
  --ink2: #a9c3cc;
  --line: #8fd9cc;
  --hair: rgba(234, 244, 242, 0.14);
  --card: rgba(234, 244, 242, 0.045);
}
.vz-midnight {
  --bg: #0c2638;
  --ink: #eaf4f2;
  --ink2: #a0bcc7;
  --line: #8fd9cc;
  --hair: rgba(234, 244, 242, 0.13);
  --card: rgba(234, 244, 242, 0.04);
  background: linear-gradient(to bottom, #15394e 0, #0c2638 140px);
}
.vz-deep {
  --bg: #07192a;
  --ink: #eaf4f2;
  --ink2: #9bb7c3;
  --line: #8fd9cc;
  --hair: rgba(234, 244, 242, 0.12);
  --card: rgba(234, 244, 242, 0.035);
  background: linear-gradient(to bottom, #0c2638 0, #07192a 140px);
}
.vz-abyss {
  --bg: #040f1b;
  --ink: #eaf4f2;
  --ink2: #93afbc;
  --line: #8fd9cc;
  --hair: rgba(234, 244, 242, 0.11);
  --card: rgba(234, 244, 242, 0.03);
  background: linear-gradient(to bottom, #07192a 0, #040f1b 140px);
}
.vz-hadal {
  --bg: #02070d;
  --ink: #eaf4f2;
  --ink2: #8da9b6;
  --line: #8fd9cc;
  --hair: rgba(234, 244, 242, 0.1);
  --card: rgba(234, 244, 242, 0.03);
  background: linear-gradient(to bottom, #040f1b 0, #02070d 140px);
}
/* continuation section — same zone again, no re-blend from the lighter
   neighbour */
.vz--flat {
  background: var(--bg);
}

/* secondary text inside zones */
.va-sub {
  color: var(--ink2);
}
.va-strong {
  color: var(--ink);
  font-weight: 600;
}
/* inline text link — a clear clickable affordance (accent + underline +
   pointer) for links living inside body copy, where bare <a> tags would
   otherwise render as plain, indistinguishable text */
.va-inlink {
  color: #0f8f7c;
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: rgba(15, 143, 124, 0.4);
  text-underline-offset: 3px;
  cursor: pointer;
  transition:
    color 0.2s ease,
    text-decoration-color 0.2s ease;
}
.va-inlink:hover {
  color: #0c715f;
  text-decoration-color: #0f8f7c;
}

/* =====================================================================
   COMPONENTS
   ===================================================================== */

/* survey-plate card: hairline frame + corner registration nodes */
.va-card {
  position: relative;
  border: 1px solid var(--hair);
  background: var(--card);
  border-radius: 2px;
}
.va-card::before,
.va-card::after {
  content: "";
  position: absolute;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  border: 1px solid var(--ink2);
  background: var(--bg, transparent);
  opacity: 0.85;
}
.va-card::before {
  top: -3px;
  left: -3px;
}
.va-card::after {
  bottom: -3px;
  right: -3px;
}

/* reading surface — a calm frosted panel so text-heavy content separates
   cleanly from the drifting atmosphere behind it. The deep-sea life stays
   visible in the page gutters, but the prose sits on its own even, slightly
   darkened surface for comfortable sustained reading. */
.reading-surface {
  position: relative;
  background: rgba(6, 17, 27, 0.66);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
  border: 1px solid var(--hair);
  border-radius: 3px;
  padding: clamp(1.75rem, 4.5vw, 3.5rem);
}
@media (max-width: 640px) {
  .reading-surface {
    padding: 1.5rem 1.35rem;
  }
}

/* =====================================================================
   PROSE — long-form reading typography. Shared globally so blog posts
   and the legal pages (/terms, /privacy, /service-agreement) all read
   the same. (Was previously trapped scoped inside BlogLayout.)
   ===================================================================== */
.prose {
  color: #c8d6dd;
  font-size: 1.15rem;
  line-height: 1.8;
}
.prose p {
  margin-bottom: 1.5rem;
}
.prose h2,
.prose h3,
.prose h4 {
  font-family: "Bricolage Grotesque", "Instrument Sans", sans-serif;
  font-weight: 600;
  letter-spacing: -0.018em;
  color: #eaf4f2;
  line-height: 1.2;
  margin-top: 2.5rem;
  margin-bottom: 1rem;
}
.prose h2 {
  font-size: 1.85rem;
}
.prose h3 {
  font-size: 1.4rem;
}
.prose h4 {
  font-size: 1.15rem;
}
.prose strong {
  color: #eaf4f2;
  font-weight: 600;
}
.prose a {
  color: #8fd9cc;
  font-weight: 500;
  border-bottom: 1px solid rgba(143, 217, 204, 0.4);
  padding-bottom: 1px;
  transition:
    color 0.2s,
    border-color 0.2s;
}
.prose a:hover {
  color: #b9ece2;
  border-color: #8fd9cc;
}
.prose ul,
.prose ol {
  margin: 1.5rem 0;
  padding-left: 1.5rem;
}
.prose ul {
  list-style: disc;
}
.prose ol {
  list-style: decimal;
}
.prose li {
  margin-bottom: 0.6rem;
}
.prose li::marker {
  color: #46c8af;
}
.prose blockquote {
  border-left: 3px solid #46c8af;
  padding-left: 1.25rem;
  margin: 1.75rem 0;
  color: #a9c3cc;
  font-style: italic;
}
.prose code {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.88em;
  color: #b9ece2;
  background: rgba(234, 244, 242, 0.05);
  border: 1px solid var(--hair);
  border-radius: 2px;
  padding: 0.12em 0.4em;
}
.prose pre {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.85rem;
  line-height: 1.7;
  background: rgba(234, 244, 242, 0.035);
  border: 1px solid var(--hair);
  border-radius: 2px;
  padding: 1.1rem 1.25rem;
  margin: 1.75rem 0;
  overflow-x: auto;
}
.prose pre code {
  background: none;
  border: none;
  padding: 0;
  color: #c8d6dd;
  font-size: inherit;
}
.prose img {
  max-width: 100%;
  height: auto;
  border-radius: 2px;
  border: 1px solid var(--hair);
  margin: 1.75rem 0;
}
.prose hr {
  border: none;
  border-top: 1px solid var(--hair);
  margin: 2.5rem 0;
}

/* buttons — solid flips automatically with the zone ink */
.va-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.78rem 1.55rem;
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  border-radius: 2px;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: var(--bg, #f2f6f6);
  transition:
    transform 0.18s ease,
    opacity 0.18s ease;
  cursor: pointer;
}
.va-btn:hover {
  opacity: 0.88;
  transform: translateY(-1px);
}
.va-btn--ghost {
  background: transparent;
  color: var(--ink);
}
.va-btn--ghost:hover {
  opacity: 0.75;
}
.va-btn .va-btn__arrow {
  font-family: "JetBrains Mono", monospace;
  font-weight: 400;
}

/* checklist tick (drawn, no icon font) */
.va-tick {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  margin-top: 0.28rem;
}
.va-tick path {
  stroke: var(--va-teal);
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* mono kbd-ish chip */
.va-chip {
  display: inline-block;
  padding: 0.28rem 0.7rem;
  border: 1px solid var(--hair);
  border-radius: 2px;
  font-family: "JetBrains Mono", monospace;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: var(--ink2);
}

/* =====================================================================
   HERO — instrument readout card
   ===================================================================== */
.va-live {
  border: 1px solid var(--hair);
  background: rgba(255, 255, 255, 0.66);
  border-radius: 2px;
  backdrop-filter: blur(4px);
}
/* dark variant for the deep inner pages (instrument panel on near-black
   water, not the surface hero's frosted white) */
.va-live--deep {
  background: rgba(234, 244, 242, 0.035);
}
.va-live__bar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--hair);
  font-family: "JetBrains Mono", monospace;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink2);
}
.va-live__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--va-teal);
  animation: va-blink 2.4s ease-in-out infinite;
}
.va-live__body {
  padding: 1rem 1rem 1.1rem;
  font-family: "JetBrains Mono", monospace;
  font-size: 0.8rem;
  line-height: 1.9;
  color: var(--ink);
}
.va-line {
  display: flex;
  gap: 0.65rem;
  opacity: 0;
  transform: translateY(4px);
  transition:
    opacity 0.45s ease,
    transform 0.45s ease;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.va-line.is-in {
  opacity: 1;
  transform: none;
}
.va-line--dim {
  color: var(--ink2);
}
.va-line--hot .va-line__mark {
  color: var(--va-amber);
}
.va-line--ok {
  color: #0e6b5c;
  font-weight: 600;
}
.va-line__mark {
  color: var(--ink2);
  flex-shrink: 0;
}
/* phones: the nowrap mono lines otherwise set the hero grid's
   min-content width (~405px on a 390px viewport), clipping the whole
   hero column at the right edge — let them wrap instead */
@media (max-width: 639px) {
  .va-line {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
  }
}
#hero .grid > * {
  min-width: 0;
}
.va-caret {
  display: inline-block;
  width: 7px;
  height: 13px;
  margin-left: 2px;
  background: var(--ink);
  vertical-align: -2px;
  animation: va-caret-blink 1.06s linear infinite;
}

/* =====================================================================
   WIREFRAME ART — strokes, vertices, motion
   ===================================================================== */
.va-art {
  position: absolute;
  pointer-events: none;
  user-select: none;
}
.va-art svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* sensor vertices twinkle */
.va-vx {
  animation: va-twinkle 5.2s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}
.va-vx--hot {
  animation: va-hotpulse 3.4s ease-in-out infinite;
  animation-delay: var(--d, 0s);
}

/* surface bathymetry — nested depth isolines breathing at different
   rates. The motion is the kelp-sway mechanism (CSS rotation on a group
   about a far-off-canvas pivot), which every engine renders smoothly: a
   hair of rotation reads as a slow vertical drift, so the contour bands
   undulate without the stepping that CSS/SMIL translate showed in
   Firefox (WebRender pixel-snaps axis-aligned SVG content). */
.va-contours {
  position: absolute;
  inset: 0;
}
.va-contours .va-vx {
  animation: none;
  opacity: 0.5;
}
/* The chart's amber findings keep their static amber, but must NOT pulse:
   the opacity animation promotes each ring to its own compositing layer,
   and Firefox/WebRender paints that layer with an opaque backing — an
   opaque disc that covers the contours behind it. Dropping the animation
   (same treatment as the soundings above) removes the layer promotion. */
.va-contours .va-vx--hot {
  animation: none;
}
/* phones: the wide chart is slice-cropped and zoomed, so the contours
   read as big coarse lines crowding the headline — dim them to a faint
   surface texture (the desktop chart is unchanged) */
@media (max-width: 1023px) {
  .va-contourwrap .va-contours {
    opacity: 0.42;
  }
}
.va-iso-a,
.va-iso-b,
.va-iso-c {
  transform-box: view-box;
  /* Promote each band to its own GPU layer so the slow breathing rotation
     is composited (rasterize once, transform on the GPU) instead of
     repainting every contour path on the main thread each frame — which is
     what makes the drift stutter when the specks/fish/gusts compete for the
     main thread. */
  will-change: transform;
}
/* three contour bands bob about a shared far-left pivot, alternating
   direction (a↓ b↑ c↓) on staggered, slow clocks so the chart breathes
   without moving in lockstep */
.va-iso-a {
  transform-origin: -3000px 190px;
  animation: va-isorot 9s ease-in-out infinite alternate;
}
.va-iso-b {
  transform-origin: -3000px 190px;
  animation: va-isorot-c 11s ease-in-out -3s infinite alternate;
}
.va-iso-c {
  transform-origin: -3000px 190px;
  animation: va-isorot 13s ease-in-out -6s infinite alternate;
}

/* the circuit medusa — slow deep drift; data pulses drip down the
   tentacle traces; the hex routing core breathes amber */
.va-medusa {
  animation: va-medusa-drift 17s ease-in-out -5s infinite alternate;
}
.va-drip {
  stroke-dasharray: 5 96;
  animation: va-drip-fall var(--pdur, 5s) linear var(--pd, 0s) infinite;
}
.va-core-halo {
  transform-box: fill-box;
  transform-origin: center;
  animation: va-core-pulse 4.2s ease-in-out infinite;
}

/* wind-gust currents — each gust is one short tapered streak (dash =
   head + trailing flecks + a gap longer than the lane) that appears,
   races the lane on an eased clock, and fades out. Per-gust prime-ish
   durations/delays keep the bundle from ever visibly looping. The
   resting dash offset (--gs) only shows under reduced motion. */
.va-gust {
  stroke-dashoffset: var(--gs, 0px);
  opacity: 0;
  animation: va-gust-run var(--gdur, 11s) cubic-bezier(0.5, 0.06, 0.45, 0.94)
    var(--gd, 0s) infinite;
}
/* riders — the wireframe life a current carries past every so often;
   their long-cycle motion + visibility windows are SMIL, in the SVG */
/* currents enter and leave like water, not rules across the page */
svg:has(.va-gust) {
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent,
    #000 14%,
    #000 86%,
    transparent
  );
  mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
}

/* the cyber phish — the brand mark gliding through the shallows */
.va-phish {
  animation: va-phish-glide 16s ease-in-out -5s infinite alternate;
}

/* kelp — each stipe sways gently about its holdfast, staggered phases */
.va-kelp {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: va-kelp-sway var(--kdur, 9s) ease-in-out var(--kd, 0s) infinite
    alternate;
}

/* plankton motes — slow rise near the kelp, fading out */
.va-mote {
  opacity: 0;
  animation: va-mote-rise var(--mdur, 11s) linear var(--md, 0s) infinite;
}

/* signal pulses rising up kelp stipes / circuit traces like bubbles */
.va-kelp-pulse {
  stroke-dasharray: 5 115;
  animation: va-pulse-rise var(--pdur, 7s) linear var(--pd, 0s) infinite;
}

/* geometric plankton/diatoms — slow drift in the sunlit margins */
.va-plankton {
  transform-box: fill-box;
  transform-origin: center;
  animation: va-plankton-drift var(--pdur, 18s) ease-in-out var(--pd, 0s)
    infinite alternate;
}

/* dart-fish school — the group glides, each dart bobs on its own phase */
.va-school {
  animation: va-school-glide 36s ease-in-out -9s infinite alternate;
}
.va-dart {
  animation: va-dart-bob 7s ease-in-out var(--d, 0s) infinite alternate;
}

/* chambered nautilus — slow mid-water drift with a gentle roll */
.va-nautilus {
  animation: va-naut-drift 19s ease-in-out -5s infinite alternate;
}

/* far-background ray — long, slow glide */
.va-ray {
  animation: va-ray-glide 38s ease-in-out -14s infinite alternate;
}
/* the manta's pectoral wings flex gently, the two wings counter-phased,
   pivoting on the body centreline so the facets breathe as it glides */
.va-ray-wing {
  transform-box: view-box;
  transform-origin: 0px 0px;
  animation: va-ray-flex 9s ease-in-out -2s infinite alternate;
}
.va-ray-wing--b {
  animation-name: va-ray-flex-b;
  animation-delay: -4.5s;
}

/* garden eels — periscoping sway about the burrow */
.va-eel {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: va-eel-sway 6.5s ease-in-out var(--d, 0s) infinite alternate;
}

/* seafloor crab — scuttle a few steps, pause, scuttle back */
.va-crab {
  animation: va-crab-scuttle 12s ease-in-out infinite;
}
/* leg articulation — the two alternating tripod groups rock a couple
   of degrees about their body-joint line, half a cycle out of phase,
   so the crab reads as stepping while the body scuttles */
.va-crab-legs {
  transform-box: fill-box;
  transform-origin: 50% 0%;
  animation: va-crab-step 1.6s ease-in-out infinite alternate;
}
.va-crab-legs--b {
  animation-delay: -0.8s;
}
/* the raised cheliped lifts in one small wave per scuttle cycle */
.va-crab-claw {
  transform-box: fill-box;
  transform-origin: 100% 100%;
  animation: va-crab-wave 12s ease-in-out infinite;
}
/* befriend the crab: a transparent hit-area that re-enables clicks on top
   of the otherwise pointer-events:none atmosphere art */
.va-crab-greet {
  pointer-events: all;
  cursor: grab;
  touch-action: none; /* let a touch-drag move the crab, not scroll the page */
}
/* the lifted crab while held: a free, full-page copy that follows the
   pointer, wiggling on a gentle dangle with a soft "picked up" shadow */
.va-crab-drag {
  position: absolute; /* document-relative, so scrolling mid-fall never breaks him */
  z-index: 55;
  pointer-events: auto; /* so he can be re-grabbed while falling/scuttling home */
  cursor: grab;
  transform-origin: 50% 40%;
  animation: va-crab-dangle 1.25s ease-in-out infinite;
  filter: drop-shadow(0 7px 9px rgba(0, 0, 0, 0.4));
}
/* on release the page script swaps these animations inline: the dangle
   stops, he sinks to the floor, then bobs as he scuttles home. */
@keyframes va-crab-dangle {
  0%,
  100% {
    transform: rotate(-4.5deg);
  }
  50% {
    transform: rotate(4.5deg);
  }
}
/* a small vertical step-bob while he scuttles back to his spot */
@keyframes va-crab-bob {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-1.6px);
  }
}
/* while grabbed and sinking he struggles: legs kick fast and the raised
   claw waves, far harder than the calm ambient step/wave */
.va-crab-drag--struggle .va-crab-legs {
  animation: va-crab-flail 0.42s ease-in-out infinite alternate;
}
.va-crab-drag--struggle .va-crab-legs--b {
  animation-delay: -0.21s; /* keep the two tripods out of phase */
}
.va-crab-drag--struggle .va-crab-claw {
  animation: va-crab-flail-claw 0.55s ease-in-out infinite;
}
@keyframes va-crab-flail {
  0% {
    transform: rotate(-13deg);
  }
  100% {
    transform: rotate(13deg);
  }
}
@keyframes va-crab-flail-claw {
  0%,
  100% {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(-17deg);
  }
}
/* feather-soft tumble: a side-to-side zigzag with decaying swings that
   settles back to centre/upright at the floor (one-shot, timed to the fall,
   so the hand-off to the scuttle has no sideways jump). Banks into each
   swing like a falling leaf. */
@keyframes va-crab-feather {
  0% {
    transform: translateX(0) rotate(0deg);
  }
  22% {
    transform: translateX(-32px) rotate(-11deg);
  }
  44% {
    transform: translateX(26px) rotate(10deg);
  }
  64% {
    transform: translateX(-20px) rotate(-8deg);
  }
  82% {
    transform: translateX(13px) rotate(5deg);
  }
  100% {
    transform: translateX(0) rotate(0deg);
  }
}
/* a brisk, pronounced stepping gait while he scuttles home — far stronger
   than the ±2.2deg ambient idle step so the legs clearly drive him along */
.va-crab-drag--scuttle .va-crab-legs {
  animation: va-crab-walk 0.42s ease-in-out infinite alternate;
}
.va-crab-drag--scuttle .va-crab-legs--b {
  animation-delay: -0.21s; /* opposite tripod leads, like a real scuttle */
}
@keyframes va-crab-walk {
  0% {
    transform: rotate(-9deg);
  }
  100% {
    transform: rotate(9deg);
  }
}
/* the wireframe heart he emotes — an HTML overlay (spawned in the page
   script) so it renders at full brightness, not dimmed by the seafloor
   group. Centered on the spawn point, then pops, drifts up, and fades. */
.va-heart-emote {
  position: fixed;
  margin-left: -18px;
  margin-top: -18px;
  pointer-events: none;
  z-index: 60;
  will-change: transform, opacity;
  filter: drop-shadow(0 0 5px rgba(255, 111, 145, 0.55));
  animation: va-heart-float 1.3s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}
@keyframes va-heart-float {
  0% {
    transform: translate(0, 0) scale(0.2) rotate(0deg);
    opacity: 0;
  }
  20% {
    transform: translate(calc(var(--dx) * 0.3), -8px) scale(1.18) rotate(var(--rot));
    opacity: 1;
  }
  45% {
    transform: translate(calc(var(--dx) * 0.6), -18px) scale(1) rotate(var(--rot));
    opacity: 1;
  }
  100% {
    transform: translate(var(--dx), -52px) scale(0.95) rotate(var(--rot));
    opacity: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  /* still a heart, just a gentle fade in place */
  @keyframes va-heart-float {
    0% {
      transform: scale(0.6);
      opacity: 0;
    }
    25% {
      transform: scale(1);
      opacity: 1;
    }
    100% {
      transform: translateY(-14px) scale(1);
      opacity: 0;
    }
  }
}

/* pipeline signal flow (dashed packets running along edges) */
.va-signal {
  stroke-dasharray: 3 11;
  animation: va-flow 2.8s linear infinite;
}

/* "How it works" ingest: alerts stream in from the sources and are absorbed
   at the ingest point (each dot drifts from its origin toward the pipeline,
   fading as it arrives; staggered so the stream feels continuous) */
.va-ingest-dot {
  animation: va-ingest-in var(--idur, 3s) linear var(--idel, 0s) infinite;
}
@keyframes va-ingest-in {
  0% {
    transform: translate(0, 0);
    opacity: 0;
  }
  14% {
    opacity: 0.75;
  }
  82% {
    opacity: 0.75;
  }
  100% {
    transform: translate(var(--tx, 0), var(--ty, 0));
    opacity: 0;
  }
}
/* the exemplar bulge travels the pipe SECTIONS only — it appears at the end of
   one section and the start of the next, and is never visible crossing a node
   centre (the node itself shows the work; see .va-fill). translateX is in SVG
   user units (like va-crab). */
/* The pipeline runs as ONE 14s cycle across five stages (arrivals 17% apart).
   Everything below is phased to that timeline. */
/* the bulge's POSITION along the pipe (translateX, SVG user units): it holds at
   a node's left edge while it shrinks in, jumps to the right edge while gone,
   holds there while it grows back, then eases out to the next node. */
.va-exemplar {
  animation: va-exemplar-run 14s ease-in-out infinite;
}
@keyframes va-exemplar-run {
  0%   { transform: translateX(0); }
  3%   { transform: translateX(48px); }                                          /* stage 1 left */
  8%   { transform: translateX(48px); }                                          /* (shrinks here) */
  9%   { transform: translateX(92px); }                                          /* jump to right edge, hidden */
  14%  { transform: translateX(92px); animation-timing-function: ease-out; }     /* grows, then darts off */
  20%  { transform: translateX(213px); }                                         /* stage 2 left */
  25%  { transform: translateX(213px); }
  26%  { transform: translateX(257px); }
  31%  { transform: translateX(257px); animation-timing-function: ease-out; }
  37%  { transform: translateX(378px); }                                         /* stage 3 left */
  42%  { transform: translateX(378px); }
  43%  { transform: translateX(422px); }
  48%  { transform: translateX(422px); animation-timing-function: ease-out; }
  54%  { transform: translateX(543px); }                                         /* stage 4 left */
  59%  { transform: translateX(543px); }
  60%  { transform: translateX(587px); }
  65%  { transform: translateX(587px); animation-timing-function: ease-out; }
  71%  { transform: translateX(708px); }                                         /* stage 5 left */
  76%  { transform: translateX(708px); }
  77%  { transform: translateX(752px); }
  82%  { transform: translateX(752px); animation-timing-function: ease-out; }
  88%  { transform: translateX(905px); }                                         /* output */
  100% { transform: translateX(905px); }
}
/* the bulge SHRINKS as the stage feeds it in (synced to the orange sweep) and
   GROWS as the stage rebuilds it (synced to the green sweep) — so the transform
   reads as one fluid motion with the edge colour, not a separate beat. */
.va-exemplar-blob {
  transform-box: fill-box;
  transform-origin: center;
  animation: va-exemplar-blob 14s ease-in-out infinite;
}
@keyframes va-exemplar-blob {
  0%, 3% { transform: scale(1); opacity: 1; }
  8% { transform: scale(0); opacity: 0; }     /* fed into stage 1 as orange sweeps */
  9% { transform: scale(0); opacity: 0; }
  14% { transform: scale(1); opacity: 1; }    /* rebuilt as green sweeps */
  20% { transform: scale(1); opacity: 1; }
  25% { transform: scale(0); opacity: 0; }    /* stage 2 */
  26% { transform: scale(0); opacity: 0; }
  31% { transform: scale(1); opacity: 1; }
  37% { transform: scale(1); opacity: 1; }
  42% { transform: scale(0); opacity: 0; }    /* stage 3 */
  43% { transform: scale(0); opacity: 0; }
  48% { transform: scale(1); opacity: 1; }
  54% { transform: scale(1); opacity: 1; }
  59% { transform: scale(0); opacity: 0; }    /* stage 4 */
  60% { transform: scale(0); opacity: 0; }
  65% { transform: scale(1); opacity: 1; }
  71% { transform: scale(1); opacity: 1; }
  76% { transform: scale(0); opacity: 0; }    /* stage 5 */
  77% { transform: scale(0); opacity: 0; }
  82% { transform: scale(1); opacity: 1; }
  88% { transform: scale(1); opacity: 1; }
  92% { transform: scale(0); opacity: 0; }    /* fed into the output */
  100% { transform: scale(0); opacity: 0; }
}
/* the colour only touches the stage's EDGES (stroke-only overlays). Orange
   sweeps the outline left→right as the issue is fed in; green sweeps left→right
   as it's verified; then everything fades back out (96→100%) so the whole
   pipeline eases to its original state instead of snapping at the loop. */
.va-fill { clip-path: inset(0 100% 0 0); }
.va-enter-1 { animation: va-enter-1 14s linear infinite; }
.va-enter-2 { animation: va-enter-2 14s linear infinite; }
.va-enter-3 { animation: va-enter-3 14s linear infinite; }
.va-enter-4 { animation: va-enter-4 14s linear infinite; }
.va-enter-5 { animation: va-enter-5 14s linear infinite; }
.va-exit-1 { animation: va-exit-1 14s linear infinite; }
.va-exit-2 { animation: va-exit-2 14s linear infinite; }
.va-exit-3 { animation: va-exit-3 14s linear infinite; }
.va-exit-4 { animation: va-exit-4 14s linear infinite; }
.va-exit-5 { animation: va-exit-5 14s linear infinite; }
@keyframes va-enter-1 { 0%, 3% { clip-path: inset(0 100% 0 0); opacity: 1; } 8%, 96% { clip-path: inset(0 0 0 0); opacity: 1; } 100% { clip-path: inset(0 0 0 0); opacity: 0; } }
@keyframes va-enter-2 { 0%, 20% { clip-path: inset(0 100% 0 0); opacity: 1; } 25%, 96% { clip-path: inset(0 0 0 0); opacity: 1; } 100% { clip-path: inset(0 0 0 0); opacity: 0; } }
@keyframes va-enter-3 { 0%, 37% { clip-path: inset(0 100% 0 0); opacity: 1; } 42%, 96% { clip-path: inset(0 0 0 0); opacity: 1; } 100% { clip-path: inset(0 0 0 0); opacity: 0; } }
@keyframes va-enter-4 { 0%, 54% { clip-path: inset(0 100% 0 0); opacity: 1; } 59%, 96% { clip-path: inset(0 0 0 0); opacity: 1; } 100% { clip-path: inset(0 0 0 0); opacity: 0; } }
@keyframes va-enter-5 { 0%, 71% { clip-path: inset(0 100% 0 0); opacity: 1; } 76%, 96% { clip-path: inset(0 0 0 0); opacity: 1; } 100% { clip-path: inset(0 0 0 0); opacity: 0; } }
@keyframes va-exit-1 { 0%, 8% { clip-path: inset(0 100% 0 0); opacity: 1; } 14%, 96% { clip-path: inset(0 0 0 0); opacity: 1; } 100% { clip-path: inset(0 0 0 0); opacity: 0; } }
@keyframes va-exit-2 { 0%, 25% { clip-path: inset(0 100% 0 0); opacity: 1; } 31%, 96% { clip-path: inset(0 0 0 0); opacity: 1; } 100% { clip-path: inset(0 0 0 0); opacity: 0; } }
@keyframes va-exit-3 { 0%, 42% { clip-path: inset(0 100% 0 0); opacity: 1; } 48%, 96% { clip-path: inset(0 0 0 0); opacity: 1; } 100% { clip-path: inset(0 0 0 0); opacity: 0; } }
@keyframes va-exit-4 { 0%, 59% { clip-path: inset(0 100% 0 0); opacity: 1; } 65%, 96% { clip-path: inset(0 0 0 0); opacity: 1; } 100% { clip-path: inset(0 0 0 0); opacity: 0; } }
@keyframes va-exit-5 { 0%, 76% { clip-path: inset(0 100% 0 0); opacity: 1; } 82%, 96% { clip-path: inset(0 0 0 0); opacity: 1; } 100% { clip-path: inset(0 0 0 0); opacity: 0; } }
/* the finished stage shoots a small green orb down the connector to its gate.
   Transient, so a shared keyframe phase-shifted by animation-delay is fine. */
.va-stage-orb {
  opacity: 0;
  animation: va-stage-orb 14s linear infinite;
}
@keyframes va-stage-orb {
  0%, 11% { opacity: 0; transform: translateY(0); }
  12% { opacity: 1; transform: translateY(0); }      /* leaves the node */
  14% { opacity: 1; transform: translateY(38px); }   /* lands on the gate */
  16%, 100% { opacity: 0; transform: translateY(38px); }
}
/* the verification gates latch grey → green as the orb lands, then ease back to
   grey at the loop. Per-gate keyframes so they all reset together at 0%. */
.va-gate-1 { animation: va-gate-1 14s linear infinite; }
.va-gate-2 { animation: va-gate-2 14s linear infinite; }
.va-gate-3 { animation: va-gate-3 14s linear infinite; }
.va-gate-4 { animation: va-gate-4 14s linear infinite; }
.va-gate-5 { animation: va-gate-5 14s linear infinite; }
@keyframes va-gate-1 { 0%, 12% { color: #46555d; } 14%, 96% { color: #46c8af; } 100% { color: #46555d; } }
@keyframes va-gate-2 { 0%, 29% { color: #46555d; } 31%, 96% { color: #46c8af; } 100% { color: #46555d; } }
@keyframes va-gate-3 { 0%, 46% { color: #46555d; } 48%, 96% { color: #46c8af; } 100% { color: #46555d; } }
@keyframes va-gate-4 { 0%, 63% { color: #46555d; } 65%, 96% { color: #46c8af; } 100% { color: #46555d; } }
@keyframes va-gate-5 { 0%, 80% { color: #46555d; } 82%, 96% { color: #46c8af; } 100% { color: #46555d; } }
/* the verified-patch node at the very end: grey like an unverified gate until
   the bulge reaches it (~88%), then green — and it eases back to grey with the
   rest of the pipeline at the loop. */
.va-patch {
  color: #46c8af;
  animation: va-patch 14s linear infinite;
}
@keyframes va-patch {
  0%, 87% { color: #46555d; }
  89%, 96% { color: #46c8af; }
  100% { color: #46555d; }
}

@keyframes va-twinkle {
  0%,
  100% {
    opacity: 0.25;
  }
  50% {
    opacity: 0.95;
  }
}
@keyframes va-hotpulse {
  0%,
  100% {
    opacity: 0.55;
  }
  50% {
    opacity: 1;
  }
}
@keyframes va-medusa-drift {
  from {
    transform: translateY(-8px);
  }
  to {
    transform: translateY(10px);
  }
}
@keyframes va-drip-fall {
  to {
    stroke-dashoffset: -202;
  }
}
@keyframes va-core-pulse {
  0%,
  100% {
    opacity: 0.25;
    transform: scale(0.82);
  }
  50% {
    opacity: 0.85;
    transform: scale(1.18);
  }
}
@keyframes va-gust-run {
  0% {
    stroke-dashoffset: 0px;
    opacity: 0;
  }
  8% {
    opacity: var(--gop, 0.45);
  }
  55% {
    opacity: calc(var(--gop, 0.45) * 0.85);
  }
  85% {
    opacity: 0;
  }
  100% {
    stroke-dashoffset: var(--gtravel, -1600px);
    opacity: 0;
  }
}
@keyframes va-flow {
  to {
    stroke-dashoffset: -140;
  }
}
/* the slight continuous pitch keeps the mark's long vertical stems
   off the pixel grid — axis-aligned thin lines under a slow glide
   alternate crisp/soft ("blink") as the layer crosses pixel
   boundaries; a rotating line never has a crisp-aligned state */
@keyframes va-phish-glide {
  from {
    transform: translateX(-18px) translateY(4px) rotate(-0.45deg);
  }
  to {
    transform: translateX(12px) translateY(-7px) rotate(0.4deg);
  }
}
@keyframes va-kelp-sway {
  from {
    transform: rotate(-1.3deg);
  }
  to {
    transform: rotate(1.5deg);
  }
}
@keyframes va-pulse-rise {
  to {
    stroke-dashoffset: -240;
  }
}
@keyframes va-plankton-drift {
  from {
    transform: translate(0, 0) rotate(0deg);
  }
  to {
    transform: translate(-8px, -14px) rotate(9deg);
  }
}
@keyframes va-school-glide {
  from {
    transform: translate(0, 0);
  }
  to {
    transform: translate(-46px, 8px);
  }
}
@keyframes va-dart-bob {
  from {
    transform: translateY(-3px);
  }
  to {
    transform: translateY(3px);
  }
}
@keyframes va-naut-drift {
  from {
    transform: translate(0, -8px) rotate(-3deg);
  }
  to {
    transform: translate(10px, 8px) rotate(4deg);
  }
}
@keyframes va-ray-glide {
  from {
    transform: translate(0, 0);
  }
  to {
    transform: translate(-64px, 10px);
  }
}
/* wing flex: a hair of rotation about the body centreline reads as the
   pectoral wings beating slowly; the two wings rotate opposite ways */
@keyframes va-ray-flex {
  from {
    transform: rotate(-1.6deg);
  }
  to {
    transform: rotate(1.6deg);
  }
}
@keyframes va-ray-flex-b {
  from {
    transform: rotate(1.6deg);
  }
  to {
    transform: rotate(-1.6deg);
  }
}
@keyframes va-eel-sway {
  from {
    transform: rotate(-3.5deg);
  }
  to {
    transform: rotate(3.5deg) translateY(2px);
  }
}
@keyframes va-crab-scuttle {
  0%,
  12% {
    transform: translate(0, 0);
  }
  18% {
    transform: translate(9px, -1px);
  }
  24% {
    transform: translate(17px, 0);
  }
  30% {
    transform: translate(26px, -1px);
  }
  36%,
  60% {
    transform: translate(30px, 0);
  }
  66% {
    transform: translate(19px, -1px);
  }
  74% {
    transform: translate(8px, 0);
  }
  82%,
  100% {
    transform: translate(0, 0);
  }
}
@keyframes va-crab-step {
  from {
    transform: rotate(-2.2deg);
  }
  to {
    transform: rotate(2.2deg);
  }
}
@keyframes va-crab-wave {
  0%,
  36%,
  58%,
  100% {
    transform: rotate(0deg);
  }
  44% {
    transform: rotate(-9deg);
  }
  51% {
    transform: rotate(3deg);
  }
}
@keyframes va-mote-rise {
  0% {
    transform: translateY(0);
    opacity: 0;
  }
  12% {
    opacity: 0.55;
  }
  82% {
    opacity: 0.28;
  }
  100% {
    transform: translateY(-150px);
    opacity: 0;
  }
}
@keyframes va-blink {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.25;
  }
}
@keyframes va-isorot {
  from {
    transform: rotate(-0.09deg);
  }
  to {
    transform: rotate(0.1deg);
  }
}
/* opposite roll — the counter-band of the breathing chart */
@keyframes va-isorot-c {
  from {
    transform: rotate(0.1deg);
  }
  to {
    transform: rotate(-0.08deg);
  }
}
/* terminal caret: sharp on/off, not a half-faded pulse */
@keyframes va-caret-blink {
  0%,
  49.9% {
    opacity: 1;
  }
  50%,
  100% {
    opacity: 0;
  }
}

/* =====================================================================
   FORM (wired to main.ts — keep selectors stable)
   ===================================================================== */
.va-form label {
  display: block;
  font-family: "JetBrains Mono", monospace;
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink2);
  margin-bottom: 0.45rem;
}
.va-form input,
.va-form select {
  width: 100%;
  padding: 0.8rem 1rem;
  border-radius: 2px;
  border: 1px solid rgba(143, 217, 204, 0.3);
  background: rgba(234, 244, 242, 0.05);
  color: var(--va-light-ink);
  font-size: 0.95rem;
  transition: border-color 0.2s ease;
}
.va-form input::placeholder {
  color: rgba(234, 244, 242, 0.38);
}
.va-form input:focus,
.va-form select:focus {
  outline: none;
  border-color: var(--va-teal);
}
.va-form select option {
  background: #07192a;
  color: var(--va-light-ink);
}
/* Strip the native dropdown chrome and draw our own chevron so selects read
   as part of the survey-plate form (waitlist + schedule modal). */
.va-form select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding-right: 2.6rem;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2393b1bd' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.95rem center;
  background-size: 14px;
}
.va-form select:hover {
  border-color: rgba(70, 200, 175, 0.5);
}
.va-form button[type="submit"] {
  width: 100%;
  justify-content: center;
  padding: 1rem 1.5rem;
}
/* success state set by main.ts (inline bg #1F6B5E + .bg-green-500) —
   force a light label so it stays readable */
.va-form button[type="submit"].bg-green-500 {
  color: #f2f9f6 !important;
}
.va-form #beta-error {
  font-size: 0.85rem;
  color: #f2b8a4;
  border: 1px solid rgba(242, 184, 164, 0.35);
  border-radius: 2px;
  padding: 0.75rem;
  text-align: center;
}

/* =====================================================================
   REVEAL (driven by main.ts IntersectionObserver)
   ===================================================================== */
html[data-theme="abyss"] .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 0.7s ease,
    transform 0.7s ease;
}
html[data-theme="abyss"] .reveal.active {
  opacity: 1;
  transform: none;
}

/* parallax layers (page script writes --pp) */
.va-par {
  transform: translate3d(0, var(--pp, 0px), 0);
  will-change: transform;
}

/* =====================================================================
   NAVBAR — depth-adaptive instrument chrome.
   Ink mixes dark→light with --va-depth; the scrolled bar mixes a light
   surface frost into a hadal frost the same way, so contrast holds at
   every point of the descent.
     depth 0 : #0B2536 ink on rgba(242,246,246,.9)  ≈ 13:1
     depth 1 : #EAF4F2 ink on rgba(2,9,15,.9)        ≈ 16:1
   ===================================================================== */
html[data-theme="abyss"] #navbar {
  color: color-mix(
    in srgb,
    #eaf4f2 calc(var(--va-depth, 0) * 100%),
    #0b2536
  );
}
/* the white logo mark inks itself like the links: dark over the
   shallows, back to white once the thermocline has passed the bar */
html[data-theme="abyss"] #navbar img[alt="Artiphishell"] {
  filter: invert(calc((1 - var(--va-depth, 0)) * 0.93));
}
html[data-theme="abyss"] #navbar.va-nav-scrolled {
  /* frost follows the page's own ramp: surface paper → twilight
     (#15394E, what's behind the bar right after the band) → hadal
     near-black as --va-floor climbs through the deep zones */
  background: color-mix(
    in srgb,
    color-mix(
        in srgb,
        rgba(2, 7, 13, 0.92) calc(var(--va-floor, 0) * 100%),
        rgba(21, 57, 78, 0.9)
      )
      calc(var(--va-depth, 0) * 100%),
    rgba(242, 246, 246, 0.88)
  );
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid
    color-mix(
      in srgb,
      rgba(234, 244, 242, 0.16) calc(var(--va-depth, 0) * 100%),
      rgba(11, 37, 54, 0.16)
    );
}
html[data-theme="abyss"] #navbar a {
  color: color-mix(
    in srgb,
    color-mix(in srgb, #eaf4f2 calc(var(--va-depth, 0) * 100%), #0b2536) 74%,
    transparent
  );
}
html[data-theme="abyss"] #navbar a:hover,
html[data-theme="abyss"] #navbar .exp-nav-active {
  color: color-mix(in srgb, #eaf4f2 calc(var(--va-depth, 0) * 100%), #0b2536);
}
/* dropdown panel stays a dark instrument panel at any depth */
html[data-theme="abyss"] #navbar .group > div > div {
  background: #07131d !important;
  border-color: rgba(234, 244, 242, 0.12) !important;
  box-shadow: 0 24px 50px -30px rgba(0, 0, 0, 0.75) !important;
}
/* scope the light dropdown ink to the panel only — the "Products"
   trigger itself must follow the depth-adaptive bar ink */
html[data-theme="abyss"] #navbar .group div a {
  color: rgba(234, 244, 242, 0.75);
}
html[data-theme="abyss"] #navbar .group div a:hover {
  background: rgba(234, 244, 242, 0.06);
}
html[data-theme="abyss"] #navbar .group .text-white {
  color: #eaf4f2 !important;
}
html[data-theme="abyss"] #navbar .group .text-gray-400,
html[data-theme="abyss"] #navbar .group .text-gray-500 {
  color: #8da9b6 !important;
}
/* Join Beta pill flips with depth: dark pill at the surface, light in the deep */
html[data-theme="abyss"] #navbar .exp-nav-cta {
  background: color-mix(
    in srgb,
    #eaf4f2 calc(var(--va-depth, 0) * 100%),
    #0b2536
  );
  color: color-mix(
    in srgb,
    #04101a calc(var(--va-depth, 0) * 100%),
    #f2f6f6
  ) !important;
  border-radius: 2px;
}
html[data-theme="abyss"] #navbar .exp-nav-cta:hover {
  opacity: 0.9;
}
/* mobile menu follows the same descent */
html[data-theme="abyss"] #mobile-menu {
  /* match the navbar's depth-driven frost so the menu blends with the page
     behind it (paper at the surface → near-black in the deep). The blur is the
     key bit the old rule lacked — without it the busy page bled through. */
  background: color-mix(
    in srgb,
    color-mix(
        in srgb,
        rgba(2, 7, 13, 0.95) calc(var(--va-floor, 0) * 100%),
        rgba(21, 57, 78, 0.93)
      )
      calc(var(--va-depth, 0) * 100%),
    rgba(242, 246, 246, 0.94)
  );
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-top: 1px solid
    color-mix(
      in srgb,
      rgba(234, 244, 242, 0.16) calc(var(--va-depth, 0) * 100%),
      rgba(11, 37, 54, 0.16)
    );
}
html[data-theme="abyss"] #mobile-menu a {
  color: color-mix(
    in srgb,
    color-mix(in srgb, #eaf4f2 calc(var(--va-depth, 0) * 100%), #0b2536) 86%,
    transparent
  );
}
html[data-theme="abyss"] #mobile-menu a:hover {
  color: color-mix(in srgb, #eaf4f2 calc(var(--va-depth, 0) * 100%), #0b2536);
}
html[data-theme="abyss"] #mobile-menu .text-gray-400 {
  color: color-mix(
    in srgb,
    color-mix(in srgb, #eaf4f2 calc(var(--va-depth, 0) * 100%), #0b2536) 60%,
    transparent
  ) !important;
}
html[data-theme="abyss"] #mobile-menu .exp-nav-cta {
  /* a plain teal text link (not the desktop's solid button); colour follows the
     depth ramp so it stays legible on both the light surface and the dark deep */
  color: color-mix(in srgb, #46c8af calc(var(--va-depth, 0) * 100%), #0e6b5c) !important;
  font-weight: 600;
  background: none !important;
  border: none;
  padding: 0;
  border-radius: 0;
}

/* =====================================================================
   FOOTER — the floor of the trench
   ===================================================================== */
html[data-theme="abyss"] footer {
  background: #02070d;
  color: #eaf4f2;
  border-top: 1px solid rgba(234, 244, 242, 0.09);
}
html[data-theme="abyss"] footer .border-t {
  border-color: rgba(234, 244, 242, 0.09) !important;
}

/* =====================================================================
   ABYSS ATMOSPHERE — reusable inner-page backdrop (AbyssAtmosphere.astro)
   A fixed full-viewport deep wash with sparse stroke-only wireframe life
   in the margins. Sits behind content; never intercepts pointer events.
   Inner abyss pages render <AbyssAtmosphere/> once inside the slot; the
   layout's #main-content + footer establish their own stacking context
   above it. Motion reuses the .va-gust/.va-plankton/.va-mote/.va-school/
   .va-dart systems and is gated by the reduced-motion block below.
   ===================================================================== */
.va-atmos {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
/* lift real content above the backdrop without changing its flow.
   NOTE: do NOT include #navbar here — it is `position:fixed z-50` and
   must stay fixed; forcing position:relative unpins it (it scrolled
   away with the page). z-50 already sits above this z-1 content and
   the z-0 atmosphere. */
html[data-theme="abyss"] #main-content,
html[data-theme="abyss"] footer {
  position: relative;
  z-index: 1;
}
/* inner pages render <AbyssAtmosphere/>; let its fixed deep wash BE the
   page background so the wireframe life reads behind transparent
   sections (the homepage has no .va-atmos, so its per-section
   scrolling backgrounds are untouched). */
html[data-theme="abyss"]:has(.va-atmos) {
  background: #02070d;
}
html[data-theme="abyss"]:has(.va-atmos) .vz {
  background: transparent;
}
.va-atmos__wash {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    #15394e 0%,
    #0c2638 22%,
    #091a2a 52%,
    #040f1b 78%,
    #02070d 100%
  );
}
.va-atmos__top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 150px;
}
.va-atmos__top svg {
  display: block;
}
.va-atmos__currents {
  position: absolute;
  inset: 0;
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent,
    #000 14%,
    #000 86%,
    transparent
  );
  mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
}
.va-atmos__currents svg {
  display: block;
}
.va-atmos__plankton {
  position: absolute;
  top: 88px;
  left: 2%;
  width: 240px;
  height: 200px;
}
.va-atmos__specks {
  position: absolute;
  inset: 0;
}
.va-atmos__mote {
  position: absolute;
  border-radius: 50%;
  background: #8fd9cc;
}
.va-atmos__fish {
  position: absolute;
  top: 32%;
  right: 6%;
  width: 90px;
  height: 46px;
}
.va-atmos__floor {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 120px;
}
.va-atmos__floor svg {
  display: block;
}

/* =====================================================================
   RESPONSIVE / DEGRADE
   ===================================================================== */
@media (max-width: 768px) {
  .va-display {
    letter-spacing: -0.015em;
  }
  .va-art--side {
    opacity: 0.5;
  }
}

/* =====================================================================
   REDUCED MOTION — kill every continuous animation; parallax is also
   gated off in the page script.
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  html[data-theme="abyss"] {
    scroll-behavior: auto;
  }
  .va-vx,
  .va-vx--hot,
  .va-iso-a,
  .va-iso-b,
  .va-iso-c,
  .va-medusa,
  .va-drip,
  .va-phish,
  .va-kelp,
  .va-kelp-pulse,
  .va-mote,
  .va-plankton,
  .va-school,
  .va-dart,
  .va-nautilus,
  .va-ray,
  .va-ray-wing,
  .va-eel,
  .va-crab,
  .va-crab-legs,
  .va-crab-claw,
  .va-crab-drag,
  .va-core-halo,
  .va-gust,
  .va-signal,
  .va-ingest-dot,
  .va-exemplar,
  .va-fill,
  .va-stage-orb,
  .va-gate-1,
  .va-gate-2,
  .va-gate-3,
  .va-gate-4,
  .va-gate-5,
  .va-patch,
  .va-live__dot,
  .va-caret {
    animation: none !important;
  }
  .va-vx {
    opacity: 0.7;
  }
  .va-mote {
    opacity: 0.3;
  }
  .va-kelp-pulse {
    opacity: 0.4;
  }
  .va-drip {
    opacity: 0.35;
  }
  .va-core-halo {
    opacity: 0.55;
  }
  /* a few static streaks remain, parked mid-lane by --gs */
  .va-gust {
    opacity: 0.3;
  }
  /* tracers and riders vanish; the phish keeps its static glow */
  .va-tracer,
  .va-rider {
    display: none;
  }
  .va-caret {
    display: none;
  }
  .va-line {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .va-par {
    transform: none !important;
  }
  html[data-theme="abyss"] .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .va-btn {
    transition: none;
  }
}

/* =====================================================================
   ABYSS ATMOSPHERE — PER-VARIANT CREATURE PLACEMENT (append-only)
   Each variant lives in a margin/corner/deep-lower area, never behind
   body text, cards, forms, or the member grid. All are hidden below lg
   via the .hidden lg:block utility on the markup. Motion reuses the
   existing va-* keyframes (gated in the reduced-motion block above).
   ===================================================================== */

/* denser plankton drift — calmer "drift" (team) variant, upper-right */
.va-atmos__plankton2 {
  position: absolute;
  top: 120px;
  right: 2%;
  width: 200px;
  height: 240px;
}

/* drifting dart-fish school — reef/default, upper-right margin */
.va-atmos__school {
  position: absolute;
  top: 26%;
  right: 4%;
  width: 200px;
  height: 118px;
}

/* a single lone fish — current (blog) variant, right margin */
.va-atmos__lone {
  position: absolute;
  top: 30%;
  right: 5%;
  width: 90px;
  height: 72px;
}

/* chambered nautilus — engine (vcve) variant, left margin mid-depth */
.va-atmos__naut {
  position: absolute;
  top: 24%;
  left: 3%;
  width: 110px;
  height: 110px;
}

/* cable-eels — engine (vcve) variant, deep lower-left near the floor */
.va-atmos__eels {
  position: absolute;
  bottom: 132px;
  left: 3%;
  width: 152px;
  height: 80px;
}

/* serene jellyfish — drift (team) variant, left margin */
.va-atmos__jelly {
  position: absolute;
  top: 22%;
  left: 3%;
  width: 88px;
  height: 130px;
}

/* kelp frond — reef (products) variant, bottom-left corner above floor */
.va-atmos__kelp {
  position: absolute;
  bottom: 96px;
  left: 2%;
  width: 80px;
  height: 180px;
}


/* =====================================================================
   "5-step" pipeline steps — shared by the homepage how-it-works section
   and the vTriage product page. The desktop layout is a card grid; on
   mobile a VERTICAL pipeline runs down the right of the 5 stacked steps
   (hex nodes that verify orange→green reusing the va-enter-/va-exit-
   classes on the same 14s timeline, with the exemplar bulge flowing down).
   ===================================================================== */
.how-rail { display: none; }

@media (max-width: 767px) {
  .how-step { position: relative; padding-right: 3rem; }

  .how-rail {
    display: block;
    position: absolute;
    top: 0;
    right: 0.3rem;
    width: 1.8rem;
    bottom: calc(-1.5rem - 1px);
  }
  .how-step:last-child .how-rail { bottom: 0; }

  .how-rail::before {
    content: "";
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    top: 1.55rem;
    bottom: 0;
    width: 2.5px;
    border-radius: 2px;
    background: rgba(143, 217, 204, 0.18);
  }
  .how-step:last-child .how-rail::before { display: none; }

  .how-rail::after {
    content: "";
    position: absolute;
    left: 50%;
    margin-left: -4.5px;
    top: 1.55rem;
    width: 9px;
    height: 5px;
    border-radius: 3px;
    background: #e89b3c;
    box-shadow: 0 0 7px rgba(232, 155, 60, 0.55);
    opacity: 0;
    animation: how-exemplar 14s ease-in-out infinite;
    animation-delay: calc(var(--si, 0) * 2.38s);
  }
  .how-step:last-child .how-rail::after { display: none; }

  .how-rail__node {
    position: absolute;
    top: 0.2rem;
    left: 50%;
    transform: translateX(-50%);
    width: 1.7rem;
    height: 1.7rem;
    overflow: visible;
  }
  .how-rail__node .how-hex { fill: #0a1722; stroke: rgba(143, 217, 204, 0.5); stroke-width: 1; }
  .how-rail__node .how-hex-in { fill: none; stroke: rgba(143, 217, 204, 0.3); stroke-width: 0.7; }
  .how-rail__node .how-hex-num {
    fill: #c8d6dd;
    font-family: "JetBrains Mono", monospace;
    font-size: 8.5px;
    text-anchor: middle;
  }
}

@keyframes how-exemplar {
  0%, 2% { top: 1.55rem; opacity: 0; }
  4% { opacity: 1; }
  15% { top: calc(100% + 0.2rem); opacity: 1; }
  17%, 100% { top: calc(100% + 0.2rem); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .how-rail::after { display: none; }
}
