/* Scene styling and keyframes for the hero animation of /features/safety.html,
   "Mei blocks a stranger". 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 --sf-at (its start) and, for a flight, the
   --sf-dx / --sf-dy offset it flies in from. */

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

@keyframes sf-fade-in { from { opacity: 0; } }
@keyframes sf-fade-out { from { opacity: 1; } }
/* Shown only between two moments: in at the start, out at the end. */
@keyframes sf-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 sf-away { 0% { opacity: 1; } 14%, 86% { opacity: 0; } 100% { opacity: 1; } }
@keyframes sf-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 sf-fly { from { transform: translate(var(--sf-dx, 0), var(--sf-dy, 0)) scale(0.4); opacity: 0; } 20% { opacity: 1; } }
/* A thing flying into a container and disappearing inside it. */
@keyframes sf-into { 0% { transform: translate(var(--sf-dx, 0), var(--sf-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 sf-gone { from { transform: none; opacity: 1; } to { transform: scale(0.3); opacity: 0; } }
@keyframes sf-drop { from { transform: translateY(-70px); opacity: 0; } 30% { opacity: 1; } }
@keyframes sf-grow { from { transform: scaleX(0); } }
@keyframes sf-draw { from { stroke-dashoffset: 100; } }
@keyframes sf-hop { 0%, 100% { transform: none; } 40% { transform: translateY(-9px); } 70% { transform: translateY(2px); } }
@keyframes sf-giggle { 0%, 40%, 80%, 100% { transform: none; } 20% { transform: translateY(-6px) rotate(-2deg); } 60% { transform: translateY(-5px) rotate(2deg); } }
@keyframes sf-shake { 0%, 100% { transform: none; } 20% { transform: rotate(-4deg); } 40% { transform: rotate(4deg); } 60% { transform: rotate(-3deg); } 80% { transform: rotate(2deg); } }
@keyframes sf-buzz { 0%, 100% { transform: none; } 10%, 30%, 50%, 70%, 90% { transform: rotate(-6deg); } 20%, 40%, 60%, 80% { transform: rotate(6deg); } }
@keyframes sf-ring { 0% { opacity: 0; } 20%, 80% { opacity: 1; } 100% { opacity: 0; } }

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

/* Scene 1, the moment: messages from a stranger pile up on Mei's buzzing phone, and her face falls. */
.sf-s1-phone, .sf-s1-ring { --sf-at: 0.5s; }
.sf-s1-b1 { --sf-at: 0.4s; --sf-dx: 240px; --sf-dy: 110px; }
.sf-s1-b2 { --sf-at: 0.9s; --sf-dx: 170px; --sf-dy: 70px; }
.sf-s1-b3 { --sf-at: 1.4s; --sf-dx: 240px; --sf-dy: 28px; }
.sf-s1-b4 { --sf-at: 1.9s; --sf-dx: 170px; --sf-dy: -14px; }
.sf-s1-b5 { --sf-at: 2.4s; --sf-dx: 240px; --sf-dy: -56px; }
.sf-s1-face, .sf-s1-mei { --sf-at: 2.8s; }

/* Scene 2, the old way: she hides the stranger, but his messages keep arriving into a box out of sight. */
.sf-s2-hide { --sf-at: 0.4s; }
.sf-s2-b1 { --sf-at: 1s; --sf-dx: 260px; --sf-dy: 18px; }
.sf-s2-b2 { --sf-at: 1.4s; --sf-dx: 214px; --sf-dy: 26px; }
.sf-s2-b3 { --sf-at: 1.8s; --sf-dx: 168px; --sf-dy: 16px; }
.sf-s2-b4 { --sf-at: 2.2s; --sf-dx: 238px; --sf-dy: 54px; }
.sf-s2-b5 { --sf-at: 2.6s; --sf-dx: 190px; --sf-dy: 58px; }
.sf-s2-face, .sf-s2-mei { --sf-at: 3s; }

/* Scene 3, allme: one tap on Block, the stranger and his messages vanish, and a report flag travels off and is checked. */
.sf-s3-block { --sf-at: 0.4s; }
.sf-s3-gone { --sf-at: 1s; }
.sf-s3-gone1 { --sf-at: 1.1s; }
.sf-s3-gone2 { --sf-at: 1.2s; }
.sf-s3-gone3 { --sf-at: 1.3s; }
.sf-s3-beam { --sf-at: 1.8s; }
.sf-s3-flag { --sf-at: 2.2s; }
.sf-s3-check { --sf-at: 2.6s; }
.sf-s3-face, .sf-s3-mei, .sf-s3-k1 { --sf-at: 2.8s; }
.sf-s3-k2 { --sf-at: 2.9s; }

/* Scene 4, the payoff: Mei relaxes with a coffee; her details go into her own box and its lid closes. */
.sf-s4-d1 { --sf-at: 0.4s; --sf-dx: -200px; --sf-dy: -40px; }
.sf-s4-d2 { --sf-at: 0.8s; --sf-dx: -210px; --sf-dy: -40px; }
.sf-s4-d3 { --sf-at: 1.2s; --sf-dx: -205px; --sf-dy: -40px; }
.sf-s4-lid { --sf-at: 2s; }
.sf-s4-check { --sf-at: 2.5s; }
.sf-s4-face, .sf-s4-mei { --sf-at: 2.8s; }
.sf-s4-heart { --sf-at: 3s; }
.sf-s4-k1 { --sf-at: 3.1s; }
.sf-s4-k2 { --sf-at: 3.2s; }
