/* ════════════════════════════════════════════════════════════════════
   VYAN · the alive layer
   Apple-feel dynamics: things press like hardware, settle like springs,
   and celebrate when money or trust moves. Motion carries meaning;
   nothing loops, nothing nags, everything respects reduced-motion.
   ════════════════════════════════════════════════════════════════════ */

/* ── Pressables: everything tappable gives under the thumb ───────── */
.btn, .btn-gold, .tlink, .fchip, .b-opt, .nav-it, .catalog-row, .route,
.tier .btn, .mod-row, .vrow.clickable, .act, .dispo, .thr, .fm-press {
  transition: transform var(--m-fast) var(--ease-spring),
              border-color var(--m-fast) var(--ease),
              background var(--m-fast) var(--ease),
              color var(--m-fast) var(--ease);
}
.btn:active, .btn-gold:active, .fchip:active, .b-opt:active, .act:active,
.dispo:active, .mod-row:active, .nav-it:active, .thr:active, .fm-press:active {
  transform: scale(.965);
}
.btn-gold:hover { transform: translateY(-1px); }
.btn-gold:active { transform: scale(.97); }

/* ── Entrances: views and rows arrive, they don't just appear ────── */
@keyframes riseIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.view > * { animation: riseIn var(--m-enter) var(--ease-exit) backwards; }
.view > *:nth-child(1) { animation-delay: 0ms; }
.view > *:nth-child(2) { animation-delay: 40ms; }
.view > *:nth-child(3) { animation-delay: 80ms; }
.view > *:nth-child(4) { animation-delay: 120ms; }
.view > *:nth-child(5) { animation-delay: 160ms; }
.view > *:nth-child(n+6) { animation-delay: 200ms; }

/* marketing pages: one subtle settle per section, once */
.rise { opacity: 0; transform: translateY(12px); }
.rise.in { opacity: 1; transform: none; transition: opacity .55s var(--ease-exit), transform .55s var(--ease-exit); }

/* ── Toasts: spring in from the right, settle precisely ──────────── */
@keyframes toastIn {
  0%   { opacity: 0; transform: translateX(18px) scale(.97); }
  60%  { opacity: 1; transform: translateX(-3px) scale(1.005); }
  100% { opacity: 1; transform: none; }
}
.toast { animation: toastIn 320ms var(--ease-exit); }

/* ── The drawer and sheet: slide with weight ─────────────────────── */
@keyframes sheetUp {
  from { transform: translateY(18px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.sheet { animation: sheetUp 280ms var(--ease-exit); }
@keyframes drawerIn {
  from { transform: translateX(24px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.drawer { animation: drawerIn 280ms var(--ease-exit); }

/* ── Ember sparks: the win moment (money or trust moved) ─────────── */
.spark-host { position: relative; }
.spark {
  position: absolute; width: 5px; height: 5px; border-radius: 1px;
  background: var(--grad-ember); pointer-events: none; z-index: 90;
  animation: sparkFly 640ms var(--ease-exit) forwards;
}
@keyframes sparkFly {
  0%   { opacity: 1; transform: translate(0, 0) scale(1) rotate(0deg); }
  100% { opacity: 0; transform: translate(var(--sx), var(--sy)) scale(.4) rotate(120deg); }
}

/* ── The +1 fly-up: every knock counts, visibly ──────────────────── */
.flyup {
  position: fixed; z-index: 120; pointer-events: none;
  font: 700 15px var(--mono); color: var(--ember);
  animation: flyUp 760ms var(--ease-exit) forwards;
}
@keyframes flyUp {
  0%   { opacity: 0; transform: translateY(4px) scale(.9); }
  20%  { opacity: 1; transform: translateY(-2px) scale(1.05); }
  100% { opacity: 0; transform: translateY(-34px) scale(1); }
}

/* ── Map pin pop: a stamp should feel like a stamp ───────────────── */
@keyframes pinPop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.9); }
  100% { transform: scale(1); }
}
.pin-pop { transform-box: fill-box; transform-origin: center; animation: pinPop 380ms var(--ease-spring); }

/* ── Streak shimmer: the ember underline breathes once on entry ──── */
@keyframes streakIn {
  from { background-size: 0% 1px; }
  to   { background-size: 100% 1px; }
}
.streak-chip {
  border-bottom: none !important;
  background-image: linear-gradient(90deg, var(--ember-hi), var(--ember));
  background-repeat: no-repeat; background-position: 0 100%; background-size: 100% 1px;
  animation: streakIn 700ms var(--ease-exit);
  padding-bottom: 3px;
}

/* ── Count-up numbers get a soft settle ──────────────────────────── */
.counting { transition: opacity 120ms var(--ease); }

/* ── Builder: module rows snap in with spring ────────────────────── */
.asm-mod { transition: opacity 300ms var(--ease-exit), transform 340ms var(--ease-spring), color 300ms var(--ease); }
.asm-mod.on { transform: none; }

/* ── Respect the human ───────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .view > *, .toast, .sheet, .drawer, .streak-chip { animation: none !important; }
  .rise { opacity: 1; transform: none; }
  .spark, .flyup { display: none; }
  .btn:active, .btn-gold:active, .fchip:active, .b-opt:active, .act:active,
  .dispo:active, .mod-row:active, .nav-it:active, .thr:active, .fm-press:active { transform: none; }
}
