/* Landing-page motion. Everything here is decoration: the page reads the
   same with this file missing, and all of it stops under reduced motion.
   motion.js adds the hooks (data-reveal, .counting, .typing…). */

/* ---- reveal on scroll: rise and fade, staggered by --i */
[data-reveal] { opacity: 0; transform: translateY(18px); transition: opacity .6s cubic-bezier(.2,.7,.2,1), transform .6s cubic-bezier(.2,.7,.2,1); transition-delay: calc(var(--i, 0) * 70ms); will-change: opacity, transform; }
[data-reveal].in { opacity: 1; transform: none; }

/* ---- hero: the headline's lines rise one after another; the card lands.
   Nothing above the fold starts at opacity 0: the first paint has to carry
   real text, or the browser picks something further down as the LCP element
   and the measured load looks far worse than it is. Transform only. */
.hero h1 .w { display: inline-block; transform: translateY(.6em); animation: rise .7s cubic-bezier(.2,.7,.2,1) forwards; }
.hero h1 .w:nth-of-type(2) { animation-delay: .12s; }
.hero h1 .w:nth-of-type(3) { animation-delay: .24s; }
@keyframes rise { to { transform: none; } }
.stage { perspective: 1000px; }
.stage .card { transform-style: preserve-3d; transition: transform .35s cubic-bezier(.2,.7,.2,1), box-shadow .35s; animation: land .9s cubic-bezier(.2,.7,.2,1) .2s both; }
@keyframes land { from { transform: translateY(26px) scale(.98); } to { transform: none; } }
.stage .card.landed { animation: none; }
.stage.tilt .card { transition: transform .12s ease-out; }
/* the bar fills in from the left once the card has landed */
.card .bar { overflow: hidden; }
.card .bar i { transform-origin: left; animation: grow .9s cubic-bezier(.2,.7,.2,1) .8s both; }
.card .bar i:nth-child(2) { animation-delay: 1.0s; }
.card .bar i:nth-child(3) { animation-delay: 1.15s; }
@keyframes grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* the coins behind the card: a nudge when the numbers finish counting */
.fizz .pill { transform-box: fill-box; transform-origin: center; }
.fizz.bump .pill { animation: bump .5s cubic-bezier(.2,.7,.2,1); }
@keyframes bump { 30% { transform: translateY(-6px) rotate(-3deg); } 100% { transform: none; } }

/* ---- feature tiles: lift on hover, glyph gives a nod */
.tile { transition: transform .25s cubic-bezier(.2,.7,.2,1), box-shadow .25s; }
@media (hover: hover) {
  .tile:hover { transform: translateY(-4px); box-shadow: 0 18px 40px -24px rgba(11,93,59,.45); }
  .tile:hover .glyph svg { animation: nod .5s cubic-bezier(.2,.7,.2,1); }
}
@keyframes nod { 30% { transform: translateY(-3px) rotate(-6deg); } 60% { transform: translateY(0) rotate(4deg); } }

/* ---- chat: a conversation that happens, not a transcript */
.bubbles .b { transition: opacity .45s cubic-bezier(.2,.7,.2,1), transform .45s cubic-bezier(.2,.7,.2,1); }
.bubbles.live .b { opacity: 0; transform: translateY(10px) scale(.98); }
.bubbles.live .b.me { transform: translate(8px, 10px) scale(.98); }
.bubbles.live .b.on { opacity: 1; transform: none; }
.b.typing { display: inline-flex; gap: 5px; align-items: center; padding: 14px 16px; }
.b.typing i { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); opacity: .4; animation: dot 1s infinite; }
.b.typing i:nth-child(2) { animation-delay: .15s; }
.b.typing i:nth-child(3) { animation-delay: .3s; }
@keyframes dot { 30% { opacity: 1; transform: translateY(-3px); } }
/* the streaming reply's caret */
.b .caret { display: inline-block; width: 2px; height: 1em; margin-left: 2px; vertical-align: -0.15em; background: var(--accent); animation: blink .9s steps(2) infinite; }
@keyframes blink { to { opacity: 0; } }
.bubbles.live .b.ai { min-height: 44px; }

/* ---- steps: the numbers pop in */
.steps li .n { transition: transform .4s cubic-bezier(.34,1.56,.64,1); }
.steps li[data-reveal]:not(.in) .n { transform: scale(.4); }

/* ---- pricing and the final word */
.price-card { transition: box-shadow .3s; }
.final .capsule { width: 84px; height: 84px; margin: 0 auto 18px; display: block; }
.final .capsule .coin { transform-box: fill-box; transform-origin: center bottom; opacity: 0; transform: translateY(-40px); }
.final .capsule.in .flat { animation: drop .7s cubic-bezier(.2,.9,.3,1.3) .1s forwards; }
.final .capsule.in .stand { animation: drop .7s cubic-bezier(.2,.9,.3,1.3) .45s forwards; }
.final .capsule.in .pill { animation: lean 1.1s cubic-bezier(.2,.7,.2,1) .1s; }
@keyframes drop { to { opacity: 1; transform: none; } }
@keyframes lean { 40% { transform: rotate(-8deg); } 100% { transform: none; } }

/* ---- counting numbers keep their width steady */
.counting { font-variant-numeric: tabular-nums; }

/* ---- nothing moves for people who asked for that */
@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; transition: none; }
  .hero h1 .w, .stage .card, .card .bar i, .fizz .pill, .tile, .glyph svg, .b, .steps li .n, .final .capsule * { animation: none !important; transition: none !important; opacity: 1 !important; transform: none !important; }
  .bubbles.live .b { opacity: 1; transform: none; }
  .b.typing { display: none; }
}
