/* ==========================================================================
   VMS UI Kit — a UniFi-style theme for Bootstrap 5.3
   --------------------------------------------------------------------------
   Layered on top of bootstrap.min.css. Design tokens in :root (light) and
   [data-bs-theme="dark"]. All custom components use the `uf-` prefix;
   Bootstrap components are re-skinned via their own CSS variables.
   ========================================================================== */

/* ---------- Fonts ---------- */
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/inter-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap; src: url("../fonts/inter-latin-500-normal.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; src: url("../fonts/inter-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/inter-latin-700-normal.woff2") format("woff2"); }

/* ---------- Design tokens ---------- */
:root,
[data-bs-theme="light"] {
  --uf-font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* brand — monochrome charcoal for the neutral light palette */
  --uf-primary: #323238;
  --uf-primary-hover: #232328;
  --uf-primary-active: #232328;
  --uf-primary-soft: rgba(50, 50, 56, 0.10);
  --uf-primary-soft-2: rgba(50, 50, 56, 0.18);
  --uf-on-primary: #ffffff;

  /* Bootstrap accent variables — keep utilities/alerts on the neutral ramp */
  --bs-primary: #323238;
  --bs-primary-rgb: 50, 50, 56;
  --bs-primary-text-emphasis: #1f1f1f;
  --bs-primary-bg-subtle: #f5f5f5;
  --bs-primary-border-subtle: #dedede;
  --bs-info: #323238;
  --bs-info-rgb: 50, 50, 56;
  --bs-info-text-emphasis: #1f1f1f;
  --bs-info-bg-subtle: #f5f5f5;
  --bs-info-border-subtle: #dedede;
  --bs-link-color-rgb: 50, 50, 56;
  --bs-link-hover-color-rgb: 35, 35, 40;
  --bs-focus-ring-rgb: 50, 50, 56;

  /* surfaces — soft neutral page with white cards and controls.
     Canvas (--uf-bg) sits one step below surface so white cards, chrome and
     controls read as raised; fills step down from surface so wells, stripes
     and hovers stay legible on both the white card and the gray page. */
  --uf-bg: #f0f0f0;
  --uf-bg-subtle: #ebebeb;
  --uf-bg-muted: #dedede;
  --uf-surface: #ffffff;

  /* lines */
  --uf-border: #d6d6d6;
  --uf-border-light: #e4e4e4;
  --uf-border-strong: #b4b4b4;

  /* text */
  --uf-text-1: #1f1f1f;
  --uf-text-2: #484848;
  --uf-text-3: #707070;

  --bs-heading-color: var(--uf-text-1);

  --uf-auth-bg: #ffffff;

  --uf-auth-visual: linear-gradient(145deg, #323238 0%, #48484d 55%, #707075 100%);

  /* status */
  --uf-green: #2eb872;
  --uf-green-soft: rgba(46, 184, 114, 0.12);
  --uf-orange: #f28c1c;
  --uf-orange-soft: rgba(242, 140, 28, 0.14);
  --uf-red: #e3402e;
  --uf-red-soft: rgba(227, 64, 46, 0.10);

  /* geometry */
  --uf-radius-lg: 12px;
  --uf-radius: 8px;
  --uf-radius-sm: 6px;
  --uf-topbar-h: 48px;
  --uf-footer-h: 44px;
  --uf-rail-w: 64px;

  /* elevation */
  --uf-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
  --uf-shadow-md: 0 4px 14px rgba(0, 0, 0, 0.08);
  --uf-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.14);
  --uf-ring: 0 0 0 3px rgba(50, 50, 56, 0.22);

  /* misc */
  --uf-scrim: rgba(0, 0, 0, 0.55);
  --uf-track: #d8d8d8;
}

[data-bs-theme="dark"] {
  /* fully neutral dark accent — no blue cast.
     NOTE: solid CTA surfaces do NOT use this gray directly in dark mode
     (see .btn-primary / .pagination overrides below: light fill + dark
     text, mirroring light mode's dark fill + white text). --uf-primary
     stays the text/border accent so links and status accents keep their
     distinction from body text. */
  --uf-primary: #949494;
  --uf-primary-hover: #b8b8b8;
  --uf-primary-active: #707070;
  --uf-primary-soft: rgba(148, 148, 148, 0.18);
  --uf-primary-soft-2: rgba(148, 148, 148, 0.28);
  /* Dark text on the gray accent (5.43:1 on #949494, AA) and on the light
     solid-button fills below (13.45:1+ on #E8E8E8, AAA). White here was
     3.03:1 and failed. */
  --uf-on-primary: #1f1f1f;

  /* Bootstrap accent variables — keep utilities/alerts on the neutral ramp */
  --bs-primary: #949494;
  --bs-primary-rgb: 148, 148, 148;
  --bs-primary-text-emphasis: #f5f5f5;
  --bs-primary-bg-subtle: #262626;
  --bs-primary-border-subtle: #3d3d3d;
  --bs-info: #949494;
  --bs-info-rgb: 148, 148, 148;
  --bs-info-text-emphasis: #f5f5f5;
  --bs-info-bg-subtle: #262626;
  --bs-info-border-subtle: #3d3d3d;
  --bs-link-color-rgb: 148, 148, 148;
  --bs-link-hover-color-rgb: 184, 184, 184;
  --bs-focus-ring-rgb: 148, 148, 148;

  --uf-bg: #1f1f1f;
  --uf-bg-subtle: #262626;
  --uf-bg-muted: #2e2e2e;
  --uf-surface: #292929;

  --uf-border: #3d3d3d;
  --uf-border-light: #333333;
  --uf-border-strong: #6a6a6a;

  --uf-text-1: #f5f5f5;
  --uf-text-2: #b8b8b8;
  --uf-text-3: #949494;

  /* Same Bootstrap heading fix as the light block: inherit is invalid on
     <html>, so resolve headings onto the kit text token per theme. */
  --bs-heading-color: var(--uf-text-1);

  /* Login backdrop shares the dashboard app background in dark mode. */
  --uf-auth-bg: var(--uf-bg);

  /* Login illustration panel turns monochrome in dark mode — the dark
     neutral ramp instead of the light slate brand gradient. */
  --uf-auth-visual: linear-gradient(145deg, var(--uf-bg) 0%, var(--uf-bg-subtle) 55%, var(--uf-bg-muted) 100%);

  --uf-green: #37c07c;
  --uf-green-soft: rgba(55, 192, 124, 0.16);
  --uf-orange: #f5a04c;
  --uf-orange-soft: rgba(245, 160, 76, 0.16);
  --uf-red: #ef5b4a;
  --uf-red-soft: rgba(239, 91, 74, 0.16);

  --uf-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --uf-shadow-md: 0 4px 14px rgba(0, 0, 0, 0.45);
  --uf-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.55);
  --uf-ring: 0 0 0 3px rgba(148, 148, 148, 0.45);

  --uf-scrim: rgba(0, 0, 0, 0.62);
  --uf-track: #333333;
}

/* ---------- Bootstrap global re-skin ---------- */
body {
  --bs-body-font-family: var(--uf-font);
  --bs-body-color: var(--uf-text-1);
  --bs-body-bg: var(--uf-bg);
  --bs-border-color: var(--uf-border);
  --bs-link-color: var(--uf-primary);
  --bs-link-hover-color: var(--uf-primary-hover);
  --bs-secondary-color: var(--uf-text-2);
  --bs-tertiary-color: var(--uf-text-3);
  --bs-tertiary-bg: var(--uf-bg-subtle);
  font-size: 0.875rem; /* 14px base */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--uf-primary-soft-2); }

/* Bootstrap utility hovers ship hardcoded blue values; keep them on the theme. */
.link-primary,
.link-info {
  color: var(--uf-primary) !important;
}
.link-primary:hover,
.link-primary:focus,
.link-info:hover,
.link-info:focus {
  color: var(--uf-primary-hover) !important;
}
.text-bg-primary,
.text-bg-info {
  color: var(--uf-on-primary) !important;
  background-color: var(--uf-primary) !important;
}

*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--uf-border-strong); border-radius: 8px; border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-track { background: transparent; }
* { scrollbar-width: thin; scrollbar-color: var(--uf-border-strong) transparent; }

/* ---------- Lucide icon helper ---------- */
svg.lucide, svg.ic { width: 1.15em; height: 1.15em; stroke-width: 1.8; vertical-align: -0.18em; flex: none; }
.ic-12 { width: 12px !important; height: 12px !important; }
.ic-14 { width: 14px !important; height: 14px !important; }
.ic-16 { width: 16px !important; height: 16px !important; }
.ic-18 { width: 18px !important; height: 18px !important; }
.ic-20 { width: 20px !important; height: 20px !important; }
.ic-24 { width: 24px !important; height: 24px !important; }
.ic-32 { width: 32px !important; height: 32px !important; }

/* ==========================================================================
   LAYOUT — top bar / icon rail / shell
   ========================================================================== */
.uf-topbar {
  position: sticky; top: 0; z-index: 1030;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  height: var(--uf-topbar-h);
  padding: 0 12px 0 8px;
  background: var(--uf-surface);
  border-bottom: 1px solid var(--uf-border-light);
}
/* Chrome (topbar + rail) shares the surface token so it stays one step above
   the content canvas in both themes: white on the light gray page, and the
   raised surface on the dark page. Filled inputs keep the subtle token. */
.uf-topbar-side { display: flex; align-items: center; gap: 4px; min-width: 0; }
.uf-topbar-side.is-right { justify-content: flex-end; gap: 8px; }

.uf-brand {
  justify-self: center;
  font-size: 15px; font-weight: 700; letter-spacing: 0.42em; text-indent: 0.42em;
  color: var(--uf-text-3); text-transform: uppercase; text-decoration: none;
  user-select: none;
}
.uf-brand:hover { color: var(--uf-text-2); }

.uf-loc {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 12px; border: 0; border-radius: var(--uf-radius);
  background: transparent; color: var(--uf-text-1);
  font-size: 14px; font-weight: 500; text-decoration: none;
}
.uf-loc { white-space: nowrap; }
.uf-loc:hover { background: var(--uf-bg-muted); }
.uf-loc .lucide { color: var(--uf-text-2); }

.uf-topbar-divider { width: 1px; height: 26px; background: var(--uf-border); margin: 0 6px; flex: none; }

.uf-app {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 12px; border-radius: var(--uf-radius);
  color: var(--uf-text-2); text-decoration: none; font-size: 14px; font-weight: 500;
  white-space: nowrap;
}
.uf-app:hover { background: var(--uf-bg-muted); color: var(--uf-text-1); }
.uf-app .uf-app-label { display: none; }
.uf-app.is-active { color: var(--uf-primary); }
.uf-app.is-active .uf-app-label { display: inline; }

.uf-avatar-btn { width: 32px; height: 32px; padding: 0; border: 0; border-radius: 50%; background: none; }
.uf-avatar-btn img { width: 32px; height: 32px; border-radius: 50%; }
.uf-avatar-btn:hover { box-shadow: 0 0 0 3px var(--uf-primary-soft-2); }

/* icon rail */
.uf-rail {
  position: fixed; top: var(--uf-topbar-h); bottom: 0; left: 0; z-index: 1020;
  display: flex; flex-direction: column; justify-content: space-between;
  width: var(--uf-rail-w);
  padding: 10px 0 12px;
  background: var(--uf-surface);
  border-right: 1px solid var(--uf-border-light);
}
.uf-rail-group { display: flex; flex-direction: column; align-items: center; gap: 6px; }
/* bottom-pinned rail group (kit settings pattern): secondary destinations such
   as user management sit just above the rail footer. margin-top auto absorbs
   the free space that space-between would otherwise distribute, pinning this
   and everything after it to the viewport bottom. An empty group (e.g. no
   permitted entries) collapses so it adds no gap. */
.uf-rail-bottom { margin-top: auto; padding-bottom: 10px; }
.uf-rail-bottom:empty { display: none; }
.uf-rail-item {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 10px;
  color: var(--uf-text-3); text-decoration: none;
}
.uf-rail-item .lucide { width: 21px; height: 21px; }
.uf-rail-item:hover { color: var(--uf-text-1); background: var(--uf-bg-muted); }
.uf-rail-item.is-active { color: var(--uf-text-1); background: var(--uf-bg-muted); }
[data-bs-theme="light"] .uf-rail-item.is-active { color: var(--uf-on-primary); background: var(--uf-primary); }

/* shell = everything right of the rail */
.uf-shell { margin-left: var(--uf-rail-w); min-height: calc(100vh - var(--uf-topbar-h)); }
.uf-page { padding: 20px 28px 40px; }  /* full-bleed like the reference; add max-width + margin-inline:auto for a centered cap */

/* secondary panel column (filters, summary) */
.uf-layout { display: flex; gap: 24px; align-items: flex-start; }
.uf-panel { width: 300px; flex: none; position: sticky; top: calc(var(--uf-topbar-h) + 16px); max-height: calc(100vh - var(--uf-topbar-h) - 32px); overflow-y: auto; }
.uf-panel-wide { width: 340px; }
.uf-content { flex: 1; min-width: 0; }

/* settings-style sub navigation (left column of a settings page) */
.uf-subnav { display: flex; flex-direction: column; gap: 2px; }
.uf-subnav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; border-radius: var(--uf-radius);
  color: var(--uf-text-1); font-size: 14px; font-weight: 500; text-decoration: none;
}
.uf-subnav-item .lucide { color: var(--uf-text-2); }
.uf-subnav-item:hover { background: var(--uf-bg-muted); }
.uf-subnav-item.is-active { background: var(--uf-bg-muted); color: var(--uf-primary); }
.uf-subnav-item.is-active .lucide { color: var(--uf-primary); }
.uf-subnav-title { padding: 18px 12px 6px; font-size: 13px; color: var(--uf-text-3); }

/* ==========================================================================
   CARDS
   ========================================================================== */
.card {
  --bs-card-border-color: var(--uf-border);
  --bs-card-border-radius: var(--uf-radius-lg);
  --bs-card-inner-border-radius: calc(var(--uf-radius-lg) - 1px);
  --bs-card-cap-bg: transparent;
  --bs-card-bg: var(--uf-surface);
  box-shadow: var(--uf-shadow-sm);
}
.card-header { border-bottom: 1px solid var(--uf-border-light); padding: 14px 18px; }
.card-body { padding: 18px; }

.uf-card-title {
  display: flex; align-items: center; gap: 9px;
  font-size: 14.5px; font-weight: 600; color: var(--uf-text-1); margin: 0;
}
.uf-card-title .lucide { color: var(--uf-text-2); }

/* ==========================================================================
   BUTTONS
   ========================================================================== */
.btn {
  --bs-btn-font-size: 14px;
  --bs-btn-font-weight: 500;
  --bs-btn-border-radius: var(--uf-radius);
  --bs-btn-padding-y: 0.45rem;
  --bs-btn-padding-x: 1rem;
  --bs-btn-focus-box-shadow: var(--uf-ring);
  transition: background-color 0.15s, color 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.btn-sm { --bs-btn-padding-y: 0.3rem; --bs-btn-padding-x: 0.7rem; --bs-btn-font-size: 13px; }

.btn-primary {
  --bs-btn-color: var(--uf-on-primary);
  --bs-btn-hover-color: var(--uf-on-primary);
  --bs-btn-active-color: var(--uf-on-primary);
  --bs-btn-disabled-color: var(--uf-on-primary);
  --bs-btn-bg: var(--uf-primary);
  --bs-btn-border-color: var(--uf-primary);
  --bs-btn-hover-bg: var(--uf-primary-hover);
  --bs-btn-hover-border-color: var(--uf-primary-hover);
  --bs-btn-active-bg: var(--uf-primary-active);
  --bs-btn-active-border-color: var(--uf-primary-active);
  --bs-btn-disabled-bg: var(--uf-primary);
  --bs-btn-disabled-border-color: var(--uf-primary);
  --bs-btn-focus-shadow-0: none;
}
.btn-primary:focus-visible { box-shadow: var(--uf-ring); }

/* Dark mode solid CTA: light fill + dark text, mirroring light mode's dark
   fill + white text (12.74:1). The global gray accent stays for text/border
   accents; only the solid fill is inverted here so the CTA keeps its
   prominence on the dark page (#E8E8E8 on #1F1F1F = 13.45:1, AAA).
   Light mode is untouched (charcoal fill + white text). */
[data-bs-theme="dark"] .btn-primary {
  --bs-btn-bg: #e8e8e8;
  --bs-btn-border-color: #e8e8e8;
  --bs-btn-hover-bg: #ffffff;
  --bs-btn-hover-border-color: #ffffff;
  --bs-btn-active-bg: #cfcfcf;
  --bs-btn-active-border-color: #cfcfcf;
}

/* UniFi's neutral secondary: white with light border */
.btn-default {
  --bs-btn-color: var(--uf-text-1);
  --bs-btn-bg: var(--uf-surface);
  --bs-btn-border-color: var(--uf-border);
  --bs-btn-hover-color: var(--uf-text-1);
  --bs-btn-hover-bg: var(--uf-bg-subtle);
  --bs-btn-hover-border-color: var(--uf-border-strong);
  --bs-btn-active-color: var(--uf-text-1);
  --bs-btn-active-bg: var(--uf-bg-muted);
  --bs-btn-active-border-color: var(--uf-border-strong);
}
.btn-ghost {
  --bs-btn-color: var(--uf-text-2);
  --bs-btn-border-color: transparent;
  --bs-btn-hover-color: var(--uf-text-1);
  --bs-btn-hover-bg: var(--uf-bg-muted);
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: var(--uf-text-1);
  --bs-btn-active-bg: var(--uf-bg-muted);
  --bs-btn-active-border-color: transparent;
}
.btn-link { --bs-btn-color: var(--uf-primary); --bs-btn-hover-color: var(--uf-primary-hover); font-weight: 500; text-decoration: none; }

/* Themed outline variants: Bootstrap's outline buttons ship hardcoded vendor
   borders that clash with the UniFi palette and with themed inputs inside
   input-groups, where the -1px seam overlap stacks them into mismatched
   outlines. Remap them onto `uf-` tokens so borders, text, and hover fills
   match the theme in both light and dark modes.
   (Focus rings already resolve to var(--uf-ring) via `.btn`.) */
.btn-outline-secondary {
  --bs-btn-color: var(--uf-text-2);
  --bs-btn-border-color: var(--uf-border-strong);
  --bs-btn-hover-color: var(--uf-text-1);
  --bs-btn-hover-bg: var(--uf-bg-muted);
  --bs-btn-hover-border-color: var(--uf-border-strong);
  --bs-btn-active-color: var(--uf-text-1);
  --bs-btn-active-bg: var(--uf-bg-muted);
  --bs-btn-active-border-color: var(--uf-border-strong);
  --bs-btn-disabled-color: var(--uf-text-3);
  --bs-btn-disabled-bg: transparent;
  --bs-btn-disabled-border-color: var(--uf-border);
}
.btn-outline-danger {
  --bs-btn-color: var(--uf-red);
  --bs-btn-border-color: var(--uf-red);
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--uf-red);
  --bs-btn-hover-border-color: var(--uf-red);
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: var(--uf-red);
  --bs-btn-active-border-color: var(--uf-red);
  --bs-btn-disabled-color: var(--uf-red);
  --bs-btn-disabled-bg: transparent;
  --bs-btn-disabled-border-color: var(--uf-red);
}
.btn-outline-primary {
  --bs-btn-color: var(--uf-primary);
  --bs-btn-border-color: var(--uf-primary);
  --bs-btn-hover-color: var(--uf-on-primary);
  --bs-btn-hover-bg: var(--uf-primary);
  --bs-btn-hover-border-color: var(--uf-primary);
  --bs-btn-active-color: var(--uf-on-primary);
  --bs-btn-active-bg: var(--uf-primary);
  --bs-btn-active-border-color: var(--uf-primary);
  --bs-btn-disabled-color: var(--uf-primary);
  --bs-btn-disabled-bg: transparent;
  --bs-btn-disabled-border-color: var(--uf-primary);
}

.uf-link { color: var(--uf-primary); font-weight: 500; text-decoration: none; cursor: pointer; }
.uf-link:hover { color: var(--uf-primary-hover); text-decoration: underline; }
.uf-link.is-danger { color: var(--uf-red); }
.uf-link.is-danger:hover { color: var(--uf-red); }

.uf-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  border: 0; border-radius: var(--uf-radius);
  background: transparent; color: var(--uf-text-2);
}
.uf-icon-btn:hover { background: var(--uf-bg-muted); color: var(--uf-text-1); }
.uf-icon-btn.is-active { color: var(--uf-primary); background: var(--uf-primary-soft); }

/* square selectable "mode" tiles (Face ID / LPR / Objects / ...) */
.uf-tile-btn {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
  min-width: 82px; min-height: 72px; padding: 10px 12px;
  background: var(--uf-surface); border: 1px solid var(--uf-border); border-radius: 10px;
  color: var(--uf-text-1); font-size: 13px; font-weight: 500;
  transition: border-color 0.15s, color 0.15s, background-color 0.15s;
}
.uf-tile-btn .lucide { width: 21px; height: 21px; color: var(--uf-text-2); transition: color 0.15s; }
.uf-tile-btn:hover { border-color: var(--uf-border-strong); background: var(--uf-bg-subtle); }
.uf-tile-btn.is-selected,
.uf-tile-btn[aria-pressed="true"] { border-color: var(--uf-primary); color: var(--uf-primary); box-shadow: inset 0 0 0 1px var(--uf-primary); background: var(--uf-surface); }
.uf-tile-btn.is-selected .lucide,
.uf-tile-btn[aria-pressed="true"] .lucide { color: var(--uf-primary); }

/* view toggle (list / grid) */
.uf-view-toggle { display: inline-flex; gap: 2px; }

/* ==========================================================================
   SEGMENTED CONTROL — built on Bootstrap's btn-check radio pattern:
   <div class="uf-seg"> <input class="btn-check"> <label class="btn uf-seg-btn"> …
   ========================================================================== */
.uf-seg { display: inline-flex; padding: 3px; gap: 2px; background: var(--uf-bg-muted); border-radius: 10px; }
.uf-seg .uf-seg-btn {
  --bs-btn-padding-y: 0.32rem;
  --bs-btn-padding-x: 0.95rem;
  --bs-btn-font-size: 13.5px;
  --bs-btn-font-weight: 500;
  --bs-btn-color: var(--uf-text-2);
  --bs-btn-hover-color: var(--uf-text-1);
  --bs-btn-hover-bg: transparent;
  --bs-btn-hover-border-color: transparent;
  --bs-btn-active-color: var(--uf-primary);
  --bs-btn-active-bg: var(--uf-surface);
  --bs-btn-active-border-color: transparent;
  --bs-btn-border-width: 0;
  --bs-btn-border-radius: 7px;
  --bs-btn-focus-box-shadow: var(--uf-ring);
  --bs-btn-box-shadow: none;
  display: inline-flex; align-items: center; justify-content: center;
  white-space: nowrap;
  transition: background-color 0.15s, color 0.15s, box-shadow 0.15s;
}
.uf-seg .btn-check:checked + .uf-seg-btn { box-shadow: var(--uf-shadow-sm); }
.uf-seg.is-block { display: flex; }
.uf-seg.is-block .uf-seg-btn { flex: 1; justify-content: center; }

/* ==========================================================================
   BADGES · DOTS · CHIPS · AVATARS
   ========================================================================== */
.badge { font-weight: 500; letter-spacing: 0.01em; }
.uf-badge { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 999px; font-size: 12px; font-weight: 500; line-height: 1.4; }
.uf-badge.is-primary { color: var(--uf-primary); background: var(--uf-primary-soft); }
.uf-badge.is-green   { color: var(--uf-green); background: var(--uf-green-soft); }
.uf-badge.is-orange  { color: var(--uf-orange); background: var(--uf-orange-soft); }
.uf-badge.is-red     { color: var(--uf-red); background: var(--uf-red-soft); }
.uf-badge.is-gray    { color: var(--uf-text-2); background: var(--uf-bg-muted); }

.uf-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: none; }
.uf-dot.is-green { background: var(--uf-green); }
.uf-dot.is-red { background: var(--uf-red); }
.uf-dot.is-orange { background: var(--uf-orange); }
.uf-dot.is-gray { background: var(--uf-border-strong); }

.uf-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 10px;
  background: var(--uf-bg-subtle); border: 1px solid var(--uf-border); border-radius: var(--uf-radius);
  font-size: 13.5px; font-weight: 500; color: var(--uf-text-1);
}
.uf-chip .lucide { color: var(--uf-text-2); }
.uf-chip-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; margin-right: -3px; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: var(--uf-text-3);
}
.uf-chip-close:hover { color: var(--uf-text-1); background: var(--uf-bg-muted); }
.uf-chip-close .lucide { width: 12px; height: 12px; }

.uf-avatar { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; flex: none; }
.uf-avatar.is-lg { width: 32px; height: 32px; }
.uf-avatar.is-xl { width: 44px; height: 44px; }

/* ==========================================================================
   FORMS
   ========================================================================== */
.form-label, label.uf-label { font-size: 13px; font-weight: 500; color: var(--uf-text-2); margin-bottom: 6px; }

.form-control, .form-select {
  background-color: var(--uf-bg-subtle);
  border: 1px solid var(--uf-border);
  border-radius: var(--uf-radius);
  color: var(--uf-text-1);
  font-size: 14px;
  padding: 0.45rem 0.8rem;
  transition: background-color 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.form-control::placeholder { color: var(--uf-text-3); }
.form-control:hover, .form-select:hover { border-color: var(--uf-border-strong); }
.form-control:focus, .form-select:focus {
  background-color: var(--uf-surface);
  border-color: var(--uf-primary);
  box-shadow: var(--uf-ring);
  color: var(--uf-text-1);
}
.form-control:disabled, .form-select:disabled { background-color: var(--uf-bg-muted); color: var(--uf-text-3); }
.form-select {
  --bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23707070' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  background-position: right 0.8rem center; background-size: 14px 14px; padding-right: 2.2rem;
}
/* Small control scale: the base rule above ties with Bootstrap's
   `.form-*-sm` on specificity and wins on source order, so re-assert
   the small scale here (same file = kit level, not a page override).
   sizing mirrors `.btn-sm` so inline filter rows (small select beside
   a small button, e.g. the pager and the table filters) align. */
.form-control-sm, .form-select-sm {
  font-size: 13px;
  padding: 0.3rem 0.7rem;
}
.form-select-sm {
  padding-right: 2rem;
  background-size: 12px 12px;
}
/* dark chevron follows the monochrome text-3; light follows the neutral ramp */
[data-bs-theme="dark"] .form-select {
  --bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%2395948f' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}
.input-group-text { background: var(--uf-bg-subtle); border: 1px solid var(--uf-border); color: var(--uf-text-3); border-radius: var(--uf-radius); }

/* search field built on Bootstrap input-group: icon addon + input form one filled surface
   <div class="input-group uf-search"> <span class="input-group-text">icon</span> <input class="form-control"> */
.uf-search { border: 1px solid var(--uf-border); border-radius: var(--uf-radius); }
.uf-search:hover { border-color: var(--uf-border-strong); }
.uf-search .input-group-text { background: var(--uf-bg-subtle); border: 0; color: var(--uf-text-3); padding-left: 12px; padding-right: 8px; }
.uf-search .form-control { border-color: transparent; border-left: 0; padding-left: 2px; background: var(--uf-bg-subtle); }
.uf-search .form-control:hover { border-color: transparent; }
.uf-search .form-control::-webkit-search-cancel-button { -webkit-appearance: none; }
.uf-search:focus-within { border-color: var(--uf-primary); box-shadow: var(--uf-ring); }
.uf-search:focus-within .input-group-text,
.uf-search:focus-within .form-control { background: var(--uf-surface); }

.form-check-input {
  border: 1.5px solid var(--uf-border-strong);
  width: 1.06em; height: 1.06em; margin-top: 0.22em;
}
.form-check-input:checked { background-color: var(--uf-primary); border-color: var(--uf-primary); }
.form-check-input[type="checkbox"] { border-radius: 4px; }
.form-check-input[type="radio"] { border-radius: 50%; }
.form-check-input:focus { border-color: var(--uf-primary); box-shadow: var(--uf-ring); }
.form-check:not(.form-switch) .form-check-input:not(:checked):focus { background-color: transparent; }
.form-check-label { font-size: 14px; color: var(--uf-text-1); padding-top: 1px; }

.form-switch .form-check-input { width: 2.2em; height: 1.2em; border-radius: 999px; border-color: transparent; background-color: var(--uf-border-strong); background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23ffffff'/%3e%3c/svg%3e"); }
.form-switch .form-check-input:checked { background-color: var(--uf-primary); border-color: var(--uf-primary); }
.form-switch .form-check-input:focus { background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23ffffff'/%3e%3c/svg%3e"); }

/* range slider — JS paints the filled track */
.form-range { height: 22px; }
.form-range::-webkit-slider-runnable-track { height: 5px; border-radius: 999px; background: var(--uf-range-fill, var(--uf-track)); }
.form-range::-webkit-slider-thumb {
  width: 17px; height: 17px; margin-top: -6px;
  background: var(--uf-surface); border: 1.5px solid var(--uf-border-strong);
  box-shadow: var(--uf-shadow-sm); appearance: none; border-radius: 50%;
}
.form-range::-webkit-slider-thumb:hover { border-color: var(--uf-primary); }
.form-range:focus::-webkit-slider-thumb { box-shadow: var(--uf-ring); }
.form-range::-moz-range-track { height: 5px; border-radius: 999px; background: var(--uf-track); }
.form-range::-moz-range-progress { height: 5px; border-radius: 999px; background: var(--uf-primary); }
.form-range::-moz-range-thumb { width: 15px; height: 15px; background: var(--uf-surface); border: 1.5px solid var(--uf-border-strong); border-radius: 50%; }

/* ==========================================================================
   TABLES
   ========================================================================== */
.table {
  --bs-table-color: var(--uf-text-1);
  --bs-table-bg: transparent;
  --bs-table-border-color: var(--uf-border-light);
  --bs-table-hover-bg: var(--uf-bg-subtle);
  --bs-table-hover-color: var(--uf-text-1);
  margin-bottom: 0;
}
.table thead th {
  font-size: 13px; font-weight: 600; color: var(--uf-text-2);
  padding: 10px 14px; border-bottom: 1px solid var(--uf-border); white-space: nowrap;
}
.table tbody td { padding: 13px 14px; vertical-align: middle; font-size: 14px; }
.table tbody tr { transition: background-color 0.12s; }
.table tbody tr:hover { background-color: var(--uf-bg-subtle); }
.uf-table-clickable tbody tr { cursor: pointer; }

/* ==========================================================================
   DROPDOWN · MODAL · POPOVER
   ========================================================================== */
.dropdown-menu {
  --bs-dropdown-border-color: var(--uf-border);
  --bs-dropdown-border-radius: 10px;
  --bs-dropdown-bg: var(--uf-surface);
  --bs-dropdown-link-hover-bg: var(--uf-bg-muted);
  --bs-dropdown-link-hover-color: var(--uf-text-1);
  --bs-dropdown-link-active-bg: var(--uf-primary-soft);
  --bs-dropdown-link-active-color: var(--uf-primary);
  --bs-dropdown-link-color: var(--uf-text-2);
  --bs-dropdown-box-shadow: var(--uf-shadow-lg);
  --bs-dropdown-padding-y: 6px;
  font-size: 14px;
}
/* Vertical rhythm matches the left rail (.uf-rail-group gap): options,
   headers and dividers breathe instead of stacking flush. Bootstrap
   re-asserts display:block on .show, so the flex column lives on the same
   selector where it ties and wins by load order (no !important). */
.dropdown-menu.show { display: flex; flex-direction: column; gap: 6px; }
.dropdown-item { display: flex; align-items: center; gap: 9px; padding: 7px 12px; border-radius: 7px; margin: 0 4px; width: auto; }
.dropdown-item .lucide { color: var(--uf-text-2); }
/* Hover/focus mirrors the left-rail row hover (.uf-rail .nav-link:hover):
   muted fill with text-1 text and icons, unlike the primary-soft active pill. */
.dropdown-item:hover .lucide, .dropdown-item:focus .lucide { color: var(--uf-text-1); }
.dropdown-header { font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--uf-text-3); }

.modal {
  --bs-modal-bg: var(--uf-surface);
  --bs-modal-border-radius: 16px;
}
.modal-content { border: 1px solid var(--uf-border); border-radius: 16px; box-shadow: var(--uf-shadow-lg); background: var(--uf-surface); }
.modal-header { border-bottom: 0; padding: 22px 24px 4px; justify-content: center; position: relative; }
.modal-title { font-size: 16px; font-weight: 600; }
.modal-header .btn-close { position: absolute; right: 18px; top: 18px; }
.modal-body { padding: 14px 28px 8px; }
.modal-footer { border-top: 0; padding: 16px 28px 24px; justify-content: center; gap: 10px; }
.btn-close { filter: none; opacity: 0.55; }
.btn-close:hover { opacity: 1; }
[data-bs-theme="dark"] .btn-close { filter: invert(1) grayscale(100%) brightness(200%); }
.modal-backdrop { --bs-backdrop-opacity: 0.45; }

.tooltip { --bs-tooltip-bg: var(--uf-text-1); --bs-tooltip-color: var(--uf-bg); --bs-tooltip-border-radius: 8px; --bs-tooltip-font-size: 12px; --bs-tooltip-opacity: 1; }
.popover { --bs-popover-border-color: var(--uf-border); --bs-popover-border-radius: 10px; --bs-popover-bg: var(--uf-surface); --bs-popover-box-shadow: var(--uf-shadow-lg); font-size: 13px; }
.popover-header { background: var(--uf-bg-subtle); font-size: 13px; }

/* ==========================================================================
   FILTER PANEL PIECES
   ========================================================================== */
.uf-filter-group { border-bottom: 1px solid var(--uf-border-light); padding: 4px 0; }
.uf-filter-group:last-child { border-bottom: 0; }
.uf-collapse-toggle {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  padding: 10px 2px; border: 0; background: none;
  font-size: 14px; font-weight: 600; color: var(--uf-text-1); text-align: left;
}
.uf-collapse-toggle .lucide { color: var(--uf-text-3); transition: transform 0.18s ease; }
.uf-collapse-toggle[aria-expanded="false"] .lucide { transform: rotate(180deg); }
.uf-collapse-toggle.is-flush { padding: 0 0 10px; }
.uf-filter-body { padding: 2px 2px 14px; }

.uf-check-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 10px; }
.uf-check-grid.is-one-col { grid-template-columns: 1fr; }
.uf-check-row { display: flex; align-items: center; gap: 9px; font-size: 14px; color: var(--uf-text-1); cursor: pointer; }
.uf-check-row .form-check-input { margin: 0; flex: none; }
.uf-check-row .lucide { color: var(--uf-text-2); }

/* time-range segmented pills */
.uf-rangebar { display: flex; align-items: center; gap: 8px; }
.uf-rangebar .uf-seg { flex: 1; }
.uf-rangebar .uf-seg .uf-seg-btn { --bs-btn-padding-x: 0; min-width: 46px; flex: 1; }

/* color swatches */
.uf-swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.uf-swatch {
  width: 22px; height: 22px; border-radius: 6px; padding: 0;
  border: 1px solid var(--uf-border); cursor: pointer;
  transition: box-shadow 0.12s, transform 0.12s;
}
.uf-swatch.is-empty { background: var(--uf-surface); position: relative; }
.uf-swatch.is-empty::after { content: ""; position: absolute; inset: 0; margin: auto; width: 12px; height: 1.5px; background: var(--uf-border-strong); transform: rotate(-45deg); }
.uf-swatch:hover { transform: scale(1.08); }
.uf-swatch.is-selected { box-shadow: 0 0 0 2px var(--uf-surface), 0 0 0 4px var(--uf-primary); }

/* device/camera list rows inside a panel */
.uf-devlist { display: flex; flex-direction: column; }
.uf-devlist-item { display: flex; align-items: center; gap: 10px; padding: 9px 4px; border-radius: var(--uf-radius); font-size: 14px; color: var(--uf-text-1); }
.uf-devlist-item:hover { background: var(--uf-bg-subtle); }
.uf-devlist-item .lucide { color: var(--uf-text-2); }
.uf-devlist-count { margin-left: auto; color: var(--uf-text-3); font-size: 13px; display: inline-flex; align-items: center; gap: 4px; }

/* ==========================================================================
   VIDEO / CAMERA TILES
   ========================================================================== */
.uf-tile {
  position: relative; display: block; overflow: hidden;
  border-radius: 10px; background: var(--uf-bg-muted);
  aspect-ratio: 16 / 9;
}
.uf-tile img.uf-tile-img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.35s ease; }
.uf-tile:hover img.uf-tile-img { transform: scale(1.035); }
.uf-tile::after { /* legibility scrims */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(18, 18, 20, 0.62) 0%, rgba(18, 18, 20, 0) 34%),
              linear-gradient(0deg, rgba(18, 18, 20, 0.38) 0%, rgba(18, 18, 20, 0) 26%);
}
.uf-tile-top { position: absolute; z-index: 2; top: 9px; left: 11px; right: 11px; color: #fff; }
.uf-tile-title { font-size: 13px; font-weight: 600; line-height: 1.25; text-shadow: 0 1px 3px rgba(0,0,0,0.4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.uf-tile-sub { font-size: 11.5px; font-weight: 400; opacity: 0.85; text-shadow: 0 1px 2px rgba(0,0,0,0.4); }
.uf-tile-bottom { position: absolute; z-index: 2; bottom: 9px; left: 11px; right: 11px; display: flex; align-items: flex-end; justify-content: space-between; gap: 8px; }
.uf-tile-tag {
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(30, 30, 33, 0.72); color: #fff;
  font-size: 11.5px; font-weight: 500; padding: 3px 8px; border-radius: 6px;
  backdrop-filter: blur(3px); white-space: nowrap;
}
.uf-tile-tag .lucide { width: 13px; height: 13px; }
.uf-tile-actions { position: absolute; z-index: 3; top: 8px; right: 8px; display: flex; gap: 4px; opacity: 0; transition: opacity 0.15s; }
.uf-tile:hover .uf-tile-actions { opacity: 1; }
.uf-tile-actions .uf-icon-btn { background: rgba(30, 30, 33, 0.72); color: #fff; }
.uf-tile-actions .uf-icon-btn:hover { background: rgba(30, 30, 33, 0.92); }
.uf-tile.is-live::before {
  content: ""; position: absolute; z-index: 2; top: 12px; right: 12px;
  width: 8px; height: 8px; border-radius: 50%; background: var(--uf-red);
  box-shadow: 0 0 0 0 rgba(227, 64, 46, 0.5); animation: uf-pulse 2s infinite;
}
@keyframes uf-pulse {
  0% { box-shadow: 0 0 0 0 rgba(227, 64, 46, 0.45); }
  70% { box-shadow: 0 0 0 7px rgba(227, 64, 46, 0); }
  100% { box-shadow: 0 0 0 0 rgba(227, 64, 46, 0); }
}
@media (prefers-reduced-motion: reduce) { .uf-tile.is-live::before { animation: none; } }

/* access-style camera card: image + caption row + lock button */
.uf-cam-card {
  border: 1px solid var(--uf-border); border-radius: var(--uf-radius-lg);
  background: var(--uf-surface); overflow: hidden;
  transition: box-shadow 0.15s, transform 0.15s;
}
.uf-cam-card:hover { box-shadow: var(--uf-shadow-md); }
.uf-cam-card .uf-cam-thumb { position: relative; aspect-ratio: 16/10; overflow: hidden; background: var(--uf-bg-muted); }
.uf-cam-card .uf-cam-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.uf-cam-card .uf-cam-play {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: rgba(255,255,255,0.85); background: rgba(0,0,0,0.12); border: 0; width: 100%;
}
.uf-cam-card .uf-cam-play .lucide { width: 34px; height: 34px; filter: drop-shadow(0 2px 6px rgba(0,0,0,0.5)); }
.uf-cam-body { display: flex; align-items: center; gap: 10px; padding: 11px 13px; }
.uf-cam-name { font-size: 14px; font-weight: 600; color: var(--uf-text-1); line-height: 1.2; }
.uf-cam-status { font-size: 12.5px; color: var(--uf-text-2); margin-top: 2px; }
.uf-lock-btn {
  margin-left: auto; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--uf-border);
  background: transparent; color: var(--uf-text-2); text-decoration: none;
}
.uf-lock-btn.is-locked { background: #3d3d3d; border-color: #3d3d3d; color: #fff; }
.uf-lock-btn.is-open { background: var(--uf-primary); border-color: var(--uf-primary); color: var(--uf-on-primary); }
.uf-lock-btn.is-warning { background: transparent; border-color: var(--uf-orange); color: var(--uf-orange); }

/* responsive tile grids (containers for generated tiles) */
.uf-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(235px, 1fr)); }
.uf-grid.is-cams { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.uf-grid.is-dense { gap: 10px; }

/* ==========================================================================
   STATS · FEED · MINIBAR CHART
   ========================================================================== */
.uf-stat { display: flex; align-items: center; gap: 12px; padding: 4px 0; }
.uf-stat-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 10px;
  background: var(--uf-primary-soft); color: var(--uf-primary); flex: none;
}
.uf-stat-icon.is-green { background: var(--uf-green-soft); color: var(--uf-green); }
.uf-stat-icon.is-orange { background: var(--uf-orange-soft); color: var(--uf-orange); }
.uf-stat-value { font-size: 20px; font-weight: 600; color: var(--uf-text-1); line-height: 1.15; }
.uf-stat-label { font-size: 13px; color: var(--uf-text-2); }

.uf-feed { display: flex; flex-direction: column; }
.uf-feed-item { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--uf-border-light); font-size: 14px; }
.uf-feed-item:last-child { border-bottom: 0; }
.uf-feed-text { min-width: 0; flex: 1; }
.uf-feed-title { font-weight: 500; color: var(--uf-text-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.uf-feed-sub { font-size: 12.5px; color: var(--uf-text-3); }
.uf-feed-time { margin-left: auto; flex: none; font-size: 13px; color: var(--uf-text-3); white-space: nowrap; }

/* pure-CSS bar chart */
.uf-minibars { display: flex; align-items: flex-end; gap: 4px; height: 110px; padding-top: 6px; }
.uf-minibars .bar { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; gap: 2px; border-radius: 3px; background: var(--uf-primary-soft-2); min-height: 4px; position: relative; }
.uf-minibars .bar .hot { background: var(--uf-primary); border-radius: 3px; }
.uf-minibars .bar .alert { background: var(--uf-red); border-radius: 3px 3px 0 0; }
.uf-minibars .bar:hover { outline: 1.5px solid var(--uf-primary); outline-offset: 1px; }
.uf-axis { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--uf-text-3); margin-top: 6px; }

/* ==========================================================================
   WEEKLY SCHEDULE GRID
   ========================================================================== */
.uf-sched-hours { display: grid; grid-template-columns: repeat(24, 1fr); flex: 1; }
.uf-sched-hours span { font-size: 11.5px; color: var(--uf-text-3); grid-column: span 4; padding-left: 2px; white-space: nowrap; }
.uf-sched-row { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.uf-sched-day { width: 34px; flex: none; font-size: 12px; color: var(--uf-text-3); }
.uf-sched-cells {
  flex: 1; display: grid; grid-template-columns: repeat(24, 1fr);
  border: 1px solid var(--uf-border); border-radius: 7px; overflow: hidden; background: var(--uf-surface);
  touch-action: none; user-select: none;
}
.uf-sched-cell { height: 30px; border-left: 1px solid var(--uf-border-light); cursor: pointer; transition: background-color 0.08s; }
.uf-sched-cell:first-child { border-left: 0; }
.uf-sched-cell:nth-child(4n+1):not(:first-child) { border-left-color: var(--uf-border); }
.uf-sched-cell:hover { background: var(--uf-primary-soft); }
.uf-sched-cell.is-on { background: var(--uf-primary-soft); box-shadow: inset 0 0 0 1px var(--uf-primary-soft-2), inset 0 -2px 0 var(--uf-primary); }
.uf-sched-cell.is-on:hover { background: var(--uf-primary-soft-2); }

/* ==========================================================================
   NAVS · TABS · BREADCRUMB · PAGINATION · PROGRESS · ALERTS
   ========================================================================== */
/* underline tabs — a UniFi skin over Bootstrap .nav-tabs */
.nav-tabs {
  --bs-nav-tabs-border-width: 0;
  --bs-nav-tabs-link-active-color: var(--uf-primary);
  --bs-nav-tabs-link-active-bg: transparent;
  --bs-nav-tabs-link-active-border-color: transparent transparent var(--uf-primary);
  --bs-nav-tabs-link-hover-border-color: transparent;
  --bs-nav-tabs-border-color: var(--uf-border);
  gap: 22px;
}
.nav-tabs .nav-link {
  padding: 9px 2px; margin-bottom: -1px; border-bottom-width: 2px;
  font-size: 14px; font-weight: 500; color: var(--uf-text-2);
}

.breadcrumb { font-size: 13.5px; --bs-breadcrumb-divider-color: var(--uf-text-3); margin: 0; }
.breadcrumb-item a { color: var(--uf-primary); text-decoration: none; font-weight: 500; }
.breadcrumb-item.active { color: var(--uf-text-2); }

.pagination { --bs-pagination-border-width: 0; --bs-pagination-border-radius: 8px; --bs-pagination-color: var(--uf-text-2); --bs-pagination-hover-bg: var(--uf-bg-muted); --bs-pagination-hover-color: var(--uf-text-1); --bs-pagination-active-bg: var(--uf-primary); --bs-pagination-active-border-color: var(--uf-primary); --bs-pagination-active-color: var(--uf-on-primary); --bs-pagination-focus-box-shadow: var(--uf-ring); gap: 3px; }
/* Dark mode active page: same light-fill + dark-text inversion as .btn-primary
   so the current page stays prominent and AAA-readable. Light mode keeps the
   charcoal fill + white text. */
[data-bs-theme="dark"] .pagination { --bs-pagination-active-bg: #e8e8e8; --bs-pagination-active-border-color: #e8e8e8; }
.page-link { border-radius: 8px !important; font-size: 13.5px; font-weight: 500; }

.progress { --bs-progress-height: 6px; --bs-progress-bg: var(--uf-track); --bs-progress-border-radius: 999px; --bs-progress-bar-bg: var(--uf-primary); }

.alert { border-radius: 10px; border-width: 1px; font-size: 14px; --bs-alert-padding-x: 14px; --bs-alert-padding-y: 12px; }
.alert-primary { --bs-alert-color: var(--uf-primary); --bs-alert-bg: var(--uf-primary-soft); --bs-alert-border-color: transparent; }
.alert-danger { --bs-alert-color: var(--uf-red); --bs-alert-bg: var(--uf-red-soft); --bs-alert-border-color: transparent; }
.alert-warning { --bs-alert-color: var(--uf-orange); --bs-alert-bg: var(--uf-orange-soft); --bs-alert-border-color: transparent; }
.alert-success { --bs-alert-color: var(--uf-green); --bs-alert-bg: var(--uf-green-soft); --bs-alert-border-color: transparent; }

/* ==========================================================================
   TOASTS — token-driven variant pattern consumed by the shared Toast.show
   builder (static/js/toast.js). The variant class on the toast root tints the
   header with the matching soft/status pair; the body stays on the surface so
   messages read in both light and dark modes.
   ========================================================================== */
.toast { --bs-toast-bg: var(--uf-surface); --bs-toast-color: var(--uf-text-1); --bs-toast-border-color: var(--uf-border); --bs-toast-header-bg: var(--uf-bg-subtle); --bs-toast-header-color: var(--uf-text-1); --bs-toast-header-border-color: var(--uf-border-light); }
.toast-success .toast-header { background-color: var(--uf-green-soft); color: var(--uf-green); border-bottom-color: transparent; }
.toast-danger .toast-header { background-color: var(--uf-red-soft); color: var(--uf-red); border-bottom-color: transparent; }
.toast-warning .toast-header { background-color: var(--uf-orange-soft); color: var(--uf-orange); border-bottom-color: transparent; }
.toast-info .toast-header { background-color: var(--uf-primary-soft); color: var(--uf-primary); border-bottom-color: transparent; }

.uf-page-head { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.uf-page-title { font-size: 20px; font-weight: 600; color: var(--uf-text-1); margin: 0; }
.uf-page-sub { font-size: 13.5px; color: var(--uf-text-2); margin-top: 2px; }

/* empty state */
.uf-empty { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 56px 20px; color: var(--uf-text-3); text-align: center; }
.uf-empty .lucide { width: 36px; height: 36px; color: var(--uf-border-strong); }
.uf-empty-title { font-size: 15px; font-weight: 600; color: var(--uf-text-2); }

/* horizontal "flow" of coordinated panels with separators (alarm manager) */
.uf-flow { display: grid; grid-template-columns: 1fr 28px 1fr 28px 1fr; align-items: start; gap: 0; }
.uf-flow-sep { display: flex; align-items: center; justify-content: center; height: 100%; padding-top: 24px; color: var(--uf-text-3); }
@media (max-width: 1199.98px) { .uf-flow { grid-template-columns: 1fr; } .uf-flow-sep { display: none; } .uf-flow > * + * { margin-top: 16px; } }

/* thin scroll areas */
.uf-scroll { overflow-y: auto; overscroll-behavior: contain; }

/* utility: muted small text */
.uf-muted { color: var(--uf-text-2); }
.uf-more { color: var(--uf-text-3); }

/* responsive: collapse rail spacing on small screens */
@media (max-width: 991.98px) {
  .uf-panel { position: static; max-height: none; width: 260px; }
  /* Below the desktop breakpoint the icon rail is hidden (navigation moves to
     a drawer/topbar), so the shell must give its reserved rail gutter back. */
  .uf-rail { display: none; }
  .uf-shell { margin-left: 0; }
}
@media (max-width: 767.98px) {
  .uf-layout { flex-direction: column; }
  .uf-panel { width: 100%; }
  .uf-page { padding: 14px 16px 32px; }
  .uf-app .uf-app-label { display: none !important; }
}
@media (max-width: 575.98px) {
  /* The context pill keeps only its icon on phones so the centered brand and
     the right-side controls keep their grid columns. */
  .uf-loc { padding: 6px 9px; }
  .uf-loc span { display: none; }
  /* Page heads stack: title block first, action buttons wrap below it. */
  .uf-page-head { flex-wrap: wrap; row-gap: 12px; }
  .uf-page-head .ms-auto { margin-left: 0 !important; width: 100%; }
  .uf-page-head .ms-auto .btn { flex: 1; }
}

/* ==========================================================================
   CHOICE CARDS (radio selection cards, e.g. deployment type pickers)
   ========================================================================== */
.uf-center-state { max-width: 780px; margin: 0 auto; padding: 40px 0 8px; text-align: center; }
.uf-center-state .uf-page-title { font-size: 22px; }
.uf-center-state .uf-page-sub { font-size: 14.5px; max-width: 560px; margin: 6px auto 0; }

.uf-choice-row { display: flex; flex-wrap: wrap; gap: 20px; justify-content: center; }
.uf-choice {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  width: 272px; padding: 20px 18px 16px; text-align: center;
  background: var(--uf-surface); border: 1px solid var(--uf-border); border-radius: var(--uf-radius-lg);
  cursor: pointer; transition: border-color 0.15s, background-color 0.15s, box-shadow 0.15s;
}
.uf-choice:hover { border-color: var(--uf-border-strong); }
.uf-choice .form-check-input { margin: 0 0 4px; float: none; }
.uf-choice:has(input:checked) {
  border-color: var(--uf-primary); background: var(--uf-primary-soft);
  box-shadow: inset 0 0 0 1px var(--uf-primary);
}
.uf-choice-title { font-size: 15px; font-weight: 600; color: var(--uf-text-1); }
.uf-choice-desc { font-size: 13px; color: var(--uf-text-2); }
.uf-choice-note { font-size: 13px; color: var(--uf-text-2); margin-top: 4px; }

/* ==========================================================================
   SORTABLE TABLE HEADERS · COLORED METRIC TEXT · COLOR-CODED CHECKS
   ========================================================================== */
.uf-sort {
  display: inline-flex; align-items: center; gap: 4px;
  border: 0; background: none; padding: 0;
  font-family: inherit; font-size: 13px; font-weight: 600; color: var(--uf-text-2);
  white-space: nowrap;
}
.uf-sort .lucide { width: 13px; height: 13px; color: var(--uf-text-3); }
.uf-sort:hover { color: var(--uf-text-1); }
.uf-sort.is-active, .uf-sort.is-active .lucide { color: var(--uf-primary); }

.uf-val { font-weight: 500; color: var(--uf-text-1); }
.uf-val.is-green { color: var(--uf-green); }
.uf-val.is-red { color: var(--uf-red); }
.uf-val.is-blue { color: var(--uf-primary); }
.uf-val.is-orange { color: var(--uf-orange); }

/* per-row color-coded checkboxes (sensor/device grouping) */
.form-check-input.is-purple:checked { background-color: #9a6b3f; border-color: #9a6b3f; }
.form-check-input.is-blue:checked   { background-color: var(--uf-primary); border-color: var(--uf-primary); }
.form-check-input.is-lime:checked   { background-color: #9bc23c; border-color: #9bc23c; }
.form-check-input.is-yellow:checked { background-color: #e0b31c; border-color: #e0b31c; }
.form-check-input.is-dgreen:checked { background-color: #1f9d55; border-color: #1f9d55; }

/* card footer link pair: "Create New | Manage" */
.uf-foot-links { display: flex; align-items: center; gap: 16px; padding-top: 14px; margin-top: 4px; }
.uf-foot-links .uf-vline { width: 1px; height: 14px; background: var(--uf-border-strong); }

/* ==========================================================================
   MEDIA MODAL (device preview: dark title bar + video + block button)
   ========================================================================== */
.uf-media-bar {
  display: flex; align-items: center; gap: 10px;
  background: #141518; border-radius: 10px; padding: 10px 14px; color: #fff;
}
.uf-media-bar .uf-media-name { font-weight: 600; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.uf-media-bar .uf-media-link { color: #d0cfca; font-size: 14px; font-weight: 500; text-decoration: none; white-space: nowrap; }
.uf-media-bar .uf-media-link:hover { text-decoration: underline; color: #f5f5f5; }
.uf-media-bar .uf-icon-btn { color: #c6c6c6; }
.uf-media-bar .uf-icon-btn:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
.uf-media-view { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 10px; background: #000; margin-top: 12px; }

/* ==========================================================================
   PORT GRID · LEGEND · ACTIVITY SPARKBARS (switch-style views)
   ========================================================================== */
.uf-ports { display: grid; grid-template-columns: repeat(24, minmax(38px, 1fr)); gap: 4px 4px; overflow-x: auto; padding-bottom: 4px; }
.uf-port-col { display: flex; flex-direction: column; align-items: center; gap: 0; }
.uf-port-dev { height: 34px; display: flex; align-items: center; justify-content: center; color: var(--uf-text-2); }
.uf-port-dev .lucide { width: 17px; height: 17px; }
.uf-port-link { width: 1px; height: 7px; border-left: 1.5px dotted var(--uf-border-strong); }
.uf-port {
  width: 100%; max-width: 44px; height: 40px; border-radius: 8px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  font-size: 11.5px; font-weight: 600; color: #fff; cursor: pointer;
  transition: filter 0.12s, transform 0.12s;
}
.uf-port:hover { filter: brightness(1.08); transform: translateY(-1px); }
.uf-port .lucide { width: 13px; height: 13px; }
.uf-port.is-fe { background: #a8c43c; }
.uf-port.is-gbe { background: #43b45c; }
.uf-port.is-25 { background: #8a8a8a; }
.uf-port.is-10 { background: #4f4f4f; }
.uf-port.is-sfp { background: #a6a6a6; }
.uf-port.is-off { background: #c8c8c8; }
.uf-port.is-disabled { background: transparent; border: 1.5px solid var(--uf-border-strong); color: var(--uf-text-3); }
.uf-port.is-wan { background: #b06a3c; }
[data-bs-theme="dark"] .uf-port.is-disabled { border-color: var(--uf-border-strong); }

.uf-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px; font-size: 12.5px; color: var(--uf-text-2); }
.uf-legend .uf-leg { display: inline-flex; align-items: center; gap: 6px; }
.uf-legend .sw { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.uf-legend .lucide { width: 14px; height: 14px; color: var(--uf-text-2); }

.uf-sparkbar { display: flex; flex-direction: column; gap: 3px; width: 120px; max-width: 100%; }
.uf-sparkbar span { display: block; height: 5px; border-radius: 2px; background: var(--uf-track); overflow: hidden; }
.uf-sparkbar span b { display: block; height: 100%; border-radius: 2px; }
.uf-sparkbar .tx b { background: var(--uf-orange); }
.uf-sparkbar .rx b { background: var(--uf-text-3); }

/* ==========================================================================
   SCHEDULE RANGE CHIPS (labeled painted ranges inside the week grid)
   ========================================================================== */
.uf-sched-cells { position: relative; }
.uf-sched-chip {
  position: absolute; top: 3px; bottom: 3px;
  display: flex; align-items: center; justify-content: center; gap: 5px;
  padding: 0 8px; overflow: hidden; white-space: nowrap;
  background: var(--uf-primary-soft-2); color: var(--uf-primary);
  font-size: 12px; font-weight: 500; border-radius: 6px;
  pointer-events: none;
}
.uf-sched-chip .lucide { width: 12px; height: 12px; }

/* ==========================================================================
   LINE CHART (SVG demo charts)
   ========================================================================== */
.uf-linechart { display: block; width: 100%; }
.uf-linechart text { font-family: var(--uf-font); font-size: 11px; fill: var(--uf-text-3); }

/* ==========================================================================
   SETTINGS ROWS (feature list: label + info icon ······ control)
   ========================================================================== */
.uf-setting-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 18px; align-items: center;
  min-height: 46px; padding: 4px 0;
}
.uf-setting-row > * { min-width: 0; }
.uf-setting-row > :first-child { max-width: 640px; }
.uf-setting-label { display: inline-flex; align-items: center; gap: 7px; font-size: 14px; font-weight: 500; color: var(--uf-text-1); }
.uf-setting-label .lucide { color: var(--uf-text-3); cursor: help; }
.uf-create-link { display: inline-flex; align-items: center; gap: 7px; color: var(--uf-primary); font-size: 14px; font-weight: 500; text-decoration: none; }
.uf-create-link .lucide { width: 17px; height: 17px; }
.uf-create-link:hover { color: var(--uf-primary-hover); }

@media (max-width: 767.98px) { .uf-setting-row { grid-template-columns: 1fr; gap: 6px; } }

/* ==========================================================================
   RIGHT SLIDE-OVER DRAWER (config panel / device detail)
   ========================================================================== */
.offcanvas.uf-drawer {
  --bs-offcanvas-width: 480px;
  background: var(--uf-bg-subtle);
  border-left: 1px solid var(--uf-border);
}
.offcanvas.uf-drawer.is-narrow { --bs-offcanvas-width: 400px; }
.uf-drawer .offcanvas-header { display: grid; grid-template-columns: 1fr auto; align-items: center; padding: 18px 20px 12px; }
.uf-drawer .uf-drawer-title { font-size: 16px; font-weight: 600; color: var(--uf-text-1); margin: 0; text-align: center; grid-column: 1 / -1; }
.uf-drawer .uf-drawer-close { position: absolute; top: 18px; right: 18px; }
.uf-drawer .offcanvas-body { padding: 4px 20px 24px; }
/* drawer sections are plain Bootstrap cards */
.uf-drawer .card { --bs-card-border-color: transparent; box-shadow: var(--uf-shadow-sm); }
.uf-drawer-tabs { display: flex; justify-content: center; gap: 8px; margin-bottom: 14px; }

/* inline info callout — use .alert.alert-primary.d-flex with an info icon */
.uf-drawer .alert { font-size: 13.5px; line-height: 1.5; }

/* device hero inside a drawer */
.uf-hero { display: flex; gap: 14px; align-items: center; }
.uf-hero img { width: 96px; height: 66px; object-fit: cover; border-radius: 8px; flex: none; }
.uf-hero-status { display: flex; align-items: center; gap: 6px; font-size: 13.5px; color: var(--uf-text-1); }
.uf-hero-actions { display: flex; gap: 16px; margin-top: 8px; flex-wrap: wrap; }
.uf-hero-actions .uf-link { white-space: nowrap; font-size: 13.5px; }

/* collapsible section header (reuses uf-collapse-toggle; is-flush = no top padding) */

/* key-value rows */
.uf-kv { display: flex; justify-content: space-between; gap: 14px; padding: 8px 0; font-size: 13.5px; border-bottom: 1px solid var(--uf-border-light); }
.uf-kv:last-child { border-bottom: 0; }
.uf-kv-key { color: var(--uf-text-2); white-space: nowrap; }
.uf-kv-val { color: var(--uf-text-1); text-align: right; overflow: hidden; text-overflow: ellipsis; }

/* segmented stacked usage bar */
.uf-segbar { display: flex; gap: 2px; height: 8px; border-radius: 999px; overflow: hidden; background: var(--uf-track); }
.uf-segbar b { display: block; height: 100%; }
.uf-segbar .is-green { background: var(--uf-green); }
.uf-segbar .is-blue { background: var(--uf-primary); }
.uf-segbar .is-dark { background: #6a6a6a; }

/* muted note box (feedback / footnote in a nav column) */
.uf-note-box { background: var(--uf-bg-muted); border-radius: 10px; padding: 12px 14px; font-size: 13px; line-height: 1.5; color: var(--uf-text-2); }

/* checkbox filter row with count */
.uf-check-row .uf-count { margin-left: auto; color: var(--uf-text-3); font-size: 12.5px; }
.uf-check-row { width: 100%; }

/* ==========================================================================
   DENSE LOG TABLE EXTRAS (flows / audit)
   ========================================================================== */
.uf-th-search { display: inline-flex; align-items: center; gap: 6px; }
.uf-th-search .lucide { width: 13px; height: 13px; color: var(--uf-text-3); }

.uf-risk { display: inline-flex; align-items: center; gap: 3px; }
.uf-risk b { width: 11px; height: 4px; border-radius: 2px; background: var(--uf-border-strong); opacity: 0.55; }
.uf-risk.is-low b:nth-child(1) { background: var(--uf-green); opacity: 1; }
.uf-risk.is-med b:nth-child(-n + 2) { background: var(--uf-orange); opacity: 1; }
.uf-risk.is-high b { background: var(--uf-red); opacity: 1; }

.uf-dir { color: var(--uf-text-2); display: inline-flex; }

/* table footer: use .card-footer.d-flex.align-items-center.gap-3.flex-wrap
   .uf-table-count  → .small.text-body-secondary
   .uf-rows-per     → .d-flex.align-items-center.gap-2.ms-auto.small.text-body-secondary */

/* ==========================================================================
   AVATAR PICK LIST (assign-to-user modal)
   ========================================================================== */
.uf-pick-list { display: flex; flex-direction: column; max-height: 320px; overflow-y: auto; margin: 0 -6px; }
.uf-pick-row { display: flex; align-items: center; gap: 12px; padding: 8px 10px; border-radius: 8px; cursor: pointer; }
.uf-pick-row:hover { background: var(--uf-bg-subtle); }
.uf-pick-row .form-check-input { margin: 0; flex: none; }
.uf-pick-name { font-size: 14px; font-weight: 500; color: var(--uf-text-1); }
.uf-pick-mail { font-size: 13.5px; color: var(--uf-text-2); margin-left: auto; }
