/* ============================================================
   Lemmorte body-acne lander: motion layer
   Loaded after app.css. Everything that hides or moves sits inside
   the no-preference block, so a reduced-motion reader gets the page
   exactly as it was, and print never inherits a hidden card.
   Transform and opacity only: nothing here can move layout.
   ============================================================ */

/* the sold floater is placed against the chip */
.livechip { position: relative; }
/* decoration exists only while motion is allowed */
.mo-spark, .mo-confetti, .mo-plus { display: none; }

@media screen and (prefers-reduced-motion: no-preference) {
  :root {
    --mo-out: cubic-bezier(.16, 1, .3, 1);
    --mo-pop: cubic-bezier(.34, 1.56, .64, 1);
  }

  /* ---- scroll reveals ----
     Keyframes, not transitions, so no transition a card already has is
     overwritten. Backwards fill means a finished reveal leaves no transform
     behind for a hover or a later pop to fight with. */
  [data-rv]:not(.is-in) { opacity: 0; }
  [data-rv].is-in { animation: mo-rv-up .64s var(--mo-out) calc(var(--rv-i, 0) * 70ms) backwards; }
  [data-rv="left"].is-in { animation-name: mo-rv-left; }
  [data-rv="right"].is-in { animation-name: mo-rv-right; animation-duration: .7s; }
  [data-rv="zoom"].is-in { animation-name: mo-rv-zoom; animation-duration: .7s; }
  /* set when a reveal ends, so removing a pop class can never replay it */
  [data-rv].rv-done { animation: none; }

  @keyframes mo-rv-up { from { opacity: 0; transform: translate3d(0, 22px, 0); } }
  @keyframes mo-rv-left { from { opacity: 0; transform: translate3d(-24px, 0, 0); } }
  @keyframes mo-rv-right { from { opacity: 0; transform: translate3d(36px, 0, 0); } }
  @keyframes mo-rv-zoom { from { opacity: 0; transform: scale(.96); } }

  /* ---- kit rows: the flag lands once its row has arrived ---- */
  .box__item.is-in .box__flag { animation: mo-stamp .34s var(--mo-pop) calc(var(--rv-i, 0) * 70ms + 420ms) backwards; }
  /* isolate keeps the glow behind the word but above the row's own fill */
  .box__item.is-free.is-in .box__price .free { position: relative; isolation: isolate; }
  .box__item.is-free.is-in .box__price .free::after {
    content: "";
    position: absolute;
    inset: -5px -9px;
    z-index: -1;
    border-radius: 999px;
    background: rgb(6 118 71 / .14);
    box-shadow: 0 0 14px 2px rgb(6 118 71 / .35);
    opacity: 0;
    pointer-events: none;
    animation: mo-glow 1.2s ease-out calc(var(--rv-i, 0) * 70ms + 640ms);
  }
  @keyframes mo-stamp { from { opacity: 0; transform: scale(1.35) rotate(-6deg); } }
  @keyframes mo-glow { 35% { opacity: 1; } }

  /* ---- add-on picker ---- */
  .addon.is-pop { animation: mo-pick .36s var(--mo-out); }
  .addon.is-pop.is-dip { animation-name: mo-dip; }
  .addon.is-hop .addon__shot { animation: mo-hop .38s var(--mo-pop); }
  @keyframes mo-pick { 40% { transform: scale(1.03); } 75% { transform: scale(.995); } }
  @keyframes mo-dip { 45% { transform: scale(.98); } }
  @keyframes mo-hop { 45% { transform: translateY(-6px) rotate(-4deg); } }

  /* clip-path, not overflow, so the badge's own box is untouched */
  .addon__badge { position: relative; clip-path: inset(0 round 999px); }
  .addon__badge::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(105deg, transparent 30%, rgb(255 255 255 / .55) 50%, transparent 70%);
    transform: translateX(-120%);
    animation: mo-sweep 3.2s ease-in-out infinite;
  }
  @keyframes mo-sweep { 0%, 55% { transform: translateX(-120%); } 100% { transform: translateX(120%); } }

  /* ---- the total, once it has rolled ---- */
  .tally .grand { position: relative; isolation: isolate; transform-origin: 100% 50%; }
  .tally .grand.mo-bump { animation: mo-bump .38s var(--mo-pop); }
  .tally .grand.mo-bump::after {
    content: "";
    position: absolute;
    inset: 2px -8px -4px;
    z-index: -1;
    border-radius: 10px;
    background: #ffd166;
    opacity: 0;
    pointer-events: none;
    animation: mo-hl .9s ease-out;
  }
  @keyframes mo-bump { 45% { transform: scale(1.04); } }
  @keyframes mo-hl { 20% { opacity: .6; } }

  /* ---- sold floater: rises in the gap beside the chip, over no text ---- */
  .mo-plus {
    display: block;
    position: absolute;
    right: 100%;
    top: 50%;
    margin: -.5em 6px 0 0;
    font-size: 11px;
    font-weight: 800;
    line-height: 1;
    color: #ffd166;
    text-shadow: 0 1px 6px rgb(0 20 40 / .6);
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    animation: mo-float 1.1s var(--mo-out) forwards;
  }
  @keyframes mo-float {
    15% { opacity: 1; }
    100% { opacity: 0; transform: translateY(-18px); }
  }

  /* ---- gift icons: a short wiggle, then a long rest ---- */
  .cue__surprise { position: relative; }
  .cue__surprise .ico,
  .surprise__eyebrow .ico { transform-origin: 50% 60%; animation: mo-wiggle 3.5s ease-in-out infinite; }
  @keyframes mo-wiggle {
    0%, 20%, 100% { transform: rotate(0); }
    4% { transform: rotate(-12deg); }
    8% { transform: rotate(12deg); }
    12% { transform: rotate(-8deg); }
    16% { transform: rotate(5deg); }
  }

  .mo-spark {
    display: block;
    position: absolute;
    width: 9px;
    height: 9px;
    background: #ffd166;
    clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
    pointer-events: none;
    opacity: 0;
    animation: mo-twinkle 2.6s ease-in-out infinite;
  }
  .mo-spark:nth-of-type(1) { top: -7px; left: 12%; }
  .mo-spark:nth-of-type(2) { top: 16%; right: -11px; width: 7px; height: 7px; background: #fff; animation-delay: -.9s; }
  .mo-spark:nth-of-type(3) { bottom: -6px; left: 64%; animation-delay: -1.7s; }
  @keyframes mo-twinkle {
    0%, 100% { opacity: 0; transform: scale(.3); }
    45% { opacity: .95; transform: scale(1) rotate(45deg); }
    70% { opacity: 0; transform: scale(.5) rotate(90deg); }
  }

  /* ---- Buy now: a heartbeat, never under the finger or the celebration ---- */
  .cta--buy { animation: mo-beat 4s ease-in-out infinite; }
  .cta--buy:active,
  body.is-packing .cta--buy { animation: none; }
  .cta--buy .cta__main .ico { animation: mo-nudge 1.4s ease-in-out infinite; }
  @keyframes mo-beat {
    0%, 17.5%, 100% { transform: none; }
    4.4% { transform: scale(1.035); }
    8.8% { transform: none; }
    13.1% { transform: scale(1.02); }
  }
  @keyframes mo-nudge { 50% { transform: translateX(4px); } }

  /* the last two minutes */
  .offerbar.is-final .offerbar__clock { animation: mo-throb 1s ease-in-out infinite; }
  @keyframes mo-throb { 50% { transform: scale(1.06); } }

  /* ---- surprise confetti: behind the copy, still unless on screen ---- */
  .sec--surprise { position: relative; isolation: isolate; }
  .mo-confetti {
    display: block;
    position: absolute;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    border-radius: inherit;
    pointer-events: none;
  }
  .mo-confetti i {
    position: absolute;
    border-radius: 50%;
    animation: mo-drift 8s ease-in-out infinite alternate paused;
  }
  .mo-confetti .is-star { border-radius: 0; clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%); }
  .sec--surprise.mo-live .mo-confetti i { animation-play-state: running; }
  @keyframes mo-drift { to { transform: translate3d(var(--dx, 8px), var(--dy, -14px), 0) rotate(160deg); } }

  /* ---- the mist bars grow in with their block ---- */
  .case.is-in .case__bar i { animation: mo-grow .9s var(--mo-out) .25s backwards; }
  @keyframes mo-grow { from { transform: scaleX(0); } }

  /* ---- formula cards and steps ---- */
  .fcard.is-in .fcard__art { animation: mo-art .62s var(--mo-out) calc(var(--rv-i, 0) * 70ms + 120ms) backwards; }
  .step.is-in::before { animation: mo-num .38s var(--mo-pop) calc(var(--rv-i, 0) * 70ms + 180ms) backwards; }
  @keyframes mo-art { from { opacity: 0; transform: translateX(14%); } }
  @keyframes mo-num { from { opacity: 0; transform: scale(.4); } }
}

/* Hover lift for a real pointer only, so a touch never sticks in it. The
   shadow is a pseudo element faded in, not an animated box-shadow. The
   formula cards clip their own overflow and sit on navy, so they lift
   without one. */
@media screen and (prefers-reduced-motion: no-preference) and (hover: hover) and (pointer: fine) {
  .quote, .plan__why li { position: relative; }
  .quote, .plan__why li, .fcard { transition: transform .3s var(--mo-out); }
  .quote::after, .plan__why li::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    box-shadow: 0 12px 26px rgb(0 20 40 / .1);
    opacity: 0;
    pointer-events: none;
    transition: opacity .3s var(--mo-out);
  }
  .quote:hover, .plan__why li:hover, .fcard:hover { transform: translateY(-3px); }
  .quote:hover::after, .plan__why li:hover::after { opacity: 1; }
  .gallery img { transition: transform .45s var(--mo-out); }
  .gallery img:hover { transform: scale(1.02); }
}
