/* -------- TENACITY visual system -------- */
/* Brand palette (Prezentácia identity značky Tenacity):
   Deep Navy #0B1426 · Slate Gray #2A3342 · Cool Gray #8B909A ·
   Light Blue #5B8CFF · White #FFFFFF. Every other token below is a
   linear tint/shade of one of those five anchors — nothing off-brand. */
:root {
  --bg-0: #0B1426;        /* Deep Navy */
  --bg-1: #131C2D;        /* Deep Navy -> Slate Gray, 25% */
  --bg-2: #2A3342;        /* Slate Gray */
  --bg-3: #474F5C;        /* Slate Gray -> Cool Gray, 30% */
  --line: rgba(139, 144, 154, 0.12);       /* Cool Gray hairline */
  --line-strong: rgba(139, 144, 154, 0.26);
  --ink-0: #FFFFFF;       /* White */
  --ink-1: #CBCDD2;       /* Cool Gray -> White, 55% */
  --ink-2: #8B909A;       /* Cool Gray */
  --ink-3: #5F6672;       /* Cool Gray -> Slate Gray, 45% */
  --accent: #5B8CFF;      /* Light Blue */
  --accent-soft: #94B4FF; /* Light Blue -> White, 35% */
  --accent-deep: #4062B3; /* Light Blue -> Deep Navy, 30% */
  --accent-glow: rgba(91, 140, 255, 0.45);
  --halo: rgba(91, 140, 255, 0.14);
  --radius: 14px;
  --maxw: 1280px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
  background: var(--bg-0);
  color: var(--ink-0);
  font-family: "Inter", system-ui, sans-serif;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
/* `hidden` on BOTH html and body makes body its own scroll container whose
   scrollWidth is wider than the screen (hero orb, about emblem and the
   nova shockwave all bleed past the edge on purpose). Touch devices then
   let a slightly diagonal swipe grab that inner horizontal scroller
   instead of the page, which is exactly the "page stops scrolling" bug.
   `clip` cuts the overflow off without creating a scroll container. */
@supports (overflow: clip) {
  html, body { overflow-x: clip; }
}
html { scroll-behavior: smooth; }
::selection { background: var(--accent-glow); color: white; }

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

.display { font-family: "Space Grotesk", "Inter", sans-serif; letter-spacing: -0.02em; font-weight: 500; }
.mono { font-family: "JetBrains Mono", ui-monospace, monospace; }

.container { max-width: var(--maxw); margin: 0 auto; padding: 0 32px; }

/* -------- Global background field (grid + radial halos) -------- */
.bg-field {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    /* faint distant galaxies — soft, elongated smudges of color, kept
       subtle so they read as atmosphere rather than decoration. Both
       stay inside the brand blue rather than drifting into off-brand
       hues — just a lighter and a deeper reading of the same accent. */
    radial-gradient(60% 22% at 14% 18%, rgba(148, 180, 255, 0.09), transparent 72%),
    radial-gradient(50% 20% at 88% 78%, rgba(64, 98, 179, 0.10), transparent 72%),
    radial-gradient(900px 600px at 80% -10%, var(--halo), transparent 60%),
    radial-gradient(700px 500px at 0% 30%, rgba(91, 140, 255, 0.08), transparent 65%),
    radial-gradient(1200px 800px at 50% 110%, rgba(91, 140, 255, 0.10), transparent 55%),
    var(--bg-0);
}
.bg-grid {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(139, 144, 154, 0.024) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(139, 144, 154, 0.024) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 40%, black 40%, transparent 90%);
  -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 40%, black 40%, transparent 90%);
  animation: gridDrift 60s linear infinite;
}
@keyframes gridDrift {
  from { background-position: 0 0, 0 0; }
  to   { background-position: 64px 64px, 64px 64px; }
}
.bg-noise {
  position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: 0.04;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.5 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  mix-blend-mode: overlay;
}

/* -------- Nav -------- */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  padding: 18px 0;
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  background: linear-gradient(to bottom, rgba(11, 20, 38, 0.7), rgba(11, 20, 38, 0.2));
  border-bottom: 1px solid transparent;
  transition: border-color 0.4s ease, background 0.4s ease;
}
.nav.scrolled {
  border-bottom-color: var(--line);
  background: rgba(11, 20, 38, 0.78);
}
/* Grid, not flex+space-between: with 3 flex items, a width change in any
   one of them (e.g. "Book a Call" vs "Rezervovať hovor" after a language
   switch) reflows the gaps and visibly shifts the other two. A grid with
   fixed edge columns keeps logo and the right-hand controls pinned in
   place; only the elastic middle column absorbs the width change. */
.nav-inner { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 24px; }
.nav-links { justify-self: center; }
.nav-inner > div:last-child { justify-self: end; }
.logo {
  display: flex; align-items: center; gap: 10px;
  font-family: "Space Grotesk", sans-serif; font-weight: 600;
  letter-spacing: 0.32em; font-size: 14px;
}
.logo-mark {
  width: 22px; height: 22px;
  display: grid; place-items: center;
  color: var(--accent);
}
.logo-mark svg { width: 100%; height: 100%; }
.nav-links { display: flex; gap: 36px; font-size: 13px; color: var(--ink-2); }
.nav-links a { transition: color 0.25s ease; }
.nav-links a:hover { color: var(--ink-0); }
.nav-cta {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 18px;
  /* Fixed width so switching language ("Book a Call" vs "Rezervovať
     hovor") doesn't resize the button and shift the lang-switch/menu
     button next to it. */
  min-width: 172px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 13px; color: var(--ink-0);
  background: rgba(139, 144, 154, 0.04);
  transition: border-color 0.3s ease, background 0.3s ease, transform 0.3s ease;
}
.nav-cta:hover { border-color: var(--accent); background: var(--halo); }
.nav-cta .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 10px var(--accent-glow);
}
@media (max-width: 800px) { .nav-links { display: none; } }
@media (max-width: 480px) { .nav-cta { display: none; } }
.menu-btn { display: none; }
@media (max-width: 800px) {
  .menu-btn {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 10px 14px;
    border: 1px solid var(--line-strong); border-radius: 999px;
    font-family: "JetBrains Mono", monospace; font-size: 11px;
    letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-0);
  }
}
.mobile-menu {
  position: fixed; inset: 0; z-index: 60;
  display: none; flex-direction: column; gap: 8px;
  padding: 96px 32px 32px;
  touch-action: none; overscroll-behavior: contain;
  background: rgba(11, 20, 38, 0.96);
  -webkit-backdrop-filter: blur(18px); backdrop-filter: blur(18px);
}
.mobile-menu.open { display: flex; }
.mobile-menu a {
  padding: 16px 0;
  font-family: "Space Grotesk", sans-serif; font-size: 28px; font-weight: 500;
  letter-spacing: -0.01em; color: var(--ink-0);
  border-bottom: 1px solid var(--line);
}
.mobile-menu .mm-langs { display: flex; gap: 8px; margin-top: 20px; }
.mobile-menu .mm-langs button {
  padding: 10px 16px;
  border: 1px solid var(--line-strong); border-radius: 999px;
  font-family: "JetBrains Mono", monospace; font-size: 11px;
  letter-spacing: 0.18em; color: var(--ink-1);
}
.mobile-menu .mm-langs button.active { border-color: var(--accent); color: var(--ink-0); background: var(--halo); }
.mobile-menu .mm-close {
  position: absolute; top: 20px; right: 24px;
  padding: 10px 16px;
  border: 1px solid var(--line-strong); border-radius: 999px;
  font-family: "JetBrains Mono", monospace; font-size: 11px;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-0);
}

/* -------- Section scaffolding -------- */
section { position: relative; z-index: 1; }
section[id] { scroll-margin-top: 112px; }
.eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--ink-2);
}
/* Same breathing dot as the hero's dormant star and the topbar pips —
   one small, recurring marker instead of a different ornament per
   section, so every section-head reads as part of the same system. */
.eyebrow::before {
  content: ""; flex-shrink: 0;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px 1px var(--accent-glow);
  animation: dotPulse 3.4s ease-in-out infinite;
}
@keyframes dotPulse {
  0%, 100% { transform: scale(1); opacity: 0.6; }
  50% { transform: scale(1.6); opacity: 1; }
}

.section-head { max-width: 720px; margin-bottom: 64px; }
.section-head h2 {
  margin-top: 18px;
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(36px, 5vw, 64px);
  letter-spacing: -0.025em; font-weight: 500;
  line-height: 1.02;
  color: var(--ink-0);
}
.section-head p {
  margin-top: 20px; max-width: 560px;
  color: var(--ink-1); font-size: 17px; line-height: 1.55;
}

/* Reveal-on-scroll — HIDDEN ONLY UNDER html.js (set by the inline script
   below). Without the gate, no-JS visitors and crawlers got a page whose
   every section sat at opacity 0 forever. */
.reveal, .reveal-stagger > * { transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1); }
html.js .reveal { opacity: 0; transform: translateY(24px); }
html.js .reveal.in { opacity: 1; transform: none; }
html.js .reveal-stagger > * { opacity: 0; transform: translateY(24px); }
html.js .reveal-stagger.in > * { opacity: 1; transform: none; }
.reveal-stagger.in > *:nth-child(1) { transition-delay: 0.05s; }
.reveal-stagger.in > *:nth-child(2) { transition-delay: 0.12s; }
.reveal-stagger.in > *:nth-child(3) { transition-delay: 0.19s; }
.reveal-stagger.in > *:nth-child(4) { transition-delay: 0.26s; }
.reveal-stagger.in > *:nth-child(5) { transition-delay: 0.33s; }
.reveal-stagger.in > *:nth-child(6) { transition-delay: 0.40s; }

/* -------- HERO -------- */
/* min-height: 100svh (where supported) instead of 100vh — svh uses the
   viewport height with mobile browser chrome fully shown and does NOT
   change as the address bar hides/shows while scrolling, so the section
   doesn't resize and visually "jump" mid-scroll like 100vh does. */
.hero { min-height: 100vh; min-height: 100svh; padding: 160px 0 120px; display: flex; align-items: center; }
.hero-inner { width: 100%; position: relative; z-index: 2; }
.hero-tag {
  display: inline-flex; align-items: center; gap: 12px;
  padding: 8px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: rgba(139, 144, 154, 0.03);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  font-family: "JetBrains Mono", monospace;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-1);
}
.hero-tag .pulse {
  position: relative;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
}
.hero-tag .pulse::after {
  content: ""; position: absolute; inset: -4px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.4;
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { transform: scale(1); opacity: 0.0; }
  50% { transform: scale(2.2); opacity: 0.35; }
}

.hero-title-row { margin-top: 32px; }
.hero-logo-lockup {
  display: block;
  width: clamp(280px, 36vw, 460px);
  height: auto;
  filter: drop-shadow(0 0 40px var(--halo));
}

.hero-sub {
  margin-top: 28px;
  display: flex; align-items: baseline; gap: 18px;
  color: var(--ink-1);
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(20px, 2.2vw, 28px);
  font-weight: 400;
  letter-spacing: -0.01em;
}
.hero-sub .bar { display: inline-block; width: 32px; height: 1px; background: var(--accent); transform: translateY(-6px); }
.hero-desc {
  margin-top: 28px; max-width: 560px;
  color: var(--ink-1);
  font-size: 17px; line-height: 1.6;
  /* Reserves the tallest translation's line count (SK/CS wrap to 3 lines,
     EN to 2) so switching language doesn't shift the CTA buttons and
     stats below it. */
  min-height: calc(1.6em * 3);
}
.hero-cta { margin-top: 44px; display: flex; gap: 14px; flex-wrap: wrap; }

.btn {
  position: relative;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 16px 26px;
  font-size: 14px; letter-spacing: 0.04em;
  border-radius: 999px;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1), box-shadow 0.3s ease, border-color 0.3s ease;
  overflow: hidden;
}
.btn-primary {
  color: var(--bg-0);
  background: linear-gradient(180deg, var(--accent-soft), var(--accent-deep));
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.18) inset, 0 10px 40px var(--accent-glow), 0 0 0 1px var(--accent-deep);
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.22) inset, 0 18px 50px var(--accent-glow), 0 0 0 1px var(--accent); }
.btn-primary::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(110deg, transparent 30%, rgba(255,255,255,0.45) 50%, transparent 70%);
  transform: translateX(-110%); transition: transform 0.9s ease;
}
.btn-primary:hover::after { transform: translateX(110%); }
.btn-ghost {
  color: var(--ink-0);
  border: 1px solid var(--line-strong);
  background: rgba(139, 144, 154, 0.03);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.btn-ghost:hover { border-color: var(--accent); background: var(--halo); transform: translateY(-2px); }
.btn .arrow { transition: transform 0.3s ease; }
.btn:hover .arrow { transform: translate(3px, -3px); }

.hero-meta {
  margin-top: 96px;
  display: flex; gap: 64px; flex-wrap: wrap;
  color: var(--ink-2); font-size: 12px;
  font-family: "JetBrains Mono", monospace;
  letter-spacing: 0.18em; text-transform: uppercase;
  border-top: 1px solid var(--line); padding-top: 24px;
}
.hero-meta strong {
  display: block; margin-top: 8px;
  font-family: "Space Grotesk", sans-serif; font-weight: 500;
  color: var(--ink-0);
  font-size: 24px; letter-spacing: -0.01em; text-transform: none;
}

/* Hero canvas (particles) */
#hero-canvas {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  mask-image: radial-gradient(ellipse 80% 60% at 60% 50%, black 30%, transparent 90%);
  -webkit-mask-image: radial-gradient(ellipse 80% 60% at 60% 50%, black 30%, transparent 90%);
  pointer-events: none;
}
.hero-orb {
  position: absolute; right: -10%; top: 12%;
  width: min(700px, 60vw); aspect-ratio: 1;
  z-index: 1; pointer-events: none;
  background:
    radial-gradient(closest-side, rgba(91, 140, 255, 0.18), transparent 70%);
  filter: blur(8px);
  animation: orbDrift 18s ease-in-out infinite alternate;
}
@keyframes orbDrift {
  from { transform: translate(0, 0) scale(1); }
  to   { transform: translate(-40px, 30px) scale(1.08); }
}

/* -------- NOVA REVEAL: dormant star -> supernova -> logo condenses from
   the afterglow -> lines. No background of its own — it sits on the same
   fixed .bg-field/.bg-grid as every other section so it reads as one
   continuous space instead of a boxed-in slide. -------- */
.nova {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex; align-items: center; justify-content: center;
  /* Deliberately NOT clipped: the flash is scaled large enough to wash
     up into the portfolio carousel above and down into services below,
     so the blast doesn't feel boxed into this one section. html/body's
     overflow-x: hidden still stops any horizontal scrollbar. */
  overflow: visible;
}
.nova-stage {
  position: relative;
  width: 100%; min-height: 100vh; min-height: 100svh;
  display: flex; align-items: center; justify-content: center;
}
/* Fades in from the top edge so it picks up from the portfolio carousel's
   star layer above instead of starting at full density on a hard line. */
.nova-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none;
  mask-image: linear-gradient(to bottom, transparent 0%, black 22%, black 88%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 22%, black 88%, transparent 100%);
}

/* Dormant star: breathes gently until ignition takes over the transform. */
.nova-core {
  position: absolute; left: 50%; top: 50%; z-index: 2;
  width: 6px; height: 6px; border-radius: 50%;
  background: #F0F4FC;
  box-shadow: 0 0 12px 3px rgba(91, 140, 255, 0.8);
  transform: translate(-50%, -50%) scale(1);
  opacity: 0.8;
  animation: novaIdle 3.4s ease-in-out infinite;
}
@keyframes novaIdle {
  0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.65; }
  50% { transform: translate(-50%, -50%) scale(1.5); opacity: 1; }
}
.nova-core.igniting {
  animation: none;
  transition: transform 0.9s cubic-bezier(0.4, 0, 0.15, 1), box-shadow 0.9s ease;
  transform: translate(-50%, -50%) scale(9);
  box-shadow: 0 0 90px 34px rgba(148, 180, 255, 0.9);
}
.nova-core.spent { transition: opacity 0.3s ease; opacity: 0; }

/* Shockwave: a thin ring that outruns the fill, the way a real blast
   wave separates from its own fireball. */
.nova-shockwave {
  position: absolute; left: 50%; top: 50%; z-index: 3;
  width: 20px; height: 20px; border-radius: 50%;
  border: 1.5px solid rgba(214, 225, 255, 0.9);
  transform: translate(-50%, -50%) scale(0);
  opacity: 0;
  pointer-events: none;
}
.nova-shockwave.grow {
  transition: transform 2s cubic-bezier(0.1, 0.8, 0.2, 1), opacity 2s ease;
  transform: translate(-50%, -50%) scale(100);
  opacity: 0;
}

.nova-flash {
  position: absolute; left: 50%; top: 50%; z-index: 3;
  width: 40px; height: 40px; border-radius: 50%;
  transform: translate(-50%, -50%) scale(0);
  background: radial-gradient(circle, #FFFFFF 0%, #D6E1FF 32%, rgba(91, 140, 255, 0.55) 58%, transparent 74%);
  opacity: 0;
  pointer-events: none;
}
/* Slow, decelerating bloom — a real fireball keeps expanding well after
   its brightest instant, it doesn't just pop and vanish. */
.nova-flash.grow {
  transition: transform 2.1s cubic-bezier(0.1, 0.7, 0.15, 1), opacity 0.5s ease;
  transform: translate(-50%, -50%) scale(85);
  opacity: 1;
}
/* Then the light collapses back toward the centre as it dies down —
   feeding directly into the logo condensing out of it. */
.nova-flash.fade {
  transition: transform 1.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 1.3s ease;
  transform: translate(-50%, -50%) scale(8);
  opacity: 0;
}

.nova-shockwave.gone, .nova-flash.gone { display: none; }

.nova-content {
  position: relative; z-index: 5;
  display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 22px;
  max-width: 720px; padding: 0 24px;
}
.nova-logo {
  width: clamp(84px, 11vw, 160px);
  color: var(--accent);
  opacity: 0;
  transform: scale(0.85);
  filter: drop-shadow(0 0 40px var(--halo));
  transition: opacity 2s ease, transform 2s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.nova-logo svg { display: block; width: 100%; height: auto; }
.nova-content.logo-in .nova-logo { opacity: 1; transform: scale(1); }

.nova-headline {
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(32px, 5.5vw, 64px);
  font-weight: 500; letter-spacing: -0.02em; line-height: 1.1;
  color: var(--ink-0);
  opacity: 0; transform: translateY(20px);
  transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.nova-headline em {
  font-style: normal;
  background: linear-gradient(120deg, var(--accent), var(--accent-soft));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.nova-content.text-in .nova-headline { opacity: 1; transform: none; }

.nova-sub {
  color: var(--ink-1); font-size: 17px; line-height: 1.6; max-width: 520px;
  opacity: 0; transform: translateY(20px);
  transition: opacity 0.9s ease 0.15s, transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) 0.15s;
}
.nova-content.text-in .nova-sub { opacity: 1; transform: none; }

/* -------- SERVICES: interactive index + single detail panel --------
   Six short rows instead of six equally-loud cards. Only ONE description
   is ever on screen at a time (the active row's), which is what actually
   fixes the "too much text" problem — a bigger grid or shorter copy
   still shows six paragraphs at once, this shows one. */
.services { padding: 140px 0; }

.services-grid { display: flex; flex-direction: column; gap: 48px; }
@media (min-width: 900px) {
  .services-grid { flex-direction: row; align-items: flex-start; gap: 80px; }
  .services-head { flex: 1 1 0; position: sticky; top: 160px; }
  .cap-list { flex: 1 1 0; min-width: 0; }
}

.cap-list {
  display: flex; flex-direction: column;
  border-top: 1px solid var(--line);
}
.cap-row {
  display: flex; align-items: center; gap: 20px;
  width: 100%; padding: 24px 10px;
  border: none; border-bottom: 1px solid var(--line);
  border-radius: 10px;
  background: none; text-align: left; cursor: pointer;
  font: inherit;
  transition: background 0.3s ease;
}
.cap-row:hover { background: rgba(139, 144, 154, 0.06); }
.cap-row.active:hover { background: var(--halo); }
.cap-row-num {
  font-family: "JetBrains Mono", monospace;
  font-size: 12px; letter-spacing: 0.1em; color: var(--ink-3);
  transition: color 0.3s ease;
}
.cap-row-title {
  flex: 1;
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(19px, 2.4vw, 26px); font-weight: 500; letter-spacing: -0.01em;
  color: var(--ink-2);
  transition: color 0.3s ease;
}
.cap-row-arrow {
  color: var(--ink-3);
  transition: color 0.3s ease, transform 0.3s ease;
}
.cap-row:hover .cap-row-title { color: var(--ink-1); }
.cap-row.active .cap-row-num { color: var(--accent); }
.cap-row.active .cap-row-title { color: var(--ink-0); }
.cap-row.active .cap-row-arrow { color: var(--accent); transform: rotate(45deg); }

.cap-panel { display: none; padding: 24px 10px 8px; }
.cap-panel.active { display: block; animation: capIn 0.4s ease; }
@keyframes capIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.cap-panel-icon {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  color: var(--accent);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: rgba(139, 144, 154, 0.03);
}
.cap-panel-icon svg { width: 22px; height: 22px; }
.cap-panel-desc {
  margin-top: 20px;
  color: var(--ink-2); font-size: 16px; line-height: 1.6;
  max-width: 440px;
}
.cap-panel-link {
  margin-top: 22px;
  display: inline-flex; align-items: center; gap: 8px;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--accent);
  transition: gap 0.3s ease;
}
.cap-panel-link:hover { gap: 12px; }

/* .cap-list is a single flex column at every size — mobile and desktop
   both behave as an accordion (hover on desktop, tap on mobile) where a
   row's panel drops open directly beneath it. DOM order is 6 rows then
   6 panels, so `order` interleaves each panel right after its own row
   instead of letting it fall after all six rows. */
.cap-row:nth-of-type(1) { order: 1; }
.cap-panel:nth-of-type(1) { order: 2; }
.cap-row:nth-of-type(2) { order: 3; }
.cap-panel:nth-of-type(2) { order: 4; }
.cap-row:nth-of-type(3) { order: 5; }
.cap-panel:nth-of-type(3) { order: 6; }
.cap-row:nth-of-type(4) { order: 7; }
.cap-panel:nth-of-type(4) { order: 8; }
.cap-row:nth-of-type(5) { order: 9; }
.cap-panel:nth-of-type(5) { order: 10; }
.cap-row:nth-of-type(6) { order: 11; }
.cap-panel:nth-of-type(6) { order: 12; }

@media (min-width: 640px) {
  .cap-panel-desc { font-size: 17px; }
}

/* -------- PORTFOLIO: coverflow preview carousel --------
   No video files exist yet — each card is a styled slot (pulsing play
   icon + category tag) sized and ready to take a <video poster="…"> once
   real captures exist (see the HTML comment inside each slot). One card
   sits active and centered; the other two peek in from the edges and
   swap in on a timer or on click (script.js). An ambient star canvas
   runs behind the whole section, matching the hero/nova backdrops. */
.portfolio { position: relative; padding: 110px 0 130px; }
/* Faded top/bottom edges instead of a hard rectangle, so this section's
   star layer hands off to the hero's canvas above and nova's below
   without a visible seam — the space just keeps going. */
.portfolio-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  mask-image: linear-gradient(to bottom, transparent 0%, black 18%, black 78%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 18%, black 78%, transparent 100%);
}
.portfolio-eyebrow { position: relative; z-index: 2; display: flex; justify-content: center; margin-bottom: 56px; }

.portfolio-carousel { position: relative; z-index: 2; height: 470px; overflow: hidden; }
.portfolio-card {
  position: absolute; top: 50%; left: 50%;
  width: min(680px, 62%);
  transition: transform 0.9s cubic-bezier(0.22, 0.8, 0.25, 1);
}
.portfolio-card[data-role="active"] { transform: translate(-50%, -50%); z-index: 3; }
.portfolio-card[data-role="next"] { transform: translate(64%, -50%); z-index: 1; }
.portfolio-card[data-role="prev"] { transform: translate(-164%, -50%); z-index: 1; }

.portfolio-card-inner {
  display: flex; flex-direction: column; gap: 18px;
  cursor: pointer;
  transition: transform 0.9s cubic-bezier(0.22, 0.8, 0.25, 1), opacity 0.9s ease, filter 0.9s ease;
}
[data-role="active"] .portfolio-card-inner { transform: scale(1); opacity: 1; filter: none; cursor: default; }
[data-role="next"] .portfolio-card-inner,
[data-role="prev"] .portfolio-card-inner { transform: scale(0.78); opacity: 0.4; filter: blur(1px); }
[data-role="next"]:hover .portfolio-card-inner,
[data-role="prev"]:hover .portfolio-card-inner { opacity: 0.65; filter: blur(0.3px); }

.portfolio-frame {
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: 16px;
  border: 1px solid var(--line-strong);
  overflow: hidden;
  background:
    radial-gradient(120% 140% at 30% 0%, var(--halo), transparent 60%),
    linear-gradient(160deg, rgba(42, 51, 66, 0.9), rgba(11, 20, 38, 0.96));
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
  transition: border-color 0.4s ease, box-shadow 0.4s ease;
}
[data-role="active"] .portfolio-frame:hover {
  border-color: var(--accent);
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.5), 0 0 40px var(--accent-glow);
}
.portfolio-video-slot { position: absolute; inset: 0; display: grid; place-items: center; }
.portfolio-play {
  position: relative;
  width: 56px; height: 56px;
  border-radius: 50%;
  display: grid; place-items: center;
  padding-left: 3px;
  border: 1px solid var(--accent);
  background: rgba(11, 20, 38, 0.7);
  color: var(--accent);
  backdrop-filter: blur(6px);
  box-shadow: 0 0 24px var(--accent-glow);
}
.portfolio-play svg { width: 18px; height: 18px; }
.portfolio-play::before {
  content: "";
  position: absolute; inset: -10px;
  border: 1px solid var(--accent);
  border-radius: 50%;
  opacity: 0;
  animation: onetPing 3.2s ease-out infinite;
}
.portfolio-tag {
  position: absolute; left: 14px; top: 14px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: rgba(11, 20, 38, 0.72);
  backdrop-filter: blur(8px);
  font-family: "JetBrains Mono", monospace;
  font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-1);
}
.portfolio-title {
  padding-left: 4px;
  font-family: "Space Grotesk", sans-serif;
  font-size: 16px; font-weight: 500;
  color: var(--ink-0);
}
@media (max-width: 640px) {
  .portfolio-carousel { height: 340px; }
  .portfolio-card { width: 84%; }
  .portfolio-card[data-role="next"] { transform: translate(48%, -50%); }
  .portfolio-card[data-role="prev"] { transform: translate(-148%, -50%); }
}

/* -------- PROCESS -------- */
.process { padding: 80px 0; }
.process .section-head { margin-bottom: 24px; }

/* Orbit: an ascending flight path connecting the three stages, with a
   comet running the whole route on a loop. Desktop-only — the curve's
   waypoints (bottom-left -> top-right) don't fold into a narrow column
   sensibly, and the plain numbered dot on each .step-num already gives
   mobile visitors the same "connected stages" cue. */
.orbit { display: none; }
@media (min-width: 860px) {
  .orbit { display: block; position: relative; margin-bottom: 0; }
  .orbit-svg { display: block; width: 100%; height: auto; aspect-ratio: 1200 / 140; }
  .orbit-line {
    fill: none; stroke: var(--line-strong); stroke-width: 1.5;
    stroke-dasharray: 3 9; stroke-linecap: round;
  }
  .orbit-comet {
    fill: var(--accent);
    filter: drop-shadow(0 0 6px var(--accent)) drop-shadow(0 0 16px var(--accent-glow));
  }
  .orbit-stop {
    position: absolute; transform: translate(-50%, -50%);
    display: flex; align-items: center; gap: 10px;
  }
  .orbit-stop--1 { left: 3.3%; top: 81.25%; }
  .orbit-stop--2 { left: 50%; top: 37.5%; }
  .orbit-stop--3 { left: 96.7%; top: 12.5%; flex-direction: row-reverse; }
  .orbit-dot {
    width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0;
    background: var(--accent);
    box-shadow: 0 0 0 4px var(--halo), 0 0 14px var(--accent-glow);
    animation: dotPulse 3.4s ease-in-out infinite;
  }
  .orbit-stop--2 .orbit-dot { animation-delay: 0.4s; }
  .orbit-stop--3 .orbit-dot { animation-delay: 0.8s; }
  .orbit-tag {
    font-family: "JetBrains Mono", monospace; font-size: 10px; letter-spacing: 0.14em;
    color: var(--ink-1);
    padding: 4px 9px; border: 1px solid var(--line-strong); border-radius: 999px;
    background: rgba(11, 20, 38, 0.75); backdrop-filter: blur(6px);
    white-space: nowrap;
  }
}

.process-track {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
}
@media (max-width: 800px) { .process-track { grid-template-columns: 1fr; gap: 40px; } }
.step { position: relative; }
.step-num {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px; letter-spacing: 0.24em; color: var(--accent);
}
.step-num::before {
  content: ""; flex-shrink: 0;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px 1px var(--accent-glow);
  animation: dotPulse 3.4s ease-in-out infinite;
}
.step:nth-child(2) .step-num::before { animation-delay: 0.4s; }
.step:nth-child(3) .step-num::before { animation-delay: 0.8s; }
.step h3 {
  margin-top: 10px;
  font-family: "Space Grotesk", sans-serif;
  font-size: 22px;
  letter-spacing: -0.01em; font-weight: 500;
  line-height: 1.2;
  color: var(--ink-0);
}
.step p {
  margin-top: 10px;
  color: var(--ink-1); font-size: 14px; line-height: 1.55;
  max-width: 320px;
}
.step-meta {
  margin-top: 16px;
  display: flex; gap: 16px;
  font-family: "JetBrains Mono", monospace;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-3);
}
.step-meta span { display: inline-flex; align-items: center; gap: 6px; }
.step-meta span::before {
  content: ""; width: 4px; height: 4px; border-radius: 50%;
  background: var(--ink-3);
}

/* -------- WORKFLOW VISUAL: orbital signal network --------
   A pulsing "orchestrator" core with six satellite nodes (grouped
   input / reasoning / action) in a hexagonal orbit around it. Static
   spokes show the hub, a looping hexagon path carries glowing packets
   past all six in sequence, and every node breathes gently in place —
   the "live system" idea reframed as a small, moving solar system
   instead of a static flowchart. */
.workflow { padding: 140px 0; }
.workflow-grid { display: flex; flex-direction: column; gap: 40px; }
.workflow-grid .section-head { margin-bottom: 0; }
@media (min-width: 900px) {
  .workflow-grid { flex-direction: row; align-items: center; gap: 64px; }
  .workflow-grid .section-head { flex: 1 1 0; }
  .workflow-grid .orbit-net { flex: 1 1 0; }
}
.orbit-net {
  position: relative;
  width: 100%;
  aspect-ratio: 600 / 440;
  border: 1px solid var(--line-strong);
  border-radius: 20px;
  background:
    radial-gradient(600px 400px at 50% 50%, var(--halo), transparent 70%),
    linear-gradient(180deg, rgba(42, 51, 66, 0.6), rgba(19, 28, 45, 0.85));
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  overflow: hidden;
}
.orbit-net-canvas, .orbit-net-svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
}
.onet-spoke { stroke: var(--line-strong); stroke-width: 1; stroke-dasharray: 2 7; }
.onet-ring { fill: none; stroke: rgba(91, 140, 255, 0.28); stroke-width: 1.2; }
.onet-packet {
  fill: var(--accent);
  filter: drop-shadow(0 0 5px var(--accent)) drop-shadow(0 0 12px var(--accent-glow));
}

.onet-core {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  z-index: 3;
  width: 15%; aspect-ratio: 1;
  border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  background: radial-gradient(circle, rgba(91, 140, 255, 0.2), rgba(11, 20, 38, 0.92) 72%);
  border: 1px solid var(--accent);
  box-shadow: 0 0 40px var(--accent-glow), inset 0 0 18px rgba(91, 140, 255, 0.18);
}
.onet-core::before {
  content: ""; position: absolute; inset: -12%;
  border: 1px solid var(--accent);
  border-radius: 50%;
  opacity: 0;
  animation: onetPing 3.2s ease-out infinite;
}
@keyframes onetPing {
  0% { transform: scale(0.85); opacity: 0.55; }
  100% { transform: scale(1.5); opacity: 0; }
}
.onet-core svg { width: 26%; color: var(--accent); }
.onet-core span {
  font-family: "JetBrains Mono", monospace; font-size: 8px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ink-1);
}

.onet-node {
  position: absolute; transform: translate(-50%, -50%);
  z-index: 2;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 10px 14px;
  min-width: 100px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(42, 51, 66, 0.92), rgba(19, 28, 45, 0.95));
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.45);
  text-align: center;
  animation: onetDrift 7s ease-in-out infinite;
}
@keyframes onetDrift {
  0%, 100% { margin-top: 0; }
  50% { margin-top: -7px; }
}
.onet-icon { display: grid; place-items: center; color: var(--accent); }
.onet-icon svg { width: 15px; height: 15px; }
.onet-label {
  font-family: "JetBrains Mono", monospace; font-size: 8px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--ink-3);
}
.onet-title { font-family: "Space Grotesk", sans-serif; font-size: 12.5px; font-weight: 500; color: var(--ink-0); }
.onet-node[data-cat="reasoning"] .onet-icon { color: var(--accent-soft); }
.onet-node[data-cat="action"] .onet-icon { color: oklch(0.78 0.17 145); }

.onet-legend {
  position: absolute; left: 20px; top: 20px; z-index: 4;
  display: flex; flex-direction: column; gap: 8px;
  font-family: "JetBrains Mono", monospace;
  font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-2);
}
.onet-legend .row { display: inline-flex; align-items: center; gap: 8px; }
.onet-legend .dot { width: 6px; height: 6px; border-radius: 50%; }
.onet-legend .dot[data-cat="input"] { background: var(--accent); }
.onet-legend .dot[data-cat="reasoning"] { background: var(--accent-soft); }
.onet-legend .dot[data-cat="action"] { background: oklch(0.78 0.17 145); }

.onet-status {
  position: absolute; right: 20px; top: 20px; z-index: 4;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: rgba(19, 28, 45, 0.8);
  backdrop-filter: blur(10px);
  font-family: "JetBrains Mono", monospace;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-1);
}
.onet-status .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: oklch(0.78 0.17 145);
  box-shadow: 0 0 10px oklch(0.78 0.17 145 / 0.7);
  animation: pulseDot 1.6s ease-in-out infinite;
}
@keyframes pulseDot { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }

/* Below 900px the hexagonal orbit doesn't have room to breathe. Rather
   than shrink it into a cramped grid of identical boxed cards, drop the
   diagram geometry entirely and read the same six nodes top to bottom as
   a single hairline-divided list (matching the about/teaser treatment) —
   a thin glowing spine drops from the orchestrator into the list so it
   still reads as "flowing out of the core" instead of a plain menu, and
   each row's icon ring picks up its category color. */
@media (max-width: 899px) {
  .workflow { padding: 72px 0; }
  .orbit-net {
    aspect-ratio: unset;
    border: none;
    border-radius: 0;
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    overflow: visible;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 8px 0 0;
  }
  .orbit-net-svg, .onet-legend, .onet-status { display: none; }

  .onet-core {
    position: relative;
    top: auto; left: auto; transform: none;
    width: 92px;
    margin: 0 auto;
    /* the glow reaches well past the badge itself into the surrounding
       page instead of stopping tight at its own edge */
    box-shadow: 0 0 60px 14px var(--accent-glow), 0 0 150px 50px rgba(91, 140, 255, 0.14), inset 0 0 18px rgba(91, 140, 255, 0.18);
  }
  .onet-core::before {
    inset: -30%;
    animation: onetPingWide 3.2s ease-out infinite;
  }
  @keyframes onetPingWide {
    0% { transform: scale(0.8); opacity: 0.5; }
    100% { transform: scale(2.6); opacity: 0; }
  }
  .onet-core::after {
    content: "";
    position: absolute; left: 50%; top: 100%;
    width: 1px; height: 32px;
    background: linear-gradient(to bottom, var(--accent), transparent);
    transform: translateX(-50%);
  }

  .onet-core + .onet-node { margin-top: 40px; border-top: 1px solid var(--line); }
  .onet-node {
    position: static;
    transform: none;
    min-width: 0;
    width: 100%;
    display: grid;
    grid-template-columns: 34px 1fr;
    column-gap: 14px; row-gap: 2px;
    align-items: center;
    padding: 16px 2px;
    border: none; border-radius: 0;
    border-bottom: 1px solid var(--line);
    background: none;
    backdrop-filter: none; -webkit-backdrop-filter: none;
    box-shadow: none;
    text-align: left;
    animation: none;
  }
  .onet-icon {
    grid-row: 1 / 3; grid-column: 1;
    width: 34px; height: 34px;
    border-radius: 50%;
    border: 1px solid currentColor;
    background: rgba(255, 255, 255, 0.03);
  }
  .onet-label { grid-row: 1; grid-column: 2; align-self: end; font-size: 9px; }
  .onet-title { grid-row: 2; grid-column: 2; align-self: start; font-size: 14px; }
}

/* -------- ABOUT --------
   An editorial statement instead of a text-block-next-to-a-card-grid:
   full-width headline, an asymmetric lead/support line underneath it
   (the lead reads as a claim, not a caption), then the four traits as a
   single hairline-divided row instead of boxed cards. A large, very faint
   T-mark bleeds off the top-right corner with a few pulsing stars — a
   quiet signature rather than another icon-in-a-circle. */
.about { position: relative; padding: 140px 0; }

/* No clip here — the mark fades to nothing well before it would hit any
   edge, so it blends into the systems section above instead of getting
   cut off flat by a section boundary; html/body's overflow-x: hidden
   still keeps the horizontal bleed from causing a scrollbar. */
.about-emblem {
  position: absolute; top: 0; right: 0; width: 640px; height: 640px; pointer-events: none; z-index: 0;
  mask-image: linear-gradient(to bottom, transparent 0%, black 30%, black 75%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 30%, black 75%, transparent 100%);
}
.about-emblem-mark {
  position: absolute; top: -70px; right: -110px;
  width: 560px; height: auto;
  color: var(--accent);
  opacity: 0.07;
}
.about-emblem-star {
  position: absolute; left: var(--x); top: var(--y);
  width: 3px; height: 3px; border-radius: 50%;
  background: var(--ink-0);
  box-shadow: 0 0 6px 1px rgba(219, 228, 247, 0.6);
  animation: dotPulse 3.4s ease-in-out infinite;
  animation-delay: var(--d);
}

.about-head { position: relative; z-index: 1; max-width: 900px; }
.about-heading {
  margin-top: 18px;
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(40px, 5.5vw, 68px);
  letter-spacing: -0.025em; font-weight: 500;
  line-height: 1.05;
}
.about-heading em {
  font-style: normal;
  background: linear-gradient(120deg, var(--accent), var(--accent-soft));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.about-lead {
  position: relative; z-index: 1;
  margin-top: 48px;
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 64px;
  max-width: 1080px;
}
.about-lead-text { font-family: "Space Grotesk", sans-serif; font-size: 21px; line-height: 1.45; font-weight: 500; color: var(--ink-0); }
.about-support-text { font-size: 16px; line-height: 1.7; color: var(--ink-2); }

.about-marks {
  position: relative; z-index: 1;
  margin-top: 72px;
  padding-top: 40px;
  border-top: 1px solid var(--line);
  display: grid; grid-template-columns: repeat(4, 1fr);
}
.about-mark-item { padding: 0 28px; border-left: 1px solid var(--line); }
.about-mark-item:first-child { padding-left: 0; border-left: none; }
.about-mark-item .num {
  display: block;
  font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.18em;
  color: var(--accent);
}
.about-mark-item h4 {
  margin-top: 14px;
  font-family: "Space Grotesk", sans-serif; font-size: 19px; font-weight: 500; color: var(--ink-0);
}
.about-mark-item p { margin-top: 10px; color: var(--ink-2); font-size: 14px; line-height: 1.6; }

@media (max-width: 900px) {
  .about-lead { grid-template-columns: 1fr; gap: 20px; }
  .about-marks { grid-template-columns: 1fr 1fr; row-gap: 32px; }
  .about-mark-item:nth-child(3), .about-mark-item:nth-child(4) { border-top: 1px solid var(--line); padding-top: 24px; }
  .about-mark-item:nth-child(3) { border-left: none; padding-left: 0; }
  .about-emblem { width: 320px; height: 320px; }
  .about-emblem-mark { width: 260px; top: -40px; right: -60px; }
}
@media (max-width: 560px) {
  .about-marks { grid-template-columns: 1fr; row-gap: 24px; }
  .about-mark-item { border-left: none; padding-left: 0; }
  .about-mark-item:not(:first-child) { border-top: 1px solid var(--line); padding-top: 24px; }
}

/* -------- FOOTER -------- */
footer { position: relative; z-index: 1; border-top: 1px solid var(--line); margin-top: 80px; padding: 80px 0 48px; }
/* Stars bottom-weighted (script.js biases their y toward the floor) and
   additionally masked so they thin out and vanish before reaching the
   top border — dense at the page's actual end, nothing left by the time
   it meets the book section above. */
footer .container { position: relative; z-index: 1; }
.footer-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0;
  mask-image: linear-gradient(to bottom, transparent 0%, black 70%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 70%);
}
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 48px; align-items: start;
}
@media (max-width: 800px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) {
  .footer-grid { grid-template-columns: 1fr; gap: 36px; }
}
.footer-brand .logo { font-size: 16px; }
.footer-brand p {
  margin-top: 18px; max-width: 360px;
  color: var(--ink-2); font-size: 14px; line-height: 1.6;
}
.footer-col h5 {
  font-family: "JetBrains Mono", monospace;
  font-size: 10px; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--ink-3); font-weight: 400;
}
.footer-col ul { list-style: none; margin-top: 16px; display: flex; flex-direction: column; gap: 10px; font-size: 14px; color: var(--ink-1); }
.footer-col li a { transition: color 0.3s ease; overflow-wrap: anywhere; }
.footer-col li a:hover { color: var(--accent); }
.footer-bar {
  margin-top: 64px; padding-top: 24px;
  border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 24px; flex-wrap: wrap;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-3);
}
.socials { display: flex; gap: 8px; }
.social {
  width: 36px; height: 36px; display: grid; place-items: center;
  border: 1px solid var(--line-strong); border-radius: 50%;
  color: var(--ink-1);
  transition: color 0.3s ease, border-color 0.3s ease, background 0.3s ease, transform 0.3s ease;
}
.social:hover { color: var(--accent); border-color: var(--accent); background: var(--halo); transform: translateY(-2px); }
.social svg { width: 14px; height: 14px; }

/* Top announcement bar */
.topbar {
  position: relative; z-index: 60;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(90deg, rgba(19,28,45,0.92), rgba(42,51,66,0.92), rgba(19,28,45,0.92));
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  overflow: hidden;
  height: 38px;
  display: flex; align-items: center;
}
.topbar::before, .topbar::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 80px; z-index: 2; pointer-events: none;
}
.topbar::before { left: 0; background: linear-gradient(to right, rgba(19,28,45,1), transparent); }
.topbar::after  { right: 0; background: linear-gradient(to left,  rgba(19,28,45,1), transparent); }
.topbar-track {
  display: flex; align-items: center; gap: 60px;
  white-space: nowrap;
  animation: marquee 38s linear infinite;
  padding-left: 100%;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink-1);
}
.topbar-track span { display: inline-flex; align-items: center; gap: 14px; }
.topbar-track .pip {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 10px var(--accent-glow);
}
.topbar-track .sep { color: var(--ink-3); }
.topbar-track .hl { color: var(--accent); }
@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
.nav { top: 38px; }

/* Coming-soon teaser — same editorial treatment as About: no boxed card,
   full-width confident heading, an asymmetric row (copy beside the
   progress bar), then the four upcoming items as a hairline-divided
   grid instead of individually bordered pills. */
.teaser { padding: 140px 0; position: relative; }
.teaser::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(700px 400px at 88% 10%, var(--halo), transparent 70%),
    radial-gradient(500px 300px at 4% 95%, rgba(91, 140, 255, 0.1), transparent 70%);
  mask-image: linear-gradient(to bottom, transparent 0%, black 15%, black 85%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 15%, black 85%, transparent 100%);
}
.teaser-head { position: relative; z-index: 1; max-width: 900px; }
.teaser-status {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 8px 14px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: var(--halo);
  font-family: "JetBrains Mono", monospace;
  font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink-0);
}
.teaser-status .ring {
  position: relative; width: 8px; height: 8px;
}
.teaser-status .ring::before, .teaser-status .ring::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: var(--accent);
}
.teaser-status .ring::after {
  animation: pulse 2s ease-out infinite;
  opacity: 0.5;
}
.teaser-heading {
  margin-top: 22px;
  font-family: "Space Grotesk", sans-serif;
  font-size: clamp(40px, 5.5vw, 68px);
  font-weight: 500; letter-spacing: -0.025em; line-height: 1.05;
}
.teaser-heading em {
  font-style: normal;
  background: linear-gradient(120deg, var(--accent), var(--accent-soft));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

.teaser-lead {
  position: relative; z-index: 1;
  margin-top: 48px;
  display: grid; grid-template-columns: 1.3fr 1fr; gap: 64px; align-items: end;
  max-width: 1080px;
}
.teaser-desc { color: var(--ink-2); font-size: 16px; line-height: 1.7; }

.teaser-list {
  position: relative; z-index: 1;
  margin-top: 72px; padding-top: 40px;
  border-top: 1px solid var(--line);
  list-style: none;
  display: grid; grid-template-columns: 1fr 1fr;
  column-gap: 56px; row-gap: 36px;
}
.teaser-list li:nth-child(even) { padding-left: 28px; border-left: 1px solid var(--line); }
.teaser-list .label {
  display: block;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--accent);
}
.teaser-list strong {
  display: block; margin-top: 12px;
  font-family: "Space Grotesk", sans-serif;
  font-size: 18px; font-weight: 500; color: var(--ink-0); line-height: 1.4;
  letter-spacing: -0.005em;
}
@media (max-width: 900px) { .teaser-lead { grid-template-columns: 1fr; gap: 24px; } }
@media (max-width: 700px) {
  .teaser-list { grid-template-columns: 1fr; row-gap: 28px; }
  .teaser-list li:nth-child(even) { padding-left: 0; border-left: none; }
  .teaser-list li:not(:first-child) { padding-top: 24px; border-top: 1px solid var(--line); }
}

/* Progress bar */
.teaser-progress {
  display: flex; flex-direction: column; gap: 10px;
}
.teaser-progress-meta {
  display: flex; justify-content: space-between; align-items: center;
  font-family: "JetBrains Mono", monospace;
  font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink-2);
}
.teaser-progress-meta .pct { color: var(--accent); }
.teaser-progress-bar {
  position: relative;
  height: 2px; width: 100%;
  background: var(--line);
  border-radius: 1px; overflow: hidden;
}
.teaser-progress-bar > span {
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 62%;
  background: linear-gradient(to right, var(--accent-deep), var(--accent), var(--accent-soft));
  box-shadow: 0 0 14px var(--accent-glow);
}
.teaser-progress-bar::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 30%;
  background: linear-gradient(to right, transparent, rgba(255,255,255,0.5), transparent);
  animation: progressSweep 2.6s ease-in-out infinite;
}
@keyframes progressSweep {
  from { transform: translateX(-100%); }
  to   { transform: translateX(400%); }
}

/* Language switcher */
.lang-switch {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 3px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: rgba(139, 144, 154, 0.03);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  margin-right: 4px;
}
.lang-switch button {
  padding: 6px 10px;
  font-family: "JetBrains Mono", monospace;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-2);
  border-radius: 999px;
  transition: color 0.25s ease, background 0.25s ease;
}
.lang-switch button:hover { color: var(--ink-0); }
.lang-switch button.active {
  color: var(--ink-0);
  background: var(--halo);
  box-shadow: 0 0 0 1px var(--accent) inset;
}
@media (max-width: 540px) { .lang-switch { display: none; } }

/* Custom cursor accent (subtle) */
.cursor-glow {
  position: fixed; pointer-events: none; z-index: 1;
  width: 260px; height: 260px; border-radius: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(91, 140, 255, 0.09), transparent 70%);
  opacity: 0; transition: opacity 0.4s ease;
  mix-blend-mode: screen;
}
body:hover .cursor-glow { opacity: 0.6; }
@media (hover: none) { .cursor-glow { display: none; } }

/* -------- Reduced motion: ambient loops stop, content stays -------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .bg-grid, .topbar-track, .hero-tag .pulse::after, .teaser-status .ring::after,
  .teaser-progress-bar::after, .eyebrow::before, .step-num::before { animation: none !important; }
  .cap-panel.active { animation: none; }
  html.js .reveal, html.js .reveal-stagger > * { opacity: 1; transform: none; transition: none; }
  #hero-canvas, .cursor-glow, .footer-canvas { display: none; }
  .nova-canvas, .nova-core, .nova-flash, .nova-shockwave { display: none; }
  .orbit-comet { display: none; }
  .onet-packet { display: none; }
  .onet-core::before { animation: none !important; opacity: 0; }
  .onet-node { animation: none !important; }
  .portfolio-card, .portfolio-card-inner { transition: none !important; }
  .about-emblem-star { animation: none !important; }
  .portfolio-play::before { animation: none !important; opacity: 0; }
  .nova-logo, .nova-headline, .nova-sub {
    opacity: 1 !important; transform: none !important; transition: none !important;
  }
}

/* -------- Focus visibility (keyboard) -------- */
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

/* -------- Book a call --------
   The whole section (heading + full booking form) is meant to fit within
   one screen — no scrolling needed to go from "Book a call." to the submit
   button. That drives every size below: tighter paddings/gaps than the
   rest of the page, a 3-up row for name/email/phone instead of stacking
   them, the optional automate/imagine questions tucked behind a closed
   <details> disclosure, and a capped, internally-scrollable slot list. */
/* min-height accounts for the 112px scroll-margin-top (see `section[id]`
   above) that the nav-anchor jump lands the section at, so the section's
   own box — not 100vh — is what has to fit under the fixed nav. */
.book { position: relative; padding: 28px 0; z-index: 2; min-height: calc(100vh - 112px); min-height: calc(100svh - 112px); display: flex; align-items: center; }
.book-grid { display: grid; grid-template-columns: 1fr 1.25fr; gap: 56px; align-items: center; width: 100%; }
.book-eyebrow {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--ink-2);
}
.book-intro h2 {
  font-family: "Space Grotesk", "Inter", sans-serif;
  font-size: clamp(32px, 3.4vw, 44px); line-height: 1.08; letter-spacing: -0.02em;
  margin: 14px 0 12px; font-weight: 500;
}
.book-intro p { color: var(--ink-1); font-size: 15px; max-width: 400px; line-height: 1.5; }
.book-contact {
  margin-top: 20px;
  display: flex; gap: 12px; flex-wrap: wrap;
  font-family: "JetBrains Mono", monospace;
  font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-2);
}
.book-contact a { transition: color 0.25s ease; }
.book-contact a:hover { color: var(--accent); }
.book-form {
  display: flex; flex-direction: column; gap: 12px;
  padding: 22px 24px;
  border: 1px solid var(--line-strong);
  border-radius: 20px;
  background: rgba(139, 144, 154, 0.025);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
}
.book-form label { display: flex; flex-direction: column; gap: 6px; }
.book-form label > span {
  font-family: "JetBrains Mono", monospace;
  font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-2);
}
.book-form input, .book-form textarea {
  background: rgba(255,255,255,0.02);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 13px;
  color: var(--ink-0);
  font: inherit; font-size: 14px;
  transition: border-color 0.25s ease, background 0.25s ease;
}
.book-form input::placeholder, .book-form textarea::placeholder { color: var(--ink-3); }
.book-form input:focus, .book-form textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: rgba(139, 144, 154, 0.05);
}
.book-form textarea { resize: vertical; min-height: 52px; font-family: inherit; }
.book-form button { cursor: pointer; }
.book-form button:disabled { opacity: 0.5; cursor: default; }
.book-row3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.book-slot-picker { display: flex; flex-direction: column; gap: 10px; }
.book-form input[type="date"] { color-scheme: dark; }
.book-slots-wrap { display: flex; flex-direction: column; gap: 6px; }
.book-slots-wrap > span {
  font-family: "JetBrains Mono", monospace;
  font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-2);
}
.book-slots {
  display: flex; flex-wrap: wrap; gap: 6px;
  max-height: 92px; overflow-y: auto;
  padding-right: 2px;
}
.book-slots::-webkit-scrollbar { width: 6px; }
.book-slots::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 3px; }
.book-slots-hint { font-size: 12px; margin: 0; }
.book-slot-btn {
  border: 1px solid var(--line);
  background: rgba(255,255,255,0.02);
  color: var(--ink-0);
  border-radius: 8px;
  padding: 6px 11px;
  font: inherit; font-size: 13px;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.book-slot-btn:hover { border-color: var(--accent); }
.book-slot-btn.is-selected { border-color: var(--accent); background: var(--accent); color: #fff; }
.book-checkbox {
  flex-direction: row !important;
  align-items: center;
  gap: 9px !important;
  cursor: pointer;
}
.book-checkbox input[type="checkbox"] {
  width: 16px; height: 16px; flex: none;
  accent-color: var(--accent);
  cursor: pointer;
}
.book-checkbox span { font-size: 13px; color: var(--ink-1); text-transform: none; letter-spacing: normal; font-family: inherit; }
.book-more { border-top: 1px solid var(--line); padding-top: 10px; }
.book-more summary {
  cursor: pointer; list-style: none;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px; letter-spacing: 0.1em;
  color: var(--ink-2);
  transition: color 0.2s ease;
}
.book-more summary::-webkit-details-marker { display: none; }
.book-more summary:hover { color: var(--accent-soft); }
.book-more[open] summary { color: var(--ink-0); margin-bottom: 10px; }
.book-more-body { display: flex; flex-direction: column; gap: 10px; }
.book-submit-row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 2px; }
#form-status { font-size: 12px; line-height: 1.4; color: var(--ink-1); margin: 0; }
.book-privacy { margin: 0; font-size: 11px; line-height: 1.4; color: var(--ink-3); }
@media (max-width: 900px) {
  /* The fit-on-one-screen treatment only makes sense on desktop, where
     there's room beside the form for the heading. Below 900px the two
     columns stack, so let the section grow and scroll normally instead
     of squeezing an unreadably tiny form into 100vh. */
  .book { padding: 80px 0 40px; min-height: 0; display: block; }
  .book-grid { grid-template-columns: 1fr; gap: 32px; }
  .book-row3 { grid-template-columns: 1fr; }
}

/* -------- Cookie consent -------- */
.cookie-banner {
  position: fixed; left: 20px; right: 20px; bottom: 20px; z-index: 200;
  max-width: 640px; margin: 0 auto;
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  padding: 20px 24px;
  background: rgba(19, 28, 45, 0.92);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
  opacity: 0; transform: translateY(16px); transition: opacity 0.4s ease, transform 0.4s ease;
}
.cookie-banner.show { opacity: 1; transform: translateY(0); }
.cookie-banner[hidden] { display: none; }
.cookie-banner p { flex: 1 1 320px; font-size: 13px; line-height: 1.6; color: var(--ink-1); }
.cookie-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.cookie-actions .btn { padding: 10px 18px; font-size: 13px; }
@media (max-width: 640px) {
  .cookie-banner { left: 12px; right: 12px; bottom: 12px; padding: 18px; }
  .cookie-actions { width: 100%; }
  .cookie-actions .btn { flex: 1; justify-content: center; }
}

/* -------- Mobile spacing --------
   The 140px/100vh rhythm reads fine on desktop, where a section's own
   width gives text somewhere to go; on a narrow phone the same numbers
   just stack into long stretches of empty starfield between sections
   that already have far less content per line. Nova is the worst
   offender — a flex-centered short headline inside a forced 100vh box
   leaves ~280px of dead space above and below it alone. Compact
   everything for phones instead of scaling the desktop numbers down. */
@media (max-width: 640px) {
  .hero { padding: 130px 0 56px; }
  .nova, .nova-stage { min-height: 62vh; min-height: 62svh; }
  .portfolio { padding: 56px 0 64px; }
  .services, .about, .teaser { padding: 64px 0; }
  .process { padding: 56px 0; }
  footer { margin-top: 48px; padding: 56px 0 40px; }

  /* Nova burn, logo and text reveal run roughly twice as fast on phones
     (script.js shortens the setTimeout schedule to match) — otherwise a
     transition tuned to feel cinematic on desktop just reads as sluggish
     on a screen people are already scrolling past quickly. */
  .nova-core.igniting { transition-duration: 0.5s; }
  .nova-shockwave.grow { transition-duration: 1.1s; }
  .nova-flash.grow { transition-duration: 1.1s; }
  .nova-flash.fade { transition-duration: 0.7s; }
  .nova-logo { transition-duration: 1s; }
  .nova-headline, .nova-sub { transition-duration: 0.5s; }
}
