/* =============================================================================
   Trove UI — the shared design system for every app in the Trove Tools portal.
   v1.2.0  (nav drawer / shared hamburger menu)

   ONE source of truth for color, type, spacing, radius, shadow and the core
   components. Served from the portal at /static/trove-ui.css and linked by every
   app; each app keeps a vendored copy as an offline/standalone fallback.

   ── How to use ──────────────────────────────────────────────────────────────
   • Style everything through the tokens below (var(--brand), var(--ink), …).
     Never hard-code a hex in an app — the Sprint 6 CI lint fails the build for it.
   • Dark mode is automatic (prefers-color-scheme) AND user-toggleable: set
     data-theme="dark" | "light" on <html>. The attribute wins over the OS.
   • Components (.btn, .card, .field, .pill, .table, .topbar, .tile, .modal…) are
     conventional, unprefixed names. An app adopts them and deletes its local copy.

   ── Brand ───────────────────────────────────────────────────────────────────
   Primary  #2563eb (blue)      Accent  #d97a2b (amber)
   ========================================================================== */

/* ---- Tokens: light (the complete palette lives here) ---------------------- */
:root {
  /* Neutrals — cool, very slightly blue-biased so the brand reads as intended. */
  --bg:          #f4f6fb;
  --surface:     #ffffff;
  --surface-2:   #eef1f7;
  --surface-3:   #e6eaf3;
  --line:        #e1e6f0;
  --line-soft:   #edf0f6;

  --ink:         #171a21;   /* primary text            */
  --muted:       #5b6373;   /* secondary text / labels */
  --faint:       #8b93a4;   /* tertiary / placeholders */

  /* Brand */
  --brand:       #2563eb;
  --brand-hover: #1d4ed8;
  --brand-soft:  #3b82f6;
  --brand-tint:  #e8eefe;   /* washed brand for chips / selected rows */
  --on-brand:    #ffffff;   /* text/icon on a brand-filled surface   */

  /* Accent (complementary amber — use sparingly for highlights) */
  --accent:      #d97a2b;
  --accent-tint: #fbeede;
  --on-accent:   #ffffff;

  /* Semantic — separate from the accent; state, not brand. */
  --ok:      #2f6b46;  --ok-tint:     #e4f1e9;
  --warn:    #9a6a12;  --warn-tint:   #fbf0d9;
  --danger:  #c1352b;  --danger-tint: #f8e5e3;
  --info:    var(--brand); --info-tint: var(--brand-tint);

  /* Geometry */
  --radius-sm:  9px;
  --radius:    14px;
  --radius-lg: 20px;
  --radius-pill: 999px;

  /* Elevation */
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, .06);
  --shadow:    0 1px 2px rgba(15, 23, 42, .05), 0 6px 22px rgba(15, 23, 42, .06);
  --shadow-lg: 0 12px 40px rgba(15, 23, 42, .14);

  /* Focus ring — one visible keyboard-focus treatment everywhere. */
  --ring: 0 0 0 3px color-mix(in srgb, var(--brand) 40%, transparent);

  /* Spacing scale (rem-based; use for gap/padding). */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;

  /* Type */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
          Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;

  /* Layout */
  --maxw:      1080px;
  --topbar-h:  56px;
  --tabbar-h:  62px;

  /* Motion */
  --tr-fast: .12s ease;
  --tr:      .18s ease;

  color-scheme: light;
}

/* ---- Tokens: dark (redefine ONLY what changes) --------------------------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:        #0f1420;
    --surface:   #171d2b;
    --surface-2: #1e2536;
    --surface-3: #263047;
    --line:      #2c3547;
    --line-soft: #242d3e;

    --ink:   #e9ecf4;
    --muted: #9aa3b6;
    --faint: #6d768a;

    --brand:       #5b8bf7;
    --brand-hover: #7ba6fb;
    --brand-soft:  #7ba6fb;
    --brand-tint:  #1a2540;
    --on-brand:    #0c1424;

    --accent:      #e0a15c;
    --accent-tint: #33260f;

    --ok:     #5cc389;  --ok-tint:     #12281c;
    --warn:   #d8a63e;  --warn-tint:   #2c2410;
    --danger: #e6786d;  --danger-tint: #331715;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .45);
    --shadow:    0 1px 2px rgba(0, 0, 0, .4), 0 8px 26px rgba(0, 0, 0, .4);
    --shadow-lg: 0 14px 44px rgba(0, 0, 0, .55);

    color-scheme: dark;
  }
}
/* Explicit toggle wins in the other direction too. */
:root[data-theme="dark"] {
  --bg:        #0f1420;
  --surface:   #171d2b;
  --surface-2: #1e2536;
  --surface-3: #263047;
  --line:      #2c3547;
  --line-soft: #242d3e;

  --ink:   #e9ecf4;
  --muted: #9aa3b6;
  --faint: #6d768a;

  --brand:       #5b8bf7;
  --brand-hover: #7ba6fb;
  --brand-soft:  #7ba6fb;
  --brand-tint:  #1a2540;
  --on-brand:    #0c1424;

  --accent:      #e0a15c;
  --accent-tint: #33260f;

  --ok:     #5cc389;  --ok-tint:     #12281c;
  --warn:   #d8a63e;  --warn-tint:   #2c2410;
  --danger: #e6786d;  --danger-tint: #331715;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .45);
  --shadow:    0 1px 2px rgba(0, 0, 0, .4), 0 8px 26px rgba(0, 0, 0, .4);
  --shadow-lg: 0 14px 44px rgba(0, 0, 0, .55);

  color-scheme: dark;
}

/* ---- Reset / base -------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
/* `hidden` must win even over components that set their own display (e.g. the
   modal backdrop uses display:grid) — so el.hidden = true always hides. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { margin: 0; line-height: 1.2; letter-spacing: -.01em; text-wrap: balance; }
h1 { font-size: 1.6rem; font-weight: 700; }
h2 { font-size: 1.28rem; font-weight: 700; }
h3 { font-size: 1.08rem; font-weight: 600; }
p  { margin: 0 0 var(--space-3); }
a  { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; }
code, kbd, samp, pre { font-family: var(--font-mono); font-size: .88em; }
hr { border: 0; border-top: 1px solid var(--line); margin: var(--space-5) 0; }

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--ring);
  border-radius: var(--radius-sm);
}

/* ---- Utilities ----------------------------------------------------------- */
.tds-container { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--space-5); }
.muted { color: var(--muted); }
.faint { color: var(--faint); }
.stack { display: grid; gap: var(--space-4); }
.row   { display: flex; align-items: center; gap: var(--space-3); }
.tnum  { font-variant-numeric: tabular-nums; }
.eyebrow {
  text-transform: uppercase; letter-spacing: .08em;
  font-size: .72rem; font-weight: 600; color: var(--muted);
}

/* ---- Buttons ------------------------------------------------------------- */
.btn {
  --btn-bg: var(--surface);
  --btn-fg: var(--ink);
  --btn-bd: var(--line);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: 9px 15px;
  font: inherit; font-weight: 600; font-size: .92rem;
  color: var(--btn-fg);
  background: var(--btn-bg);
  border: 1px solid var(--btn-bd);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--tr-fast), border-color var(--tr-fast), color var(--tr-fast), transform var(--tr-fast);
  text-decoration: none;
  white-space: nowrap;
}
.btn:hover { background: var(--surface-2); border-color: var(--brand); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }

.btn-primary {
  --btn-bg: var(--brand); --btn-fg: var(--on-brand); --btn-bd: var(--brand);
}
.btn-primary:hover { --btn-bg: var(--brand-hover); --btn-bd: var(--brand-hover); }

.btn-danger { --btn-bg: var(--danger); --btn-fg: #fff; --btn-bd: var(--danger); }
.btn-danger:hover { filter: brightness(1.06); --btn-bd: var(--danger); }

.btn-ghost { --btn-bg: transparent; --btn-bd: transparent; --btn-fg: var(--muted); }
.btn-ghost:hover { --btn-bg: var(--surface-2); --btn-fg: var(--ink); --btn-bd: transparent; }

.btn-sm { padding: 6px 11px; font-size: .84rem; }
.btn-lg { padding: 12px 20px; font-size: 1rem; }
.btn-block { width: 100%; }

/* ---- Form fields --------------------------------------------------------- */
.field { display: grid; gap: 6px; }
.field > label, .label {
  font-size: .82rem; font-weight: 600; color: var(--muted);
}
.input, .select, .textarea,
input[type="text"], input[type="email"], input[type="password"],
input[type="search"], input[type="number"], input[type="tel"], input[type="url"],
input[type="date"], select, textarea {
  width: 100%;
  padding: 10px 12px;
  font: inherit; font-size: .93rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color var(--tr-fast), box-shadow var(--tr-fast);
}
.input:focus, .select:focus, .textarea:focus,
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--brand); box-shadow: var(--ring);
}
.input::placeholder, .textarea::placeholder, input::placeholder, textarea::placeholder {
  color: var(--faint);
}
textarea, .textarea { min-height: 96px; resize: vertical; }
.field-hint { font-size: .78rem; color: var(--faint); }
.field-error { font-size: .78rem; color: var(--danger); }

/* ---- Cards / surfaces ---------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.card-pad { padding: var(--space-5); }
.card-hd  { padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--line); }
.card-bd  { padding: var(--space-5); }

/* ---- Pills / badges (semantic state, not brand) -------------------------- */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px;
  font-size: .76rem; font-weight: 600; line-height: 1.5;
  border-radius: var(--radius-pill);
  background: var(--surface-2); color: var(--muted);
}
.pill-ok     { background: var(--ok-tint);     color: var(--ok); }
.pill-warn   { background: var(--warn-tint);   color: var(--warn); }
.pill-danger { background: var(--danger-tint); color: var(--danger); }
.pill-brand  { background: var(--brand-tint);  color: var(--brand); }
.pill-accent { background: var(--accent-tint); color: var(--accent); }

/* ---- Tables -------------------------------------------------------------- */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); }
.table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.table th, .table td { text-align: left; padding: 11px 14px; border-bottom: 1px solid var(--line-soft); }
.table th {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); font-weight: 600; background: var(--surface-2);
}
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: var(--surface-2); }
.table .tnum { font-variant-numeric: tabular-nums; }

/* ---- Topbar (standalone app header) -------------------------------------- */
.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  height: var(--topbar-h);
  padding: 0 var(--space-5);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.topbar .brand { display: flex; align-items: center; gap: var(--space-2); font-weight: 700; color: var(--ink); }
.topbar .brand-mark { width: 24px; height: 24px; border-radius: 6px; display: block; }
.topbar .spacer { flex: 1; }

/* Theme toggle — same control in every app. */
.theme-toggle {
  width: 34px; height: 34px; flex: none; padding: 0;
  display: grid; place-items: center;
  font-size: 16px; line-height: 1; cursor: pointer;
  color: var(--muted); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  transition: color var(--tr-fast), border-color var(--tr-fast);
}
.theme-toggle:hover { color: var(--brand); border-color: var(--brand); }

/* ---- Tiles (dashboard launcher grid) ------------------------------------- */
.tile-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-4); }
.tile {
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--space-4);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-sm);
  transition: border-color var(--tr), box-shadow var(--tr), transform var(--tr);
  text-decoration: none; color: var(--ink);
}
.tile:hover { border-color: var(--brand); box-shadow: var(--shadow); transform: translateY(-2px); text-decoration: none; }
.tile .tile-icon { font-size: 1.5rem; line-height: 1; }
.tile .tile-name { font-weight: 600; }
.tile .tile-desc { font-size: .84rem; color: var(--muted); }

/* ---- Alerts / inline messages -------------------------------------------- */
.alert {
  padding: 11px 14px; border-radius: var(--radius-sm);
  font-size: .9rem; border: 1px solid var(--line); background: var(--surface-2); color: var(--ink);
}
.alert-ok     { background: var(--ok-tint);     border-color: color-mix(in srgb, var(--ok) 35%, transparent);     color: var(--ok); }
.alert-warn   { background: var(--warn-tint);   border-color: color-mix(in srgb, var(--warn) 35%, transparent);   color: var(--warn); }
.alert-danger { background: var(--danger-tint); border-color: color-mix(in srgb, var(--danger) 35%, transparent); color: var(--danger); }

/* ---- Toasts (transient notifications) ------------------------------------ */
.toasts {
  position: fixed; z-index: 70; bottom: 16px; left: 50%; transform: translateX(-50%);
  display: grid; justify-items: center; gap: 8px;
  width: max-content; max-width: min(360px, calc(100vw - 32px));
}
.toast {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 13px;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-left: 3px solid var(--brand);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
  font-size: .9rem;
}
.toast-ok     { border-left-color: var(--ok); }
.toast-warn   { border-left-color: var(--warn); }
.toast-danger { border-left-color: var(--danger); }
.toast .toast-close {
  margin-left: auto; padding: 0 2px; line-height: 1; font-size: 1rem;
  background: none; border: 0; color: var(--faint); cursor: pointer;
}
.toast .toast-close:hover { color: var(--ink); }

/* ---- Modal / dialog ------------------------------------------------------ */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(8, 12, 20, .5);
  display: grid; place-items: center; padding: var(--space-5);
}
.modal {
  width: 100%; max-width: 460px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.modal-hd { padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--line); font-weight: 700; }
.modal-bd { padding: var(--space-5); }
.modal-ft { padding: var(--space-4) var(--space-5); border-top: 1px solid var(--line); display: flex; justify-content: flex-end; gap: var(--space-2); }

/* ---- Mobile tab bar ------------------------------------------------------ */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  height: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  display: flex; align-items: stretch;
  background: var(--surface); border-top: 1px solid var(--line);
}
.tabbar a {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  font-size: .68rem; font-weight: 600; color: var(--muted); text-decoration: none;
}
.tabbar a .ico { font-size: 1.15rem; line-height: 1; }
.tabbar a[aria-current="page"], .tabbar a.active { color: var(--brand); }

/* ---- Nav drawer (the shared hamburger menu) ------------------------------
   One consistent slide-in menu for every app. The app fills it with its OWN
   nav items — the chrome (identity header, list rows, footer) looks identical
   everywhere. Opens from the right; toggled by a `.hamburger` button.

   Markup:
     <button class="hamburger" aria-label="Menu" aria-controls="app-drawer"
             aria-expanded="false" onclick="tdsDrawer(true)">
       <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2"
            stroke-linecap="round"><path d="M4 6h16M4 12h16M4 18h16"/></svg>
     </button>
     <div class="drawer-scrim" onclick="tdsDrawer(false)"></div>
     <aside id="app-drawer" class="drawer" role="dialog" aria-modal="true" aria-label="Menu">
       <div class="drawer-head">
         <div class="drawer-av">M</div>
         <div class="drawer-id"><b>Marcus Reed</b><span>Royse City · Manager</span></div>
         <button class="drawer-close" aria-label="Close" onclick="tdsDrawer(false)">✕</button>
       </div>
       <div class="drawer-label">Menu</div>
       <nav class="drawer-nav">
         <a href="/"          aria-current="page"><span class="ico">🏠</span>Event Feed</a>
         <a href="/events/new"><span class="ico">＋</span>Log Event</a>
       </nav>
       <div class="drawer-foot">
         <a href="/logout"><span class="ico">↪</span>Sign out</a>
       </div>
     </aside>

   Toggle (one small helper the app defines once):
     function tdsDrawer(open){
       document.getElementById('app-drawer').classList.toggle('open', open);
       document.querySelector('.drawer-scrim').classList.toggle('open', open);
       document.querySelector('.hamburger')?.setAttribute('aria-expanded', open);
     }
     addEventListener('keydown', e => { if (e.key === 'Escape') tdsDrawer(false); });
   -------------------------------------------------------------------------- */
.hamburger {
  width: 34px; height: 34px; flex: none; padding: 0;
  display: grid; place-items: center; cursor: pointer;
  color: var(--muted); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  transition: color var(--tr-fast), border-color var(--tr-fast);
}
.hamburger:hover { color: var(--brand); border-color: var(--brand); }
.hamburger svg { width: 19px; height: 19px; }

.drawer-scrim {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(8, 12, 20, .46);
  opacity: 0; pointer-events: none; transition: opacity var(--tr);
}
.drawer-scrim.open { opacity: 1; pointer-events: auto; }

.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 91;
  width: min(84%, 320px);
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); color: var(--ink);
  border-left: 1px solid var(--line); box-shadow: var(--shadow-lg);
  transform: translateX(100%); transition: transform var(--tr);
}
.drawer.open { transform: translateX(0); }

/* Identity header */
.drawer-head {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-4); border-bottom: 1px solid var(--line);
}
.drawer-av {
  width: 36px; height: 36px; flex: none;
  display: grid; place-items: center;
  font-weight: 700; font-size: .95rem;
  color: var(--on-brand); background: var(--brand); border-radius: var(--radius-sm);
}
.drawer-id { min-width: 0; margin-right: auto; }
.drawer-id b { display: block; font-size: .95rem; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.drawer-id span { display: block; font-size: .74rem; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.drawer-close {
  width: 30px; height: 30px; flex: none; padding: 0;
  display: grid; place-items: center; cursor: pointer;
  font-size: 1.05rem; line-height: 1;
  color: var(--faint); background: none; border: 0; border-radius: var(--radius-sm);
}
.drawer-close:hover { color: var(--ink); background: var(--surface-2); }

/* Section label */
.drawer-label {
  padding: var(--space-3) var(--space-4) var(--space-1);
  text-transform: uppercase; letter-spacing: .07em;
  font-size: .68rem; font-weight: 700; color: var(--muted);
}

/* Nav rows + footer rows share the same row styling */
.drawer-nav { flex: 1; overflow-y: auto; padding: var(--space-1) var(--space-2) var(--space-2); }
.drawer-nav a, .drawer-foot a {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 9px 10px; border-radius: var(--radius-sm);
  font-weight: 600; font-size: .9rem; color: var(--ink); text-decoration: none;
}
.drawer-nav a:hover, .drawer-foot a:hover { background: var(--surface-2); text-decoration: none; }
.drawer-nav a[aria-current="page"], .drawer-nav a.active {
  background: var(--brand-tint); color: var(--brand);
}
.drawer-nav a .ico, .drawer-foot a .ico {
  width: 20px; flex: none; text-align: center; font-size: 1.05rem; line-height: 1;
}
.drawer-foot {
  border-top: 1px solid var(--line); padding: var(--space-2);
  display: flex; flex-direction: column; gap: 1px;
}
.drawer-foot a { color: var(--muted); font-weight: 700; }

/* ---- Empty / loading states ---------------------------------------------- */
.empty {
  display: grid; gap: 6px; place-items: center; text-align: center;
  padding: var(--space-7) var(--space-5); color: var(--muted);
}
.empty .empty-icon { font-size: 2rem; opacity: .7; }
.spinner {
  width: 20px; height: 20px; border-radius: 50%;
  border: 2px solid var(--line); border-top-color: var(--brand);
  animation: tds-spin .7s linear infinite;
}
@keyframes tds-spin { to { transform: rotate(360deg); } }

/* ---- Respect reduced motion ---------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
