/* ==========================================================================
   Black Raven design system.
   Pure black base. Color behaves as emitted light, never as a large fill:
   every accent is either a hairline rule, an 11px label, a focus ring, or a
   plus-lighter glow. Body text stays neutral so the black survives.
   Zero dependencies, zero build step, no inline styles (strict CSP).
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Fonts. Self-hosted latin subsets, so the CSP needs no Google Fonts host.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Space Grotesk';
  src: url('../fonts/space-grotesk-var-latin.woff2') format('woff2-variations');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Space Mono';
  src: url('../fonts/space-mono-400-latin.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Space Mono';
  src: url('../fonts/space-mono-700-latin.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   2. Registered custom properties. Only registered properties can be
      animated by the compositor, which is what makes the rotating conic and
      the glow ramps pure CSS instead of a rAF loop.
   -------------------------------------------------------------------------- */

@property --brv-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}
@property --brv-bloom {
  syntax: '<number>';
  initial-value: 0;
  inherits: false;
}

/* --------------------------------------------------------------------------
   3. Tokens.
   -------------------------------------------------------------------------- */

:root {
  --bg: #000000;
  --surface: rgba(255, 255, 255, 0.035);
  --surface-2: rgba(255, 255, 255, 0.06);
  --border: rgba(255, 255, 255, 0.09);
  --border-strong: rgba(255, 255, 255, 0.18);
  --text: #ededE8;
  --muted: #7a7d78;
  --dim: #4d504b;

  /* Product channels. Each pillar owns exactly one hue. */
  --ch-platform: #21b8cd;   /* Raven CRM */
  --ch-agents: #8b5cf6;     /* AI Agents */
  --ch-soc: #ffb020;        /* Agentic SOC */
  --ch-build: #ff5c7a;      /* Applied Engineering */
  --ch-live: #00ff41;       /* status signal only, never decorative */

  /* Section-local accent. Every component reads this, so a pillar recolors
     itself by setting one property on its wrapper. */
  --accent: var(--ch-platform);
  --glow: color-mix(in oklab, var(--accent) 34%, transparent);
  --rail: color-mix(in oklab, var(--accent) 22%, transparent);
  --wash: color-mix(in oklab, var(--accent) 9%, transparent);

  --font-display: 'Space Grotesk', 'Space Mono', system-ui, sans-serif;
  --font-body: 'Space Mono', ui-monospace, monospace;

  --shell: 1240px;
  --gutter: clamp(20px, 5vw, 48px);
  --band: clamp(72px, 11vh, 140px);
  --radius: 3px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  color-scheme: dark;
}

.ch-platform { --accent: var(--ch-platform); }
.ch-agents   { --accent: var(--ch-agents); }
.ch-soc      { --accent: var(--ch-soc); }
.ch-build    { --accent: var(--ch-build); }
.ch-managed  { --accent: #cfd2cc; }

/* --------------------------------------------------------------------------
   4. Base.
   -------------------------------------------------------------------------- */

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

html {
  background: var(--bg);
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  overflow-x: clip;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.65;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 0.98;
  margin: 0;
  text-wrap: balance;
}

h1 { font-size: clamp(2.6rem, 7.4vw, 5.4rem); }
h2 { font-size: clamp(2rem, 4.6vw, 3.4rem); }
h3 { font-size: clamp(1.15rem, 1.9vw, 1.45rem); letter-spacing: -0.02em; }

p { margin: 0; max-width: 62ch; }

a { color: inherit; text-decoration: none; }

img, video, canvas { display: block; max-width: 100%; }

::selection { background: var(--accent); color: #000; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.band { padding-block: var(--band); position: relative; }
.band-tight { padding-top: 0; }
.span-all { grid-column: 1 / -1; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   5. Grain. Non-negotiable on a black site: without it every large dark
      gradient bands visibly on OLED. Stepped background-position gives film
      grain without re-rasterizing the SVG filter each frame.
   -------------------------------------------------------------------------- */

.grain {
  position: fixed;
  inset: -120px;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain-shift 900ms steps(1) infinite;
}

@keyframes grain-shift {
  0%   { transform: translate3d(0, 0, 0); }
  20%  { transform: translate3d(-30px, 18px, 0); }
  40%  { transform: translate3d(22px, -26px, 0); }
  60%  { transform: translate3d(-14px, -12px, 0); }
  80%  { transform: translate3d(28px, 20px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* --------------------------------------------------------------------------
   6. Aurora. Four channel-colored radials, blurred and drifting. Rendered at
      quarter size and scaled back up so the blur runs over one sixteenth of
      the pixels: same look, a fraction of the fill rate.
   -------------------------------------------------------------------------- */

.aurora {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
  isolation: isolate;
  mask-image: linear-gradient(to bottom, #000 55%, transparent 100%);
}

.aurora::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 25%; height: 25%;
  transform-origin: 0 0;
  transform: scale(4);
  filter: blur(58px);
  mix-blend-mode: plus-lighter;
  background:
    radial-gradient(40% 46% at 20% 26%, color-mix(in oklab, var(--ch-platform) 92%, transparent), transparent 70%),
    radial-gradient(36% 42% at 76% 18%, color-mix(in oklab, var(--ch-agents) 88%, transparent), transparent 68%),
    radial-gradient(32% 38% at 58% 78%, color-mix(in oklab, var(--ch-soc) 55%, transparent), transparent 66%),
    radial-gradient(28% 34% at 10% 82%, color-mix(in oklab, var(--ch-build) 48%, transparent), transparent 64%);
  opacity: 0.5;
  animation: aurora-drift 34s ease-in-out infinite alternate;
}

/* Second, slower layer so the field never reads as a single moving blob. */
.aurora::after {
  content: '';
  position: absolute;
  inset: -20%;
  mix-blend-mode: plus-lighter;
  opacity: 0.5;
  background: conic-gradient(
    from var(--brv-angle),
    transparent 0deg,
    color-mix(in oklab, var(--ch-agents) 15%, transparent) 70deg,
    transparent 150deg,
    color-mix(in oklab, var(--ch-platform) 15%, transparent) 250deg,
    transparent 360deg
  );
  filter: blur(90px);
  animation: aurora-spin 60s linear infinite;
}

/* Core bloom directly behind the headline. Additive, so the falloff resolves
   to exactly #000 and the page still reads as pure black. */
.hero::before {
  content: '';
  position: absolute;
  inset: -30% 30% 10% -25%;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(closest-side,
    color-mix(in oklab, var(--ch-agents) 30%, transparent),
    transparent 72%);
  mix-blend-mode: plus-lighter;
  filter: blur(50px);
}

@keyframes aurora-drift {
  0%   { transform: scale(4) translate(0, 0); }
  50%  { transform: scale(4.25) translate(-2.2%, 1.6%); }
  100% { transform: scale(4) translate(1.8%, -1.4%); }
}

@keyframes aurora-spin {
  to { --brv-angle: 360deg; }
}

/* Hairline field. Sits under the aurora, reads as instrumentation. */
.mesh {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0.045) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.045) 1px, transparent 1px);
  background-size: 72px 72px;
  mask-image: radial-gradient(120% 80% at 50% 0%, #000 10%, transparent 72%);
}

/* Cursor tracer. --mx / --my are written from JS via setProperty, which CSP
   does not govern, so this needs no style-src exception.
   Not a soft spotlight: hairline crosshairs in the section's channel color
   meeting at the cursor, with a small additive node at the intersection. It
   reads as a targeting reticle on the instrument panel, and each pillar
   section recolors it through --accent. */
.spotlight {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 500ms var(--ease);
  /* The intersection node. Additive, so pure black survives outside it. */
  background: radial-gradient(
    70px circle at var(--mx, 50%) var(--my, 40%),
    color-mix(in oklab, var(--accent) 26%, transparent),
    transparent 65%
  );
  mix-blend-mode: plus-lighter;
}

/* Horizontal hairline. Brightest near the cursor, dissolving outward. */
.spotlight::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: var(--my, 50%);
  height: 1px;
  background: color-mix(in oklab, var(--accent) 60%, transparent);
  mask-image: radial-gradient(280px 1px at var(--mx, 50%) 50%, #000, transparent 85%);
}

/* Vertical hairline. */
.spotlight::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--mx, 50%);
  width: 1px;
  background: color-mix(in oklab, var(--accent) 60%, transparent);
  mask-image: radial-gradient(1px 280px at 50% var(--my, 50%), #000, transparent 85%);
}

body:hover .spotlight { opacity: 1; }

/* --------------------------------------------------------------------------
   7. Shared primitives.
   -------------------------------------------------------------------------- */

.label {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0;
}

.label::before {
  content: '';
  width: 22px;
  height: 1px;
  background: var(--accent);
  box-shadow: 0 0 8px var(--glow);
  flex: none;
}

.eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}

.lede {
  color: var(--muted);
  font-size: clamp(0.95rem, 1.4vw, 1.06rem);
  line-height: 1.7;
}

.rule {
  height: 1px;
  border: 0;
  margin: 0;
  background: linear-gradient(to right, var(--border-strong), transparent 70%);
}

/* Buttons. The primary is the only element on a page allowed a real glow. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 24px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  position: relative;
  isolation: isolate;
  transition: border-color 260ms var(--ease), background 260ms var(--ease),
              color 260ms var(--ease), transform 260ms var(--ease);
}

.btn:hover {
  border-color: var(--accent);
  background: var(--surface-2);
  transform: translateY(-1px);
}

.btn-primary {
  border-color: color-mix(in oklab, var(--accent) 55%, transparent);
  background: color-mix(in oklab, var(--accent) 12%, #000);
  color: #fff;
}

.btn-primary::after {
  content: '';
  position: absolute;
  inset: -18px;
  z-index: -1;
  background: radial-gradient(closest-side, var(--glow), transparent 72%);
  mix-blend-mode: plus-lighter;
  opacity: 0;
  transition: opacity 320ms var(--ease);
}

.btn-primary:hover {
  background: color-mix(in oklab, var(--accent) 22%, #000);
  border-color: var(--accent);
}
.btn-primary:hover::after { opacity: 1; }

.btn-ghost { background: transparent; }

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* Status chip. The only place the green ever appears. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 11px;
  border: 1px solid color-mix(in oklab, var(--ch-live) 34%, transparent);
  border-radius: 999px;
  background: rgba(0, 255, 65, 0.05);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ch-live);
  white-space: nowrap;
}

.chip .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ch-live);
  box-shadow: 0 0 9px var(--ch-live);
  animation: pulse 2.4s ease-in-out infinite;
  flex: none;
}

@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.42; transform: scale(0.82); }
}

/* --------------------------------------------------------------------------
   8. Header.
   -------------------------------------------------------------------------- */

.header {
  position: sticky;
  top: 0;
  z-index: 200;
  border-bottom: 1px solid transparent;
  transition: border-color 300ms var(--ease), background 300ms var(--ease);
}

.header.is-stuck {
  background: rgba(0, 0, 0, 0.72);
  backdrop-filter: blur(14px);
  border-bottom-color: var(--border);
}

.header .shell {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 80px;
}

.logo {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  flex: none;
}

.logo-icon { width: 58px; height: auto; }
.logo-name { height: 58px; width: auto; max-width: none; }

/* The footer lockup can run larger still without fighting a nav bar. */
.footer .logo-icon { width: 34px; }
/* Sized to fit the brand column: a fixed height wider than the column lets
   max-width clamp one axis and squish the mark. */
.footer .logo-name { height: 19px; }

.nav {
  display: flex;
  align-items: center;
  gap: 4px;
}

.nav a {
  padding: 9px 14px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
  border-radius: var(--radius);
  transition: color 220ms var(--ease), background 220ms var(--ease);
}

.nav a:hover, .nav a[aria-current='page'] {
  color: var(--text);
  background: var(--surface);
}

.nav-login {
  border: 1px solid var(--border);
  margin-left: 8px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.nav-login svg { width: 13px; height: 13px; }

.burger {
  display: none;
  flex-direction: column;
  gap: 5px;
  padding: 10px;
  background: none;
  border: 0;
  cursor: pointer;
}
.burger span {
  display: block;
  width: 20px;
  height: 1.5px;
  background: var(--text);
  transition: transform 260ms var(--ease), opacity 200ms var(--ease);
}
.burger[aria-expanded='true'] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.burger[aria-expanded='true'] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded='true'] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   9. Hero.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  isolation: isolate;
  padding-block: clamp(56px, 8vh, 104px) clamp(48px, 7vh, 88px);
  overflow: hidden;
}

.hero .shell {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}

.hero h1 { margin-block: 20px 22px; }

.hero h1 .glow-word {
  position: relative;
  color: #fff;
  text-shadow:
    0 0 14px color-mix(in oklab, var(--ch-platform) 45%, transparent),
    0 0 44px color-mix(in oklab, var(--ch-agents) 30%, transparent);
}

.hero .lede { margin-bottom: 30px; }

/* --------------------------------------------------------------------------
   10. Luna instrument frame. The avatar is presented as an instrument with
       state, timecode and a live waveform, not as hero footage. A dead flat
       waveform beside a face is what makes an avatar read as fake, so the
       canvas runs a synthesized idle trace before audio ever exists.
   -------------------------------------------------------------------------- */

.luna {
  --accent: var(--ch-agents);
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012));
  overflow: hidden;
  isolation: isolate;
}

.luna::before {
  content: '';
  position: absolute;
  inset: -1px;
  z-index: -1;
  background: linear-gradient(140deg, var(--rail), transparent 42%, transparent 62%, var(--rail));
  opacity: 0.85;
}

.luna-rail {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.luna-rail .id { color: var(--text); }
.luna-timecode { font-variant-numeric: tabular-nums; color: var(--dim); }

/* Square because the source is: both luna-ambient.mp4 and the poster are
   720x720. At 5/4 cover had to crop her vertically, and every value of
   object-position was a choice about which part of her head to lose. A square
   stage fits the clip exactly, so there is nothing left to crop. */
.luna-stage {
  position: relative;
  aspect-ratio: 1 / 1;
  background: #000;
  overflow: hidden;
}

.luna-stage video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Dead centre: the stage is square and so is the clip, so cover is an exact
     fit and there is no crop to bias. */
  object-position: center;
  /* Feathers the square source into the black canvas so it never reads as a
     video box pasted onto the page. */
  mask-image:
    radial-gradient(78% 78% at 50% 42%, #000 52%, transparent 100%),
    linear-gradient(to bottom, #000 74%, transparent 98%);
  mask-composite: intersect;
  -webkit-mask-composite: source-in;
}

/* Idle and message clips are stacked; is-talking crossfades between them.
   The idle layer keeps playing underneath, so the fade back has frames. The
   fade is long and eased because the script starts it before the message
   ends: she hands back to the idle loop mid motion, not off a freeze. */
.luna-stage video { transition: opacity 900ms var(--ease); }
#lunaTalk { opacity: 0; }
.luna-stage.is-talking #lunaTalk { opacity: 1; }
.luna-stage.is-talking #lunaIdle { opacity: 0; }

/* The live call track replaces the idle clip. It must not inherit the feather
   mask or the call looks broken, and it sits below the disclosure badge. */
.luna-stage.is-live video { mask-image: none; }

.luna-live-video {
  position: absolute;
  inset: 0;
  z-index: 20;
  width: 100%;
  height: 100%;
  object-fit: cover;
  mask-image: none;
}

.luna-stage.is-live .luna-scan { opacity: 0.14; }

.luna-vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 110px 34px #000;
}

.luna-scan {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.35;
  background: repeating-linear-gradient(
    to bottom,
    transparent 0 2px,
    rgba(0, 0, 0, 0.32) 2px 3px
  );
}

/* EU AI Act Article 50(1), California AB 853 and 16 CFR 465. Visible for the
   whole session, above the remote video track, never clickable, never
   dismissible. Do not weaken this. */
.luna-ai-badge {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 40;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 9px;
  border: 1px solid color-mix(in oklab, var(--ch-live) 55%, transparent);
  background: rgba(0, 0, 0, 0.78);
  color: var(--ch-live);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  pointer-events: none;
  white-space: nowrap;
}

.luna-state {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 30;
}

.luna-wave {
  display: block;
  width: 100%;
  height: 46px;
  border-top: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.012);
}

.luna-transcript {
  /* Always exactly two lines tall. Captions swap between one and two lines
     as Luna speaks, and letting the box grow made the whole page pump up and
     down with her. 2 x (11.5px x 1.5) + 22px padding, and clamp anything
     longer rather than reflowing the document. */
  height: calc(2 * 1.5 * 11.5px + 22px);
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  padding: 11px 14px;
  border-top: 1px solid var(--border);
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--muted);
}
.luna-transcript .caret { color: var(--accent); }

/* Only ever on screen when the outgoing mic track has gone silent mid call.
   Uses the SOC amber rather than the section accent: this is a fault, and it
   should not look like part of the card's normal colour story. [hidden] needs
   saying because the display below would otherwise beat it. */
.luna-mic-warning {
  display: block;
  padding: 10px 14px;
  border-top: 1px solid color-mix(in oklab, var(--ch-soc) 42%, transparent);
  background: color-mix(in oklab, var(--ch-soc) 10%, transparent);
  color: color-mix(in oklab, var(--ch-soc) 70%, var(--text));
  font-size: 11px;
  line-height: 1.5;
  max-width: none;
}

.luna-mic-warning[hidden] { display: none; }

.luna-controls {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--border);
  border-top: 1px solid var(--border);
}

.luna-controls .btn {
  border: 0;
  border-radius: 0;
  background: rgba(0, 0, 0, 0.55);
  font-size: 11px;
  padding: 15px 12px;
}
.luna-controls .btn:hover { background: var(--surface-2); transform: none; }

.luna-sound {
  position: absolute;
  left: 50%;
  bottom: 16px;
  z-index: 35;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 15px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.74);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  animation: sound-breathe 2.8s ease-in-out infinite;
}

.luna-sound[hidden] { display: none; }

@keyframes sound-breathe {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.18); }
  50%      { box-shadow: 0 0 22px 2px rgba(255, 255, 255, 0.10); }
}

.luna-notice {
  padding: 10px 14px 14px;
  font-size: 10px;
  line-height: 1.5;
  color: var(--dim);
  max-width: none;
}

/* --------------------------------------------------------------------------
   11. Fleet ticker. Real agent state, not slogans.
   -------------------------------------------------------------------------- */

.ticker {
  position: relative;
  z-index: 2;
  border-block: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.015);
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
}

.ticker-track {
  display: flex;
  width: max-content;
  animation: ticker 46s linear infinite;
}

.ticker-track > * { flex: none; }

.ticker-item {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 12px 26px;
  font-size: 11px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

.ticker-item b {
  color: var(--text);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.ticker-item i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px var(--glow);
  flex: none;
}

@keyframes ticker {
  to { transform: translate3d(-50%, 0, 0); }
}

.ticker:hover .ticker-track { animation-play-state: paused; }

/* --------------------------------------------------------------------------
   12. Section header.
   -------------------------------------------------------------------------- */

.head {
  display: grid;
  gap: 16px;
  margin-bottom: clamp(36px, 5vw, 60px);
  max-width: 760px;
}

.head h2 { margin: 0; }

/* --------------------------------------------------------------------------
   13. Pillars.
   -------------------------------------------------------------------------- */

.pillars {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.pillar {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: clamp(24px, 3vw, 34px);
  background: #000;
  overflow: hidden;
  transition: background 340ms var(--ease);
}

.pillar::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--accent);
  box-shadow: 0 0 16px var(--glow);
  transform: scaleX(0.16);
  transform-origin: left;
  transition: transform 460ms var(--ease);
}

.pillar::after {
  content: '';
  position: absolute;
  inset: -55% -25% auto;
  height: 130%;
  z-index: -1;
  background: radial-gradient(closest-side, var(--wash), transparent 74%);
  mix-blend-mode: plus-lighter;
  opacity: 0;
  transition: opacity 420ms var(--ease);
}

.pillar:hover::before { transform: scaleX(1); }
.pillar:hover::after { opacity: 1; }

.pillar-index {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}

.pillar h3 { color: #fff; }

.pillar p { color: var(--muted); font-size: 13.5px; }

.pillar ul {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: grid;
  gap: 7px;
}

.pillar li {
  position: relative;
  padding-left: 17px;
  font-size: 12.5px;
  color: var(--muted);
}

.pillar li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 8px;
  width: 7px;
  height: 1px;
  background: var(--accent);
}

.pillar .status {
  margin-top: auto;
  padding-top: 16px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   14. Case studies.
   -------------------------------------------------------------------------- */

.cases {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 18px;
}

.case {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: clamp(22px, 2.6vw, 30px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
  transition: border-color 340ms var(--ease), transform 340ms var(--ease);
}

.case:hover {
  border-color: color-mix(in oklab, var(--accent) 45%, transparent);
  transform: translateY(-2px);
}

.case::after {
  content: '';
  position: absolute;
  inset: auto -30% -70% -30%;
  height: 120%;
  z-index: -1;
  background: radial-gradient(closest-side, var(--wash), transparent 72%);
  mix-blend-mode: plus-lighter;
  opacity: 0;
  transition: opacity 400ms var(--ease);
}
.case:hover::after { opacity: 1; }

.case-figure {
  font-family: var(--font-display);
  font-size: clamp(2.1rem, 3.4vw, 2.9rem);
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.case-figure span {
  font-size: 0.42em;
  color: var(--accent);
  letter-spacing: 0.06em;
  margin-left: 4px;
}

.case h3 { font-size: 1.02rem; color: var(--text); }
.case p { font-size: 12.8px; color: var(--muted); }

.case-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: auto;
  padding-top: 8px;
}

.tag {
  padding: 4px 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
}

.tag.on {
  border-color: color-mix(in oklab, var(--accent) 42%, transparent);
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   14b. Feature grid and page hero, used on the interior pages.
   -------------------------------------------------------------------------- */

.page-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(64px, 11vh, 132px) clamp(40px, 6vh, 72px);
}

.page-hero .shell { position: relative; z-index: 2; }
.page-hero .head { margin-bottom: 0; max-width: 820px; }

.features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

.feature {
  display: grid;
  gap: 10px;
  align-content: start;
  padding: 22px;
  border: 1px solid var(--border);
  border-left: 2px solid var(--rail);
  border-radius: var(--radius);
  background: var(--surface);
  transition: border-left-color 320ms var(--ease), background 320ms var(--ease);
}

.feature:hover {
  border-left-color: var(--accent);
  background: var(--surface-2);
}

.feature h3 { font-size: 0.98rem; color: #fff; }
.feature p { font-size: 12.5px; color: var(--muted); }

/* Anchored detail sections get a scroll offset so the sticky header does not
   cover the heading when a footer link jumps to them. */
.anchor { scroll-margin-top: 90px; }

.detail {
  display: grid;
  gap: clamp(26px, 3.4vw, 40px);
  padding-block: clamp(48px, 7vw, 84px);
  border-top: 1px solid var(--border);
}

.detail-head {
  display: grid;
  gap: 14px;
  max-width: 720px;
}

.proof {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  padding: 11px 16px;
  border: 1px solid color-mix(in oklab, var(--accent) 32%, transparent);
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--accent) 7%, #000);
  font-size: 12px;
  color: var(--muted);
  width: fit-content;
}

.proof b {
  font-family: var(--font-display);
  font-size: 1.35rem;
  letter-spacing: -0.03em;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   14c. Forms.
   -------------------------------------------------------------------------- */

.form {
  display: grid;
  gap: 16px;
  padding: clamp(22px, 3vw, 32px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.field { display: grid; gap: 7px; }

.field label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #000;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 13.5px;
  transition: border-color 220ms var(--ease);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--accent);
  outline: none;
}

.field textarea { resize: vertical; min-height: 108px; }

.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.form-error {
  color: #ff6b6b;
  font-size: 12px;
  margin: 0;
}

/* Sits under the submit button: scope, privacy and what happens next, in the
   one place a visitor is deciding whether to hand over a work address. */
/* Lead capture band. The form is the first action on the page, so it is capped
   to a comfortable typing width rather than stretched across the whole shell. */
.form-band .form,
.form-band .console { max-width: 640px; }

.form-band .console { margin-top: 18px; }

.form-note {
  font-size: 12px;
  line-height: 1.6;
  color: var(--muted);
  margin: 0;
}

.form-note a { color: inherit; text-decoration: underline; }

.field-opt { color: var(--muted); font-weight: 400; }

.form-ok {
  display: grid;
  gap: 12px;
  justify-items: start;
  padding: 26px 0;
}

.form-ok h3 { color: var(--ch-live); }

.contact-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.contact-fact { padding: 20px; background: #000; display: grid; gap: 6px; }

.contact-fact h4 {
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}

.contact-fact p { font-size: 13px; color: var(--text); }
.contact-fact a { color: var(--accent); }

/* --------------------------------------------------------------------------
   14d. Legal pages. Long-form reading, so the measure is tighter than the
        rest of the site and the mono body gets more leading.
   -------------------------------------------------------------------------- */

.legal { max-width: 74ch; display: grid; gap: 4px; }

.legal h2, .legal h3 {
  font-size: clamp(1.05rem, 1.7vw, 1.25rem);
  color: #fff;
  margin-top: 34px;
  margin-bottom: 4px;
}

.legal p, .legal li {
  color: var(--muted);
  font-size: 13.5px;
  line-height: 1.8;
  max-width: none;
}

.legal ul, .legal ol { margin: 0; padding-left: 20px; display: grid; gap: 6px; }
.legal a { color: var(--ch-platform); text-decoration: underline; text-underline-offset: 3px; }
.legal strong { color: var(--text); }

/* --------------------------------------------------------------------------
   15. Metrics.
   -------------------------------------------------------------------------- */

.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1px;
  background: var(--border);
  border-block: 1px solid var(--border);
}

.metric {
  padding: clamp(26px, 3.4vw, 40px) clamp(20px, 2.4vw, 30px);
  background: #000;
  display: grid;
  gap: 9px;
}

.metric-value {
  font-family: var(--font-display);
  font-size: clamp(2.3rem, 4.4vw, 3.5rem);
  font-weight: 700;
  letter-spacing: -0.045em;
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.metric-value em {
  font-style: normal;
  font-size: 0.4em;
  color: var(--accent);
  margin-left: 3px;
}

.metric-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.metric-note { font-size: 11px; color: var(--dim); line-height: 1.5; }

/* --------------------------------------------------------------------------
   16. SOC console block.
   -------------------------------------------------------------------------- */

.console {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.015);
  overflow: hidden;
  font-size: 12px;
}

.console-rail {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 15px;
  border-bottom: 1px solid var(--border);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.console-body { padding: 6px 0; }

.console-line {
  display: grid;
  grid-template-columns: 74px 78px 1fr;
  gap: 14px;
  align-items: baseline;
  padding: 9px 15px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  line-height: 1.5;
}
.console-line:last-child { border-bottom: 0; }

.console-line time { color: var(--dim); font-variant-numeric: tabular-nums; font-size: 11px; }

.console-tag {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.console-tag.hold { color: var(--ch-soc); }
.console-tag.human { color: var(--ch-live); }

.console-line p { color: var(--muted); font-size: 12px; }
.console-line b { color: var(--text); font-weight: 700; }

/* --------------------------------------------------------------------------
   17. Split blocks.
   -------------------------------------------------------------------------- */

.split {
  display: grid;
  /* 380 rather than 300: at a tablet width two 300px tracks still fit, which
     squeezed console text to about 190px and wrapped it to nine lines. */
  grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
  gap: clamp(30px, 4.6vw, 64px);
  align-items: start;
}

.stack { display: grid; gap: 18px; align-content: start; }

/* --------------------------------------------------------------------------
   18. CTA and footer.
   -------------------------------------------------------------------------- */

.cta {
  position: relative;
  isolation: isolate;
  text-align: center;
  overflow: hidden;
  border-top: 1px solid var(--border);
}

.cta::after {
  content: '';
  position: absolute;
  inset: 30% -20% -60%;
  z-index: -1;
  background: radial-gradient(closest-side,
    color-mix(in oklab, var(--ch-platform) 18%, transparent), transparent 70%);
  mix-blend-mode: plus-lighter;
  filter: blur(40px);
}

.cta .head { margin-inline: auto; text-align: center; justify-items: center; }
.cta .actions { justify-content: center; }
.cta p { margin-inline: auto; }

.footer {
  border-top: 1px solid var(--border);
  padding-block: clamp(44px, 6vw, 68px) 26px;
  font-size: 12.5px;
}

.footer-grid {
  display: grid;
  grid-template-columns: minmax(220px, 1.6fr) repeat(auto-fit, minmax(130px, 1fr));
  gap: 34px;
  margin-bottom: 40px;
}

.footer-brand p { color: var(--muted); margin-top: 14px; font-size: 12.5px; max-width: 34ch; }

.footer h4 {
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 14px;
}

.footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.footer li a { color: var(--muted); transition: color 200ms var(--ease); }
.footer li a:hover { color: var(--text); }

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding-top: 22px;
  border-top: 1px solid var(--border);
  color: var(--dim);
  font-size: 11px;
}
.footer-bottom a { color: var(--dim); }
.footer-bottom a:hover { color: var(--muted); }

/* --------------------------------------------------------------------------
   19. Scroll-driven reveals. Native timeline, so no IntersectionObserver and
       no main-thread work. Without support the element is simply visible.
   -------------------------------------------------------------------------- */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .reveal {
      animation: reveal-in linear both;
      animation-timeline: view();
      animation-range: entry 4% cover 26%;
    }
    .scan-progress {
      animation: progress linear both;
      animation-timeline: scroll(root block);
      transform-origin: left;
    }
  }
}

@keyframes reveal-in {
  from { opacity: 0; transform: translateY(22px); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: none; }
}

@keyframes progress {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

.scan-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 300;
  background: linear-gradient(to right, var(--ch-platform), var(--ch-agents), var(--ch-soc));
  transform: scaleX(0);
  transform-origin: left;
}

/* Cross-document transitions. Zero JS, and Firefox simply ignores it. */
@view-transition { navigation: auto; }

/* --------------------------------------------------------------------------
   20. Responsive.
   -------------------------------------------------------------------------- */

@media (max-width: 940px) {
  .hero .shell { grid-template-columns: 1fr; }
  /* Single column: the panel is capped, so centre it rather than
     leaving half the row empty on a tablet. */
  /* Natural DOM order when stacked: the headline has to land before Luna, or
     a phone opens on a face with no idea what the company does. */
  .hero-visual { max-width: 460px; margin-inline: auto; width: 100%; }
}

@media (max-width: 900px) {
  .nav {
    position: fixed;
    inset: 80px 0 auto;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 12px var(--gutter) 24px;
    background: rgba(0, 0, 0, 0.96);
    border-bottom: 1px solid var(--border);
    transform: translateY(-12px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 240ms var(--ease), transform 240ms var(--ease);
  }
  .nav.is-open { opacity: 1; transform: none; pointer-events: auto; }
  .nav a { padding: 14px 4px; font-size: 13px; }
  .nav-login { margin: 10px 0 0; justify-content: center; }
  .burger { display: flex; }

  /* The lockup must never be the thing that shrinks. Without flex:none the
     header squeezes the wordmark, and because its height is fixed the image
     distorts rather than scaling: 6:1 art rendered at 3.5:1. */
  .logo { flex: none; }
  .logo-icon { width: 40px; }
  .logo-name { height: 40px; max-width: none; }
  .header .shell { min-height: 64px; }
  .nav { inset: 64px 0 auto; }

  /* Long unbroken strings (addresses, emails) must not push the page wide. */
  .contact-fact p, .legal p, .legal li { overflow-wrap: anywhere; }
}

@media (max-width: 760px) {
  .luna-controls { grid-template-columns: 1fr; }
  .console-line { grid-template-columns: 1fr; gap: 4px; }
}

/* Phones. The footer's auto-fit track list wants 220px plus a 130px column,
   which is wider than the content box below roughly 700px and was the one
   real horizontal overflow on the site. */
@media (max-width: 700px) {
  .footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 26px 20px;
  }
  .footer-brand { grid-column: 1 / -1; }
}

@media (max-width: 430px) {
  .footer-grid { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  .logo-icon { width: 34px; }
  .logo-name { height: 34px; }
  /* Give the caption a third line: the invitation wraps further on a phone. */
  .luna-transcript { height: calc(3 * 1.5 * 11.5px + 22px); -webkit-line-clamp: 3; }
  .btn { width: 100%; }
  .actions { gap: 10px; }
  .book-panel { height: min(760px, 96vh); }
}

/* --------------------------------------------------------------------------
   21. Reduced motion. Motion stops, the composition stays: the aurora freezes
       on a designed frame rather than disappearing.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .grain { animation: none; }
  .spotlight { display: none; }
}

/* --------------------------------------------------------------------------
   22. Booking modal. Our own scheduling app in an overlay, so a visitor sees
       available times without leaving the page. Opened by [data-book].
   -------------------------------------------------------------------------- */

.book-modal {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: grid;
  place-items: center;
  padding: clamp(12px, 3vw, 40px);
  background: rgba(0, 0, 0, 0.78);
  backdrop-filter: blur(8px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms var(--ease);
}

.book-modal.is-open {
  opacity: 1;
  pointer-events: auto;
}

.book-panel {
  width: min(960px, 100%);
  height: min(760px, 92vh);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: #000;
  overflow: hidden;
  transform: translateY(14px) scale(0.985);
  transition: transform 300ms var(--ease);
}

.book-modal.is-open .book-panel { transform: none; }

.book-rail {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
}

.book-close {
  padding: 7px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 220ms var(--ease);
}

.book-close:hover { border-color: var(--accent); }

.book-frame {
  flex: 1;
  width: 100%;
  border: 0;
  background: #000;
}

.book-lock { overflow: hidden; }
