/* Scene styling and keyframes for the hero animation of /features/privacy.html,
   "Only Sofia holds the key". Every animated element's resting style IS its final pose; the
   keyframes only animate towards it (fill-mode both), so a scene shown without animation
   (reduced motion) is complete. Keyframes run only while their scene carries .is-active.
   Timing: an element's timing class sets --pv-at (its start) and, for a flight, the
   --pv-dx / --pv-dy offset it flies in from. */

.pv-ink { color: var(--anim-ink); }
.pv-friend { color: var(--brand-2); }
.pv-brand { color: var(--brand-1); }
.pv-warm { color: var(--anim-warm); }
.pv-love { color: var(--anim-love); }
.pv-alert { color: var(--anim-alert); }
.pv-muted { color: var(--anim-muted); }
.pv-line { fill: var(--anim-muted); opacity: 0.7; }
.pv-line-ink { fill: var(--anim-ink); }
.pv-glow-soft { fill: var(--anim-warm-soft); }
.pv-floor { fill: var(--anim-muted); opacity: 0.35; }
.pv-beam, .pv-halo { fill: none; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 0; }
.pv-halo { stroke: var(--anim-warm-soft); stroke-width: 12; }
.pv-beam { stroke: var(--anim-warm); stroke-width: 3; }
.pv-beam-alert { stroke: var(--anim-alert); }
.pv-face-out, .pv-face-mid, .pv-gone, .pv-ringing, .pv-into, .pv-mid { opacity: 0; }
.pv-pop, .pv-fly, .pv-gone, .pv-drop, .pv-into, .pv-grow { transform-box: fill-box; transform-origin: center; }
.pv-grow { transform-origin: 0 50%; }
.pv-body { transform-box: fill-box; transform-origin: 50% 100%; }
.pv-buzz { transform-box: fill-box; transform-origin: 50% 50%; }

@keyframes pv-fade-in { from { opacity: 0; } }
@keyframes pv-fade-out { from { opacity: 1; } }
/* Shown only between two moments: in at the start, out at the end. */
@keyframes pv-mid { 0% { opacity: 0; } 14%, 86% { opacity: 1; } 100% { opacity: 0; } }
/* Gone for a while, then back: out at the start, in again at the end. */
@keyframes pv-away { 0% { opacity: 1; } 14%, 86% { opacity: 0; } 100% { opacity: 1; } }
@keyframes pv-pop { from { transform: scale(0); opacity: 0; } 50% { opacity: 1; } }
/* A thing flying to where it lands; each element names its own start offset. */
@keyframes pv-fly { from { transform: translate(var(--pv-dx, 0), var(--pv-dy, 0)) scale(0.4); opacity: 0; } 20% { opacity: 1; } }
/* A thing flying into a container and disappearing inside it. */
@keyframes pv-into { 0% { transform: translate(var(--pv-dx, 0), var(--pv-dy, 0)); opacity: 0; } 15% { opacity: 1; } 80% { transform: none; opacity: 1; } 100% { transform: translateY(14px) scale(0.6); opacity: 0; } }
/* Leaving: shrinks and fades to nothing. */
@keyframes pv-gone { from { transform: none; opacity: 1; } to { transform: scale(0.3); opacity: 0; } }
@keyframes pv-drop { from { transform: translateY(-70px); opacity: 0; } 30% { opacity: 1; } }
@keyframes pv-grow { from { transform: scaleX(0); } }
@keyframes pv-draw { from { stroke-dashoffset: 100; } }
@keyframes pv-hop { 0%, 100% { transform: none; } 40% { transform: translateY(-9px); } 70% { transform: translateY(2px); } }
@keyframes pv-giggle { 0%, 40%, 80%, 100% { transform: none; } 20% { transform: translateY(-6px) rotate(-2deg); } 60% { transform: translateY(-5px) rotate(2deg); } }
@keyframes pv-shake { 0%, 100% { transform: none; } 20% { transform: rotate(-4deg); } 40% { transform: rotate(4deg); } 60% { transform: rotate(-3deg); } 80% { transform: rotate(2deg); } }
@keyframes pv-buzz { 0%, 100% { transform: none; } 10%, 30%, 50%, 70%, 90% { transform: rotate(-6deg); } 20%, 40%, 60%, 80% { transform: rotate(6deg); } }
@keyframes pv-ring { 0% { opacity: 0; } 20%, 80% { opacity: 1; } 100% { opacity: 0; } }

/* Springy entrances overshoot through the easing, not through extra keyframes. */
.is-active .pv-pop { animation: pv-pop 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) var(--pv-at, 0s) both; }
.is-active .pv-fly { animation: pv-fly 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) var(--pv-at, 0s) both; }
.is-active .pv-drop { animation: pv-drop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) var(--pv-at, 0s) both; }
.is-active .pv-grow { animation: pv-grow 0.4s ease var(--pv-at, 0s) both; }
.is-active .pv-into { animation: pv-into 1.1s ease-in-out var(--pv-at, 0s) both; }
.is-active .pv-gone { animation: pv-gone 0.5s ease-in var(--pv-at, 1s) both; }
.is-active .pv-ringing { animation: pv-ring 1s ease var(--pv-at, 0.3s) both; }
.is-active .pv-buzzing { animation: pv-buzz 0.9s ease var(--pv-at, 0.3s) both; }
/* A face swap: the earlier face fades out as the later one fades in, at the pair's --pv-at. */
.is-active .pv-face-out { animation: pv-fade-out 0.2s ease var(--pv-at, 1s) both; }
.is-active .pv-face-in { animation: pv-fade-in 0.2s ease var(--pv-at, 1s) both; }
.is-active .pv-face-mid, .is-active .pv-mid { animation: pv-mid var(--pv-dur, 1.4s) linear var(--pv-at, 1s) both; }
.is-active .pv-away { animation: pv-away var(--pv-dur, 1.4s) linear var(--pv-at, 1s) both; }
.is-active .pv-hop { animation: pv-hop 0.5s ease-out var(--pv-at, 1s) both; }
.is-active .pv-giggle { animation: pv-giggle 0.6s ease var(--pv-at, 1s) both; }
.is-active .pv-shake { animation: pv-shake 0.4s ease var(--pv-at, 1s) both; }
.is-active .pv-beam, .is-active .pv-halo { animation: pv-draw 0.5s ease-in-out var(--pv-at, 1s) both; }

/* Scene 1, the moment: Sofia's card, address and email fly to Yuki and Amara, who laugh. */
.pv-s1-face, .pv-s1-sofia { --pv-at: 0.3s; }
.pv-s1-t1 { --pv-at: 0.5s; --pv-dx: -250px; --pv-dy: 120px; }
.pv-s1-t2 { --pv-at: 0.8s; --pv-dx: -254px; --pv-dy: 70px; }
.pv-s1-t3 { --pv-at: 1.1s; --pv-dx: -250px; --pv-dy: -50px; }
.pv-s1-cface, .pv-s1-yuki { --pv-at: 1.8s; }
.pv-s1-amara { --pv-at: 1.9s; }
.pv-s1-heart { --pv-at: 2.1s; }

/* Scene 2, the old way: a server keeps everything readable, a stranger peeks and a card leaks away. */
.pv-s2-peek { --pv-at: 1s; }
.pv-s2-no { --pv-at: 1.6s; }
.pv-s2-steal { --pv-at: 2s; --pv-dx: -128px; --pv-dy: 0px; }
.pv-s2-face, .pv-s2-sofia { --pv-at: 2.4s; }

/* Scene 3, allme: every detail travels as a lock, the server keeps locks, and they open only at Yuki and Amara. */
.pv-s3-l0 { --pv-at: 0.4s; --pv-dx: -184px; --pv-dy: 40px; }
.pv-s3-l00 { --pv-at: 0.6s; --pv-dx: -184px; --pv-dy: -10px; }
.pv-s3-l1 { --pv-at: 1.3s; --pv-dx: -130px; --pv-dy: 100px; }
.pv-s3-l2 { --pv-at: 1.6s; --pv-dx: -130px; --pv-dy: -66px; }
.pv-s3-open { --pv-at: 2.4s; }
.pv-s3-cface, .pv-s3-yuki { --pv-at: 2.5s; }
.pv-s3-amara { --pv-at: 2.6s; }
.pv-s3-face, .pv-s3-sofia { --pv-at: 2.8s; }

/* Scene 4, the payoff: a private field on her phone opens with her key for a moment, then locks itself again. */
.pv-s4-key { --pv-at: 0.5s; --pv-dx: 120px; --pv-dy: -20px; }
.pv-s4-lock, .pv-s4-open { --pv-at: 1.2s; --pv-dur: 3s; }
.pv-s4-face { --pv-at: 1.4s; }
.pv-s4-k1 { --pv-at: 1.6s; }
.pv-s4-k2 { --pv-at: 1.7s; }
.pv-s4-sofia { --pv-at: 4.4s; }
