/* Astro motion layer: entrances, cursor glow, button life, dialogs, background.
   Rule: entrance animations only play when you ARRIVE on a page (body.entering, set by the router for ~1 s),
   never when a page updates itself in place - so live updates don't blink. */

:root {
  --ease-out: cubic-bezier(.22, 1, .36, 1);       /* fast start, soft landing */
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1); /* slight overshoot */
}

/* ---------- page entrance ---------- */
.page { animation: none; }
body.entering .page { animation: ast-page-in .55s var(--ease-out) both; }
@keyframes ast-page-in { from { opacity: 0; transform: translateY(14px); filter: blur(6px); } to { opacity: 1; transform: none; filter: none; } }
body.entering .page .st-head h1 { animation: ast-title-in .7s var(--ease-out) both .05s; }
@keyframes ast-title-in { from { opacity: 0; transform: translateY(18px); letter-spacing: .02em; } to { opacity: 1; transform: none; } }
body.entering .page .st-composer { animation: ast-rise .6s var(--ease-out) both .12s, st-spin 12s linear infinite; }

/* cards cascade in (--i is set by app.js, capped so long lists don't wait) */
body.entering .page :is(.st-card, .st-tile, .ast-char, .st-voice, .ast-u, .ast-model, .ast-panel, .ast-key, .ast-tr:not(.th)) {
  animation: ast-rise .55s var(--ease-out) both; animation-delay: calc(var(--i, 0) * 45ms + 120ms);
}
@keyframes ast-rise { from { opacity: 0; transform: translateY(16px) scale(.98); } to { opacity: 1; transform: none; } }

/* a finished generation swapping in: soft reveal */
.st-card.fresh { animation: ast-reveal .8s var(--ease-out) both; }
@keyframes ast-reveal { from { opacity: 0; transform: scale(.96); filter: blur(10px) saturate(1.6); } to { opacity: 1; transform: none; filter: none; } }

/* ---------- cursor spotlight on cards (position from app.js: --mx/--my) ---------- */
:is(.st-card, .st-tile, .ast-char, .st-voice, .ast-panel, .ast-model, .ast-u, .st-composer) { position: relative; isolation: isolate; }
:is(.st-card, .st-tile, .ast-char, .st-voice, .ast-panel, .ast-model, .ast-u)::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 2; opacity: 0; transition: opacity .35s;
  background: radial-gradient(420px circle at var(--mx, 50%) var(--my, 50%), rgba(196, 181, 253, .12), transparent 45%);
  box-shadow: inset 0 0 0 1px rgba(244, 114, 182, .0);
}
:is(.st-card, .st-tile, .ast-char, .st-voice, .ast-panel, .ast-model, .ast-u):hover::after { opacity: 1; }
.st-card, .st-tile, .st-voice, .ast-model { transition: transform .35s var(--ease-out), border-color .25s, box-shadow .35s var(--ease-out); }
.st-card:hover, .st-tile:hover, .st-voice:hover { transform: translateY(-4px); box-shadow: 0 24px 48px -24px rgba(139, 92, 246, .55), 0 0 0 1px rgba(196, 181, 253, .18); }
.st-media img, .st-media video, .st-tile-media img, .st-tile-media video { transition: transform .6s var(--ease-out), filter .4s; }
.st-card:hover .st-media img, .st-card:hover .st-media video, .st-tile:hover .st-tile-media img, .st-tile:hover .st-tile-media video { transform: scale(1.04); }
.st-hover { transform: translateY(-4px); transition: opacity .25s, transform .35s var(--ease-out); }
.st-card:hover .st-hover, .st-tile:hover .st-hover { transform: none; }

/* ---------- buttons ---------- */
.st-go, .btn.primary { position: relative; overflow: hidden; background-size: 200% 100%; transition: transform .2s var(--ease-spring), background-position .6s var(--ease-out), box-shadow .3s, filter .2s; }
.st-go:hover:not(:disabled), .btn.primary:hover { background-position: 100% 0; box-shadow: 0 14px 36px -10px rgba(244, 114, 182, .7); }
.st-go::before, .btn.primary::before { /* light sweep */
  content: ''; position: absolute; inset: 0; transform: translateX(-120%); pointer-events: none;
  background: linear-gradient(105deg, transparent 30%, rgba(255, 255, 255, .35) 50%, transparent 70%);
}
.st-go:hover:not(:disabled)::before, .btn.primary:hover::before { transform: translateX(120%); transition: transform .8s var(--ease-out); }
.st-go:active:not(:disabled), .btn:active, .st-add:active, .st-seg button:active, .st-ic:active { transform: scale(.96); }
.st-go#go:not(:disabled) { animation: ast-ready 2.8s ease-in-out infinite; }
@keyframes ast-ready { 50% { box-shadow: 0 10px 34px -6px rgba(244, 114, 182, .75), 0 0 0 4px rgba(244, 114, 182, .08); } }
.st-go.busy { pointer-events: none; color: transparent; animation: none; }
.st-go.busy::after { content: ''; position: absolute; left: 50%; top: 50%; width: 18px; height: 18px; margin: -9px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .35); border-top-color: #fff; animation: spin .7s linear infinite; }
.btn, .st-add, .st-link, .st-ic, .st-prov button { transition: transform .2s var(--ease-spring), background .2s, color .2s, border-color .2s; }
.st-add:hover:not(:disabled) { transform: translateY(-1px); }
.st-link svg { transition: transform .25s var(--ease-out); }
.st-link:hover svg { transform: translateX(3px); }

/* ---------- segmented controls, pills, inputs ---------- */
.st-seg button, .st-seg a { transition: background .3s var(--ease-out), color .2s, box-shadow .3s; }
.st-seg button.on, .st-seg a.on { animation: ast-pop .35s var(--ease-spring); }
@keyframes ast-pop { from { transform: scale(.94); } }
.st-pill { transition: border-color .2s, background .2s, transform .2s var(--ease-spring); }
.st-pill:hover { transform: translateY(-1px); background: rgba(36, 27, 82, .6); }
.input, .select, .textarea, .st-search, .st-composer textarea { transition: border-color .2s, box-shadow .3s var(--ease-out), background .2s; }
.input:focus, .select:focus, .textarea:focus { border-color: #a78bfa; box-shadow: 0 0 0 4px rgba(139, 92, 246, .18); }
.st-composer:focus-within { box-shadow: 0 34px 90px -30px rgba(244, 114, 182, .55), 0 0 0 1px rgba(196, 181, 253, .25), inset 0 1px 0 rgba(255, 255, 255, .06); }
.st-search:focus-within { border-color: #a78bfa; box-shadow: 0 0 0 4px rgba(139, 92, 246, .15); }
.ast-switch { transition: background .3s var(--ease-out); }
.ast-switch::after { transition: left .35s var(--ease-spring), transform .2s; }
.ast-switch:active::after { transform: scaleX(1.25); }

/* ---------- sidebar ---------- */
.nav a { position: relative; transition: background .25s, color .2s, transform .25s var(--ease-out); }
.nav a:hover { transform: translateX(3px); }
.nav a svg { transition: transform .35s var(--ease-spring); }
.nav a:hover svg { transform: scale(1.15) rotate(-6deg); }
.nav a.active::before { content: ''; position: absolute; left: 0; top: 18%; bottom: 18%; width: 3px; border-radius: 3px; background: var(--grad);
  box-shadow: 0 0 12px rgba(244, 114, 182, .8); animation: ast-grow .4s var(--ease-spring); }
@keyframes ast-grow { from { transform: scaleY(0); } }
.astro-mark::after { animation: ast-orbit 9s linear infinite; }
@keyframes ast-orbit { 50% { transform: rotate(-12deg) scale(1.04); } 0%, 100% { transform: rotate(-25deg); } }
.ast-w-row b { transition: color .4s; }
.ast-w-row b.changed { animation: ast-flash 1.2s var(--ease-out); }
@keyframes ast-flash { 0% { color: #f9a8d4; text-shadow: 0 0 14px rgba(244, 114, 182, .9); } }

/* ---------- dialogs + toasts ---------- */
.modal-root { animation: ast-fade .25s var(--ease-out); backdrop-filter: blur(10px) saturate(1.2); background: rgba(5, 4, 15, .62); }
@keyframes ast-fade { from { opacity: 0; backdrop-filter: blur(0); } }
.modal { animation: ast-modal .45s var(--ease-spring); background: linear-gradient(180deg, rgba(26, 20, 62, .96), rgba(14, 11, 34, .98)); border-color: rgba(196, 181, 253, .22); }
@keyframes ast-modal { from { opacity: 0; transform: translateY(18px) scale(.94); } }
.toast { animation: ast-toast .5s var(--ease-spring); background: linear-gradient(180deg, rgba(30, 23, 70, .96), rgba(16, 12, 38, .98)); backdrop-filter: blur(12px); }
@keyframes ast-toast { from { opacity: 0; transform: translateX(30px) scale(.95); } }

/* ---------- live progress ---------- */
.st-shimmer { background: linear-gradient(110deg, rgba(36, 27, 82, .55) 30%, rgba(139, 92, 246, .32) 45%, rgba(244, 114, 182, .22) 55%, rgba(36, 27, 82, .55) 70%); background-size: 250% 100%; }
.st-pbar i { position: relative; overflow: hidden; }
.st-pbar i::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .55), transparent); animation: ast-sweep 1.4s linear infinite; }
@keyframes ast-sweep { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.st-pct { animation: ast-breathe 2.4s ease-in-out infinite; }
@keyframes ast-breathe { 50% { filter: brightness(1.25); } }

/* ---------- loading placeholders (shown while a page loads) ---------- */
.ast-skel { display: grid; gap: 18px; padding-top: 6px; }
.ast-skel i { display: block; border-radius: 14px; background: linear-gradient(110deg, rgba(36, 27, 82, .45) 30%, rgba(139, 92, 246, .18) 50%, rgba(36, 27, 82, .45) 70%);
  background-size: 250% 100%; animation: st-sheen 1.4s linear infinite; }
.ast-skel .t { width: 38%; height: 44px; } .ast-skel .s { width: 60%; height: 14px; }
.ast-skel .b { height: 180px; border-radius: 24px; }
.ast-skel .row { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }
.ast-skel .row i { height: 220px; border-radius: 18px; }

/* ---------- background: slow twinkle + drifting nebula ---------- */
.astro-sky { animation: ast-drift 40s ease-in-out infinite alternate; }
@keyframes ast-drift { to { transform: translate3d(-1.5%, 1%, 0) scale(1.04); } }
.astro-sky::after { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(1px 1px at 30% 25%, #fff, transparent 60%), radial-gradient(1.5px 1.5px at 65% 70%, #fff, transparent 60%),
    radial-gradient(1px 1px at 82% 22%, #fff, transparent 60%), radial-gradient(1px 1px at 15% 60%, #fff, transparent 60%), radial-gradient(1.5px 1.5px at 50% 45%, #fff, transparent 60%);
  animation: ast-twinkle 5s ease-in-out infinite alternate; }
@keyframes ast-twinkle { from { opacity: .15; } to { opacity: .8; } }

/* sign-in card */
.ast-login { animation: ast-modal .7s var(--ease-spring) both; }
.ast-login .astro-mark.big { animation: ast-float 5s ease-in-out infinite; }
@keyframes ast-float { 50% { transform: translateY(-6px); } }

/* ---------- respect "reduce motion" ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  .st-card:hover, .st-tile:hover, .st-voice:hover, .nav a:hover { transform: none; }
}
