/* =========================================================
   CargoFlow — design tokens
   Dark navy is the default/primary appearance; light is optional.
   Company primary/secondary/sidebar colors are injected as inline
   :root overrides in layouts/app.php from the `companies` table.
========================================================= */
:root{
  --bg:#0B1220;
  --surface:#101a2e;
  --surface-2:#152238;
  --surface-3:#1b2a45;
  --border:#243252;
  --ink:#E7ECF6;
  --ink-soft:#AEB8CC;
  --ink-faint:#78839c;
  --primary:#2F6FED;
  --primary-ink:#ffffff;
  --secondary:#10213D;
  --sidebar-bg:#0B1220;
  --good:#3FCB8A;
  --good-bg:rgba(63,203,138,0.14);
  --warn:#F0B24A;
  --warn-bg:rgba(240,178,74,0.14);
  --bad:#F0645F;
  --bad-bg:rgba(240,100,95,0.14);
  --info:#5AA7FF;
  --info-bg:rgba(90,167,255,0.14);
  --radius-sm:8px;
  --radius:14px;
  --radius-lg:20px;
  --shadow: 0 1px 2px rgba(0,0,0,.35), 0 12px 32px -12px rgba(0,0,0,.55);
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, "SF Mono", Consolas, monospace;
}

:root[data-theme="light"]{
  --bg:#F3F5FA;
  --surface:#ffffff;
  --surface-2:#F6F8FC;
  --surface-3:#EBEFF6;
  --border:#E1E6F0;
  --ink:#131A2A;
  --ink-soft:#5B6478;
  --ink-faint:#94A0B6;
  --sidebar-bg:#10213D;
  --good:#1F9D63;
  --good-bg:#E4F6EC;
  --warn:#B8792A;
  --warn-bg:#FBF0DE;
  --bad:#D5473F;
  --bad-bg:#FBE7E6;
  --info:#2F6FED;
  --info-bg:#E9F0FF;
  --shadow: 0 1px 2px rgba(16,33,61,.06), 0 10px 28px -14px rgba(16,33,61,.18);
}

*,*::before,*::after{ box-sizing:border-box; }
html,body{ height:100%; }
/* Baseline icon size — the icon() helper emits a bare <svg viewBox="0 0 24
   24"> with no width/height of its own (by design, so context-specific
   rules like .btn svg / .kpi-icon svg can size it), but that also means an
   icon dropped directly into a heading or a flex row with NO such rule
   renders at the browser's oversized default replaced-element size instead
   of a sane icon size. This low-specificity default fixes that gap; every
   more specific existing rule (.btn svg, .kpi-icon svg, .nav-link svg, …)
   still wins as before. */
svg{ width:20px; height:20px; }
body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:var(--font-sans);
  font-size:15px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden; /* the page itself must never scroll sideways — wide content scrolls in its own container instead (see .rtc-table-wrap) */
}
h1,h2,h3,h4{ margin:0; font-weight:650; letter-spacing:-0.01em; }
p{ margin:0; }
a{ color:inherit; text-decoration:none; }
button{ font-family:inherit; }
::selection{ background:var(--primary); color:#fff; }

/* The one clickable-entity treatment used everywhere (see entityLink() in
   Helpers/functions.php) — a subtle color + underline-on-hover/focus,
   deliberately not a permanently-underlined old-fashioned link. */
.entity-link{ color:var(--ink); font-weight:600; border-radius:4px; }
.entity-link:hover,.entity-link:focus-visible{ color:var(--primary); text-decoration:underline; }
.entity-link:focus-visible{ outline:2px solid var(--primary); outline-offset:2px; }

.mono{ font-family:var(--font-mono); }
.nowrap{ white-space:nowrap; }
.text-soft{ color:var(--ink-soft); }
.text-faint{ color:var(--ink-faint); }

/* =========================================================
   App shell
========================================================= */
.app-shell{
  display:grid;
  grid-template-columns:264px 1fr;
  min-height:100vh;
  transition:grid-template-columns .24s ease;
}
/* Grid items default to min-width:auto, which refuses to shrink below the
   content's intrinsic width — meaning any one wide element anywhere on a
   page could silently stretch this ENTIRE column (and drag the sticky
   topbar/sidebar grid track along with it) instead of wrapping/scrolling
   locally. This is the single most common cause of whole-page horizontal
   overflow; every inner component still needs its own correct wrapping,
   but nothing can fix itself while the outer shell refuses to constrain it. */
.app-main{ min-width:0; }

/* Desktop/tablet collapsed rail — the toggle class lives on <html> (same
   place data-theme lives), set before first paint from localStorage so a
   returning user never sees a flash of the wrong state. See layouts/app.php. */
:root.sidebar-collapsed .app-shell{ grid-template-columns:76px 1fr; }
@media (max-width:767px){
  .app-shell{ grid-template-columns:1fr; }
  /* Below the mobile breakpoint the collapse preference is irrelevant —
     the sidebar is always full-width off-canvas, never a narrow rail.
     (":root.sidebar-collapsed .app-shell" outranks plain ".app-shell" on
     specificity alone, so this override must repeat the same selector
     here rather than relying on the rule above.) */
  :root.sidebar-collapsed .app-shell{ grid-template-columns:1fr; }
}

/* ---- Sidebar ---- */
.sidebar{
  background:var(--sidebar-bg);
  border-right:1px solid rgba(255,255,255,0.06);
  padding:20px 14px 24px;
  display:flex;
  flex-direction:column;
  gap:4px;
  position:sticky;
  top:0;
  height:100vh;
  overflow-y:auto;
  overflow-x:hidden;
  transition:width .24s ease, padding .24s ease;
}
@media (max-width:767px){
  .sidebar{ display:none; }
}

/* ---- Desktop/tablet collapsed rail ----
   Every selector here is scoped to ".sidebar:not(.mobile-open)": the
   collapsed-rail preference lives on <html> (so it survives a full page
   reload before app.js even runs — see layouts/app.php), which is also an
   ancestor of the MOBILE drawer. Without this guard, a user who last
   collapsed the desktop rail would open the mobile drawer to find it
   silently icon-only too — reproduced directly while building this: labels
   and the logo text vanished from the slide-in drawer the moment the
   desktop preference was "collapsed". The drawer must always show full
   labels regardless of the desktop/tablet preference. */
:root.sidebar-collapsed .sidebar:not(.mobile-open){ padding:20px 10px 24px; }
:root.sidebar-collapsed .sidebar:not(.mobile-open) .brand{ justify-content:center; padding:8px 0 20px; }
:root.sidebar-collapsed .sidebar:not(.mobile-open) .brand .name,
:root.sidebar-collapsed .sidebar:not(.mobile-open) .brand .sub,
:root.sidebar-collapsed .sidebar:not(.mobile-open) .nav-link span,
:root.sidebar-collapsed .sidebar:not(.mobile-open) .section-title,
:root.sidebar-collapsed .sidebar:not(.mobile-open) .sidebar-footer .nav-link span{
  display:none;
}
:root.sidebar-collapsed .sidebar:not(.mobile-open) .nav-link{ justify-content:center; padding:10px; }
:root.sidebar-collapsed .sidebar:not(.mobile-open) .sidebar-close-btn{ display:none; }
/* In the icons-only rail the accordion header is meaningless — hide it and
   always show the group's links, matching the pre-accordion behaviour. */
:root.sidebar-collapsed .sidebar:not(.mobile-open) .nav-accordion-toggle{ display:none; }
:root.sidebar-collapsed .sidebar:not(.mobile-open) .nav-accordion-panel[hidden]{ display:flex; }

/* ---- Collapsible nav group (the Finance section) ---- */
/* `.nav-group{display:flex}` (below) beats the bare UA `[hidden]{display:none}`,
   so — exactly like `.notif-bell-panel[hidden]` — the collapsed panel needs an
   explicit rule. The collapsed-rail override above (higher specificity) still
   forces it back open in the icons-only sidebar. */
.nav-accordion-panel[hidden]{ display:none; }
.nav-accordion-toggle{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  width:100%; background:none; border:0; cursor:pointer; font:inherit;
  /* inherit the .section-title look it also carries */
}
.nav-accordion-toggle svg{ width:16px; height:16px; opacity:.6; transition:transform .15s ease; flex-shrink:0; }
.nav-accordion-toggle[aria-expanded="true"] svg{ transform:rotate(180deg); }
.nav-accordion-toggle:hover{ color:rgba(255,255,255,0.85); }
.nav-accordion-toggle:focus-visible{ outline:2px solid var(--primary); outline-offset:2px; border-radius:6px; }

/* Hover tooltip for a collapsed rail icon — reuses each link's own `title`
   text (set once in sidebar.php) rather than a second, separately
   maintained label. Desktop/tablet only; irrelevant on a full-width mobile drawer. */
:root.sidebar-collapsed .sidebar:not(.mobile-open) .nav-link{ position:relative; }
:root.sidebar-collapsed .sidebar:not(.mobile-open) .nav-link:hover::after,
:root.sidebar-collapsed .sidebar:not(.mobile-open) .nav-link:focus-visible::after{
  content:attr(title);
  position:absolute;
  left:100%;
  top:50%;
  transform:translateY(-50%);
  margin-left:10px;
  background:var(--surface-3);
  color:var(--ink);
  border:1px solid var(--border);
  box-shadow:var(--shadow);
  padding:6px 11px;
  border-radius:8px;
  font-size:12.5px;
  font-weight:500;
  white-space:nowrap;
  z-index:70;
  pointer-events:none;
}
@media (max-width:767px){
  :root.sidebar-collapsed .nav-link:hover::after{ content:none; }
}

.sidebar.mobile-open{
  display:flex;
  position:fixed;
  inset:0 22% 0 0;
  z-index:60;
  height:100vh;
  box-shadow:var(--shadow);
  animation:slide-in .2s ease-out;
}
@media (max-width:420px){
  .sidebar.mobile-open{ inset:0 12% 0 0; }
}
@keyframes slide-in{ from{ transform:translateX(-12px); opacity:0;} to{ transform:translateX(0); opacity:1;} }

.brand{
  display:flex;
  align-items:center;
  gap:10px;
  padding:8px 10px 20px;
  color:#fff;
}
.brand .logo-mark{
  width:34px;height:34px;border-radius:10px;
  background:var(--primary);
  display:flex;align-items:center;justify-content:center;
  font-weight:700;font-size:14px;color:#fff;flex-shrink:0;
}
.brand .logo-img{ width:34px;height:34px;border-radius:10px;object-fit:cover;flex-shrink:0; }
.brand .name{ font-size:15.5px; font-weight:700; color:#fff; line-height:1.2; white-space:nowrap; }
.brand .sub{ font-size:11px; color:rgba(255,255,255,0.5); white-space:nowrap; }
.brand-text{ min-width:0; overflow:hidden; }

.sidebar-close-btn{
  margin-left:auto;
  flex-shrink:0;
  width:32px; height:32px; border-radius:9px;
  display:flex; align-items:center; justify-content:center;
  background:rgba(255,255,255,0.06);
  border:1px solid rgba(255,255,255,0.1);
  color:rgba(255,255,255,0.8);
  cursor:pointer;
}
.sidebar-close-btn:hover{ color:#fff; border-color:rgba(255,255,255,0.3); }
.sidebar-close-btn svg{ width:16px; height:16px; }
@media (max-width:767px){
  /* Hidden by default off-canvas; shown only once the drawer is actually open. */
  .sidebar-close-btn{ display:none; }
  .sidebar.mobile-open .sidebar-close-btn{ display:flex; }
}

.nav-group{ display:flex; flex-direction:column; gap:2px; margin-bottom:6px; }
.nav-link{
  display:flex; align-items:center; gap:11px;
  padding:9px 12px;
  border-radius:10px;
  color:rgba(255,255,255,0.72);
  font-size:13.8px;
  font-weight:500;
  transition:background .12s ease, color .12s ease;
}
.nav-link svg{ width:18px; height:18px; flex-shrink:0; opacity:.9; }
.nav-link:hover{ background:rgba(255,255,255,0.06); color:#fff; }
.nav-link.active{ background:var(--primary); color:#fff; }
.nav-link.active svg{ opacity:1; }
.nav-link.disabled{ opacity:.35; pointer-events:none; }

.sidebar-footer{
  margin-top:auto;
  padding-top:14px;
  border-top:1px solid rgba(255,255,255,0.08);
}

/* ---- Topbar ---- */
.topbar{
  position:sticky; top:0; z-index:40;
  display:flex; align-items:center; justify-content:space-between;
  gap:16px;
  padding:14px 20px;
  background:color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter:blur(10px);
  border-bottom:1px solid var(--border);
}
.topbar .page-title{ font-size:18px; font-weight:650; }
.topbar-actions{ display:flex; align-items:center; gap:10px; }
.icon-btn{
  width:38px; height:38px; border-radius:10px;
  display:flex; align-items:center; justify-content:center;
  background:var(--surface-2); border:1px solid var(--border);
  color:var(--ink-soft); cursor:pointer;
}
.icon-btn:hover{ color:var(--ink); border-color:var(--primary); }
.icon-btn svg{ width:18px; height:18px; }
.menu-toggle{ display:none; }
@media (max-width:767px){ .menu-toggle{ display:flex; } }

/* Desktop/tablet-only "expand sidebar" button — only ever visible once the
   rail is actually collapsed, so it never competes with the mobile
   hamburger (the two never show at the same time: this one needs
   min-width:768px, the mobile one needs max-width:767px). */
.sidebar-expand-btn{ display:none; }
@media (min-width:768px){
  :root.sidebar-collapsed .sidebar-expand-btn{ display:flex; }
}

.user-chip{
  display:flex; align-items:center; gap:9px;
  padding:6px 10px 6px 6px;
  border-radius:99px;
  background:var(--surface-2);
  border:1px solid var(--border);
  color:var(--ink); /* buttons don't inherit body's color in the UA stylesheet — without
    this, .u-name silently fell back to the browser's default black button text
    instead of the theme's --ink, invisible against the dark background */
  cursor:pointer;
}
.user-chip .avatar{
  width:28px;height:28px;border-radius:50%;
  background:var(--primary); color:#fff;
  display:flex;align-items:center;justify-content:center;
  font-size:12px; font-weight:700;
}
.user-chip .u-name{ font-size:13px; font-weight:600; white-space:nowrap; }
.user-chip .u-role{ font-size:11px; color:var(--ink-faint); white-space:nowrap; }
@media (max-width:560px){
  .user-chip{ padding:0; background:none; border:none; }
  .user-chip .u-name, .user-chip .u-role{ display:none; }
}
@media (max-width:420px){ .topbar .page-title{ font-size:16px; } }

.content{ padding:22px; max-width:1400px; }
@media (max-width:640px){ .content{ padding:14px; } }

/* =========================================================
   Cards / KPIs
========================================================= */
/* NOTE: every responsive track list below uses minmax(0,1fr) rather than a
   bare 1fr. A bare "1fr" track's automatic minimum size is its content's
   min-content width (not 0) per the CSS Grid sizing algorithm — so a card
   with a long number/label can silently force the whole track (and every
   sibling in it) wider than the container, even though there's only one
   column. minmax(0,1fr) removes that hidden floor so the column actually
   shrinks to fit the viewport; .kpi-card/.kpi-value still get their own
   min-width:0 below as a second line of defense. */
.kpi-grid{
  display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:16px; margin-bottom:24px;
}
@media (max-width:900px){ .kpi-grid{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
/* Two cards per row down to the smallest supported phone width (320px) —
   kpi-card/.kpi-value already have min-width:0 + overflow-wrap:anywhere,
   so a long value wraps onto a second line instead of ever forcing
   horizontal overflow. Only true single-card-width starvation (<280px,
   below any supported device) would fall back further, which grid's own
   auto-min-content sizing already prevents from breaking layout. */
@media (max-width:480px){ .kpi-grid{ grid-template-columns:repeat(2,minmax(0,1fr)); } }

/* 5-up variant (Finance tab: Charged/Discounted/Paid/Refunded/Outstanding) —
   same responsive collapse as .kpi-grid, just a different desktop count.
   Was previously an inline style="grid-template-columns:repeat(5,1fr)" with
   no mobile override at all, forcing 5 cramped columns on every viewport. */
.kpi-grid-5{ grid-template-columns:repeat(5,minmax(0,1fr)); }
@media (max-width:900px){ .kpi-grid-5{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:480px){ .kpi-grid-5{ grid-template-columns:repeat(2,minmax(0,1fr)); } }

/* 3-up variant (BL operation-cost panel: Approved / Pending / Rejected). */
.kpi-grid-3{ grid-template-columns:repeat(3,minmax(0,1fr)); }
@media (max-width:640px){ .kpi-grid-3{ grid-template-columns:repeat(1,minmax(0,1fr)); } }

/* 6-up and 7-up variants (BL Operations Center KPI rows) — same responsive
   collapse: a comfortable count on desktop, 3-up on tablet, 2-up on phone.
   Uses classes (not inline grid-template-columns) so the media queries
   below actually win over the desktop count. */
.kpi-grid-6{ grid-template-columns:repeat(6,minmax(0,1fr)); }
.kpi-grid-7{ grid-template-columns:repeat(7,minmax(0,1fr)); }
@media (max-width:1200px){ .kpi-grid-6, .kpi-grid-7{ grid-template-columns:repeat(3,minmax(0,1fr)); } }
@media (max-width:640px){ .kpi-grid-6, .kpi-grid-7{ grid-template-columns:repeat(2,minmax(0,1fr)); } }

/* Compact "go to this settings page" cards (Finance/TRA/Goods Tracking/
   Notifications). auto-fit + minmax naturally gives two per row on a
   phone and more on tablet/desktop, collapsing to one column only if a
   card genuinely can't fit — no hardcoded breakpoint deciding the count. */
.settings-link-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:12px; }
.settings-link-card{
  display:flex; flex-direction:column; gap:8px; padding:16px; border-radius:var(--radius);
  border:1px solid var(--border); background:var(--surface); color:inherit; text-decoration:none; min-width:0;
}
.settings-link-card:hover{ border-color:var(--primary); }
.settings-link-card svg{ width:22px;height:22px;flex-shrink:0; }
.settings-link-card .settings-link-title{ font-weight:600; font-size:13.5px; }
.settings-link-card .settings-link-sub{ font-size:11.5px; color:var(--ink-faint); }

.kpi-card{
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--radius);
  padding:18px 20px;
  box-shadow:var(--shadow);
  display:flex; flex-direction:column; gap:10px;
  min-width:0;
}
.kpi-card .kpi-top{ display:flex; align-items:center; justify-content:space-between; }
.kpi-card .kpi-icon{
  width:36px;height:36px;border-radius:10px;
  background:var(--primary); opacity:.9;
  display:flex;align-items:center;justify-content:center;color:#fff;
}
.kpi-card .kpi-icon svg{ width:18px;height:18px; }
.kpi-card .kpi-value{ font-size:26px; font-weight:700; overflow-wrap:anywhere; }
.kpi-card .kpi-label{ font-size:12.5px; color:var(--ink-soft); }
/* A KPI card that is also a link to a filtered destination (Loose Cargo
   Operations Center). Purely additive — a plain .kpi-card is unaffected. */
a.kpi-card{ text-decoration:none; color:inherit; transition:border-color .12s ease, transform .12s ease; }
a.kpi-card:hover{ border-color:var(--primary); transform:translateY(-2px); }
a.kpi-card:focus-visible{ outline:2px solid var(--primary); outline-offset:2px; }
.kpi-sub{ font-size:11.5px; color:var(--ink-faint); font-weight:500; overflow-wrap:anywhere; }

/* Loose Cargo — clickable status/payment-status chips. Reuses the card
   surface tokens; two-up on phones, wrapping row on wider screens. */
.lc-status-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:10px; }
.lc-status-chip{
  display:flex; flex-direction:column; gap:2px; padding:12px 14px; min-height:64px;
  border:1px solid var(--border); border-radius:var(--radius-sm); background:var(--surface);
  color:inherit; text-decoration:none; transition:border-color .12s ease;
}
.lc-status-chip:hover{ border-color:var(--primary); }
.lc-status-chip:focus-visible{ outline:2px solid var(--primary); outline-offset:2px; }
.lc-status-chip .lc-chip-count{ font-size:20px; font-weight:700; }
.lc-status-chip .lc-chip-label{ font-size:11.5px; color:var(--ink-soft); }
.lc-filter-form{ display:flex; gap:10px; flex-wrap:wrap; width:100%; align-items:flex-end; }
.lc-filter-form .field{ margin:0; }
.lc-filter-form .field label{ font-size:11px; }
.lc-filter-form .input{ min-width:0; }
.lc-money-eq{ display:block; font-size:11px; color:var(--ink-faint); }

/* BL Operations Center — lightweight inline bar rows for the operational
   insights section (no charting library). Theme-aware via tokens. */
.bld-bar-row{ display:grid; grid-template-columns:130px 1fr 44px; gap:10px; align-items:center; font-size:12.5px; }
.bld-bar-row + .bld-bar-row{ margin-top:8px; }
.bld-bar-label{ color:var(--ink-soft); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bld-bar-track{ background:var(--surface-3); border-radius:999px; height:10px; overflow:hidden; }
.bld-bar-fill{ height:100%; background:var(--primary); border-radius:999px; min-width:2px; }
.bld-bar-val{ text-align:right; font-variant-numeric:tabular-nums; color:var(--ink); font-weight:600; }
@media (max-width:520px){ .bld-bar-row{ grid-template-columns:100px 1fr 40px; gap:8px; } }
.bld-spark{ display:flex; align-items:flex-end; gap:3px; height:44px; }
.bld-spark-bar{ flex:1; min-width:3px; background:var(--primary); opacity:.85; border-radius:2px 2px 0 0; }
.bld-today-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:10px; }
.bld-today-cell{ border:1px solid var(--border); border-radius:var(--radius-sm); padding:12px 14px; background:var(--surface); }
.bld-today-cell .n{ font-size:20px; font-weight:700; }
.bld-today-cell .k{ font-size:11.5px; color:var(--ink-soft); }

.card{
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--radius);
  box-shadow:var(--shadow);
}
/* Brief highlight when a deep-link (#anchor) scrolls a section into view. */
@keyframes section-flash-kf{
  0%{ box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 55%, transparent); }
  100%{ box-shadow:0 0 0 3px transparent; }
}
.section-flash{ animation:section-flash-kf 1.4s ease-out; border-radius:var(--radius); }
@media (prefers-reduced-motion: reduce){ .section-flash{ animation:none; } }
.card-header{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:16px 20px; border-bottom:1px solid var(--border);
  flex-wrap:wrap;
}
.card-header h3{ font-size:15.5px; }
.card-body{ padding:20px; }
@media (max-width:640px){ .card-body{ padding:14px; } }

/* =========================================================
   Tabs — a small, generic primitive (first user of it: Settings ->
   Backup & Restore). [data-tabs] wraps a row of [data-tab-trigger] buttons
   and any number of sibling [data-tab-panel] blocks; app.js toggles which
   panel is visible. Scrolls horizontally on narrow screens rather than
   wrapping/shrinking, so labels never truncate.
========================================================= */
.tabs-nav{
  display:flex; gap:4px; padding:6px; margin-bottom:16px;
  background:var(--surface-2); border-radius:var(--radius-sm);
  overflow-x:auto; -webkit-overflow-scrolling:touch;
}
.tabs-nav-btn{
  flex:none; padding:8px 14px; border-radius:8px; border:none; background:transparent;
  color:var(--ink-soft); font-size:13px; font-weight:600; cursor:pointer; white-space:nowrap;
}
.tabs-nav-btn:hover{ color:var(--ink); }
.tabs-nav-btn.active{ background:var(--surface); color:var(--primary); box-shadow:var(--shadow); }
[data-tab-panel]{ display:none; }
[data-tab-panel].active{ display:block; }

/* =========================================================
   Buttons
========================================================= */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:9px 16px; border-radius:10px; font-size:13.5px; font-weight:600;
  border:1px solid transparent; cursor:pointer; white-space:nowrap;
  min-height:40px;
}
.btn svg{ width:16px;height:16px; }
.btn-primary{ background:var(--primary); color:#fff; }
.btn-primary:hover{ filter:brightness(1.08); }
.btn-secondary{ background:var(--surface-2); color:var(--ink); border-color:var(--border); }
.btn-secondary:hover{ border-color:var(--primary); }
.btn-danger{ background:var(--bad-bg); color:var(--bad); }
.btn-danger:hover{ filter:brightness(1.1); }
.btn-ghost{ background:transparent; color:var(--ink-soft); }
.btn-ghost:hover{ color:var(--ink); background:var(--surface-2); }
.btn-sm{ padding:6px 11px; font-size:12.5px; min-height:32px; border-radius:8px; }
.btn-block{ width:100%; }
.btn:disabled{ opacity:.55; cursor:not-allowed; }
.btn.is-blocked{ opacity:.55; cursor:not-allowed; }

/* Inline loading spinner for buttons mid-AJAX-request (e.g. "Checking...") */
.btn-spin{
  width:14px;height:14px;border-radius:50%;
  border:2px solid rgba(255,255,255,0.4); border-top-color:#fff;
  animation:btn-spin-rotate .7s linear infinite; flex-shrink:0;
}
.btn-secondary .btn-spin,.btn-ghost .btn-spin{ border-color:var(--border); border-top-color:var(--ink-soft); }
@keyframes btn-spin-rotate{ to{ transform:rotate(360deg); } }

/* =========================================================
   Forms
========================================================= */
.field{ display:flex; flex-direction:column; gap:6px; margin-bottom:16px; }
.field label{ font-size:12.5px; font-weight:600; color:var(--ink-soft); }
.field .hint{ font-size:11.5px; color:var(--ink-faint); }
.field .error{ font-size:11.5px; color:var(--bad); }
.input, select.input, textarea.input{
  width:100%;
  background:var(--surface-2);
  border:1px solid var(--border);
  color:var(--ink);
  border-radius:10px;
  padding:10px 12px;
  font-size:14px;
  font-family:inherit;
  min-height:42px;
}
textarea.input{ min-height:88px; resize:vertical; }
.input:focus, select.input:focus, textarea.input:focus{
  outline:none; border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 22%, transparent);
}
.input-row{ display:grid; grid-template-columns:1fr 1fr; gap:14px; }
@media (max-width:520px){ .input-row{ grid-template-columns:1fr; } }
.color-swatch-input{ display:flex; align-items:center; gap:10px; }
.color-swatch-input input[type="color"]{
  width:42px; height:42px; border-radius:10px; border:1px solid var(--border);
  background:var(--surface-2); padding:2px; cursor:pointer;
}
.switch{ position:relative; display:inline-flex; align-items:center; gap:10px; cursor:pointer; }
.switch input{ position:absolute; opacity:0; width:1px; height:1px; }
.switch .track{
  width:38px; height:22px; border-radius:99px; background:var(--surface-3);
  border:1px solid var(--border); position:relative; transition:background .15s;
}
.switch .track::after{
  content:""; position:absolute; top:2px; left:2px; width:16px; height:16px;
  border-radius:50%; background:var(--ink-faint); transition:transform .15s, background .15s;
}
.switch input:checked + .track{ background:var(--primary); border-color:var(--primary); }
.switch input:checked + .track::after{ transform:translateX(16px); background:#fff; }
.switch input:disabled + .track{ opacity:.45; cursor:not-allowed; }

/* =========================================================
   Status badges
========================================================= */
.badge{
  display:inline-flex; align-items:center; gap:5px;
  padding:3px 10px; border-radius:99px;
  font-size:11.5px; font-weight:650; letter-spacing:.01em;
  white-space:nowrap;
}
.badge::before{ content:""; width:6px; height:6px; border-radius:50%; background:currentColor; }
.badge-good{ background:var(--good-bg); color:var(--good); }
.badge-warn{ background:var(--warn-bg); color:var(--warn); }
.badge-bad{ background:var(--bad-bg); color:var(--bad); }
.badge-info{ background:var(--info-bg); color:var(--info); }
.badge-neutral{ background:var(--surface-3); color:var(--ink-soft); }

/* =========================================================
   Responsive Table / Card system
   Desktop: real <table>. Mobile: stacked cards. Same data, same markup
   pass, toggled purely with CSS — never a horizontally scrolling table.
========================================================= */
.rtc-toolbar{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:14px 20px; border-bottom:1px solid var(--border);
}
.rtc-search{ position:relative; flex:1; min-width:180px; }
.rtc-search svg{ position:absolute; left:12px; top:50%; transform:translateY(-50%); width:16px;height:16px; color:var(--ink-faint); }
.rtc-search input{ padding-left:36px; }

.rtc-table-wrap{ overflow-x:auto; }
table.rtc-table{ width:100%; border-collapse:collapse; font-size:13.5px; }
.rtc-table th{
  text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--ink-faint); padding:10px 20px; border-bottom:1px solid var(--border);
  white-space:nowrap;
}
.rtc-table td{ padding:13px 20px; border-bottom:1px solid var(--border); vertical-align:middle; }
.rtc-table tr:last-child td{ border-bottom:none; }
.rtc-table tr:hover td{ background:var(--surface-2); }
.rtc-row-actions{ display:flex; gap:6px; justify-content:flex-end; }

.rtc-cards{ display:none; flex-direction:column; gap:12px; padding:14px; }
.rtc-card{
  border:1px solid var(--border); border-radius:var(--radius-sm);
  padding:14px 16px; background:var(--surface-2);
  display:flex; flex-direction:column; gap:10px;
}
.rtc-card-top{ display:flex; align-items:flex-start; justify-content:space-between; gap:10px; }
.rtc-card-title{ font-size:14.5px; font-weight:650; }
.rtc-card-sub{ font-size:12px; color:var(--ink-soft); }
.rtc-card-rows{ display:flex; flex-direction:column; gap:6px; }
.rtc-card-row{ display:flex; justify-content:space-between; gap:10px; font-size:12.8px; }
.rtc-card-row .k{ color:var(--ink-faint); }
.rtc-card-row .v{ text-align:right; color:var(--ink); }
.rtc-card-actions{ display:flex; gap:8px; padding-top:2px; }

@media (max-width:820px){
  .rtc-table-wrap{ display:none; }
  .rtc-cards{ display:flex; }
}

[data-col].col-hidden{ display:none !important; }

/* =========================================================
   Column selector — pairs with a table-card instance to let
   users choose which data-col="<key>" cells are visible.
========================================================= */
.col-selector{ position:relative; display:inline-flex; }
.col-selector-panel{
  position:absolute; top:calc(100% + 6px); right:0; z-index:40;
  width:240px; max-height:340px; overflow-y:auto;
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-sm);
  box-shadow:var(--shadow); padding:10px;
}
.col-selector-header{
  display:flex; align-items:center; justify-content:space-between;
  font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-faint);
  padding:2px 6px 8px; margin-bottom:6px; border-bottom:1px solid var(--border);
}
.col-selector-header .btn-link{ font-size:11.5px; text-transform:none; letter-spacing:0; }
.col-selector-list{ display:flex; flex-direction:column; gap:2px; }
.col-selector-item{
  display:flex; align-items:center; gap:9px; padding:7px 6px; border-radius:8px;
  font-size:13.5px; color:var(--ink); cursor:pointer;
}
.col-selector-item:hover{ background:var(--surface-2); }
.col-selector-item input{ width:15px; height:15px; accent-color:var(--primary); flex:none; }
.col-selector-item.is-required{ color:var(--ink-soft); cursor:default; }
.col-selector-item.is-required:hover{ background:none; }

.empty-state{ display:flex; flex-direction:column; align-items:center; text-align:center; gap:10px; padding:52px 20px; color:var(--ink-soft); }
.empty-state svg{ width:40px;height:40px; color:var(--ink-faint); }
.empty-state h4{ color:var(--ink); font-size:15px; }

.pagination{ display:flex; align-items:center; justify-content:center; gap:6px; padding:16px 20px; }
.pagination a, .pagination span{
  min-width:32px; height:32px; display:flex; align-items:center; justify-content:center;
  border-radius:8px; font-size:12.5px; color:var(--ink-soft); border:1px solid transparent;
}
.pagination a:hover{ border-color:var(--border); color:var(--ink); }
.pagination .current{ background:var(--primary); color:#fff; }

/* =========================================================
   Modals — centered on desktop, bottom-sheet/full-screen on mobile
========================================================= */
.modal-backdrop{
  position:fixed; inset:0; background:rgba(4,8,18,0.6);
  display:flex; align-items:center; justify-content:center;
  padding:20px; z-index:100; opacity:0; pointer-events:none;
  transition:opacity .15s ease;
}
.modal-backdrop.open{ opacity:1; pointer-events:auto; }
.modal{
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg);
  width:100%; max-width:520px; display:flex; flex-direction:column;
  /* dvh (dynamic viewport height) excludes mobile browser chrome — plain vh
     is the LARGEST possible viewport, so on a phone with the address bar
     visible a modal sized purely in vh can be taller than what's actually
     on screen, pushing Save/Cancel off the bottom. The vh line is a
     fallback for browsers predating dvh support; dvh wins wherever it's understood. */
  max-height:88vh; max-height:88dvh;
  box-shadow:var(--shadow);
  transform:translateY(8px) scale(.98); opacity:0; transition:transform .16s ease, opacity .16s ease;
}
.modal-backdrop.open .modal{ transform:translateY(0) scale(1); opacity:1; }
.modal.modal-lg{ max-width:760px; }
/* Every modal's header/body/footer sit inside a <form> (see any
   data-modal-open target in the app) — without this rule the form is an
   ordinary block box with no height limit of its own, so .modal's
   max-height just clips the bottom of whatever didn't fit instead of
   letting .modal-body scroll while the header/footer stay put. Making the
   form itself a flex column (and the sole flexible item within .modal)
   is what lets the flex-column/overflow-y:auto pattern below actually work. */
.modal > form{ display:flex; flex-direction:column; min-height:0; flex:1; }
.modal-header{ flex-shrink:0; display:flex; align-items:center; justify-content:space-between; padding:18px 22px; border-bottom:1px solid var(--border); }
.modal-header h3{ font-size:16px; }
.modal-body{ flex:1; min-height:0; padding:22px; overflow-y:auto; }
.modal-footer{ flex-shrink:0; display:flex; justify-content:flex-end; gap:10px; padding:16px 22px; border-top:1px solid var(--border); flex-wrap:wrap; }
.modal-close{ width:32px;height:32px; border-radius:8px; display:flex; align-items:center; justify-content:center; color:var(--ink-faint); cursor:pointer; }
.modal-close:hover{ background:var(--surface-2); color:var(--ink); }

@media (max-width:640px){
  .modal-backdrop{ padding:0; align-items:flex-end; }
  .modal{
    max-width:none; width:100%; max-height:92vh; max-height:92dvh; border-radius:20px 20px 0 0;
    transform:translateY(100%);
  }
  .modal-backdrop.open .modal{ transform:translateY(0); }
  /* Buttons in a modal footer go full-width and stack on a phone rather
     than staying side-by-side and cramped (see .modal-footer's flex-wrap
     above — this makes the stack deliberate/clean instead of an accidental wrap). */
  .modal-footer{ flex-direction:column-reverse; }
  .modal-footer .btn{ width:100%; }
  .modal.modal-fullscreen{ height:100vh; max-height:100vh; border-radius:0; }
}

.confirm-modal .modal-body{ display:flex; gap:14px; align-items:flex-start; }
.confirm-modal .confirm-icon{
  width:40px;height:40px;border-radius:10px;background:var(--bad-bg);color:var(--bad);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
}
.confirm-modal .confirm-icon svg{ width:20px;height:20px; }

/* Small tinted icon chip for card/section headers (TRA dashboard, Tracking Center groups) */
.section-icon{
  width:36px;height:36px;border-radius:10px;background:var(--info-bg);color:var(--info);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
}
.section-icon svg{ width:18px;height:18px; }
.section-icon-sm{ width:26px;height:26px;border-radius:8px; }
.section-icon-sm svg{ width:14px;height:14px; }

/* Tracking Center — one clickable row per result, desktop and mobile alike */
.tc-result-list{ display:flex; flex-direction:column; gap:2px; }
.tc-result-row{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:11px 12px; border-radius:10px; color:var(--ink); text-decoration:none;
}
.tc-result-row:hover{ background:var(--surface-2); }
.tc-result-title{ font-weight:600; font-size:13.5px; }
.tc-result-sub{ font-size:12px; color:var(--ink-faint); margin-top:1px; }
.tc-search-loading{
  display:flex; align-items:center; justify-content:center; gap:10px;
  padding:52px 20px; color:var(--ink-soft); font-size:13.5px;
}
.tc-search-loading .btn-spin{ border-color:var(--border); border-top-color:var(--ink-soft); }
.tc-search-error{
  padding:16px 18px; border-radius:10px; background:var(--bad-bg); color:var(--bad); font-size:13.5px;
}

/* =========================================================
   Toasts
========================================================= */
.toast-stack{
  position:fixed; top:18px; right:18px; z-index:200;
  display:flex; flex-direction:column; gap:10px; width:min(360px, calc(100vw - 36px));
}
@media (max-width:640px){
  .toast-stack{ top:auto; bottom:18px; right:12px; left:12px; width:auto; }
}
.toast{
  background:var(--surface); border:1px solid var(--border); border-left:3px solid var(--good);
  border-radius:12px; padding:12px 14px; box-shadow:var(--shadow);
  display:flex; align-items:flex-start; gap:10px;
  animation:toast-in .18s ease-out;
}
.toast.leaving{ animation:toast-out .15s ease-in forwards; }
@keyframes toast-in{ from{ opacity:0; transform:translateY(-6px);} to{ opacity:1; transform:translateY(0);} }
@keyframes toast-out{ to{ opacity:0; transform:translateX(8px);} }
.toast.toast-error{ border-left-color:var(--bad); }
.toast.toast-info{ border-left-color:var(--info); }
.toast .toast-icon{ width:18px;height:18px; flex-shrink:0; margin-top:1px; }
.toast.toast-success .toast-icon{ color:var(--good); }
.toast.toast-error .toast-icon{ color:var(--bad); }
.toast.toast-info .toast-icon{ color:var(--info); }
.toast .toast-msg{ font-size:13px; flex:1; }
.toast .toast-close{ cursor:pointer; color:var(--ink-faint); }

/* =========================================================
   Login page
========================================================= */
.auth-shell{
  min-height:100vh; display:flex; align-items:center; justify-content:center;
  background:radial-gradient(1200px 600px at 20% -10%, color-mix(in srgb, var(--primary) 18%, transparent), transparent 60%), var(--bg);
  padding:20px;
}
.auth-card{ width:100%; max-width:400px; background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg); box-shadow:var(--shadow); padding:32px 28px; }
.auth-brand{ display:flex; flex-direction:column; align-items:center; gap:10px; margin-bottom:22px; text-align:center; }
.auth-brand .logo-mark{ width:48px;height:48px;border-radius:14px;background:var(--primary);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;font-size:18px; }
.auth-brand h1{ font-size:18px; }
.auth-brand p{ font-size:13px; color:var(--ink-soft); }
.auth-alert{
  background:var(--bad-bg); color:var(--bad); border-radius:10px; padding:10px 14px; font-size:13px; margin-bottom:16px;
  display:flex; gap:8px; align-items:flex-start;
}
.auth-alert svg{ width:16px;height:16px; flex-shrink:0; margin-top:1px; }
/* Informational (not an error): e.g. "Your session has expired. Please log in again." */
.auth-notice{
  background:var(--info-bg, rgba(47,111,237,.12)); color:var(--info, var(--primary)); border-radius:10px; padding:10px 14px; font-size:13px; margin-bottom:16px;
  display:flex; gap:8px; align-items:flex-start;
}
.auth-notice svg{ width:16px;height:16px; flex-shrink:0; margin-top:1px; }

/* Reusable inline validation-error banner for any AJAX form/modal (see
   data-ajax-form handling in app.js) — same visual language as .auth-alert,
   generically named since it isn't specific to the auth pages. */
.modal-alert{
  background:var(--bad-bg); color:var(--bad); border-radius:10px; padding:10px 14px; font-size:13px; margin-bottom:14px;
  display:flex; gap:8px; align-items:flex-start;
}
.modal-alert svg{ width:16px;height:16px; flex-shrink:0; margin-top:1px; }
.modal-alert a{ color:inherit; font-weight:600; text-decoration:underline; }

/* In-app notification bell (topbar) — a small self-contained dropdown,
   styled to match .modal's own surface/border/shadow tokens rather than
   introducing a second visual language for "a panel that floats over the
   page". See initNotifBell() in app.js for the fetch/mark-read behavior. */
.notif-bell-wrap{ position:relative; }
.notif-bell-count{
  position:absolute; top:2px; right:2px; min-width:16px; height:16px; padding:0 4px;
  background:var(--bad); color:#fff; font-size:10.5px; font-weight:700; line-height:16px;
  text-align:center; border-radius:999px;
}
.notif-bell-panel{
  /* Viewport-anchored (position:fixed) so it can never be clipped by the
     topbar / a parent overflow. app.js sets `top` from the live topbar
     height on open; `right`/`left`/`width` come from the breakpoint rules
     below. Desktop = right-aligned popover, mobile = full-width sheet. */
  position:fixed; top:64px; right:16px;
  width:360px; max-width:calc(100vw - 32px); max-height:min(70vh, 560px);
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg);
  box-shadow:var(--shadow); z-index:150; display:flex; flex-direction:column; overflow:hidden;
}
.notif-bell-header-actions{ display:flex; align-items:center; gap:10px; }
.notif-bell-close{
  display:none; background:none; border:none; padding:0; width:24px; height:24px; line-height:1;
  font-size:20px; color:var(--ink-faint); cursor:pointer; border-radius:6px;
}
.notif-bell-close:hover{ color:var(--ink); background:var(--surface-2); }
/* The panel's open/closed state is driven by the [hidden] attribute (toggled
   in app.js). The rule above sets display:flex, which is an author-level
   declaration and therefore overrides the browser's built-in
   [hidden]{display:none}, leaving the panel permanently visible — including
   on page load. This explicit author-level rule restores the intended
   behaviour: hidden attribute present => not rendered. */
.notif-bell-panel[hidden]{ display:none; }
.notif-bell-header{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:12px 14px; border-bottom:1px solid var(--border); font-weight:650; font-size:13.5px;
}
.notif-bell-list{ overflow-y:auto; flex:1; min-height:0; }
.notif-bell-item{ position:relative; display:flex; gap:10px; align-items:flex-start; padding:11px 22px 11px 14px; border-bottom:1px solid var(--border); cursor:pointer; }
a.notif-bell-item{ text-decoration:none; color:inherit; }
.notif-bell-item:last-child{ border-bottom:none; }
.notif-bell-item:hover{ background:var(--surface-2); }
a.activity-row:hover{ background:var(--surface-2); }
.notif-bell-item.unread{ background:color-mix(in srgb, var(--primary) 6%, transparent); }
.notif-bell-item.unread .notif-bell-text{ font-weight:600; }
.notif-bell-item.unread::after{
  content:''; position:absolute; top:15px; right:10px;
  width:7px; height:7px; border-radius:50%; background:var(--primary);
}
.notif-bell-item .notif-bell-icon{ width:30px;height:30px;border-radius:8px; background:var(--surface-2); color:var(--primary); display:flex;align-items:center;justify-content:center; flex-shrink:0; }
.notif-bell-item .notif-bell-icon svg{ width:15px;height:15px; }
.notif-bell-item .notif-bell-text{ font-size:13px; line-height:1.4; min-width:0; overflow-wrap:anywhere; }
.notif-bell-item .notif-bell-title{ font-weight:600; }
.notif-bell-item .notif-bell-detail{ font-size:12px; color:var(--ink-soft); line-height:1.4; }
.notif-bell-item.unread .notif-bell-detail{ font-weight:400; }
.notif-bell-item .notif-bell-time{ font-size:11px; color:var(--ink-faint); margin-top:2px; }
.btn-link{ background:none; border:none; padding:0; color:var(--primary); font-size:12.5px; font-weight:600; cursor:pointer; }
.btn-link:hover{ text-decoration:underline; }
@media (max-width:640px){
  /* Dedicated mobile layout: a full-width panel flush under the topbar,
     not the desktop fixed-width dropdown. No horizontal overflow (left/right
     gutters only), its own vertical scroll area, never clipped. */
  .notif-bell-panel{
    top:56px; left:8px; right:8px; bottom:auto;
    width:auto; max-width:none;
    max-height:calc(100vh - 68px);
    border-radius:14px;
  }
  .notif-bell-close{ display:inline-flex; align-items:center; justify-content:center; }
}

/* Every entity-select Tom Select instance uses dropdownParent:'body' (see
   initEntitySelects() in app.js) specifically so its dropdown can render
   above a modal instead of being clipped by .modal-body's own
   overflow-y:auto — but reparenting to <body> alone isn't enough: Tom
   Select's own stylesheet sets .ts-dropdown to z-index:10, well under
   .modal-backdrop's 100, so without this override the (correctly
   positioned) dropdown would still be hidden behind the modal itself. */
/* ---------------------------------------------------------
   Profile dropdown — the topbar's user-chip button opens this. Same
   viewport-anchored fixed-panel technique as .notif-bell-panel above (JS
   sets `top` from the live topbar height; breakpoints below handle
   left/right/width), so it can never be clipped by a parent's overflow
   and never causes horizontal page scroll on narrow viewports.
--------------------------------------------------------- */
.avatar-lg{ width:44px; height:44px; font-size:16px; flex-shrink:0; }
.profile-dropdown-panel{
  position:fixed; top:64px; right:16px;
  width:300px; max-width:calc(100vw - 32px); max-height:min(80vh, 620px);
  background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-lg);
  box-shadow:var(--shadow); z-index:150; display:flex; flex-direction:column; overflow-y:auto;
}
.profile-dropdown-panel[hidden]{ display:none; }
.profile-panel-header{ display:flex; align-items:center; gap:12px; padding:16px 16px 14px; }
.profile-panel-identity{ min-width:0; }
.profile-panel-name{ font-size:14.5px; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.profile-panel-role{ font-size:12px; color:var(--primary); font-weight:600; margin-top:1px; }
.profile-panel-email{ font-size:12px; color:var(--ink-faint); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.profile-panel-menu{ display:flex; flex-direction:column; padding:6px; }
.profile-panel-item{
  display:flex; align-items:center; gap:10px; padding:9px 10px; border-radius:10px;
  font-size:13.5px; font-weight:600; color:var(--ink); text-decoration:none;
  background:none; border:none; text-align:left; cursor:pointer; width:100%; font-family:inherit;
}
.profile-panel-item svg{ width:17px; height:17px; color:var(--ink-faint); flex-shrink:0; }
.profile-panel-item:hover{ background:var(--surface-2); }
.profile-panel-divider{ height:1px; background:var(--border); margin:2px 12px; }
.profile-panel-theme{ padding:12px 16px; }
.profile-panel-theme-label{ font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-faint); margin-bottom:10px; }
.profile-panel-theme-options{ display:flex; gap:8px; }
.theme-option{
  flex:1; display:flex; flex-direction:column; align-items:center; gap:6px;
  padding:10px 6px; border:1px solid var(--border); border-radius:12px; cursor:pointer;
  font-size:11.5px; font-weight:600; color:var(--ink-soft); position:relative;
}
.theme-option svg{ width:18px; height:18px; }
.theme-option input{ position:absolute; opacity:0; inset:0; margin:0; cursor:pointer; }
.theme-option:has(input:checked){ border-color:var(--primary); background:color-mix(in srgb, var(--primary) 10%, transparent); color:var(--ink); }
.theme-option:has(input:focus-visible){ outline:2px solid var(--primary); outline-offset:1px; }
.profile-panel-signout-form{ padding:6px; }
.profile-panel-signout{ color:var(--bad); }
.profile-panel-signout svg{ color:var(--bad); }
@media (max-width:640px){
  .profile-dropdown-panel{
    top:56px; left:8px; right:8px;
    width:auto; max-width:none;
    max-height:calc(100vh - 68px);
    border-radius:14px;
  }
}

body > .ts-dropdown{ z-index:1000; }
.auth-meta{ text-align:center; margin-top:18px; font-size:12px; color:var(--ink-faint); }

/* =========================================================
   Misc
========================================================= */
.section-title{ font-size:13px; font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:var(--ink-faint); margin:22px 0 10px; }
.section-title:first-child{ margin-top:0; }
.grid-2{ display:grid; grid-template-columns:1fr 1fr; gap:18px; }
@media (max-width:900px){ .grid-2{ grid-template-columns:1fr; } }
.stack{ display:flex; flex-direction:column; gap:16px; }
.row-between{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.divider{ height:1px; background:var(--border); margin:18px 0; }
.pill-list{ display:flex; flex-wrap:wrap; gap:6px; }
.checkbox-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(180px,1fr)); gap:8px 16px; }
.checkbox-item{ display:flex; align-items:center; gap:8px; font-size:13px; }
.checkbox-item input{ width:16px;height:16px; accent-color:var(--primary); }
.module-toggle-row{ display:flex; align-items:center; justify-content:space-between; padding:12px 0; border-bottom:1px solid var(--border); }
.module-toggle-row:last-child{ border-bottom:none; }
.module-toggle-row .m-name{ font-size:13.8px; font-weight:600; }
.module-toggle-row .m-core{ font-size:11px; color:var(--ink-faint); }

.color-preview-bar{ display:flex; height:8px; border-radius:99px; overflow:hidden; margin-top:8px; }
.color-preview-bar span{ flex:1; }

.forbidden-page, .not-found-page{
  min-height:70vh; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:12px; text-align:center; padding:40px;
}
.forbidden-page .code, .not-found-page .code{ font-size:56px; font-weight:800; color:var(--primary); }

.icon-lg{ width:26px; height:26px; }

.theme-icon-light{ display:none; }
:root[data-theme="light"] .theme-icon-dark{ display:none; }
:root[data-theme="light"] .theme-icon-light{ display:inline-flex; }

@media (prefers-reduced-motion: reduce){
  *{ animation-duration:0.001ms !important; transition-duration:0.001ms !important; }
}

/* ---------------------------------------------------------
   Tom Select — retheme the stock CSS onto this app's own tokens instead of
   its default light styling, so it matches .input in both themes.
--------------------------------------------------------- */
.ts-wrapper.single .ts-control, .ts-wrapper.multi .ts-control{
  background:var(--surface-2); border:1px solid var(--border); color:var(--ink);
  border-radius:10px; padding:6px 10px; min-height:42px; box-shadow:none;
}
.ts-wrapper.single.focus .ts-control, .ts-wrapper.focus .ts-control{
  border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 22%, transparent);
}
.ts-control input{ color:var(--ink); }
.ts-control input::placeholder{ color:var(--ink-faint); }
.ts-dropdown{
  background:var(--surface); border:1px solid var(--border); border-radius:10px;
  box-shadow:var(--shadow); color:var(--ink); margin-top:4px; z-index:1200;
}
.ts-dropdown .ts-dropdown-content{ padding:4px; }
.ts-dropdown [data-selectable], .ts-dropdown .no-results, .ts-dropdown .optgroup-header{
  padding:8px 10px; border-radius:8px; font-size:13.5px;
}
.ts-dropdown .active{ background:var(--surface-3); color:var(--ink); }
.ts-dropdown .no-results{ color:var(--ink-faint); }
.ts-wrapper.single .ts-control:after{ border-color:var(--ink-faint) transparent transparent transparent; }
.ts-wrapper .ts-control > .item{ color:var(--ink); background:transparent; }
.ts-wrapper.disabled .ts-control{ opacity:0.6; }
.ts-hidden-accessible{ position:absolute; }
