/*
 * Immersive polish layer (feat/immersive-polish branch).
 *
 * Sound toggle, scroll progress hairline, hero entrance, kicker draw-in,
 * FAQ motion, voice-call states, and button press feedback for the
 * liquid-glass homepage. Everything here is gated behind body.js-ready or
 * aria/state hooks, so a no-JS visit renders the plain site untouched.
 * House rule honoured: NO cursor-tracking glow, sheen, or floating
 * ornament of any kind — feedback comes from motion and refraction only.
 */

/* ───── Card content packs to the top ─────
   .glass-card__inner is a 100%-height grid, and grid's initial
   align-content: normal stretches every auto track equally — cards in a
   stretched row ended up with their heading marooned in a void mid-card.
   Pack content to the top; leftover space collects at the bottom, which
   reads as intentional padding instead of a rendering failure. The hero
   face already ships align-content: start. */
.glass-card__inner {
  align-content: start;
}

/* ───── Scroll progress hairline ─────
   A 2px lime→champagne thread above the nav that tracks reading progress.
   Pure scroll-position feedback; it never reacts to the cursor. */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 90;
  pointer-events: none;
  transform: scaleX(var(--scroll-p, 0));
  transform-origin: 0 50%;
  background: linear-gradient(90deg, #d7f29b, #e8d4a1);
  opacity: 0.85;
}

/* ───── Nav scrolled state ─────
   Geometry is untouched (the glass overlay never desyncs); only the shell's
   own border and shadow deepen once the page moves under it. */
.site-header .nav-shell {
  transition: border-color 300ms ease, box-shadow 300ms ease;
}

.site-header.is-scrolled .nav-shell {
  border-color: rgba(245, 242, 234, 0.24) !important;
  box-shadow: 0 18px 44px rgba(7, 18, 14, 0.42) !important;
}

/* ───── Sound toggle ─────
   Injected by immersive.js as the last .nav-links item. A calm speaker
   glyph; the sound waves only appear while enabled. */
.sound-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid rgba(245, 242, 234, 0.28);
  border-radius: 999px;
  background: rgba(245, 242, 234, 0.07);
  color: rgba(245, 242, 234, 0.85);
  cursor: pointer;
  transition: border-color 180ms ease, background 180ms ease, color 180ms ease, transform 140ms ease;
}

.sound-toggle:hover {
  border-color: rgba(215, 242, 155, 0.55);
  color: #d7f29b;
}

.sound-toggle:active {
  transform: scale(0.92);
}

.sound-toggle:focus-visible {
  outline: 2px solid #d7f29b;
  outline-offset: 2px;
}

.sound-toggle svg {
  width: 18px;
  height: 18px;
  display: block;
}

.sound-toggle .sound-toggle__waves {
  opacity: 0;
  transition: opacity 200ms ease;
}

.sound-toggle .sound-toggle__mute {
  opacity: 0.9;
  transition: opacity 200ms ease;
}

.sound-toggle[aria-pressed="true"] {
  border-color: rgba(215, 242, 155, 0.6);
  background: rgba(215, 242, 155, 0.14);
  color: #d7f29b;
}

.sound-toggle[aria-pressed="true"] .sound-toggle__waves {
  opacity: 1;
}

.sound-toggle[aria-pressed="true"] .sound-toggle__mute {
  opacity: 0;
}

.sound-toggle .sound-toggle__waves,
.sound-toggle .sound-toggle__mute {
  transition: opacity 200ms ease;
}

/* the waves breathe while sound is live */
.sound-toggle[aria-pressed="true"] .sound-toggle__wave-1 {
  animation: sound-wave 1.6s ease-in-out infinite;
}

.sound-toggle[aria-pressed="true"] .sound-toggle__wave-2 {
  animation: sound-wave 1.6s ease-in-out 0.25s infinite;
}

@keyframes sound-wave {
  50% {
    opacity: 0.35;
  }
}

/* ───── Button press feedback ─────
   The hover lift already exists; a settle on press completes the physical
   read. Transition added only where the base sheet had none. */
.button,
.button-secondary,
.text-button,
.nav-cta {
  transition: transform 150ms ease, color 160ms ease, background 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}

.button:active,
.button-secondary:active,
.nav-cta:active,
.voice-widget__button:active:not(:disabled),
.lgx-mobile-cta:active {
  transform: translateY(0) scale(0.97);
}

.text-button:active {
  transform: translateY(1px);
}

.lead-form input[type="submit"] {
  transition: transform 150ms ease, box-shadow 160ms ease, background 160ms ease;
}

.lead-form input[type="submit"]:active:not(:disabled) {
  transform: scale(0.98);
}

/* ───── Hero entrance ─────
   One staggered rise on load: eyebrow, the four display lines, lede,
   actions, meta, then the trust signals. A slight blur-to-sharp reads like
   a focus pull. Runs once; the flip faces are untouched. */
@media (prefers-reduced-motion: no-preference) {
  body.js-ready .hero .eyebrow,
  body.js-ready .hero-title__line,
  body.js-ready .hero .lede,
  body.js-ready .hero-actions,
  body.js-ready .hero-meta,
  body.js-ready .hero-signal,
  body.js-ready .hero-proof-stack > .glass-card {
    animation: hero-rise 0.85s cubic-bezier(0.23, 1, 0.32, 1) both;
  }

  body.js-ready .hero .eyebrow { animation-delay: 0.08s; }
  body.js-ready .hero-title__line:nth-child(1) { animation-delay: 0.16s; }
  body.js-ready .hero-title__line:nth-child(2) { animation-delay: 0.24s; }
  body.js-ready .hero-title__line:nth-child(3) { animation-delay: 0.32s; }
  body.js-ready .hero-title__line:nth-child(4) { animation-delay: 0.4s; }
  body.js-ready .hero .lede { animation-delay: 0.5s; }
  body.js-ready .hero-actions { animation-delay: 0.58s; }
  body.js-ready .hero-meta { animation-delay: 0.66s; }
  body.js-ready .hero-signal:nth-child(1) { animation-delay: 0.78s; }
  body.js-ready .hero-signal:nth-child(2) { animation-delay: 0.86s; }
  body.js-ready .hero-signal:nth-child(3) { animation-delay: 0.94s; }
  body.js-ready .hero-proof-stack > .glass-card--proof { animation-delay: 0.3s; }
  body.js-ready .hero-proof-stack > .glass-card--voice { animation-delay: 0.48s; }
}

@keyframes hero-rise {
  from {
    opacity: 0;
    transform: translateY(18px);
    filter: blur(5px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

/* ───── Kicker draw-in ─────
   A short hairline leads each section/card kicker, drawn left-to-right as
   the heading reveals. currentColor keeps it champagne on dark glass. */
body.js-ready .section-kicker::before,
body.js-ready .card-kicker::before {
  content: "";
  display: inline-block;
  width: 1.6em;
  height: 1px;
  margin-right: 0.6em;
  vertical-align: middle;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 700ms cubic-bezier(0.23, 1, 0.32, 1) 200ms;
}

body.js-ready .is-visible .section-kicker::before,
body.js-ready .is-visible .card-kicker::before {
  transform: scaleX(1);
}

/* ───── FAQ motion ─────
   The +/− chip already rotates; give it a transition and let the answer
   body rise as it lands. Height animation itself is JS (immersive.js)
   because <details> has no animatable open state in CSS. */
.faq-card summary::after {
  transition: transform 250ms ease, background-color 250ms ease;
}

.faq-card details[open] > p {
  animation: faq-rise 320ms cubic-bezier(0.23, 1, 0.32, 1) both;
}

@keyframes faq-rise {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
}

/* ───── Voice call states ─────
   The status dot already changes colour per state; this layer makes the
   card feel on-air: the mic badge breathes with the caller's real level
   (--voice-level is published by enhance.jsx while a call is live) and a
   slow sonar ring marks active states. Status signalling, not ornament. */
.voice-widget__mic {
  position: relative;
  transition: transform 120ms ease-out;
}

.glass-card--voice[data-voice-state="listening"] .voice-widget__mic,
.glass-card--voice[data-voice-state="active"] .voice-widget__mic {
  transform: scale(calc(1 + var(--voice-level, 0) * 0.22));
}

.voice-widget__mic::after {
  content: "";
  position: absolute;
  inset: -1px;
  border: 1px solid rgba(215, 242, 155, 0);
  border-radius: 50%;
  pointer-events: none;
}

.glass-card--voice[data-voice-state="active"] .voice-widget__mic::after,
.glass-card--voice[data-voice-state="listening"] .voice-widget__mic::after {
  animation: voice-sonar 1.9s ease-out infinite;
}

.glass-card--voice[data-voice-state="speaking"] .voice-widget__mic::after {
  animation: voice-sonar 1.15s ease-out infinite;
}

.glass-card--voice[data-voice-state="connecting"] .voice-widget__mic,
.glass-card--voice[data-voice-state="permission"] .voice-widget__mic {
  animation: voice-wait 1.2s ease-in-out infinite;
}

@keyframes voice-sonar {
  0% {
    transform: scale(1);
    opacity: 0;
    border-color: rgba(215, 242, 155, 0.55);
  }
  15% {
    opacity: 1;
  }
  100% {
    transform: scale(1.7);
    opacity: 0;
    border-color: rgba(215, 242, 155, 0);
  }
}

@keyframes voice-wait {
  50% {
    opacity: 0.55;
  }
}

/* ───── Reduced motion ───── */
@media (prefers-reduced-motion: reduce) {
  .scroll-progress {
    display: none;
  }

  .sound-toggle[aria-pressed="true"] .sound-toggle__wave-1,
  .sound-toggle[aria-pressed="true"] .sound-toggle__wave-2,
  .voice-widget__mic,
  .voice-widget__mic::after {
    animation: none !important;
  }

  .glass-card--voice[data-voice-state="listening"] .voice-widget__mic,
  .glass-card--voice[data-voice-state="active"] .voice-widget__mic {
    transform: none;
  }

  .faq-card details[open] > p {
    animation: none;
  }
}

/* ───── Mobile placement of the sound toggle ───── */
@media (max-width: 760px) {
  .sound-toggle {
    width: 44px;
    height: 44px;
  }
}
