/* ============================================================
   KALYTERA — Control Surface
   A dark-first operations console. State (live / recording / alarm)
   is the only thing that lights up; the accent stays quiet.
   Dark is the committed default; light tokens exist for a future toggle.
   ============================================================ */
:root {
  /* Ground & surfaces */
  --k-bg: #0A0E15;
  --k-surface: #111826;
  --k-surface-2: #161F30;
  --k-surface-3: #1D2740;
  --k-raise: #202B44;
  --k-border: #232E45;
  --k-border-strong: #33425F;
  --k-line-soft: rgba(255,255,255,.05);

  /* Text — the two faint tokens were below AA (~2.3:1) on the dark surfaces; raised so eyebrows,
     event timestamps, KPI sublabels and placeholders stay legible at a glance in a control room. */
  --k-text: #E8EEF7;
  --k-text-muted: #8A99B4;
  --k-text-subtle: #7C8BA6;
  /* Small metadata uses this token throughout the console, including on surface-3. Keep it above
     WCAG AA contrast there instead of treating "faint" as unreadable. */
  --k-text-faint: #8190AC;

  /* Accent — quiet steel blue, interaction only */
  --k-primary: #3E5C86;
  --k-primary-hover: #4E7099;
  --k-primary-active: #35507A;
  --k-primary-bright: #7C9BC9;
  --k-primary-soft: rgba(90,130,180,.16);
  --k-primary-glow: rgba(80,112,153,.35);

  /* Semantic state — the vivid layer */
  --k-success: #34D6A4;   --k-success-bg: rgba(52,214,164,.14);  --k-success-fg: #4FE3B6;
  --k-warning: #F6B33D;   --k-warning-bg: rgba(246,179,61,.14);  --k-warning-fg: #F9C566;
  --k-danger:  #FF5D6B;   --k-danger-bg:  rgba(255,93,107,.14);  --k-danger-fg:  #FF838D;
  --k-info:    #6E8CC4;   --k-info-bg:    rgba(110,140,196,.16); --k-info-fg:    #9DB4DB;
  --k-neutral-bg: rgba(255,255,255,.05); --k-neutral-fg: #9DAAC1;

  /* Camera / stream status */
  --k-status-online: #34D6A4;
  --k-status-recording: #FF5D6B;
  --k-status-idle: #F6B33D;
  --k-status-error: #F6B33D;
  --k-status-offline: #5C6B84;

  --sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "Cascadia Code", "SF Mono", "Segoe UI Mono", Consolas, Menlo, monospace;

  --k-radius-sm: 7px; --k-radius: 10px; --k-radius-lg: 16px; --k-radius-pill: 999px;
  --k-shadow-sm: 0 1px 2px rgba(0,0,0,.3);
  --k-shadow: 0 14px 40px rgba(0,0,0,.4);
  --k-shadow-lg: 0 22px 60px rgba(0,0,0,.5);

  --rail-w: 78px; --topbar-h: 54px;
  color-scheme: dark;
}

html { font-size: 15px; }

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--sans);
  background:
    radial-gradient(1100px 640px at 82% -10%, rgba(90,130,180,.09), transparent 60%),
    var(--k-bg);
  color: var(--k-text);
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--k-primary-soft); }
* { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.16) transparent; }
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-thumb { background: rgba(255,255,255,.12); border-radius: 6px; border: 2px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.22); background-clip: content-box; }

.mono { font-family: var(--mono); }
.tabular, .num { font-variant-numeric: tabular-nums; }
:focus-visible { outline: 2px solid var(--k-primary-bright); outline-offset: 2px; border-radius: 5px; }

a { color: var(--k-primary-bright); }
code { color: var(--k-primary-bright); background: var(--k-surface-2); padding: .08em .4em; border-radius: 5px; font-family: var(--mono); font-size: .86em; }

/* ============================================================
   Dark treatment for the Bootstrap-based pages
   ============================================================ */
.card { background: var(--k-surface); border: 1px solid var(--k-border); color: var(--k-text); border-radius: var(--k-radius-lg); }
.card-header, .card-footer { background: transparent; border-color: var(--k-border); }
.text-secondary { color: var(--k-text-muted) !important; }
.text-muted { color: var(--k-text-muted) !important; }
.text-body-secondary { color: var(--k-text-muted) !important; }
.border, .border-top, .border-bottom, .border-start, .border-end { border-color: var(--k-border) !important; }
hr, .dropdown-divider { border-color: var(--k-border); opacity: 1; }

.table { color: var(--k-text); --bs-table-bg: transparent; --bs-table-color: var(--k-text); border-color: var(--k-border); }
.table > :not(caption) > * > * { background: transparent; color: var(--k-text); border-color: var(--k-line-soft); box-shadow: none; }
.table > thead > tr > th { color: var(--k-text-muted); font-size: .74rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; border-color: var(--k-border); font-family: var(--mono); }
.table > tbody > tr { transition: background-color .12s ease; }
.table:not(.table-hover) > tbody > tr:hover > * { background-color: var(--k-surface-2); }
.table-secondary, .table-secondary > * { --bs-table-bg: var(--k-surface-2); color: var(--k-text-muted) !important; }

.form-control, .form-select {
  background-color: var(--k-surface-2); border: 1px solid var(--k-border); color: var(--k-text); border-radius: 9px;
}
.form-control::placeholder { color: var(--k-text-faint); }
.form-control:focus, .form-select:focus { background-color: var(--k-surface-2); border-color: var(--k-primary-bright); color: var(--k-text); box-shadow: 0 0 0 3px var(--k-primary-soft); }
.form-control:disabled, .form-select:disabled { background-color: var(--k-surface); color: var(--k-text-muted); }
.form-select { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%238A99B4' stroke-width='1.6' stroke-linecap='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E"); }
.form-label { color: var(--k-text-muted); font-size: .82rem; font-weight: 600; margin-bottom: .35rem; }
.form-text { color: var(--k-text-subtle); }
.form-check-input { background-color: var(--k-surface-2); border-color: var(--k-border-strong); }
.form-check-input:checked { background-color: var(--k-primary); border-color: var(--k-primary); }
.input-group-text { background: var(--k-surface); border-color: var(--k-border); color: var(--k-text-muted); }

.modal-content { background: var(--k-surface); border: 1px solid var(--k-border-strong); border-radius: var(--k-radius-lg); color: var(--k-text); box-shadow: var(--k-shadow-lg); }
.modal-header, .modal-footer { border-color: var(--k-border); }
.btn-close { filter: invert(1) grayscale(1) brightness(1.6); opacity: .6; }
.btn-close:hover { opacity: 1; }

.dropdown-menu { background: var(--k-surface-2); border: 1px solid var(--k-border-strong); border-radius: var(--k-radius); box-shadow: var(--k-shadow); padding: 5px; }
.dropdown-item { color: var(--k-text); border-radius: 7px; padding: 8px 12px; }
.dropdown-item:hover, .dropdown-item:focus { background: var(--k-surface-3); color: var(--k-text); }
.dropdown-item.text-danger { color: var(--k-danger-fg) !important; }
.dropdown-item.text-danger:hover { background: var(--k-danger-bg); }

.list-group-item { background: transparent; border-color: var(--k-border); color: var(--k-text); }

.alert { border-radius: var(--k-radius); border: 1px solid var(--k-border); }
.alert-info { background: var(--k-info-bg); border-color: rgba(110,140,196,.3); color: var(--k-info-fg); }
.alert-success { background: var(--k-success-bg); border-color: rgba(52,214,164,.3); color: var(--k-success-fg); }
.alert-warning { background: var(--k-warning-bg); border-color: rgba(246,179,61,.3); color: var(--k-warning-fg); }
.alert-danger { background: var(--k-danger-bg); border-color: rgba(255,93,107,.3); color: var(--k-danger-fg); }
.alert-light, .alert-secondary { background: var(--k-surface-2); color: var(--k-text-muted); }

.nav-tabs { border-color: var(--k-border); }
.nav-tabs .nav-link { color: var(--k-text-muted); border: 0; border-bottom: 2px solid transparent; }
.nav-tabs .nav-link.active { color: var(--k-text); background: transparent; border-bottom-color: var(--k-primary-bright); }

.progress { background: var(--k-surface-3); border-radius: 999px; }
.badge.text-bg-secondary { background: var(--k-neutral-bg) !important; color: var(--k-neutral-fg) !important; }
.badge.text-bg-light { background: var(--k-surface-2) !important; color: var(--k-text-muted) !important; }

/* ============================================================
   Buttons
   ============================================================ */
.btn {
  --bs-btn-font-weight: 600; --bs-btn-border-radius: 9px;
  transition: color .15s, background-color .15s, border-color .15s, box-shadow .15s, transform .04s;
}
.btn-sm { --bs-btn-border-radius: 8px; }
.btn:active { transform: translateY(.5px); }

.btn-primary {
  --bs-btn-bg: var(--k-primary); --bs-btn-border-color: var(--k-primary);
  --bs-btn-hover-bg: var(--k-primary-hover); --bs-btn-hover-border-color: var(--k-primary-hover);
  --bs-btn-active-bg: var(--k-primary-active); --bs-btn-active-border-color: var(--k-primary-active);
  --bs-btn-color: #fff; --bs-btn-hover-color: #fff;
  --bs-btn-disabled-bg: #2a3a55; --bs-btn-disabled-border-color: #2a3a55; --bs-btn-disabled-color: #8394ad;
  box-shadow: 0 4px 14px var(--k-primary-glow);
}
.btn-secondary {
  --bs-btn-bg: var(--k-surface-2); --bs-btn-border-color: var(--k-border-strong); --bs-btn-color: var(--k-text);
  --bs-btn-hover-bg: var(--k-surface-3); --bs-btn-hover-border-color: var(--k-border-strong); --bs-btn-hover-color: var(--k-text);
}
.btn-success { --bs-btn-bg: #1f9d78; --bs-btn-border-color: #1f9d78; --bs-btn-hover-bg: #1a8a69; --bs-btn-hover-border-color: #1a8a69; --bs-btn-color: #fff; }
.btn-danger { --bs-btn-bg: #d84656; --bs-btn-border-color: #d84656; --bs-btn-hover-bg: #c53b4a; --bs-btn-color: #fff; }
.btn-outline-primary { --bs-btn-color: var(--k-primary-bright); --bs-btn-border-color: var(--k-border-strong); --bs-btn-hover-bg: var(--k-primary); --bs-btn-hover-border-color: var(--k-primary); --bs-btn-hover-color: #fff; --bs-btn-active-bg: var(--k-primary-active); }
.btn-outline-secondary { --bs-btn-color: var(--k-text-muted); --bs-btn-border-color: var(--k-border-strong); --bs-btn-hover-bg: var(--k-surface-2); --bs-btn-hover-color: var(--k-text); --bs-btn-hover-border-color: var(--k-border-strong); --bs-btn-active-bg: var(--k-surface-3); --bs-btn-active-color: var(--k-text); }
.btn-outline-success { --bs-btn-color: var(--k-success-fg); --bs-btn-border-color: rgba(52,214,164,.35); --bs-btn-hover-bg: rgba(52,214,164,.14); --bs-btn-hover-color: var(--k-success-fg); --bs-btn-hover-border-color: var(--k-success); }
.btn-outline-danger { --bs-btn-color: var(--k-danger-fg); --bs-btn-border-color: rgba(255,93,107,.35); --bs-btn-hover-bg: rgba(255,93,107,.14); --bs-btn-hover-color: var(--k-danger-fg); --bs-btn-hover-border-color: var(--k-danger); }
.btn-outline-warning { --bs-btn-color: var(--k-warning-fg); --bs-btn-border-color: rgba(246,179,61,.35); --bs-btn-hover-bg: rgba(246,179,61,.14); --bs-btn-hover-color: var(--k-warning-fg); --bs-btn-hover-border-color: var(--k-warning); }
.btn-outline-light { --bs-btn-color: var(--k-text); --bs-btn-border-color: var(--k-border-strong); --bs-btn-hover-bg: var(--k-surface-2); --bs-btn-hover-color: var(--k-text); }
.btn-icon { display: inline-flex; align-items: center; justify-content: center; gap: .45rem; }
.btn-icon.btn-square { padding-left: .5rem; padding-right: .5rem; }

/* ============================================================
   Icons
   ============================================================ */
.k-icon { flex: 0 0 auto; vertical-align: -.18em; }
.k-icon:not([width]) { width: 18px; height: 18px; }
.sidebar-icon { width: 21px; height: 21px; }

/* ============================================================
   Shell — icon rail + top command bar + canvas
   ============================================================ */
.app-shell {
  display: grid;
  grid-template-columns: var(--rail-w) 1fr;
  grid-template-rows: var(--topbar-h) 1fr;
  grid-template-areas: "rail topbar" "rail canvas";
  height: 100dvh; overflow: hidden;
}
.rail {
  grid-area: rail; background: linear-gradient(180deg, #0C1119, #080C12);
  border-right: 1px solid var(--k-border); display: flex; flex-direction: column;
  align-items: center; padding: 13px 0 12px; gap: 3px; z-index: 20;
}
.rail-brand { width: 42px; height: 42px; border-radius: 13px; display: grid; place-items: center; margin-bottom: 14px; flex: 0 0 auto;
  background: linear-gradient(145deg, #46618C, #33507A); box-shadow: 0 6px 18px var(--k-primary-glow); }
.rail-brand svg { width: 23px; height: 23px; stroke: #fff; fill: none; }
.rail-brand img { width: 34px; height: auto; display: block; }
.rail-nav { display: flex; flex-direction: column; gap: 3px; align-items: center; flex: 1; width: 100%; }
.rail-link {
  width: 60px; padding: 9px 0 7px; border: 0; background: transparent; cursor: pointer; text-decoration: none;
  border-radius: var(--k-radius); display: flex; flex-direction: column; align-items: center; gap: 5px;
  color: var(--k-text-faint); transition: color .15s, background .15s; position: relative;
}
.rail-link svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.7; }
.rail-link span { font-size: 10px; font-weight: 600; }
.rail-link:hover { color: var(--k-text-muted); background: rgba(255,255,255,.03); }
.rail-link.active { color: var(--k-primary-bright); }
.rail-link.active::before { content: ""; position: absolute; left: -13px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 28px; border-radius: 0 3px 3px 0; background: var(--k-primary-bright); box-shadow: 0 0 12px var(--k-primary-glow); }
.rail-badge { position: absolute; top: 4px; right: 10px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px;
  background: var(--k-danger); color: #fff; font-size: 10px; font-weight: 700; display: grid; place-items: center; font-family: var(--mono); }
.rail-foot { display: flex; flex-direction: column; gap: 9px; align-items: center; }
.rail-foot .avatar { width: 36px; height: 36px; border-radius: 11px; background: var(--k-surface-2); border: 1px solid var(--k-border);
  display: grid; place-items: center; font-weight: 700; font-size: 13px; color: var(--k-primary-bright); cursor: pointer; }
.rail-foot form { margin: 0; }

.topbar {
  grid-area: topbar; border-bottom: 1px solid var(--k-border); display: flex; align-items: center; gap: 14px;
  padding: 0 16px; background: rgba(10,14,21,.7); backdrop-filter: blur(8px); z-index: 15;
}
.topbar .ws { display: flex; align-items: center; min-width: 0; }
.topbar .ws-name { font-weight: 650; font-size: 14px; }
.topbar .ws-sub { color: var(--k-text-faint); font-size: 11px; font-family: var(--mono); }
.topbar-search { flex: 1; min-width: 180px; max-width: 440px; display: flex; align-items: center; gap: 9px; height: 34px; padding: 0 8px 0 12px;
  background: var(--k-surface); border: 1px solid var(--k-border); border-radius: 9px; color: var(--k-text-muted); }
.topbar-search svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.8; }
.topbar-search input { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--k-text); font-size: 13px; outline: none; }
.topbar-search:focus-within { border-color: color-mix(in srgb, var(--k-primary-bright) 62%, var(--k-border)); box-shadow: 0 0 0 3px var(--k-primary-soft); }
.topbar-search-shortcut { flex: 0 0 auto; border: 1px solid var(--k-border-strong); border-radius: 5px; background: var(--k-surface-2); color: var(--k-text-faint); font-family: var(--mono); font-size: 9px; font-weight: 650; line-height: 1; padding: 4px 5px; }
.status-strip { display: flex; align-items: center; gap: 7px; margin-left: auto; }
.stat-pill { display: flex; align-items: center; gap: 7px; height: 32px; padding: 0 11px; background: var(--k-surface); border: 1px solid var(--k-border); border-radius: 8px; }
.stat-pill .k { font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--k-text-faint); }
.stat-pill .v { font-family: var(--mono); font-weight: 700; font-size: 13px; }
.dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }
.dot.live, .dot.online { background: var(--k-status-online); box-shadow: 0 0 7px var(--k-status-online); }
.dot.rec { background: var(--k-status-recording); box-shadow: 0 0 7px var(--k-status-recording); animation: k-pulse 1.6s infinite; }
.dot.off { background: var(--k-status-offline); }
.dot.warn, .dot.idle { background: var(--k-status-idle); }
@keyframes k-pulse { 0%,100%{opacity:1} 50%{opacity:.35} }

.icon-btn { width: 34px; height: 34px; border-radius: 8px; border: 1px solid var(--k-border); background: var(--k-surface);
  display: grid; place-items: center; cursor: pointer; color: var(--k-text-muted); position: relative; text-decoration: none; }
.icon-btn:hover { color: var(--k-text); border-color: var(--k-border-strong); }
.icon-btn svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 1.8; }
.icon-btn .bump { position: absolute; top: -5px; right: -5px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px;
  background: var(--k-danger); color: #fff; font-size: 10px; font-weight: 700; display: grid; place-items: center; font-family: var(--mono); }

.canvas { grid-area: canvas; overflow: auto; position: relative; }
.canvas.no-scroll { overflow: hidden; }
.page { margin-inline: auto; max-width: 1500px; padding: 22px 26px 32px; width: 100%; }
.page-narrow { max-width: 1180px; }

/* ============================================================
   Page header + eyebrow
   ============================================================ */
.page-header { display: flex; flex-direction: column; gap: 14px; margin-bottom: 22px; }
@media (min-width: 768px) { .page-header { flex-direction: row; align-items: flex-end; justify-content: space-between; } }
.page-header-text { min-width: 0; }
.page-header-eyebrow, .eyebrow { color: var(--k-text-faint); font-family: var(--mono); font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .14em; margin-bottom: 5px; }
.page-header-eyebrow--redundant { display: none; }
.page-header-title { font-size: 24px; font-weight: 680; line-height: 1.15; margin: 0; letter-spacing: -.015em; color: var(--k-text); }
.page-header-subtitle { color: var(--k-text-muted); font-size: 13.5px; margin: 4px 0 0; max-width: 68ch; }
.page-header-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; flex: 0 0 auto; }
.page-header-back { display: inline-flex; align-items: center; gap: 5px; color: var(--k-text-muted); font-size: 12.5px; font-weight: 550; text-decoration: none; margin-bottom: 8px; transition: color .12s ease; }
.page-header-back:hover, .page-header-back:focus-visible { color: var(--k-primary-bright); }
.page-header-back svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2; }
.immersive-header .page-header-back { margin: 0 6px 0 0; }

/* ============================================================
   Shared load / error / empty states + skeletons
   Reused by every list loader so a failed fetch reads as
   "couldn't load — retry", never as "you have no data".
   ============================================================ */
.k-state { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 9px; text-align: center; padding: 30px 20px; color: var(--k-text-muted); min-height: 120px; }
.k-state svg { width: 28px; height: 28px; stroke: currentColor; fill: none; stroke-width: 1.6; opacity: .7; }
.k-state-title { font-weight: 620; color: var(--k-text); font-size: 14px; }
.k-state-msg { font-size: 12.5px; color: var(--k-text-muted); max-width: 44ch; margin: 0; line-height: 1.5; }
.k-state--error svg { color: var(--k-danger-fg, #f0a9a9); opacity: .9; }
.k-state .btn { margin-top: 3px; }

.skeleton { position: relative; overflow: hidden; background: var(--k-surface-2); border-radius: 8px; animation: k-pulse 1.4s ease-in-out infinite; }
.skeleton-row { height: 46px; margin: 7px 0; }
.skeleton-line { height: 12px; border-radius: 6px; }

.k-spin { display: inline-block; width: 14px; height: 14px; margin-right: 7px; vertical-align: -2px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: k-spin .7s linear infinite; }
.k-spin-lg { width: 26px; height: 26px; border-width: 2.5px; margin: 0; }
@keyframes k-spin { to { transform: rotate(360deg); } }

/* Global quick-search dropdown (topbar) */
.k-search-pop { position: fixed; background: color-mix(in srgb, var(--k-surface-2) 94%, transparent); border: 1px solid var(--k-border-strong); border-radius: 13px; box-shadow: 0 22px 58px rgba(0,0,0,.56); padding: 7px; z-index: 1075; max-height: min(68vh, 620px); overflow: auto; display: none; backdrop-filter: blur(18px); }
.k-search-pop.show { display: block; }
.k-search-intro { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 8px 10px 9px; border-bottom: 1px solid var(--k-line-soft); }
.k-search-intro > :first-child { color: var(--k-text); font-size: 12px; font-weight: 680; }
.k-search-intro > :last-child { color: var(--k-text-faint); font-size: 10.5px; }
.k-search-head { padding: 10px 10px 4px; font-size: 9.5px; font-weight: 650; letter-spacing: .13em; text-transform: uppercase; color: var(--k-text-faint); font-family: var(--mono); }
.k-search-item { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 7px 9px; border-radius: 9px; text-decoration: none; color: var(--k-text); font-size: 13px; }
.k-search-item-icon { width: 29px; height: 29px; flex: 0 0 auto; display: grid; place-items: center; border: 1px solid var(--k-border); border-radius: 8px; background: var(--k-surface); color: var(--k-text-muted); }
.k-search-item-icon svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.8; }
.k-search-item-copy { display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; }
.k-search-item-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.k-search-item .sub { color: var(--k-text-faint); font-size: 10.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.k-search-enter { color: var(--k-text-faint); font-family: var(--mono); font-size: 12px; opacity: 0; }
.k-search-item:hover, .k-search-item.sel { background: var(--k-primary-soft); color: var(--k-text); }
.k-search-item:hover .k-search-item-icon, .k-search-item.sel .k-search-item-icon { border-color: color-mix(in srgb, var(--k-primary-bright) 42%, var(--k-border)); color: var(--k-primary-bright); }
.k-search-item:hover .k-search-enter, .k-search-item.sel .k-search-enter { opacity: 1; }
.k-search-empty { padding: 14px; color: var(--k-text-muted); font-size: 12.5px; text-align: center; }
.k-search-foot { display: flex; align-items: center; gap: 12px; margin-top: 5px; padding: 8px 10px 5px; border-top: 1px solid var(--k-line-soft); color: var(--k-text-faint); font-size: 10px; }
.k-search-foot > span { align-items: center; display: inline-flex; gap: 4px; }
.k-search-foot kbd { background: var(--k-surface); border: 1px solid var(--k-border); border-radius: 4px; color: var(--k-text-muted); font-family: var(--mono); font-size: 9px; line-height: 1; padding: 3px 4px; }

/* Dashboard stat cards that link somewhere / need attention */
a.stat-card { color: inherit; transition: border-color .12s ease, transform .12s ease; }
a.stat-card:hover { border-color: var(--k-border-strong); }
.stat-card--attention { position: relative; }
.stat-card--attention::before { content: ''; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px; border-radius: 3px; background: var(--k-warning); }
.stat-card--attention .stat-value { color: var(--k-warning-fg); }

/* Video-wall cell buttons: translucent dark glass so they read over any camera scene (was btn-light,
   which flashed a foreign bright button over the most-looked-at surface in the app). */
.btn-cell { background: rgba(10,16,26,.62); color: #E8EEF7; border: 1px solid rgba(255,255,255,.14); backdrop-filter: blur(6px); }
.btn-cell:hover, .btn-cell:focus-visible { background: rgba(20,28,44,.84); color: #fff; border-color: rgba(255,255,255,.28); }

/* Respect the OS "reduce motion" setting: kill decorative animation/transition everywhere. The two
   canvas overlays (live/playback) additionally gate their JS tweening on this in code. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  /* Exception: a loading spinner that doesn't spin conveys nothing, so keep the ring rotating even
     under reduce-motion. It is functional status, not decoration. */
  .cell-spinner-ring {
    animation-duration: .8s !important;
    animation-iteration-count: infinite !important;
  }
}

/* ============================================================
   Chips / badges
   ============================================================ */
.chip { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 9px; border-radius: 999px; font-size: 11px; font-weight: 650; font-family: var(--mono); letter-spacing: .02em; white-space: nowrap; }
.chip svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; }
.chip.live, .chip.online { background: var(--k-success-bg); color: var(--k-success-fg); }
.chip.rec, .chip.recording { background: var(--k-danger-bg); color: var(--k-danger-fg); }
.chip.warn, .chip.idle { background: var(--k-warning-bg); color: var(--k-warning-fg); }
.chip.off, .chip.offline, .chip.neutral { background: var(--k-neutral-bg); color: var(--k-neutral-fg); }
.chip.accent, .chip.info { background: var(--k-primary-soft); color: var(--k-primary-bright); }

.k-badge { display: inline-flex; align-items: center; gap: .35em; padding: .2rem .6rem; border-radius: 999px; font-size: .74rem; font-weight: 600; line-height: 1.4; white-space: nowrap; border: 1px solid transparent; }
.k-badge::before { content: ""; width: .5em; height: .5em; border-radius: 50%; background: currentColor; opacity: .95; flex: 0 0 auto; }
.k-badge--dotless::before { display: none; }
.k-badge--success, .k-badge--online   { background: var(--k-success-bg); color: var(--k-success-fg); }
.k-badge--danger,  .k-badge--recording{ background: var(--k-danger-bg);  color: var(--k-danger-fg); }
.k-badge--warning, .k-badge--error, .k-badge--idle { background: var(--k-warning-bg); color: var(--k-warning-fg); }
.k-badge--info     { background: var(--k-primary-soft); color: var(--k-primary-bright); }
.k-badge--offline, .k-badge--neutral  { background: var(--k-neutral-bg); color: var(--k-neutral-fg); }
.k-badge--recording::before { animation: k-pulse 1.4s ease-in-out infinite; }

/* ============================================================
   Panels / surfaces / empty states
   ============================================================ */
.panel, .portal-card { background: var(--k-surface); border: 1px solid var(--k-border); border-radius: var(--k-radius-lg); box-shadow: none; }
/* Bootstrap scopes --bs-card-spacer-* to .card, and .card-body derives ALL its padding from them.
   A .card-body nested in our .panel/.portal-card surface (which is not a .card) would otherwise resolve
   those vars to nothing and collapse to padding:0 — headers/icons then sit flush in the top-left corner.
   Supply the spacers so a .card-body renders identically inside a .panel as inside a .card. */
.panel, .portal-card { --bs-card-spacer-y: 1rem; --bs-card-spacer-x: 1rem; }
.portal-card.border-success { border-color: rgba(52,214,164,.4) !important; }
.empty-state { background: var(--k-surface-2); border: 1px dashed var(--k-border-strong); border-radius: var(--k-radius); color: var(--k-text-muted); padding: 2.25rem 2rem; text-align: center; }
.empty-state .k-icon { color: var(--k-text-faint); }

/* Stat card (legacy dashboard + reused) */
.stat-card { position: relative; overflow: hidden; }
.stat-card::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 4px; background: linear-gradient(180deg, var(--k-primary-bright), var(--k-primary)); }
.stat-label { color: var(--k-text-muted); font-size: .8rem; font-weight: 600; letter-spacing: .03em; text-transform: uppercase; display: flex; align-items: center; gap: .4rem; }
.stat-value { font-size: 1.9rem; font-weight: 700; margin: .35rem 0; font-family: var(--mono); font-variant-numeric: tabular-nums; }
.storage-progress { height: .7rem; border-radius: 999px; background: var(--k-surface-3); }
.storage-progress .progress-bar { background: linear-gradient(90deg, var(--k-primary), var(--k-primary-bright)); }

/* KPI + sparkline (Insights) */
.kpi-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 1199.98px) { .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 575.98px) { .kpi-grid { grid-template-columns: minmax(0, 1fr); } }
.kpi { border: 1px solid var(--k-border); border-radius: var(--k-radius-lg); background: var(--k-surface); display: flex; flex-direction: column; padding: 16px; }
.kpi .eyebrow { display: flex; align-items: center; gap: 7px; margin-bottom: 10px; }
.kpi .eyebrow svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2; }
.kpi .kpi-value { font-family: var(--mono); font-size: 26px; font-weight: 700; letter-spacing: -.01em; }
.kpi .kpi-sub { font-size: 11.5px; color: var(--k-text-faint); margin-top: 3px; min-height: 2.8em; }
.kpi .spark { height: 34px; margin-top: auto; padding-top: 10px; }

/* ============================================================
   Live events / alarms
   ============================================================ */
.ev { border: 1px solid var(--k-border); border-radius: var(--k-radius); padding: 11px 12px; background: var(--k-surface-2); border-left-width: 3px; display: flex; flex-direction: column; gap: 7px; }
.ev.crit, .ev.critical { border-left-color: var(--k-danger); }
.ev.warn, .ev.warning { border-left-color: var(--k-warning); }
.ev.info { border-left-color: var(--k-primary-bright); }
.ev-top { display: flex; align-items: center; gap: 8px; }
.ev-top .who { font-weight: 650; font-size: 13px; }
.ev-top .when { margin-left: auto; font-family: var(--mono); font-size: 10px; color: var(--k-text-faint); }
.ev-desc { font-size: 12.5px; color: var(--k-text-muted); line-height: 1.45; }
.ev-desc b { color: var(--k-text); font-weight: 600; }

/* Rule cards (plain-language) */
/* Cap the track width and left-align so a few rule cards cluster as a tidy group instead of
   stretching full-width (or stranding empty trailing columns) at small tenant scale. */
.rules-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 420px)); justify-content: start; gap: 12px; }
.rule { border: 1px solid var(--k-border); border-radius: var(--k-radius-lg); background: var(--k-surface); padding: 15px 16px; display: flex; flex-direction: column; gap: 12px; }
.rule-head { display: flex; align-items: center; gap: 9px; }
.rule-head .nm { font-weight: 650; font-size: 14px; }
.sentence { font-size: 13.5px; line-height: 1.75; color: var(--k-text-muted); }
.sentence .t { color: var(--k-text); font-weight: 600; padding: 1px 7px; border-radius: 6px; background: var(--k-surface-2); border: 1px solid var(--k-border); white-space: nowrap; }
.sentence .t.obj { color: var(--k-primary-bright); border-color: var(--k-border-strong); background: var(--k-primary-soft); }
.sentence .t.act { color: var(--k-success-fg); border-color: rgba(52,214,164,.3); background: var(--k-success-bg); }
.toggle { width: 38px; height: 22px; border-radius: 999px; background: var(--k-success); position: relative; cursor: pointer; border: 0; flex: 0 0 auto; }
.toggle::after { content: ""; position: absolute; top: 2px; right: 2px; width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: .15s; }
.toggle.off { background: var(--k-surface-3); border: 1px solid var(--k-border-strong); }
.toggle.off::after { right: auto; left: 2px; background: var(--k-text-faint); }
.toggle:disabled { cursor: not-allowed; opacity: .5; }

/* ============================================================
   Master–detail (Cameras) + tabs
   ============================================================ */
.master-detail { position: absolute; inset: 0; display: grid; grid-template-columns: 300px 1fr; }
.md-list { border-right: 1px solid var(--k-border); background: var(--k-surface); overflow: auto; }
.md-detail { overflow: auto; }
.md-row { display: flex; align-items: center; gap: 11px; padding: 12px 15px; border-bottom: 1px solid var(--k-line-soft); cursor: pointer; border-left: 3px solid transparent; text-decoration: none; color: var(--k-text); }
.md-row:hover { background: var(--k-surface-2); }
.md-row.active { background: var(--k-primary-soft); border-left-color: var(--k-primary-bright); }
.md-row .thumb { width: 104px; height: 58px; border-radius: 8px; background: radial-gradient(100% 100% at 30% 0, #223049, #0e141d); border: 1px solid var(--k-border); flex: 0 0 auto; overflow: hidden; position: relative; padding: 0; }
.md-row button.thumb { cursor: zoom-in; appearance: none; -webkit-appearance: none; }
.md-row button.thumb:focus-visible { outline: 2px solid var(--k-primary-bright); outline-offset: 2px; }
.md-row .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.md-row .thumb .thumb-expand-hint { position: absolute; top: 5px; right: 5px; width: 21px; height: 21px; border-radius: 6px; display: grid; place-items: center; background: rgba(6,10,18,.6); color: #fff; opacity: 0; transition: opacity .14s ease; pointer-events: none; }
.md-row .thumb .thumb-expand-hint svg { width: 13px; height: 13px; stroke: currentColor; fill: none; }
.md-row:hover button.thumb .thumb-expand-hint, .md-row button.thumb:focus-visible .thumb-expand-hint { opacity: 1; }
/* The row is the container; this link is the select target so the thumb button can own its own click.
   Name on its own line (full width) so the status badge on the meta line below never eats into it. */
.md-row-main { display: flex; flex-direction: column; justify-content: center; gap: 3px; flex: 1; min-width: 0; text-decoration: none; color: inherit; }
.md-row-name { font-size: 13px; font-weight: 600; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.md-row-meta { display: flex; align-items: center; gap: 8px; min-width: 0; }
.md-row-meta small { font-family: var(--mono); font-size: 10px; color: var(--k-text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.md-row-meta .k-badge { flex: 0 0 auto; margin-left: auto; }
/* Cameras list rows carry a large snapshot, so give the column extra room for names. */
.master-detail.md-cameras { grid-template-columns: clamp(320px, 24vw, 380px) 1fr; }
.cam-thumb-disabled { align-items: center; color: var(--k-text-faint); display: flex; flex-direction: column; font-size: 10px; gap: 3px; justify-content: center; }
.cam-thumb-disabled .k-icon { color: var(--k-text-faint); }
@media (max-width: 900px) { .master-detail.md-cameras { grid-template-columns: 1fr; } }

.detail-tabs { display: flex; gap: 2px; padding: 0 26px; border-bottom: 1px solid var(--k-border); background: var(--k-surface); overflow-x: auto; }
.detail-tab { border: 0; background: transparent; color: var(--k-text-muted); padding: 13px 15px; cursor: pointer; font-size: 13px; font-weight: 600; border-bottom: 2px solid transparent; margin-bottom: -1px; display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; text-decoration: none; }
.detail-tab svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.9; }
.detail-tab.active { color: var(--k-text); border-bottom-color: var(--k-primary-bright); }

.field-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px 22px; }
.pill-tabs { display: inline-flex; gap: 3px; padding: 4px; background: var(--k-surface); border: 1px solid var(--k-border); border-radius: 10px; }
.pill-tab { border: 0; background: transparent; color: var(--k-text-muted); padding: 7px 14px; border-radius: 7px; cursor: pointer; font-size: 13px; font-weight: 600; display: inline-flex; align-items: center; gap: 7px; }
.pill-tab.active { background: var(--k-primary-soft); color: var(--k-primary-bright); }

/* ============================================================
   Video wall (Live / Playback) — dark, retained structural names
   ============================================================ */
.camera-grid { background: #05070c; border-radius: var(--k-radius); display: grid; gap: 8px; min-height: 320px; padding: 8px; }
.playback-camera-grid .camera-cell, .camera-grid .camera-cell { max-height: 46vh; }
.playback-camera-grid.grid-3 .camera-cell, .playback-camera-grid.grid-4 .camera-cell,
.camera-grid.grid-3 .camera-cell, .camera-grid.grid-4 .camera-cell { max-height: 30vh; }
.grid-1 { grid-template-columns: 1fr; }
.grid-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
.grid-5 { grid-template-columns: repeat(5, minmax(0,1fr)); }
.grid-6 { grid-template-columns: repeat(6, minmax(0,1fr)); }
.camera-cell { align-items: center; aspect-ratio: 16/9; border-radius: var(--k-radius-sm); container-name: camera-tile; container-type: inline-size; display: flex; justify-content: center; overflow: hidden; position: relative; border: 1px solid var(--k-border);
  background: repeating-linear-gradient(115deg, rgba(255,255,255,.012) 0 2px, transparent 2px 5px), radial-gradient(120% 90% at 30% 10%, #16203200, #0a0e15 70%); }
.camera-cell.livecell, .camera-cell:has(.camera-video) { border-color: rgba(52,214,164,.22); }
.camera-cell.selected-cell { box-shadow: inset 0 0 0 2px var(--k-primary-bright); }
.camera-cell.fit-cover .camera-video, .camera-cell.fit-cover .cell-poster { object-fit: cover; }
.camera-cell.zoomed { cursor: grab; } .camera-cell.zoomed.panning { cursor: grabbing; }
.camera-video { height: 100%; object-fit: contain; width: 100%; }
/* z-index 4: sit above the <video> (z1), loading veil (z2) and detection overlay (z3) — the video is
   position:relative z1, so without this the picture occludes the name/status (visible only through the
   object-fit letterbox bars, i.e. "half hidden"). Cell controls stay on top at z5. */
.cell-label { background: linear-gradient(transparent, rgba(5,7,12,.85)); bottom: 0; color: #fff; font-size: .78rem; left: 0; overflow: hidden; padding: .5rem .7rem; position: absolute; right: 0; text-overflow: ellipsis; white-space: nowrap; z-index: 4; }
.cell-status { border-radius: 999px; font-size: .7rem; font-weight: 700; padding: .2rem .5rem; position: absolute; left: .6rem; text-transform: uppercase; top: .6rem; font-family: var(--mono); letter-spacing: .05em; z-index: 4; }
.status-live { background: var(--k-success-bg); color: var(--k-success-fg); }
.status-rec { background: var(--k-danger-bg); color: var(--k-danger-fg); }
.status-offline { background: var(--k-neutral-bg); color: var(--k-neutral-fg); }
.cell-transport { border-radius: 999px; font-size: .58rem; font-weight: 700; left: .6rem; letter-spacing: .04em; padding: .18rem .45rem; position: absolute; text-transform: uppercase; top: .6rem; z-index: 2; font-family: var(--mono); }
.transport-webrtc { background: var(--k-primary-soft); color: var(--k-primary-bright); }
.transport-hls { background: rgba(52,214,164,.14); color: var(--k-success-fg); }
.empty-cell { background: #0b111c; }
.cell-overlay { align-items: center; display: flex; height: 100%; justify-content: center; width: 100%; }
.camera-cell.empty-cell { border-style: dashed; border-color: var(--k-border); transition: border-color .15s, background .15s; }
.camera-cell.empty-cell:hover { background: #0f1726; border-color: var(--k-primary-bright); }
.camera-cell .cell-placeholder { font-weight: 500; color: var(--k-text-faint); }
.camera-cell.is-dense-empty .cell-placeholder { padding: .25rem; }
.camera-cell.is-dense-empty .cell-placeholder-icon { margin-bottom: 0 !important; }
.camera-cell.is-dense-empty .cell-placeholder-icon svg { height: 18px; width: 18px; }
.camera-cell.is-dense-empty .cell-placeholder-text { display: none; }
.camera-grid.is-cell-focused { position: relative; }
.focus-mode-ribbon {
  align-items: center;
  backdrop-filter: blur(10px);
  background: rgba(10,16,26,.82);
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 999px;
  box-shadow: 0 8px 24px rgba(0,0,0,.34);
  color: #E8EEF7;
  cursor: pointer;
  display: inline-flex;
  font-size: 11.5px;
  font-weight: 650;
  left: 50%;
  max-width: calc(100% - 24px);
  min-height: 34px;
  overflow: hidden;
  padding: 7px 13px;
  position: absolute;
  text-overflow: ellipsis;
  top: 10px;
  transform: translateX(-50%);
  white-space: nowrap;
  z-index: 12;
}
.focus-mode-ribbon:hover, .focus-mode-ribbon:focus-visible { background: rgba(20,28,44,.94); border-color: rgba(255,255,255,.3); }

/* Immersive full-height layout */
.immersive-header { display: flex; align-items: baseline; gap: .85rem; flex: 0 0 auto; margin-bottom: .55rem; }
.immersive-eyebrow { color: var(--k-text-faint); font-family: var(--mono); font-size: .64rem; font-weight: 700; text-transform: uppercase; letter-spacing: .12em; flex: 0 0 auto; }
.immersive-title { font-size: 1.15rem; font-weight: 700; margin: 0; line-height: 1.1; }
.immersive-subtitle { color: var(--k-text-muted); font-size: .8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.live-view-toolbar, .playback-toolbar { row-gap: .4rem; }
.live-view-toolbar .form-select-sm, .playback-toolbar .form-select-sm { background-color: var(--k-surface-2); }

/* ---- Compact grouped toolbar for the video-grid pages (Monitor / Investigate) ---- */
.grid-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: .3rem; background: var(--k-surface); border: 1px solid var(--k-border); border-radius: var(--k-radius-lg); padding: .3rem .45rem; }
.gt-group { display: flex; align-items: center; gap: .25rem; }
.gt-group + .gt-group { border-left: 1px solid var(--k-border); margin-left: .1rem; padding-left: .4rem; }
.gt-spacer { flex: 1 1 auto; min-width: .5rem; }
.gt-meta { color: var(--k-text-faint); font-size: .72rem; font-family: var(--mono); white-space: nowrap; padding: 0 .35rem; }
.grid-toolbar .form-select-sm { height: 32px; border-radius: 8px; border-color: var(--k-border-strong); }

.tbtn { display: inline-flex; align-items: center; justify-content: center; gap: .35rem; height: 32px; min-width: 32px; padding: 0 .6rem; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--k-text-muted); cursor: pointer; font-size: .78rem; font-weight: 500; line-height: 1; white-space: nowrap; text-decoration: none; transition: background .12s, color .12s, border-color .12s; }
.tbtn:hover, .tbtn:focus-visible { background: var(--k-surface-2); color: var(--k-text); }
.tbtn.tbtn--icon { width: 32px; padding: 0; }
.tbtn.is-active, .tbtn[aria-pressed="true"] { background: var(--k-primary-soft); color: var(--k-primary-bright); }
.tbtn.tbtn--danger:hover { background: var(--k-danger-bg); color: var(--k-danger-fg); }
.tbtn svg { flex: 0 0 auto; }
.tbtn:disabled { opacity: .45; cursor: not-allowed; }
.seg > button:disabled { opacity: .45; cursor: not-allowed; }

/* Segmented single-select (used for playback speed) */
.seg { display: inline-flex; align-items: stretch; background: var(--k-surface-2); border: 1px solid var(--k-border-strong); border-radius: 8px; overflow: hidden; height: 32px; }
.seg > button { border: 0; background: transparent; color: var(--k-text-muted); min-width: 32px; padding: 0 .5rem; cursor: pointer; font-size: .74rem; font-weight: 600; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
.seg > button + button { border-left: 1px solid var(--k-border); }
.seg > button:hover { background: var(--k-surface-3); color: var(--k-text); }
.seg > button.active, .seg > button.is-active { background: var(--k-primary); color: #fff; }

.grid-toolbar-menu .dropdown-item { display: flex; align-items: center; gap: .55rem; }
.grid-toolbar-menu .dropdown-item svg { flex: 0 0 auto; opacity: .85; }

@media (min-width: 992px) {
  .canvas.content-immersive { display: flex; flex-direction: column; height: calc(100dvh - var(--topbar-h)); max-height: calc(100dvh - var(--topbar-h)); padding: .85rem 1.15rem .95rem; overflow: hidden; }
  .content-immersive .live-view-layout { flex: 1 1 auto; min-height: 0; gap: .85rem; }
  .content-immersive .live-view-sidebar, .content-immersive .playback-sidebar { max-height: none; height: 100%; }
  .content-immersive .live-view-main, .content-immersive .playback-main { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
  .content-immersive .live-view-toolbar, .content-immersive .playback-toolbar, .content-immersive #exportStatus, .content-immersive .playback-timeline-panel { flex: 0 0 auto; }
  .content-immersive .camera-grid { flex: 1 1 auto; min-height: 0; grid-auto-rows: 1fr; }
  .content-immersive .camera-grid .camera-cell { aspect-ratio: auto; max-height: none; height: 100%; min-height: 0; }
  .content-immersive .live-view-stage:not(.has-wall-state) > #noStreams { display: none !important; }
}

/* ============================================================
   Auth (login) — dark
   ============================================================ */
.auth-page { align-items: center; background: radial-gradient(1000px 600px at 70% -10%, rgba(90,130,180,.12), transparent 60%), var(--k-bg); display: flex; min-height: 100dvh; }
.auth-card { border-radius: var(--k-radius-lg); background: var(--k-surface); border: 1px solid var(--k-border-strong); box-shadow: var(--k-shadow-lg); }
.auth-card .card-body { padding: 2.5rem 2.4rem 2.7rem; }
.auth-logo { width: 196px; max-width: 70%; height: auto; display: block; margin: 0 auto 1.9rem; }
.auth-title { text-align: center; font-size: 1.2rem; font-weight: 600; color: var(--k-text); letter-spacing: -.01em; margin: 0 0 1.7rem; }
.auth-page .form-control-lg { font-size: .95rem; padding: .62rem .85rem; border-radius: 10px; }
.auth-page .btn-lg { padding: .68rem 1rem; font-size: .98rem; }

/* ============================================================
   Utilities
   ============================================================ */
.data-mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.hairline { border-top: 1px solid var(--k-border); }
.muted { color: var(--k-text-muted); }

/* ============================================================
   Responsive — tablet & phone.
   Everything here is scoped to max-width, so the desktop layout above
   is left exactly as-is; these rules only add mobile behaviour.
   ============================================================ */

/* Tablet / small laptop (below the 992px immersive breakpoint) */
@media (max-width: 991.98px) {
  /* Immersive pages (Monitor / Investigate) only get their fixed-height flex
     layout at >=992px; below that let the canvas SCROLL instead of clipping
     (it is marked no-scroll for the desktop full-bleed layout). */
  .canvas.no-scroll, .canvas.content-immersive { overflow: auto; }
  .canvas.content-immersive {
    height: auto;
    max-height: none;
    padding: 12px 14px 22px;
  }

  /* The global search bar is redundant on small screens — reclaim the width. */
  .topbar-search { display: none; }

  /* Keep video-wall cells usable: cap the widest grids. */
  .grid-5, .grid-6 { grid-template-columns: repeat(3, minmax(0,1fr)); }
  .grid-4 { grid-template-columns: repeat(2, minmax(0,1fr)); }

  /* Master–detail (Cameras) stacks to one column. */
  .master-detail { grid-template-columns: 1fr; }
}

/* Shared list actions keep desktop table alignment; the phone record layout below expands and wraps
   the same group without changing the Razor/JavaScript markup. */
.mobile-record-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
}

/* Portrait tablets share the compact shell. Keeping the desktop rail at exactly 768px used to
   leave less usable content than the phone layout one pixel below it. */
@media (max-width: 839.98px) {
  .app-shell {
    grid-template-columns: 1fr;
    grid-template-rows: var(--topbar-h) 1fr auto;
    grid-template-areas: "topbar" "canvas" "rail";
  }
  .rail {
    flex-direction: row;
    align-items: stretch;
    gap: 0;
    width: 100%;
    min-width: 0;
    padding: 0;
    padding-bottom: env(safe-area-inset-bottom); /* clear the iOS home indicator */
    border-right: 0;
    border-top: 1px solid var(--k-border);
    background: linear-gradient(0deg, #0C1119, #0A0F17);
  }
  .rail-brand { display: none; }
  .rail-nav { flex: 1 1 auto; flex-direction: row; width: auto; min-width: 0; gap: 0; }
  .rail-link {
    flex: 1 1 0; width: auto; min-width: 0;
    border-radius: 0; padding: 7px 2px 5px; gap: 3px;
  }
  .rail-link svg { width: 21px; height: 21px; }
  .rail-link span {
    font-size: 11px; max-width: 100%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .rail-link[data-compact-label] span:not(.rail-badge) { display: none; }
  .rail-link[data-compact-label]::after {
    content: attr(data-compact-label);
    font-size: 11px;
    font-weight: 600;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Active marker: a bar across the top of the tab instead of down the left. */
  .rail-link.active::before {
    left: 50%; top: 0; transform: translateX(-50%);
    width: 24px; height: 3px; border-radius: 0 0 3px 3px;
  }
  .rail-badge { top: 4px; right: 24%; }
  .rail-foot {
    flex-direction: row; align-items: center; gap: 2px;
    padding: 0 4px; border-left: 1px solid var(--k-border);
  }
  .rail-foot .avatar { display: none; }          /* keep the bar to nav + sign-out */
  .rail-foot .icon-btn { width: 42px; height: 42px; }

  /* Topbar: tighten and drop the status pills (alarms count stays on the tab bar). */
  .topbar { gap: 8px; padding: 0 12px; }
  .status-strip { display: none; }
  .topbar .ws-name { font-size: 13px; }
  .topbar .ws-sub { font-size: 10px; }

  /* Content spacing + headings scale down. */
  .page { padding: 14px 14px 26px; }
  .page-narrow { max-width: 100%; }
  /* PageHeaderTagHelper adds Bootstrap's important mb-4/gap-3 utilities. Override them explicitly
     on phones so the shared header does not waste the same vertical space as desktop. */
  .page-header { margin-bottom: 10px !important; gap: 7px !important; }
  .page-header:not(.immersive-header) {
    align-items: stretch !important;
    flex-direction: column !important;
  }
  .page-header-title { font-size: 17px; line-height: 1.18; }
  .page-header-subtitle { margin-top: 3px; font-size: 12.5px; line-height: 1.4; }
  .page-header-back {
    min-height: 40px;
    margin-top: -10px;
    margin-bottom: -6px;
    padding-right: 8px;
    font-size: 11.5px;
  }
  .page-header-actions { gap: 6px; }
  .page-header-actions .btn { min-height: 40px; }
  .immersive-header { flex-wrap: wrap; gap: .5rem; }
}

/* Keep dense walls bounded throughout the compact layout so transport/timeline controls remain in
   the working viewport. The selected 1×1 view remains unconstrained. */
@media (max-width: 991.98px) {
  .content-immersive .camera-grid {
    align-content: start;
    max-height: max(320px, min(52dvh, 420px));
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .content-immersive .camera-grid.grid-1 { max-height: none; overflow: visible; }
}

/* Phones keep two useful camera columns where there is room; the smallest handsets fall back to
   one readable column below. Portrait tablets retain the <=991px wall. */
@media (max-width: 575.98px) {
  .grid-2, .grid-3, .grid-4, .grid-5, .grid-6 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .playback-camera-grid .camera-cell, .camera-grid .camera-cell,
  .playback-camera-grid.grid-3 .camera-cell, .playback-camera-grid.grid-4 .camera-cell,
  .camera-grid.grid-3 .camera-cell, .camera-grid.grid-4 .camera-cell { max-height: none; }
}

@media (max-width: 359.98px) {
  .grid-2, .grid-3, .grid-4, .grid-5, .grid-6 {
    grid-template-columns: minmax(0, 1fr);
  }
  /* A height-capped one-column wall must size tracks from the 16:9 tiles. With the default `auto`
     tracks, Grid distributes the stage across every row while each tile keeps its intrinsic
     height, causing adjacent video, labels and controls to overlap. Let the wall scroll full tiles. */
  .content-immersive .camera-grid:not(.grid-1) {
    grid-auto-rows: max-content;
  }
  .rail-link span:not(.rail-badge) { display: none; }
  .rail-link[data-compact-label]::after { display: none; }
  .rail-link { padding-block: 8px; }
}

/* Configuration tables become labelled records throughout tablet widths. This prevents the
   840–991px side-rail range from turning action columns into a hidden horizontal-scroll target. */
@media (max-width: 991.98px) {
  /* Slightly denser tables so more fits without horizontal scroll. */
  .page .table { font-size: .82rem; }

  /* Configuration lists become labelled records instead of miniature desktop tables. Keep the
     real header available to assistive technology while the data-label copy supplies the visible
     field name. Opt-in keeps dense diagnostics and timeline tables horizontally scrollable. */
  .mobile-record-table-wrap { overflow: visible; }
  .mobile-record-table { display: block; width: 100%; }
  .mobile-record-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
  .mobile-record-table tbody {
    display: grid;
    gap: 8px;
    width: 100%;
  }
  .mobile-record-table tbody tr {
    display: grid;
    width: 100%;
    min-width: 0;
    padding: 9px 11px;
    border: 1px solid var(--k-border);
    border-radius: 10px;
    background: var(--k-surface-2);
  }
  .mobile-record-table tbody td {
    display: grid;
    grid-template-columns: minmax(76px, 30%) minmax(0, 1fr);
    gap: 9px;
    align-items: start;
    min-width: 0;
    padding: 4px 0;
    border: 0;
    text-align: left !important;
    white-space: normal !important;
    overflow-wrap: anywhere;
  }
  .mobile-record-table tbody td::before {
    content: attr(data-label);
    color: var(--k-text-faint);
    font-family: var(--mono);
    font-size: 10.5px;
    font-weight: 650;
    letter-spacing: .06em;
    line-height: 1.45;
    text-transform: uppercase;
  }
  .mobile-record-table tbody td:first-child:not([colspan]) { padding-top: 0; }
  .mobile-record-table tbody td:last-child:not([colspan]) { padding-bottom: 0; }
  .mobile-record-table tbody td[data-label="Actions"] {
    grid-template-columns: minmax(0, 1fr);
    gap: 5px;
    padding-top: 7px;
  }
  .mobile-record-table tbody td[colspan] {
    display: block;
    padding: 0;
  }
  .mobile-record-table tbody td[colspan]::before { content: none; }
  .mobile-record-table .mobile-record-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: flex-start !important;
    min-width: 0;
  }
  .mobile-record-table .mobile-record-actions .btn {
    min-height: 40px;
    margin-left: 0 !important;
  }
  .mobile-record-table code { font-size: 11px; }
}

@media (max-width: 575.98px) {
  /* Bootstrap modals go (near) full-width on a phone. */
  .modal-dialog:not(.modal-fullscreen) { margin: .5rem; }
}

@media (max-width: 839.98px) and (pointer: coarse) {
  .canvas .btn:not(.btn-close),
  .canvas .form-control,
  .canvas .form-select {
    min-height: 44px;
  }

  .mobile-record-table .mobile-record-actions .btn,
  .camera-entry-tabs .pill-tab,
  .site-assignment-head .btn,
  .arc-account-row-actions .btn,
  .arc-camera-assignment > .btn {
    min-height: 44px !important;
  }

  /* Preserve the compact visual track while making the whole switch a true 44px touch target. */
  .toggle {
    background: transparent;
    border: 0;
    height: 44px;
    width: 50px;
  }
  .toggle::before {
    background: var(--k-success);
    border-radius: 999px;
    content: "";
    height: 22px;
    left: 6px;
    position: absolute;
    top: 11px;
    width: 38px;
  }
  .toggle::after { right: 8px; top: 13px; }
  .toggle.off { background: transparent; border: 0; }
  .toggle.off::before { background: var(--k-surface-3); border: 1px solid var(--k-border-strong); }
  .toggle.off::after { left: 8px; right: auto; }
}
