/* ==========================================================================
   hero.css — homepage hero (product showroom) + site-wide brand tokens.
   One dedicated stylesheet. Small enough to inline the critical parts if you
   wish (see README). No @import, no external fonts fetched at runtime.
   ========================================================================== */

/* --- Self-hosted display font. Drop the subsetted woff2 in static/fonts/ ----
   Until the file exists the robust condensed fallback stack below is used, so
   the hero never blocks on the font (font-display: swap). See README for the
   subsetting command. */
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/BarlowCondensed-SemiBold.ba4513495282.woff2") format("woff2");
}
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/BarlowCondensed-Bold.e1180918b873.woff2") format("woff2");
}

/* Register accent as an animatable custom property so a discipline change can
   smoothly cross-tint (plain --vars don't transition without @property). */
@property --color-accent {
  syntax: "<color>";
  inherits: true;
  initial-value: #e08a3c;
}
@property --color-accent-soft {
  syntax: "<color>";
  inherits: true;
  initial-value: #f0a057;
}

/* ==========================================================================
   BRAND TOKENS — named generically; the rest of the site inherits these later.
   ========================================================================== */
/* Brand tokens (accent / base tones / text / fonts / radii) now live once in
   tokens.css — the single source, per the token-reconciliation decision (design
   leads). hero.css keeps only hero-specific tokens below and consumes the rest.
   tokens.css is loaded before hero.css everywhere the hero renders (base.html
   head + the /dev/hero/ preview). */
:root {
  /* Studio lighting (mood shifts per discipline via accent) */
  --studio-key: rgba(255, 244, 232, 0.17);
  --studio-rim: color-mix(in srgb, var(--color-accent) 55%, transparent);
  --studio-floor: rgba(0, 0, 0, 0.55);

  /* Warm scrim over the background photo (matches the warm base tone). */
  --scrim-top: rgba(13, 10, 7, 0.52);
  --scrim-bottom: rgba(13, 10, 7, 0.86);
  --scrim-vignette: rgba(13, 10, 7, 0.55);

  /* Motion */
  --ease-stage: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur-relight: 620ms;

  /* Stage sizing */
  --stage-w: min(46vh, 520px);
}

/* --- Discipline accent + lighting-mood overrides (data-attribute driven) --- */
.hero[data-discipline="race"] {
  --color-accent: #ff4326;
  --color-accent-soft: #ff7a5c;
  --studio-key: rgba(255, 235, 230, 0.20);
}
.hero[data-discipline="adventure"] {
  --color-accent: #e08a3c;
  --color-accent-soft: #f0a057;
  --studio-key: rgba(255, 244, 232, 0.17);
}
.hero[data-discipline="offroad"] {
  --color-accent: #f2a900;
  --color-accent-soft: #ffca55;
  --studio-key: rgba(255, 249, 232, 0.19);
}

/* --- Light mode: warm off-white studio, same staging logic (proper invert) - */
.hero[data-theme="light"] {
  --color-bg-deep: #efe9e1;
  --color-bg: #f6f2ec;
  --color-surface: rgba(20, 16, 12, 0.05);
  --color-surface-strong: rgba(20, 16, 12, 0.09);
  --color-line: rgba(30, 22, 16, 0.22);
  --color-hairline: rgba(30, 22, 16, 0.12);
  --color-text: #211b16;
  --color-text-dim: rgba(33, 27, 22, 0.72);
  --color-text-muted: rgba(33, 27, 22, 0.5);
  --studio-key: rgba(255, 255, 255, 0.85);
  --studio-floor: rgba(60, 40, 24, 0.22);
  /* warm off-white scrim so dark text stays legible over the photo */
  --scrim-top: rgba(246, 242, 236, 0.55);
  --scrim-bottom: rgba(246, 242, 236, 0.88);
  --scrim-vignette: rgba(246, 242, 236, 0.5);
}

/* ==========================================================================
   HERO SHELL
   ========================================================================== */
.hero {
  position: relative;
  isolation: isolate;
  min-height: 100svh;
  overflow: hidden;
  background: var(--color-bg-deep);
  color: var(--color-text);
  font-family: var(--font-body);
  transition: background var(--dur-relight) var(--ease-stage),
              color var(--dur-relight) var(--ease-stage),
              --color-accent var(--dur-relight) var(--ease-stage),
              --color-accent-soft var(--dur-relight) var(--ease-stage);
}
.hero *,
.hero *::before,
.hero *::after { box-sizing: border-box; }

/* --- Full-bleed background photo (behind everything) ----------------------- */
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: block;
}
.hero__bg-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 42%;
}

/* --- The scrim: darken/tint the photo + key light, rim glow, topo texture --- */
.hero__void {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    /* rim glow from the accent, low + behind the figure */
    radial-gradient(120% 80% at 50% 120%, var(--studio-rim) 0%, transparent 52%),
    /* dramatic key light, upper-centre */
    radial-gradient(80% 60% at 50% -6%, var(--studio-key) 0%, transparent 55%),
    /* top + bottom darkening so the switcher and headline stay legible */
    linear-gradient(to bottom,
      var(--scrim-top) 0%, transparent 26%, transparent 54%, var(--scrim-bottom) 100%),
    /* edge vignette to seat the figure in the scene */
    radial-gradient(130% 100% at 50% 46%, transparent 42%, var(--scrim-vignette) 100%);
  transition: background var(--dur-relight) var(--ease-stage);
}
/* Low-contrast topographic contour motif — texture, not decoration */
.hero__void::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.5;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1100' height='1100' viewBox='0 0 1100 1100'%3E%3Cg fill='none' stroke='%23ffffff' stroke-opacity='0.06' stroke-width='1'%3E%3Cpath d='M60 550 C 260 380, 840 720, 1040 540'/%3E%3Cpath d='M40 640 C 280 470, 820 820, 1060 620'/%3E%3Cpath d='M80 460 C 300 300, 800 640, 1020 460'/%3E%3Cpath d='M20 740 C 300 560, 840 900, 1080 700'/%3E%3Cpath d='M100 370 C 320 230, 780 560, 1000 380'/%3E%3Cpath d='M50 830 C 320 650, 820 980, 1070 800'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 130% 130%;
  background-position: center;
}

/* ==========================================================================
   DISCIPLINE SWITCHER
   ========================================================================== */
.hero__switcher {
  position: absolute;
  top: clamp(1rem, 3.2vh, 2.2rem);
  /* centre with auto-margins, NOT transform — the entrance animation owns
     `transform`, so translateX(-50%) here would be clobbered mid-animation. */
  left: 0;
  right: 0;
  margin-inline: auto;
  width: max-content;
  max-width: calc(100vw - 1.5rem);
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.3rem;
  border-radius: var(--radius-chip);
  background: var(--color-surface);
  border: 1px solid var(--color-hairline);
  backdrop-filter: blur(8px);
}
.hero__disc {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--color-text-muted);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(0.85rem, 1.4vw, 1.02rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.5rem 1.05rem;
  min-height: 44px;
  border-radius: var(--radius-chip);
  cursor: pointer;
  white-space: nowrap;
  transition: color 200ms ease, background 200ms ease;
}
.hero__disc:hover { color: var(--color-text-dim); }
.hero__disc.is-active {
  color: var(--color-text);
  background: color-mix(in srgb, var(--color-accent) 22%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-accent) 55%, transparent);
}
.hero__disc:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* ==========================================================================
   STAGE  (poster LCP + model-viewer island + floor)
   ========================================================================== */
.hero__stage {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 5.5rem 1rem 4.5rem;
}
.hero__model {
  position: relative;
  width: var(--stage-w);
  aspect-ratio: 4 / 5;
  max-width: 92vw;
}

/* soft round pedestal glow behind the feet */
.hero__pedestal {
  position: absolute;
  z-index: 1;
  left: 50%;
  bottom: calc(4.5rem - 4vh);
  transform: translateX(-50%);
  width: min(60vh, 640px);
  height: min(60vh, 640px);
  pointer-events: none;
  background: radial-gradient(closest-side,
      color-mix(in srgb, var(--color-accent) 20%, transparent) 0%,
      transparent 70%);
  filter: blur(6px);
  opacity: 0.7;
}

/* Poster hidden per design (the placeholder silhouette looked bad during load);
   the background photo covers first paint. The <img> stays in the HTML (crawlable
   + explicit dimensions). Swap in a real render and set display:block to restore
   it as the LCP still. */
.hero__poster {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: none;
  transition: opacity 520ms var(--ease-stage);
}
.hero__poster-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center bottom;
  filter: drop-shadow(0 32px 40px rgba(0, 0, 0, 0.55));
}
/* When the 3D has faded in, retire the poster */
.hero.is-model-ready .hero__poster { opacity: 0; pointer-events: none; }

/* model-viewer island */
.hero__mv {
  position: absolute;
  inset: 0;
  z-index: 3;
  width: 100%;
  height: 100%;
  background: transparent;
  --poster-color: transparent;
  --progress-bar-color: transparent;
  --progress-bar-height: 0px;
  opacity: 0;
  transition: opacity 520ms var(--ease-stage);
}
/* kill model-viewer's loading progress bar entirely */
.hero__mv::part(default-progress-bar) { display: none; }
.hero.is-model-ready .hero__mv { opacity: 1; }
/* brief opacity dip while a discipline swap loads the next GLB */
.hero.is-swapping .hero__mv { opacity: 0; }
.hero.is-swapping .hero__poster { opacity: 1; }

/* faked floor: contact shadow + soft mirror reflection (CSS, no heavy scene) */
.hero__floor {
  position: absolute;
  z-index: 1;
  left: 50%;
  bottom: -2%;
  transform: translateX(-50%);
  width: 78%;
  height: 16%;
  pointer-events: none;
  background:
    radial-gradient(60% 55% at 50% 42%, var(--studio-floor) 0%, transparent 72%);
}
.hero__floor::after { /* faint sheen line where figure meets floor */
  content: "";
  position: absolute;
  left: 12%;
  right: 12%;
  top: 40%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--color-hairline), transparent);
}

/* ==========================================================================
   HOTSPOT CHIPS  (anchored spec-chips w/ leader line, defined state)
   ========================================================================== */
.hero__chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--leader);
  text-decoration: none;
  white-space: nowrap;
  /* place the bulb (chip origin) on the projected 3D point */
  transform: translate(-8px, -50%);
  --leader: 13px;
  --hotspot: #ffffff;   /* white default; turns yellow on hover */
}
/* flat white bulb (1:1 with the reference) + soft pulsing halo */
/* Bulb — matches the site's Three.js hotspots exactly: a flat white disc
   (unlit SphereGeometry #fff) with a separate faint white ring (RingGeometry,
   0.25 opacity, ~2x the dot). Only the RING pulses: scale = 1 + sin(t)*0.3
   i.e. 0.7 <-> 1.3, ~2.1s. Hover tint = #f4a61e (both dot + ring). */
.hero__chip-dot {
  position: relative;
  flex: 0 0 auto;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--hotspot);
  /* faint 1px edge only — the scene bulb is flat/unlit, no drop shadow */
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18);
  transition: background 160ms ease;
}
.hero__chip-dot::after {   /* faint ring (opacity 0.25) that pulses 0.7<->1.3 */
  content: "";
  position: absolute;
  inset: -7px;
  border-radius: 50%;
  border: 3px solid var(--hotspot);
  opacity: 0.25;
  pointer-events: none;
  animation: hero-bulb-ring 2.1s ease-in-out infinite;
}
@keyframes hero-bulb-ring {
  0%, 100% { transform: scale(0.7); }
  50%      { transform: scale(1.3); }
}
.hero__chip-label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #9e9e9e;              /* greyed out */
  text-shadow: none;
  transition: color 160ms ease;
}
/* left-side hotspots: dot stays on the body, label floats to its LEFT */
.hero__chip--left .hero__chip-label {
  position: absolute;
  right: calc(100% + var(--leader));
  top: 50%;
  transform: translateY(-50%);
}
/* hover / focus -> yellow (label, bulb, and halo all re-tint via --hotspot) */
.hero__chip:hover,
.hero__chip:focus-visible { --hotspot: #f4a61e; }
.hero__chip:hover .hero__chip-label,
.hero__chip:focus-visible .hero__chip-label { color: #f4a61e; }
.hero__chip:hover .hero__chip-dot,
.hero__chip:focus-visible .hero__chip-dot {
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5),
              0 0 10px color-mix(in srgb, var(--hotspot) 80%, transparent);
}
.hero__chip:focus-visible { outline: none; }
.hero__chip:focus-visible .hero__chip-label {
  outline: 2px solid var(--hotspot);
  outline-offset: 3px;
}

/* ==========================================================================
   FALLBACK / NO-JS  — model-viewer undefined => chips flow as a readable row
   below the poster. Same nodes, zero JS DOM-moving.
   ========================================================================== */
.hero__chips-caption {
  display: none;
  margin: 0.2rem 0 0.6rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  text-align: center;
}
.hero__stage:has(.hero__mv:not(:defined)) .hero__chips-caption { display: block; }

.hero__mv:not(:defined) {
  position: static;
  inset: auto;
  height: auto;
  opacity: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  max-width: 92vw;
}
.hero__mv:not(:defined) .hero__chip {
  transform: none;
  position: static;
}
.hero__mv:not(:defined) .hero__chip--left .hero__chip-label,
.hero__mv:not(:defined) .hero__chip-label {
  position: static;
  right: auto;
  transform: none;
}
/* keep the poster in normal flow so the row sits beneath it (not overlapping) */
.hero__stage:has(.hero__mv:not(:defined)) .hero__poster { position: relative; }
.hero__stage:has(.hero__mv:not(:defined)) .hero__model {
  aspect-ratio: auto;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* JS-built mobile chip row (nodes moved out of model-viewer on small screens) */
.hero__chips-row {
  display: none;
  gap: 0.5rem;
  width: 100%;
  max-width: 92vw;
  margin-top: 1rem;
  padding: 0.2rem 0.2rem 0.6rem;
  overflow-x: auto;
  scrollbar-width: none;
  scroll-snap-type: x proximity;
}
.hero__chips-row::-webkit-scrollbar { display: none; }
.hero__chips-row .hero__chip {
  transform: none;
  scroll-snap-align: start;
  flex: 0 0 auto;
}
.hero__chips-row .hero__chip--left .hero__chip-label,
.hero__chips-row .hero__chip-label { position: static; right: auto; transform: none; }

/* ==========================================================================
   HEADLINE OVERLAY (bottom-left)
   ========================================================================== */
.hero__copy {
  position: absolute;
  left: clamp(1.1rem, 4vw, 3.4rem);
  bottom: clamp(1.2rem, 4vh, 2.8rem);
  z-index: 6;
  max-width: min(46ch, 80vw);
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.45);
}
.hero[data-theme="light"] .hero__copy { text-shadow: 0 2px 18px rgba(255, 255, 255, 0.5); }
.hero__kicker {
  margin: 0 0 0.55rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.74rem;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: #9e9e9e;
}
.hero__headline {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.7rem, 3.6vw, 3rem);
  line-height: 1.02;
  letter-spacing: 0.005em;
  text-transform: uppercase;
  color: var(--color-text);
}
.hero__headline span { display: block; white-space: nowrap; }
.hero__headline-accent { color: var(--color-accent); }
.hero__subline {
  margin: 0.7rem 0 0;
  font-size: clamp(0.9rem, 1.6vw, 1.05rem);
  letter-spacing: 0.02em;
  color: var(--color-text-dim);
}

/* ==========================================================================
   CONTROLS (play/pause + theme)
   ========================================================================== */
.hero__controls {
  position: absolute;
  right: clamp(1rem, 3vw, 2.2rem);
  bottom: clamp(1.2rem, 4vh, 2.4rem);
  z-index: 6;
  display: flex;
  gap: 0.6rem;
}
.hero__ctrl {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-surface);
  border: 1px solid var(--color-hairline);
  color: var(--color-text-dim);
  cursor: pointer;
  backdrop-filter: blur(8px);
  transition: color 180ms ease, border-color 180ms ease, background 180ms ease;
}
.hero__ctrl:hover {
  color: var(--color-text);
  border-color: color-mix(in srgb, var(--color-accent) 60%, transparent);
}
.hero__ctrl:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.hero__icon {
  width: 20px;
  height: 20px;
  fill: currentColor;
  stroke: currentColor;
  stroke-width: 0;
}
.hero__icon--sun,
.hero__icon--sun path { fill: none; stroke: currentColor; }
/* icon visibility per state */
.hero__ctrl--play .hero__icon--play { display: none; }
.hero__ctrl--play[aria-pressed="false"] .hero__icon--pause { display: none; }
.hero__ctrl--play[aria-pressed="false"] .hero__icon--play { display: block; }
.hero__ctrl--theme .hero__icon--sun { display: none; }
.hero[data-theme="light"] .hero__ctrl--theme .hero__icon--moon { display: none; }
.hero[data-theme="light"] .hero__ctrl--theme .hero__icon--sun { display: block; }

/* ==========================================================================
   ENTRANCE ANIMATION (staggered, first load) + idle motion
   ========================================================================== */
@keyframes hero-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes hero-fade { from { opacity: 0; } to { opacity: 1; } }
.hero__switcher { animation: hero-rise 640ms var(--ease-stage) both; }
.hero__copy     { animation: hero-rise 720ms 120ms var(--ease-stage) both; }
.hero__controls { animation: hero-rise 720ms 220ms var(--ease-stage) both; }
.hero__model    { animation: hero-fade 900ms 80ms var(--ease-stage) both; }
.hero__chip     { animation: hero-fade 600ms calc(260ms + var(--i, 0) * 90ms) var(--ease-stage) both; }

/* Desktop: sit the figure right-of-centre (like the production site) so the
   far-left Helmets label has room and the headline gets breathing space. */
@media (min-width: 721px) {
  /* Wide element so <model-viewer> (which clips hotspot labels at its own
     bounds) has horizontal room for the outer labels. The model frames to
     height, so it stays the same size and just gets side margin. */
  .hero__model {
    width: min(88vw, 780px);
    height: min(64vh, 580px);
    aspect-ratio: auto;
    transform: translateX(3%);
  }
  .hero__pedestal { left: 52%; }
}

/* ==========================================================================
   MOBILE  (≤ 720px): chips collapse below the model, no float over the figure
   ========================================================================== */
@media (max-width: 720px) {
  /* Bigger figure now that the hotspots no longer sit alongside it (−10%). */
  :root { --stage-w: min(79vw, 396px); }
  /* Centre the chibi in the middle of the hero. */
  .hero__stage { justify-content: center; padding: 4rem 0.75rem 5rem; }
  .hero__headline { font-size: clamp(1.5rem, 6.4vw, 2.2rem); }
  .hero__copy { max-width: 88vw; }
  .hero__controls { bottom: clamp(1rem, 3vh, 1.6rem); }

  /* Hotspots stay anchored on the figure (with labels) — no caption/row.
     Only Helmets (dot on the held helmet at the figure's edge) would run off the
     left edge, so flip just that label to point inward. Pants/Boots face left. */
  .hero__chips-caption { display: none; }
  /* Nudge hotspots on mobile (~5% of the figure ≈ 21px). Helmets: down + right;
     Pants: down. */
  /* Helmets shifted right enough that its left-facing label keeps its leader gap
     and still clears the model-viewer's left edge. */
  .hero__chip[slot="hotspot-helmets"] { top: 19px; left: 10px; }
  .hero__chip[slot="hotspot-pants"] { top: 19px; }
  /* Jackets + Gloves nudged 5% right. */
  .hero__chip[slot="hotspot-jackets"] { left: 6px; top: -11px; }
  .hero__chip[slot="hotspot-gloves"] { left: 15px; }
  /* White hotspot labels on mobile. */
  .hero__chip-label { color: #fff; }
  /* Bigger tap target: an invisible ~44px hit area around each dot (visual size
     of the dot is unchanged). */
  .hero__chip-dot::before { content: ""; position: absolute; inset: -26px; border-radius: 50%; }
  /* No play/pause control on mobile. */
  .hero__controls { display: none; }
  /* Bigger near-black shadow rising from the bottom, up behind the title — grounds
     the figure and gives depth so it doesn't feel cramped against the headline. */
  .hero__void::before {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(to top,
      rgba(5, 4, 3, 0.98) 0%, rgba(5, 4, 3, 0.92) 13%,
      rgba(5, 4, 3, 0.55) 30%, transparent 48%);
  }
  /* No pre-upgrade "horizontal hotspots" flash: keep the chips hidden until the
     model has loaded and anchored them onto the figure. */
  .hero:not(.is-model-ready) .hero__chip { visibility: hidden; }
  /* Stop hotspot labels being clipped at the model's edges as it rotates: extend the
     <model-viewer> box past the screen edges so its clip bounds sit off-viewport.
     The figure frames to height, so its size/centre are unchanged; .hero overflow
     hidden clips the off-screen margins (no horizontal scroll). */
  .hero__mv { left: -20vw; right: -20vw; width: auto; }
}

/* Guarantee no horizontal overflow at 360px */
@media (max-width: 380px) {
  :root { --stage-w: min(70vw, 300px); }
  .hero__switcher { gap: 0; padding: 0.25rem; }
  .hero__disc { padding: 0.5rem 0.7rem; letter-spacing: 0.1em; }
}

/* ==========================================================================
   REDUCED MOTION — no auto-rotate, no entrance, static poster acceptable
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .hero,
  .hero *,
  .hero *::before,
  .hero *::after {
    animation: none !important;
    transition: none !important;
  }
}
