/*
 * INSTATuner Action System
 * ========================
 *
 * Single source of truth for every interactive element's loading / disabled /
 * focus / hover / active behaviour. Every button, link, form submit, file
 * upload, and Livewire action inherits from these primitives so the UX is
 * uniform across all 5 surfaces (dashboard, editor, dyno, compare, library)
 * without each page reinventing it.
 *
 * Contracts:
 *
 *   1. Any element with `wire:loading` automatically receives a spinner +
 *      disabled-cursor + pointer-events:none while the matching action is
 *      pending. No manual markup needed in blades.
 *
 *   2. Any `<button>`, `<a.btn>`, or `[role=button]` shows cursor-pointer,
 *      visible focus ring, smooth hover, pressed state, and disabled state
 *      automatically.
 *
 *   3. Any element with `.skeleton` or `[data-skeleton]` gets the shimmer
 *      pulse. Containers can use `.skeleton-stack` to render N rows.
 *
 *   4. Page transitions: Livewire's wire:navigate fires
 *      `livewire:navigating` / `livewire:navigated` events; we surface them
 *      as a top-of-viewport progress bar via `.page-progress`.
 *
 *   5. Toasts: `.toast-stack` is the singleton mount point; toasts are added
 *      via the global `window.toast` helper (defined in action-system.js).
 *
 * Reduced motion: every animation respects `@media (prefers-reduced-motion)`.
 */

/* ============================================================
   1. Universal interactive baseline
   ============================================================ */
button,
a.btn, .btn,
[role="button"],
[wire\:click],
[x-on\:click],
[\@click] {
    cursor: pointer;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    transition: opacity 180ms ease, transform 180ms ease,
                background-color 180ms ease, border-color 180ms ease,
                color 180ms ease, box-shadow 180ms ease;
}

button:focus-visible,
a:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: 2px solid rgb(var(--accent, 255 106 0));
    outline-offset: 2px;
    border-radius: var(--r-default, 6px);
}

button:disabled,
.btn:disabled,
.btn.is-loading,
[disabled],
[aria-disabled="true"] {
    cursor: not-allowed !important;
    opacity: 0.55;
    pointer-events: auto;
}

button:disabled:hover,
.btn:disabled:hover { transform: none !important; }

/* ============================================================
   2. Spinner -- 3 sizes, single SVG-free implementation
   ============================================================ */
.spinner,
.spinner-sm,
.spinner-lg {
    display: inline-block;
    width: 14px; height: 14px;
    border: 2px solid currentColor;
    border-bottom-color: transparent;
    border-radius: 50%;
    animation: ax-spin 0.8s linear infinite;
    vertical-align: -2px;
    flex-shrink: 0;
}
.spinner-sm { width: 10px; height: 10px; border-width: 1.5px; }
.spinner-lg { width: 22px; height: 22px; border-width: 2.5px; }

@keyframes ax-spin { to { transform: rotate(360deg); } }

/* ============================================================
   3. Wire:loading blanket -- covers EVERY Livewire button without
      requiring per-blade <span wire:loading> markup
   ============================================================ */

/* Default: any [wire:loading] element is hidden until the action
   it targets is in flight. Livewire flips this. */
[wire\:loading],
[wire\:loading\.delay],
[wire\:loading\.delay\.shortest],
[wire\:loading\.delay\.shorter],
[wire\:loading\.delay\.short],
[wire\:loading\.delay\.long],
[wire\:loading\.delay\.longer],
[wire\:loading\.delay\.longest] {
    display: none;
}

/* When loading: the targeted button itself dims + shows cursor:wait */
button[wire\:loading\.attr="disabled"],
button[wire\:loading\.class\.add],
.btn[wire\:loading\.attr="disabled"] {
    /* style hooks consumed by Livewire's runtime */
}

/* When ANY action fires (Livewire flips a `data-loading` attr on the
   element OR adds `is-loading`), give the button a spinner suffix
   regardless of whether the blade author wrote one. */
.is-loading {
    position: relative;
    color: transparent !important;
    pointer-events: none;
}
.is-loading::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    width: 14px; height: 14px;
    margin-top: -7px; margin-left: -7px;
    border: 2px solid currentColor;
    border-bottom-color: transparent;
    border-radius: 50%;
    color: rgb(var(--text-primary, 240 240 245));
    animation: ax-spin 0.8s linear infinite;
}
.btn--primary.is-loading::after { color: #fff; }

/* Inline spinner that lives BEFORE button text -- explicit markup */
.btn-spin-inline {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

/* ============================================================
   4. Skeleton + shimmer
   ============================================================ */
.skeleton,
[data-skeleton] {
    position: relative;
    overflow: hidden;
    background: rgb(var(--bg-surface-2, 27 27 38) / 0.45);
    border-radius: var(--r-default, 6px);
    color: transparent !important;
    user-select: none;
    pointer-events: none;
}
.skeleton::after,
[data-skeleton]::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(
        90deg,
        transparent,
        rgb(var(--text-primary, 240 240 245) / 0.06),
        transparent
    );
    animation: ax-shimmer 1.4s ease-in-out infinite;
}
@keyframes ax-shimmer {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(100%); }
}

.skeleton-row { height: 14px; margin-bottom: 8px; border-radius: 4px; }
.skeleton-row--lg { height: 20px; }
.skeleton-row--sm { height: 10px; }
.skeleton-card { height: 132px; border-radius: var(--r-default); }
.skeleton-circle { width: 32px; height: 32px; border-radius: 50%; }

.skeleton-stack > * + * { margin-top: 10px; }

/* ============================================================
   5. Top-of-viewport page progress bar
   Driven by Livewire navigation events + form submits
   ============================================================ */
.page-progress {
    position: fixed;
    top: 0; left: 0; right: 0;
    height: 2.5px;
    z-index: var(--z-toast, 1080);
    pointer-events: none;
    background: transparent;
    overflow: hidden;
}
.page-progress::after {
    content: '';
    position: absolute;
    top: 0; left: 0;
    height: 100%;
    width: 0;
    background: linear-gradient(
        90deg,
        rgb(var(--accent, 255 106 0)),
        rgb(var(--accent-hot, 255 60 0))
    );
    box-shadow: 0 0 12px rgb(var(--accent, 255 106 0) / 0.7);
    transition: width 200ms ease, opacity 240ms ease;
    opacity: 0;
}
.page-progress.is-active::after { opacity: 1; }
.page-progress.is-active[data-progress="0"]::after { width: 0%; }
.page-progress.is-active[data-progress="20"]::after { width: 20%; }
.page-progress.is-active[data-progress="40"]::after { width: 45%; }
.page-progress.is-active[data-progress="60"]::after { width: 70%; }
.page-progress.is-active[data-progress="80"]::after { width: 88%; }
.page-progress.is-active[data-progress="100"]::after { width: 100%; opacity: 0; }

/* ============================================================
   6. Toast stack
   ============================================================ */
.toast-stack {
    position: fixed;
    top: 16px; right: 16px;
    z-index: var(--z-toast, 1080);
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
    max-width: min(400px, calc(100vw - 32px));
}
.toast {
    pointer-events: auto;
    padding: 10px 14px;
    background: rgb(var(--bg-elevated, 24 24 36));
    border: 1px solid rgb(var(--border-hairline, 64 64 80));
    border-left-width: 3px;
    border-radius: var(--r-default, 6px);
    box-shadow: 0 12px 30px rgb(0 0 0 / 0.45);
    font: 500 13px/1.4 var(--font-body, system-ui, sans-serif);
    color: rgb(var(--text-primary, 240 240 245));
    display: flex;
    align-items: flex-start;
    gap: 10px;
    transform: translateX(120%);
    animation: ax-toast-in 240ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
.toast.is-leaving { animation: ax-toast-out 200ms ease forwards; }
@keyframes ax-toast-in  { to { transform: translateX(0); } }
@keyframes ax-toast-out {
    to { transform: translateX(120%); opacity: 0; }
}
.toast--ok    { border-left-color: rgb(var(--signal-ok, 76 217 100)); }
.toast--info  { border-left-color: rgb(var(--signal-cyan, 34 211 238)); }
.toast--warn  { border-left-color: rgb(var(--signal-amber, 245 158 11)); }
.toast--error { border-left-color: rgb(var(--signal-crimson, 239 68 68)); }
.toast__icon { flex: 0 0 auto; margin-top: 2px; }

/* ============================================================
   7. Scroll-reveal (Intersection Observer driven, prefers-reduced-motion safe)
   ============================================================ */
[data-reveal] {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 600ms ease, transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
    will-change: opacity, transform;
}
[data-reveal].is-visible {
    opacity: 1;
    transform: translateY(0);
}
[data-reveal-delay="100"] { transition-delay: 100ms; }
[data-reveal-delay="200"] { transition-delay: 200ms; }
[data-reveal-delay="300"] { transition-delay: 300ms; }
[data-reveal-delay="400"] { transition-delay: 400ms; }

@media (prefers-reduced-motion: reduce) {
    [data-reveal] { opacity: 1; transform: none; transition: none; }
    .skeleton::after, [data-skeleton]::after { animation: none; }
    .spinner, .spinner-sm, .spinner-lg { animation-duration: 2s; }
}

/* ============================================================
   8. Helpers used by action-system.js
   ============================================================ */
[data-action-busy="true"] {
    cursor: wait !important;
    pointer-events: none;
    position: relative;
}

/* Disable all hover transforms on touch devices -- they look broken
   when the hover state lingers after a tap. */
@media (hover: none) {
    button:hover, .btn:hover { transform: none !important; }
}

/* ============================================================
   9. TOOLTIPS -- pure CSS, [data-tooltip="..."] on any element
   No JS needed. Position via [data-tooltip-pos="top|bottom|left|right"].
   Default: top. Auto-fades in 200ms after 400ms hover delay.
   ============================================================ */
[data-tooltip] {
    position: relative;
}
[data-tooltip]::before,
[data-tooltip]::after {
    position: absolute;
    pointer-events: none;
    opacity: 0;
    transition: opacity 200ms ease 400ms, transform 200ms ease 400ms;
    z-index: var(--z-tooltip, 1070);
}
[data-tooltip]::before {
    /* arrow */
    content: '';
    width: 0; height: 0;
    border: 5px solid transparent;
}
[data-tooltip]::after {
    content: attr(data-tooltip);
    padding: 6px 10px;
    background: rgb(var(--bg-elevated, 24 24 36));
    color: rgb(var(--text-primary, 240 240 245));
    border: 1px solid rgb(var(--border-hairline, 64 64 80));
    border-radius: var(--r-default, 6px);
    font: 500 11.5px/1.4 var(--font-body, system-ui);
    white-space: nowrap;
    max-width: 240px;
    box-shadow: 0 6px 16px rgb(0 0 0 / 0.5);
}

/* Default position: top */
[data-tooltip]::before { bottom: calc(100% + 1px); left: 50%; transform: translateX(-50%) translateY(4px); border-top-color: rgb(var(--border-hairline, 64 64 80)); }
[data-tooltip]::after  { bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%) translateY(4px); }
[data-tooltip-pos="bottom"]::before { top: calc(100% + 1px); bottom: auto; transform: translateX(-50%) translateY(-4px); border-top-color: transparent; border-bottom-color: rgb(var(--border-hairline, 64 64 80)); }
[data-tooltip-pos="bottom"]::after  { top: calc(100% + 8px); bottom: auto; transform: translateX(-50%) translateY(-4px); }
[data-tooltip-pos="left"]::before   { right: calc(100% + 1px); left: auto; bottom: 50%; transform: translate(4px, 50%); border-top-color: transparent; border-left-color: rgb(var(--border-hairline, 64 64 80)); }
[data-tooltip-pos="left"]::after    { right: calc(100% + 8px); left: auto; bottom: 50%; transform: translate(4px, 50%); white-space: normal; }
[data-tooltip-pos="right"]::before  { left: calc(100% + 1px); bottom: 50%; transform: translate(-4px, 50%); border-top-color: transparent; border-right-color: rgb(var(--border-hairline, 64 64 80)); }
[data-tooltip-pos="right"]::after   { left: calc(100% + 8px); bottom: 50%; transform: translate(-4px, 50%); white-space: normal; }

[data-tooltip]:hover::before,
[data-tooltip]:hover::after,
[data-tooltip]:focus-visible::before,
[data-tooltip]:focus-visible::after {
    opacity: 1;
}
[data-tooltip]:hover::before          { transform: translateX(-50%) translateY(0); }
[data-tooltip]:hover::after           { transform: translateX(-50%) translateY(0); }
[data-tooltip-pos="bottom"]:hover::before { transform: translateX(-50%) translateY(0); }
[data-tooltip-pos="bottom"]:hover::after  { transform: translateX(-50%) translateY(0); }
[data-tooltip-pos="left"]:hover::before, [data-tooltip-pos="left"]:hover::after,
[data-tooltip-pos="right"]:hover::before, [data-tooltip-pos="right"]:hover::after { transform: translate(0, 50%); }

/* Disable tooltip on touch devices -- they fire on long-press anyway and overlay UX is broken */
@media (hover: none) {
    [data-tooltip]::before, [data-tooltip]::after { display: none; }
}

/* ============================================================
   10. ONBOARDING TOUR -- spotlight + popover on element
   ============================================================ */
.tour-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal, 1050);
    pointer-events: none;
    background: rgb(0 0 0 / 0.6);
    backdrop-filter: blur(2px);
    transition: opacity 240ms ease;
}
.tour-overlay.is-active { pointer-events: auto; }

.tour-spotlight {
    position: fixed;
    z-index: calc(var(--z-modal, 1050) + 1);
    border-radius: 10px;
    box-shadow:
        0 0 0 4px rgb(var(--accent, 255 106 0) / 0.5),
        0 0 0 9999px rgb(0 0 0 / 0.6),
        0 0 24px rgb(var(--accent, 255 106 0) / 0.4);
    pointer-events: none;
    transition: top 320ms cubic-bezier(0.4, 0, 0.2, 1),
                left 320ms cubic-bezier(0.4, 0, 0.2, 1),
                width 320ms cubic-bezier(0.4, 0, 0.2, 1),
                height 320ms cubic-bezier(0.4, 0, 0.2, 1);
}

.tour-popover {
    position: fixed;
    z-index: calc(var(--z-modal, 1050) + 2);
    width: min(360px, calc(100vw - 32px));
    background: rgb(var(--bg-elevated, 24 24 36));
    border: 1px solid rgb(var(--border-hairline, 64 64 80));
    border-radius: 12px;
    box-shadow: 0 24px 60px rgb(0 0 0 / 0.6), 0 0 0 1px rgb(var(--accent, 255 106 0) / 0.3);
    padding: 18px 20px 16px;
    color: rgb(var(--text-primary, 240 240 245));
    transition: top 320ms ease, left 320ms ease, opacity 200ms ease;
}
.tour-popover__step {
    font: 500 10.5px/1 var(--font-mono, monospace);
    color: rgb(var(--accent, 255 106 0));
    letter-spacing: 0.1em;
    text-transform: uppercase;
    margin-bottom: 6px;
}
.tour-popover__title {
    font-size: 16px;
    font-weight: 600;
    margin: 0 0 8px;
    line-height: 1.3;
}
.tour-popover__body {
    font-size: 13px;
    line-height: 1.55;
    color: rgb(var(--text-secondary, 176 176 186));
    margin-bottom: 14px;
}
.tour-popover__nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}
.tour-popover__dots {
    display: flex;
    gap: 4px;
}
.tour-popover__dot {
    width: 6px; height: 6px;
    background: rgb(var(--text-muted, 112 112 128));
    border-radius: 50%;
    transition: background 200ms;
}
.tour-popover__dot.is-active {
    background: rgb(var(--accent, 255 106 0));
    width: 18px;
    border-radius: 999px;
}
.tour-popover__btn {
    padding: 6px 12px;
    border-radius: 6px;
    font: 500 12px/1 var(--font-body, system-ui);
    cursor: pointer;
    border: 1px solid rgb(var(--border-hairline));
    background: transparent;
    color: rgb(var(--text-secondary));
    transition: all 150ms;
}
.tour-popover__btn:hover {
    border-color: rgb(var(--accent));
    color: rgb(var(--accent));
}
.tour-popover__btn--primary {
    background: rgb(var(--accent));
    border-color: rgb(var(--accent));
    color: rgb(var(--bg-base, 8 8 12));
}
.tour-popover__btn--primary:hover {
    background: rgb(var(--accent-hot, 255 60 0));
}

/* Empty-state SVG illustrations -- placeholder containers */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 48px 24px;
    color: rgb(var(--text-muted, 112 112 128));
    gap: 14px;
}
.empty-state__art {
    width: min(180px, 50vw);
    height: auto;
    opacity: 0.85;
}
.empty-state__art .pulse-stroke {
    stroke-dasharray: 4 6;
    animation: ax-empty-dash 8s linear infinite;
}
@keyframes ax-empty-dash { to { stroke-dashoffset: -100; } }
.empty-state__art .pulse-glow {
    animation: ax-empty-glow 2.4s ease-in-out infinite;
}
@keyframes ax-empty-glow {
    0%, 100% { opacity: 0.4; }
    50%      { opacity: 1; }
}
.empty-state__title {
    font: 600 16px/1.3 var(--font-body);
    color: rgb(var(--text-primary));
}
.empty-state__sub {
    font: 13px/1.5 var(--font-body);
    color: rgb(var(--text-secondary));
    max-width: 380px;
}
.empty-state__cta {
    margin-top: 4px;
}

@media (prefers-reduced-motion: reduce) {
    .empty-state__art .pulse-stroke,
    .empty-state__art .pulse-glow { animation: none; }
    .tour-popover, .tour-spotlight { transition: none; }
}

/* Catalog row clickable affordance */
.catalog-row {
    cursor: pointer;
    transition: background 150ms ease;
}
.catalog-row:hover { background: rgb(var(--accent) / 0.06); }
.catalog-row:focus-visible { outline: 2px solid rgb(var(--accent)); outline-offset: -2px; }

/* Generic clickable list-row pattern */
.row-clickable { cursor: pointer; transition: background 150ms ease; }
.row-clickable:hover { background: rgb(var(--accent) / 0.06); }
.row-clickable:focus-visible { outline: 2px solid rgb(var(--accent)); outline-offset: -2px; }

/* ============================================================
   COOKIE BANNER -- bottom-of-viewport, slide-up entrance
   ============================================================ */
.cookie-banner {
    position: fixed;
    bottom: 16px; left: 16px; right: 16px;
    max-width: 720px;
    margin: 0 auto;
    z-index: var(--z-fixed, 1030);
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 14px 18px;
    background: rgb(var(--bg-elevated, 24 24 36));
    border: 1px solid rgb(var(--border-hairline, 64 64 80));
    border-radius: 12px;
    box-shadow: 0 12px 36px rgb(0 0 0 / 0.55);
    color: rgb(var(--text-primary, 240 240 245));
    font: 500 13px/1.5 var(--font-body, system-ui, sans-serif);
    animation: cookie-banner-in 320ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
.cookie-banner.is-leaving {
    animation: cookie-banner-out 260ms ease forwards;
}
@keyframes cookie-banner-in {
    from { transform: translateY(120%); opacity: 0; }
    to   { transform: translateY(0);    opacity: 1; }
}
@keyframes cookie-banner-out {
    to { transform: translateY(120%); opacity: 0; }
}
.cookie-banner__icon {
    flex-shrink: 0;
    color: rgb(var(--accent, 255 106 0));
    margin-top: 2px;
}
.cookie-banner__body { flex: 1; min-width: 0; }
.cookie-banner__body strong {
    display: block;
    font-weight: 600;
    margin-bottom: 4px;
    color: rgb(var(--text-primary));
}
.cookie-banner__body p {
    margin: 0;
    font-size: 12.5px;
    color: rgb(var(--text-secondary, 176 176 186));
    line-height: 1.5;
}
.cookie-banner__actions {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-shrink: 0;
}
.cookie-banner__link {
    color: rgb(var(--text-secondary));
    font-size: 12px;
    text-decoration: underline;
    padding: 6px 8px;
}
.cookie-banner__link:hover { color: rgb(var(--accent)); }
.cookie-banner__btn {
    padding: 8px 16px;
    background: rgb(var(--accent));
    color: rgb(var(--bg-base, 8 8 12));
    border: 0;
    border-radius: 8px;
    font: 600 12.5px/1 var(--font-body);
    cursor: pointer;
    transition: background 150ms;
}
.cookie-banner__btn:hover { background: rgb(var(--accent-hot, 255 60 0)); }

@media (max-width: 640px) {
    .cookie-banner { flex-wrap: wrap; padding: 12px 14px; }
    .cookie-banner__actions { width: 100%; justify-content: flex-end; }
}
@media (prefers-reduced-motion: reduce) {
    .cookie-banner { animation: none; }
    .cookie-banner.is-leaving { animation: none; opacity: 0; }
}
