/* Rogi.AI — Redesign prototype (short copy) */

:root {
  --bg: #080808;
  --surface: #111111;
  --surface-2: #181818;
  --border: rgba(255, 255, 255, 0.08);
  --text: #ececec;
  --text-muted: #8a8a8a;
  --text-dim: #5c5c5c;
  --accent: #69e7ce;
  --accent-soft: rgba(105, 231, 206, 0.12);
  --max: 1120px;
  --header-h: 72px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Hero (Figma 20:255) — light theme, editorial */
  --hero-bg: #ffffff;
  --hero-ink: #000000;
  --hero-ink-active: #161616;
  --hero-ink-muted: #666666;
  --hero-ink-quiet: #949494;
  --hero-label: #888888;
  --hero-rule: #e5e5e5;
  --font-display: "Forma DJR Display", "DM Sans", "Inter", -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: "Fragment Mono", ui-monospace, "SF Mono", Menlo, monospace;
  /* Fixed header — height reserves space above section content
     (large enough for hero brand height AND for the 5-item vertical nav) */
  --site-header-h: 220px;
}

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

html { scroll-behavior: smooth; font-size: 16px; }

body {
  font: 400 16px/1.6 Inter, system-ui, sans-serif;
  color: var(--text-muted);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; border: none; background: none; cursor: pointer; color: inherit; }
address { font-style: normal; }

.container {
  width: min(var(--max), 100% - 48px);
  margin-inline: auto;
}

/* Typography */
.logo {
  font: 600 18px/1 Inter, sans-serif;
  color: var(--text);
  letter-spacing: -0.02em;
}
.logo--sm { font-size: 15px; }
.logo__dot { color: var(--accent); }

.eyebrow {
  font: 500 11px/1 JetBrains Mono, monospace;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 20px;
}

h1 {
  font: 700 clamp(40px, 6vw, 72px)/1.02 Syne, sans-serif;
  letter-spacing: -0.03em;
  color: var(--text);
  margin-bottom: 24px;
}

h1 em {
  font-style: normal;
  color: var(--accent);
}

h2 {
  font: 600 clamp(28px, 4vw, 44px)/1.08 Syne, sans-serif;
  letter-spacing: -0.025em;
  color: var(--text);
}

h3 {
  font: 500 17px/1.3 Inter, sans-serif;
  color: var(--text);
}

.lead, .section-lead, .product-body, .tagline {
  font-size: 17px;
  line-height: 1.65;
  max-width: 52ch;
}

.hook {
  margin-top: 16px;
  color: var(--text-dim);
  max-width: 46ch;
}

.hook strong { color: var(--text); font-weight: 500; }

.accent { color: var(--accent); }

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 14px 24px;
  border-radius: 999px;
  font: 500 14px/1 Inter, sans-serif;
  transition: background 0.25s, color 0.25s, border-color 0.25s;
}

.btn--primary {
  background: var(--accent);
  color: #041410;
}

.btn--primary:hover { background: #7ef0da; }

.btn--ghost {
  border: 1px solid var(--border);
  color: var(--text);
}

.btn--ghost:hover { border-color: rgba(255,255,255,0.2); }

/* ============================================================
   Hero — Figma node 20:255
   Editorial light layout: brand + inline nav, wide image,
   3-column facts strip. Forma DJR Display (fallback DM Sans),
   Inter for nav, Fragment Mono for labels.
   ============================================================ */

.hero-section {
  background: var(--hero-bg);
  color: var(--hero-ink);
  padding: var(--site-header-h) clamp(20px, 4vw, 44px) clamp(20px, 4vw, 44px);
  /* Stable viewport unit. `100dvh` is dynamic — it grows as the iOS
     address bar retracts on scroll, which resizes the section mid-
     animation and drags the ScrollTrigger `bottom bottom` anchor
     with it. Result: a visible curve "peek" the moment scroll
     starts, because the trigger progress was already > 0 by the
     time the section finished settling. `100svh` = the small
     viewport height (screen minus the address bar), stable across
     the address-bar collapse, so the trigger fires from a rock-
     steady zero baseline. */
  height: 100vh;
  height: 100svh;
  width: 100%;
  position: relative;
  overflow: hidden;
  display: flex;
}

.hero-inner {
  flex: 1;
  max-width: 1440px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: clamp(20px, 2.5vw, 32px);
  min-height: 0;
  width: 100%;
}

/* ============================================================
   Shared fixed header — brand cross-fade + single nav with
   animated color scheme (light → dark on scroll).
   ============================================================ */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  padding: clamp(20px, 4vw, 44px);
  pointer-events: none;
  /* Animated by GSAP on scroll */
  --nav-ink: #666666;
  --nav-ink-active: #161616;
}

.site-header__inner {
  max-width: 1440px;
  margin-inline: auto;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px;
}

.site-header a,
.site-header nav {
  pointer-events: auto;
}

/* Brand swap: two overlapping brand states */
.brand-swap {
  position: relative;
  min-width: 440px;
  height: 100px;
  flex-shrink: 0;
}

.brand {
  position: absolute;
  top: 0;
  left: 0;
  will-change: opacity;
}

.brand--hero {
  display: flex;
  flex-direction: column;
  gap: 4px;
  opacity: 1;
}

.brand--compact {
  display: block;
  width: 40px;
  height: 40px;
  opacity: 0;
}

.brand--compact img {
  width: 100%;
  height: 100%;
  display: block;
}

.brand__eyebrow {
  font: 400 clamp(13px, 1.2vw, 18px)/1.2 var(--font-display);
  color: var(--hero-ink-quiet);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  margin: 0;
}

.brand__title {
  font: 500 clamp(38px, 6.5vw, 66px)/1.2 var(--font-display);
  color: #000;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  margin: 0;
}

/* Single nav — colors animated via CSS custom properties */
.site-nav {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 16px;
  padding-top: 4px;
  flex-shrink: 0;
}

.site-nav a {
  font: 500 16px/1 Inter, -apple-system, BlinkMacSystemFont, sans-serif;
  color: var(--nav-ink);
  transition: color 0.2s ease;
  white-space: nowrap;
}

.site-nav a:hover,
.site-nav a.is-active {
  color: var(--nav-ink-active);
}

.site-nav a.is-active { font-weight: 700; }

/* Media */
.hero-media {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  border-radius: 2px;
  background: #0a0a0a;
}

.hero-media img,
.hero-media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* Facts strip */
.hero-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  margin: 0;
}

.hero-fact {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-top: 12px;
  border-top: 1px solid var(--hero-rule);
}

.hero-fact dt {
  /* Match .brand__eyebrow ("BUILDING INTELLECTUAL DEVICES") 1:1 —
     same face, size, weight, color, tracking, transform. */
  font: 400 clamp(13px, 1.2vw, 18px)/1.2 var(--font-display);
  color: var(--hero-ink-quiet);
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.hero-fact dd {
  /* Value is the primary content of each row — must dominate the
     label above it. Prior #949494 was below WCAG AA on white
     (~2.85:1); --hero-ink-active (#161616) restores the hierarchy
     (label = quiet gray, value = near-black) and passes AA at any
     size. Weight bumped from 300 to 400 so the display face is
     legible at 16px without needing a heavier size. */
  font: 400 16px/1.35 var(--font-display);
  color: var(--hero-ink-active);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin: 0;
}

.hero-fact dd a {
  color: inherit;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s;
}

.hero-fact dd a:hover { border-bottom-color: currentColor; }

/* Scroll transition curve (morphs upward on scroll to About) */
.scene-curve {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 5;
  pointer-events: none;
  will-change: transform;
}

.scene-curve__path {
  will-change: d;
}

/* ============================================================
   Mobile Hero — Figma node 51:31 (380 × 888 phone frame)
   Layout: header stays as row (brand column left, nav column right),
   image fills below, facts stack vertically with hairline top rules.
   ============================================================ */
@media (max-width: 720px) {
  :root {
    /* Header content (eyebrow 10px + title 32px + 44px top padding)
       fits in ~200px; reserve a bit more to keep the image below the
       fixed header from getting cramped on the shortest viewports. */
    --site-header-h: 205px;
  }

  /* Header stays row (brand left, nav right column), matching Figma. */
  .site-header {
    padding: 44px clamp(20px, 6vw, 44px);
  }
  .site-header__inner {
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    gap: 20px;
  }
  .brand-swap {
    min-width: 0;
    height: auto;
    flex: 1 1 auto;
  }
  .brand--hero { gap: 2px; }
  .brand__eyebrow {
    /* Figma: 10px / 1px tracking (= 0.1em) */
    font-size: 10px;
    letter-spacing: 0.1em;
  }
  .brand__title {
    /* Figma: 32px / 1.6px tracking (= 0.05em), Medium */
    font-size: 32px;
    letter-spacing: 0.05em;
  }
  .site-nav {
    flex-direction: column;
    align-items: flex-end;
    gap: 12px;
    padding-top: 0;
    flex: 0 0 auto;
  }
  .site-nav a {
    /* Figma: 12px Inter, Medium (Home = Bold, handled by .is-active) */
    font: 500 12px/1 Inter, -apple-system, BlinkMacSystemFont, sans-serif;
  }

  /* Hero content — vertical column below fixed header. Section is
     locked to 100svh (small viewport height) — the screen minus the
     iOS address bar. Unlike `100dvh`, `100svh` does not grow when
     the address bar retracts on scroll, so the section's bottom
     edge is a stable reference point for the ScrollTrigger curve
     morph and the whole hero always fits in one screen without
     scroll. Earlier `height: auto` + a portrait 3:4 GIF (~454 px
     tall on a 393-wide phone) overflowed the viewport by ~90 px
     and forced the user to scroll to reach BASE / FOCUS / EMAIL. */
  .hero-section {
    padding: var(--site-header-h) clamp(20px, 6vw, 44px) clamp(20px, 6vw, 44px);
    height: 100vh;
    height: 100svh;
  }
  .hero-inner { gap: 24px; }

  /* Media absorbs whatever vertical space is left after the header
     padding + facts strip. Aspect ratio is dropped so the GIF turns
     into a responsive landscape rectangle instead of a fixed 3:4
     portrait tile — always fits the remaining slot, never pushes
     the fact rows below the fold. `min-height` keeps the media
     legible on very short viewports (< 650 dvh). */
  .hero-media {
    flex: 1 1 0;
    aspect-ratio: auto;
    width: 100%;
    min-height: 140px;
  }

  /* Facts — vertical stack with hairline top borders (Figma 51:43). */
  .hero-facts {
    grid-template-columns: 1fr;
    gap: 0;
  }
  .hero-fact {
    padding-block: 12px;
    gap: 4px;
  }
  .hero-fact dt {
    /* Figma 51:45 label: 10px, 1px tracking, quiet-gray. */
    font-size: 10px;
    letter-spacing: 0.1em;
  }
  .hero-fact dd {
    /* Figma value: 16px, 0.8px tracking (= 0.05em) — kept from base. */
    font-size: 16px;
  }
}

/* ============================================================
   About — Figma node 20:276
   Dark #252525 band, centered manifesto: kicker → big headline
   → hairline → body → CTA button.
   ============================================================ */

.about-section {
  background: #0e1010;
  color: #f3f3f3;
  padding: clamp(20px, 4vw, 44px);
  /* Stable — see .hero-section note. About also hosts the second
     curve morph reference (the Hero → About reveal target), so its
     height needs to be as steady as Hero's. */
  height: 100vh;
  height: 100svh;
  width: 100%;
  position: relative;
  display: flex;
  overflow: hidden;
}

.about-inner {
  flex: 1;
  max-width: 1440px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
}

.about-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: 100%;
}

.about-kicker {
  font: 400 11px/1 var(--font-mono);
  color: #e5e5e5;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 0;
}

.about-heading {
  font: 500 clamp(28px, 4.4vw, 44px)/1.2 var(--font-display);
  color: #f3f3f3;
  letter-spacing: 0.05em;
  text-align: center;
  max-width: 640px;
  margin: 0;
}

.about-rule {
  width: min(100%, 688px);
  height: 0;
  border: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  margin: 4px 0 0;
}

.about-body {
  font: 400 18px/1.6 Inter, -apple-system, BlinkMacSystemFont, sans-serif;
  color: #e5e5e5;
  text-align: center;
  max-width: 522px;
  margin: 0;
}

.about-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 16px 32px;
  margin-top: 28px;
  background: #e5e5e5;
  color: #0e1010;
  font: 600 14px/1 Inter, -apple-system, BlinkMacSystemFont, sans-serif;
  letter-spacing: 0.02em;
  transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.about-cta:hover {
  background: #ffffff;
  transform: translateY(-1px);
}

.about-cta:active { transform: translateY(0); }

@media (max-width: 720px) {
  .about-content { gap: 10px; }
}

/* ============================================================
   Projects — Figma node 20:349
   Light editorial section: kicker + heading, followed by a
   horizontal peek-gallery of 6 items that bleeds past the right
   edge, hinting there's more to scroll horizontally.
   ============================================================ */

.projects-section {
  background: #ffffff;
  color: #161616;
  padding: var(--site-header-h) 0 clamp(20px, 4vw, 44px);
  min-height: 100vh;
  width: 100%;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: clamp(32px, 5vh, 64px);
  overflow: hidden;
}

.projects-inner {
  /* Effective content width (after `padding-inline`) is 1440px, which
     matches Leadership's inner exactly — Leadership puts its clamp()
     gutter on the section itself, so its 1440-cap centres inside the
     already-inset content box. Projects has to keep the section
     full-bleed (for the marquee), so we bake the same gutter into
     both the inner's `max-width` and its `padding-inline`. Result:
     the heading's left edge lines up with Leadership at any viewport,
     including anything wider than 1440. */
  max-width: calc(1440px + 2 * clamp(20px, 4vw, 44px));
  margin-inline: auto;
  padding-inline: clamp(20px, 4vw, 44px);
  width: 100%;
}

.projects-head {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.projects-kicker {
  font: 400 11px/1 var(--font-mono);
  color: #888;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 0;
}

.projects-heading {
  font: 500 clamp(28px, 4.4vw, 44px)/1.2 var(--font-display);
  color: #000;
  letter-spacing: 0.05em;
  /* Same intrinsic width as Leadership's .leadership-head__intro (638px)
     — this is what "same offset as A three-person core…" comes down to
     in Figma spec (node 20:363 → w-[638px]). Ensures both headings sit
     at identical top y AND wrap on the same horizontal grid. */
  max-width: 638px;
  margin: 0;
}

.projects-heading br { display: block; }

/* Infinite marquee — natively scrollable box.
   `overflow-x: auto` lets the user pan the gallery with a finger /
   trackpad; a rAF loop in JS advances `scrollLeft` at a steady rate
   for the auto-marquee effect. Track holds two identical copies of
   the item set; JS wraps `scrollLeft` past one set-width to make
   the loop seamless. `touch-action: pan-x` keeps vertical page
   scroll working when the user swipes up/down over the strip, and
   `overscroll-behavior-x: contain` prevents the swipe from
   triggering iOS Safari's back/forward navigation gesture. */
.projects-marquee {
  width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  margin-top: auto;
  padding-block: 4px;
  touch-action: pan-x;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.projects-marquee::-webkit-scrollbar { display: none; }

.projects-marquee__track {
  display: flex;
  align-items: center;
  gap: 36px;
  width: max-content;
  user-select: none;
}

.projects-item {
  flex: 0 0 auto;
  margin: 0;
  overflow: hidden;
}

.projects-item img,
.projects-item video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  -webkit-user-drag: none;
  user-select: none;
}

/* Exact widths & heights from Figma (20:349 children + 51:30) */
.projects-item--metal  { width: 456px; height: 255px; }
.projects-item--silver { width: 331px; height: 246px; }
.projects-item--mesh   { width: 381px; height: 353px; }
.projects-item--clear  { width: 491px; height: 319px; }
.projects-item--3d     { width: 628px; height: 353px; }
.projects-item--photo  { width: 354px; height: 353px; }

/* Camera item has a light-gray plate with the product centered on it */
.projects-item--camera {
  width: 354px;
  height: 353px;
  background: #e4e4e4;
  display: flex;
  align-items: center;
  justify-content: center;
}
.projects-item--camera img {
  width: 78%;
  height: 78%;
  object-fit: contain;
}

@media (max-width: 720px) {
  .projects-heading br { display: none; }
  .projects-item--metal  { width: 320px; height: 180px; }
  .projects-item--silver { width: 240px; height: 180px; }
  .projects-item--mesh   { width: 260px; height: 240px; }
  .projects-item--clear  { width: 340px; height: 220px; }
  .projects-item--3d     { width: 420px; height: 240px; }
  .projects-item--camera { width: 240px; height: 240px; }
  .projects-item--photo  { width: 240px; height: 240px; }
}

/* ============================================================
   Leadership — Figma node 23:3357
   Light section, 100vh. Top row: kicker + heading (left) and
   supporting paragraph (right). Bottom row: three 350×350 portrait
   cards with name + role, evenly distributed.
   ============================================================ */

.leadership-section {
  background: #ffffff;
  color: #161616;
  padding: var(--site-header-h) clamp(20px, 4vw, 44px) clamp(20px, 4vw, 44px);
  min-height: 100vh;
  width: 100%;
  position: relative;
  display: flex;
  overflow: hidden;
}

.leadership-inner {
  flex: 1;
  max-width: 1440px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  /* Fixed gap between head and people row — no `justify-content:
     space-between`, which was stretching the whitespace to fill
     the whole flex column. This value is roughly half of the
     previously observed visible gap. */
  gap: clamp(48px, 8vh, 100px);
  width: 100%;
  min-height: 0;
}

/* Head — two columns, top-aligned, justified apart */
.leadership-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 40px;
  width: 100%;
}

.leadership-head__intro {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 638px;
}

.leadership-kicker {
  font: 400 11px/1 var(--font-mono);
  color: #888;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  margin: 0;
}

.leadership-heading {
  font: 500 clamp(28px, 4.4vw, 44px)/1.2 var(--font-display);
  color: #000;
  letter-spacing: 0.05em;
  margin: 0;
}

.leadership-body {
  font: 400 clamp(15px, 1.2vw, 18px)/1.6 Inter, -apple-system, BlinkMacSystemFont, sans-serif;
  color: #666;
  max-width: 490px;
  margin: 0;
  flex-shrink: 0;
}

/* People row — three cards, space-between */
.leadership-people {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  width: 100%;
}

.person-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 44px;
  flex-shrink: 0;
}

.person-card__photo {
  width: clamp(220px, 24vw, 350px);
  aspect-ratio: 1;
  overflow: hidden;
  position: relative;
  pointer-events: none;
}

/* Faithful re-creation of the per-image crops from Figma:
   Savva     — image fills 350×350 exactly (no offset).
   Andrey    — h 149.06%, top -6.53% (vertical stretch, crop from top).
   Savelii   — h 149.94%, top -3.79% (same, but slightly less crop). */
.person-card__photo img {
  position: absolute;
  left: 0;
  display: block;
  width: 100%;
}

.person-card__photo--savva img {
  top: 0;
  height: 100%;
}
.person-card__photo--andrey img {
  top: -6.53%;
  height: 149.06%;
}
.person-card__photo--savelii img {
  top: -3.79%;
  height: 149.94%;
}

.person-card__meta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
}

.person-card__name {
  font: 400 22px/1 var(--font-display);
  color: #000;
  letter-spacing: 0.02em;
  margin: 0;
  white-space: nowrap;
}

.person-card__role {
  font: 400 14px/1 Inter, -apple-system, BlinkMacSystemFont, sans-serif;
  color: #666;
  margin: 0;
  white-space: nowrap;
}

@media (max-width: 900px) {
  .leadership-heading br { display: none; }
  .leadership-head {
    flex-direction: column;
    gap: 24px;
  }
  .leadership-people {
    flex-direction: column;
    gap: 44px;
  }
  .person-card__photo {
    width: clamp(220px, 60vw, 300px);
  }
}

/* Mobile-only: with three portrait cards stacked vertically, the last
   card's meta ("Lead Product Designer") sits ~20 px above the section
   edge (default clamp bottom padding), then Contact's dark bg begins
   abruptly. Bump the bottom padding to exactly 100 px so there's a
   clear breathing gap between the last card and the section end. */
@media (max-width: 720px) {
  .leadership-section {
    padding-bottom: 100px;
  }
}

/* ============================================================
   Contact — Figma node 23:3462
   Dark section, mirrors About's palette. Big centered "Say Hi",
   thin rule, stacked underlined links. Revealed via the scene-curve
   inside the Leadership section (same technique as Hero → About).
   ============================================================ */

.contact-section {
  background: #0e1010;
  color: #f3f3f3;
  padding: var(--site-header-h) clamp(20px, 4vw, 44px) clamp(20px, 4vw, 44px);
  min-height: 100vh;
  width: 100%;
  position: relative;
  display: flex;
  overflow: hidden;
}

.contact-inner {
  flex: 1;
  max-width: 1440px;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding-block: clamp(48px, 10vh, 100px);
  width: 100%;
}

.contact-heading {
  font: 500 clamp(40px, 6.2vw, 66px)/1.2 var(--font-display);
  color: #f3f3f3;
  letter-spacing: 0.05em;
  text-align: center;
  margin: 0;
}

/* ============================================================
   Contact heading — typewriter variant
   Ghost span reserves the full-text width so the h2 stays
   centered inside .contact-inner from the start. The overlay
   (position: absolute over the ghost) lays out the typed text
   + caret left-aligned so characters appear left-to-right,
   matching Framer-style typewriter behaviour. Both the overlay
   and caret animation are gated by the `.is-typing` class,
   which JS adds when the section actually enters the viewport
   — so nothing (not even the caret) is visible before the user
   scrolls to it.
   ============================================================ */

.contact-heading.contact-heading--typewriter,
.reveal-stagger > .contact-heading--typewriter {
  position: relative;
  /* Two-class / descendant selectors bump specificity to (0,0,2,0)
     so this override wins over `.reveal-stagger > *` — the heading
     stays visible from the start (ghost reserves layout, overlay
     hidden), and the typing animation controls appearance instead
     of the generic reveal-fade. */
  opacity: 1;
  transform: none;
  transition: none;
}

.contact-heading__ghost {
  visibility: hidden;
  white-space: nowrap;
}

.contact-heading__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: baseline;
  justify-content: flex-start;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.25s ease-out;
}

.contact-heading--typewriter.is-typing .contact-heading__overlay {
  opacity: 1;
}

.contact-heading__typed {
  color: inherit;
  white-space: pre;
}

.contact-heading__caret {
  display: inline-block;
  width: 0.06em;
  min-width: 3px;
  height: 0.85em;
  background: currentColor;
  margin-left: 0.05em;
  vertical-align: -6%;
  opacity: 0;
}

.contact-heading--typewriter.is-typing .contact-heading__caret {
  animation: contact-caret-blink 1s steps(2) infinite;
}

@keyframes contact-caret-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  /* Reduced motion — no blink, and JS shows text immediately. */
  .contact-heading__caret,
  .contact-heading--typewriter.is-typing .contact-heading__caret {
    animation: none;
    opacity: 1;
  }
  .contact-heading__overlay { opacity: 1; }
}

.contact-rule {
  width: min(100%, 688px);
  height: 0;
  border: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  margin: 0;
}

.contact-links {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding-block: 12px;
}

.contact-link {
  font: 400 clamp(22px, 2.6vw, 33px)/1.3 var(--font-display);
  color: #f3f3f3;
  letter-spacing: 0.04em;
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 1px;
  transition: opacity 0.2s ease;
}

.contact-link:hover { opacity: 0.7; }

/* Scoped position for the Leadership → Contact curve.
   Base .scene-curve rules (absolute inset:0, z-index:5, pointer-events:none)
   already apply; this variant just documents intent. */
.scene-curve--to-contact {
  /* inherits everything from .scene-curve */
}

/* Sections */
.section {
  padding: 96px 0;
  border-top: 1px solid var(--border);
}

.section-head {
  display: grid;
  gap: 20px;
  margin-bottom: 48px;
}

@media (min-width: 768px) {
  .section-head {
    grid-template-columns: minmax(180px, 280px) 1fr;
    gap: 48px;
    align-items: start;
  }
}

/* Facts */
.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: 16px;
  overflow: hidden;
  margin-bottom: 32px;
}

.facts__item {
  background: var(--surface);
  padding: 20px 22px;
}

.facts__item dt {
  font: 500 10px/1 JetBrains Mono, monospace;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 8px;
}

.facts__item dd {
  font-size: 14px;
  color: var(--text);
  line-height: 1.45;
}

.facts__item--accent dd { color: var(--accent); }

/* Cards */
.cards {
  display: grid;
  gap: 16px;
}

@media (min-width: 768px) {
  .cards { grid-template-columns: repeat(3, 1fr); }
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 28px;
  transition: border-color 0.3s, transform 0.3s var(--ease);
}

.card:hover {
  border-color: rgba(105, 231, 206, 0.35);
  transform: translateY(-2px);
}

.card__num {
  font: 500 11px/1 JetBrains Mono, monospace;
  color: var(--text-dim);
  display: block;
  margin-bottom: 20px;
}

.card h3 { margin-bottom: 10px; }
.card p { font-size: 14px; line-height: 1.55; }

/* Product */
.section--product {
  background: linear-gradient(180deg, var(--bg) 0%, #0c1210 50%, var(--bg) 100%);
}

.product-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-end;
  gap: 16px;
  margin-bottom: 24px;
}

.status {
  font: 500 11px/1 JetBrains Mono, monospace;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.product-body { margin-bottom: 40px; }

.gallery {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 24px;
  margin-bottom: 32px;
}

@media (min-width: 768px) {
  .gallery { padding: 32px; }
}

.gallery__controls {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 28px;
}

.swatch {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-radius: 999px;
  border: 1px solid var(--border);
  font: 500 11px/1 JetBrains Mono, monospace;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}

.swatch.active {
  border-color: var(--accent);
  color: var(--text);
  background: var(--accent-soft);
}

.swatch__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.15);
}

.swatch__dot--black { background: #1a1a1a; }
.swatch__dot--silver { background: linear-gradient(135deg, #d8d8d8, #888); }
.swatch__dot--titanium { background: linear-gradient(135deg, #6a6a6a, #3a3a3a); }

.gallery__stage { position: relative; min-height: 220px; }

.variant {
  display: none;
  grid-template-columns: 1fr;
  gap: 16px;
}

.variant.active {
  display: grid;
  animation: fadeIn 0.4s var(--ease);
}

@media (min-width: 640px) {
  .variant.active { grid-template-columns: 1.2fr 0.8fr; }
}

.variant figure {
  background: var(--surface-2);
  border-radius: 12px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.variant img {
  width: 100%;
  height: auto;
  object-fit: contain;
}

.variant figcaption {
  font: 500 10px/1 JetBrains Mono, monospace;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

.specs {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--border);
  border-top: 1px solid var(--border);
  margin-top: 24px;
  border-radius: 12px;
  overflow: hidden;
}

@media (min-width: 640px) {
  .specs { grid-template-columns: repeat(4, 1fr); }
}

.specs > div {
  background: var(--surface-2);
  padding: 16px 18px;
}

.specs dt {
  font: 500 10px/1 JetBrains Mono, monospace;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 6px;
}

.specs dd { font-size: 13px; color: var(--text); }

.highlights {
  list-style: none;
  display: grid;
  gap: 12px;
}

@media (min-width: 640px) {
  .highlights { grid-template-columns: repeat(2, 1fr); }
}

.highlights li {
  font-size: 14px;
  padding-left: 18px;
  position: relative;
}

.highlights li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

/* Team */
.section-copy {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.section-copy .tagline {
  color: var(--text);
  font-size: 20px;
  line-height: 1.35;
  max-width: 30ch;
}

.section-copy p:not(.tagline) {
  color: var(--text-muted);
  max-width: 54ch;
}

.team-grid {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}

@media (min-width: 720px) {
  .team-grid { grid-template-columns: repeat(3, 1fr); gap: 20px; }
}

.person {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 18px;
  overflow: hidden;
  transition: border-color 0.3s, transform 0.3s var(--ease);
}

.person:hover {
  border-color: rgba(105, 231, 206, 0.28);
  transform: translateY(-2px);
}

.person__photo {
  position: relative;
  aspect-ratio: 4 / 5;
  background:
    linear-gradient(135deg, var(--surface-2) 0%, #101010 100%);
  overflow: hidden;
}

.person__photo::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(45deg, transparent 46%, rgba(255,255,255,0.03) 46%, rgba(255,255,255,0.03) 54%, transparent 54%);
  background-size: 24px 24px;
  opacity: 0.6;
}

.person__slot {
  position: absolute;
  bottom: 16px;
  left: 18px;
  font: 500 11px/1 JetBrains Mono, monospace;
  letter-spacing: 0.14em;
  color: var(--text-dim);
}

.person__meta {
  padding: 18px 20px 22px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.person__meta h3 {
  font: 500 17px/1.2 Inter, sans-serif;
  color: var(--text);
  letter-spacing: -0.005em;
}

.person__meta p {
  font-size: 13px;
  color: var(--text-dim);
}

/* Contact */
.section--contact { padding-bottom: 64px; }

.contact {
  display: grid;
  gap: 40px;
}

@media (min-width: 768px) {
  .contact {
    grid-template-columns: 1fr 1.2fr;
    gap: 64px;
    align-items: start;
  }
}

.contact address {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 16px;
  font-size: 15px;
  color: var(--text-muted);
}

.contact__list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--border);
}

.contact__list a {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 0;
  border-bottom: 1px solid var(--border);
  transition: color 0.2s;
}

.contact__list a span:first-child {
  font-size: 13px;
  color: var(--text-dim);
}

.contact__list a span:last-child {
  font-size: 14px;
  color: var(--text);
}

.contact__list a:hover span:last-child { color: var(--accent); }

/* Reveal */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}

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

.reveal-stagger > * {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.55s var(--ease), transform 0.55s var(--ease);
}

.reveal-stagger > *.visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal, .reveal-stagger > *, .variant.active { animation: none; transition: none; opacity: 1; transform: none; }
}

/* ============================================================
   Preloader — 12-blade radial spinner (Apple-style).
   Direct port of the React `<Spinner>` component supplied by
   the user: `.spinner-blade` × 12 arranged around a square
   container, each with staggered opacity fade so a single
   "lit" blade appears to rotate around the ring. Blade metrics
   use em units, so container width/height (via .spinner--sm/md/lg)
   drives everything else — matches the source's h-3/h-4/h-6.
   ============================================================ */

.preloader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  pointer-events: auto;
}

/* White "cover" is drawn by the SVG path (not the div bg) so it can
   be morphed away with GSAP MorphSVG on exit — same mechanism the
   scene-curves in Hero and Leadership use. viewBox 0-100 with
   `preserveAspectRatio="none"` stretches to any viewport size. */
.preloader-mask {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  pointer-events: none;
}

.preloader-mask__path {
  fill: #ffffff;
}

.spinner {
  position: relative;
  display: inline-block;
  color: #161616;
  z-index: 2;
}

/* Matches the React component's size prop: sm=12, md=16, lg=24 (px). */
.spinner--sm { width: 12px; height: 12px; font-size: 12px; }
.spinner--md { width: 16px; height: 16px; font-size: 16px; }
.spinner--lg { width: 24px; height: 24px; font-size: 24px; }

.spinner-blade {
  position: absolute;
  left: 0.4629em;
  bottom: 0;
  width: 0.074em;
  height: 0.2777em;
  border-radius: 0.0555em;
  background: currentColor;
  /* Rotate each blade around the container centre — origin sits
     0.2222em above the blade's top edge, which lands exactly at
     the container's vertical midpoint (blade top is 0.7223em
     from container top; 0.7223 − 0.2223 = 0.5em). */
  transform-origin: center -0.2222em;
  animation: spinner-fade 1s linear infinite;
  will-change: opacity;
}

/* 12 blades every 30°. Negative animation-delays put every blade
   at a different phase of the fade at t=0, giving the rotating
   "chase" without any CSS keyframe knowing about rotation. */
.spinner-blade:nth-child(1)  { transform: rotate(0deg);   animation-delay: -0.917s; }
.spinner-blade:nth-child(2)  { transform: rotate(30deg);  animation-delay: -0.833s; }
.spinner-blade:nth-child(3)  { transform: rotate(60deg);  animation-delay: -0.750s; }
.spinner-blade:nth-child(4)  { transform: rotate(90deg);  animation-delay: -0.667s; }
.spinner-blade:nth-child(5)  { transform: rotate(120deg); animation-delay: -0.583s; }
.spinner-blade:nth-child(6)  { transform: rotate(150deg); animation-delay: -0.500s; }
.spinner-blade:nth-child(7)  { transform: rotate(180deg); animation-delay: -0.417s; }
.spinner-blade:nth-child(8)  { transform: rotate(210deg); animation-delay: -0.333s; }
.spinner-blade:nth-child(9)  { transform: rotate(240deg); animation-delay: -0.250s; }
.spinner-blade:nth-child(10) { transform: rotate(270deg); animation-delay: -0.167s; }
.spinner-blade:nth-child(11) { transform: rotate(300deg); animation-delay: -0.083s; }
.spinner-blade:nth-child(12) { transform: rotate(330deg); animation-delay:  0.000s; }

@keyframes spinner-fade {
  0%   { opacity: 1; }
  100% { opacity: 0.15; }
}

@media (prefers-reduced-motion: reduce) {
  .spinner-blade { animation: none; opacity: 0.4; }
}
