/* Meiyan concept B: a little motion (2026-10-08). Loaded AFTER site-l.css on /b/ pages only (and B's booking frame).
   Ruben: "a tad bit of animation ... nothing super exaggerated ... classy and a little exciting ... low key bounces".
   Rules: transform/opacity only (the individual `translate` / `scale` / `rotate` properties, so nothing here overwrites
   another rule's `transform`), nothing loops, nothing moves while someone is reading it, no parallax.
   All of it sits inside prefers-reduced-motion: no-preference, so "reduce" turns every animation off.
   Scroll reveals are switched on by assets/motion-l.js (it only hides things that are still below the screen). */
:root{
  --mo-out:cubic-bezier(.22,1,.36,1);        /* soft ease-out: reveals, step changes */
  --mo-spring:cubic-bezier(.34,1.3,.64,1);   /* low-key overshoot: things that "settle" */
  --mo-press:cubic-bezier(.34,1.56,.64,1);   /* the spring back after a tap */
}
/* the booking confirmation check (drawn into .done-box by motion-l.js); static when motion is off */
.mo-check{display:block;width:60px;height:60px;margin:0 0 18px}
.mo-check circle{fill:#effbfb;stroke:var(--blue,#6adad8);stroke-width:2}
.mo-check path{fill:none;stroke:#1f6f6b;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:34;stroke-dashoffset:0}

@media (prefers-reduced-motion:no-preference){
@keyframes moUp{from{opacity:0;translate:0 var(--mo-y,12px)}to{opacity:1;translate:none}}
@keyframes moFade{from{opacity:0}to{opacity:1}}
@keyframes moGrow{from{opacity:0;scale:.97}to{opacity:1;scale:1}}
@keyframes moPop{from{scale:.86}to{scale:1}}
@keyframes moPopIn{from{opacity:0;scale:.6}to{opacity:1;scale:1}}
@keyframes moSettle{from{opacity:0;scale:.92}to{opacity:1;scale:1}}
@keyframes moDraw{from{stroke-dashoffset:34}to{stroke-dashoffset:0}}
@keyframes moRing{0%{rotate:0deg}14%{rotate:13deg}28%{rotate:-10deg}42%{rotate:7deg}56%{rotate:-4deg}70%{rotate:2deg}84%,100%{rotate:0deg}}

/* 1. Taps: everything you press gives a little, then springs back (a 0.1 s press, a 0.45 s release with a tiny
      overshoot). On a mouse, picker tiles also lift 2px. */
.theme-l .btn,.theme-l .lr-b,.theme-l .of-pick,.theme-l .l-bell,.theme-l .lp-chip-x,.theme-l .ld-x,.theme-l .chip,
.theme-l .lp-opt,.theme-l .pt-tab.lsv,.theme-l .opt,.theme-l .pick,.theme-l .goal,.theme-l .consult-card,.theme-l .cal button,.theme-l .slots button{
  --mo-t:border-color .2s,background .2s,background-color .2s,box-shadow .25s,color .2s,transform .2s var(--mo-out),translate .3s var(--mo-out),opacity .2s;
  transition:scale .45s var(--mo-press),var(--mo-t)}
.theme-l .btn:active,.theme-l .lr-b:active,.theme-l .of-pick:active,.theme-l .l-bell:active,.theme-l .lp-chip-x:active,.theme-l .ld-x:active,.theme-l .chip:active,
.theme-l .cal button:active,.theme-l .slots button:active{scale:.96;transition:scale .1s ease-out,var(--mo-t)}
.theme-l .lp-opt:active,.theme-l .pt-tab.lsv:active,.theme-l .opt:active,.theme-l .pick:active,.theme-l .goal:active,.theme-l .consult-card:active{scale:.985;transition:scale .1s ease-out,var(--mo-t)}
.theme-l .btn:disabled:active,.theme-l .cal button:disabled:active,.theme-l .slots button:disabled:active{scale:1}
@media (hover:hover){
  .theme-l .lp-opt:hover,.theme-l .pt-tab.lsv:hover{translate:0 -2px;box-shadow:0 12px 26px -20px rgba(34,25,22,.45)}
  .theme-l .lp-opt.on:hover{box-shadow:0 0 0 1px var(--blue) inset,0 12px 26px -20px rgba(34,25,22,.45)}
  .theme-l .pt-tab.lsv[aria-pressed=true]:hover{box-shadow:0 0 0 1px var(--blue) inset,0 12px 26px -20px rgba(34,25,22,.45)}
}
/* a picked option's photo / tick settles in with one small bounce */
.theme-l .lp-opt.on .ph,.theme-l .pt-tab.lsv[aria-pressed=true] .ph,
.theme-l .pick[aria-pressed=true] i,.theme-l .goal[aria-pressed=true] i,.theme-l .consult-card[aria-pressed=true] i,
.theme-l .cal button.sel,.theme-l .slots button.sel{animation:moPop .45s var(--mo-press)}

/* 2. Home hero: the words rise in on arrival (0.75 s, 90 ms apart); the picker's tiles follow in a quick cascade. */
.theme-l .lh-words>*{animation:moUp .75s var(--mo-out) both;--mo-y:14px}
.theme-l .lh-words>:nth-child(2){animation-delay:.09s}
.theme-l .lh-words>:nth-child(3){animation-delay:.18s}
.theme-l .lh-words>:nth-child(4){animation-delay:.26s}
/* 2026-10-11 hero helper (job 37, Ruben: "...without an ugly bar like we have now..."): .l-award is gone; the rating
   line rides in with the Claim row above (.lh-words>*). */

/* 3. Picker + booking card: each step's heading and tiles cascade in (0.42 s each, 30 ms apart). The step boxes are
      switched with [hidden], and a CSS animation restarts whenever its box comes back from display:none, so this
      follows the card's own script without touching it. */
/* (the card is a fixed size and its steps scroll inside it, so tiles grow in from 97% instead of sliding: nothing
   ever pokes past the box or flashes a scrollbar) */
.theme-l .lp-step:not([hidden]) .lp-h:not([hidden]){animation:moFade .3s var(--mo-out) both}
.theme-l .lp-grid:not([hidden])>.lp-opt{animation:moGrow .42s var(--mo-out) both;animation-delay:.02s}
.theme-l .lp-grid:not([hidden])>.lp-opt:nth-child(2){animation-delay:.05s}
.theme-l .lp-grid:not([hidden])>.lp-opt:nth-child(3){animation-delay:.08s}
.theme-l .lp-grid:not([hidden])>.lp-opt:nth-child(4){animation-delay:.11s}
.theme-l .lp-grid:not([hidden])>.lp-opt:nth-child(5){animation-delay:.14s}
.theme-l .lp-grid:not([hidden])>.lp-opt:nth-child(6){animation-delay:.17s}
.theme-l .lp-grid:not([hidden])>.lp-opt:nth-child(n+7){animation-delay:.2s}
.theme-l .lp-book:not([hidden]){animation:moFade .35s var(--mo-out) both}
.theme-l .lp-chip:not([hidden]){animation:moUp .35s var(--mo-out) both;--mo-y:6px}
.theme-l .lp-bar i{transition:width .55s var(--mo-out)}
.theme-l .progress i{transition:background-color .4s var(--mo-out)}
/* booking steps (book.html and the frame inside the card): soft fade + 10px rise on every step change */
.theme-l .step.on{animation:moUp .38s var(--mo-out) both;--mo-y:10px}
.theme-l.embed .step.on{animation-name:moFade}  /* inside the card's frame <main> is a fixed scroll box: fade only */
/* "You're booked": the circle settles in, then the tick draws itself */
.theme-l .step.on .mo-check{animation:moPopIn .5s .05s var(--mo-spring) both}
.theme-l .step.on .mo-check path{animation:moDraw .42s .32s var(--mo-out) both}

/* 4. Scroll reveals (motion-l.js adds .mo-r to things still below the screen, then .mo-in as they arrive):
      fade + 12px rise, 0.6-0.7 s, rows of cards 70 ms apart, once only. */
.mo-r{opacity:0;translate:0 var(--mo-y,12px)}
.mo-r.mo-in{opacity:1;translate:none;transition:opacity .6s var(--mo-out) var(--mo-d,0s),translate .7s var(--mo-out) var(--mo-d,0s)}
.lr-rail>.mo-r{--mo-y:10px}

/* 5. Price list: the chosen category's prices fade in; FAQ answers fade in as they open. */
.theme-l .lsv-pane .pt-pane:not([hidden]){animation:moFade .3s var(--mo-out)}
.theme-l .faq details[open]>:not(summary){animation:moUp .35s var(--mo-out) both;--mo-y:6px}

/* 6. The bell: its dot pops in, then one gentle ring, about a second after the page opens. Then it stays still.
      Not at all once the offers have been seen (the dot is gone then too). */
html:not(.deals-seen) .theme-l .l-dot{animation:moPopIn .45s 1s var(--mo-press) both}
html:not(.deals-seen) .theme-l .l-bell svg{transform-origin:50% 14%;animation:moRing .95s 1.25s ease-in-out both}
/* the offers panel: its cards rise in one after another as it slides open */
.l-deals.in .ld-card{animation:moUp .5s .12s var(--mo-out) both;--mo-y:14px}
.l-deals.in .ld-card:nth-child(2){animation-delay:.19s}
.l-deals.in .ld-card:nth-child(n+3){animation-delay:.26s}

/* 7. First-visit offer pop-up (site.js adds .in; the screen itself already fades in). Inside it things arrive in order:
      wordmark, "GET", then "$50 OFF" settles with one small overshoot, the line and question, the three buttons 50 ms
      apart, then the small links. About 1 s from start to finish. The claim form and the "you're in" screen (.of2-s,
      switched with [hidden]) each fade up 10px when they come in. */
.offer-pop.in .of2-brand{animation:moUp .55s .06s var(--mo-out) both;--mo-y:8px}
.offer-pop.in .of2-s[data-s=offer] .of2-get{animation:moUp .55s .12s var(--mo-out) both;--mo-y:10px}
.offer-pop.in .of2-s[data-s=offer] .of2-amt{animation:moSettle .65s .2s var(--mo-spring) both}
.offer-pop.in .of2-s[data-s=offer] .of2-sub{animation:moUp .5s .3s var(--mo-out) both;--mo-y:8px}
.offer-pop.in .of2-s[data-s=offer] .of2-ask{animation:moUp .5s .35s var(--mo-out) both;--mo-y:8px}
.offer-pop.in .of2-s[data-s=offer] .of-pick{animation:moUp .5s .4s var(--mo-out) both;--mo-y:10px}
.offer-pop.in .of2-s[data-s=offer] .of-pick:nth-child(2){animation-delay:.45s}
.offer-pop.in .of2-s[data-s=offer] .of-pick:nth-child(3){animation-delay:.5s}
.offer-pop.in .of2-s[data-s=offer] .of2-unsure,.offer-pop.in .of2-s[data-s=offer] .of-no,.offer-pop.in .of-body>.of-fine{animation:moFade .5s .56s var(--mo-out) both}
.offer-pop.in .of2-s[data-s=form]:not([hidden]),.offer-pop.in .of2-s[data-s=done]:not([hidden]){animation:moUp .4s var(--mo-out) both;--mo-y:10px}
.theme-l .of-pick[disabled]:active{scale:1}
}
