/* ════════════════════════════════════════════════════════════
   Motion system — elegant, restrained, Linear/Notion-grade.
   All transitions: 200-320ms · cubic-bezier(0.2, 0.8, 0.2, 1)
   ════════════════════════════════════════════════════════════ */

:root {
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);    /* expo-out — silky deceleration */
  --ease-soft: cubic-bezier(0.2, 0.8, 0.2, 1);  /* gentle ease for UI */
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* mild overshoot */
  --dur-1: 160ms;
  --dur-2: 240ms;
  --dur-3: 360ms;
  --dur-4: 520ms;
}

/* Master animations toggle — Settings → Motion & Density */
html[data-animations="off"] *,
html[data-animations="off"] *::before,
html[data-animations="off"] *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
}

/* ───── 1. Page enter — fade + lift ───── */
@keyframes pageEnter {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.app-scroll > div {
  animation: pageEnter var(--dur-3) var(--ease-out) both;
}

/* ───── 2. Detail page — slide from right with depth ───── */
@keyframes detailIn {
  from { opacity: 0; transform: translateX(18px) scale(0.985); }
  to   { opacity: 1; transform: translateX(0) scale(1); }
}
.detail-hero { animation: detailIn var(--dur-3) var(--ease-out) both; }

/* ───── 3. Section reveal — staggered ───── */
@keyframes sectionRise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.section {
  animation: sectionRise var(--dur-3) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 60ms + 80ms);
}
.section:nth-of-type(1) { --i: 0; }
.section:nth-of-type(2) { --i: 1; }
.section:nth-of-type(3) { --i: 2; }
.section:nth-of-type(4) { --i: 3; }
.section:nth-of-type(5) { --i: 4; }
.section:nth-of-type(6) { --i: 5; }
.section:nth-of-type(7) { --i: 6; }
.section:nth-of-type(8) { --i: 7; }

/* ───── 4. Card grid stagger ───── */
@keyframes cardRise {
  from { opacity: 0; transform: translateY(8px) scale(0.99); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.un-card,
.rec-card,
.card,
.poster-card,
.dossier-card,
.editorial-card,
.flippable-card {
  animation: cardRise var(--dur-3) var(--ease-out) both;
}
.un-card:nth-child(1), .rec-card:nth-child(1) { animation-delay: 40ms; }
.un-card:nth-child(2), .rec-card:nth-child(2) { animation-delay: 100ms; }
.un-card:nth-child(3), .rec-card:nth-child(3) { animation-delay: 160ms; }
.un-card:nth-child(4), .rec-card:nth-child(4) { animation-delay: 220ms; }
.un-card:nth-child(5), .rec-card:nth-child(5) { animation-delay: 280ms; }
.un-card:nth-child(6), .rec-card:nth-child(6) { animation-delay: 340ms; }
.un-card:nth-child(7), .rec-card:nth-child(7) { animation-delay: 400ms; }
.un-card:nth-child(8), .rec-card:nth-child(8) { animation-delay: 460ms; }

/* ───── 5. Press feedback — tactile but subtle ───── */
button,
.un-card,
.rec-card,
.kpi,
.tab,
.act-btn,
.indicator-toggle,
.expand-head {
  transition:
    transform var(--dur-1) var(--ease-soft),
    background-color var(--dur-2) var(--ease-soft),
    border-color var(--dur-2) var(--ease-soft),
    color var(--dur-2) var(--ease-soft),
    opacity var(--dur-2) var(--ease-soft),
    box-shadow var(--dur-2) var(--ease-soft);
}
button:active,
.un-card:active,
.rec-card:active,
.act-btn:active,
.tab:active {
  transform: scale(0.97);
  transition-duration: 80ms;
}

/* hover lift for cards (desktop only) */
@media (hover: hover) {
  .un-card:hover,
  .rec-card:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 16px -8px rgba(0, 0, 0, 0.4);
  }
}

/* ───── 6. Tab bar — active indicator ───── */
.tabbar .tab { position: relative; }
.tabbar .tab svg,
.tabbar .tab span {
  transition: transform var(--dur-2) var(--ease-spring), opacity var(--dur-2) var(--ease-soft);
}
.tabbar .tab.active svg {
  transform: translateY(-1px) scale(1.08);
}
.tabbar .tab::before {
  content: '';
  position: absolute;
  top: 2px;
  left: 50%;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent-strong, var(--up));
  opacity: 0;
  transform: translateX(-50%) scale(0);
  transition: opacity var(--dur-2) var(--ease-soft), transform var(--dur-2) var(--ease-spring);
}
.tabbar .tab.active::before {
  opacity: 1;
  transform: translateX(-50%) scale(1);
}

/* ───── 7. Market & Term tabs — soft pill slide ───── */
.market-tabs button,
.term-tabs button,
[role="tablist"] button {
  transition:
    background-color var(--dur-2) var(--ease-soft),
    color var(--dur-2) var(--ease-soft),
    border-color var(--dur-2) var(--ease-soft);
}

/* ───── 8. Fusion ring — soft scale & fade-in (preserves data-driven dashoffset) ───── */
@keyframes ringIn {
  from { opacity: 0; transform: scale(0.92); }
  to   { opacity: 1; transform: scale(1); }
}
.fusion-ring-wrap svg {
  animation: ringIn var(--dur-4) var(--ease-spring) both;
  transform-origin: center;
}

/* ───── 9. Number tick — used by AnimatedNumber wrapper ───── */
.num-tick {
  display: inline-block;
  font-variant-numeric: tabular-nums;
  transition: color var(--dur-2) var(--ease-soft);
}

/* ───── 10. Skeleton shimmer ───── */
@keyframes shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
.skeleton {
  background: linear-gradient(
    90deg,
    var(--bg-3, rgba(255,255,255,0.04)) 0%,
    var(--bg-2, rgba(255,255,255,0.08)) 50%,
    var(--bg-3, rgba(255,255,255,0.04)) 100%
  );
  background-size: 200% 100%;
  animation: shimmer 1.6s linear infinite;
  border-radius: 4px;
}

/* ───── 11. Refresh icon — smooth rotation ───── */
@keyframes spin {
  to { transform: rotate(360deg); }
}
.refreshing svg,
.spinning {
  animation: spin 800ms var(--ease-soft) infinite;
}

/* ───── 12. Pulse dot — breathing ───── */
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.55; transform: scale(0.86); }
}
.dot,
.pulse-dot,
.pulse {
  animation: pulse 2.4s var(--ease-soft) infinite;
}

/* ───── 13. Banner slide-down ───── */
@keyframes bannerDrop {
  from { opacity: 0; transform: translateY(-8px); max-height: 0; margin-bottom: 0; }
  to   { opacity: 1; transform: translateY(0); max-height: 200px; }
}
.banner,
.continuity-banner {
  animation: bannerDrop var(--dur-3) var(--ease-out) both;
}

/* ───── 14. Expand card — accordion ───── */
.expand-body {
  animation: expandDown var(--dur-3) var(--ease-out) both;
  overflow: hidden;
}
@keyframes expandDown {
  from { opacity: 0; max-height: 0; transform: translateY(-4px); }
  to   { opacity: 1; max-height: 600px; transform: translateY(0); }
}

/* ───── 15. Tweaks panel — slide in from right ───── */
@keyframes tweaksIn {
  from { opacity: 0; transform: translateX(12px); }
  to   { opacity: 1; transform: translateX(0); }
}
[class*="tweaks"][class*="panel"] {
  animation: tweaksIn var(--dur-2) var(--ease-out) both;
}

/* ───── 16. Subtle scroll momentum ───── */
.app-scroll {
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
}

/* ───── 17. Action bar floating in ───── */
@keyframes actionBarRise {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}
.action-bar {
  animation: actionBarRise var(--dur-4) var(--ease-out) 240ms both;
}

/* ───── 18. Chart line draw-on ───── */
@keyframes drawLine {
  from { stroke-dashoffset: 1000; }
  to   { stroke-dashoffset: 0; }
}
.chart-panel svg path[stroke]:not([fill]),
.curve-path {
  stroke-dasharray: 1000;
  animation: drawLine 1.2s var(--ease-out) 100ms both;
}

/* ───── 19. KPI value subtle pop on mount ───── */
@keyframes kpiPop {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.kpi .v,
.stat-cell .v {
  animation: kpiPop var(--dur-3) var(--ease-spring) both;
  animation-delay: calc(var(--i, 0) * 40ms + 120ms);
}

/* ───── 20. Honor reduced motion ───── */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
