/* ==========================================================================
   base.css - design tokens, reset, base typography, global keyframes
   All colors, spacing, radii and font tokens live here. No other stylesheet
   is allowed to declare a raw hex value.
   ========================================================================== */

:root {
  /* --- raw palette ------------------------------------------------------ */
  --c-navy-900: #0b1220;
  --c-navy-800: #161f34;
  --c-slate-900: #0f172a;
  --c-slate-100: #f1f5f9;
  --c-slate-50: #f8fafc;
  --c-blue-200: #bfdbfe;
  --c-blue-500: #3b82f6;
  --c-blue-600: #2563eb;
  --c-blue-700: #1d4ed8;
  --c-sky-400: #38bdf8;
  --c-sky-500: #0ea5e9;
  --c-green-500: #22c55e;
  --c-amber-600: #d97706;
  --c-red-500: #ef4444;
  --c-white: #ffffff;

  /* --- channel triplets, used to build translucent variants ------------- */
  --rgb-primary: 37, 99, 235;
  --rgb-primary-light: 59, 130, 246;
  --rgb-sky: 14, 165, 233;
  --rgb-sky-bright: 56, 189, 248;
  --rgb-blue-pale: 191, 219, 254;
  --rgb-success: 34, 197, 94;
  --rgb-danger: 239, 68, 68;
  --rgb-light: 241, 245, 249;
  --rgb-panel: 248, 250, 252;
  --rgb-white: 255, 255, 255;
  --rgb-ink: 15, 23, 42;
  --rgb-shadow: 0, 0, 0;

  /* --- semantic colors -------------------------------------------------- */
  --color-bg: var(--c-navy-900);
  --color-surface: var(--c-navy-800);
  --color-surface-soft: rgba(var(--rgb-white), 0.04);
  --color-surface-strong: rgba(var(--rgb-white), 0.09);
  --color-surface-ghost: rgba(var(--rgb-white), 0.1);
  --color-surface-veil: rgba(var(--rgb-white), 0.18);
  --color-surface-veil-soft: rgba(var(--rgb-white), 0.2);

  --color-text: var(--c-slate-100);
  --color-text-muted: rgba(var(--rgb-light), 0.65);
  --color-text-invert: var(--c-slate-900);
  --color-text-invert-muted: rgba(var(--rgb-ink), 0.65);
  --color-on-primary: var(--c-white);
  --color-on-primary-muted: rgba(var(--rgb-white), 0.85);
  --color-on-primary-faint: rgba(var(--rgb-white), 0.8);

  --color-primary: var(--c-blue-600);
  --color-primary-light: var(--c-blue-500);
  --color-success: var(--c-green-500);
  --color-warning: var(--c-amber-600);
  --color-danger: var(--c-red-500);

  --color-border: rgba(var(--rgb-white), 0.12);
  --color-border-soft: rgba(var(--rgb-white), 0.1);
  --color-border-strong: rgba(var(--rgb-white), 0.15);
  --color-border-invert: rgba(var(--rgb-ink), 0.08);
  --color-border-success: rgba(var(--rgb-success), 0.25);
  --color-border-success-soft: rgba(var(--rgb-success), 0.18);
  --color-border-danger: rgba(var(--rgb-danger), 0.25);

  --color-icon-danger-bg: rgba(var(--rgb-danger), 0.12);
  --color-icon-success-bg: rgba(var(--rgb-success), 0.12);

  /* --- header ------------------------------------------------------------
     Opaque white, scrolled or not. Everything sitting on it is keyed to these
     tokens so the contrast stays deliberate. */
  --color-header-bg: var(--c-white);
  --color-header-surface: var(--c-white);
  --color-header-text: var(--color-text-invert);
  --color-header-text-muted: var(--color-text-invert-muted);
  --color-header-link-active: var(--color-primary);
  --color-header-icon: var(--color-text-invert);

  --color-footer-bg: var(--c-slate-100);

  --color-selection: rgba(var(--rgb-primary), 0.2);
  /* --- scan graph -------------------------------------------------------
     Edges: solid when the result is in, dashed while scanning.
     Nodes: a deliberate mix of depths, not one flat blue. */
  --color-scan-line-done: rgba(var(--rgb-primary-light), 0.85);
  --color-scan-line-active: rgba(var(--rgb-primary-light), 0.9);
  --color-scan-node: var(--color-primary);
  --color-scan-node-deep: var(--c-blue-700);
  --color-scan-node-bright: var(--c-sky-400);
  --color-scan-node-pale: var(--c-blue-200);
  --color-scan-halo: rgba(var(--rgb-sky-bright), 0.55);
  --color-scan-pulse: var(--c-white);

  /* --- gradients -------------------------------------------------------- */
  --gradient-logo-start: var(--c-blue-500);
  --gradient-logo-end: var(--c-blue-600);
  --gradient-primary: linear-gradient(135deg, var(--color-primary), var(--color-primary));
  --gradient-primary-soft: linear-gradient(160deg, var(--color-primary), var(--color-primary));
  --gradient-eyebrow: linear-gradient(135deg, var(--color-primary), var(--color-primary), var(--color-success));
  --gradient-heading: linear-gradient(135deg, var(--color-primary), var(--color-primary));
  --gradient-clear: linear-gradient(135deg, rgba(var(--rgb-success), 0.08), rgba(var(--rgb-success), 0.02));
  --gradient-section-wash: linear-gradient(180deg, transparent, rgba(var(--rgb-primary), 0.035), transparent);
  --gradient-blob-primary: radial-gradient(circle, rgba(var(--rgb-primary), 0.16), transparent 70%);
  --gradient-blob-sky: radial-gradient(circle, rgba(var(--rgb-sky), 0.14), transparent 70%);
  --gradient-halo: radial-gradient(circle at 70% 20%, rgba(var(--rgb-primary), 0.14), transparent 65%);
  --gradient-halo-story: radial-gradient(circle at 30% 30%, rgba(var(--rgb-primary), 0.18), transparent 65%);

  /* --- decorative grid backdrops ---------------------------------------- */
  --grid-line-faint: linear-gradient(rgba(var(--rgb-primary), 0.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--rgb-primary), 0.06) 1px, transparent 1px);
  --grid-line-medium: linear-gradient(rgba(var(--rgb-primary), 0.1) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--rgb-primary), 0.1) 1px, transparent 1px);
  --grid-line-strong: linear-gradient(rgba(var(--rgb-primary), 0.12) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--rgb-primary), 0.12) 1px, transparent 1px);
  --grid-line-light: linear-gradient(rgba(var(--rgb-white), 0.12) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--rgb-white), 0.12) 1px, transparent 1px);

  /* --- shadows ---------------------------------------------------------- */
  --shadow-header: 0 1px 0 rgba(var(--rgb-ink), 0.04);
  --shadow-header-scrolled: 0 4px 20px rgba(var(--rgb-ink), 0.08);
  --shadow-card: 0 30px 60px -28px rgba(var(--rgb-ink), 0.22);
  --shadow-card-lg: 0 40px 80px -30px rgba(var(--rgb-ink), 0.25);
  --shadow-card-hover: 0 20px 40px -20px rgba(var(--rgb-primary), 0.25);
  --shadow-step: 0 4px 14px rgba(var(--rgb-ink), 0.05);
  --shadow-cta: 0 16px 44px -10px rgba(var(--rgb-primary), 0.7);
  --shadow-button: 0 12px 30px -8px rgba(var(--rgb-primary), 0.75);
  --shadow-price: 0 30px 60px -24px rgba(var(--rgb-primary), 0.5);
  --shadow-button-light: 0 16px 32px -12px rgba(var(--rgb-shadow), 0.25);

  /* --- filters ---------------------------------------------------------- */
  --glow-scan-node-bright: drop-shadow(0 0 6px rgba(var(--rgb-sky-bright), 0.8));
  --glow-scan-node-pale: drop-shadow(0 0 5px rgba(var(--rgb-blue-pale), 0.65));
  --glow-scan-pulse: drop-shadow(0 0 4px rgba(var(--rgb-white), 0.9));

  /* --- spacing scale ---------------------------------------------------- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 16px;
  --space-4: 24px;
  --space-5: 32px;
  --space-6: 48px;
  --space-7: 64px;
  --space-8: 96px;
  --space-9: 128px;

  /* --- radii ------------------------------------------------------------ */
  --radius-xs: 2px;
  --radius-sm: 7px;
  --radius-md: 10px;
  --radius-lg: 12px;
  --radius-xl: 16px;
  --radius-2xl: 20px;
  --radius-3xl: 26px;
  --radius-pill: 999px;
  --radius-circle: 50%;

  /* --- typography ------------------------------------------------------- */
  --font-sans: "Sora", "Segoe UI", system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;

  --fs-3xs: 12px;
  --fs-2xs: 13px;
  --fs-xs: 14px;
  --fs-sm: 16px;
  --fs-md: 18px;
  --fs-lg: 20px;
  --fs-xl: 24px;
  --fs-2xl: 28px;
  --fs-3xl: 32px;
  --fs-4xl: 48px;

  --fs-display: clamp(32px, 4.6vw, 60px);
  --fs-display-page: clamp(32px, 5vw, 60px);
  --fs-title: clamp(28px, 4vw, 40px);
  --fs-title-sm: clamp(28px, 3.6vw, 40px);
  --fs-title-xs: clamp(24px, 3.2vw, 32px);

  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-black: 800;

  --lh-tight: 1.1;
  --lh-snug: 1.15;
  --lh-base: 1.6;
  --lh-relaxed: 1.7;
  --lh-loose: 1.8;

  --ls-tight: -0.03em;
  --ls-snug: -0.02em;
  --ls-wide: 0.06em;
  --ls-wider: 0.1em;
  --ls-widest: 0.16em;
  --ls-eyebrow: 0.14em;

  /* --- layout ----------------------------------------------------------- */
  --container-wide: 1240px;
  --container-lg: 1180px;
  --container-md: 1080px;
  --container-sm: 820px;
  --container-xs: 720px;
  --header-height: 76px;
  --gutter: 24px;

  /* --- motion ----------------------------------------------------------- */
  --transition-fast: 0.25s ease;
  --transition-base: 0.3s ease;
  --transition-slow: 0.35s ease;
  --transition-reveal: 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);

  /* --- elevation -------------------------------------------------------- */
  --z-decor: 0;
  --z-content: 1;
  --z-header: 100;
}

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
h4,
p,
figure {
  margin: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

img,
svg {
  max-width: 100%;
}

a {
  color: var(--color-primary);
  text-decoration: none;
}

button,
select,
input {
  font-family: inherit;
}

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

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --- shared text roles ---------------------------------------------------- */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-eyebrow);
  color: var(--color-primary);
  margin-bottom: var(--space-3);
}

.eyebrow--danger {
  color: var(--color-danger);
}

.eyebrow--success {
  color: var(--color-success);
}

.section-title {
  font-size: var(--fs-title);
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-snug);
  color: var(--color-text);
  margin-bottom: var(--space-3);
}

.section-title--sm {
  font-size: var(--fs-title-sm);
}

.section-lead {
  font-size: var(--fs-sm);
  line-height: var(--lh-relaxed);
  color: var(--color-text-muted);
}

.mono {
  font-family: var(--font-mono);
}

/* --- global keyframes ----------------------------------------------------- */
@keyframes gridMove {
  0% {
    background-position: 0 0;
  }
  100% {
    background-position: 64px 64px;
  }
}

/* drift only - no scaling, so nothing behind the scan card appears to zoom */
@keyframes blobMove1 {
  0%,
  100% {
    transform: translate(0, 0);
  }
  50% {
    transform: translate(30px, -20px);
  }
}

@keyframes blobMove2 {
  0%,
  100% {
    transform: translate(0, 0);
  }
  50% {
    transform: translate(-24px, 26px);
  }
}

@keyframes nodePulse {
  0%,
  100% {
    opacity: 0.4;
  }
  50% {
    opacity: 1;
  }
}

/* -26 is exactly two periods of the 6/7 dash pattern, so the loop is seamless */
@keyframes dashMove {
  to {
    stroke-dashoffset: -26;
  }
}

/* expanding ring around the hub node while scanning */
@keyframes nodeHalo {
  0% {
    stroke-width: 0;
    stroke-opacity: 0.55;
  }
  100% {
    stroke-width: 16;
    stroke-opacity: 0;
  }
}

@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* --- scroll reveal -------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity var(--transition-reveal), transform var(--transition-reveal);
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }

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