/**
 * motion.css — Animation system
 *
 * All durations and easings reference tokens.css.
 * accessibility.css nullifies everything below via prefers-reduced-motion.
 * Add new keyframes here; reference --duration-* and --ease-* tokens only.
 */

/* ─── Keyframes ─────────────────────────────────────────── */

@keyframes ps-shimmer {
  from { background-position: -200% center; }
  to   { background-position:  200% center; }
}

@keyframes ps-gold-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-gold-500) 40%, transparent); }
  50%       { box-shadow: 0 0 0 8px color-mix(in srgb, var(--color-gold-500) 0%, transparent); }
}

@keyframes ps-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

@keyframes ps-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes ps-fade-out {
  from { opacity: 1; }
  to   { opacity: 0; }
}

@keyframes ps-slide-up {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes ps-slide-down {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(8px); }
}

@keyframes ps-slide-in-right {
  from { opacity: 0; transform: translateX(16px); }
  to   { opacity: 1; transform: translateX(0); }
}

@keyframes ps-slide-out-right {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(16px); }
}

@keyframes ps-blur-reveal {
  from { opacity: 0; filter: blur(6px); transform: translateY(4px); }
  to   { opacity: 1; filter: blur(0);   transform: translateY(0); }
}

@keyframes ps-cross-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes ps-descend {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes ps-scale-in {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1); }
}

/* ─── Page Transitions ──────────────────────────────────── */

.ps-page-enter {
  animation: ps-slide-up var(--duration-normal, 280ms) var(--ease-out, ease-out) both;
}

.ps-page-exit {
  animation: ps-slide-down var(--duration-fast, 200ms) var(--ease-in, ease-in) both;
}

/* ─── Semantic motion utility classes (Track 7.1) ───────── */
/* Prefer var(--motion-precise | --motion-calm | --motion-lift) in component CSS.
   Use these utility classes for ad-hoc hover/state motion. */

.ps-motion-precise { transition: var(--motion-precise); }
.ps-motion-calm    { transition: var(--motion-calm); }
.ps-motion-lift    { transition: var(--motion-lift); }

/* ─── Per-route page enter variants ─────────────────────── */
/* Used by router.js ROUTE_TRANSITIONS map for differentiated navigation feel */

.ps-page-enter--fade {
  /* Today — like waking up. Gradual, no motion. */
  animation: ps-cross-fade var(--duration-slow, 400ms) var(--ease-out, ease-out) both;
}

.ps-page-enter--blur {
  /* Blueprint — seeing yourself clearly. Blur lifts. */
  animation: ps-blur-reveal var(--duration-slower, 600ms) var(--ease-silk, cubic-bezier(0.25, 0.46, 0.45, 0.94)) both;
}

.ps-page-enter--descend {
  /* Relationships — arriving into connection. Descends gently. */
  animation: ps-descend var(--duration-slow, 400ms) var(--ease-out, ease-out) both;
}

.ps-page-enter--scale {
  /* Home — snaps cleanly into place. */
  animation: ps-scale-in var(--duration-normal, 280ms) var(--ease-silk, cubic-bezier(0.25, 0.46, 0.45, 0.94)) both;
}

/* Shell remount fade (no transform — avoids layout thrash) */
.ps-shell-enter {
  animation: ps-fade-in var(--duration-slow, 400ms) var(--ease-out, ease-out) both;
}

/* ─── Skeleton Shimmer ──────────────────────────────────── */

.ps-skeleton {
  background: linear-gradient(
    90deg,
    var(--surface-secondary, #1a1a1a) 25%,
    color-mix(in srgb, var(--surface-secondary, #1a1a1a) 60%, var(--text-dim, #666)) 50%,
    var(--surface-secondary, #1a1a1a) 75%
  );
  background-size: 200% 100%;
  animation: ps-shimmer 1.5s linear infinite;
  border-radius: var(--radius-sm, 4px);
}

/* ─── Spinner ───────────────────────────────────────────── */

.ps-spinner {
  display: inline-block;
  width: 1.25em;
  height: 1.25em;
  border: 2px solid transparent;
  border-top-color: currentColor;
  border-radius: 50%;
  animation: ps-spin 0.7s linear infinite;
}

/* ─── Toast / Alert Transitions ────────────────────────── */

.ps-toast--entering {
  animation: ps-slide-in-right var(--duration-fast, 200ms) var(--ease-out, ease-out) both;
}

.ps-toast--exiting {
  animation: ps-slide-out-right var(--duration-fast, 200ms) var(--ease-in, ease-in) both;
}

/* ─── Modal Transitions ─────────────────────────────────── */

.ps-modal-overlay--visible {
  animation: ps-fade-in var(--duration-normal, 280ms) var(--ease-out, ease-out) both;
}

.ps-modal--visible {
  animation: ps-slide-up var(--duration-normal, 280ms) var(--ease-silk, cubic-bezier(0.25, 0.46, 0.45, 0.94)) both;
}

/* ─── Upgrade CTA Pulse ─────────────────────────────────── */

.ps-upgrade-cta--pulse {
  animation: ps-gold-pulse 2s var(--ease-in-out, ease-in-out) 3;
}

/* ─── Home CTA Card Pulse ────────────────────────────────── */

.ps-home__cta-card--pulse {
  animation: ps-gold-pulse 2.5s ease-in-out 3;
}

/* ─── Touch Target Enforcement ──────────────────────────── */

.ps-touchable {
  min-height: 48px; /* --space-12 */
  min-width: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ─── Empty State Entrance ──────────────────────────────── */

.ps-empty-state {
  animation: ps-fade-in var(--duration-slow, 400ms) var(--ease-out, ease-out) both;
}

/* ─── Staggered List Entrance ───────────────────────────── */

@keyframes ps-stagger-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

.ps-stagger > * {
  animation: ps-stagger-in var(--duration-normal, 280ms) var(--ease-silk, cubic-bezier(0.25, 0.46, 0.45, 0.94)) both;
}

.ps-stagger > *:nth-child(1)  { animation-delay: 0ms; }
.ps-stagger > *:nth-child(2)  { animation-delay: 60ms; }
.ps-stagger > *:nth-child(3)  { animation-delay: 120ms; }
.ps-stagger > *:nth-child(4)  { animation-delay: 180ms; }
.ps-stagger > *:nth-child(5)  { animation-delay: 240ms; }
.ps-stagger > *:nth-child(6)  { animation-delay: 300ms; }
.ps-stagger > *:nth-child(n+7) { animation-delay: 360ms; }

/* ─── Skeleton → Content Morph ──────────────────────────── */

@keyframes ps-skeleton-reveal {
  from { opacity: 0; filter: blur(4px); transform: scale(0.98); }
  to   { opacity: 1; filter: blur(0);   transform: scale(1); }
}

.ps-skeleton-reveal {
  animation: ps-skeleton-reveal var(--duration-slow, 400ms) var(--ease-silk, cubic-bezier(0.25, 0.46, 0.45, 0.94)) both;
}

/* ─── Card Hover Lift ───────────────────────────────────── */

.ps-card {
  transition: transform var(--duration-fast, 200ms) var(--ease-out, ease-out),
              box-shadow var(--duration-fast, 200ms) var(--ease-out, ease-out);
}

@media (hover: hover) {
  .ps-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md, 0 4px 8px rgba(0, 0, 0, 0.35));
  }
}

/* ─── Scale-on-press (buttons & interactive targets) ────── */

@keyframes ps-press {
  0%   { transform: scale(1); }
  50%  { transform: scale(0.97); }
  100% { transform: scale(1); }
}

.ps-button:active,
[role="button"]:active {
  animation: ps-press 180ms var(--ease-out, ease-out);
}

/* ─── Floating Entrance (hero/empty-state) ──────────────── */

@keyframes ps-float-in {
  from { opacity: 0; transform: translateY(20px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.ps-float-in {
  animation: ps-float-in var(--duration-slower, 600ms) var(--ease-silk, cubic-bezier(0.25, 0.46, 0.45, 0.94)) both;
}

/* ─── Subtle Breathe (ambient idle elements) ────────────── */

@keyframes ps-breathe {
  0%, 100% { opacity: 0.7; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.02); }
}

.ps-breathe {
  animation: ps-breathe 4s var(--ease-in-out, ease-in-out) infinite;
}

/* ─── Type Reveal Ceremony ──────────────────────────────── */

@keyframes ps-particle-burst {
  0%   { opacity: 1; transform: translate(-50%, -50%) rotate(var(--angle)) translateX(0); }
  60%  { opacity: 1; transform: translate(-50%, -50%) rotate(var(--angle)) translateX(var(--radius, 60px)); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(var(--angle)) translateX(var(--radius, 60px)); }
}

@keyframes ps-type-reveal-word {
  0%   { opacity: 0; transform: translateY(20px) scale(0.92); letter-spacing: 0.3em; }
  100% { opacity: 1; transform: translateY(0)    scale(1);    letter-spacing: 0.1em; }
}

.ps-type-reveal {
  position: fixed;
  inset: 0;
  z-index: var(--z-onboarding, 500);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: radial-gradient(ellipse at center, #0d1229 0%, var(--bg-cosmic, #070a14) 70%);
  animation: ps-fade-in var(--duration-slow, 400ms) var(--ease-out, ease-out) both;
}

.ps-type-reveal__burst {
  position: relative;
  width: 120px;
  height: 120px;
  margin-bottom: var(--space-8, 2rem);
}

.ps-type-reveal__particle {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold, #c9a84c);
  animation: ps-particle-burst 1.2s var(--ease-out, ease-out) both;
}

.ps-type-reveal__word {
  animation: ps-type-reveal-word var(--duration-slower) var(--ease-silk, cubic-bezier(0.25, 0.46, 0.45, 0.94)) 400ms both;
}

/* ─── SVG Draw-In (bodygraph channels) ──────────────────── */

@keyframes ps-draw-in {
  from { stroke-dashoffset: 1; opacity: 0.3; }
  to   { stroke-dashoffset: 0; opacity: 1; }
}

.ps-draw-in {
  stroke-dasharray: 1;
  animation: ps-draw-in var(--duration-slower, 600ms) var(--ease-silk, cubic-bezier(0.25, 0.46, 0.45, 0.94)) both;
}

/* ─── Number Count-Up Glow ──────────────────────────────── */

@keyframes ps-glow-in {
  from { opacity: 0; text-shadow: 0 0 8px var(--color-gold-500, #c9a84c); }
  to   { opacity: 1; text-shadow: none; }
}

.ps-glow-in {
  animation: ps-glow-in var(--duration-slow, 400ms) var(--ease-out, ease-out) both;
}

/* ─── Responsive Layout Tiers ───────────────────────────── */
/* Note: `.ps-nav-bottom` and `.ps-nav-side` are legacy class names that are
 * never rendered — the real bottom nav uses `.ps-nav` (see nav-bar.js).
 * Show/hide of `.ps-nav` across breakpoints is handled in responsive.css.
 * Layout container helpers below remain in case shells opt into them. */

/* < 640px: stacked layout (bottom nav, full-width content) */
@media (max-width: 639px) {
  .ps-layout-sidebar {
    display: none;
  }

  .ps-layout-content {
    width: 100%;
  }
}

/* ≥ 640px: sidebar layout (wider panels, side nav) */
@media (min-width: 640px) {
  .ps-layout-sidebar {
    display: block;
  }
}

/* ─── Chart Birth Ceremony (resonance PR-3 / repair A1) ───
 * BodyGraph({ ceremony: true }) stamps `.bg-svg--ceremony` on the SVG root and
 * `.bg-reveal` + an inline `--reveal-delay` on defined centers, active
 * channels, and the gates layer. Everything below keys off those hooks.
 *
 * CRITICAL: every hidden initial state lives INSIDE keyframes and is applied
 * via animation-fill-mode: both — never as a static opacity: 0 — so when
 * accessibility.css collapses animation durations under
 * prefers-reduced-motion the chart degrades to instantly visible, not blank.
 */

/* Channel draw-in: elements carry pathLength="1", so dasharray 1 = one full
 * stroke; reuses the ps-draw-in keyframes above (dashoffset 1 → 0). */
.bg-svg--ceremony .bg-channel.bg-reveal {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: ps-draw-in 700ms var(--ease-silk, ease) var(--reveal-delay, 0ms) both;
}

/* Center bloom: shape + label scale-settle into place. transform-box:
 * fill-box keeps the scale centered on each shape, not the SVG origin. */
@keyframes ps-center-bloom {
  from { opacity: 0; transform: scale(1.06); }
  to   { opacity: 1; transform: scale(1); }
}

.bg-svg--ceremony .bg-center.bg-reveal > * {
  transform-box: fill-box;
  transform-origin: center;
  animation: ps-center-bloom 600ms var(--ease-silk, cubic-bezier(0.25, 0.46, 0.45, 0.94)) var(--reveal-delay, 0ms) both;
}

/* Gate badges: one quiet group-fade after the anatomy has landed. */
@keyframes ps-gates-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.bg-svg--ceremony .bg-gates-layer.bg-reveal {
  animation: ps-gates-fade 600ms var(--ease-silk, cubic-bezier(0.25, 0.46, 0.45, 0.94)) var(--reveal-delay, 0ms) both;
}

/* Tap-to-skip escape hatch: adding .bg-reveal--now to the SVG root zeroes
 * every stagger so the finished chart is on screen within one animation
 * frame. The draw/bloom/fade still resolve (fill-mode both), just instantly. */
.bg-svg--ceremony.bg-reveal--now .bg-channel.bg-reveal,
.bg-svg--ceremony.bg-reveal--now .bg-center.bg-reveal > *,
.bg-svg--ceremony.bg-reveal--now .bg-gates-layer.bg-reveal {
  animation-delay: 0ms !important;
  animation-duration: 0.01ms !important;
}

/* accessibility.css zeroes animation-duration under prefers-reduced-motion
 * but leaves animation-delay intact — zero the ceremony delays too so the
 * reduced-motion experience is the finished chart, immediately. */
@media (prefers-reduced-motion: reduce) {
  .bg-svg--ceremony .bg-channel.bg-reveal,
  .bg-svg--ceremony .bg-center.bg-reveal > *,
  .bg-svg--ceremony .bg-gates-layer.bg-reveal {
    animation-delay: 0ms !important;
  }
}
