/* Scene styling and keyframes for the hero animation of /features/groups.html,
   "Sofia's three circles". 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. */

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

@keyframes gr-fade-in { from { opacity: 0; } }
@keyframes gr-fade-out { from { opacity: 1; } }
/* A face shown only between two swaps: in at the start, out at the end. */
@keyframes gr-mid { 0% { opacity: 0; } 14%, 86% { opacity: 1; } 100% { opacity: 0; } }
@keyframes gr-pop { from { transform: scale(0); opacity: 0; } 50% { opacity: 1; } }
/* A detail flying from Sofia to where it lands; each element names its own start offset. */
@keyframes gr-fly { from { transform: translate(var(--gr-dx, 0), var(--gr-dy, 0)) scale(0.4); opacity: 0; } 20% { opacity: 1; } }
@keyframes gr-draw { from { stroke-dashoffset: 100; } }
@keyframes gr-hop { 0%, 100% { transform: none; } 40% { transform: translateY(-9px); } 70% { transform: translateY(2px); } }
@keyframes gr-giggle { 0%, 40%, 80%, 100% { transform: none; } 20% { transform: translateY(-6px) rotate(-2deg); } 60% { transform: translateY(-5px) rotate(2deg); } }
@keyframes gr-shake { 0%, 100% { transform: none; } 20% { transform: rotate(-4deg); } 40% { transform: rotate(4deg); } 60% { transform: rotate(-3deg); } 80% { transform: rotate(2deg); } }

/* Springy entrances overshoot through the easing, not through extra keyframes. */
.is-active .gr-pop { animation: gr-pop 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) var(--gr-at, 0s) both; }
.is-active .gr-fly { animation: gr-fly 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) var(--gr-at, 0s) both; }
/* A face swap: the earlier face fades out as the later one fades in, at the pair's --gr-at. */
.is-active .gr-face-out { animation: gr-fade-out 0.2s ease var(--gr-at, 1s) both; }
.is-active .gr-face-in { animation: gr-fade-in 0.2s ease var(--gr-at, 1s) both; }
.is-active .gr-face-mid { animation: gr-mid var(--gr-dur, 1.4s) linear var(--gr-at, 1s) both; }

/* Scene 1, the moment: Sofia's family, friends and work appear as three circles around her. */
.gr-s1-c1 { --gr-at: 0.3s; }
.gr-s1-c2 { --gr-at: 0.6s; }
.gr-s1-c3 { --gr-at: 0.9s; }
.gr-s1-i1 { --gr-at: 1.1s; }
.gr-s1-i2 { --gr-at: 1.25s; }
.gr-s1-i3 { --gr-at: 1.4s; }
.gr-s1-face { --gr-at: 1.6s; }
.is-active .gr-s1-sofia { animation: gr-hop 0.5s ease-out 1.6s both; }
.gr-s1-k1 { --gr-at: 1.9s; }
.gr-s1-k2 { --gr-at: 2s; }

/* Scene 2, the old way: one business card, her home address on it, goes to everyone; the copy
   that reaches Mateo at work gets a red cross, and both faces fall. */
.gr-s2-card { --gr-at: 0.3s; }
.gr-s2-f1 { --gr-at: 0.8s; --gr-dx: -150px; --gr-dy: 30px; }
.gr-s2-f2 { --gr-at: 1s; --gr-dx: -250px; --gr-dy: 30px; }
.gr-s2-f3 { --gr-at: 1.2s; --gr-dx: -350px; --gr-dy: 30px; }
.gr-s2-no { --gr-at: 2s; }
.gr-s2-mface { --gr-at: 2.1s; }
.is-active .gr-s2-mateo { animation: gr-shake 0.4s ease 2.1s both; }
.gr-s2-face { --gr-at: 2.4s; }
.is-active .gr-s2-sofia { animation: gr-shake 0.4s ease 2.4s both; }
.gr-s2-ask { --gr-at: 2.7s; }

/* Scene 3, allme: each detail flies into the circle it fits — home address and birthday to
   family, the mobile number to friends, the work email to work — and every circle cheers. */
.gr-s3-t1 { --gr-at: 0.4s; --gr-dx: -160px; --gr-dy: -60px; }
.gr-s3-t2 { --gr-at: 0.7s; --gr-dx: -194px; --gr-dy: -62px; }
.gr-s3-t3 { --gr-at: 1s; --gr-dx: -312px; --gr-dy: 0px; }
.gr-s3-t4 { --gr-at: 1.3s; --gr-dx: -428px; --gr-dy: -70px; }
.gr-s3-c1 { --gr-at: 2s; }
.gr-s3-c2 { --gr-at: 2.15s; }
.gr-s3-c3 { --gr-at: 2.3s; }
.gr-s3-cface { --gr-at: 2.4s; }
.is-active .gr-s3-yuki { animation: gr-hop 0.5s ease-out 2.4s both; }
.is-active .gr-s3-amara { animation: gr-hop 0.5s ease-out 2.5s both; }
.is-active .gr-s3-mateo { animation: gr-hop 0.5s ease-out 2.6s both; }
.gr-s3-face { --gr-at: 2.8s; }
.is-active .gr-s3-sofia { animation: gr-hop 0.5s ease-out 2.8s both; }

/* Scene 4, the payoff: Mateo asks for her birthday for the office cake, Sofia approves on her
   phone, it travels to him alone — Yuki and Amara are not reached — and the cake arrives. */
.gr-s4-ask { --gr-at: 0.3s; }
.gr-s4-askcake { --gr-at: 0.5s; }
.gr-s4-yes { --gr-at: 1.3s; }
.gr-s4-mface1 { --gr-at: 1.4s; }
.is-active .gr-s4-halo, .is-active .gr-s4-beam { animation: gr-draw 0.5s ease-in-out 1.7s both; }
.gr-s4-cake { --gr-at: 2.3s; }
.is-active .gr-s4-mateo { animation: gr-hop 0.5s ease-out 2.4s both; }
.gr-s4-k1 { --gr-at: 2.5s; }
.gr-s4-k2 { --gr-at: 2.6s; }
.gr-s4-mface2 { --gr-at: 2.6s; }
.gr-s4-k3 { --gr-at: 2.7s; }
.gr-s4-sface { --gr-at: 3s; }
.is-active .gr-s4-sofia { animation: gr-giggle 0.6s ease 3s both; }
.gr-s4-heart { --gr-at: 3.1s; }
