/* ==========================================================================
   Motion: tokens mirror, pre-hide rules, registered properties, header settle,
   journey node cues, disclosure/submenu keyframes, reduced-motion zeroing.
   Spec: docs/motion-spec.md v2 (sections 2.2, 3.2, 4.4, 5.3, 5.4, 5.5, 5.7, 6.5, 6.9, 8.2).
   Owner: gsap-engineer.
   Never hides anything except under html.motion-pending (set by the head snippet,
   removed by motion.js or the 2.5 s failsafe). motion-ready never hides anything.
   ========================================================================== */

/* ---- 2.2 CSS mirror of the motion tokens ---------------------------------- */
:root {
  --motion-dur-xs: 150ms;
  --motion-dur-s: 300ms;
  --motion-dur-m: 600ms;
  --motion-dur-l: 900ms;
  --motion-ease-settle: cubic-bezier(0.215, 0.61, 0.355, 1);      /* ~ power3.out */
  --motion-ease-soft: cubic-bezier(0.25, 0.46, 0.45, 0.94);       /* ~ power2.out */
  --motion-ease-draw: cubic-bezier(0.455, 0.03, 0.515, 0.955);    /* ~ power2.inOut */
  --motion-ease-exit: cubic-bezier(0.55, 0.085, 0.68, 0.53);      /* ~ power2.in */
  --motion-rise-xs: 8px;
  --motion-rise-s: 16px;
  --motion-rise-m: 24px;
}

/* ---- Registered custom properties (JS writes numbers/angles; CSS feeds transform only) ----
   --motion-rule must inherit: it is set on .stat-prose__fig and read by its ::after pseudo-element,
   and a pseudo-element only receives an inherited value from its originating element. */
@property --motion-rule { syntax: '<number>'; inherits: true; initial-value: 1; }
@property --orbit-inner { syntax: '<angle>'; inherits: true; initial-value: 0deg; }
@property --orbit-outer { syntax: '<angle>'; inherits: true; initial-value: 0deg; }

/* ---- 3.2 Pre-hide (opacity only; never visibility or display) -------------- */
html.motion-pending [data-motion="fade-up"],
html.motion-pending [data-motion="fade-in"],
html.motion-pending [data-motion="scale-in"],
html.motion-pending [data-motion="split-heading"],
html.motion-pending [data-motion="stagger"],
html.motion-pending [data-motion="draw"],
html.motion-pending [data-motion="stat-prose"],
html.motion-pending [data-motion="hero"] .page-hero__inner,
html.motion-pending [data-motion="page-hero"] .page-hero__inner,
html.motion-pending [data-motion="page-hero"] .page-hero__contour,
html.motion-pending [data-motion="page-hero"] .page-hero__texture { opacity: 0; }
/* never pre-hidden: count-up, parallax, stipple, orbit, journey, [data-hero-field] */

/* ---- hero field canvas (created by motion.js; background is the hero's own CSS) ---- */
[data-hero-field] > canvas { display: block; width: 100%; height: 100%; pointer-events: none; }

/* ---- split headings: serif display faces have tall ascenders/descenders ------ */
.split-line { padding-block: 0.08em; margin-block: -0.08em; }

/* ---- count-up and stat prose: no jitter, screen readers hear the final value only ---- */
[data-motion="count-up"],
.stat-prose__num { font-variant-numeric: tabular-nums; }
/* fallback in case base.css .visually-hidden changes */
[data-motion="count-up"] > .visually-hidden,
.stat-prose__num > .visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ---- 5.7 Glass header settle (pill never hides, never changes height) ------- */
.site-header__bar { transition: transform var(--motion-dur-s) var(--motion-ease-settle); }
.site-header__bar::before { opacity: .72; transition: opacity var(--motion-dur-s) var(--motion-ease-soft); }
.site-header__bar::after  { opacity: 0;   transition: opacity var(--motion-dur-s) var(--motion-ease-soft); }
.site-header.is-scrolled .site-header__bar { transform: translateY(-6px); }
.site-header.is-scrolled .site-header__bar::before { opacity: .94; }
.site-header.is-scrolled .site-header__bar::after  { opacity: 1; }
.site-header.is-nav-open .site-header__bar { transform: none; }
html { scroll-padding-top: calc(var(--header-h, 4.5rem) + 0.75rem); }
/* the fixed demo pill and toasts can cover focused content at the bottom edge */
html { scroll-padding-bottom: 5rem; }

/* ---- 5.5 Journey: connector svg and node cues (CSS-owned state cues) ------------ */
.journey__path { position: absolute; left: 0; top: 0; pointer-events: none; overflow: visible; }
.journey__node {
  transition: transform var(--motion-dur-s) var(--motion-ease-settle),
              background-color var(--motion-dur-s) var(--motion-ease-soft);
}
.journey__step.is-reached .journey__node { transform: scale(1.25); }

/* ---- 6.5 Dialog backdrop fade (the dialog itself is components.css) -------- */
@media (prefers-reduced-motion: no-preference) {
  .dialog[open]::backdrop { animation: bc-backdrop-in var(--motion-dur-s) var(--motion-ease-soft); }
  @keyframes bc-backdrop-in { from { opacity: 0; } }

  /* ---- 6.9 Native <details>: content fades in, close is instant ---------- */
  details[open] > :not(summary) { animation: bc-disclose var(--motion-dur-s) var(--motion-ease-soft); }
  @keyframes bc-disclose { from { opacity: 0; transform: translateY(-4px); } }

  /* Desktop nav submenu (1100px and up) and demo role switcher panel */
  @media (min-width: 68.75em) {
    .nav-trigger[aria-expanded="true"] + .subnav { animation: bc-drop var(--motion-dur-xs) var(--motion-ease-soft); }
  }
  .demo-switcher__panel:not([hidden]) { animation: bc-drop var(--motion-dur-xs) var(--motion-ease-soft); }
  @keyframes bc-drop { from { opacity: 0; transform: translateY(-4px); } }
}

/* ---- 8.2 Reduced motion: every CSS-owned transition is zeroed ---------------- */
@media (prefers-reduced-motion: reduce) {
  .site-header__bar,
  .site-header__bar::before,
  .site-header__bar::after,
  .journey__node { transition: none; }
}

/* ---- Print: every motion-managed element prints fully visible and in place ---- */
@media print {
  html.motion-pending [data-motion],
  [data-motion],
  [data-motion] * {
    opacity: 1 !important;
    transform: none !important;
    translate: none !important;
    scale: none !important;
    rotate: none !important;
    clip-path: none !important;
    will-change: auto !important;
    animation: none !important;
  }
  [data-motion] [style*="stroke-dash"] { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
  [data-motion] .split-line { overflow: visible !important; }
  [data-hero-field] { display: none !important; }
}
