/* ============================================================
   KREWNIVERSE — style.css
   Design language: Kinetic Brutalism on a cosmic void.
   Pure #000 only. Spectral palette:
   yellow-green → blue-cyan → purple-magenta → red-orange.
   No gray backgrounds. No light mode.
   ============================================================ */

/* ---------- Design tokens ---------- */
:root {
  --void: #000000;

  /* Spectral palette, sampled from the galaxy fill of the logo */
  --lime:    #c6ff5e;
  --teal:    #35e0c9;
  --blue:    #4f7cff;
  --purple:  #b44cff;
  --magenta: #ff3d81;
  --orange:  #ff7a3d;

  --grad-spectral: linear-gradient(90deg,
    var(--lime), var(--teal), var(--blue),
    var(--purple), var(--magenta), var(--orange));

  /* Text ramp — all values verified ≥4.5:1 against #000 for body copy.
     (0.72 ≈ #B8B8B8 ≈ 8.0:1 · 0.60 ≈ #999999 ≈ 5.3:1) */
  --ink:       #ffffff;
  --ink-dim:   rgba(255, 255, 255, 0.72);
  --ink-mute:  rgba(255, 255, 255, 0.60);
  --hairline:  rgba(255, 255, 255, 0.12);

  --font-display: "Unbounded", system-ui, sans-serif;
  --font-body:    "Space Grotesk", system-ui, sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, monospace;

  /* Spacing scale (density 4/10 — marketing-page rhythm) */
  --space-xs: 8px;
  --space-sm: 16px;
  --space-md: 24px;
  --space-lg: 40px;
  --space-xl: 64px;
  --space-2xl: 96px;
  --space-3xl: 140px;

  --nav-h: 76px;
  --max-w: 1240px;
  --radius: 18px;

  /* Easing */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-io:  cubic-bezier(0.65, 0, 0.35, 1);
}

/* ---------- Reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--void);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }
h1, h2, h3 { font-family: var(--font-display); line-height: 1.06; margin: 0; }
a { color: inherit; }
button { font: inherit; }

::selection { background: var(--purple); color: var(--void); }

/* Visible focus for keyboard users on every interactive element */
:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 3px;
  border-radius: 6px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--void);
  border: 1px solid var(--teal);
  color: var(--ink);
  padding: 12px 20px;
  border-radius: 0 0 10px 0;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

/* ---------- Utilities ---------- */
.grad-text {
  background: var(--grad-spectral);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* Wide-tracked mono micro-label — the "technical precision" voice */
.micro-label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0;
}
.micro-label .dot {
  display: inline-block;
  width: 7px; height: 7px;
  margin-right: 10px;
  border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 0 10px var(--teal);
  vertical-align: middle;
  animation: pulse-dot 2.4s var(--ease-io) infinite;
}
@keyframes pulse-dot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.8); }
}

/* ---------- Background layers ---------- */

/* Static nebula gradient — pre-load backdrop and the permanent fallback
   for prefers-reduced-motion / no-WebGL visitors. */
.nebula-fallback {
  position: fixed;
  inset: 0;
  z-index: -3;
  /* Reads as a galactic band rather than scattered blobs: a sheared
     diagonal glow with emission clouds seated along it, matching the
     WebGL scene's composition so the fallback isn't a different sky. */
  background:
    radial-gradient(38% 26% at 30% 34%, rgba(198, 255, 94, 0.07), transparent 72%),
    radial-gradient(44% 30% at 68% 30%, rgba(53, 224, 201, 0.10), transparent 72%),
    radial-gradient(52% 34% at 78% 62%, rgba(180, 76, 255, 0.15), transparent 74%),
    radial-gradient(40% 26% at 24% 70%, rgba(255, 61, 129, 0.09), transparent 72%),
    radial-gradient(30% 20% at 88% 84%, rgba(255, 122, 61, 0.07), transparent 74%),
    linear-gradient(155deg,
      transparent 32%,
      rgba(79, 124, 255, 0.07) 44%,
      rgba(180, 76, 255, 0.09) 52%,
      rgba(53, 224, 201, 0.05) 60%,
      transparent 70%),
    var(--void);
}

/* WebGL canvas mount — fixed behind all content, fades in when ready */
#universe {
  position: fixed;
  inset: 0;
  z-index: -2;
  opacity: 0;
  transition: opacity 1.6s ease;
}

/* Sits between the canvas and the content. JS ramps its opacity as the
   hero scrolls away — see onScrollUI() in main.js. */
.void-scrim {
  position: fixed;
  inset: 0;
  z-index: -1;
  opacity: 0;
  pointer-events: none;
  /* Tuned to two competing needs: dark enough that body copy holds its
     contrast ratio, sheer enough that the 3D constructs still read. The
     column where copy lives gets the denser end of the gradient. */
  background: radial-gradient(130% 90% at 38% 45%,
    rgba(0, 0, 0, 0.86), rgba(0, 0, 0, 0.55) 78%);
}
#universe.is-live { opacity: 1; }
#universe canvas { display: block; width: 100%; height: 100%; }

/* Film grain — kills banding across large black fields */
.grain {
  position: fixed;
  inset: -50%;
  z-index: 0;
  pointer-events: none;
  opacity: 0.032;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain-shift 6s steps(6) infinite;
}
@keyframes grain-shift {
  0%   { transform: translate(0, 0); }
  20%  { transform: translate(-3%, 2%); }
  40%  { transform: translate(2%, -3%); }
  60%  { transform: translate(-2%, -2%); }
  80%  { transform: translate(3%, 3%); }
  100% { transform: translate(0, 0); }
}

/* Scroll progress hairline */
.scroll-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 90;
  pointer-events: none;
}
.scroll-progress span {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--grad-spectral);
  box-shadow: 0 0 12px rgba(180, 76, 255, 0.7);
}

/* ---------- Cursor motion effect (desktop only, enabled by JS) ----------
   A stardust trail on canvas plus a ring that stretches along its
   direction of travel — the faster the pointer moves, the more it
   elongates, like a body under acceleration. */

.cursor-trail {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 94;
  opacity: 0;
  transition: opacity 0.4s ease;
}
.cursor-trail.is-on { opacity: 1; }

.cursor-ring {
  position: fixed;
  top: 0; left: 0;
  width: 34px; height: 34px;
  margin: -17px 0 0 -17px;
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: 50%;
  pointer-events: none;
  z-index: 95;
  opacity: 0;
  /* `transform` is written every frame by JS (position + velocity
     stretch), so it must NOT be transitioned — a transition here would
     fight the rAF loop and smear the ring. Only the hover swell, which
     JS does not touch, is animated. */
  transition: opacity 0.3s ease, width 0.25s var(--ease-out),
              height 0.25s var(--ease-out), margin 0.25s var(--ease-out),
              border-color 0.25s ease, background 0.25s ease;
}
/* The ring stays invisible while travelling — the comet head is the
   cursor. It only appears over interactive targets, where it earns its
   keep as an affordance rather than competing with the comet. */
.cursor-ring.is-hot {
  opacity: 1;
  width: 58px; height: 58px;
  margin: -29px 0 0 -29px;
  border-color: var(--teal);
  background: rgba(53, 224, 201, 0.1);
}

/* Gate the cursor effect on pointer type, not viewport width. main.js
   gates on `(pointer: fine)`, so a width breakpoint here would disagree
   with it — a narrow desktop window would run the whole particle loop
   against an element CSS had hidden. */
@media (hover: none), (pointer: coarse) {
  .cursor-ring,
  .cursor-trail { display: none; }
}

/* Page content sits above the grain layer purely by DOM order.
   Critically, `main` must NOT get a z-index — that would create a
   stacking context and cut the logo's `mix-blend-mode: screen` off
   from the WebGL canvas behind it, turning the JPG into a black box. */
main, .footer { position: relative; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 44px;            /* touch target floor */
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.9rem;
  text-decoration: none;
  border-radius: 999px;
  padding: 0.85em 1.9em;
  cursor: pointer;
  position: relative;
  transition: transform 0.25s var(--ease-out), box-shadow 0.25s ease, color 0.2s ease;
}

/* Primary CTA — spectral border ring + glow bloom on hover */
.btn--primary {
  color: var(--ink);
  background:
    linear-gradient(var(--void), var(--void)) padding-box,
    var(--grad-spectral) border-box;
  border: 2px solid transparent;
}
.btn--primary::after {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  background: var(--grad-spectral);
  opacity: 0;
  filter: blur(16px);
  z-index: -1;
  transition: opacity 0.3s ease;
}
.btn--primary:hover,
.btn--primary:focus-visible {
  transform: translateY(-2px);
  box-shadow:
    0 0 18px rgba(180, 76, 255, 0.5),
    0 0 44px rgba(53, 224, 201, 0.3);
}
.btn--primary:hover::after { opacity: 0.55; }
.btn--primary:active { transform: translateY(0); }

/* Circular icon CTA (hero secondary) */
.btn--circle {
  padding: 0;
  border-radius: 999px;
  color: var(--ink-dim);
  background: transparent;
  border: 0;
  gap: 14px;
}
.btn--circle svg {
  width: 46px; height: 46px;
  flex: none;
  padding: 13px;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  transition: transform 0.35s var(--ease-out), border-color 0.25s ease,
              background 0.25s ease, color 0.25s ease;
}
.btn--circle span {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.btn--circle:hover svg,
.btn--circle:focus-visible svg {
  transform: rotate(45deg);
  border-color: var(--teal);
  background: rgba(53, 224, 201, 0.1);
  color: var(--teal);
}
.btn--circle:hover { color: var(--ink); }

.btn--lg { font-size: 0.98rem; padding: 1.05em 2.3em; }
.btn--xl { font-size: 1.1rem;  padding: 1.15em 2.8em; }

/* ---------- Navbar ---------- */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  transition: background 0.35s ease, backdrop-filter 0.35s ease, border-color 0.35s ease;
  border-bottom: 1px solid transparent;
}
.nav.is-scrolled {
  background: rgba(0, 0, 0, 0.68);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  border-bottom-color: var(--hairline);
}

.nav__inner {
  max-width: var(--max-w);
  margin: 0 auto;
  height: var(--nav-h);
  padding: 0 var(--space-md);
  display: flex;
  align-items: center;
  gap: var(--space-lg);
}

.nav__brand {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;          /* touch target floor */
  text-decoration: none;
  flex: none;
}
.nav__brand img {
  height: 38px;
  width: auto;
  mix-blend-mode: screen;   /* melts the JPG's black into the void */
  transition: filter 0.3s ease;
}
.nav__brand:hover img { filter: drop-shadow(0 0 12px rgba(180, 76, 255, 0.85)); }
.nav__brand-word {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.14em;
}

.nav__menu {
  display: flex;
  gap: var(--space-lg);
  list-style: none;
  margin: 0 auto;
  padding: 0;
}
.nav__menu a {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  min-height: 44px;
  align-content: center;
  text-decoration: none;
  color: var(--ink-dim);
  font-size: 0.92rem;
  font-weight: 500;
  transition: color 0.2s ease;
}
.nav__idx {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  color: var(--teal);
  opacity: 0.75;
}
.nav__menu a:hover, .nav__menu a:focus-visible { color: var(--ink); }

.nav__cta { white-space: nowrap; flex: none; }

/* Burger */
.nav__toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  width: 44px; height: 44px;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0;
}
.nav__toggle span {
  width: 24px; height: 2px;
  background: var(--ink);
  margin-left: auto; margin-right: auto;
  transition: transform 0.3s var(--ease-out), opacity 0.3s ease;
}
.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(4px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { transform: translateY(-4px) rotate(-45deg); }

/* ---------- Hero ---------- */
.hero {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: calc(var(--nav-h) + var(--space-lg)) var(--space-md) var(--space-xl);
  text-align: center;
  position: relative;
}
/* The hero's layers tilt as real planes in space, driven by --rx/--ry
   which JS updates from the cursor. Each layer carries its OWN
   perspective() inside its transform rather than inheriting one from a
   parent: `perspective` on an ancestor would create a stacking context
   and cut the lockup's screen blend off from the canvas, turning the
   logo back into a black rectangle. */
.hero__inner {
  max-width: 1140px;
  width: 100%;
  --rx: 0deg;
  --ry: 0deg;
}

.hero__lockup {
  width: min(210px, 46vw);
  margin: 0 auto var(--space-sm);
  mix-blend-mode: screen;   /* melts the JPG's black into the starfield */
  /* Nearest layer, so it swings widest */
  transform: perspective(1100px) rotateX(var(--rx)) rotateY(var(--ry)) translateZ(60px);
  transition: transform 0.35s var(--ease-out);
}
.hero__title {
  transform: perspective(1400px) rotateX(calc(var(--rx) * 0.55))
             rotateY(calc(var(--ry) * 0.55)) translateZ(30px);
  transition: transform 0.45s var(--ease-out);
}
.hero__sub,
.hero__actions {
  transform: perspective(1600px) rotateX(calc(var(--rx) * 0.3))
             rotateY(calc(var(--ry) * 0.3)) translateZ(12px);
  transition: transform 0.55s var(--ease-out);
}

.hero__eyebrow { margin-bottom: var(--space-sm); }

/* Kinetic display lockup: solid line over outlined line.
   Capped so the sub-headline and CTA stay above the fold at 900px tall. */
.hero__title {
  /* Capped so "breaks the scroll" holds one line and the CTA stays
     above the fold on a 900px-tall viewport. */
  font-size: clamp(2rem, 5.4vw, 4.5rem);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.035em;
  margin-bottom: var(--space-md);
}
.line { display: block; }

.line--solid { color: var(--ink); }

/* Smaller closing beat under two oversized lines */
.line--sm { font-size: 0.5em; margin-top: 0.18em; }

/* Outline line — the pattern-interruption moment: hollow letterforms that
   flood with the spectral gradient. Resting state is FLOODED so that with
   JS off (no .js-anim) the headline still reads in full brand colour; the
   animation below only adds the hollow-to-flood transition on top. */
.line--outline {
  color: transparent;
  -webkit-text-stroke: 1.5px transparent;
  position: relative;
}
.line--outline::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  background: var(--grad-spectral);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  pointer-events: none;
}

.hero__sub {
  font-size: clamp(1.02rem, 1.7vw, 1.24rem);
  color: var(--ink-dim);
  max-width: 620px;
  margin: 0 auto var(--space-lg);
}

.hero__actions {
  display: flex;
  gap: var(--space-md);
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}

.hero__scroll-hint {
  position: absolute;
  bottom: var(--space-md);
  left: 50%;
  transform: translateX(-50%);
  padding-bottom: 26px;
}
.hero__scroll-hint::after {
  content: "";
  position: absolute;
  bottom: 0; left: 50%;
  width: 1px; height: 18px;
  background: linear-gradient(var(--teal), transparent);
  animation: hint-drop 2s var(--ease-io) infinite;
}
@keyframes hint-drop {
  0%, 100% { opacity: 0.25; transform: translateY(0); }
  50%      { opacity: 1;    transform: translateY(6px); }
}

/* ---------- Marquee band ---------- */
.marquee {
  overflow: hidden;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  padding: var(--space-md) 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  position: relative;
  z-index: 1;
  /* Fade the ends so the loop seam never shows */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.marquee__track {
  display: flex;
  width: max-content;
  animation: marquee 34s linear infinite;
}
.marquee__set {
  display: flex;
  align-items: center;
  flex: none;
}
.marquee__set b {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.1rem, 2.6vw, 1.9rem);
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--ink);
  white-space: nowrap;
}
/* Diamond separator — drawn in CSS, not an emoji */
.marquee__set i {
  width: 9px; height: 9px;
  margin: 0 clamp(20px, 3.4vw, 46px);
  flex: none;
  transform: rotate(45deg);
  background: var(--grad-spectral);
}
@keyframes marquee { to { transform: translateX(-50%); } }
.marquee:hover .marquee__track { animation-play-state: paused; }

/* ---------- Section scaffolding ---------- */
.section {
  position: relative;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: var(--space-3xl) var(--space-md);
}

.section__head { max-width: 800px; margin-bottom: var(--space-2xl); }

.section__index {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: var(--space-md);
}
.section__index span {
  color: var(--teal);
  padding-right: 12px;
  border-right: 1px solid var(--hairline);
}

.section__title {
  font-size: clamp(2rem, 6vw, 4.2rem);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.03em;
}

.section__sub {
  color: var(--ink-dim);
  font-size: 1.08rem;
  margin: var(--space-md) 0 0;
  max-width: 620px;
}

/* ---------- Services (horizontal snap track) ---------- */
.services__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(310px, 350px);
  gap: var(--space-md);
  overflow-x: auto;
  padding: 6px 4px var(--space-md);
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
  scrollbar-color: rgba(180, 76, 255, 0.5) transparent;
}
.services__track::-webkit-scrollbar { height: 5px; }
.services__track::-webkit-scrollbar-track { background: rgba(255,255,255,0.05); border-radius: 3px; }
.services__track::-webkit-scrollbar-thumb {
  background: linear-gradient(90deg, var(--teal), var(--purple));
  border-radius: 3px;
}

.services__hint { text-align: right; margin-top: var(--space-xs); }

.card {
  scroll-snap-align: start;
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius);
  padding: var(--space-md) var(--space-md) var(--space-md);
  overflow: hidden;
  background:
    linear-gradient(rgba(0,0,0,0.9), rgba(0,0,0,0.9)) padding-box,
    linear-gradient(155deg, var(--c1), transparent 48%, var(--c2)) border-box;
  border: 1px solid transparent;
  transition: transform 0.35s var(--ease-out), box-shadow 0.35s ease;
}
/* Spectral wash floods up from the bottom edge on hover */
.card::before {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 55%;
  background: linear-gradient(to top,
    color-mix(in srgb, var(--c1) 16%, transparent), transparent);
  opacity: 0;
  transition: opacity 0.4s ease;
  z-index: -1;
}
.card:hover::before, .card:focus-within::before { opacity: 1; }
.card:hover, .card:focus-within {
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--c1) 40%, transparent),
    0 18px 50px color-mix(in srgb, var(--c1) 16%, transparent);
}

/* Card interiors lift on separate planes when the card tilts, so it
   reads as a volume with layers inside rather than a flat panel. */
.card__top,
.card__title,
.card__tag,
.card__link {
  transition: transform 0.4s var(--ease-out);
}
.card:hover .card__top   { transform: translateZ(40px); }
.card:hover .card__title { transform: translateZ(28px); }
.card:hover .card__tag   { transform: translateZ(20px); }
.card:hover .card__link  { transform: translateZ(26px); }

.card__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: var(--space-md);
}
.card__num {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.2em;
  color: var(--c1);
}
.card__icon {
  width: 42px; height: 42px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  border: 1px solid var(--hairline);
  color: var(--c1);
  transition: border-color 0.3s ease, background 0.3s ease, transform 0.35s var(--ease-out);
}
.card__icon svg { width: 21px; height: 21px; }
.card:hover .card__icon {
  border-color: color-mix(in srgb, var(--c1) 55%, transparent);
  background: color-mix(in srgb, var(--c1) 10%, transparent);
  transform: translateY(-2px);
}

.card__title {
  font-size: 1.22rem;
  font-weight: 700;
  line-height: 1.25;
  margin-bottom: var(--space-xs);
}
.card__tag {
  color: var(--c1);
  font-weight: 700;
  font-size: 0.9rem;
  margin: 0 0 12px;
}
.card__body {
  color: var(--ink-dim);
  font-size: 0.96rem;
  margin: 0 0 var(--space-md);
  flex: 1;
}
.card__link {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: 44px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  transition: color 0.2s ease, gap 0.25s var(--ease-out);
}
.card__link svg { width: 16px; height: 16px; }
.card__link:hover, .card__link:focus-visible { color: var(--c1); gap: 15px; }

/* ---------- Process ---------- */
.process__orbit { margin: calc(var(--space-xl) * -1) 0 var(--space-lg); }
.process__orbit svg { width: 100%; height: clamp(140px, 22vw, 250px); display: block; }
.orbit-node { filter: drop-shadow(0 0 9px currentColor); }
/* JS sets the dash values for the scroll-scrubbed draw-in */
.orbit-path { stroke-dasharray: 4 7; animation: orbit-dash 26s linear infinite; }
@keyframes orbit-dash { to { stroke-dashoffset: -800; } }

.process__steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-lg) var(--space-md);
}
.step {
  border-top: 2px solid var(--step);
  padding-top: var(--space-md);
  position: relative;
}
.step::before {
  content: "";
  position: absolute;
  top: -2px; left: 0;
  width: 0; height: 2px;
  background: var(--ink);
  transition: width 0.5s var(--ease-out);
}
.step:hover::before { width: 100%; }
.step__num {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.2em;
  color: var(--step);
}
.step__title {
  font-size: 1.28rem;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  margin: 10px 0 var(--space-xs);
}
.step p { color: var(--ink-dim); font-size: 0.95rem; margin: 0; }

/* ---------- Results ---------- */
.results__metrics {
  display: grid;
  /* Explicit 2-up / 4-up rather than auto-fit: auto-fit lands on 3
     columns at mid widths and leaves a visibly empty fourth cell. */
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--hairline);      /* hairline grid via gap */
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  overflow: hidden;
}
.metric {
  text-align: center;
  padding: var(--space-lg) var(--space-sm);
  background: rgba(0, 0, 0, 0.86);
  transition: background 0.35s ease, transform 0.35s var(--ease-out);
  transform-style: preserve-3d;
}
.metric:hover { background: rgba(255, 255, 255, 0.03); }
.metric__value {
  display: block;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(2.3rem, 5vw, 3.4rem);
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;  /* stops width jitter while counting */
  background: var(--grad-spectral);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.metric__label {
  display: block;
  margin-top: 10px;
  color: var(--ink-mute);
  font-size: 0.88rem;
  line-height: 1.45;
}

/* ---------- About / Philosophy ---------- */
.about__manifesto {
  max-width: 760px;
  columns: 1;
}
.about__manifesto p {
  color: var(--ink-dim);
  font-size: clamp(1.03rem, 1.6vw, 1.18rem);
  margin: 0 0 var(--space-md);
}
.about__manifesto em { color: var(--ink); font-style: normal; font-weight: 700; }

.about__vow {
  margin: var(--space-xl) 0 0;
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  font-size: clamp(1.4rem, 4vw, 2.8rem);
  background: var(--grad-spectral);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ---------- Final CTA ---------- */
.final-cta {
  text-align: center;
  padding-top: var(--space-3xl);
  padding-bottom: calc(var(--space-3xl) + 40px);
}
.final-cta__title {
  font-size: clamp(2.2rem, 8vw, 5.6rem);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: -0.035em;
  margin-bottom: var(--space-md);
}
.final-cta__sub {
  color: var(--ink-dim);
  max-width: 560px;
  margin: 0 auto var(--space-lg);
  font-size: 1.1rem;
}
.final-cta__micro { margin-top: var(--space-md); }

/* ---------- Footer ---------- */
.footer {
  border-top: 1px solid var(--hairline);
  background: var(--void);
}
.footer__inner {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: var(--space-xl) var(--space-md) var(--space-lg);
}
.footer__brand { display: block; text-decoration: none; }
.footer__lockup {
  width: min(230px, 55vw);
  margin: 0 0 var(--space-lg);
  mix-blend-mode: screen;
}
.footer__cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--space-lg);
  padding-bottom: var(--space-lg);
  border-bottom: 1px solid var(--hairline);
}
.footer__col { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.footer__col .micro-label { margin-bottom: 12px; color: var(--teal); }
.footer__col a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;          /* touch target floor */
  color: var(--ink-dim);
  text-decoration: none;
  font-size: 0.95rem;
  transition: color 0.2s ease;
}
.footer__col a:hover { color: var(--ink); }
.footer__col--cta .btn { margin-top: 4px; }

.footer__legal {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-xs);
  color: var(--ink-mute);
  font-size: 0.82rem;
  margin: var(--space-md) 0 0;
}
.footer__tagline { font-family: var(--font-mono); letter-spacing: 0.1em; }

/* ---------- Floating sticky CTA ---------- */
.sticky-cta {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 0.85em 1.6em;
  border-radius: 999px;
  border: 2px solid transparent;
  background:
    linear-gradient(var(--void), var(--void)) padding-box,
    var(--grad-spectral) border-box;
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.82rem;
  text-decoration: none;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transform: translateY(14px) scale(0.96);
  transition: opacity 0.35s ease, transform 0.35s var(--ease-out), box-shadow 0.25s ease;
}
.sticky-cta.is-visible { opacity: 1; pointer-events: auto; transform: none; }
.sticky-cta:hover { box-shadow: 0 0 22px rgba(180, 76, 255, 0.55), 0 0 50px rgba(53,224,201,0.3); }
.sticky-cta__pulse {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--lime);
  box-shadow: 0 0 10px var(--lime);
  animation: pulse-dot 2.4s var(--ease-io) infinite;
}

/* ---------- Scroll reveal ----------
   Only hides content when JS is active, so no-JS visitors and
   crawlers always receive fully visible markup. */
.js-anim .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.75s var(--ease-out), transform 0.75s var(--ease-out);
}
.js-anim .reveal.is-visible { opacity: 1; transform: none; }

/* ---------- Hero entrance ----------
   Deliberately CSS, not GSAP. The hero is the above-the-fold value
   proposition and must be readable within 3s on every device. CSS
   animations are driven by the compositor's own timeline, so they still
   complete when requestAnimationFrame is throttled (backgrounded tab,
   starved GPU) — which would otherwise freeze a JS tween mid-stagger
   and leave the headline invisible. GSAP keeps the scroll choreography,
   where a dropped frame costs nothing. */
.char { display: inline-block; will-change: transform, opacity; }

/* These animate the independent `translate` property, not `transform`.
   The hero layers use `transform` for their cursor tilt, and an
   animation with fill-mode `both` would otherwise hold `transform: none`
   forever after finishing and cancel the tilt outright. */
@keyframes char-rise {
  from { opacity: 0; translate: 0 0.45em; }
  to   { opacity: 1; translate: 0 0; }
}
@keyframes rise-in {
  from { opacity: 0; translate: 0 18px; }
  to   { opacity: 1; translate: 0 0; }
}
/* Hollow → flooded, timed to land just after the characters finish rising */
@keyframes flood-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes stroke-fade {
  from { -webkit-text-stroke-color: rgba(255, 255, 255, 0.5); }
  to   { -webkit-text-stroke-color: rgba(255, 255, 255, 0); }
}
.js-anim .line--outline        { animation: stroke-fade 0.9s var(--ease-out) both; animation-delay: 1.15s; }
.js-anim .line--outline::after { animation: flood-in   0.9s var(--ease-out) both; animation-delay: 1.15s; }

.js-anim .hero__title .char {
  animation: char-rise 0.55s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 22ms);
}
.js-anim .hero__eyebrow { animation: rise-in 0.6s var(--ease-out) both; animation-delay: 0.05s; }
.js-anim .hero__sub     { animation: rise-in 0.6s var(--ease-out) both; animation-delay: 0.95s; }
.js-anim .hero__actions { animation: rise-in 0.6s var(--ease-out) both; animation-delay: 1.1s; }

/* ---------- Responsive: 1024 / 768 / 375 ---------- */
@media (min-width: 900px) {
  .results__metrics { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 1024px) {
  :root { --space-3xl: 110px; --space-2xl: 76px; }
  .nav__menu { gap: var(--space-md); }
}

@media (max-width: 860px) {
  .nav__toggle { display: flex; margin-left: auto; }
  .nav__cta { display: none; }          /* floating sticky CTA covers mobile */
  .nav__brand-word { display: none; }

  .nav__menu {
    position: fixed;
    top: var(--nav-h);
    left: 0; right: 0;
    flex-direction: column;
    align-items: center;
    gap: 0;
    margin: 0;
    padding: var(--space-md) 0 var(--space-lg);
    background: rgba(0, 0, 0, 0.96);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    border-bottom: 1px solid var(--hairline);
    transform: translateY(-140%);
    transition: transform 0.4s var(--ease-out);
  }
  .nav__menu.is-open { transform: translateY(0); }
  .nav__menu a { font-size: 1.1rem; min-height: 52px; }

  .section { padding: var(--space-2xl) var(--space-md); }
  .services__track { grid-auto-columns: 84vw; }
  .process__orbit { margin-top: calc(var(--space-lg) * -1); }
  .footer__legal { flex-direction: column; }
}

@media (max-width: 420px) {
  :root { --space-3xl: 84px; --space-2xl: 64px; --space-md: 20px; }
  body { font-size: 16px; }
  .hero__lockup { width: 66vw; }
  .services__track { grid-auto-columns: 88vw; }
  .sticky-cta { right: 12px; bottom: 12px; font-size: 0.78rem; }
  .marquee__set b { font-size: 1.05rem; }
}

/* ---------- Reduced motion: static nebula fallback ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  /* The 3D scene never initializes (main.js checks the same query);
     the static nebula gradient stays as the permanent backdrop. */
  #universe { display: none; }
  .grain { display: none; }
  .marquee__track { animation: none; transform: none; }

  /* Everything visible, nothing animated in */
  .js-anim .reveal,
  .js-anim .hero__title .char {
    opacity: 1 !important;
    transform: none !important;
    translate: none !important;
  }

  /* No cursor-driven 3D tilt — flatten every parallax plane */
  .hero__lockup, .hero__title, .hero__sub, .hero__actions,
  .card:hover .card__top, .card:hover .card__title,
  .card:hover .card__tag, .card:hover .card__link {
    transform: none !important;
  }
  .line--outline.is-flooded::after { opacity: 1; }
}
