/* ════════════════════════════════════════════════════════════════════════════
   VAULT V2 — Motion System (Real-Object Rebuild)

   The whole product moves with one of three curves: --ease-real-out,
   --ease-real-inout, --ease-real-in (defined in css/vault-v2.css :root).
   This file is a SHARED motion pack used by atrium presence orbs,
   zone transitions, the loading skeleton, the screenshot-protection
   shield, the live waveform during recording, and the brass ring
   (per docs/emtrace-movement-design.md Section 3.1).

   Removed in the Real-Object rebuild (these classes were dead code or
   spec-violating overshoot decoration):
     • springIn keyframe with scale(1.04) + Y wobble + cubic-bezier 1.56
     • bounce-tap (overshoot scale-down on tap)
     • breathe / breathe-slow / breathe-fast / glowBreathe (infinite loops)
     • sealBreak (rotate(5deg) → rotate(-15deg) shrink-spin)
     • contentReveal (blur(12px) reveal)
     • capsuleSend (orphaned — Phase 5 implements send differently)
     • warmthRipple (orphaned)
     • orbSpeaking / orbNewCapsule (notification-app pulse rings)

   Kept (and re-graded to the real-object dialect):
     • spring-in / spring-in-delay-N — opacity-only fade for atrium orbs
     • zoneEnter / zoneExit — opacity-only zone swap
     • skeleton + skeletonShimmer — loading affordance
     • live-waveform — literal audio reading during recording
     • hold-ring — brass ring per Hold-to-Listen spec
     • privacy-shield — screenshot-protection flash
   ════════════════════════════════════════════════════════════════════════════ */

/* ════════════════════════════════════════════════════════════════
   ENTRANCE FADE (atrium presence orbs)
   ════════════════════════════════════════════════════════════════ */
.spring-in {
  animation: springIn var(--dur-cross) var(--ease-real-out) both;
}

.spring-in-delay-1 { animation-delay: 40ms; }
.spring-in-delay-2 { animation-delay: 80ms; }
.spring-in-delay-3 { animation-delay: 120ms; }
.spring-in-delay-4 { animation-delay: 160ms; }
.spring-in-delay-5 { animation-delay: 200ms; }

@keyframes springIn {
  /* Real-Object: opacity-only. NO scale 0.8→1.04 overshoot, NO Y wobble.
     The element fades into existence on the wall like a portrait being
     unveiled. Class name is kept for backward compatibility with
     atrium markup. */
  from { opacity: 0; }
  to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .spring-in { animation: none !important; opacity: 1; }
}

/* ════════════════════════════════════════════════════════════════
   ZONE TRANSITIONS
   ════════════════════════════════════════════════════════════════ */
.zone-exit {
  animation: zoneExit 280ms var(--ease-real-out) both;
}

@keyframes zoneExit {
  to { opacity: 0; }
}

.zone-enter {
  animation: zoneEnterMotion 280ms var(--ease-real-out) both;
}

@keyframes zoneEnterMotion {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .zone-exit, .zone-enter { animation: none !important; }
}

/* ════════════════════════════════════════════════════════════════
   HOLD-TO-LISTEN BRASS RING
   The brass ring grows from the contact point during a long-press,
   completing ~75% by 500ms and full circle by 800ms. Per
   docs/emtrace-movement-design.md Section 3.1 — this is signature
   trade-dress motion. JS (when wired) toggles .holding to fill the
   stroke-dashoffset.
   ════════════════════════════════════════════════════════════════ */
.hold-ring {
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  pointer-events: none;
}

.hold-ring svg {
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
}

.hold-ring circle {
  fill: none;
  stroke: var(--glow-primary);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 283;
  stroke-dashoffset: 283;
  transition: stroke-dashoffset 800ms linear;
}

.hold-ring.holding circle {
  stroke-dashoffset: 0;
}

@media (prefers-reduced-motion: reduce) {
  .hold-ring circle { transition: none !important; }
}

/* ════════════════════════════════════════════════════════════════
   RECORDING WAVEFORM ANIMATION
   Live audio reading during composer recording. Each bar's height is
   driven by an analyser sample; this class only paces the alternation.
   ════════════════════════════════════════════════════════════════ */
.live-waveform .bar {
  animation: waveformLive 0.6s ease-in-out infinite alternate;
}

.live-waveform .bar:nth-child(1) { animation-delay: 0s; }
.live-waveform .bar:nth-child(2) { animation-delay: 0.08s; }
.live-waveform .bar:nth-child(3) { animation-delay: 0.16s; }
.live-waveform .bar:nth-child(4) { animation-delay: 0.24s; }
.live-waveform .bar:nth-child(5) { animation-delay: 0.32s; }
.live-waveform .bar:nth-child(6) { animation-delay: 0.4s; }
.live-waveform .bar:nth-child(7) { animation-delay: 0.48s; }
.live-waveform .bar:nth-child(8) { animation-delay: 0.56s; }
.live-waveform .bar:nth-child(9) { animation-delay: 0.64s; }
.live-waveform .bar:nth-child(10) { animation-delay: 0.72s; }

@keyframes waveformLive {
  0% { height: 4px; opacity: 0.4; }
  100% { height: var(--bar-max-height, 28px); opacity: 0.9; }
}

@media (prefers-reduced-motion: reduce) {
  .live-waveform .bar { animation: none !important; height: var(--bar-max-height, 28px); }
}

/* ════════════════════════════════════════════════════════════════
   LOADING SKELETON
   ════════════════════════════════════════════════════════════════ */
.skeleton {
  background: linear-gradient(90deg, var(--vault-elevated) 25%, var(--vault-surface) 50%, var(--vault-elevated) 75%);
  background-size: 200% 100%;
  animation: skeletonShimmer 1.5s ease-in-out infinite;
  border-radius: var(--radius-sm);
}

@keyframes skeletonShimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none !important; }
}

/* ════════════════════════════════════════════════════════════════
   SCREENSHOT PROTECTION FLASH
   ════════════════════════════════════════════════════════════════ */
.privacy-shield {
  position: fixed;
  inset: 0;
  background: var(--vault-obsidian);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.1s;
}

.privacy-shield.active {
  opacity: 1;
  pointer-events: auto;
}

.privacy-shield .shield-icon {
  font-size: 3rem;
  animation: shieldPulse 0.5s var(--ease-real-out);
}

@keyframes shieldPulse {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .privacy-shield .shield-icon { animation: none !important; }
}
