/* ============================================================
   PMill motion layer
   Principles (borrowed from transitions.dev):
   - Motion tokens, never hard-coded durations.
   - Transition named properties only (never `all`).
   - Enter is slower than exit; exits are quick and never bounce.
   - Every recipe has a reduced-motion guard.
   Loaded after main.css; safe to override component transitions.
   ============================================================ */

:root {
    --duration-instant: 90ms;
    --duration-quick: 150ms;
    --duration-base: 250ms;
    --duration-slow: 400ms;
    --duration-reveal: 520ms;

    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-in: cubic-bezier(0.4, 0, 1, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
    --ease-spring: cubic-bezier(0.34, 1.45, 0.64, 1);
    --ease-soft-spring: cubic-bezier(0.22, 1.2, 0.36, 1);

    --stagger: 45ms;
    --reveal-distance: 10px;
    --pop-distance: 8px;
    --pop-blur: 2px;

    /* Retune the legacy tokens so every existing `var(--transition-*)`
       picks up the new easing without touching each rule. */
    --transition-fast: var(--duration-quick) var(--ease-out);
    --transition-base: var(--duration-base) var(--ease-out);
    --transition-slow: var(--duration-slow) var(--ease-out);
}

/* ------------------------------------------------------------
   1. Base interaction polish (named properties, quick timings)
   ------------------------------------------------------------ */
a,
button,
.btn,
.card,
.nav-link,
.sidebar-item,
.sport-chip,
.status-filter-btn,
.period-btn-compact,
.sort-btn,
.filter-btn,
.feed-tab,
.game-card,
.pick-card,
.home-card,
.home-pick,
.home-ticket,
.home-board,
.group-card,
.activity-card,
.lp-pillar,
.lp-sport,
.lp-ticket {
    transition-property: color, background-color, border-color, box-shadow, transform, opacity;
    transition-duration: var(--duration-quick);
    transition-timing-function: var(--ease-out);
}

/* Pressed state: a tiny scale-down reads as "acknowledged". */
.btn:active,
.nav-link:active,
.sport-chip:active,
.status-filter-btn:active,
.period-btn-compact:active,
.sort-btn:active,
.feed-tab:active,
.home-btn:active,
.lp-btn-primary:active,
.lp-btn-ghost:active {
    transform: scale(0.97);
    transition-duration: var(--duration-instant);
}

/* Cards lift on hover, settle quickly on leave. */
.game-card:hover,
.home-pick:hover,
.home-ticket:hover,
.group-card:hover,
.lp-ticket:hover {
    transform: translateY(-2px);
}

/* Focus rings animate in rather than snapping. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: none;
    box-shadow: var(--focus-ring, 0 0 0 3px rgba(46, 160, 67, 0.35));
    transition: box-shadow var(--duration-quick) var(--ease-out);
}

/* ------------------------------------------------------------
   2. Overlays: dropdowns, menus, trays, modals, drawers
   Enter: scale from an origin. Exit: quicker, smaller scale delta.
   ------------------------------------------------------------ */

/* Profile dropdown (navbar) */
.profile-menu {
    transform-origin: top right;
    transform: translateY(-4px) scale(0.97);
    opacity: 0;
    visibility: hidden;
    transition:
        transform var(--duration-quick) var(--ease-out),
        opacity var(--duration-quick) var(--ease-out),
        visibility 0s linear var(--duration-quick);
    will-change: transform, opacity;
}

.profile-dropdown.open .profile-menu {
    transform: translateY(0) scale(1);
    opacity: 1;
    visibility: visible;
    transition:
        transform var(--duration-base) var(--ease-out),
        opacity var(--duration-base) var(--ease-out),
        visibility 0s;
}

.profile-menu .profile-menu-item {
    transition: background-color var(--duration-quick) var(--ease-out), color var(--duration-quick) var(--ease-out);
}

/* Mobile nav sheet */
.nav-menu-panel {
    transform-origin: top center;
    opacity: 0;
    transform: translateY(-6px);
    transition:
        max-height var(--duration-base) var(--ease-out),
        opacity var(--duration-quick) var(--ease-out),
        transform var(--duration-quick) var(--ease-out);
}

.nav-menu-panel.open {
    opacity: 1;
    transform: translateY(0);
    transition:
        max-height var(--duration-slow) var(--ease-out),
        opacity var(--duration-base) var(--ease-out),
        transform var(--duration-base) var(--ease-out);
}

.nav-menu-panel .nav-menu-item {
    opacity: 0;
    transform: translateY(6px);
    transition:
        opacity var(--duration-base) var(--ease-out),
        transform var(--duration-base) var(--ease-out),
        background-color var(--duration-quick) var(--ease-out),
        border-color var(--duration-quick) var(--ease-out),
        color var(--duration-quick) var(--ease-out);
}

.nav-menu-panel.open .nav-menu-item {
    opacity: 1;
    transform: translateY(0);
}

.nav-menu-panel.open .nav-menu-item:nth-child(1) { transition-delay: calc(var(--stagger) * 0.5); }
.nav-menu-panel.open .nav-menu-item:nth-child(2) { transition-delay: calc(var(--stagger) * 1); }
.nav-menu-panel.open .nav-menu-item:nth-child(3) { transition-delay: calc(var(--stagger) * 1.5); }
.nav-menu-panel.open .nav-menu-item:nth-child(4) { transition-delay: calc(var(--stagger) * 2); }
.nav-menu-panel.open .nav-menu-item:nth-child(5) { transition-delay: calc(var(--stagger) * 2.5); }
.nav-menu-panel.open .nav-menu-item:nth-child(6) { transition-delay: calc(var(--stagger) * 3); }
.nav-menu-panel.open .nav-menu-item:nth-child(7) { transition-delay: calc(var(--stagger) * 3.5); }
.nav-menu-panel.open .nav-menu-item:nth-child(8) { transition-delay: calc(var(--stagger) * 4); }
.nav-menu-panel.open .nav-menu-item:nth-child(9) { transition-delay: calc(var(--stagger) * 4.5); }
.nav-menu-panel.open .nav-menu-item:nth-child(n + 10) { transition-delay: calc(var(--stagger) * 5); }

.nav-menu-backdrop {
    opacity: 0;
    transition: opacity var(--duration-base) var(--ease-out);
}

.nav-menu-backdrop.open { opacity: 1; }

/* Bet slip drawer */
.bet-slip {
    transition: transform var(--duration-slow) var(--ease-out), box-shadow var(--duration-slow) var(--ease-out);
    will-change: transform;
}

.bet-slip.open { box-shadow: -16px 0 48px rgba(0, 0, 0, 0.45); }

/* Search palette */
.search-overlay.open .search-modal {
    animation: m-modal-in var(--duration-base) var(--ease-out) both;
}

@keyframes m-modal-in {
    from { opacity: 0; transform: translateY(-6px) scale(0.97); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

/* Generic modal recipe: add .m-modal to any dialog box, toggle
   .is-open / .is-closing on it. Works with existing display toggles
   because it only animates transform + opacity. */
.m-modal {
    transform-origin: center;
    transform: scale(0.96);
    opacity: 0;
    transition:
        transform var(--duration-base) var(--ease-out),
        opacity var(--duration-base) var(--ease-out);
    will-change: transform, opacity;
}

.m-modal.is-open { transform: scale(1); opacity: 1; }

.m-modal.is-closing {
    transform: scale(0.98);
    opacity: 0;
    transition:
        transform var(--duration-quick) var(--ease-in),
        opacity var(--duration-quick) var(--ease-in);
}

/* Any element that is shown by setting display:block/flex from JS can
   opt into an enter animation with .m-enter (one shot). */
.m-enter { animation: m-enter var(--duration-base) var(--ease-out) both; }

@keyframes m-enter {
    from { opacity: 0; transform: translateY(6px) scale(0.985); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

/* ------------------------------------------------------------
   3. Toasts: spring in, quick fade out
   ------------------------------------------------------------ */
.toast {
    animation: m-toast-in var(--duration-slow) var(--ease-soft-spring) both;
    transition: opacity var(--duration-quick) var(--ease-in), transform var(--duration-quick) var(--ease-in);
}

.toast.toast-out,
.toast.is-closing {
    opacity: 0;
    transform: translateY(8px) scale(0.98);
}

@keyframes m-toast-in {
    from { opacity: 0; transform: translateY(14px) scale(0.96); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

/* ------------------------------------------------------------
   4. Badges: diagonal slide + spring pop when they appear/update
   ------------------------------------------------------------ */
.dm-badge,
.nav-menu-badge,
.notification-badge,
.notif-badge,
.bet-slip-toggle-count,
.m-badge-pop {
    animation: m-badge-pop var(--duration-slow) var(--ease-spring) both;
    transform-origin: bottom left;
}

@keyframes m-badge-pop {
    0% { opacity: 0; transform: translate(-4px, 4px) scale(0.6); }
    60% { opacity: 1; }
    100% { opacity: 1; transform: translate(0, 0) scale(1); }
}

/* ------------------------------------------------------------
   5. Numbers: digit pop-in with blur when a value lands/changes
   Apply .m-pop (re-added by motion.js on change).
   ------------------------------------------------------------ */
.m-pop {
    display: inline-block;
    animation: m-pop-in var(--duration-reveal) var(--ease-spring) both;
    will-change: transform, opacity, filter;
}

@keyframes m-pop-in {
    0% { opacity: 0; transform: translateY(var(--pop-distance)); filter: blur(var(--pop-blur)); }
    100% { opacity: 1; transform: translateY(0); filter: blur(0); }
}

/* Live score ticks: green/red flash that fades. */
.m-tick-up { animation: m-tick-up var(--duration-slow) var(--ease-out) both; }
.m-tick-down { animation: m-tick-down var(--duration-slow) var(--ease-out) both; }

@keyframes m-tick-up {
    0% { color: var(--success); transform: translateY(-2px); }
    100% { color: inherit; transform: translateY(0); }
}

@keyframes m-tick-down {
    0% { color: var(--error); transform: translateY(2px); }
    100% { color: inherit; transform: translateY(0); }
}

/* ------------------------------------------------------------
   6. Reveal: staggered entrance for lists and card grids.
   motion.js sets --i on each child and adds .m-reveal-item.
   ------------------------------------------------------------ */
.m-reveal-item {
    animation: m-reveal var(--duration-reveal) var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * var(--stagger));
}

@keyframes m-reveal {
    from { opacity: 0; transform: translateY(var(--reveal-distance)); }
    to { opacity: 1; transform: translateY(0); }
}

/* Skeleton → content: content fades in on top of the shimmer. */
.m-skeleton-swap > * { animation: m-fade-in var(--duration-base) var(--ease-out) both; }

@keyframes m-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* ------------------------------------------------------------
   7. Sliding pill tabs (segmented controls)
   motion.js injects .m-tabs-pill into containers it manages and
   writes transform/width inline so the pill glides to the active tab.
   ------------------------------------------------------------ */
.m-tabs { position: relative; isolation: isolate; }
.m-tabs > * { position: relative; z-index: 1; }

.m-tabs .m-tabs-pill {
    position: absolute;
    top: 0;
    left: 0;
    height: 0;
    width: 0;
    border-radius: inherit;
    background: var(--m-tabs-pill-bg, var(--bg-elevated));
    box-shadow: var(--m-tabs-pill-shadow, 0 1px 2px rgba(0, 0, 0, 0.4), inset 0 0 0 1px rgba(255, 255, 255, 0.06));
    transform: translate(0, 0);
    transition:
        transform var(--duration-base) var(--ease-out),
        width var(--duration-base) var(--ease-out),
        height var(--duration-base) var(--ease-out);
    will-change: transform, width;
    z-index: 0;
    pointer-events: none;
}

[data-theme="light"] .m-tabs .m-tabs-pill {
    --m-tabs-pill-bg: #fff;
    --m-tabs-pill-shadow: 0 1px 2px rgba(15, 23, 42, 0.12);
}

/* When the pill is active, the active tab's own background steps
   aside so the pill is the only highlight. */
.m-tabs.m-tabs--ready > .active,
.m-tabs.m-tabs--ready > [aria-selected="true"] {
    background: transparent !important;
    box-shadow: none !important;
}

/* Green variant used by filter chips on PMill / feed tabs. */
.m-tabs--accent .m-tabs-pill {
    --m-tabs-pill-bg: rgba(46, 160, 67, 0.14);
    --m-tabs-pill-shadow: inset 0 0 0 1px rgba(46, 160, 67, 0.35);
}

/* ------------------------------------------------------------
   8. Text state swap (e.g. "Follow" → "Following", "Copied")
   ------------------------------------------------------------ */
.m-swap { animation: m-swap var(--duration-base) var(--ease-out) both; }

@keyframes m-swap {
    0% { opacity: 0; transform: translateY(-4px); filter: blur(1px); }
    100% { opacity: 1; transform: translateY(0); filter: blur(0); }
}

/* Success check draw-in for confirmations. */
.m-check path { stroke-dasharray: 32; stroke-dashoffset: 32; animation: m-check var(--duration-slow) var(--ease-out) forwards; }

@keyframes m-check { to { stroke-dashoffset: 0; } }

/* Shake for errors (e.g. invalid bet amount). */
.m-shake { animation: m-shake var(--duration-slow) var(--ease-out) both; }

@keyframes m-shake {
    10%, 90% { transform: translateX(-1px); }
    20%, 80% { transform: translateX(2px); }
    30%, 50%, 70% { transform: translateX(-3px); }
    40%, 60% { transform: translateX(3px); }
}

/* ------------------------------------------------------------
   9. Reduced motion: keep state changes, drop the choreography.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    .m-tabs .m-tabs-pill { transition: none !important; }
    .m-reveal-item, .m-pop, .toast, .m-badge-pop { animation: none !important; opacity: 1 !important; transform: none !important; filter: none !important; }
}
