/* All motion lives in this layer so the reduced-motion/static override at the
   bottom has one clear kill switch. Gating classes on <html>:
   .js (set pre-paint) · .static (?static=1) · .reduced-motion ·
   .no-sda (scroll-driven animations unsupported → IO fallback) ·
   .popover-ok · .gl-live (canvas confirmed) · .fonts-ready */

@layer motion {
  /* ── Scroll-driven reveals (primary path) ── */
  @supports (animation-timeline: view()) {
    html.js:not(.static):not(.reduced-motion):not(.no-sda) [data-reveal] {
      animation-name: rise-in;
      animation-fill-mode: both;
      animation-timing-function: var(--ease-soft);
      animation-timeline: view();
      animation-range: entry 10% cover 32%;
    }

    html.js:not(.static):not(.reduced-motion):not(.no-sda) .section-title {
      animation-name: bloom-pass;
      animation-fill-mode: both;
      animation-timing-function: linear;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
    }

    html.js:not(.static):not(.reduced-motion):not(.no-sda) .layer-connector {
      animation-name: draw-down;
      animation-fill-mode: both;
      animation-timing-function: var(--ease-soft);
      animation-timeline: view();
      animation-range: entry 0% cover 40%;
    }

    html.js:not(.static):not(.reduced-motion):not(.no-sda) .contact-email {
      animation-name: settle-glow;
      animation-fill-mode: both;
      animation-timing-function: linear;
      animation-timeline: view();
      animation-range: entry 0% cover 60%;
    }
  }

  @supports (animation-timeline: scroll()) {
    html.js:not(.static):not(.reduced-motion) .nav-progress {
      animation-name: progress-grow;
      animation-fill-mode: both;
      animation-timing-function: linear;
      animation-timeline: scroll(root);
    }
  }

  /* ── IntersectionObserver fallback path ──── */
  html.js.no-sda:not(.static):not(.reduced-motion) [data-reveal] {
    opacity: 0;
    translate: 0 22px;
    transition: opacity var(--dur-reveal) var(--ease-soft), translate var(--dur-reveal) var(--ease-soft);
  }

  html.js.no-sda:not(.static):not(.reduced-motion) [data-reveal].is-visible {
    opacity: 1;
    translate: 0 0;
  }

  html.js.no-sda:not(.static):not(.reduced-motion) .layer-connector {
    scale: 1 0;
    transition: scale 0.8s var(--ease-soft);
  }

  html.js.no-sda:not(.static):not(.reduced-motion) .layer-connector.is-drawn {
    scale: 1 1;
  }

  /* ── Keyframes ────────────────────────────── */
  @keyframes rise-in {
    from { opacity: 0; translate: 0 22px; }
    to   { opacity: 1; translate: 0 0; }
  }

  @keyframes bloom-pass {
    0%   { --bloom-power: 0; }
    50%  { --bloom-power: 1; }
    100% { --bloom-power: 0.15; }
  }

  @keyframes draw-down {
    from { scale: 1 0; }
    to   { scale: 1 1; }
  }

  @keyframes settle-glow {
    0%   { box-shadow: 0 0 0 color-mix(in srgb, var(--gold) 0%, transparent); }
    70%  { box-shadow: 0 0 44px color-mix(in srgb, var(--gold) 22%, transparent); }
    100% { box-shadow: 0 0 26px color-mix(in srgb, var(--gold) 12%, transparent); }
  }

  @keyframes progress-grow {
    from { scale: 0 1; }
    to   { scale: 1 1; }
  }

  /* Section titles carry a scroll-answering glow */
  .section-title {
    text-shadow: 0 0 calc(var(--bloom-power, 0) * 26px)
      color-mix(in srgb, var(--section-accent, var(--gold)) 60%, transparent);
  }

  /* ── Hero glyph stagger (boot-time, once) ── */
  .hero h1 .glyph { display: inline-block; }

  html.js:not(.static):not(.reduced-motion) .stagger-go .glyph {
    animation: glyph-in 0.9s var(--ease-soft) both;
    animation-delay: calc(var(--i, 0) * 70ms);
  }

  @keyframes glyph-in {
    from { opacity: 0; translate: 0 0.35em; filter: blur(6px); }
    to   { opacity: 1; translate: 0 0; filter: blur(0); }
  }

  /* Motto and CTA follow the wordmark in */
  html.js:not(.static):not(.reduced-motion) .stagger-go ~ .motto {
    animation: glyph-in 1s var(--ease-soft) 0.5s both;
  }
  html.js:not(.static):not(.reduced-motion) .stagger-go ~ .hero-desc {
    animation: glyph-in 1s var(--ease-soft) 0.65s both;
  }
  html.js:not(.static):not(.reduced-motion) .stagger-go ~ .hero-cta {
    animation: glyph-in 1s var(--ease-soft) 0.8s both;
  }

  /* ── Pointer spotlight state ──────────────── */
  html.js .glass-card {
    transition: --card-glow-x 0.18s ease, --card-glow-y 0.18s ease,
      border-color var(--dur-quick), translate var(--dur-quick) var(--ease-soft);
  }

  .glass-card.lit { --card-glow-a: 1; }

  .glass-card.pulse::before {
    animation: touch-pulse 0.9s ease both;
  }

  @keyframes touch-pulse {
    0%   { opacity: 0; }
    30%  { opacity: 1; }
    100% { opacity: 0; }
  }

  /* ── Popover menu entry/exit ──────────────── */
  #mobile-menu[popover] {
    opacity: 0;
    translate: -50% -8px;
    transition: opacity 0.25s ease, translate 0.25s var(--ease-soft),
      overlay 0.25s allow-discrete, display 0.25s allow-discrete;
  }

  #mobile-menu:popover-open {
    opacity: 1;
    translate: -50% 0;
  }

  @starting-style {
    #mobile-menu:popover-open {
      opacity: 0;
      translate: -50% -8px;
    }
  }

  /* ── Kill switches ────────────────────────── */
  html.reduced-motion *,
  html.reduced-motion *::before,
  html.reduced-motion *::after,
  html.static *,
  html.static *::before,
  html.static *::after {
    animation: none !important;
    transition: none !important;
  }

  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation: none !important;
      transition: none !important;
    }
  }
}
