/* ============================================================
   Design foundation — single source of truth for every surface
   (public site, auth, dashboard, admin).

   Load this BEFORE any layout-specific <style> block so layouts
   can still override, and AFTER Bootstrap on the pages that use it.
   ============================================================ */

/* ------------------------------------------------------------
   1. TOKENS — dark is the default theme
   ------------------------------------------------------------ */
:root {
    /* Surfaces: each step is a deliberate elevation, not a random shade */
    --bg-primary:   #0b0e11;   /* page */
    --bg-secondary: #151a21;   /* card / panel */
    --bg-tertiary:  #1e2329;   /* input / nested surface */
    --bg-elevated:  #23262a;   /* menu / popover */
    --bg-surface:   #151a21;
    --bg-hover:     #2b3139;

    --glass:        rgba(255, 255, 255, 0.03);
    --glass-border: rgba(255, 255, 255, 0.07);
    --border:       #2b3139;
    --border-light: #3a4149;
    --border-active:#474d57;

    /* Text — every value below is >= 4.5:1 on bg-primary..bg-tertiary */
    --text-primary:   #ffffff;
    --text-secondary: #98a1af;
    --text-tertiary:  #7f8a97;
    --text-on-brand:  #ffffff;

    /* Brand.
       --brand      = fills, graphics, large type (>= 3:1, decorative-safe)
       --brand-text = the same hue lightened until body text passes 4.5:1 */
    --brand:        #9945ff;
    --brand-text:   #b47cff;
    --brand-strong: #7c3aed;
    --brand-subtle: rgba(153, 69, 255, 0.14);
    --accent:       #00d4aa;
    --accent-text:  #2ee6c0;
    --accent-subtle:rgba(0, 212, 170, 0.14);

    /* Back-compat aliases used across existing views — do not remove */
    --accent-purple: var(--brand);
    --accent-cyan:   var(--accent);
    --accent-pink:   #ff6b9d;
    --accent-blue:   #3b82f6;
    --accent-green:  #00ffa3;
    --violet:        var(--brand);
    --violet-dark:   var(--brand-strong);
    --violet-subtle: var(--brand-subtle);
    --cyan:          var(--accent);

    /* Semantic status */
    --green:        #0ecb81;
    --green-text:   #2ee08f;
    --green-dark:   #059669;
    --green-subtle: rgba(14, 203, 129, 0.14);
    --red:          #f6465d;
    --red-text:     #ff7085;
    --red-dark:     #dc2626;
    --red-subtle:   rgba(246, 70, 93, 0.14);
    --yellow:       #f0b90b;
    --yellow-text:  #f5c93f;
    --yellow-subtle:rgba(240, 185, 11, 0.14);
    --info:         #3b82f6;
    --info-text:    #7dabff;
    --info-subtle:  rgba(59, 130, 246, 0.14);
    --success: var(--green);
    --danger:  var(--red);
    --warning: var(--yellow);

    /* Text laid directly on a solid status fill. The fills invert between
       themes — bright in dark, deep in light — so the readable ink flips
       with them rather than staying white in both. */
    --text-on-success: #06231a;
    --text-on-danger:  #2b060c;
    --text-on-warning: #241704;

    --gradient-primary: linear-gradient(135deg, #9945ff, #00d4aa);
    --gradient-success: linear-gradient(135deg, #0ecb81, #059669);
    --gradient-danger:  linear-gradient(135deg, #f6465d, #dc2626);

    --nav-bg: #0b0e11;
    --nav-bg-scrolled: rgba(11, 14, 17, 0.92);
    --scrim: rgba(0, 0, 0, 0.6);
    --shadow-color: rgba(0, 0, 0, 0.5);

    /* Type */
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    --font-display: 'Space Grotesk', var(--font-sans);
    --font-mono: 'SF Mono', 'Monaco', 'Roboto Mono', 'Consolas', monospace;

    --text-xs:  0.75rem;   /* 12 — labels, captions only */
    --text-sm:  0.8125rem; /* 13 — dense table/meta text */
    --text-md:  0.875rem;  /* 14 — app body */
    --text-base:1rem;      /* 16 — reading body, all mobile inputs */
    --text-lg:  1.125rem;  /* 18 */
    --text-xl:  1.375rem;  /* 22 */
    --text-2xl: 1.75rem;   /* 28 */
    --text-3xl: 2.25rem;   /* 36 */

    /* 4pt spacing rhythm */
    --space-1: 4px;   --space-2: 8px;   --space-3: 12px;  --space-4: 16px;
    --space-5: 20px;  --space-6: 24px;  --space-8: 32px;  --space-10: 40px;
    --space-12: 48px; --space-16: 64px;

    /* Radii */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-xl: 20px;
    --radius-pill: 999px;

    /* Elevation — one consistent ladder, no ad-hoc shadows */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.28);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.32);
    --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.40);
    --shadow-xl: 0 24px 56px rgba(0, 0, 0, 0.48);

    /* Motion — one rhythm everywhere */
    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-in:  cubic-bezier(0.55, 0, 1, 0.45);
    --dur-fast: 130ms;
    --dur-base: 200ms;
    --dur-slow: 300ms;

    --focus-ring: var(--accent-text);
    --tap-min: 44px;  /* minimum interactive target */

    --nav-height: 64px;
    --bottom-nav-height: 68px;
    --content-max: 1180px;
}

/* ------------------------------------------------------------
   2. LIGHT THEME
   Not an inversion: surfaces get lighter, brand desaturates so it
   stays legible on white, and text keeps the same 3-step hierarchy.
   ------------------------------------------------------------ */
[data-theme="light"] {
    --bg-primary:   #ffffff;
    --bg-secondary: #f7f8fa;
    --bg-tertiary:  #eef0f4;
    --bg-elevated:  #ffffff;
    --bg-surface:   #ffffff;
    --bg-hover:     #e6e9ef;

    --glass:        rgba(15, 23, 42, 0.03);
    --glass-border: rgba(15, 23, 42, 0.09);
    --border:       #dfe3ea;
    --border-light: #cbd2dd;
    --border-active:#9aa4b2;

    --text-primary:   #0f172a;  /* 16.7:1 on white */
    --text-secondary: #475569;  /*  7.6:1 on white */
    /* Tertiary is measured against bg-tertiary, not white — that is the
       surface it actually sits on (inputs, disabled controls). 4.8:1 on
       white was only 4.2:1 there. */
    --text-tertiary:  #5f6b7a;  /*  5.4:1 on white, 4.8:1 on bg-tertiary */
    --text-on-brand:  #ffffff;

    --brand:        #6d28d9;
    --brand-text:   #6d28d9;    /* 7.0:1 on white */
    --brand-strong: #5b21b6;
    --brand-subtle: rgba(109, 40, 217, 0.10);
    --accent:       #0d9488;
    --accent-text:  #0f766e;    /* 4.9:1 on white */
    --accent-subtle:rgba(13, 148, 136, 0.10);

    --accent-pink:  #be185d;
    --accent-blue:  #1d4ed8;
    --accent-green: #047857;

    /* The -text variants are darkened until they clear 4.5:1 on their own
       tinted background, not merely on plain white. */
    --green:        #047857;
    --green-text:   #046a4d;
    --green-dark:   #065f46;
    --green-subtle: rgba(4, 120, 87, 0.10);
    --red:          #be123c;
    --red-text:     #a80f35;
    --red-dark:     #9f1239;
    --red-subtle:   rgba(190, 18, 60, 0.10);
    --yellow:       #a16207;
    --yellow-text:  #8a5309;
    --yellow-subtle:rgba(161, 98, 7, 0.12);
    --info:         #1d4ed8;
    --info-text:    #1d4ed8;
    --info-subtle:  rgba(29, 78, 216, 0.10);

    /* Light-mode status fills are deep, so their ink is white */
    --text-on-success: #ffffff;
    --text-on-danger:  #ffffff;
    --text-on-warning: #ffffff;

    --gradient-primary: linear-gradient(135deg, #6d28d9, #0d9488);
    --gradient-success: linear-gradient(135deg, #047857, #065f46);
    --gradient-danger:  linear-gradient(135deg, #be123c, #9f1239);

    --nav-bg: #ffffff;
    --nav-bg-scrolled: rgba(255, 255, 255, 0.92);
    --scrim: rgba(15, 23, 42, 0.45);
    --shadow-color: rgba(15, 23, 42, 0.10);

    --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
    --shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08);
    --shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.12);
    --shadow-xl: 0 24px 56px rgba(15, 23, 42, 0.16);

    --focus-ring: #6d28d9;
}

/* ------------------------------------------------------------
   3. BASE
   ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scroll-behavior: smooth;
}

body {
    margin: 0;
    font-family: var(--font-sans);
    font-size: var(--text-md);
    line-height: 1.55;
    color: var(--text-primary);
    background-color: var(--bg-primary);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: hidden;      /* guards against stray full-bleed children */
    text-rendering: optimizeLegibility;
}

/* Long-form copy stays inside a readable measure (60–75 chars) */
.prose p, .prose li { max-width: 68ch; line-height: 1.7; }

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.015em;
    margin-top: 0;              /* trailing margin is left to each layout */
    color: var(--text-primary);
}

img, svg, video, canvas { max-width: 100%; height: auto; }

a { color: var(--brand-text); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--brand-text); }

/* Figures in tables, prices, timers: no width jitter as digits change */
.mono, .tabular, td.num, .num {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}
.mono { font-family: var(--font-mono); }

/* ------------------------------------------------------------
   4. FOCUS — visible on every interactive element, in both themes.
   :focus-visible only, so pointer users never see a stray ring.
   ------------------------------------------------------------ */
:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}
/* Elements that clip their own overflow need an inset ring instead */
.drawer-item:focus-visible,
.sidebar-link:focus-visible,
.bottom-nav-item:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: -2px;
}
:focus:not(:focus-visible) { outline: none; }

/* Keyboard-only skip target */
.skip-link {
    position: absolute;
    left: var(--space-4);
    top: -100%;
    z-index: 10000;
    padding: 10px 16px;
    border-radius: var(--radius-md);
    background: var(--bg-elevated);
    color: var(--text-primary);
    border: 1px solid var(--border-active);
    font-size: var(--text-md);
    font-weight: 600;
    text-decoration: none;
    transition: top var(--dur-base) var(--ease-out);
}
.skip-link:focus { top: var(--space-4); }

.sr-only {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ------------------------------------------------------------
   5. INTERACTION BASELINE
   ------------------------------------------------------------ */
button, [role="button"], a[href], label[for], select, summary {
    touch-action: manipulation;   /* removes the 300ms tap delay */
}
button, input, select, textarea { font-family: inherit; font-size: inherit; }
button:not(:disabled), [role="button"]:not([aria-disabled="true"]) { cursor: pointer; }

/* Anything that looks tappable must be tappable — icon buttons included */
.tap-target { min-width: var(--tap-min); min-height: var(--tap-min); }

:disabled, [aria-disabled="true"], .is-disabled {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
}
/* Read-only is not disabled: it stays legible and focusable */
[readonly] { background: var(--bg-tertiary); color: var(--text-secondary); cursor: default; }

/* iOS zooms any input under 16px on focus — never let that happen.
   Above the phone breakpoint we can go back to the denser app size. */
@media (max-width: 767.98px) {
    input:not([type="checkbox"]):not([type="radio"]),
    select, textarea { font-size: 1rem; }
}

/* Enforce the 44px minimum only where a finger is the pointer, so
   desktop admin tables keep their density. */
@media (pointer: coarse) {
    button, [role="button"], .btn, .tab,
    input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]),
    select, textarea, .drawer-item, .bottom-nav-item {
        min-height: var(--tap-min);
    }
}

::placeholder { color: var(--text-tertiary); opacity: 1; }
::selection { background: var(--brand-subtle); color: var(--text-primary); }

/* ------------------------------------------------------------
   6. MOTION
   ------------------------------------------------------------ */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes shimmerSweep { 100% { transform: translateX(100%); } }

.spin { animation: spin 0.8s linear infinite; display: inline-block; }

/* Skeleton placeholder — reserves space so async content cannot shift layout */
.skeleton {
    position: relative;
    overflow: hidden;
    background: var(--bg-tertiary);
    border-radius: var(--radius-md);
}
.skeleton::after {
    content: '';
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg, transparent, var(--glass-border), transparent);
    animation: shimmerSweep 1.4s infinite;
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    /* Ambient decoration carries no meaning — drop it entirely */
    .gradient-orb, .mesh-grid, .skeleton::after { display: none !important; }

    /* A busy indicator is functional feedback, not decoration, so it
       keeps turning — just slower and without the fast strobe. */
    .spin { animation: spin 1.6s linear infinite !important; }
}

/* ------------------------------------------------------------
   6b. PRELOADER (shared by every layout)

   One dismissal path, one direction. The CSS keyframe is only a
   failsafe for when JavaScript never runs; the moment the script
   marks the element done, the animation is cancelled and the node
   is removed — so it can never fade back in for a second showing.
   ------------------------------------------------------------ */
.preloader {
    position: fixed;
    inset: 0;
    z-index: 99999;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    background: var(--bg-primary);
    animation: preloaderRelease 0.35s var(--ease-out) 1.6s forwards;
}

/* JS is authoritative: kill the keyframe so it cannot re-assert opacity. */
.preloader.is-done {
    animation: none !important;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.25s var(--ease-out), visibility 0.25s;
}

@keyframes preloaderRelease {
    to { opacity: 0; visibility: hidden; pointer-events: none; }
}

.preloader-logo {
    width: 48px;
    height: 48px;
    border-radius: var(--radius-lg);
    background: var(--gradient-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    color: #fff;
    box-shadow: var(--shadow-lg);
    position: relative;
    overflow: hidden;
}

.preloader-logo::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(45deg, transparent 40%, rgba(255, 255, 255, 0.28) 50%, transparent 60%);
    animation: logoShine 1.4s infinite;
}

.preloader-text {
    font-family: var(--font-display);
    font-size: var(--text-xs);
    font-weight: 600;
    color: var(--text-secondary);
    letter-spacing: 2px;
    text-transform: uppercase;
}

.preloader-bar {
    width: 96px;
    height: 2px;
    background: var(--glass-border);
    border-radius: var(--radius-pill);
    overflow: hidden;
}

.preloader-progress {
    width: 0;
    height: 100%;
    background: var(--gradient-primary);
    animation: loadProgress 1.1s var(--ease-out) forwards;
}

@keyframes logoShine { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }
@keyframes loadProgress { 0% { width: 0; } 100% { width: 100%; } }

/* A cover that hides content is exactly what a reduced-motion user
   does not need; skip it entirely. */
@media (prefers-reduced-motion: reduce) {
    .preloader { display: none !important; }
}

/* ------------------------------------------------------------
   7. SCROLLBAR
   ------------------------------------------------------------ */
* { scrollbar-width: thin; scrollbar-color: var(--border-light) transparent; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-light); border-radius: var(--radius-pill); }
::-webkit-scrollbar-thumb:hover { background: var(--border-active); }

/* ------------------------------------------------------------
   8. SHARED PRIMITIVES
   ------------------------------------------------------------ */

/* Wide content scrolls inside its own container — the page never does */
.scroll-x {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-x: contain;
}

/* Status colour is never the only signal: pair it with an icon or label */
.status-dot {
    width: 8px; height: 8px; border-radius: 50%;
    display: inline-block; flex-shrink: 0; margin-right: 6px;
}

/* Brand lockup: an uploaded logo replaces the wordmark entirely; the
   wordmark only reappears if that image fails to load.

   The logo is given a definite height so every upload renders at the same
   optical size, with a width ceiling so a wide banner cannot crowd out the
   rest of the header. object-fit letterboxes anything that hits both. */
.brand-logo {
    display: block;
    height: var(--brand-logo-h, 38px);
    width: auto;
    max-width: var(--brand-logo-w, 200px);
    object-fit: contain;
    object-position: left center;
}

@media (max-width: 575.98px) {
    .brand-logo {
        height: calc(var(--brand-logo-h, 38px) - 6px);
        max-width: min(var(--brand-logo-w, 200px), 150px);
    }
}

.brand-fallback { display: inline-flex; align-items: center; gap: 0.5rem; min-width: 0; }
.brand-fallback[hidden] { display: none; }

.u-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.u-stack { display: flex; flex-direction: column; }
.u-row { display: flex; align-items: center; }

/* Safe areas — notch, Dynamic Island, home indicator */
.safe-top    { padding-top: env(safe-area-inset-top, 0px); }
.safe-bottom { padding-bottom: env(safe-area-inset-bottom, 0px); }
.safe-x {
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
}

/* Print: drop chrome, keep content */
@media print {
    .navbar-custom, .bottom-nav, .drawer, .drawer-overlay,
    .admin-sidebar, .preloader, .animated-bg, .mesh-grid { display: none !important; }
    body { background: #fff; color: #000; padding: 0 !important; }
}
