/* ===== ContaBilè motion layer — techniques from transitions.dev =====
   Signature: spring easing + blur on enter/exit, staggered reveals.
   12 transitions: number pop-in, card resize, notification badge, text swap,
   menu dropdown, modal, panel reveal, page side-by-side, icon swap,
   success check, avatar hover, error shake. */

:root {
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);   /* overshoot */
  --ease-out:    cubic-bezier(0.22, 1, 0.36, 1);       /* smooth quint */
  --ease-inout:  cubic-bezier(0.65, 0, 0.35, 1);
  --t-fast: .22s;
  --t-base: .36s;
  --t-slow: .52s;
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* 1 — NUMBER POP-IN : blur + rise + scale, staggered per card */
@keyframes numPop {
  0%   { opacity: 0; filter: blur(12px); transform: translateY(14px) scale(.94); }
  60%  { filter: blur(0); }
  100% { opacity: 1; filter: blur(0); transform: none; }
}
.num-pop { animation: numPop .62s var(--ease-spring) both; animation-delay: var(--stagger, 0s); }

/* 2 — CARD RESIZE : smooth size/shape morph */
.card-resize { transition: height var(--t-base) var(--ease-out),
  grid-template-rows var(--t-base) var(--ease-out), box-shadow var(--t-base) var(--ease-out); }
.expandable { cursor: pointer; }
.expand-grid { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--t-base) var(--ease-out); }
.expand-grid.open { grid-template-rows: 1fr; }
.expand-grid > .expand-inner { overflow: hidden; }

/* 3 — NOTIFICATION BADGE : diagonal slide + spring pop */
@keyframes badgePop {
  0%   { opacity: 0; transform: translate(6px, -6px) scale(.4); }
  70%  { opacity: 1; transform: translate(0,0) scale(1.18); }
  100% { transform: translate(0,0) scale(1); }
}
.badge-pop { animation: badgePop .5s var(--ease-spring) both; }

/* 4 — TEXT STATES SWAP : blur out / blur in */
@keyframes textIn { from { opacity: 0; filter: blur(7px); transform: translateY(5px); } to { opacity: 1; filter: blur(0); transform: none; } }
.text-swap { animation: textIn var(--t-base) var(--ease-out) both; }

/* 5 — MENU DROPDOWN : origin-aware scale + fade (top-right) */
@keyframes menuIn { from { opacity: 0; transform: scale(.92) translateY(-6px); filter: blur(4px); } to { opacity: 1; transform: none; filter: blur(0); } }
.menu-in { transform-origin: top right; animation: menuIn .26s var(--ease-out) both; }

/* 6 — MODAL : scale-up + blur (overrides base) */
@keyframes modalPop { 0% { opacity: 0; transform: scale(.9) translateY(16px); filter: blur(8px); } 60% { filter: blur(0); } 100% { opacity: 1; transform: none; filter: blur(0); } }
.modal { animation: modalPop .42s var(--ease-spring) both !important; }
.modal-scrim { animation: scrimIn var(--t-fast) ease both; }
@keyframes scrimIn { from { opacity: 0; } to { opacity: 1; } }

/* 7 — PANEL REVEAL : already transform-based; spring it */
.assistant { transition: transform var(--t-slow) var(--ease-spring) !important; }

/* 8 — PAGE SIDE-BY-SIDE : forward / back directional slide + blur */
@keyframes pageFwd { from { opacity: 0; transform: translateX(34px); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } }
@keyframes pageBack { from { opacity: 0; transform: translateX(-34px); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } }
.page-fwd  { animation: pageFwd  .4s var(--ease-out) both; }
.page-back { animation: pageBack .4s var(--ease-out) both; }
.page-fwd .view, .page-back .view { animation: none; }

/* 9 — ICON SWAP : scale + blur cross-rotate */
.icon-swap { position: relative; display: inline-grid; place-items: center; }
.icon-swap > * { grid-area: 1 / 1; transition: opacity var(--t-fast) var(--ease-out),
  transform var(--t-fast) var(--ease-spring), filter var(--t-fast) var(--ease-out); }
.icon-swap > .out { opacity: 0; transform: scale(.5) rotate(-40deg); filter: blur(4px); pointer-events: none; }
.icon-swap > .in  { opacity: 1; transform: none; filter: blur(0); }

/* 10 — SUCCESS CHECK : blur + rotate settle, then draw */
@keyframes checkIn { 0% { opacity: 0; transform: scale(.4) rotate(-25deg); filter: blur(8px); } 60% { transform: scale(1.1) rotate(4deg); filter: blur(0); } 100% { opacity: 1; transform: none; } }
.check-circle { animation: checkIn .55s var(--ease-spring) both; }

/* 11 — AVATAR GROUP HOVER : distance-falloff lift + bouncy return */
.avatar-group { display: flex; }
.avatar-group .ag { transition: transform .34s var(--ease-spring), box-shadow .34s var(--ease-out); margin-left: -10px; border: 2px solid var(--surface); }
.avatar-group .ag:first-child { margin-left: 0; }
.avatar-group:hover .ag { transform: translateY(2px); }
.avatar-group .ag:hover { transform: translateY(-7px) scale(1.06); box-shadow: var(--shadow); z-index: 3; }
.avatar-group .ag:hover + .ag { transform: translateY(-3px); }

/* 12 — ERROR STATE SHAKE : cubic-bezier shake */
@keyframes shake { 10%,90% { transform: translateX(-1px); } 20%,80% { transform: translateX(2px); } 30%,50%,70% { transform: translateX(-4px); } 40%,60% { transform: translateX(4px); } }
.shake { animation: shake .5s cubic-bezier(.36,.07,.19,.97) both; }
.field .ipt.error, .field select.ipt.error { border-color: var(--neg); background: color-mix(in oklch, var(--neg) 8%, var(--surface-2)); }
.err-text { color: var(--neg); font-size: 12px; margin-top: 5px; display: flex; align-items: center; gap: 5px; animation: textIn var(--t-fast) var(--ease-out) both; }

/* shared micro: hover lift on interactive cards/rows */
.lift { transition: transform var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out); }
.lift:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.nav-item, .btn, .chip, .icon-btn { transition: background .16s var(--ease-out), color .16s var(--ease-out), transform var(--t-fast) var(--ease-spring), box-shadow var(--t-fast) var(--ease-out); }
.btn:active, .icon-btn:active { transform: scale(.95); }
