/* ============================================================
   COMMAND DECK — motion
   Rules this file obeys:
     1. Every duration and easing comes from tokens.css.
     2. Compositor-safe properties only: transform, opacity, clip-path.
     3. One hero moment per screen (the clock confirmation), and it fires
        only after an actual clock action, never on a plain page visit.
     4. Motion never blocks input. Nothing here gates a click.
     5. Reduced motion collapses duration to 1ms via the token override, so
        every animation still LANDS ON ITS FINAL VISIBLE STATE.
   Stagger is expressed with :nth-child rather than an inline --index, so the
   strict Content-Security-Policy needs no style-attribute exception.
   ============================================================ */

@keyframes rise {
  from { opacity: 0; transform: translate3d(0, var(--travel-md), 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ---------------- Page entrance ----------------
   Supporting sections rise in sequence behind the lead element. */

.content > * {
  animation: rise var(--d-base) var(--e-out) both;
}
.content > *:nth-child(1) { animation-delay: calc(var(--stagger) * 0); }
.content > *:nth-child(2) { animation-delay: calc(var(--stagger) * 1); }
.content > *:nth-child(3) { animation-delay: calc(var(--stagger) * 2); }
.content > *:nth-child(4) { animation-delay: calc(var(--stagger) * 3); }
.content > *:nth-child(5) { animation-delay: calc(var(--stagger) * 4); }
.content > *:nth-child(6) { animation-delay: calc(var(--stagger) * 5); }
.content > *:nth-child(n + 7) { animation-delay: calc(var(--stagger) * 6); }

/* Roster rows settle after their card. Capped so a long list does not
   turn into a slow cascade the user has to sit through. */
.roster-row { animation: fade var(--d-fast) var(--e-out) both; }
.roster-row:nth-child(1) { animation-delay: calc(var(--stagger) * 1); }
.roster-row:nth-child(2) { animation-delay: calc(var(--stagger) * 1.4); }
.roster-row:nth-child(3) { animation-delay: calc(var(--stagger) * 1.8); }
.roster-row:nth-child(4) { animation-delay: calc(var(--stagger) * 2.2); }
.roster-row:nth-child(n + 5) { animation-delay: calc(var(--stagger) * 2.6); }

.auth-card { animation: rise var(--d-slow) var(--e-out) both; }

/* ---------------- The one hero moment ----------------
   Applied only when the page was reached by completing a clock action.
   A camera-style push-in plus a single bloom of light: composed, not loud. */

@keyframes heroLand {
  from { transform: scale(0.965); }
  to   { transform: scale(1); }
}

@keyframes heroBloom {
  from { opacity: 0.55; transform: scale(0.7); }
  to   { opacity: 0;    transform: scale(1.9); }
}

@keyframes heroWipe {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

.clock-card.is-hero {
  animation: heroLand var(--d-hero) var(--e-spring) both;
}

.clock-card.is-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 240px;
  height: 240px;
  border-radius: var(--r-full);
  background: radial-gradient(circle, var(--accent-line), transparent 68%);
  animation: heroBloom var(--d-hero) var(--e-out) both;
  pointer-events: none; /* the bloom must never intercept a click */
}

.clock-card.is-hero .clock-face {
  animation: heroWipe var(--d-hero) var(--e-out) both;
}

.clock-card.is-hero .clock-state {
  animation: rise var(--d-slow) var(--e-out) both;
  animation-delay: calc(var(--stagger) * 3);
}

/* ---------------- Live-state breathing ----------------
   Opacity only, and the reduced-motion block stops it at one cycle. */

@keyframes breathe {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

.clock-state[data-state="in"] .pulse-dot,
.clock-state[data-state="break"] .pulse-dot {
  animation: breathe var(--d-breathe) var(--e-in-out) infinite;
}

/* ---------------- Flash message ---------------- */

.flash-slot { animation: rise var(--d-base) var(--e-out) both; }

/* ---------------- Reduced motion ----------------
   Durations are already collapsed by the token override. These rules remove
   the remaining decorative pieces so nothing is left mid-transform, and every
   element sits at its complete, readable final state. */

@media (prefers-reduced-motion: reduce) {
  .clock-card.is-hero::before { display: none; }
  .clock-card.is-hero .clock-face { clip-path: none; }
  .clock-state .pulse-dot { animation: none; opacity: 1; }
  .btn[data-busy="true"]::after { animation: none; }
}
