/* ════════════════════════════════════════════════════════════════
 *  MOTION SYSTEM — shared timing/easing tokens + global micro-interactions
 *
 *  Loaded AFTER hayya-theme.css (so it can refine the active theme's
 *  interactive surfaces) and BEFORE _mobile-perf.css (so the global
 *  prefers-reduced-motion + backdrop-filter neutralizers still win).
 *
 *  One source of truth for "how motion feels" across the whole site:
 *  every transition/animation references the same duration + easing
 *  vars so the UI reads as one cohesive product, not a pile of one-off
 *  effects. Decorative motion is auto-disabled by the reduced-motion
 *  guard in _mobile-perf.css; the functional bits here (press feedback,
 *  focus rings) stay instant-but-present under that guard, which is the
 *  correct accessible behaviour.
 * ════════════════════════════════════════════════════════════════ */

:root {
  /* Easing — ease-out for entering/hover (confident decelerate),
     ease-in for exiting, spring for tactile release overshoot. */
  --mo-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --mo-ease-in: cubic-bezier(0.55, 0.06, 0.68, 0.19);
  --mo-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Duration scale — micro-interactions stay 140-340ms (skill rule:
     150-300ms for micro, <=400ms for transitions). */
  --mo-dur-fast: 140ms;
  --mo-dur-base: 220ms;
  --mo-dur-slow: 340ms;
}

/* Native-anchor smooth scroll (rules-page toc chips, in-page jumps).
   The reduced-motion guard flips this back to `auto` automatically. */
html { scroll-behavior: smooth; }

/* ── Unify the transition feel across every interactive surface ──
   These all already animate on hover (translateY lifts) but with
   mixed `.2s ease` / `.25s ease` shorthands. Restating one cohesive
   transition over the props they actually animate (transform, shadow,
   border, background, colour, opacity) makes hover + the new press
   states below read with one rhythm. transform runs on the fast token
   so a tap/hover feels snappy; the chrome (shadow/border) settles on
   the base token. */
.btn,
.play-card, .play-go, .play-go span,
.feature-card, .ornate-card,
.store-card, .store-card-action, .store-tab,
.lb-row, .lb-tab,
.swatch, .cardback-swatch,
.chip, .toc-chip,
.nav-tab, .nav-toggle, .nav-brand, .nav-bell, .nav-profile-circle {
  transition:
    transform var(--mo-dur-fast) var(--mo-ease-out),
    box-shadow var(--mo-dur-base) var(--mo-ease-out),
    border-color var(--mo-dur-base) var(--mo-ease-out),
    background-color var(--mo-dur-base) var(--mo-ease-out),
    color var(--mo-dur-base) var(--mo-ease-out),
    opacity var(--mo-dur-base) var(--mo-ease-out);
}

/* ── Press feedback (the single biggest "feels alive" win) ──
   Tactile scale-in on activation. Selectors match (or exceed) the
   specificity of the existing :hover transforms so the press wins
   while pointer-down (hover + active both true → later rule wins). */

/* Buttons press IN (counteracts the hover lift → reads as physical). */
.btn:active,
.btn.btn-primary:active, .btn.btn-ghost:active,
.btn.btn-secondary:active, .btn.btn-danger:active,
.btn-primary:active, .btn-secondary:active, .btn-danger:active,
.store-card-action:active:not(:disabled),
.link-btn:active, .msg-send-btn:active {
  transform: translateY(0) scale(0.95);
}

/* Whole-card link surfaces press subtly (large area → tiny scale). */
.play-card:active,
.feature-card:active, .ornate-card:active {
  transform: translateY(0) scale(0.99);
}

/* Small pickable tiles + chips press a touch harder. */
.swatch:active, .cardback-swatch:active {
  transform: scale(0.93);
}
.chip:active, .toc-chip:active,
.lb-tab:active, .store-tab:active {
  transform: scale(0.95);
}

/* Icon/circle nav controls scale; text nav links dim (scaling a
   full-width drawer row looks wrong, opacity reads cleaner). */
.nav-toggle:active, .nav-brand:active,
.nav-bell:active, .nav-profile-circle:active {
  transform: scale(0.92);
}
.nav-tab:active { opacity: 0.6; }

/* ── Touch devices: kill sticky hover lifts ──
   These surfaces lift on :hover with no pointer guard, so on a phone
   the lift gets stuck after a tap until the user touches elsewhere.
   On coarse pointers we neutralize the hover transform (the :active
   press above is the real touch feedback). Specificity matches the
   theme's hover rules; loaded later → wins. */
@media (hover: none) {
  .btn-primary:hover, .btn-ghost:hover,
  .btn.btn-primary:hover, .btn.btn-ghost:hover,
  .play-card:hover, .feature-card:hover, .ornate-card:hover,
  .store-card:hover,
  .swatch:hover, .cardback-swatch:hover {
    transform: none;
  }
  .play-card:hover .play-go span,
  .feature-card:hover .feature-arrow {
    transform: none;
  }
}

/* ── Keyboard focus ring (a11y, severity High) ──
   One consistent gold ring on every interactive control, keyboard-only
   (:focus-visible) so mouse/touch activation stays clean. `outline`
   never triggers layout, so it's safe on animated surfaces. Raw form
   fields are intentionally excluded — auth/settings inputs own their
   focus styling (e.g. .swatch:focus-within) and some are visually
   hidden radios where an outline would render in the wrong place. */
.btn:focus-visible,
.play-card:focus-visible, .feature-card:focus-visible, .ornate-card:focus-visible,
.store-card-action:focus-visible, .store-tab:focus-visible,
.lb-tab:focus-visible, .lb-row:focus-visible,
.swatch:focus-visible, .cardback-swatch:focus-visible,
.chip:focus-visible, .toc-chip:focus-visible,
.nav-tab:focus-visible, .nav-toggle:focus-visible, .nav-brand:focus-visible,
.nav-bell:focus-visible, .nav-profile-circle:focus-visible,
a:focus-visible, button:focus-visible,
[role="button"]:focus-visible, summary:focus-visible {
  outline: 2px solid var(--gold-bright, #ffd700);
  outline-offset: 2px;
}

/* ── Mobile nav drawer: slide the menu in instead of a hard snap ──
   The drawer toggles display:none → flex (untransitionable), so a
   one-shot keyframe on .open is the way to animate its appearance.
   Scoped to the mobile width + the .open state, so the always-open
   desktop nav and the closed drawer are untouched. Reduced-motion
   zeroes the duration → instant. */
@media (max-width: 760px) {
  .screens-nav.open .nav-tabs {
    animation: mo-drawer-in var(--mo-dur-base) var(--mo-ease-out) both;
  }
}
@keyframes mo-drawer-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ════════════════════════════════════════════════════════════════
 *  PAGE TRANSITIONS — soft enter on load + fade-out on same-origin nav
 *
 *  The enter animation is gated by `.mo-anim`, which the inline head
 *  script in base.html adds BEFORE first paint — so there's no
 *  flash-of-visible-then-hidden, and with JS off nothing is ever
 *  hidden. Only the page CONTENT (<main>) animates; the nav + footer
 *  are siblings of <main>, so they stay put and the content rises into
 *  a stable frame.
 *
 *  Content pages get a transform rise. The game / matchmaking / lobby
 *  scenes carry fixed-positioned descendants (forfeit X, deck, banners)
 *  + their own cinematics, so they get `.mo-flat` → an opacity-only
 *  fade, because a transform on <main> would reparent a fixed child's
 *  containing block and make it jump. Reduced-motion: the inline script
 *  never adds the class, so this whole block stays inert.
 * ════════════════════════════════════════════════════════════════ */
html.mo-anim main {
  animation: mo-page-rise var(--mo-dur-slow) var(--mo-ease-out) both;
}
html.mo-anim.mo-flat main {
  animation-name: mo-page-fade; /* opacity only — safe over fixed descendants */
}
@keyframes mo-page-rise {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}
@keyframes mo-page-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Fade the leaving page out just before the browser navigates, so a
   same-origin click reads as a crossfade into the next page's enter
   animation. motion.js adds `.mo-leaving` then navigates on transitionend
   with a hard failsafe, so navigation can never hang. */
html.mo-leaving body {
  opacity: 0;
  transition: opacity var(--mo-dur-fast) var(--mo-ease-in);
}

/* ════════════════════════════════════════════════════════════════
 *  PER-SURFACE STAGGER — hero text, cards, and rows pop in sequence
 *
 *  A container marked [data-mo-stagger] reveals its direct children one
 *  after another (the home hero, the play cards, leaderboard rows, the
 *  auth CTAs). `:has()` keys <main> off the marker's presence so the
 *  page frame fades (no transform) while the children own the rise — no
 *  per-route bookkeeping, the marker IS the switch. Browsers without
 *  :has() fall back to <main> rising AND children staggering (still
 *  correct, just layered). Reuses the mo-page-rise keyframe. Gated by
 *  .mo-anim (set before first paint), so with JS off / reduced-motion
 *  nothing is ever hidden. Works for JS-inserted children too (the
 *  animation fires on insertion — e.g. leaderboard rows). */
html.mo-anim main:has([data-mo-stagger]) { animation-name: mo-page-fade; }
html.mo-anim [data-mo-stagger] > * {
  animation: mo-page-rise var(--mo-dur-slow) var(--mo-ease-out) both;
}
html.mo-anim [data-mo-stagger] > *:nth-child(1) { animation-delay: 60ms; }
html.mo-anim [data-mo-stagger] > *:nth-child(2) { animation-delay: 110ms; }
html.mo-anim [data-mo-stagger] > *:nth-child(3) { animation-delay: 160ms; }
html.mo-anim [data-mo-stagger] > *:nth-child(4) { animation-delay: 210ms; }
html.mo-anim [data-mo-stagger] > *:nth-child(5) { animation-delay: 260ms; }
html.mo-anim [data-mo-stagger] > *:nth-child(6) { animation-delay: 310ms; }
html.mo-anim [data-mo-stagger] > *:nth-child(n+7) { animation-delay: 360ms; }

/* ════════════════════════════════════════════════════════════════
 *  PRESS PARITY — the chrome controls Phase 1 didn't enumerate
 *
 *  The matchmaking accept/decline/cancel buttons already carry their
 *  own :active in the owner-approved radar design, and the gold focus
 *  ring already reaches every <button>/<a> via the :focus-visible rule
 *  above — so matchmaking is covered without touching its cinematic.
 *  The game's scopa/hayya/dinari/car cinematics and the matchmaking
 *  radar/VS handoff are DELIBERATELY untouched (approved design +
 *  documented fragility). This block only adds transform-only press to
 *  the leftover non-fragile chrome buttons/links so every tappable
 *  control feels alive consistently. transform-only → no layout reflow.
 * ════════════════════════════════════════════════════════════════ */
.mm-promo-cta, .mm-promo-close,
.notif-panel-close, .notif-panel-readall, .notif-panel-link,
.eye-toggle {
  transition: transform var(--mo-dur-fast) var(--mo-ease-out);
}
.mm-promo-cta:active, .notif-panel-readall:active,
.notif-panel-link:active { transform: scale(0.96); }
.mm-promo-close:active, .notif-panel-close:active,
.eye-toggle:active { transform: scale(0.9); }
