/* ═══════════════════════════════════════════════════════════════════════════
 * Roadaro — premium.css  v2 (refinement pass)
 * One motion system for the whole app. Tokens first, everything inherits.
 *   micro interactions 120–180ms · modals 180–260ms · entrances 250–400ms
 * Transform/opacity only (no layout-property animation). Reduced-motion safe.
 * ═══════════════════════════════════════════════════════════════════════════ */
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&display=swap');
:root{
  /* ── Canonical color palette (single source of truth) ──────────────────
   * Each page links this file BEFORE its own <style>, so any page that still
   * declares these in its own :root keeps winning — colors are unchanged.
   * These values are the documented default + a safety net for pages that
   * link premium.css but are missing a token. Light theme: */
  --bg:#f3f4f8; --bg2:#eaecf2; --w:#fff;
  --navy:#00394d; --red:#dc1e28; --green:#1a7a40; --gold:#c8901a; --blue:#1e3fa8;
  --border:#dce0ea; --t:#1a1a2e; --t2:#556; --t3:#8892a8;

  --m-fast:140ms; --m-mod:220ms; --m-in:300ms;
  --ease:cubic-bezier(.25,.7,.3,1); --ease-pop:cubic-bezier(.25,.9,.3,1.15);
  --elev-1:0 1px 2px rgba(15,25,60,.05),0 2px 8px rgba(15,25,60,.05);
  --elev-2:0 2px 6px rgba(15,25,60,.06),0 8px 24px rgba(15,25,60,.08);
  --elev-3:0 8px 20px rgba(15,25,60,.10),0 20px 48px rgba(15,25,60,.12);
}
[data-theme="dark"]{
  --bg:#0d1117; --bg2:#161b22; --w:#1c2128;
  --navy:#58a6ff; --red:#f85149; --green:#3fb950; --gold:#d29922; --blue:#58a6ff;
  --border:#30363d; --t:#c9d1d9; --t2:#8b949e; --t3:#6e7681;

  --elev-1:0 1px 2px rgba(0,0,0,.35),0 2px 8px rgba(0,0,0,.3);
  --elev-2:0 2px 6px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.35);
  --elev-3:0 8px 20px rgba(0,0,0,.5),0 20px 48px rgba(0,0,0,.45);
}

/* ── Global micro-interactions (fast, quiet) ───────────────────────────── */
button{transition:transform var(--m-fast) var(--ease),box-shadow var(--m-fast) var(--ease),opacity var(--m-fast) var(--ease),background var(--m-fast) var(--ease);}
button:not(:disabled):active{transform:scale(.975);}
button:disabled{opacity:.45;cursor:not-allowed;}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--blue,#1e3fa8)!important;box-shadow:0 0 0 3px rgba(30,63,168,.10);transition:box-shadow var(--m-fast) var(--ease),border-color var(--m-fast) var(--ease);}
[data-theme="dark"] input:focus,[data-theme="dark"] select:focus,[data-theme="dark"] textarea:focus{box-shadow:0 0 0 3px rgba(88,166,255,.14);}
/* Selection must be unmistakable on BOTH themes. The old rgba(30,63,168,.16) was a
 * navy at 16% alpha — effectively invisible on the dark theme's near-black surfaces.
 * Solid brand blue + forced text color reads clearly everywhere; the dark rule is
 * explicit (not var(--blue)) because the token flips to a LIGHT blue in dark mode,
 * which would need dark text, not white. */
::selection{background:#1e3fa8;color:#fff;}
[data-theme="dark"] ::selection{background:#58a6ff;color:#0d1117;}
tbody tr{transition:background var(--m-fast) var(--ease);}

/* ── Keyframes ─────────────────────────────────────────────────────────── */
@keyframes pnx-fade-in{from{opacity:0;}to{opacity:1;}}
@keyframes pnx-slide-up{from{opacity:0;transform:translateY(8px);}to{opacity:1;transform:none;}}
@keyframes pnx-pop{0%{transform:scale(.7);opacity:0;}75%{transform:scale(1.04);}100%{transform:scale(1);opacity:1;}}
@keyframes pnx-toast{from{opacity:0;transform:translate(-50%,8px);}to{opacity:1;transform:translate(-50%,0);}}

/* ── Reusable classes ──────────────────────────────────────────────────── */

.status-badge{display:inline-flex;align-items:center;gap:5px;padding:2px 9px;border-radius:99px;font-size:9.5px;font-weight:800;letter-spacing:.02em;background:var(--bg,#f3f4f8);border:1px solid var(--border,#dce0ea);color:var(--t2,#556);}
.status-badge::before{content:'';width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.7;}
.status-badge.ok{color:var(--green,#1a7a40);background:rgba(26,122,64,.08);border-color:rgba(26,122,64,.2);}
.status-badge.warn{color:var(--gold,#b8860b);background:rgba(184,134,11,.08);border-color:rgba(184,134,11,.22);}
.status-badge.bad{color:var(--red,#dc1e28);background:rgba(220,30,40,.07);border-color:rgba(220,30,40,.2);}

#toast,.toast{animation:pnx-toast var(--m-mod) var(--ease) both;}

.empty-state{padding:34px 20px;text-align:center;color:var(--t3,#8892a8);font-size:12px;animation:pnx-fade-in var(--m-in) var(--ease) both;}
.empty-state i{font-size:30px;display:block;margin:0 auto 8px;opacity:.8;}

/* ── Page entrance: once, quick ─────────────────────────────────────────── */
.wrap,.main,.page{animation:pnx-fade-in 250ms var(--ease) both;}

/* ── Nav polish ─────────────────────────────────────────────────────────── */
.nav-link{transition:background var(--m-fast) var(--ease),color var(--m-fast) var(--ease);}
.nav-link.active{box-shadow:0 1px 6px rgba(15,32,96,.16);}

/* ── Reduced motion: hard kill ──────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important;}
}

/* ═══════════════════════════════════════════════════════════════════════════
 * v3 — PREMIUM COMMAND-CENTER LIBRARY
 * KPI cards · glow buttons · scroll reveal · tilt · spinner
 * All additive. All transform/opacity. All reduced-motion safe.
 * (2026-07-29: the never-adopted half of this layer was deleted — hero/bento/
 *  premium-card/table/button, glass-panel, status-pill, mobile-card, cine-bg,
 *  skeleton, and the fade/slide/pulse utilities. Zero uses in any page or JS.
 *  Recover from git history if a page ever wants one back.)
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ── KPI cards ──────────────────────────────────────────────────────────── */
.kpi-card{background:var(--w,#fff);border:1px solid var(--border,#dce0ea);border-radius:13px;padding:15px 16px;position:relative;overflow:hidden;
  transition:transform var(--m-fast) var(--ease),box-shadow var(--m-fast) var(--ease),border-color var(--m-fast) var(--ease);}
.kpi-card::before{content:'';position:absolute;left:0;top:12%;bottom:12%;width:3px;border-radius:3px;background:var(--blue,#1e3fa8);opacity:.85;}
.kpi-card.gold::before{background:var(--gold,#c8901a);}
.kpi-card.green::before{background:var(--green,#1a7a40);}
.kpi-card.red::before{background:var(--red,#dc1e28);}
.kpi-card:hover{transform:translateY(-2px);box-shadow:var(--elev-2);}
.kpi-value{font-size:27px;font-weight:800;line-height:1;color:var(--navy,#00394d);font-variant-numeric:tabular-nums;letter-spacing:-.01em;}
.kpi-label{font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--t3,#8892a8);margin-top:5px;}
.kpi-trend{display:inline-flex;align-items:center;gap:3px;font-size:9.5px;font-weight:800;margin-top:6px;padding:2px 8px;border-radius:99px;}
.kpi-trend.up{color:var(--green,#1a7a40);background:rgba(26,122,64,.09);}
.kpi-trend.down{color:var(--red,#dc1e28);background:rgba(220,30,40,.08);}
[data-theme="dark"] .kpi-value{color:var(--blue,#58a6ff);}

/* ── Glow button ────────────────────────────────────────────────────────── */
.glow-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:10px 20px;border:none;border-radius:10px;
  background:linear-gradient(135deg,#00394d,#0a5a7a);color:#fff;font-weight:800;font-size:12px;cursor:pointer;overflow:hidden;
  box-shadow:0 2px 10px rgba(0,57,77,.25);transition:transform var(--m-fast) var(--ease),box-shadow var(--m-fast) var(--ease);}
.glow-btn:hover{transform:translateY(-1px);box-shadow:0 6px 22px rgba(10,90,122,.4);}
.glow-btn::after{content:'';position:absolute;top:0;left:-90%;width:55%;height:100%;transform:skewX(-20deg);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.18),transparent);transition:left .55s var(--ease);}
.glow-btn:hover::after{left:130%;}
.glow-btn.gold{background:linear-gradient(135deg,#c8901a,#e0a92e);color:#1a1306;box-shadow:0 2px 10px rgba(200,144,26,.3);}
.glow-btn.gold:hover{box-shadow:0 6px 22px rgba(200,144,26,.45);}
.glow-btn.danger{background:linear-gradient(135deg,#b3151f,#dc1e28);box-shadow:0 2px 10px rgba(220,30,40,.3);}

/* ── Scroll reveal (activated only when premium.js adds html.pnx-js) ────── */
html.pnx-js [data-reveal]{opacity:0;transform:translateY(14px);transition:opacity .55s var(--ease),transform .55s var(--ease);}
html.pnx-js [data-reveal="left"]{transform:translateX(-18px);}
html.pnx-js [data-reveal="right"]{transform:translateX(18px);}
html.pnx-js [data-reveal="scale"]{transform:scale(.96);}
html.pnx-js [data-reveal].revealed{opacity:1;transform:none;}

/* ── Hover tilt (transform driven by premium.js; CSS handles the easing) ── */
.hover-tilt{transition:transform .18s var(--ease),box-shadow .18s var(--ease);will-change:transform;}
.hover-tilt:hover{box-shadow:var(--elev-2);}

/* ── Spinner ────────────────────────────────────────────────────────────── */
.pnx-spinner{width:18px;height:18px;border-radius:50%;border:2.5px solid rgba(127,127,127,.25);border-top-color:var(--blue,#1e3fa8);animation:pnx-rotate .7s linear infinite;display:inline-block;}
@keyframes pnx-rotate{to{transform:rotate(360deg);}}

/* ── Accessible focus (keyboard only, zero-specificity, app-wide) ───────── */
:where(button,a,select,summary,[role="button"],[tabindex]:not([tabindex="-1"])):focus-visible{outline:2px solid var(--blue,#1e3fa8);outline-offset:2px;}
[data-theme="dark"] :where(button,a,select,summary,[role="button"],[tabindex]:not([tabindex="-1"])):focus-visible{outline-color:#58a6ff;}

/* ── Reduced motion: final guard (reveal must never hide content) ───────── */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important;}
  html.pnx-js [data-reveal]{opacity:1!important;transform:none!important;}
  .hover-tilt{transform:none!important;}
}

/* ── Global slim scrollbars (app-wide default; any page's own scrollbar CSS
 *    still wins because page <style> loads after this file) ──────────────── */
*{scrollbar-width:thin;scrollbar-color:rgba(120,135,170,.40) transparent;}
::-webkit-scrollbar{width:9px;height:9px;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-thumb{background:rgba(120,135,170,.38);border-radius:8px;border:2px solid transparent;background-clip:content-box;}
::-webkit-scrollbar-thumb:hover{background:rgba(120,135,170,.60);background-clip:content-box;}
[data-theme="dark"] *{scrollbar-color:rgba(120,140,180,.45) transparent;}
[data-theme="dark"] ::-webkit-scrollbar-thumb{background:rgba(120,140,180,.40);background-clip:content-box;}

/* ── Magnetic hover smoothing + button loading state (drive by premium.js) ── */
.magnetic{transition:transform var(--m-fast) var(--ease);}
.is-loading{cursor:wait;pointer-events:none;}
.is-loading .pnx-spinner{vertical-align:middle;}
.glow-btn .pnx-spinner,.is-loading .pnx-spinner{border-color:rgba(255,255,255,.35);border-top-color:#fff;}

/* ── Staggered reveal for a container's children (opt-in: [data-stagger]) ──
 *    Only active once premium.js marks the page; reduced-motion shows all.   */
html.pnx-js [data-stagger]>*{opacity:0;animation:pnx-slide-up var(--m-in) var(--ease) both;}
html.pnx-js [data-stagger]>*:nth-child(1){animation-delay:.02s;}
html.pnx-js [data-stagger]>*:nth-child(2){animation-delay:.07s;}
html.pnx-js [data-stagger]>*:nth-child(3){animation-delay:.12s;}
html.pnx-js [data-stagger]>*:nth-child(4){animation-delay:.17s;}
html.pnx-js [data-stagger]>*:nth-child(5){animation-delay:.22s;}
html.pnx-js [data-stagger]>*:nth-child(6){animation-delay:.27s;}
html.pnx-js [data-stagger]>*:nth-child(n+7){animation-delay:.30s;}
@media (prefers-reduced-motion: reduce){html.pnx-js [data-stagger]>*{opacity:1!important;animation:none!important;}}

/* ═══════════════════════════════════════════════════════════════════════════
 * v3.1 — Honest empty / loading / error states
 * Extends the existing .empty-state. Use real copy ("No active loads"),
 * never fake data. .es-title / .es-msg / .es-action are optional children.
 * ═══════════════════════════════════════════════════════════════════════════ */
.empty-state .es-title{font-size:14px;font-weight:800;color:var(--t2,#556);margin-bottom:3px;letter-spacing:-.01em;}
.empty-state .es-msg{font-size:12px;color:var(--t3,#8892a8);max-width:340px;margin:0 auto;line-height:1.5;}
.empty-state .es-action{display:inline-flex;align-items:center;gap:6px;margin-top:14px;padding:8px 16px;border-radius:8px;border:1px solid var(--border,#dce0ea);
  background:var(--w,#fff);color:var(--navy,#00394d);font-weight:800;font-size:11.5px;cursor:pointer;transition:border-color var(--m-fast) var(--ease),box-shadow var(--m-fast) var(--ease);}
.empty-state .es-action:hover{border-color:var(--blue,#1e3fa8);box-shadow:var(--elev-1);}

/* Error state — explains what went wrong + how to recover; never apologetic, never vague */
.error-state{padding:34px 20px;text-align:center;color:var(--t3,#8892a8);font-size:12px;animation:pnx-fade-in var(--m-in) var(--ease) both;}
.error-state i{font-size:30px;display:block;margin:0 auto 8px;color:var(--red,#dc1e28);opacity:.9;}
.error-state .es-title{font-size:14px;font-weight:800;color:var(--t2,#556);margin-bottom:3px;}
.error-state .es-msg{font-size:12px;color:var(--t3,#8892a8);max-width:340px;margin:0 auto;line-height:1.5;}
.error-state .es-action{display:inline-flex;align-items:center;gap:6px;margin-top:14px;padding:8px 16px;border-radius:8px;border:none;
  background:var(--red,#dc1e28);color:#fff;font-weight:800;font-size:11.5px;cursor:pointer;transition:opacity var(--m-fast) var(--ease),box-shadow var(--m-fast) var(--ease);}
.error-state .es-action:hover{opacity:.92;box-shadow:var(--elev-1);}

/* Inline loading row — drop into a table/list while real data is fetched */
.pnx-loading-row{display:flex;align-items:center;justify-content:center;gap:9px;padding:26px 20px;color:var(--t3,#8892a8);font-size:12px;font-weight:600;}

/* ═══════════════════════════════════════════════════════════════════════════
 * v4 — SYSTEM SCALES (impeccable pass, 2026-07-02)
 * Semantic tint + control-scale tokens. Pages converge onto these instead of
 * re-hardcoding the same pastel hexes (#e8f8ee / #fff8e0 / #fdecec / …) and
 * inventing per-page control sizes. Additive only — nothing here restyles an
 * element by itself; pages opt in by referencing the tokens.
 * ═══════════════════════════════════════════════════════════════════════════ */
:root{
  /* control scale (reference values — adopt per page, never force globally) */
  --ctl-h-sm:26px; --ctl-h:30px; --ctl-h-lg:36px;
  --ctl-r:8px; --ctl-r-lg:10px; --ctl-font:11.5px;
  /* page shell scale */
  --gutter:20px; --page-max:1180px; --page-max-wide:1340px;
  /* semantic tints — ok / warn / bad / info / gold (bg + border pairs) */
  --ok-bg:rgba(26,122,64,.08);    --ok-bd:rgba(26,122,64,.22);
  --warn-bg:rgba(184,134,11,.09); --warn-bd:rgba(184,134,11,.24);
  --bad-bg:rgba(220,30,40,.07);   --bad-bd:rgba(220,30,40,.2);
  --info-bg:rgba(30,63,168,.07);  --info-bd:rgba(30,63,168,.2);
  --gold-bg:rgba(200,144,26,.10); --gold-bd:rgba(200,144,26,.28);
}
[data-theme="dark"]{
  --ok-bg:rgba(63,185,80,.12);    --ok-bd:rgba(63,185,80,.32);
  --warn-bg:rgba(210,153,34,.13); --warn-bd:rgba(210,153,34,.34);
  --bad-bg:rgba(248,81,73,.12);   --bad-bd:rgba(248,81,73,.32);
  --info-bg:rgba(88,166,255,.12); --info-bd:rgba(88,166,255,.32);
  --gold-bg:rgba(210,153,34,.13); --gold-bd:rgba(210,153,34,.36);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * Roadaro brand wordmark — option E (icon lockup): Space Grotesk, mono white.
 * The gold accent now lives only in the flame/drop mark, not split into "aro".
 * Overrides every page's inline wordmark style; the accent <b>/<span> inherits
 * its parent color so light-navbar pages stay readable.
 * ═══════════════════════════════════════════════════════════════════════════ */
.login-logo-text,.logo-name,.logo,.nav-logo,.dvl-word,.tlogo,.loader-brand,.ls-word,.lbox-t span{
  font-family:'Space Grotesk',-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif!important;
  font-weight:600!important;letter-spacing:-.03em!important;
}
.login-logo-text span,.logo-name b,.logo b,.nav-logo b,.dvl-word b,.tlogo b,.loader-brand b,.ls-word span,.lbox-t span b{
  color:inherit!important;font-weight:700!important;
}
