/*
 * The animated banner illustration (components/site/BannerArt.tsx: every page banner with the hands-and-globe picture). Same
 * motion as the 404 animation (scripts/build-lottie.mjs, 60 fps): its easings, a 1.5 s entrance played once, then the
 * loop (most motions every 4 s, clouds and rising hearts every 8 s). Distances are in picture pixels (--px: one pixel of the 514 px wide picture), so
 * the motion keeps its size whatever the banner's height. Nothing moves for visitors who prefer reduced motion.
 *
 * Which way each piece moves keeps every cut edge out of sight: the hands lift (their sleeves continue below the
 * banner), the white leaf and the right sprig only lean towards the hand they tuck behind, the right cloud (cut off by
 * the picture's edge) only drifts outwards.
 */
.zzb {
  --px: calc(100cqw / 514);
  --in-out: cubic-bezier(0.45, 0, 0.55, 1);
  --out: cubic-bezier(0.2, 0.4, 0.35, 1);
  --back: cubic-bezier(0.34, 1.5, 0.64, 1);
  position: absolute; aspect-ratio: 514 / 459; container-type: inline-size; pointer-events: none; user-select: none;
}
.zzb img, .zzb span { position: absolute; display: block; max-width: none !important; height: auto !important; margin: 0; padding: 0; border: 0; }

/* in a captured page banner (BannerArt.tsx → withBannerArt): instead of the static background its ::before drew — same
   place (right, full height) and the same fading on tablets and phones (Elementor's --overlay-opacity) */
.zzb-host { position: relative; overflow: hidden; }
.zzb-host::before { background-image: none !important; }
.zzb-host > .zzb { top: 0; right: 0; height: 100%; z-index: 0; opacity: var(--overlay-opacity, 1); }
.zzb-host > :not(.zzb) { position: relative; z-index: 1; }

/* loops run 2 s each way (a 4 s cycle) from the end of the entrance (1.5 s); each entrance ends where its loop starts */

/* the globe pops in and lifts with the hands (no glow behind it: the picture stays as it is) */
.zzb-globe { animation: zzb-pop 0.6s var(--back) 0.1s both, zzb-lift 2s var(--in-out) 1.5s infinite alternate; }
.zzb-handLeft, .zzb-handRight { animation: zzb-rise-in 0.83s var(--back) 0.33s both, zzb-lift 2s var(--in-out) 1.5s infinite alternate; }

/* hearts float up from the globe, one every 1.5 s */
.zzb-rise {
  opacity: 0;
  animation: zzb-float 8s linear infinite, zzb-float-size 8s linear infinite, zzb-float-fade 8s linear infinite;
  animation-delay: var(--at);
}
.zzb-rise-0 { --at: 1.5s; --dx: -37; --r0: -10deg; --r1: 8deg; }
.zzb-rise-1 { --at: 3s; --dx: 27; --r0: 10deg; --r1: -8deg; }
.zzb-rise-2 { --at: 4.5s; --dx: -11; --r0: -10deg; --r1: 8deg; }
.zzb-rise-3 { --at: 6s; --dx: 40; --r0: 10deg; --r1: -8deg; }
.zzb-rise-4 { --at: 7.5s; --dx: -27; --r0: -10deg; --r1: 8deg; }

/* the picture's two hearts pop in, then bob */
.zzb-heartLeft { --tilt: -6deg; animation: zzb-pop 0.6s var(--back) 0.4s both, zzb-bob 2s var(--in-out) 1.5s infinite alternate; }
.zzb-heartRight { --tilt: 6deg; animation: zzb-pop 0.6s var(--back) 0.5s both, zzb-bob 2s var(--in-out) 2.5s infinite alternate; }

/* clouds drift in and fade up, then drift back and forth over 8 s */
.zzb-cloudLeft {
  --from: -56; --to: -28;
  animation: zzb-drift-in 1.5s var(--in-out) both, zzb-fade-in 1s var(--in-out) both, zzb-drift 4s var(--in-out) 1.5s infinite alternate;
}
.zzb-cloudRight {
  --from: 58; --to: 26;
  animation: zzb-drift-in 1.5s var(--in-out) both, zzb-fade-in 1s var(--in-out) both, zzb-drift 4s var(--in-out) 1.5s infinite alternate;
}

/* leaves grow in from their stems, then sway 6° */
.zzb-leafBlue { --sway: 6deg; animation: zzb-pop 0.73s var(--back) 0.57s both, zzb-sway 2s var(--in-out) 1.5s infinite alternate; }
.zzb-sprigRight { --sway: -6deg; animation: zzb-pop 0.7s var(--back) 0.7s both, zzb-sway 2s var(--in-out) 1.5s infinite alternate; }
.zzb-sprigLeft { --sway: -6deg; animation: zzb-pop 0.7s var(--back) 0.63s both, zzb-sway 2s var(--in-out) 1.5s infinite alternate; }
.zzb-leafWhite { --sway: 6deg; animation: zzb-pop 0.7s var(--back) 0.77s both, zzb-sway 2s var(--in-out) 1.5s infinite alternate; }

/* dots fade in, then twinkle now and then */
.zzb-dotLeft, .zzb-dotSmall, .zzb-dotRight { animation: zzb-fade-in 1.5s var(--in-out) both, zzb-twinkle 8s var(--in-out) var(--at) infinite; }
.zzb-dotLeft { --at: 2s; }
.zzb-dotSmall { --at: 3.5s; }
.zzb-dotRight { --at: 2.5s; }

@keyframes zzb-pop { from { scale: 0; } to { scale: 1; } }
@keyframes zzb-lift { from { translate: 0 0; } to { translate: 0 calc(-9 * var(--px)); } }
@keyframes zzb-rise-in { from { translate: 0 calc(270 * var(--px)); } to { translate: 0 0; } }
@keyframes zzb-bob { from { translate: 0 0; rotate: 0deg; } to { translate: 0 calc(-7 * var(--px)); rotate: var(--tilt); } }
@keyframes zzb-drift-in { from { translate: calc(var(--from) * var(--px)) 0; } to { translate: 0 0; } }
@keyframes zzb-drift { from { translate: 0 0; } to { translate: calc(var(--to) * var(--px)) 0; } }
@keyframes zzb-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes zzb-sway { from { rotate: 0deg; } to { rotate: var(--sway); } }
@keyframes zzb-twinkle { 0%, 25%, 100% { opacity: 1; } 12.5% { opacity: 0.3; } }
/* 1.83 s of each 8 s: up 81 px and out to the side (eased out), springing from 20% to full size, fading over the last 0.5 s */
@keyframes zzb-float {
  0% { translate: calc(var(--dx) * 0.3 * var(--px)) 0; rotate: var(--r0); animation-timing-function: cubic-bezier(0.2, 0.4, 0.35, 1); }
  22.92%, 100% { translate: calc(var(--dx) * var(--px)) calc(-81 * var(--px)); rotate: var(--r1); }
}
@keyframes zzb-float-size {
  0% { scale: 0.2; animation-timing-function: cubic-bezier(0.34, 1.5, 0.64, 1); }
  6.25% { scale: 1; animation-timing-function: cubic-bezier(0.45, 0, 0.55, 1); }
  22.92%, 100% { scale: 0.8; }
}
@keyframes zzb-float-fade { 0% { opacity: 0; } 0.01%, 16.67% { opacity: 1; } 22.92%, 100% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .zzb *, .zzb *::before { animation: none !important; }
  .zzb-rise { display: none !important; }
}
