/* ASM motion for the public pages (home, about, game, news) and light reveals on the portal pages (Shop, Collections,
   Market, Inventory, Collectors; phase 2). SITE-UPGRADE, own code, no library.
   Motion is opt-in: html.motion-ok is set by the inline gate in <head> only when the visitor allows it (no
   prefers-reduced-motion, no Save-Data). Without it every element is in its final state. Only transform and opacity
   animate; reveals use CSS scroll-driven animations where the browser has them, else motion.js adds `.in`. */

:root { --ease-out: cubic-bezier(.16, 1, .3, 1); --display: 'Oswald', 'Arial Narrow', Impact, sans-serif; }

@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }
.site-header .brand-mark { view-transition-name: asm-brand; }
::view-transition-group(root) { animation-duration: .42s; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .42s; animation-timing-function: cubic-bezier(.16, 1, .3, 1); }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.chip { display: inline-flex; align-items: center; gap: 7px; min-height: 26px; padding: 0 11px; border: 1px solid var(--line-strong); border-radius: 999px; color: var(--ink-secondary); font: 600 10px/1 'Inter', sans-serif; letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; background: rgba(8, 9, 10, .55); }
.chip i { width: 6px; height: 6px; border-radius: 50%; background: var(--muted); flex: none; }
.chip[data-state="live"] i { background: var(--rarity-uncommon); box-shadow: 0 0 8px var(--rarity-uncommon); }
.chip[data-state="game"] i { background: var(--game-accent); box-shadow: 0 0 8px var(--game-accent); }
.chip[data-state="game"] { border-color: var(--game-accent-line); color: #e8e8e6; }
.chip[data-state="soon"] i { background: var(--rarity-legendary); }
.chip[data-state="hold"] i { background: var(--rarity-mythic); }
.chip[hidden] { display: none; }

/* Numbers that count up keep the width of their final text (motion.js sets min-width), so nothing moves. */
:is([data-fact], [data-odds-for]):not([data-fact="special"]) { display: inline-block; font-variant-numeric: tabular-nums; }
.display { font-family: var(--display); font-weight: 600; letter-spacing: .005em; line-height: .95; text-transform: uppercase; }

@keyframes asm-rise { from { opacity: 0; translate: 0 26px; } to { opacity: 1; translate: none; } }
@keyframes asm-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes asm-swing { from { opacity: 0; rotate: -3deg; translate: 0 -10px; } to { opacity: 1; rotate: none; translate: none; } }
html.motion-ok .reveal,
html.motion-ok :is(.about-section, .news-item, .game-page .news-section, .home-news .story-card, .home-spot .story-card) {
  animation: asm-rise linear both; animation-timeline: view(); animation-range: entry 0% entry 65%;
}
html.motion-ok .reveal-fade { animation: asm-fade linear both; animation-timeline: view(); animation-range: entry 0% entry 60%; }
html.motion-ok .reveal-swing { transform-origin: 50% 0; animation: asm-swing linear both; animation-timeline: view(); animation-range: entry 0% entry 70%; }
@supports not (animation-timeline: view()) {
  html.motion-ok :is(.reveal, .reveal-fade, .reveal-swing),
  html.motion-ok :is(.about-section, .news-item, .game-page .news-section, .home-news .story-card, .home-spot .story-card) { animation: none; }
  html.motion-io .reveal:not(.in) { opacity: 0; translate: 0 26px; }
  html.motion-io .reveal-fade:not(.in) { opacity: 0; }
  html.motion-io .reveal-swing:not(.in) { opacity: 0; rotate: -3deg; translate: 0 -10px; transform-origin: 50% 0; }
  html.motion-io :is(.reveal, .reveal-fade, .reveal-swing) { transition: opacity .7s var(--ease-out), translate .7s var(--ease-out), rotate .7s var(--ease-out); }
}

@media (hover: hover) and (pointer: fine) {
  html.motion-ok :is(.home-news .story-card, .home-spot .story-card, .news-card) { transition: transform .35s var(--ease-out); }
  html.motion-ok :is(.home-news .story-card, .home-spot .story-card, .news-card):hover { transform: translateY(-4px); }
}

@keyframes asm-menu-in { from { opacity: 0; transform: translateX(-18px); } to { opacity: 1; transform: none; } }
html.motion-ok .menu-dialog[open] nav a { animation: asm-menu-in .5s var(--ease-out) both; }
html.motion-ok .menu-dialog[open] nav a:nth-child(2) { animation-delay: .03s; }
html.motion-ok .menu-dialog[open] nav a:nth-child(3) { animation-delay: .06s; }
html.motion-ok .menu-dialog[open] nav a:nth-child(4) { animation-delay: .09s; }
html.motion-ok .menu-dialog[open] nav a:nth-child(5) { animation-delay: .12s; }
html.motion-ok .menu-dialog[open] nav a:nth-child(6) { animation-delay: .15s; }
html.motion-ok .menu-dialog[open] nav a:nth-child(7) { animation-delay: .18s; }
html.motion-ok .menu-dialog[open] nav a:nth-child(8) { animation-delay: .21s; }
html.motion-ok .menu-dialog[open] nav a:nth-child(9) { animation-delay: .24s; }
html.motion-ok .menu-dialog[open] nav a:nth-child(n+10) { animation-delay: .27s; }
html.motion-ok .menu-dialog[open] .menu-extra { animation: asm-fade .5s var(--ease-out) .3s both; }

/* Portal pages: headings and cards rise in as they scroll into view. Their cards are drawn by script, so these are
   scroll-driven only (no IntersectionObserver pass); a browser without view() timelines simply shows them. Skeletons
   never animate, and the layout is untouched: only opacity and translate move. */
@keyframes asm-card-in { from { opacity: 0; translate: 0 18px; } to { opacity: 1; translate: none; } }
@supports (animation-timeline: view()) {
  html.motion-ok :is(
    body[data-page="shop"] :is(.shop-section-heading, .shop-explainer > *, .shop-collection-head, .crate-trial-strip, .crate-release-note),
    body[data-page="collections"] :is(.portal-title, .items-header, .collections-grid > .collection-card, .items-grid > .asset-card),
    body[data-page="market"] :is(.market-section-head, .market-grid > .market-card:not(.is-skeleton), .market-partner-card),
    body[data-page="inventory"] :is(.inv-section-head, .inv-grid > .inv-tile, .crate-owned-card),
    body[data-page="collectors"] :is(.collector-grid > .collector-card:not(.collector-card-skeleton))
  ) { animation: asm-card-in linear both; animation-timeline: view(); animation-range: entry 0% entry 60%; }
}

html.reduce-motion :is(.hero-offline, .manifesto, .story, .index, .image-cta, .game-landing, .game-page, .about-section, .news-page) *,
html.reduce-motion :is(.hero-offline, .manifesto, .story, .index, .image-cta, .game-landing, .game-page, .about-section, .news-page) *::before,
html.reduce-motion :is(.hero-offline, .manifesto, .story, .index, .image-cta, .game-landing, .game-page, .about-section, .news-page) *::after { transition: none !important; }
