/* ============================================================
   chibiboba motion system
   Shared tokens, scroll reveals, marquee, float. All animation is
   transform/opacity only; prefers-reduced-motion strips movement.
   ============================================================ */

:root {
  --cbm-ease-out: cubic-bezier(0.23, 1, 0.32, 1);      /* strong ease-out: entrances */
  --cbm-ease-inout: cubic-bezier(0.77, 0, 0.175, 1);   /* on-screen movement */
  --cbm-fast: 160ms;
  --cbm-med: 300ms;
  --cbm-slow: 550ms;
}

/* ── scroll reveals ──
   Elements with .rv are hidden only once JS confirms it will reveal them
   (html.cbm-js). No JS -> content simply shows. */
html.cbm-js .rv {
  opacity: 0;
  transform: translateY(16px);
}
html.cbm-js .rv.in {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 450ms ease, transform var(--cbm-slow) var(--cbm-ease-out);
}
/* stagger: data-d="1".."6" adds 70ms per step */
html.cbm-js .rv.in[data-d="1"] { transition-delay: 70ms; }
html.cbm-js .rv.in[data-d="2"] { transition-delay: 140ms; }
html.cbm-js .rv.in[data-d="3"] { transition-delay: 210ms; }
html.cbm-js .rv.in[data-d="4"] { transition-delay: 280ms; }
html.cbm-js .rv.in[data-d="5"] { transition-delay: 350ms; }
html.cbm-js .rv.in[data-d="6"] { transition-delay: 420ms; }
/* variant: reveal drifting in from the side (clouds) */
html.cbm-js .rv.rv-left  { transform: translateX(-26px); }
html.cbm-js .rv.rv-right { transform: translateX(26px); }
html.cbm-js .rv.in.rv-left, html.cbm-js .rv.in.rv-right { transform: translateX(0); }

/* ── announcement marquee ──
   .cbm-marquee holds two identical .cbm-marquee-track spans; the pair
   scrolls -50% for a seamless loop. */
.cbm-marquee { overflow: hidden; white-space: nowrap; }
.cbm-marquee .cbm-marquee-inner {
  display: inline-flex;
  animation: cbmMarquee 26s linear infinite;
  will-change: transform;
}
.cbm-marquee .cbm-marquee-track { display: inline-block; padding-right: 3em; }
@keyframes cbmMarquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ── ambient float (mascot, hero cup) ── */
.cbm-float { animation: cbmFloat 4.5s ease-in-out infinite; will-change: transform; }
.cbm-float-slow { animation: cbmFloat 6.5s ease-in-out infinite; will-change: transform; }
@keyframes cbmFloat {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-12px) rotate(1.2deg); }
}

/* ── floating pearls layer (hero scenes) ── */
.cbm-pearls { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
.cbm-pearl {
  position: absolute; border-radius: 50%;
  background: rgba(61, 40, 23, 0.10);
  animation: cbmPearlDrift 9s ease-in-out infinite;
  will-change: transform;
}
.cbm-pearl:nth-child(2n) { animation-duration: 12s; animation-delay: 1.2s; background: rgba(129, 87, 63, 0.10); }
.cbm-pearl:nth-child(3n) { animation-duration: 15s; animation-delay: 2.6s; }
@keyframes cbmPearlDrift {
  0%, 100% { transform: translateY(0) translateX(0); }
  33%      { transform: translateY(-22px) translateX(8px); }
  66%      { transform: translateY(10px) translateX(-8px); }
}

/* ── cart badge pop (class toggled by CBMotion.flyPearl) ── */
.cbm-badge-pop { animation: cbmBadgePop 420ms var(--cbm-ease-out); }
@keyframes cbmBadgePop {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.45); }
  100% { transform: scale(1); }
}

/* ── reduced motion: movement off, content stays readable ── */
@media (prefers-reduced-motion: reduce) {
  html.cbm-js .rv { opacity: 1; transform: none; transition: none; }
  .cbm-marquee .cbm-marquee-inner,
  .cbm-float, .cbm-float-slow,
  .cbm-pearl { animation: none; }
}
