/* ============================================================================
   Pro UI — TRANSITION surface (lock -> chat reveal animation).
   Scope root: body.pro-lock.pro-authed  — every selector is nested under it so
   these rules ONLY fire when the Pro lockscreen was shown AND auth succeeded.
   Additive: nothing here matches until chat-slim.js adds `pro-authed` to <body>
   (which it only does when proFlag('lockscreen') is on, i.e. body.pro-lock).
   Uses var(--pro-*) tokens from pro-tokens.css. No external assets.
   Canon: A.I Vault/J-Bot/J-Bot Pro Surface Blueprint.md
   ============================================================================ */

/* ---------------------------------------------------------------------------
   Motion beats (from transition.html), compressed into a ~500ms one-shot:
     0ms    lock card is fully present, sitting over the chat behind it
     ~120ms card flares (scale up a hair) then collapses + fades
     ~200ms a cyan bloom flashes at the disc, scrim veil begins to lift
     ~500ms card gone, scrim gone, chat settled in behind
   The lock card here is the LIVE #auth-gate — we fade + scale IT out (opacity
   + transform only), lift a scrim pseudo-layer, and let the chat behind settle.
   --------------------------------------------------------------------------- */

/* Keep the gate paintable through the animation. chat-slim.js's finish() slams
   `.hidden` (display:none !important) on #auth-gate the instant a credential is
   accepted — a display:none element can't animate. Re-assert a painted box on
   the scoped root (higher specificity + !important beats the .hidden rule) so
   the reveal actually plays, then land it on a gone-but-in-DOM end state. */
body.pro-lock.pro-authed #auth-gate,
body.pro-lock.pro-authed #auth-gate.hidden {
  display: grid !important;               /* override .hidden { display:none !important } */
  animation: pro-tr-gate-out 500ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
  will-change: opacity, transform;
  transform-origin: 50% 46%;
}

/* The card itself gets the flare-then-collapse pump on top of the wrapper fade,
   so the reveal reads as the lock "opening" rather than a flat crossfade. */
body.pro-lock.pro-authed #auth-gate .auth-card {
  animation: pro-tr-card-out 500ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
  will-change: opacity, transform;
  transform-origin: 50% 46%;
}

/* Scrim veil + cyan bloom: a soft dark overlay that lifts, and a single cyan
   flash at the unlock beat. Painted as ::before / ::after on the gate so we
   introduce no new DOM (the operator only injects the sr-only announce span). */
body.pro-lock.pro-authed #auth-gate::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;                            /* behind the auth-card, over the chat */
  pointer-events: none;
  background: rgba(6, 10, 16, 0.55);      /* == var(--pro-base) veil */
  animation: pro-tr-scrim-lift 500ms ease forwards;
}

body.pro-lock.pro-authed #auth-gate::after {
  content: "";
  position: fixed;
  left: 50%;
  top: 46%;
  width: 340px;
  height: 340px;
  margin: -170px 0 0 -170px;
  z-index: -1;
  pointer-events: none;
  border-radius: 50%;
  opacity: 0;
  background: radial-gradient(circle,
    rgba(92, 240, 255, 0.55) 0%,          /* == var(--pro-glow-cyan) */
    rgba(34, 211, 238, 0.18) 34%,         /* == var(--pro-spine-cyan) */
    transparent 66%);
  animation: pro-tr-bloom 500ms ease forwards;
}

/* The chat behind the gate: settle in (fade + tiny rise) as the veil lifts.
   .slim-app is the chat root in chat-slim.html; scoped so it only animates on
   the unlock, never on normal loads. */
body.pro-lock.pro-authed .slim-app {
  animation: pro-tr-app-settle 560ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
  will-change: opacity, transform;
}

/* ---- keyframes ---- */
@keyframes pro-tr-gate-out {
  0%   { opacity: 1; }
  40%  { opacity: 1; }
  100% { opacity: 0; visibility: hidden; pointer-events: none; }
}

@keyframes pro-tr-card-out {
  0%   { opacity: 1; transform: scale(1); }
  24%  { opacity: 1; transform: scale(1.015); }   /* flare */
  100% { opacity: 0; transform: scale(0.9); }     /* collapse */
}

@keyframes pro-tr-scrim-lift {
  0%   { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes pro-tr-bloom {
  0%   { opacity: 0; transform: scale(0.6); }
  40%  { opacity: 0.95; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.5); }
}

@keyframes pro-tr-app-settle {
  0%   { opacity: 0; transform: translateY(6px); }
  40%  { opacity: 0; transform: translateY(6px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* ---------------------------------------------------------------------------
   Reduced motion: no animation, instant. The gate goes straight to its gone
   end-state and the chat is fully present — same final frame, zero motion.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  body.pro-lock.pro-authed #auth-gate,
  body.pro-lock.pro-authed #auth-gate.hidden {
    animation: none;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }
  body.pro-lock.pro-authed #auth-gate .auth-card,
  body.pro-lock.pro-authed #auth-gate::before,
  body.pro-lock.pro-authed #auth-gate::after {
    animation: none;
    opacity: 0;
  }
  body.pro-lock.pro-authed .slim-app {
    animation: none;
    opacity: 1;
    transform: none;
  }
}
