/* Milo Me motion: playful but purposeful (brand guide §4: gentle, never "fade-in on everything").
   Rules: animate transform/opacity only; entrances run once ([data-anim] + .is-in from ui.js);
   idle loops pause off screen (.is-paused); nothing is hidden without JS, with reduced motion, or in calm mode. */

:root { --ease-spring: cubic-bezier(.3, 1.6, .5, 1); --ease-out: cubic-bezier(.2, 1, .3, 1); }

/* ---------- Entrances (once) ---------- */
@media (prefers-reduced-motion: no-preference) {
  /* Hidden start only while waiting to enter; "backwards" fill so hovers work after */
  html.js:not(.mm-calm) :is([data-anim="drop"], [data-anim="swing"], [data-anim="stick"]):not(.is-in) { opacity: 0; }
  html.js:not(.mm-calm) [data-anim].is-in { animation-duration: .7s; animation-timing-function: var(--ease-spring); animation-fill-mode: backwards; animation-delay: calc(min(var(--i, 0), 6) * 80ms); }
  html.js:not(.mm-calm) [data-anim="drop"].is-in { animation-name: mm-in-drop; }
  html.js:not(.mm-calm) [data-anim="swing"].is-in { animation-name: mm-in-swing; animation-duration: .9s; animation-timing-function: ease-out; }
  html.js:not(.mm-calm) [data-anim="stick"].is-in { animation-name: mm-in-stick; }

  /* Toy blocks: bento tiles stack in on load */
  html.js:not(.mm-calm) .mm-bento > * { animation: mm-in-drop .7s var(--ease-spring) backwards; }
  .mm-bento > :nth-child(2) { animation-delay: .1s !important; } .mm-bento > :nth-child(3) { animation-delay: .2s !important; }
  .mm-bento > :nth-child(4) { animation-delay: .28s !important; } .mm-bento > :nth-child(5) { animation-delay: .36s !important; } .mm-bento > :nth-child(6) { animation-delay: .44s !important; }

  /* Product tags swing in on their strings, staggered across a row */
  :is(.mm-grid, .mm-carousel__track, .mm-stores) > :nth-child(4n+2) { --i: 1; }
  :is(.mm-grid, .mm-carousel__track, .mm-stores) > :nth-child(4n+3) { --i: 2; }
  :is(.mm-grid, .mm-carousel__track, .mm-stores) > :nth-child(4n+4) { --i: 3; }

  /* Age chart: bars grow up from the ground */
  html.js:not(.mm-calm) [data-anim="grow"]:not(.is-in) .mm-agebar__fill { transform: scaleY(0); }
  html.js:not(.mm-calm) [data-anim="grow"].is-in .mm-agebar__fill { animation: mm-grow .8s var(--ease-spring) backwards; transform-origin: 50% 100%; }
  [data-anim="grow"] .mm-agebar:nth-child(2) .mm-agebar__fill { animation-delay: .08s; } [data-anim="grow"] .mm-agebar:nth-child(3) .mm-agebar__fill { animation-delay: .16s; }
  [data-anim="grow"] .mm-agebar:nth-child(4) .mm-agebar__fill { animation-delay: .24s; } [data-anim="grow"] .mm-agebar:nth-child(5) .mm-agebar__fill { animation-delay: .32s; }

  /* Bars (stock meter, review breakdown) fill from the reading start */
  html.js:not(.mm-calm) [data-anim="fill"]:not(.is-in) i { transform: scaleX(0); }
  html.js:not(.mm-calm) [data-anim="fill"].is-in i { animation: mm-fill 1s var(--ease-out) backwards; }
  [data-anim="fill"] i { transform-origin: left center; } [dir="rtl"] [data-anim="fill"] i { transform-origin: right center; }
  [data-anim="fill"] li:nth-child(2) i { animation-delay: .1s; } [data-anim="fill"] li:nth-child(3) i { animation-delay: .2s; }
  [data-anim="fill"] li:nth-child(4) i { animation-delay: .3s; } [data-anim="fill"] li:nth-child(5) i { animation-delay: .4s; }

  /* Journey & order timeline: the rainbow path fills step by step, dots pop on */
  html.js:not(.mm-calm) [data-anim="path"]:not(.is-in) li::before { transform: scaleX(0); }
  html.js:not(.mm-calm) [data-anim="path"].is-in li::before { animation: mm-fill .5s var(--ease-out) backwards; }
  html.js:not(.mm-calm) [data-anim="path"].is-in :is(.mm-journey__dot, .mm-timeline__dot) { animation: mm-in-stick .5s var(--ease-spring) backwards; }
  [data-anim="path"] li::before { transform-origin: left center; } [dir="rtl"] [data-anim="path"] li::before { transform-origin: right center; }
  [data-anim="path"] li:nth-child(2)::before, [data-anim="path"] li:nth-child(2) :is(.mm-journey__dot, .mm-timeline__dot) { animation-delay: .25s !important; }
  [data-anim="path"] li:nth-child(3)::before, [data-anim="path"] li:nth-child(3) :is(.mm-journey__dot, .mm-timeline__dot) { animation-delay: .5s !important; }
  [data-anim="path"] li:nth-child(4)::before, [data-anim="path"] li:nth-child(4) :is(.mm-journey__dot, .mm-timeline__dot) { animation-delay: .75s !important; }
}

/* While the preloader is up, entrances wait on their first frame and play as the sky lifts */
html.mm-loading :is(.mm-bento > *, [data-anim].is-in, [data-anim].is-in *, [data-anim].is-in li::before) { animation-play-state: paused !important; }

@keyframes mm-in-drop { 0% { opacity: 0; transform: translateY(-42px) scale(.92) rotate(-3deg); } 60% { opacity: 1; transform: translateY(6px) scale(1.01); } }
@keyframes mm-in-swing { 0% { opacity: 0; transform: translateY(-18px) rotate(10deg); } 35% { opacity: 1; transform: rotate(-6deg); } 60% { transform: rotate(3deg); } 80% { transform: rotate(-1deg); } }
@keyframes mm-in-stick { 0% { opacity: 0; transform: scale(.6) rotate(-10deg); } 60% { opacity: 1; transform: scale(1.06) rotate(2deg); } }
@keyframes mm-grow { 0% { transform: scaleY(0); } }
@keyframes mm-fill { 0% { transform: scaleX(0); } }

/* ---------- Idle loops (small, paused off screen) ---------- */
@media (prefers-reduced-motion: no-preference) {
  /* Balloons bob on "translate" so the hover lift (transform) still works */
  html:not(.mm-calm) .mm-balloon__b { animation: mm-bob-y 5s ease-in-out infinite; }
  .mm-balloon:nth-child(2) .mm-balloon__b { animation-delay: -1.2s; } .mm-balloon:nth-child(3) .mm-balloon__b { animation-delay: -2.4s; }
  .mm-balloon:nth-child(4) .mm-balloon__b { animation-delay: -3.1s; } .mm-balloon:nth-child(5) .mm-balloon__b { animation-delay: -.6s; } .mm-balloon:nth-child(6) .mm-balloon__b { animation-delay: -1.8s; }
  .mm-balloon:hover svg.string { animation: mm-sway 1s ease-in-out; }

  /* One slow cloud drifts across each sky band */
  html:not(.mm-calm) .mm-band--sky::after { /* the page body already clips sideways, so no overflow rule needed */
    content: ""; position: absolute; z-index: 0; top: 36px; left: 0; width: 120px; height: 46px; pointer-events: none; opacity: .9;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 40'%3E%3Cg fill='%23fff'%3E%3Ccircle cx='18' cy='26' r='12'/%3E%3Ccircle cx='32' cy='18' r='15'/%3E%3Ccircle cx='47' cy='25' r='12'/%3E%3Crect x='18' y='24' width='30' height='14' rx='7'/%3E%3C/g%3E%3C/svg%3E") no-repeat center / contain;
    animation: mm-drift-x 70s linear infinite;
  }
  .mm-band--sky > .mm-wrap { position: relative; z-index: 1; }

  /* WhatsApp says hello once, ten seconds in */
  html:not(.mm-calm) .mm-wa { animation: mm-hello 1.4s ease-in-out 10s 1; }
}
@keyframes mm-bob-y { 50% { translate: 0 -7px; } }
@keyframes mm-drift-x { 0% { transform: translateX(-140px); } 100% { transform: translateX(100vw); } }
[dir="rtl"] .mm-band--sky::after { animation-direction: reverse; }
@keyframes mm-hello { 0%, 100% { rotate: 0deg; } 15%, 45% { rotate: -14deg; } 30%, 60% { rotate: 12deg; } 75% { rotate: -4deg; } }
.is-paused, .is-paused::after, .is-paused *, .is-paused *::before, .is-paused *::after { animation-play-state: paused !important; }

/* ---------- Micro-interactions ---------- */
/* Logo Milo wiggles on hover; nav dots hop */
.mm-lockup:hover img { animation: mm-wobble .6s ease-in-out; }
:is(.mm-nav a, .mm-nav > button):hover::before { animation: mm-dot-hop .5s var(--ease-spring); }
@keyframes mm-dot-hop { 40% { transform: translateY(-6px) scale(1.25); } }

/* Cart bag squashes when an item lands; wishlist icon heartbeat on save */
.is-squash .mm-icon { animation: mm-squash .5s var(--ease-spring); }
@keyframes mm-squash { 30% { transform: scale(1.25, .8); } 60% { transform: scale(.9, 1.12); } }
.is-beat .mm-icon { animation: mm-beat .6s ease-in-out; }
@keyframes mm-beat { 20%, 60% { transform: scale(1.3); } 40% { transform: scale(1); } }

/* Tab bar icon hops when tapped */
.mm-tabbar .is-tap .mm-icon { animation: mm-tap .45s var(--ease-spring); }
@keyframes mm-tap { 40% { transform: translateY(-7px) scale(1.12); } }

/* Heart fills with a pop (the burst of little hearts comes from ui.js) */
[data-fav][aria-pressed="true"] .mm-icon { animation: mm-heart-pop .45s var(--ease-spring); }
@keyframes mm-heart-pop { 0% { transform: scale(.6); } 60% { transform: scale(1.3); } }

/* Add to cart: the button says "Added!" and a +1 floats off */
.mm-btn.is-added { position: relative; --btn-bg: var(--success); --btn-edge: color-mix(in srgb, var(--success), #000 25%); animation: mm-in-stick .35s var(--ease-spring); }
.mm-plus1 { position: absolute; top: -6px; inset-inline-end: 10px; font: 800 15px var(--font-display); color: var(--success); pointer-events: none; animation: mm-plus1 .9s var(--ease-out) forwards; }
@keyframes mm-plus1 { 0% { opacity: 0; transform: translateY(6px) scale(.7); } 25% { opacity: 1; } 100% { opacity: 0; transform: translateY(-30px) scale(1.1); } }

/* Stepper number and totals roll when they change */
.mm-stepper output.is-up, .mm-price.is-roll { animation: mm-roll-up .35s var(--ease-spring); }
.mm-stepper output.is-down { animation: mm-roll-down .35s var(--ease-spring); }
.mm-price.is-roll { display: inline-block; }
@keyframes mm-roll-up { 0% { opacity: 0; transform: translateY(60%); } }
@keyframes mm-roll-down { 0% { opacity: 0; transform: translateY(-60%); } }

/* Picks: checkbox, radio, swatch, size, tab, age filter all pop when chosen */
.mm-check input:checked, .mm-option input:checked { animation: mm-in-stick .3s var(--ease-spring); }
:is(.mm-swatch, .mm-size)[aria-checked="true"], .mm-swatch[aria-pressed="true"], .mm-tab[aria-selected="true"] { animation: mm-ring .35s var(--ease-spring); }
@keyframes mm-ring { 0% { transform: scale(.9); } 60% { transform: scale(1.08); } }
.mm-agepick__bar[aria-pressed="true"] i { animation: mm-boing .45s var(--ease-spring); transform-origin: 50% 100%; }
@keyframes mm-boing { 30% { transform: scaleY(.8); } 65% { transform: scaleY(1.1); } }
.mm-range input:active::-webkit-slider-thumb { transform: scale(1.2, .85); }
.mm-range input::-webkit-slider-thumb { transition: transform .2s var(--ease-spring); }
/* Every pickable thing answers the same way: a pale sky fill on hover, a small press when tapped */
:is(.mm-option, .mm-size, .mm-chip, .mm-tab, .mm-swatch, .mm-agebar, .mm-check) { transition-property: border-color, background-color, box-shadow, color, transform, scale, translate; transition-duration: .15s; }
:is(.mm-option:not(.is-disabled):not(:has(input:checked)), .mm-size:not(:disabled):not([aria-checked="true"])):hover { background: color-mix(in srgb, var(--sky) 35%, var(--surface)); }
.mm-check:hover input:not(:checked):not(:disabled) { border-color: var(--second); }
:is(.mm-option:not(.is-disabled), .mm-size:not(:disabled), .mm-chip, .mm-tab, .mm-swatch, .mm-agebar, .mm-check):active { scale: .96; }

/* Accordions and order rows open with a small drop instead of a jump */
:is(.mm-acc details, .mm-order)[open] > :not(summary) { animation: mm-reveal .35s var(--ease-out); }
@keyframes mm-reveal { 0% { opacity: 0; transform: translateY(-8px); } }

/* Invalid fields and a wrong promo code give a gentle "no" shake */
.mm-field.is-invalid :is(.mm-input, .mm-select, .mm-textarea), .is-shake { animation: mm-shake .45s ease; }

/* Filter chips pop in, drawer lines slide in one by one */
.mm-activechips .mm-chip { animation: mm-in-stick .4s var(--ease-spring) backwards; }
.mm-activechips .mm-chip:nth-child(2) { animation-delay: .06s; } .mm-activechips .mm-chip:nth-child(3) { animation-delay: .12s; } .mm-activechips .mm-chip:nth-child(4) { animation-delay: .18s; }
.mm-drawer[open] .mm-line { animation: mm-line-in .45s var(--ease-spring) backwards; }
.mm-drawer[open] .mm-line:nth-child(2) { animation-delay: .07s; } .mm-drawer[open] .mm-line:nth-child(3) { animation-delay: .14s; } .mm-drawer[open] .mm-line:nth-child(4) { animation-delay: .21s; }
@keyframes mm-line-in { 0% { opacity: 0; transform: translateX(calc(var(--from-x, 24px))); } }
[dir="rtl"] .mm-drawer { --from-x: -24px; }

/* Default address star twinkles twice */
.mm-addrcard.is-default .mm-badge .mm-icon { animation: mm-twinkle 1.4s ease-in-out 2; }

/* Toast: a little Milo pops in with the message */
.mm-toast__milo { width: 30px; height: 30px; border-radius: 50%; flex: none; animation: mm-in-stick .45s var(--ease-spring); }
.mm-toast--success .mm-icon { display: none; }

/* ---------- Milo the character (ui.js): tap moves, pet, nap, logo reactions ---------- */
/* Reaction classes go on any Milo picture: stage Milos (img.mm-milo) and the header logo (.mm-lockup img) */
img.mm-milo.is-perk { scale: 1.05; }
img.is-boop { animation: mm-boop .6s var(--ease-spring); }
img.is-giggle { animation: mm-giggle .7s ease-in-out; }
img.is-jump { animation: mm-jump .7s var(--ease-spring); }
img.is-spin { animation: mm-party .85s var(--ease-spring); }
img.is-dizzy { animation: mm-dizzy 1.5s ease-in-out; }
img.is-happy { animation: mm-happy .9s var(--ease-spring); }
img.is-no { animation: mm-no .55s ease-in-out; }
img.is-wake { animation: mm-wake .55s var(--ease-spring); }
img.is-nap { animation: mm-nap 3.2s ease-in-out infinite; }
@keyframes mm-boop { 25% { transform: scale(1.14, .86); } 55% { transform: scale(.94, 1.08); } }
@keyframes mm-giggle { 15%, 45%, 75% { transform: rotate(-8deg) translateY(-3px); } 30%, 60%, 90% { transform: rotate(8deg); } }
@keyframes mm-jump { 40% { transform: translateY(-30px) scale(.96, 1.05); } 70% { transform: translateY(0) scale(1.06, .94); } }
@keyframes mm-dizzy { 20% { transform: rotate(-16deg) translateX(-6px); } 40% { transform: rotate(14deg) translateX(6px); } 60% { transform: rotate(-10deg); } 80% { transform: rotate(6deg); } }
@keyframes mm-happy { 20% { transform: scale(1.1) translateY(-6px); } 40% { transform: scale(.97); } 60% { transform: scale(1.06) translateY(-3px); } }
@keyframes mm-no { 20%, 60% { transform: translateX(-5px) rotate(-5deg); } 40%, 80% { transform: translateX(5px) rotate(5deg); } }
@keyframes mm-wake { 30% { transform: translateY(-16px) scale(1.05); } }
@keyframes mm-nap { 50% { transform: rotate(-6deg) translateY(4px) scale(.98); } }

/* Stars circling a dizzy Milo */
.mm-orbit { position: fixed; z-index: 110; width: 0; height: 0; pointer-events: none; animation: mm-spin 1s linear infinite; }
.mm-orbit svg { position: absolute; width: 20px; height: 20px; margin: -10px; }
.mm-orbit svg:nth-child(1) { transform: translate(0, -34px); } .mm-orbit svg:nth-child(2) { transform: translate(30px, 16px) scale(.8); } .mm-orbit svg:nth-child(3) { transform: translate(-30px, 16px) scale(.7); }

/* Speech bubble: one, re-used, fixed and clamped inside the screen; the tail points at Milo (--tx) */
.mm-say {
  position: fixed; z-index: 110; max-width: min(260px, calc(100vw - 24px)); padding: 9px 16px; border-radius: 18px; background: var(--surface);
  font: 700 16px/1.35 var(--font-display); color: var(--second-strong); box-shadow: var(--shadow); pointer-events: none; text-align: center;
  opacity: 0; transform: translateY(8px) scale(.7); transform-origin: var(--tx, 50%) 100%; transition: opacity .2s, transform .35s var(--ease-spring);
}
.mm-say::after { content: ""; position: absolute; top: 100%; left: var(--tx, 50%); width: 16px; height: 10px; margin-left: -8px; background: inherit; clip-path: polygon(0 0, 100% 0, 50% 100%); }
.mm-say.is-below { transform-origin: var(--tx, 50%) 0; transform: translateY(-8px) scale(.7); }
.mm-say.is-below::after { top: auto; bottom: 100%; clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.mm-say.is-on { opacity: 1; transform: none; }

/* Calm mode and reduced motion: no leaning or perking; the bubble still talks (it just appears) */
html.mm-calm img.mm-milo { --lean: 0deg !important; scale: none !important; }
@media (prefers-reduced-motion: reduce) { img.mm-milo { --lean: 0deg !important; scale: none !important; } }

/* Components page demo (tpl-*) */
.tpl-milo { display: flex; flex-wrap: wrap; gap: 28px; align-items: center; padding: 32px; border-radius: var(--r-lg); background: var(--sky); }
.tpl-milo .tpl-notes { flex: 1; min-width: 240px; }

@keyframes mm-party { 30% { transform: translateY(-34px) scale(1.08) rotate(-12deg); } 60% { transform: translateY(-34px) rotate(200deg); } 100% { transform: rotate(360deg); } }

/* Bursts (hearts or rainbow confetti) created by ui.js */
.mm-burst { position: fixed; z-index: 120; width: 0; height: 0; pointer-events: none; }
.mm-burst i { position: absolute; left: -7px; top: -7px; width: 14px; height: 14px; color: var(--c); animation: mm-burst .8s cubic-bezier(.2, .8, .3, 1) forwards; }
.mm-burst svg { width: 100%; height: 100%; }
.mm-burst--confetti i { width: 8px; height: 12px; left: -4px; top: -6px; border-radius: 3px; background: var(--c); }
@keyframes mm-burst { 0% { opacity: 1; transform: scale(.3); } 100% { opacity: 0; transform: translate(var(--x), var(--y)) rotate(var(--r)) scale(.9); } }

/* ---------- Back-to-top balloon ---------- */
.mm-top {
  position: fixed; z-index: 45; bottom: 100px; inset-inline-end: 30px; display: grid; justify-items: center; padding: 0; border: 0; background: none; cursor: pointer;
  opacity: 0; transform: translateY(24px) scale(.8); pointer-events: none; transition: opacity .3s, transform .45s var(--ease-spring);
}
.mm-top.is-show { opacity: 1; transform: none; pointer-events: auto; }
.mm-top__b { width: 48px; height: 56px; border-radius: 50% 50% 47% 47% / 56% 56% 44% 44%; background: var(--rb-4); color: var(--ink); display: grid; place-items: center; position: relative; box-shadow: inset -6px -6px 0 rgb(38 52 74 / .08); }
.mm-top__b::before { content: ""; position: absolute; top: 10px; inset-inline-start: 11px; width: 8px; height: 12px; border-radius: 50%; background: #fff; opacity: .6; rotate: 25deg; }
.mm-top__b .mm-icon { --icon: 20px; rotate: 180deg; }
.mm-top__string { width: 12px; height: 22px; color: var(--second); }
.mm-top.is-show .mm-top__b { animation: mm-bob-y 3s ease-in-out infinite; }
.mm-top:hover .mm-top__b { transform: scale(1.08) rotate(-6deg); transition: transform .3s var(--ease-spring); }
.mm-top.is-fly { transform: translateY(-110vh) rotate(-8deg); transition: transform .9s cubic-bezier(.5, 0, .7, .4), opacity .9s; opacity: 0; }
@media (max-width: 760px) {
  .mm-top { bottom: calc(150px + env(safe-area-inset-bottom, 0px)); inset-inline-end: 22px; }
  body:has(.mm-buybar) .mm-top { bottom: calc(160px + env(safe-area-inset-bottom, 0px)); }
}

/* ---------- Calm mode switch (footer) ---------- */
.mm-calm-toggle { display: inline-flex; align-items: center; gap: 8px; padding: 6px 4px; border: 0; background: none; color: var(--ink-soft); font: 500 14px var(--font-body); cursor: pointer; }
.mm-calm-toggle__track { width: 38px; height: 22px; border-radius: var(--r-pill); background: rgb(106 72 168 / .2); position: relative; transition: background-color .2s; }
.mm-calm-toggle__track i { position: absolute; top: 3px; inset-inline-start: 3px; width: 16px; height: 16px; border-radius: 50%; background: var(--surface); transition: transform .3s var(--ease-spring); }
.mm-calm-toggle[aria-checked="true"] .mm-calm-toggle__track { background: var(--accent-strong); }
.mm-calm-toggle[aria-checked="true"] .mm-calm-toggle__track i { transform: translateX(16px); }
[dir="rtl"] .mm-calm-toggle[aria-checked="true"] .mm-calm-toggle__track i { transform: translateX(-16px); }

/* ---------- Soft page transition (browsers that support it) ---------- */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: .25s; }
  .mm-header { view-transition-name: mm-header; }
  .mm-tabbar { view-transition-name: mm-tabbar; }
}
html.mm-calm::view-transition-group(*), html.mm-calm::view-transition-old(*), html.mm-calm::view-transition-new(*) { animation: none; }

/* ---------- Calm mode: decorative motion off, states still change instantly ---------- */
html.mm-calm *, html.mm-calm *::before, html.mm-calm *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
html.mm-calm .mm-preloader__rainbow path { stroke-dashoffset: 0; animation: none; }

/* Design polish: buy-bar Milo peek and a small wobble on field errors */
@keyframes mm-peek-up { 0% { opacity: 0; transform: translateY(20px); } }
.mm-error .mm-icon { animation: mm-wobble .5s ease-in-out; }
