/* Motion shared by the site and the CRM. Rendering replaces the DOM, so entrances are keyed: mount() in shared.js adds
   .enter the first time a [data-enter] key shows up, .shown/.seen for [data-reveal]; leave() adds .leave before a dialog goes. */
/* Press: a ripple (see wireRipple in shared.js) plus a small squeeze. */
.btn:active:not(:disabled), .seg > button:active:not(:disabled), .menu-btn:active, .pay-opt:active, .gal-btn:active, .ed-tool:active:not(:disabled), .map-zoom button:active:not(:disabled) { transform: scale(.96); }
.ripple { position: fixed; z-index: 2000; overflow: hidden; pointer-events: none; }
.ripple i { position: absolute; border-radius: 50%; background: currentColor; opacity: .22; transform: scale(0); animation: ripple .6s var(--ease-out) forwards; }
@keyframes ripple { to { transform: scale(1); opacity: 0; } }
/* Right after a re-render nothing transitions: fresh nodes would otherwise animate from their unstyled state (hover etc.). */
.settling, .settling * { transition: none !important; }
/* Entrances (mount() adds .enter once per key) and exits (leave() adds .leave). */
@keyframes fade { from { opacity: 0; } }
@keyframes rise { from { opacity: 0; translate: 0 12px; } }
@keyframes pop { from { opacity: .4; scale: .6; } }
@keyframes dialog-in { from { opacity: 0; transform: translateY(28px) scale(.96); } }
@keyframes dialog-out { to { opacity: 0; transform: translateY(14px) scale(.97); } }
@keyframes drop { from { opacity: 0; transform: translateY(-8px) scale(.97); } }
.dialog-backdrop.enter, .lb.enter { animation: fade .25s ease-out both; }
.dialog-backdrop.enter > .dialog { animation: dialog-in .5s var(--ease-spring) both; }
.dialog-backdrop.leave, .lb.leave { animation: fade .2s ease-in reverse both; }
.dialog-backdrop.leave > .dialog { animation: dialog-out .2s ease-in both; }
.lb-fig img.enter { animation: lb-img .45s var(--ease-out) both; }
@keyframes lb-img { from { opacity: 0; scale: .96; } }
.bell-panel.enter { animation: drop .25s var(--ease-out) both; transform-origin: top right; }
.tab-body.enter, .step.enter { animation: rise .4s var(--ease-out); }
.seg > button.on.enter, .menu-btn.on.enter, .pay-opt.on.enter { animation: pop-soft .35s var(--ease-spring); }
@keyframes pop-soft { from { transform: scale(.92); } }
.step.enter .done .check-draw, .lead-done .check-draw { color: var(--sage-deep); }
/* the plan: hover lifts a desk, a new selection pops */
:is(.map-box, .site-map) g[data-pick] { transform-box: fill-box; transform-origin: center; transition: scale .25s var(--ease-out); }
:is(.map-box, .site-map) g[data-pick]:hover { scale: 1.07; }
:is(.map-box, .site-map) g[data-pick].enter { animation: pop .5s var(--ease-spring); }
:is(.map-box, .site-map) rect[data-pick] { transition: fill .25s; }
:is(.map-box, .site-map) rect[data-pick]:hover { fill: color-mix(in srgb, var(--color-accent) 5%, transparent) !important; }
:is(.map-box, .site-map) rect[data-pick].enter { animation: room-sel .6s var(--ease-out); }
@keyframes room-sel { from { stroke-width: 14; stroke-opacity: 0; } }
/* spinner for buttons and busy toasts */
.spin { display: inline-block; width: 15px; height: 15px; margin-right: 9px; vertical-align: -2px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin .7s linear infinite; }
@keyframes spin { to { rotate: 360deg; } }
/* check mark that draws itself */
.check-draw { width: 64px; height: 64px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.check-draw circle { stroke-dasharray: 151; stroke-dashoffset: 151; animation: draw .7s var(--ease-out) .1s forwards; }
.check-draw path { stroke-dasharray: 36; stroke-dashoffset: 36; animation: draw .45s var(--ease-out) .6s forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
/* scroll reveal (data-reveal): stagger with --i */
[data-reveal]:not(.seen):not(.shown) { opacity: 0; }
[data-reveal].shown { animation: reveal .8s var(--ease-out) both; animation-delay: calc(var(--i, 0) * 80ms); }
@keyframes reveal { from { opacity: 0; translate: 0 22px; } }
@media print { [data-reveal] { opacity: 1 !important; animation: none !important; } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}
