/* HeyTextMe — motion system (see MOTION.md).
   Two durations, one enter easing ("settle"), one exit easing ("sharp").
   Reuse these tokens everywhere; never invent per-component timings.
   Screen push/pop and list add/remove use a vanilla mount/unmount helper
   (motion.js) instead of Framer Motion — same result, no build step. */

:root {
  --dur-micro: 150ms;   /* taps, toggles, hovers */
  --dur-struct: 300ms;  /* screens, sheets, bubbles */
  --ease-settle: cubic-bezier(.22, 1, .36, 1);  /* appears / moves into place */
  --ease-sharp:  cubic-bezier(.4, 0, 1, 1);      /* dismiss / leaves */
}

/* 1 · message bubbles */
@keyframes bubble-in-sent { from { opacity: 0; transform: translateY(8px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes bubble-in-recv { from { opacity: 0; transform: translateX(-10px); } to { opacity: 1; transform: none; } }

/* 2 · screen push / pop — clipped in one container, both run together */
@keyframes push-in     { from { transform: translateX(100%); } to { transform: none; } }
@keyframes push-out    { from { transform: none; filter: brightness(1); } to { transform: translateX(-24%); filter: brightness(.82); } }
@keyframes pop-in-back { from { transform: translateX(-24%); filter: brightness(.82); } to { transform: none; filter: brightness(1); } }
@keyframes pop-out     { from { transform: none; } to { transform: translateX(100%); } }

/* 3 · takeover rise (deliberately slow) */
@keyframes rise { from { opacity: 0; transform: scale(1.08); } to { opacity: 1; transform: none; } }

/* 4 · bottom sheet + scrim */
@keyframes sheet-up  { from { transform: translateY(105%); } to { transform: none; } }
@keyframes sheet-down { from { transform: none; } to { transform: translateY(105%); } }
@keyframes scrim-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes scrim-out { from { opacity: 1; } to { opacity: 0; } }

/* 5 · confirmation checkmark */
@keyframes check-pop { 0% { opacity: 0; transform: scale(.3); } 70% { opacity: 1; transform: scale(1.12); } 100% { transform: scale(1); } }

/* 6 · notification banner */
@keyframes banner-in  { 0% { transform: translateY(-160%); opacity: .4; } 80% { transform: translateY(6px); opacity: 1; } 100% { transform: none; } }
@keyframes banner-out { to { transform: translateY(-160%); opacity: 0; } }

/* 7 · micro */
@keyframes pulse { 0%, 100% { box-shadow: 0 0 0 3px rgba(255, 98, 98, .28); } 50% { box-shadow: 0 0 0 7px rgba(255, 98, 98, 0); } }
@keyframes shake { 20% { transform: translateX(-6px); } 40% { transform: translateX(6px); } 60% { transform: translateX(-5px); } 80% { transform: translateX(4px); } }

/* ---- screen transition machinery ----
   The router keeps the outgoing screen mounted alongside the incoming one; both
   are position:absolute in a clipped container. motion.js removes the outgoing
   one on animationend. */
.s-push-in  { animation: push-in  var(--dur-struct) var(--ease-settle); z-index: 2; }
.s-push-out { animation: push-out var(--dur-struct) var(--ease-settle) forwards; z-index: 1; }
.s-pop-in   { animation: pop-in-back var(--dur-struct) var(--ease-settle); z-index: 1; }
.s-pop-out  { animation: pop-out var(--dur-struct) var(--ease-settle) forwards; z-index: 2; }

/* tap press — any element carrying .tap */
.tap { transition: transform 120ms var(--ease-settle); }
.tap:active { transform: scale(.94); }

/* reduced motion — kill everything, keep the app usable */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
