/* theme.css — Nova Pulse: warm graphite studio, one signal-orange accent.
   Dark opens first (a product shot under one lamp); light is a stone-coloured
   studio with the same graphite product. Reference: Teenage Engineering's
   product pages — industrial type, one loud colour, everything else quiet. */

:root {
  color-scheme: dark;
  --canvas: #0c0c0e;
  --surface: #141416;
  --surface-2: #1c1c1f;
  --border: #2a2a2e;
  --border-strong: #3d3d43;
  --ink: #f3f0ea;
  --muted: #9d9a94;
  --accent: #ff5a1f;
  --accent-hover: #ff7440;
  --accent-ink: #120804;
  --accent-text: #ff7a45;
  --accent-strong: #ffb391;
  --accent-soft: #2b1610;
  --accent-border: #5c2c1a;
  --success: #22c55e;
  --success-ink: #052e13;
  --success-soft: #0f2a1a;
  --success-strong: #7fe6a6;
  --warning: #f59e0b;
  --warning-ink: #3a2400;
  --warning-soft: #2c2008;
  --warning-strong: #fbbf6a;
  --danger: #f43f5e;
  --danger-ink: #3a0410;
  --danger-soft: #2b0f16;
  --danger-strong: #fb7185;
  --chart-1: #ff5a1f;
  --chart-2: #22c5c5;
  --chart-3: #f59e0b;
  --chart-4: #f43f5e;
  --chart-5: #38bdf8;
  --chart-6: #a3e635;

  --font-display: "Archivo Variable", "Inter Variable", ui-sans-serif, system-ui, sans-serif;
  --font-body: "Inter Variable", ui-sans-serif, system-ui, sans-serif;
  --font-sans: "Inter Variable", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "DM Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --display-weight: 700;
  --display-tracking: -0.04em;
  --eyebrow-tracking: 0.14em;
  --radius-card: 1.25rem;
  --radius-btn: 0.625rem;
  --shadow-card: none;

  /* The product's finishes — read by the 3D scene, so the case recolours with the page. */
  --x-shell-graphite: #3b3b42;
  --x-shell-pearl: #e9e6df;
  --x-shell-terracotta: #b5573a;

  /* The 3D studio's lamps and softboxes. */
  --x-light-key: #fff1e1;
  --x-light-warm: #ffe6cc;
  --x-light-sky: #ffffff;
  --x-light-ground: #222226;
  --x-light-bounce: #5a5a61;
  --x-light-void: #050506;

  /* The dark statement band: near-black and bone in both modes. */
  --x-band-bg: #060607;
  --x-band-ink: #f3f0ea;
  --x-band-muted: #a8a49c;
  --x-band-line: #2c2b28;
}

html[data-theme="light"] {
  color-scheme: light;
  --canvas: #ebe8e1;
  --surface: #f6f4ef;
  --surface-2: #e2ded6;
  --border: #d6d2c8;
  --border-strong: #b7b2a6;
  --ink: #17140f;
  --muted: #5d584e;
  --accent: #c93c08;
  --accent-hover: #a83006;
  --accent-ink: #ffffff;
  --accent-text: #b23406;
  --accent-strong: #8a2803;
  --accent-soft: #f6dccd;
  --accent-border: #e2b39c;
  --success: #15803d;
  --success-ink: #ffffff;
  --success-soft: #e3f3e8;
  --success-strong: #137638;
  --warning: #b45309;
  --warning-ink: #ffffff;
  --warning-soft: #f6ead9;
  --warning-strong: #a64c08;
  --danger: #b91c1c;
  --danger-ink: #ffffff;
  --danger-soft: #f6dede;
  --danger-strong: #b91c1c;
  --chart-1: #c93c08;
  --chart-2: #0f9b9b;
  --chart-3: #b45309;
  --chart-4: #b91c1c;
  --chart-5: #0369a1;
  --chart-6: #4d7c0f;

  --x-shell-graphite: #232327;
  --x-shell-pearl: #f4f2ed;
  --x-shell-terracotta: #a84a2e;

  --x-light-key: #fff6ea;
  --x-light-warm: #ffeedd;
  --x-light-sky: #ffffff;
  --x-light-ground: #6d6960;
  --x-light-bounce: #bdb8ad;
  --x-light-void: #2a2926;

  --x-band-bg: #100f0d;
  --x-band-ink: #f3f0ea;
  --x-band-muted: #a8a49c;
  --x-band-line: #2c2b28;
}

/*
 * app.css — Nova Pulse's own screen: the intro curtain, the scroll-driven
 * 3D stage, the rotatable showcase and the battery band. Tokens only.
 */

html:not(.reduced-motion) {
  scroll-behavior: smooth;
}
html {
  scroll-padding-top: 4.5rem;
}

.icon-sm {
  width: 1rem;
  height: 1rem;
}

/* ------------------------------------------------------------------ *
 * The mark: a small equalizer. Static in the nav, alive in the loader.
 * ------------------------------------------------------------------ */
.eq {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  height: 1.25rem;
}
.eq i {
  display: block;
  width: 3px;
  border-radius: 9999px;
  background: var(--accent);
}
.eq-xl {
  height: 5rem;
  gap: 8px;
}
.eq-xl i {
  width: 8px;
}
.eq-live i {
  height: 100%;
  transform-origin: center;
  animation: eq-bounce 1.05s ease-in-out infinite;
  animation-delay: calc(var(--n, 0) * -0.11s);
}
@keyframes eq-bounce {
  0%, 100% { transform: scaleY(0.18); }
  50% { transform: scaleY(1); }
}
html.reduced-motion .eq-live i {
  animation: none;
  transform: scaleY(0.6);
}

/* ------------------------------------------------------------------ *
 * The intro: a real progress counter, then a curtain that lifts off
 * the page. If scripts never finish, the failsafe lifts it anyway.
 * ------------------------------------------------------------------ */
#loader {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 1.5rem 1.5rem 2.5rem;
  background: var(--canvas);
  color: var(--ink);
  clip-path: inset(0 0 0 0);
  transition: clip-path 0.95s cubic-bezier(0.76, 0, 0.24, 1) 0.2s;
  animation: loader-failsafe 0.4s ease 14s forwards;
}
@media (min-width: 768px) {
  #loader {
    padding: 2.5rem 3rem 3.5rem;
  }
}
#loader > * {
  transition: opacity 0.35s ease, transform 0.5s ease;
}
#loader.is-done {
  clip-path: inset(0 0 100% 0);
}
#loader.is-done > * {
  opacity: 0;
  transform: translateY(-1rem);
}
#loader.is-gone {
  visibility: hidden;
  pointer-events: none;
}
.loader-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  background: var(--border);
}
.loader-bar span {
  position: absolute;
  inset: 0;
  background: var(--accent);
  transform: scaleX(var(--p, 0));
  transform-origin: left;
}
@keyframes loader-failsafe {
  to { opacity: 0; visibility: hidden; pointer-events: none; }
}
html.reduced-motion #loader,
html.reduced-motion #loader > * {
  transition: opacity 0.3s ease;
  transform: none;
}
html.reduced-motion #loader.is-done {
  clip-path: none;
  opacity: 0;
}

/* The first screen rises in behind the curtain. Everything rests visible. */
@keyframes rise {
  from { opacity: 0; transform: translateY(1.5rem); }
  to { opacity: 1; transform: none; }
}
html.is-ready .hero-rise {
  animation: rise 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both;
  animation-delay: calc(0.55s + var(--d, 0s));
}
html.reduced-motion .hero-rise {
  animation: none !important;
}

/* ------------------------------------------------------------------ *
 * Navigation: transparent over the stage, solid once you leave it.
 * ------------------------------------------------------------------ */
.nav-bar {
  border-bottom: 1px solid transparent;
  transition: background-color 0.25s ease, border-color 0.25s ease;
}
.nav-bar.is-solid {
  background: var(--canvas);
  border-bottom-color: var(--border);
}

/* ------------------------------------------------------------------ *
 * The scroll-driven stage
 * ------------------------------------------------------------------ */
#experience {
  height: 500vh;
}
.sticky-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  --gx: 70%;
}
.stage-glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(52% 58% at var(--gx) 46%, color-mix(in srgb, var(--accent) 20%, transparent), transparent 72%);
}
.stage-rings {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-radial-gradient(circle at var(--gx) 46%, transparent 0, transparent 5rem, color-mix(in srgb, var(--ink) 8%, transparent) 5rem, color-mix(in srgb, var(--ink) 8%, transparent) calc(5rem + 1px));
  -webkit-mask-image: radial-gradient(circle at var(--gx) 46%, black 0, transparent 62%);
  mask-image: radial-gradient(circle at var(--gx) 46%, black 0, transparent 62%);
}
.stage-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to top, var(--canvas), transparent 42%);
}

.scene-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: pan-y;
}

/* Chapters: type over the scene. JS drives --o (opacity) and --y (offset). */
.chapter {
  position: absolute;
  z-index: 10;
  left: 1.5rem;
  right: 1.5rem;
  bottom: 6.5rem;
  opacity: var(--o, 0);
  transform: translateY(var(--y, 1rem));
  pointer-events: none;
}
#panel-hero {
  opacity: var(--o, 1);
  transform: translateY(var(--y, 0px));
}
.chapter.is-active {
  pointer-events: auto;
}
.chapter-figure {
  font-size: clamp(3.75rem, 9vw, 8rem);
  font-weight: 800;
  line-height: 0.85;
  letter-spacing: -0.05em;
  color: var(--accent-text);
}
.chapter-unit {
  margin-left: 0.5rem;
  font-size: 0.26em;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--muted);
}
@media (min-width: 1024px) {
  .chapter {
    bottom: auto;
    width: 26rem;
  }
  .chapter-side {
    top: 50%;
    translate: 0 -50%;
  }
  .chapter-left {
    left: 4rem;
    right: auto;
  }
  .chapter-right {
    right: 4rem;
    left: auto;
  }
  #panel-hero {
    top: auto;
    translate: none;
    left: 4rem;
    right: auto;
    bottom: 7rem;
    width: 44rem;
  }
}

.rail {
  position: absolute;
  z-index: 10;
  left: 1.5rem;
  right: 1.5rem;
  bottom: 1.75rem;
  display: flex;
  align-items: center;
}
@media (min-width: 768px) {
  .rail {
    left: 3rem;
    right: 3rem;
    bottom: 2.5rem;
  }
}
.rail-track {
  position: relative;
  flex: 1;
  height: 1px;
  margin: 0 1rem;
  background: var(--border-strong);
}
.rail-fill {
  position: absolute;
  inset: 0;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
}

/* Reduced motion, or no WebGL: the stage becomes a plain stacked page. */
.reduced #experience,
#experience.reduced {
  height: auto;
}
.reduced .sticky-stage {
  position: relative;
  height: auto;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 6rem 1.5rem 4rem;
}
.reduced .chapter {
  position: static;
  width: auto;
  max-width: 34rem;
  opacity: 1;
  transform: none;
  translate: none;
  pointer-events: auto;
}
.reduced .chapter + .chapter {
  margin-top: 3rem;
}
.reduced .rail {
  display: none;
}
html.no-webgl .scene-canvas,
html.no-webgl .viewer-ui {
  display: none;
}

/* ------------------------------------------------------------------ *
 * Showcase viewer, angle buttons, finish swatches
 * ------------------------------------------------------------------ */
.viewer {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background:
    radial-gradient(70% 80% at 50% 42%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 70%),
    var(--surface);
}
.viewer .scene-canvas {
  cursor: grab;
}
.viewer .scene-canvas.is-grabbing {
  cursor: grabbing;
}
.viewer-hint {
  position: absolute;
  right: 1rem;
  bottom: 1rem;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.75rem;
  border-radius: 9999px;
  background: color-mix(in srgb, var(--canvas) 78%, transparent);
  color: var(--muted);
  font-size: 0.75rem;
  pointer-events: none;
}

.seg-btn {
  height: 2.5rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-btn);
  background: var(--surface);
  color: var(--muted);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.seg-btn:hover {
  border-color: var(--ink);
  color: var(--ink);
}
.seg-btn[aria-pressed="true"] {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
}
.seg-btn:focus-visible,
.swatch:focus-visible,
.hotspot-dot:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.swatch {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 9999px;
  border: 1px solid var(--border-strong);
  background: var(--sw);
  cursor: pointer;
  transition: box-shadow 0.15s ease;
}
.swatch[aria-pressed="true"] {
  box-shadow: 0 0 0 2px var(--canvas), 0 0 0 4px var(--accent);
}

/* Hotspots follow the model: JS projects each anchor to --hx / --hy. */
.hotspot {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 10;
  opacity: var(--ho, 1);
  transform: translate(var(--hx, -999px), var(--hy, -999px));
}
.hotspot-dot {
  position: relative;
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  margin: -1rem 0 0 -1rem;
  border: 2px solid var(--canvas);
  border-radius: 9999px;
  background: var(--accent);
  color: var(--accent-ink);
  cursor: pointer;
}
.hotspot-dot::after {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  border: 2px solid var(--accent);
  opacity: 0;
}
html:not(.reduced-motion) .hotspot-dot::after {
  animation: hotspot-ping 2.4s ease-out infinite;
}
@keyframes hotspot-ping {
  0% { opacity: 0.7; transform: scale(1); }
  100% { opacity: 0; transform: scale(2); }
}
.hotspot-tip {
  --tx: -50%;
  position: absolute;
  left: 0;
  top: 1.5rem;
  width: 15rem;
  padding: 0.75rem 0.875rem;
  border: 1px solid var(--border-strong);
  border-radius: 0.75rem;
  background: var(--surface);
  opacity: 0;
  pointer-events: none;
  transform: translate(var(--tx), 4px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.hotspot[data-side="l"] .hotspot-tip {
  --tx: -1rem;
}
.hotspot[data-side="r"] .hotspot-tip {
  --tx: calc(-100% + 1rem);
}
.hotspot:hover .hotspot-tip,
.hotspot:focus-within .hotspot-tip {
  opacity: 1;
  pointer-events: auto;
  transform: translate(var(--tx), 0);
}
.tip-title {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-text);
}
.tip-text {
  margin-top: 0.25rem;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--muted);
}

/* ------------------------------------------------------------------ *
 * The dark statement band and the battery bar
 * ------------------------------------------------------------------ */
.band-dark {
  background: var(--x-band-bg);
  color: var(--x-band-ink);
}
.band-muted {
  color: var(--x-band-muted);
}
.batt-seg {
  position: relative;
  height: 4rem;
  overflow: hidden;
  border: 1px solid var(--x-band-line);
  border-radius: 0.5rem;
}
.batt-fill {
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--accent) 45%, var(--x-band-bg));
  transform-origin: left;
}
.batt-fill-strong {
  background: var(--accent);
}
.battery.is-in .batt-fill {
  animation: batt-fill 1.3s cubic-bezier(0.2, 0.7, 0.2, 1) both;
  animation-delay: calc(var(--i, 0) * 0.2s);
}
@keyframes batt-fill {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}
html.reduced-motion .battery.is-in .batt-fill {
  animation: none;
}

/* ------------------------------------------------------------------ *
 * The spec sheet
 * ------------------------------------------------------------------ */
.spec-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding-block: 1.25rem;
  border-top: 1px solid var(--border-strong);
}
.spec-row:last-child {
  border-bottom: 1px solid var(--border-strong);
}
.spec-row dt {
  color: var(--muted);
}
.spec-row dd {
  padding-left: 1.5rem;
  text-align: right;
  font-weight: 500;
}

/* ------------------------------------------------------------------ *
 * The closing scene
 * ------------------------------------------------------------------ */
.close-stage {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  overflow: hidden;
  --gx: 70%;
}
