/* Scene styling and keyframes for the hero animation of /features/messaging.html,
   "Liam's quiet inbox". 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 --mg-at (its start) and, for a flight, the
   --mg-dx / --mg-dy offset it flies in from. */

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

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

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

/* A phone screen that lights up and stays lit. */
.mg-lit { fill: var(--anim-warm-soft); }
@keyframes mg-show { from { opacity: 0; } }
.is-active .mg-show { animation: mg-show 0.35s ease var(--mg-at, 1s) both; }
/* A thing that is thrown back where it came from: it flies in, stops, and falls away. */
.mg-bounce { opacity: 0; transform-box: fill-box; transform-origin: center; }
@keyframes mg-bounce { 0% { transform: translate(var(--mg-dx, 0), var(--mg-dy, 0)); opacity: 0; } 15% { opacity: 1; } 55% { transform: none; opacity: 1; } 70% { transform: translateX(10px) rotate(8deg); opacity: 1; } 100% { transform: translate(40px, 50px) rotate(30deg); opacity: 0; } }
.is-active .mg-bounce { animation: mg-bounce 1.6s ease-in-out var(--mg-at, 1s) both; }
/* A lid tossed off a box. */
.mg-toss { opacity: 0; transform-box: fill-box; transform-origin: center; }
@keyframes mg-toss { 0% { transform: none; opacity: 1; } 100% { transform: translate(70px, -120px) rotate(40deg); opacity: 0; } }
.is-active .mg-toss { animation: mg-toss 0.8s cubic-bezier(0.34, 1.56, 0.64, 1) var(--mg-at, 1s) both; }

/* Scene 1, the moment: at school the other children's phones buzz with messages from strangers; Liam's stays quiet. */
.mg-s1-b1 { --mg-at: 0.4s; --mg-dx: 200px; --mg-dy: -60px; }
.mg-s1-b2 { --mg-at: 0.9s; --mg-dx: 160px; --mg-dy: -70px; }
.mg-s1-b3 { --mg-at: 1.4s; --mg-dx: 120px; --mg-dy: -60px; }
.mg-s1-p1, .mg-s1-r1 { --mg-at: 0.6s; }
.mg-s1-p2, .mg-s1-r2 { --mg-at: 1.1s; }
.mg-s1-p3, .mg-s1-r3 { --mg-at: 1.6s; }
.mg-s1-liam, .mg-s1-liamf { --mg-at: 3s; }

/* Scene 2, the old way: strangers' messages and questions pour into one buzzing phone, and Liam's face falls. */
.mg-s2-phone, .mg-s2-ring { --mg-at: 0.4s; }
.mg-s2-b1 { --mg-at: 0.5s; --mg-dx: 160px; --mg-dy: -40px; }
.mg-s2-b2 { --mg-at: 1s; --mg-dx: 220px; --mg-dy: 20px; }
.mg-s2-b3 { --mg-at: 1.5s; --mg-dx: 160px; --mg-dy: 80px; }
.mg-s2-b4 { --mg-at: 2s; --mg-dx: 150px; --mg-dy: 40px; }
.mg-s2-liam, .mg-s2-liamf { --mg-at: 2.8s; }

/* Scene 3, allme: messages from Sofia, Yuki and a company he uses reach Liam; a stranger's message bounces off. */
.mg-s3-l1 { --mg-at: 0.4s; }
.mg-s3-l2 { --mg-at: 0.8s; }
.mg-s3-l3 { --mg-at: 1.2s; }
.mg-s3-c1 { --mg-at: 0.9s; }
.mg-s3-c2 { --mg-at: 1.3s; }
.mg-s3-c3, .mg-s3-lit { --mg-at: 1.7s; }
.mg-s3-sb { --mg-at: 1.9s; --mg-dx: 90px; --mg-dy: 0px; }
.mg-s3-no { --mg-at: 2.6s; }
.mg-s3-liam, .mg-s3-liamf { --mg-at: 3s; }

/* Scene 4, the payoff: Yuki's request reaches Sofia, Liam's guardian, who says yes; a stranger's request is turned away. */
.mg-s4-card { --mg-at: 0.4s; --mg-dx: 340px; --mg-dy: -110px; }
.mg-s4-lit { --mg-at: 1.4s; }
.mg-s4-ok { --mg-at: 1.6s; }
.mg-s4-yuki, .mg-s4-yukif { --mg-at: 1.9s; }
.mg-s4-sc { --mg-at: 2s; --mg-dx: 200px; --mg-dy: 0px; }
.mg-s4-no { --mg-at: 2.8s; }
.mg-s4-sofia, .mg-s4-sofiaf, .mg-s4-liam, .mg-s4-liamf { --mg-at: 3.2s; }
.mg-s4-heart { --mg-at: 3.5s; }
.mg-s4-k1 { --mg-at: 3.6s; }
.mg-s4-k2 { --mg-at: 3.7s; }
