/* Admin motion (0.10, toned down on the owner's word): little moves, and
   what moves has a job. The burst breathes, the tab bar slides to the
   chosen tab, buttons push into their shadow when pressed, switches slide,
   and a card leans a fraction of a degree toward the pointer (admin/
   motion.js sets --mx / --my and data-tilt). Plain ease-out everywhere;
   no springs, pulses, glows or drifting blobs. theme.css's reduced-motion
   rule removes all of it, admin/motion.js stops the tilt, nothing is lost.
   Admin only; the stage never sees this file. */

.burst-admin { animation: burst-breathe 4.2s ease-in-out infinite; }
@keyframes burst-breathe { 0%, 100% { scale: 1; } 50% { scale: 1.05; } }

#admin-tabs[data-glide]::after { transition: left .25s ease-out, width .25s ease-out; }
#admin-tabs button { transition: background-color .15s ease-out, color .15s ease-out; }

.btn { transition: transform .1s ease-out, box-shadow .1s ease-out, background-color .15s ease-out, color .15s ease-out; }
.btn:not(:disabled):hover { transform: translate(-1px, -1px); }
.btn:not(:disabled):active { transform: translate(2px, 2px); box-shadow: 0 0 0 var(--ink-line); transition-duration: .04s; }

/* Tilt: at most about a third of a degree, so the card only answers the
   pointer rather than swinging. */
.panel fieldset { transition: transform .3s ease-out; }
.panel fieldset[data-tilt] {
  transform: perspective(1400px) rotateX(calc(var(--my, 0) * -.32deg)) rotateY(calc(var(--mx, 0) * .32deg));
  transition-duration: .15s;
}

#admin .row.check input[type="checkbox"] { transition: background-color .15s ease-out; }
#admin .row.check input[type="checkbox"]::before { transition: translate .18s ease-out, background-color .15s ease-out; }

.panel { animation: panel-in .18s ease-out both; }
.toast { animation: toast-up .2s ease-out both; }
@keyframes toast-up { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.modal { animation: modal-up .18s ease-out both; }
@keyframes modal-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* A wrong PIN nudges the pad sideways once; keys push into their shadow. */
.pin-key { transition: transform .08s ease-out, box-shadow .08s ease-out; }
.pin-key:not(:disabled):active { transform: translate(3px, 3px); box-shadow: 0 0 0 var(--ink-line); }
.pinpad.shake { animation: pin-shake .28s ease-out both; }
@keyframes pin-shake { 0%, 100% { translate: 0 0; } 25% { translate: -6px 0; } 75% { translate: 6px 0; } }
@media (prefers-reduced-motion: reduce) { .pinpad.shake { animation: none; } .pin-key { transition: none; } }
