/* Sigma AI — animations
   Every keyframe on the site lives here, grouped by where it is used.
   Looping scenes pause while they are off screen (.anim-scope without .in-view),
   and everything is switched off for visitors who ask for reduced motion (bottom of file). */

/* ---------- Entrances ---------- */
@keyframes enter-rise { from { opacity: 0; transform: translateY(14px); } }
@keyframes enter-rail { from { opacity: 0; transform: translateX(-12px); } }
@keyframes enter-art  { from { opacity: 0; transform: scale(1.07); } }
@keyframes fade-in    { from { opacity: 0; } }
@keyframes fade-out   { to { opacity: 0; } }

/* Page content rises in, staggered with --i */
.rise { animation: enter-rise .65s var(--ease) backwards; animation-delay: calc(var(--i, 0) * 70ms + 40ms); }
/* Sidebar items slide in from the rail on the first visit of a session */
.first-visit .sb-anim { animation: enter-rail .5s var(--ease) backwards; animation-delay: calc(var(--i, 0) * 55ms + 1.05s); }
.first-visit .rise { animation-delay: calc(var(--i, 0) * 70ms + 1.05s); }
/* Hero artwork settles in */
.pot-art { animation: enter-art 1.3s var(--ease) backwards; }
.first-visit .pot-art { animation-delay: .95s; }

/* Scroll reveal: add .reveal, JS adds .is-in when the element scrolls into view */
.js .reveal { opacity: 0; transform: translateY(18px); transition: opacity .6s var(--ease), transform .6s var(--ease); transition-delay: calc(var(--i, 0) * 60ms); }
.js .reveal.is-in { opacity: 1; transform: none; }

/* ---------- Page loader (first visit only, pure CSS so it can never get stuck) ---------- */
@keyframes loader-appear { from { opacity: 0; transform: translateY(6px) scale(.97); } }
@keyframes loader-fill   { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes loader-out    { to { opacity: 0; visibility: hidden; } }
.first-visit .loader { animation: loader-out .45s ease 1s forwards; }
.loader-inner { animation: loader-appear .4s var(--ease) .05s backwards; }
.loader-bar span { animation: loader-fill .95s cubic-bezier(.3, 0, .2, 1) forwards; }

/* ---------- Live indicators ---------- */
@keyframes live-pulse {
  0% { box-shadow: 0 0 0 0 rgba(var(--pulse), .5); }
  70%, 100% { box-shadow: 0 0 0 7px rgba(var(--pulse), 0); }
}
.live-dot { animation: live-pulse 2s ease-out infinite; }

@keyframes value-bump {
  30% { transform: scale(1.03); text-shadow: 0 0 28px rgba(var(--pulse), .35); }
}
.bump { animation: value-bump .7s var(--ease); }

@keyframes delta-float {
  0% { opacity: 0; transform: translateY(8px); }
  20% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-18px); }
}
.pot-delta.show { animation: delta-float 1.6s var(--ease) forwards; }

/* ---------- Loading skeletons ---------- */
@keyframes shimmer { from { background-position: 160% 0; } to { background-position: -60% 0; } }
.sk {
  display: block; border-radius: 6px;
  background: linear-gradient(100deg, var(--surface-3) 30%, var(--surface-4) 50%, var(--surface-3) 70%);
  background-size: 240% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}

/* ---------- Progress bars and charts ---------- */
@keyframes bar-grow { from { width: 0; } }
.bar > span { animation: bar-grow 1s var(--ease) .15s backwards; }

@keyframes line-draw { to { stroke-dashoffset: 0; } }
.chart .line.draw { stroke-dasharray: 1; stroke-dashoffset: 1; animation: line-draw 1.2s var(--ease) forwards; }
.chart .area { animation: fade-in .8s ease .25s backwards; }
@keyframes bar-rise { from { transform: scaleY(0); } }
.chart .bar-rect { transform-box: fill-box; transform-origin: bottom; animation: bar-rise .7s var(--ease) backwards; animation-delay: calc(var(--i, 0) * 18ms); }
.chart svg.static .line.draw { stroke-dasharray: none; animation: none; }
.chart svg.static .area, .chart svg.static .bar-rect { animation: none; }

/* ---------- Hero scene ---------- */
@keyframes coin-float {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50% { transform: translateY(-12px) rotate(5deg); }
}
.coin { transform-box: fill-box; transform-origin: center; animation: coin-float var(--dur, 7s) ease-in-out var(--delay, 0s) infinite; }

@keyframes ring-dash { to { stroke-dashoffset: -340; } }
.ring-dash { animation: ring-dash 16s linear infinite; }
.ring-dash.rev { animation-direction: reverse; animation-duration: 22s; }

@keyframes beam-breathe { 0%, 100% { opacity: .6; } 50% { opacity: 1; } }
.ps-beam { animation: beam-breathe 7s ease-in-out infinite; }

/* ---------- Feature card: Explore (token lanes drift up and down) ---------- */
/* Each lane holds its tiles twice, so moving by half its height (plus half a gap) loops seamlessly. */
@keyframes lane-drift { to { transform: translateY(calc(-50% - 5px)); } }
.lane { animation: lane-drift var(--dur, 28s) linear infinite; }
.lane:nth-child(even) { animation-direction: reverse; }

/* ---------- Feature card: Launch (a form fills itself in, 10s loop) ---------- */
@keyframes sheet-float {
  0%, 100% { transform: rotate(-4deg) translateY(0); }
  50% { transform: rotate(-2.5deg) translateY(-7px); }
}
@keyframes orbit-spin { to { transform: rotate(360deg); } }
@keyframes type-name {
  0%, 6% { width: 0; }
  28%, 92% { width: calc(var(--n) * 1ch); }
  100% { width: 0; }
}
@keyframes type-ticker {
  0%, 34% { width: 0; }
  48%, 92% { width: calc(var(--n) * 1ch); }
  100% { width: 0; }
}
@keyframes caret-blink { 50% { opacity: 0; } }
@keyframes caret-name-window   { 0%, 5% { visibility: hidden; } 6%, 30% { visibility: visible; } 31%, 100% { visibility: hidden; } }
@keyframes caret-ticker-window { 0%, 33% { visibility: hidden; } 34%, 50% { visibility: visible; } 51%, 100% { visibility: hidden; } }
@keyframes avatar-in {
  0%, 50% { opacity: 0; transform: scale(.6); }
  56%, 92% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: none; }
}
@keyframes form-progress {
  0%, 6% { transform: scaleX(0); }
  28% { transform: scaleX(.34); }
  48% { transform: scaleX(.67); }
  58%, 92% { transform: scaleX(1); }
  100% { transform: scaleX(0); }
}
@keyframes check-pop {
  0%, 59% { transform: scale(0); }
  63% { transform: scale(1.18); }
  66%, 92% { transform: scale(1); }
  100% { transform: scale(0); }
}
@keyframes title-in {
  0%, 60% { opacity: 0; transform: translateY(4px); }
  66%, 92% { opacity: 1; transform: none; }
  100% { opacity: 0; }
}
.orbit { animation: orbit-spin 18s linear infinite; }
.sheet { animation: sheet-float 6s ease-in-out infinite; }
.typed-name   { animation: type-name 10s steps(var(--n)) infinite; }
.typed-ticker { animation: type-ticker 10s steps(var(--n)) infinite; }
.caret-name   { animation: caret-blink .9s step-end infinite, caret-name-window 10s linear infinite; }
.caret-ticker { animation: caret-blink .9s step-end infinite, caret-ticker-window 10s linear infinite; }
.sheet-avatar .art { animation: avatar-in 10s ease infinite; }
.sheet-progress span { animation: form-progress 10s ease infinite; }
.sheet-check { animation: check-pop 10s ease-out infinite; }
.sheet-title { animation: title-in 10s ease infinite; }

/* ---------- Draw celebration ---------- */
@keyframes confetti-fall {
  0% { opacity: 1; transform: translate3d(0, 0, 0) rotate(0deg); }
  85% { opacity: 1; }
  100% { opacity: 0; transform: translate3d(var(--dx), 104vh, 0) rotate(var(--r)); }
}
.confetti i { animation: confetti-fall var(--d, 2.6s) cubic-bezier(.25, .6, .45, 1) var(--delay, 0s) both; }

@keyframes win-flash {
  0% { box-shadow: 0 0 0 0 rgba(var(--pulse), .45); }
  100% { box-shadow: 0 0 0 26px rgba(var(--pulse), 0); }
}
.flash { animation: win-flash .8s ease-out; }

/* ---------- Launch flow ---------- */
@keyframes spin { to { transform: rotate(360deg); } }
.spinner { animation: spin .85s linear infinite; }

@keyframes success-in { from { opacity: 0; transform: translateY(10px) scale(.92); } }
.success > * { animation: success-in .5s var(--spring) backwards; }
.success > :nth-child(2) { animation-delay: .06s; }
.success > :nth-child(3) { animation-delay: .12s; }
.success > :nth-child(4) { animation-delay: .18s; }

/* ---------- Overlays ---------- */
@keyframes modal-in  { from { opacity: 0; transform: translateY(10px) scale(.97); } }
@keyframes modal-out { to { opacity: 0; transform: translateY(6px) scale(.98); } }
.modal-root .modal { animation: modal-in .3s var(--ease); }
.modal-root .modal-backdrop { animation: fade-in .25s ease; }
.modal-root.is-closing .modal { animation: modal-out .18s ease-in forwards; }
.modal-root.is-closing .modal-backdrop { animation: fade-out .18s ease-in forwards; }

@keyframes toast-in  { from { opacity: 0; transform: translateY(14px) scale(.96); } }
@keyframes toast-out { to { opacity: 0; transform: translateX(28px); } }
.toast { animation: toast-in .35s var(--ease); }
.toast.is-leaving { animation: toast-out .22s ease-in forwards; }

@keyframes menu-in { from { opacity: 0; transform: translateY(-6px) scale(.98); } }
.menu:not([hidden]) { animation: menu-in .18s var(--ease); transform-origin: top right; }
.search-pop:not([hidden]) { animation: menu-in .18s var(--ease); transform-origin: top center; }

/* ---------- Scroll-fade edges ----------
   Scroll areas fade out at an edge only while there is more content in that direction.
   Uses scroll-driven animations where supported; js/components.js sets the same variables elsewhere. */
@property --fade-l { syntax: '<length>'; inherits: false; initial-value: 0px; }
@property --fade-r { syntax: '<length>'; inherits: false; initial-value: 0px; }
@property --fade-t { syntax: '<length>'; inherits: false; initial-value: 0px; }
@property --fade-b { syntax: '<length>'; inherits: false; initial-value: 0px; }
.scroll-fade-x {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
}
.scroll-fade-y {
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 var(--fade-t), #000 calc(100% - var(--fade-b)), transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 var(--fade-t), #000 calc(100% - var(--fade-b)), transparent 100%);
}
@keyframes scroll-fade-x { 0% { --fade-l: 0px; --fade-r: 56px; } 6% { --fade-l: 56px; } 94% { --fade-r: 56px; } 100% { --fade-l: 56px; --fade-r: 0px; } }
@keyframes scroll-fade-y { 0% { --fade-t: 0px; --fade-b: 40px; } 8% { --fade-t: 40px; } 92% { --fade-b: 40px; } 100% { --fade-t: 40px; --fade-b: 0px; } }
@supports (animation-timeline: scroll()) {
  .scroll-fade-x { animation: scroll-fade-x linear both; animation-timeline: scroll(self inline); }
  .scroll-fade-y { animation: scroll-fade-y linear both; animation-timeline: scroll(self block); }
}

/* ---------- Page transitions between pages (browsers with cross-document view transitions) ---------- */
@view-transition { navigation: auto; }
.sidebar { view-transition-name: sidebar; }
.topbar { view-transition-name: topbar; }
::view-transition-old(root) { animation: .16s ease-in both fade-out; }
::view-transition-new(root) { animation: .24s var(--ease) both fade-in; }

/* ---------- Pause looping scenes while they are off screen ---------- */
.js .anim-scope:not(.in-view) *,
.js .anim-scope:not(.in-view) *::before,
.js .anim-scope:not(.in-view) *::after { animation-play-state: paused !important; }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .lane, .orbit, .sheet, .coin, .ring-dash, .ps-beam, .live-dot, .sk, .spinner,
  .typed-name, .typed-ticker, .caret-name, .caret-ticker,
  .sheet-avatar .art, .sheet-progress span, .sheet-check, .sheet-title { animation: none !important; }
  .first-visit .loader { display: none; }
  .js .reveal { opacity: 1; transform: none; }
  @view-transition { navigation: none; }
}
