/* ============================================================================
   FREQ1C — VOID.FM · enhance.css  (v2 layer — ADDITIVE, decoupled from styles.css)
   Everything here is either behind `.fx-motion` (motion) or the `.tuner` block.
   Tokens are inherited from styles.css :root (BUILD_CONTRACT §2 is LAW):
   near-monochrome void + ONE violet accent, sharp corners, Space Grotesk/Mono.
   Remove this file + enhance.js and v2 falls back to the exact v1 behaviour.
   ========================================================================== */

/* ------------------------------------------------------------------ *
   1. SCROLL-REVEAL  (only when motion is allowed → never hides content
      for reduced-motion users or if enhance.js fails to run)
 * ------------------------------------------------------------------ */
.fx-motion .reveal{
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .62s var(--ease-out), transform .62s var(--ease-out);
  will-change: opacity, transform;
}
.fx-motion .reveal.is-inview{ opacity: 1; transform: none; }
/* gentle capped stagger for grids/rows that reveal together */
.fx-motion .reveal.is-inview:nth-child(1){ transition-delay: 0ms; }
.fx-motion .reveal.is-inview:nth-child(2){ transition-delay: 40ms; }
.fx-motion .reveal.is-inview:nth-child(3){ transition-delay: 80ms; }
.fx-motion .reveal.is-inview:nth-child(4){ transition-delay: 120ms; }
.fx-motion .reveal.is-inview:nth-child(5){ transition-delay: 160ms; }
.fx-motion .reveal.is-inview:nth-child(n+6){ transition-delay: 200ms; }

/* ------------------------------------------------------------------ *
   2. HERO PARALLAX  (depth on scroll + pointer). enhance.js writes the
      transforms; we only declare the compositor hints + baseline scale
      so translating the figure never reveals a hard edge.
 * ------------------------------------------------------------------ */
.fx-motion .hero{ perspective: 1200px; }
.fx-motion .hero__figure{ transform: scale(1.09); will-change: transform, opacity; }
.fx-motion .hero__core{ will-change: transform; }
.fx-motion .hero__copy{ will-change: transform; }
/* wordmark gets a slow living bloom — pure opacity/text-shadow, cheap */
.fx-motion .hero__wordmark{ animation: wordmark-breathe 7s var(--ease) infinite; }
@keyframes wordmark-breathe{
  0%,100%{ text-shadow: 0 0 2px var(--accent-dim), 0 0 60px rgba(138,107,255,0.22); }
  50%{     text-shadow: 0 0 2px var(--accent-dim), 0 0 90px rgba(138,107,255,0.40); }
}

/* ------------------------------------------------------------------ *
   2b. SPACE HERO — pinned scrollytelling "descent into the signal"
       (Wix-Studio-style multi-layer parallax; desktop + motion only).
       enhance.js writes the transforms from scroll progress 0→1.
 * ------------------------------------------------------------------ */
.hero-stage{ position: relative; }
.hero-pin{ position: relative; }
/* depth layers hidden unless we're actually running the journey */
.hero__sky, .hero__debris{ display: none; }

/* v2 FINAL — parallax descent dropped (per Scott); keep the solid clean hero.
   Stage/pin collapse to normal flow; cosmos sky + cover-debris stay off. */
.hero-stage{ height: auto; }
.hero-pin{ position: static; height: auto; }

.hero__sky{
  position: absolute; inset: -6% -6% -6% -6%;
  z-index: 0; pointer-events: none; opacity: .5;
  background:
    radial-gradient(120% 90% at 68% 34%, rgba(138,107,255,0.22), transparent 55%),
    url("assets/img/gen/scene-cosmos.jpg") center/cover no-repeat;
  will-change: transform, opacity;
}
.hero__debris{ position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.hero__debris .chip{
  position: absolute; width: var(--sz, 84px); aspect-ratio: 1;
  background-size: cover; background-position: center;
  opacity: .28; border: 1px solid var(--accent-dim);
  box-shadow: 0 0 34px -10px var(--accent-glow);
  filter: saturate(.85) brightness(.82);
  will-change: transform, opacity;
}
/* keep copy above the drifting art, figure between */
.fx-motion .hero-pin .hero__copy{ z-index: 4; }
.fx-motion .hero-pin .hero__figure{ z-index: 2; }
.fx-motion .hero-pin .hero__core{ z-index: 1; }

.hero__scrollcue{
  position: absolute; left: 50%; bottom: 5%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: var(--s-2);
  color: var(--text-mute); text-decoration: none; z-index: 5;
  letter-spacing: var(--tracking-label);
}
.hero__scrollcue:hover{ color: var(--text-dim); }
.hero__scrollcue-arrow{ color: var(--accent); font-size: 1.05rem; }
.fx-motion .hero__scrollcue-arrow{ animation: cue-bob 1.9s var(--ease) infinite; }
@keyframes cue-bob{ 0%,100%{ transform: translateY(0); opacity: .55; } 50%{ transform: translateY(7px); opacity: 1; } }
/* parallax journey off — scroll cue, cosmos sky, and cover-debris all stay hidden */
.hero__scrollcue, .hero__sky, .hero__debris{ display: none !important; }

@media (prefers-reduced-motion: reduce){
  .hero-stage{ height: auto !important; }
  .hero-pin{ position: static !important; height: auto !important; }
  .hero__sky, .hero__debris, .hero__scrollcue{ display: none !important; }
}

/* ------------------------------------------------------------------ *
   3. THE FM TUNER  (signature — injected atop #/states by enhance.js)
 * ------------------------------------------------------------------ */
.tuner{
  position: relative;
  margin: 0 0 var(--s-8);
  padding: clamp(var(--s-4), 3vw, var(--s-6));
  border: var(--border);
  border-top: var(--border-accent);
  background:
    radial-gradient(120% 140% at 50% -20%, rgba(138,107,255,0.10), transparent 60%),
    var(--surface);
  overflow: hidden;
}
.tuner::before{  /* faint carrier-wave grid in the panel ground */
  content: "";
  position: absolute; inset: 0;
  background-image: repeating-linear-gradient(90deg, rgba(138,107,255,0.05) 0 1px, transparent 1px 40px);
  opacity: .5; pointer-events: none;
}
.tuner > *{ position: relative; z-index: 1; }

.tuner__head{
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-4); flex-wrap: wrap; margin-bottom: var(--s-5);
}
.tuner__readout{ display: flex; align-items: baseline; gap: .4ch; line-height: 1; }
.tuner__freq{
  font-family: var(--font-mono); font-weight: 700;
  font-size: clamp(2.4rem, 7vw, 4rem); color: var(--text);
  letter-spacing: .02em; font-variant-numeric: tabular-nums;
  text-shadow: 0 0 34px rgba(138,107,255,0.45);
}
.tuner__freq.is-tuning{ color: var(--accent-hover); }
.tuner__mhz{
  font-family: var(--font-mono); font-size: var(--fs-label);
  letter-spacing: var(--tracking-label); color: var(--text-mute);
  text-transform: uppercase;
}

/* --- NOW-TUNED readout panel --- */
.tuner__now{ min-height: 148px; margin-bottom: var(--s-6); }
.tuner__now-band{ display: block; color: var(--accent); margin-bottom: var(--s-2); }
.tuner__now-name{
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.75rem, 5vw, var(--fs-h1));
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
  line-height: 1.02; color: var(--text);
}
.tuner__now-tag{
  font-family: var(--font-mono); font-size: var(--fs-sm);
  color: var(--text-dim); margin-top: var(--s-1); letter-spacing: .02em;
}
.tuner__now-desc{
  max-width: 62ch; margin-top: var(--s-3);
  color: var(--text-dim); font-size: var(--fs-body); line-height: 1.5;
}
.tuner__now-foot{
  display: flex; align-items: center; gap: var(--s-4);
  margin-top: var(--s-4); flex-wrap: wrap;
}
.tuner__now-count{ color: var(--text-mute); }
.tuner__now[data-empty="true"] .tuner__now-count{ color: var(--text-mute); }
/* retune flicker whenever the locked station changes */
.tuner__now.is-retune{ animation: tuner-retune .5s var(--ease-bloom); }
@keyframes tuner-retune{
  0%{ opacity: .15; transform: translateY(6px); filter: blur(0.4px); }
  100%{ opacity: 1; transform: none; filter: none; }
}

/* --- THE DIAL --- */
.tuner__dial{
  position: relative;
  height: 116px;
  border: var(--border);
  background: linear-gradient(180deg, var(--bg-2), var(--bg));
  cursor: ew-resize; user-select: none; touch-action: none;
  overflow: hidden;
}
.tuner__dial:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }
/* fine + coarse tick ruler along the bottom */
.tuner__ticks{ position: absolute; inset: auto 0 0 0; height: 46px; pointer-events: none; }
.tuner__tick{
  position: absolute; bottom: 0; width: 1px; background: var(--line-strong);
}
.tuner__tick--minor{ height: 10px; opacity: .5; }
.tuner__tick--major{ height: 20px; background: var(--text-mute); opacity: .7; }
/* station markers (one per state) */
.tuner__station{
  position: absolute; top: 0; bottom: 0; width: 34px;
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  gap: var(--s-1); padding-top: var(--s-3);
  background: transparent; border: 0; cursor: pointer; color: var(--text-mute);
}
.tuner__station-pip{
  width: 2px; height: 26px; background: var(--line-strong);
  transition: background var(--dur) var(--ease), height var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.tuner__station-f{
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .04em;
  color: var(--text-mute); font-variant-numeric: tabular-nums;
  transition: color var(--dur) var(--ease);
}
.tuner__station:hover .tuner__station-pip{ background: var(--accent-dim); height: 30px; }
.tuner__station:hover .tuner__station-f{ color: var(--text-dim); }
.tuner__station[data-empty="true"] .tuner__station-pip{ opacity: .4; }
.tuner__station[data-active="true"] .tuner__station-pip{
  background: var(--accent); height: 34px;
  box-shadow: 0 0 14px var(--accent-glow);
}
.tuner__station[data-active="true"] .tuner__station-f{ color: var(--accent-hover); }
/* the needle */
.tuner__needle{
  position: absolute; top: 6px; bottom: 6px; width: 2px;
  background: linear-gradient(180deg, var(--accent-hover), var(--accent));
  box-shadow: 0 0 12px var(--accent-glow), 0 0 26px var(--accent-glow);
  transform: translateX(-50%); left: 0;
  pointer-events: none; z-index: 3;
}
.tuner__needle::before{  /* glowing head cap */
  content: ""; position: absolute; top: -3px; left: 50%; transform: translateX(-50%);
  width: 9px; height: 9px; background: var(--text);
  box-shadow: 0 0 10px var(--accent-hover), 0 0 22px var(--accent-glow);
}
.tuner__dial.is-dragging .tuner__needle{ box-shadow: 0 0 18px var(--accent-glow), 0 0 40px var(--accent-glow); }

.tuner__hint{
  margin-top: var(--s-3); color: var(--text-mute);
  display: flex; gap: var(--s-4); flex-wrap: wrap;
}
.tuner__scanline{  /* subtle sweeping scan glint over the dial during power-on */
  position: absolute; top: 0; bottom: 0; width: 120px; left: 0;
  background: linear-gradient(90deg, transparent, rgba(138,107,255,0.10), transparent);
  transform: translateX(-140px); pointer-events: none; z-index: 2; opacity: 0;
}
.tuner__dial.is-scanning .tuner__scanline{ opacity: 1; }

@media (max-width: 640px){
  .tuner__dial{ height: 104px; }
  .tuner__station{ width: 28px; }
  .tuner__station-f{ font-size: 8px; }
  .tuner__now{ min-height: 172px; }
}

/* IN SEQUENCE order toggle */
.seq-order{
  background: transparent; border: var(--border); color: var(--text-dim);
  padding: var(--s-2) var(--s-3); cursor: pointer;
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.seq-order:hover{ border-color: var(--accent); color: var(--text); background: var(--elevated); }
.seq-order:focus-visible{ outline: 2px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------------------ *
   4. 10-STATE LADDER RAIL  (compact ascent legend under the tuner)
 * ------------------------------------------------------------------ */
.ladder{ display: grid; grid-template-columns: 1fr; gap: 2px; margin-top: var(--s-6); }
.ladder__row{
  display: grid; grid-template-columns: 2.2rem 1fr auto auto; align-items: center;
  gap: var(--s-3); padding: var(--s-2) var(--s-3);
  border: 1px solid transparent; border-left: 2px solid var(--line-strong);
  background: linear-gradient(90deg, rgba(138,107,255,0.05), transparent 60%);
  color: var(--text-dim); text-decoration: none;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
/* luminance ramp: the climb toward the light (stays inside the violet→white palette) */
.ladder__row{ --rung: 0; }
.ladder__row:hover{ border-left-color: var(--accent); background: linear-gradient(90deg, rgba(138,107,255,0.14), transparent 70%); transform: translateX(3px); }
.ladder__rung{ font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--text-mute); letter-spacing: var(--tracking-label); }
.ladder__name{ font-family: var(--font-display); font-weight: 600; text-transform: uppercase; letter-spacing: var(--tracking-wide); color: var(--text); font-size: var(--fs-sm); }
.ladder__band{ font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--text-mute); letter-spacing: .04em; }
.ladder__f{ font-family: var(--font-mono); font-size: var(--fs-micro); color: var(--accent); letter-spacing: .04em; }
.ladder__row[data-empty="true"] .ladder__name{ color: var(--text-mute); }
@media (max-width: 640px){
  .ladder__band{ display: none; }
  .ladder__row{ grid-template-columns: 2rem 1fr auto; }
}

/* ------------------------------------------------------------------ *
   5. REDUCED-MOTION — belt & suspenders (the .fx-motion gate already
      keeps all of the above off, but pin the essentials just in case)
 * ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce){
  .reveal{ opacity: 1 !important; transform: none !important; }
  .hero__figure, .hero__core, .hero__copy{ transform: none !important; }
  .hero__wordmark{ animation: none !important; }
  .tuner__now.is-retune{ animation: none !important; }
}
