/* covden.com landing page.
   Tokens derive from the brand palette (charcoal #171F22, pale #C1D1CF, steel #748B91); the violet glow
   is sampled from Covden Core itself. Loaded under a strict CSP: no inline styles anywhere, so every
   visual decision lives in this file. */

@font-face { font-family: "Figtree"; font-weight: 400; font-display: swap; src: url("assets/fonts/figtree-400.woff2") format("woff2"); }
@font-face { font-family: "Figtree"; font-weight: 500; font-display: swap; src: url("assets/fonts/figtree-500.woff2") format("woff2"); }
@font-face { font-family: "Figtree"; font-weight: 600; font-display: swap; src: url("assets/fonts/figtree-600.woff2") format("woff2"); }
@font-face { font-family: "Figtree"; font-weight: 700; font-display: swap; src: url("assets/fonts/figtree-700.woff2") format("woff2"); }

:root {
  --bg: #0b0f11;
  --bg-raised: #11171a;
  --ink: #eef3f2;
  --muted: #9fadac;            /* 8.1:1 on --bg */
  --pale: #c1d1cf;
  --steel: #748b91;
  --violet: #8f7df7;
  --violet-soft: rgba(143, 125, 247, 0.28);
  --line: rgba(193, 209, 207, 0.34);
  --line-faint: rgba(193, 209, 207, 0.14);
  --glass: rgba(255, 255, 255, 0.055);
  --glass-edge: rgba(255, 255, 255, 0.13);
  --radius: 22px;
  --page: min(1120px, 100% - 48px);
  /* The art is sized by height as well as width: the Core's face sits ~60% down its disc, so the
     first screen must show about four fifths of the disc under ~430px of copy. */
  --art: clamp(320px, min(94vw, calc((100svh - 430px) / 0.8)), 900px);
  --visible: 0.8;              /* share of the art shown above the hero's bottom edge */
  --k: 0.88;                    /* stage scale; main.js keeps it exact, these are the no-JS fallbacks */
  --px: 0;                      /* pointer offset, -0.5..0.5, set by main.js */
  --py: 0;
  color-scheme: dark;
}
@media (max-width: 900px) { :root { --k: 0.76; } }
@media (max-width: 700px) { :root { --k: 0.66; } }
@media (max-width: 480px) { :root { --k: 0.36; } }

*, *::before, *::after { box-sizing: border-box; }
html { background: var(--bg); scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 400 17px/1.6 "Figtree", ui-sans-serif, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased; overflow-x: clip;
}
img, svg { display: block; max-width: 100%; }
a { color: inherit; }
h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -0.02em; text-wrap: balance; }
p { margin: 0; text-wrap: pretty; }
.hero__lede, .section__lede, .closing p { text-wrap: balance; }
:focus-visible { outline: 2px solid var(--pale); outline-offset: 3px; border-radius: 8px; }

.skip { position: absolute; left: 16px; top: -48px; z-index: 50; padding: 10px 16px; background: var(--ink); color: var(--bg); border-radius: 999px; text-decoration: none; }
.skip:focus { top: 16px; }

/* ── Pills ─────────────────────────────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 22px;
  border-radius: 999px; font-weight: 500; font-size: 16px; text-decoration: none; white-space: nowrap;
  transition: background-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.pill--light { background: var(--ink); color: #0b0f11; }
.pill--light:hover { background: #fff; box-shadow: 0 0 0 6px rgba(238, 243, 242, 0.08); }
.pill--dark { background: rgba(255, 255, 255, 0.06); color: var(--ink); border: 1px solid var(--glass-edge); }
.pill--dark:hover { background: rgba(255, 255, 255, 0.11); }
.pill--large { min-height: 54px; padding: 0 30px; font-size: 17px; }

/* ── Nav ───────────────────────────────────────────────────────────────── */
.nav {
  position: absolute; inset: 0 0 auto; z-index: 20; display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 24px; width: var(--page); margin: 0 auto; padding-top: 28px;
}
.nav__brand img { height: 34px; width: auto; }
.nav__links { display: flex; gap: 36px; }
.nav__links a { text-decoration: none; color: var(--pale); font-size: 16px; transition: color .2s; }
.nav__links a:hover { color: #fff; }
.nav__actions { display: flex; gap: 10px; justify-self: end; }

/* ── Hero ──────────────────────────────────────────────────────────────── */
.hero {
  position: relative; overflow: clip; isolation: isolate;
  display: flex; flex-direction: column; align-items: center;
  padding-top: clamp(104px, 13vh, 150px);
  background:
    radial-gradient(60% 55% at 12% 0%, rgba(143, 125, 247, 0.16), transparent 70%),
    radial-gradient(45% 40% at 90% 8%, rgba(116, 139, 145, 0.10), transparent 70%),
    var(--bg);
}
.hero::after {  /* soft floor where the disc meets the fold */
  content: ""; position: absolute; inset: auto 0 0; height: 56px; z-index: 5;
  background: linear-gradient(to bottom, transparent, var(--bg)); pointer-events: none;
}

.hero__sky { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.stars { position: absolute; inset: 0; background-repeat: repeat; }
.stars--a { background-size: 397px 397px; opacity: .45; background-image:
  radial-gradient(1px 1px at 31px 47px, #fff 50%, transparent 51%), radial-gradient(1px 1px at 173px 19px, #dfe7e6 50%, transparent 51%),
  radial-gradient(1.4px 1.4px at 289px 133px, #fff 50%, transparent 51%), radial-gradient(1px 1px at 97px 241px, #fff 50%, transparent 51%),
  radial-gradient(1px 1px at 353px 311px, #e6ecff 50%, transparent 51%), radial-gradient(1px 1px at 211px 367px, #fff 50%, transparent 51%); }
.stars--b { background-size: 541px 541px; opacity: .32; background-image:
  radial-gradient(1px 1px at 67px 113px, #cfc8ff 50%, transparent 51%), radial-gradient(1px 1px at 419px 59px, #fff 50%, transparent 51%),
  radial-gradient(1.2px 1.2px at 257px 283px, #fff 50%, transparent 51%), radial-gradient(1px 1px at 491px 419px, #fff 50%, transparent 51%),
  radial-gradient(1px 1px at 139px 487px, #dfe7e6 50%, transparent 51%); }
.stars--c { background-size: 673px 673px; opacity: .26; background-image:
  radial-gradient(1.6px 1.6px at 149px 71px, #fff 50%, transparent 51%), radial-gradient(1px 1px at 521px 197px, #e6ecff 50%, transparent 51%),
  radial-gradient(1px 1px at 331px 467px, #fff 50%, transparent 51%), radial-gradient(1.3px 1.3px at 613px 593px, #cfc8ff 50%, transparent 51%); }

.hero__copy { position: relative; z-index: 10; display: flex; flex-direction: column; align-items: center; text-align: center; width: var(--page); }
.hero__title { font-size: clamp(40px, min(6.4vw, 8.4vh), 78px); line-height: 1.02; letter-spacing: -0.035em; }
.hero__title .line { display: block; }
.hero__title .w { display: inline-block; }
.hero__lede { max-width: 34em; margin-top: 22px; color: var(--muted); font-size: clamp(16px, 1.5vw, 18px); }
.hero__copy .pill--large { margin-top: 30px; }
.hero__note { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 18px; margin: 16px 0 0; padding: 0; list-style: none; color: var(--steel); font-size: 14px; }
.hero__note li + li::before { content: "·"; margin-right: 18px; color: var(--line); }

/* Art: an in-flow square whose lower part is clipped by the hero, so the disc always rises from the
   bottom edge below the copy and can never collide with it, whatever the viewport height. */
.hero__art {
  position: relative; z-index: 2; width: var(--art); aspect-ratio: 1; flex: none;
  margin-top: clamp(8px, 2vh, 28px); margin-bottom: calc(var(--art) * (var(--visible) - 1));
}
/* The stage is fixed at 1000px so the sketch SVG, the Core and the spark motion paths share one exact
   coordinate system; it is scaled as a whole to fit the art box. */
.stage { position: absolute; left: 0; top: 0; width: 1000px; height: 1000px; transform: scale(var(--k)); transform-origin: 0 0; }
.layer { position: absolute; inset: 0; }
.layer--sketch { translate: calc(var(--px) * -8px) calc(var(--py) * -6px); }
.layer--core { translate: calc(var(--px) * 6px) calc(var(--py) * 4px); }
.layer--sparks { translate: calc(var(--px) * 14px) calc(var(--py) * 10px); }

.glow {
  position: absolute; inset: -12%; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(143, 125, 247, 0.42), rgba(116, 139, 145, 0.10) 62%, transparent 76%);
  filter: blur(18px);
}

#sketch { width: 1000px; height: 1000px; overflow: visible; }
#sketch .draw { fill: none; stroke: var(--line); stroke-width: 1.4; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 0; vector-effect: non-scaling-stroke; }
#sketch .guides .draw { stroke: var(--line-faint); }
#sketch .tick { stroke: var(--line); }
#sketch .halo { stroke: rgba(193, 209, 207, 0.42); filter: drop-shadow(0 0 6px var(--violet-soft)); }
#sketch .halo--inner { stroke: rgba(143, 125, 247, 0.30); }
#sketch .orbit { stroke: rgba(193, 209, 207, 0.26); }
#sketch .construct .draw { stroke: rgba(207, 200, 255, 0.55); }
#sketch .notes text { fill: rgba(193, 209, 207, 0.5); font: 500 17px "Figtree", sans-serif; letter-spacing: 0.04em; }

#core { position: absolute; left: 0; top: 0; width: 1000px; height: 1000px; max-width: none; user-select: none; -webkit-user-drag: none; }

.spark {
  position: absolute; left: 0; top: 0; width: 58px; height: 58px; max-width: none;
  /* Layered behind the Core: a spark is seen where its orbit runs outside the disc and passes behind the
     character on the far side, so it can never cover the face. */
  offset-anchor: center; offset-rotate: 0deg;
  filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.35));
}
.spark[data-orbit="1"] { offset-path: path("M-51.5 567.2A560 150 -10 1 1 1051.5 372.8A560 150 -10 1 1 -51.5 567.2Z"); }
.spark[data-orbit="2"] { offset-path: path("M-135.2 392.0A640 205 7 1 1 1135.2 548.0A640 205 7 1 1 -135.2 392.0Z"); }
.spark[data-orbit="3"] { offset-path: path("M0.7 496.2A500 112 -3 1 1 999.3 443.8A500 112 -3 1 1 0.7 496.2Z"); }
/* Resting positions, spread so no two sparks meet; the orbit animation starts from these. */
.spark--violet { --start: 8%; offset-distance: var(--start); }
.spark--blue   { --start: 41%; offset-distance: var(--start); }
.spark--gold   { --start: 72%; offset-distance: var(--start); }
.spark--rose   { --start: 20%; offset-distance: var(--start); }
.spark--green  { --start: 60%; offset-distance: var(--start); }
.spark--orange { --start: 32%; offset-distance: var(--start); width: 50px; height: 50px; }
.spark--red    { --start: 86%; offset-distance: var(--start); width: 50px; height: 50px; }

.glass-card {
  position: absolute; z-index: 6; display: grid; grid-template-columns: 1fr auto; gap: 10px 18px;
  width: 250px; padding: 18px 20px 20px; border-radius: 18px;
  /* Dark glass, as in the reference: the text must stay readable even where the card overlaps the
     pale disc, which light glass could not guarantee. */
  background: rgba(14, 19, 22, 0.62); border: 1px solid var(--glass-edge);
  backdrop-filter: blur(18px) saturate(140%); -webkit-backdrop-filter: blur(18px) saturate(140%);
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.08);
  translate: calc(var(--px) * 18px) calc(var(--py) * 12px);
}
/* Anchored to the hero's bottom edge beside the disc, as in the reference, and never off-screen. */
.glass-card--left { left: max(16px, calc(50% - var(--art) * 0.5 - 170px)); bottom: calc(var(--art) * var(--visible) * 0.52); }
.glass-card--right { right: max(16px, calc(50% - var(--art) * 0.5 - 230px)); bottom: calc(var(--art) * var(--visible) * 0.16); }
.glass-card__label { grid-column: 1; color: var(--muted); font-size: 13px; }
.glass-card__value { grid-column: 1; font-size: 17px; font-weight: 600; line-height: 1.3; }
.glass-card__icon { grid-column: 2; grid-row: 1 / span 2; width: 30px; height: 30px; border-radius: 50%; background: var(--ink); display: grid; place-items: center; }
.glass-card__icon svg { width: 18px; height: 18px; fill: none; stroke: #0b0f11; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ── Threads between sections ─────────────────────────────────────────── */
.thread { display: grid; place-items: center; height: 120px; }
.thread svg { width: 20px; height: 120px; overflow: visible; }
.thread path { fill: none; stroke: var(--line); stroke-width: 1.4; stroke-dasharray: 1; stroke-dashoffset: 0; vector-effect: non-scaling-stroke; }
.thread circle { fill: var(--bg); stroke: var(--violet); stroke-width: 1.4; }

/* ── Sections ──────────────────────────────────────────────────────────── */
.section { width: var(--page); margin: 0 auto; padding: 56px 0 72px; scroll-margin-top: 24px; }
.section--narrow { width: min(820px, 100% - 48px); }
.section__head { text-align: center; max-width: 640px; margin: 0 auto 48px; }
.eyebrow { color: var(--violet); font-size: 14px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; }
.section h2 { margin-top: 10px; font-size: clamp(32px, 4vw, 48px); line-height: 1.08; }
.section__lede { margin-top: 14px; color: var(--muted); font-size: 18px; }
/* The eyebrow repeats the heading for sighted scanning; screen readers hear the heading once. */
#how .eyebrow { display: none; }

.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; margin: 0; padding: 0; list-style: none; counter-reset: none; }
.step { position: relative; padding: 28px 26px 30px; border-radius: var(--radius); background: var(--bg-raised); border: 1px solid rgba(255, 255, 255, 0.06); }
.step__pose { width: 150px; height: 150px; margin: 0 auto 20px; }
.step__n { color: var(--violet); font-size: 14px; font-weight: 600; letter-spacing: .1em; }
.step h3 { margin-top: 6px; font-size: 22px; }
.step p { margin-top: 10px; color: var(--muted); }

.cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.card {
  padding: 28px; border-radius: var(--radius); background: var(--glass); border: 1px solid var(--glass-edge);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
}
.card__icon { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 12px; background: rgba(143, 125, 247, 0.14); border: 1px solid rgba(143, 125, 247, 0.30); }
.card__icon svg { width: 22px; height: 22px; fill: none; stroke: #cfc8ff; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.card h3 { margin-top: 18px; font-size: 20px; }
.card p { margin-top: 8px; color: var(--muted); }

.faq { border-top: 1px solid var(--glass-edge); }
.faq details { border-bottom: 1px solid var(--glass-edge); }
.faq summary {
  display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 22px 4px;
  cursor: pointer; list-style: none; font-size: 19px; font-weight: 500;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; flex: none; width: 14px; height: 14px; transition: rotate .25s ease;
  background: linear-gradient(var(--pale), var(--pale)) center / 14px 1.6px no-repeat, linear-gradient(var(--pale), var(--pale)) center / 1.6px 14px no-repeat;
}
.faq details[open] summary::after { rotate: 45deg; }
.faq details p { padding: 0 4px 22px; color: var(--muted); max-width: 44em; }

.closing { width: var(--page); margin: 24px auto 0; padding: 72px 24px; text-align: center; border-radius: 28px;
  background: radial-gradient(70% 90% at 50% 0%, rgba(143, 125, 247, 0.18), transparent 70%), var(--bg-raised);
  border: 1px solid rgba(255, 255, 255, 0.06); }
.closing h2 { font-size: clamp(30px, 4vw, 44px); }
.closing p { margin: 14px auto 0; color: var(--muted); max-width: 30em; }
.closing .pill--large { margin-top: 28px; }

.footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 20px; width: var(--page); margin: 72px auto 0; padding: 32px 0 48px; border-top: 1px solid rgba(255, 255, 255, 0.07); }
.footer img { height: 28px; width: auto; }
.footer__links { display: flex; flex-wrap: wrap; gap: 24px; }
.footer__links a { color: var(--pale); text-decoration: none; font-size: 15px; }
.footer__links a:hover { color: #fff; }
.footer__legal { color: var(--steel); font-size: 14px; }

/* ── Narrow screens ───────────────────────────────────────────────────── */
/* The cards need room beside the disc; below this they would sit on the Core itself. Both statements
   are repeated in full in the Safety section, so nothing is lost. */
@media (max-width: 1099px) { .glass-card { display: none; } }
@media (max-width: 900px) {
  .nav { grid-template-columns: 1fr auto; }
  .nav__links { display: none; }
  .steps { grid-template-columns: 1fr; max-width: 480px; margin: 0 auto; }
}
@media (max-width: 700px) {
  .cards { grid-template-columns: 1fr; }
  .hero__note li + li::before { display: none; }
  .hero__note { flex-direction: column; gap: 4px; }
}
@media (max-width: 480px) {
  .nav { gap: 12px; padding-top: 20px; }
  .nav__brand img { height: 28px; }
  .nav .pill--dark { display: none; }   /* sign-in remains in the footer */
  .pill { min-height: 42px; padding: 0 16px; font-size: 15px; }
  .section { padding-top: 32px; }
}

/* ── Motion ────────────────────────────────────────────────────────────────
   Everything below runs only for people who have not asked for reduced motion, so the base styles
   above are always the finished, static scene. Entrances use `backwards` fill: the final state is the
   element's own style and the keyframes only describe how it arrives. The Core is only ever moved,
   faded or softened (brand rule: never stretched, recoloured or warped). */

/* Brand rule: nothing moves while the page cannot be seen. */
.is-paused *, .is-paused *::before, .is-paused *::after { animation-play-state: paused !important; }

@media (prefers-reduced-motion: no-preference) {
  /* Sky */
  .hero__sky { animation: fade-in 1.6s ease-out backwards; }
  .stars--b { animation: twinkle 7s ease-in-out 1.6s infinite alternate; }
  .stars--c { animation: twinkle 11s ease-in-out 3s infinite alternate; }

  /* Headline, word by word, then the rest of the copy */
  .hero__title .w { animation: word-rise .9s cubic-bezier(.2, .7, .2, 1) backwards; animation-delay: calc(var(--i, 0) * 70ms + 80ms); }
  .hero__title .line:nth-child(1) .w:nth-child(1) { --i: 0; }
  .hero__title .line:nth-child(1) .w:nth-child(2) { --i: 1; }
  .hero__title .line:nth-child(1) .w:nth-child(3) { --i: 2; }
  .hero__title .line:nth-child(2) .w:nth-child(1) { --i: 3; }
  .hero__title .line:nth-child(2) .w:nth-child(2) { --i: 4; }
  .hero__title .line:nth-child(2) .w:nth-child(3) { --i: 5; }
  .hero__title .line:nth-child(2) .w:nth-child(4) { --i: 6; }
  .hero__title .line:nth-child(2) .w:nth-child(5) { --i: 7; }
  .hero__lede { animation: fade-up .9s cubic-bezier(.2, .7, .2, 1) .55s backwards; }
  .hero__copy .pill--large { animation: fade-up .9s cubic-bezier(.2, .7, .2, 1) .7s backwards; }
  .hero__note { animation: fade-in 1s ease-out .9s backwards; }

  /* The sketch draws itself: guides, then halo, then orbits, then the construction marks */
  #sketch .draw { animation: draw 1.2s cubic-bezier(.65, 0, .35, 1) backwards; }
  #sketch .d1 { animation-delay: .2s; }
  #sketch .d2 { animation-delay: .45s; }
  #sketch .d3 { animation-delay: .75s; animation-duration: 1.4s; }
  #sketch .d4 { animation-delay: 1s; animation-duration: 1.5s; }
  #sketch .d5 { animation-delay: 1.3s; animation-duration: .9s; }
  #sketch .notes { animation: fade-in .8s ease-out 1.7s backwards; }

  /* The glow gathers, then breathes */
  .glow { animation: fade-in 1.8s ease-out .2s backwards, breathe 9s ease-in-out 2s infinite alternate; }

  /* The real Core arrives into the sketch, then floats */
  #core { animation: core-arrive 1.2s cubic-bezier(.16, 1, .3, 1) 1.4s backwards, core-float 7s ease-in-out 2.6s infinite alternate; }

  /* Sparks pop onto their orbits one at a time, then travel them */
  .spark { animation: spark-arrive .7s cubic-bezier(.34, 1.56, .64, 1) backwards, orbit var(--period) linear infinite; }
  .spark[data-orbit="1"] { --period: 38s; }
  .spark[data-orbit="2"] { --period: 54s; }
  .spark[data-orbit="3"] { --period: 30s; }
  .spark--violet { animation-delay: 2.00s, 0s; }
  .spark--blue   { animation-delay: 2.11s, 0s; }
  .spark--gold   { animation-delay: 2.22s, 0s; }
  .spark--rose   { animation-delay: 2.33s, 0s; }
  .spark--green  { animation-delay: 2.44s, 0s; }
  .spark--orange { animation-delay: 2.55s, 0s; }
  .spark--red    { animation-delay: 2.66s, 0s; }

  /* Glass cards float in, then bob. `transform` animates so it composes with the pointer `translate`. */
  .glass-card { animation: card-in 1s cubic-bezier(.2, .7, .2, 1) backwards, bob 6s ease-in-out infinite alternate; }
  .glass-card--left { animation-delay: 2.4s, 3.4s; }
  .glass-card--right { animation-delay: 2.6s, 4.2s; animation-duration: 1s, 7s; }

  /* Below the fold: each section reveals once, and the threads between them draw themselves */
  .js [data-reveal]:not(.is-revealed) { opacity: 0; }
  .js [data-reveal].is-revealed { animation: reveal .9s cubic-bezier(.2, .7, .2, 1) backwards; }
  .js .steps [data-reveal]:nth-child(2).is-revealed, .js .cards [data-reveal]:nth-child(2).is-revealed { animation-delay: .1s; }
  .js .steps [data-reveal]:nth-child(3).is-revealed, .js .cards [data-reveal]:nth-child(3).is-revealed { animation-delay: .2s; }
  .js .cards [data-reveal]:nth-child(4).is-revealed { animation-delay: .3s; }
  .js .thread.is-revealed { animation: none; }
  .js .thread.is-revealed path { animation: draw 1.1s cubic-bezier(.65, 0, .35, 1) backwards; }
  .js .thread.is-revealed circle { animation: fade-in .5s ease-out .9s backwards; }

  .pill--light:hover { transform: translateY(-1px); }
}

@keyframes fade-in { from { opacity: 0; } }
@keyframes fade-up { from { opacity: 0; transform: translateY(14px); } }
@keyframes word-rise { from { opacity: 0; transform: translateY(.45em); filter: blur(6px); } }
@keyframes twinkle { to { opacity: .08; } }
@keyframes draw { from { stroke-dashoffset: 1; } }
@keyframes breathe { to { opacity: .72; transform: scale(1.05); } }
@keyframes core-arrive { from { opacity: 0; translate: 0 38px; filter: blur(14px); } to { opacity: 1; translate: 0 0; filter: blur(0); } }
@keyframes core-float { from { translate: 0 0; } to { translate: 0 -8px; } }
@keyframes spark-arrive { from { opacity: 0; scale: .2; } }
@keyframes orbit { from { offset-distance: var(--start); } to { offset-distance: calc(var(--start) + 100%); } }
@keyframes card-in { from { opacity: 0; transform: translateY(26px); } }
@keyframes bob { to { transform: translateY(-7px); } }
@keyframes reveal { from { opacity: 0; transform: translateY(22px); } }
