/* ============================================================================
   Kenhos-FS UI — ported verbatim from the Django proof-of-concept design system
   (dev-stuff/djangosrc/templates/base.html + per-page extra_css). Foundation,
   shell (sidebar/topbar), and shared components live here. White-label colours
   come from CSS vars set by App.razor (defaults match the Django palette).
   ============================================================================ */

:root {
    --accent: #3b82f6;
    --sidebar-bg: #1e293b;
    --sidebar-active: #334155;
    --sidebar-fg: #cbd5e1;
    --shadow: 0 1px 3px rgba(0,0,0,.08);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-size: 0.875rem;
    background: #f5f5f5;
    color: #333;
}

/* ---- Layout shell (base.html) ---- */
.layout { display: flex; min-height: 100vh; }

.sidebar { width: 240px; flex-shrink: 0; background: var(--sidebar-bg); color: #fff; display: flex; flex-direction: column; position: sticky; top: 0; height: 100vh; }
.sidebar-header { padding: 20px; font-size: 1.25rem; font-weight: 600; border-bottom: 1px solid var(--sidebar-border, #334155); }
.sidebar-logo { max-height: 28px; display: block; }
.sidebar-nav { flex: 1; padding: 12px 0; overflow-y: auto; }
.sidebar-nav::-webkit-scrollbar { width: 8px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.12); border-radius: 4px; }

.nav-icon { width: 18px; height: 18px; flex-shrink: 0; vertical-align: middle; }
.sidebar-nav a { display: flex; align-items: center; gap: 10px; padding: 10px 20px; color: var(--sidebar-fg); text-decoration: none; transition: background 0.15s; }
.sidebar-nav a:hover, .sidebar-nav a.active { background: var(--sidebar-active); color: #fff; text-decoration: none; }
.nav-label { display: flex; align-items: center; gap: 10px; }

.nav-parent-toggle { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 10px 20px; color: var(--sidebar-fg); background: none; border: none; font: inherit; text-align: left; cursor: pointer; transition: background 0.15s; }
.nav-parent-toggle:hover { background: var(--sidebar-active); color: #fff; }
.nav-arrow::after { content: "\25B8"; font-size: 0.75rem; transition: transform 0.15s; display: inline-block; }
.nav-parent-toggle.open .nav-arrow::after { transform: rotate(90deg); }
.nav-children { display: none; }
.nav-children.open { display: block; }
.nav-children a { padding-left: 48px; }

.nav-section-label { padding: 32px 20px 4px; font-size: 0.6rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: var(--sidebar-fg); opacity: .6; }
.nav-section-label:first-child { padding-top: 4px; }

.nav-coming-soon { display: flex; align-items: center; gap: 10px; padding: 10px 20px; color: #475569; font-size: inherit; }
.nav-coming-soon .badge-soon, .nav-child-coming-soon .badge-soon { font-size: 0.55rem; background: #334155; color: #64748b; padding: 1px 6px; border-radius: 9999px; margin-left: auto; }
.nav-child-coming-soon { display: flex; align-items: center; padding: 8px 20px 8px 48px; color: #475569; font-size: inherit; }

.sidebar-footer { padding: 14px 20px; border-top: 1px solid var(--sidebar-border, #334155); }
.role-badge { font-size: 0.62rem; text-transform: uppercase; letter-spacing: .05em; background: #334155; color: #94a3b8; padding: 3px 8px; border-radius: 6px; }

.content-area { flex: 1; display: flex; flex-direction: column; min-width: 0; }

/* ---- Top bar (base.html) ---- */
.topbar { background: var(--topbar-bg, #fff); color: var(--topbar-fg, #334155); border-bottom: 1px solid rgba(120,120,120,.22); padding: 0 20px; height: 44px; display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; box-shadow: 0 1px 3px rgba(0,0,0,0.06); position: sticky; top: 0; z-index: 20; }
.topbar-breadcrumb { display: flex; align-items: center; gap: 5px; font-size: 0.8rem; color: var(--topbar-fg, #5a6472); }
.topbar-breadcrumb a { color: var(--topbar-fg, #8b95a1); opacity: .68; text-decoration: none; }
.topbar-breadcrumb a:hover { opacity: 1; }
.topbar-breadcrumb .separator { color: var(--topbar-fg, #c8cdd4); opacity: .4; }
.topbar-breadcrumb .current { color: var(--topbar-fg, #0d1117); font-weight: 500; }
.topbar-right { display: flex; align-items: center; gap: 16px; }
.topbar-user { font-size: 0.8rem; color: var(--topbar-fg, #5a6472); opacity: .82; text-decoration: none; }
.topbar-user:hover { opacity: 1; }
.topbar-logout { font-size: 0.8rem; color: var(--topbar-fg, #5a6472); background: none; border: 1px solid rgba(120,120,120,.35); border-radius: 4px; padding: 4px 10px; cursor: pointer; font-family: inherit; }
.topbar-logout:hover { background: rgba(120,120,120,.12); }
.topbar-divider { width: 1px; height: 20px; background: var(--topbar-fg, #dde1e7); opacity: .25; }

.tenant-selector { display: flex; align-items: center; }
.tenant-current { font-size: 0.8rem; color: #374151; font-weight: 500; }
.tenant-dropdown { position: relative; }
.tenant-dropdown-toggle { display: flex; align-items: center; gap: 6px; font-size: 0.8rem; font-family: inherit; color: #374151; background: #f9fafb; border: 1px solid #d1d5db; border-radius: 4px; padding: 4px 10px; cursor: pointer; white-space: nowrap; }
.tenant-dropdown-toggle:hover { background: #f3f4f6; }
/* Top-bar tenant switcher: make it generously wide (name left, caret right). */
.topbar-right .tenant-dropdown-toggle { min-width: 300px; justify-content: space-between; }
.topbar-right .tenant-dropdown-menu { min-width: 300px; }
/* SearchSelect used as a toolbar filter: match the height/shape of .input / select.input next to it. */
.tenant-dropdown.ss-input { min-width: 200px; }
.tenant-dropdown.ss-input .tenant-dropdown-toggle { width: 100%; height: 36px; padding: 7px 10px; font-size: inherit; border-radius: 6px; background: #fff; justify-content: space-between; }
/* Wide variant: a roomier field whose dropdown panel matches the field width exactly. */
.tenant-dropdown.ss-wide { width: 380px; max-width: 100%; }
/* Match the height/shape of .input / select.input so it lines up with adjacent form controls. */
.tenant-dropdown.ss-wide .tenant-dropdown-toggle { width: 100%; height: 36px; padding: 7px 10px; font-size: inherit; border-radius: 6px; background: #fff; justify-content: space-between; }
.tenant-dropdown.ss-wide .tenant-dropdown-menu { left: 0; right: auto; width: 100%; min-width: 0; max-width: none; }
/* Locked/disabled search-select (e.g. Timezone while Business hours = Same as tenant). */
.tenant-dropdown-toggle:disabled { background: #f8fafc; color: #94a3b8; cursor: not-allowed; }
.tenant-dropdown-menu { display: none; position: absolute; top: calc(100% + 4px); right: 0; background: #fff; border: 1px solid #d1d5db; border-radius: 6px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); min-width: 330px; max-width: 480px; z-index: 100; overflow: hidden; }
.tenant-dropdown-menu.open { display: block; }
.tenant-search-wrap { padding: 8px; border-bottom: 1px solid #e5e7eb; }
.tenant-search { width: 100%; padding: 6px 8px; border: 1px solid #d1d5db; border-radius: 4px; font-size: 0.8rem; font-family: inherit; }
.tenant-search:focus { outline: none; border-color: #3b82f6; box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15); }
.tenant-options { max-height: 240px; overflow-y: auto; }
.tenant-option { padding: 8px 12px; font-size: 0.8rem; color: #374151; cursor: pointer; }
.tenant-option:hover { background: #f3f4f6; }
.tenant-option.selected { background: #eff6ff; color: #1e40af; font-weight: 500; }

.main-content { flex: 1; padding: 32px; background-color: var(--app-bg, #f5f5f5); background-image: var(--app-bg-image, none); background-size: cover; background-position: center; background-attachment: fixed; }

/* Dashboard charts. Fixed chart height (an svg with height:100% balloons with no bound).
   Inside the dashboard every panel is a white card (consistent with the bar + totals boxes). */
.dash .graph-card { background: #fff; box-shadow: var(--shadow); border: none; }
.dash-chart { width: 100%; height: 220px; display: block; }
.chart-legend { display: flex; flex-wrap: wrap; gap: 14px; font-size: .78rem; color: #64748b; margin-top: 8px; padding-left: 16px; }
.chart-legend .sw, .calls-breakdown .sw, .history-totals .sw { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; vertical-align: middle; }

/* Grouped calls figures bar (active now / historical totals) — big, equal tiles. Spans its
   container (full width as the "Now" KPI strip; one chart-card wide inside the History grid). */
.callsbar { display: flex; background: #fff; border-radius: 8px; box-shadow: var(--shadow); padding: 18px 8px; }
.callsbar .cbig { flex: 1; display: flex; flex-direction: column; align-items: center; text-align: center; padding: 0 6px; border-right: 1px solid #f1f5f9; }
.callsbar .cbig:last-child { border-right: none; }
.callsbar .cbig.divide { border-left: 2px solid #e5e7eb; }
.callsbar .cbig .n { font-size: 1.9rem; font-weight: 600; line-height: 1; color: #1e293b; white-space: nowrap; }
.callsbar .cbig .n .of { font-size: 1rem; font-weight: 500; color: #94a3b8; }
.callsbar .cbig .t { font-size: .78rem; color: #64748b; margin-top: 6px; }

/* Dashboard: a 3-column grid; panels span 1/3 (.c1), 2/3 (.c2) or full width (default).
   align-items:stretch keeps every panel in a row the same height. */
.dash { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; align-items: stretch; }
.dash > * { grid-column: 1 / -1; }            /* full width unless told otherwise */
.dash > .c1 { grid-column: span 1; }
.dash > .c2 { grid-column: span 2; }
.dash-section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0; padding-bottom: 8px; border-bottom: 1px solid #e5e7eb; }
.dash-section-head:not(:first-child) { margin-top: 10px; }
.dash-section-head h2 { font-size: .95rem; font-weight: 600; color: var(--header-text, #1e293b); margin: 0; display: flex; align-items: center; gap: 8px; }
@media (max-width: 980px) { .dash { grid-template-columns: 1fr; } .dash > .c1, .dash > .c2 { grid-column: 1 / -1; } }

/* History totals (1/3): five mini-boxes filling the row height; coloured numbers are the chart key */
.totals-stack { display: flex; flex-direction: column; gap: 10px; }
/* min-height:0 + compact rows so the five boxes divide the chart's height beside them, rather than
   forcing the row taller than the chart. */
.totals-stack .tbox { flex: 1; min-height: 0; background: #fff; border-radius: 8px; box-shadow: var(--shadow); padding: 8px 16px; display: flex; align-items: center; gap: 10px; }
.totals-stack .tbox .t { font-size: .95rem; color: #475569; }
.totals-stack .tbox .n { margin-left: auto; font-size: 1.6rem; font-weight: 600; line-height: 1; color: #1e293b; }
/* Stat boxes that deep-link to their detail page (dashboard Now / History). */
.callsbar a.cbig, .totals-stack a.tbox { text-decoration: none; color: inherit; cursor: pointer; transition: background .12s; }
.callsbar a.cbig:hover, .totals-stack a.tbox:hover { background: #f8fafc; }
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: #16a34a; box-shadow: 0 0 0 0 rgba(22,163,74,.5); animation: live-pulse 2s infinite; }
@keyframes live-pulse { 0%,100% { box-shadow: 0 0 0 0 rgba(22,163,74,.5); } 50% { box-shadow: 0 0 0 5px rgba(22,163,74,0); } }

/* Chart axes */
.chart-area { display: flex; gap: 8px; }
.chart-yaxis { display: flex; flex-direction: column; justify-content: space-between; height: 200px; min-width: 30px; text-align: right; font-size: .7rem; color: #94a3b8; }
.chart-plot { flex: 1; min-width: 0; }
.chart-xaxis { display: flex; justify-content: space-between; font-size: .7rem; color: #94a3b8; margin-top: 4px; padding-left: 38px; }

/* ---- Page banner alert (base.html) ---- */
.alert { background: #fef3c7; border: 1px solid #f59e0b; color: #92400e; padding: 12px 16px; border-radius: 6px; margin-bottom: 24px; font-size: 0.875rem; }
.alert a { color: #92400e; font-weight: 600; }
.alert-success { background: #f0fdf4; color: #166534; border: 1px solid #bbf7d0; padding: 10px 16px; border-radius: 6px; margin-bottom: 16px; font-size: 0.85rem; }
.alert-error { background: #fef2f2; color: #991b1b; border: 1px solid #fecaca; padding: 10px 16px; border-radius: 6px; margin-bottom: 16px; font-size: 0.85rem; }
.alert-info { background: #eff6ff; color: #1d4ed8; border: 1px solid #bfdbfe; padding: 10px 16px; border-radius: 6px; margin-bottom: 16px; font-size: 0.85rem; }
.alert-ok { background: #f0fdf4; color: #166534; border: 1px solid #bbf7d0; padding: 10px 16px; border-radius: 6px; margin-bottom: 16px; font-size: 0.85rem; }
.alert-warn { background: #fffbeb; color: #92400e; border: 1px solid #fde68a; padding: 10px 16px; border-radius: 6px; margin-bottom: 16px; font-size: 0.85rem; }

/* ---- Pagination (base.html) ---- */
.pagination-bar { display: flex; align-items: center; justify-content: space-between; margin-top: 12px; font-size: 0.75rem; color: #64748b; }
.pagination-bar .pagination-info { display: flex; align-items: center; gap: 8px; }
.pagination-bar select { padding: 4px 6px; border: 1px solid #d1d5db; border-radius: 4px; font-size: 0.75rem; font-family: inherit; background: #fff; cursor: pointer; }
.pagination-nav { display: flex; align-items: center; gap: 2px; }
.pagination-nav a, .pagination-nav span { display: inline-flex; align-items: center; justify-content: center; min-width: 28px; height: 28px; padding: 0 6px; border: 1px solid #d1d5db; border-radius: 4px; text-decoration: none; color: #374151; font-size: 0.75rem; background: #fff; }
.pagination-nav a:hover { background: #f3f4f6; }
.pagination-nav .current { background: var(--accent, #1e293b); color: #fff; border-color: var(--accent, #1e293b); }
.pagination-nav .disabled { color: #c8cdd4; cursor: default; pointer-events: none; }

/* ============================================================================
   Shared components (ported from the Django per-page extra_css blocks)
   ============================================================================ */

h1 { font-size: 1.5rem; font-weight: 600; color: var(--header-text, #1e293b); margin: 0 0 22px; }
.page-header { margin-bottom: 24px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.page-header h1 { margin: 0; }
/* Header-aligned Save/Cancel. Save is the solid dark primary; Cancel is a solid light-grey
   button — still obviously a button, but easy to tell apart from Save at a glance. */
.header-actions { display: flex; align-items: center; gap: 8px; }
.header-actions .btn { min-width: 92px; justify-content: center; }
.header-actions .btn-secondary { background: #e2e8f0; border-color: #cbd5e1; color: #334155; }
.header-actions .btn-secondary:hover { background: #cbd5e1; }
h1:focus, h1:focus-visible, [tabindex="-1"]:focus, [tabindex="-1"]:focus-visible { outline: none; }
h2 { font-size: 1.05rem; font-weight: 600; color: var(--header-text, #1e293b); }
h3 { font-size: 0.95rem; font-weight: 600; color: #1e293b; }
a { color: var(--accent, #2563eb); text-decoration: none; }
a:hover { text-decoration: underline; }
.muted { color: #94a3b8; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .82rem; }
.page-lead { color: #64748b; margin: 0 0 20px; max-width: 80ch; }
/* Inline page breadcrumbs are redundant — the topbar renders the breadcrumb trail. */
.breadcrumb { display: none; }

/* Toolbar above tables */
.toolbar { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.toolbar .spacer { flex: 1; }
.search-box, input.search { padding: 8px 12px; border: 1px solid #d1d5db; border-radius: 6px; font-size: inherit; width: 240px; font-family: inherit; }
.search-box:focus { outline: none; border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59,130,246,.15); }

/* Stat cards */
.stat-bar, .stat-cards { display: flex; gap: 12px; margin-bottom: 20px; flex-wrap: wrap; }
.stat-card { background: #fff; border-radius: 8px; box-shadow: var(--shadow); padding: 14px 20px; flex: 1; min-width: 160px; }
/* Fixed-width cards (pack from the left, don't stretch) — keeps a lone card from ballooning. */
.stat-cards.compact .stat-card { flex: 0 0 270px; }
/* Reusable half-width variant — packs more, narrower cards. Opt in per page. */
.stat-cards.narrow .stat-card { flex: 0 0 135px; min-width: 0; }
/* …but a card carrying a wider value (e.g. an HH:MM:SS talk-time total) can opt back out. */
.stat-cards.narrow .stat-card.wide { flex: 0 0 200px; }
.stat-card .value { font-size: 1.25rem; font-weight: 700; color: #1e293b; }
.stat-card .label { font-size: 0.7rem; color: #94a3b8; text-transform: uppercase; letter-spacing: .03em; margin-top: 2px; }
.stat-card.green .value { color: #166534; }
.stat-card.red .value { color: #991b1b; }
.stat-card.amber .value { color: #92400e; }

/* Hub / settings index card grid */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
/* Integrations list: 25% wider cards, all equal width (1fr) and equal height (grid stretch + flex card). */
.integrations-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(325px, 1fr)); gap: 16px; align-items: stretch; }
.integrations-grid > .card { display: flex; flex-direction: column; }
.integrations-card-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 8px; }
.integrations-card-head .badges { display: flex; gap: 6px; align-items: center; flex-shrink: 0; }
.card { background: #fff; border-radius: 8px; box-shadow: var(--shadow); padding: 18px 20px; }
.card-link { display: block; color: #333; }
.card-link:hover { box-shadow: 0 2px 8px rgba(0,0,0,.12); text-decoration: none; }
.card-kicker { font-size: 0.68rem; text-transform: uppercase; letter-spacing: .05em; color: #94a3b8; font-weight: 600; }
.card-value { font-size: 1.25rem; font-weight: 600; margin: 4px 0 6px; color: #1e293b; }
.card-desc { color: #64748b; font-size: 0.82rem; }
.card-section-title { font-weight: 600; color: #1e293b; font-size: 0.85rem; padding-bottom: 10px; margin-bottom: 14px; border-bottom: 1px solid #e5e7eb; }
.card-columns { column-gap: 16px; column-count: 3; }
@media (max-width: 1300px) { .card-columns { column-count: 2; } }
@media (max-width: 860px) { .card-columns { column-count: 1; } }
.card-columns > .card { break-inside: avoid; margin-bottom: 16px; display: inline-block; width: 100%; }

/* Form cards (Django .form-card + .card-title). .panel/.panel-head/.panel-body
   are kept as aliases so existing pages keep rendering during migration. */
.form-card, .panel { background: #fff; border-radius: 8px; box-shadow: var(--shadow); margin-bottom: 16px; }
.card-title, .panel-head { padding: 12px 16px; font-weight: 600; color: #1e293b; font-size: 0.85rem; border-bottom: 1px solid #e5e7eb; background: #f9fafb; border-radius: 8px 8px 0 0; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.panel-body { padding: 6px 16px; }
.form-card .card-body { padding: 16px; }

/* Settings table (Django .settings-tbl): name | control | description */
.settings-tbl { width: 100%; border-collapse: collapse; }
.settings-tbl td { padding: 12px 16px; border-bottom: 1px solid #f1f5f9; vertical-align: middle; }
.settings-tbl tr:last-child td { border-bottom: none; }
.settings-tbl .setting-name { font-weight: 500; color: #374151; white-space: nowrap; width: 220px; }
.settings-tbl .setting-control { width: 420px; }
.settings-tbl .setting-desc { color: #94a3b8; font-size: 0.78rem; }
.dependent-row { display: none; }
.dependent-row.visible { display: table-row; }

/* Generic label|control|desc grid rows (.setting-row) — alias of settings-tbl for Razor components */
.setting-row { display: grid; grid-template-columns: 190px minmax(0, 320px) minmax(140px, 1fr); gap: 14px; align-items: start; padding: 12px 16px; border-bottom: 1px solid #f1f5f9; }
.setting-row:last-child { border-bottom: none; }
.setting-row > .lbl { font-weight: 500; color: #374151; padding-top: 7px; }
.setting-row > .help { font-size: 0.78rem; color: #94a3b8; }
@media (max-width: 980px) { .setting-row { grid-template-columns: 1fr; gap: 6px; } }
/* User editor: wide Account panel on the left, narrow Tools card on the right quarter. */
.editor-split { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 1fr); gap: 16px; align-items: start; }
/* Account fields are 50% wider than the default control column (320 → 480px). */
.user-editor .setting-row { grid-template-columns: 190px minmax(0, 480px) minmax(140px, 1fr); }
@media (max-width: 980px) { .editor-split { grid-template-columns: 1fr; } .user-editor .setting-row { grid-template-columns: 1fr; } }
/* Host admin: full-width settings — wider label column, vertically-centred rows, single wide control. */
.host-settings .setting-row { grid-template-columns: 240px minmax(0, 1fr); align-items: center; }
.host-settings .setting-row > .lbl { padding-top: 0; }
.host-settings .setting-row > .help { display: none; }

/* Voicemail settings tab: wide label column (≥380px, grows to fit) + single-line labels so the long
   option text never wraps. */
.vm-settings .setting-row { grid-template-columns: minmax(380px, max-content) minmax(0, 1fr); align-items: center; }
.vm-settings .setting-row > .lbl { padding-top: 0; white-space: nowrap; }
/* The Security tab's labels are longer ("Prohibited recent passwords (history)"…), so widen just its
   label column; the other host tabs keep the standard 240px. */
.host-settings .wide-label-rows .setting-row { grid-template-columns: 360px minmax(0, 1fr); }
@media (max-width: 760px) { .host-settings .setting-row,
                            .host-settings .wide-label-rows .setting-row { grid-template-columns: 1fr; align-items: start; } }
/* Rows whose control stacks multiple items (input + warning/button): align the label to the
   top so it lines up with the input, not the centre of the whole stack. */
.host-settings .setting-row.row-stacked { align-items: start; }
.host-settings .setting-row.row-stacked > .lbl { padding-top: 8px; }
/* Call-alert rows: an on/off toggle next to the recipient list, sharing the standard label column. */
.host-settings .setting-row.row-muted { opacity: .55; }
/* Alert rows: a consistent 3-column grid shared by the "Call alerts" and "Alerts" cards —
   alert name | on/off toggle (just wide enough for the toggle) | email field. The toggle cell is
   empty on the default-email row; the name column is wide enough for the longest title not to wrap. */
.host-settings .alert-grid { display: grid; grid-template-columns: 320px 56px minmax(0, 1fr); gap: 14px; align-items: center; padding: 12px 16px; }
.host-settings .alert-grid > .lbl { font-weight: 500; color: #374151; }
.host-settings .alert-grid .input { width: 100%; }
@media (max-width: 760px) { .host-settings .alert-grid { grid-template-columns: 1fr; gap: 6px; } }
/* Auto-ban config cards sit in the firewall page's narrow 1/4-width right column. The default
   3-column setting-row (190px label + control + help) collapses the control track to ~0 there,
   crushing the threshold number inputs to a sliver. Keep label (left) and control (right) side
   by side, but give the control a real fixed width so the toggle/number box always fits. */
.autoban-config .setting-row { grid-template-columns: minmax(0, 1fr) 130px; gap: 12px; align-items: center; padding: 10px 16px; }
.autoban-config .setting-row > .lbl { padding-top: 0; }
.autoban-config .setting-row > .help { display: none; }
/* Header "Power" split-button dropdown (Host page). */
.power-menu { position: relative; display: inline-block; z-index: 101; }
.power-menu-list { display: none; position: absolute; top: calc(100% + 4px); right: 0; background: #fff; border: 1px solid #d1d5db; border-radius: 6px; box-shadow: 0 8px 24px rgba(0,0,0,.12); min-width: 170px; z-index: 101; overflow: hidden; }
.power-menu-list.open { display: block; }
.power-menu-list button { display: block; width: 100%; text-align: left; padding: 9px 14px; background: #fff; border: none; font: inherit; cursor: pointer; color: #374151; }
.power-menu-list button:hover { background: #f3f4f6; }
.power-menu-list button.danger { color: #dc2626; }
.power-backdrop { position: fixed; inset: 0; z-index: 99; }
/* Raw email source / headers block in the Email Log detail modal. */
.email-raw { white-space: pre-wrap; word-break: break-word; font-size: .76rem; background: #0b1020; color: #d1d5db; padding: 12px; border-radius: 6px; margin: 0; }
/* Packet capture: live output on the left, a fixed-width settings column on the right that
   collapses below it on narrow screens. */
/* Fill the viewport (minus the 44px topbar and 32px×2 main-content padding) so the
   trailing console flexes to whatever height is left, with no window scrollbar. Shared
   by the packet-capture and voice-engine-log consoles. */
.fill-page { display: flex; flex-direction: column; height: calc(100vh - 108px); }
.capture-grid { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 16px; align-items: stretch; flex: 1 1 auto; min-height: 0; }
.capture-grid > .panel { display: flex; flex-direction: column; min-height: 0; margin-bottom: 0; }
.capture-grid > .panel > .panel-body { flex: 1 1 auto; min-height: 0; display: flex; }
.capture-grid > div:last-child { min-height: 0; overflow-y: auto; }   /* settings column scrolls internally if ever taller than the viewport */
@media (max-width: 900px) { .fill-page { height: auto; } .capture-grid { grid-template-columns: 1fr; } }
/* Settings form: stack label over a full-width control so fields use the column width. */
.capture-form .setting-row { grid-template-columns: 1fr; gap: 5px; padding: 10px 16px; align-items: start; }
.capture-form .setting-row > .lbl { padding-top: 0; font-size: .8rem; }
.capture-form .setting-row > .help { display: none; }
/* Live packet-capture output — uses most of the viewport height, with its own scrollbar. */
.capture-out { white-space: pre-wrap; word-break: break-word; font-size: .76rem; line-height: 1.45; background: #0b1020; color: #cbd5e1; padding: 12px; border-radius: 6px; margin: 0; flex: 1 1 auto; min-height: 200px; overflow: auto; }
/* Inline checkbox / radio labels (filter builder). */
.chk-inline, .radio-inline { display: inline-flex; align-items: center; gap: 6px; font-size: .85rem; color: #374151; cursor: pointer; }
.chk-inline input, .radio-inline input { cursor: pointer; }
/* Aligned checkbox grid (filter builder services/protocols). */
.chk-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 14px; }

/* Editor with wide controls (no help column). The card stays full width (as always); the control
   column is bounded so inputs are roomy but don't stretch the whole screen. Announcement editor. */
.wide-rows .setting-row { grid-template-columns: 190px minmax(0, 560px); }
/* Tenant editor (General/Limits/Features) — a ~50% wider label column so the longer labels sit on one line. */
.tenant-edit-rows .setting-row { grid-template-columns: 285px minmax(0, 560px); }
.wide-rows .setting-row > .help { display: none; }
.wide-rows input[type=range] { width: 100%; }

/* Outbound route editor: If… then Then… stacked, each kept at the exact width the side-by-side
   columns had (half the container minus half the 18px gap) — i.e. the width is unchanged. */
.route-split { display: grid; grid-template-columns: calc(50% - 9px); gap: 18px; align-items: start; }
.route-split .setting-row { grid-template-columns: 190px minmax(0, 1fr); }
.route-split .setting-row > .help { display: none; }
.route-split .setting-row.row-muted { opacity: .55; }
/* Component-driven play button: icon is rendered via CSS (not textContent) so the Blazor renderer
   and the JS player never both mutate the button's DOM. .playing (on the row) = paused/playing icon;
   .busy = a spinner while audio is being generated. */
.track-play[data-managed="true"]::before { content: "\25B6"; } /* ▶ */
.track-item.playing .track-play[data-managed="true"]::before { content: "\275A\275A"; } /* ❚❚ */
.track-play[data-managed="true"].busy::before { content: ""; display: inline-block; width: 11px; height: 11px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: btn-spin 0.6s linear infinite; vertical-align: middle; }
@keyframes btn-spin { to { transform: rotate(360deg); } }
/* Inline spinner for buttons in a busy/working state. */
.btn-spinner { display: inline-block; width: 13px; height: 13px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: btn-spin 0.6s linear infinite; vertical-align: middle; margin-right: 8px; }
/* Render the searchable voice picker as a full-width form control (not the compact chip). */
.wide-rows .tenant-dropdown { width: 100%; }
.wide-rows .tenant-dropdown-toggle { width: 100%; justify-content: space-between; background: #fff; height: 36px; padding: 7px 10px; font-size: inherit; border-radius: 6px; }
.wide-rows .tenant-dropdown-menu { left: 0; right: auto; width: 100%; min-width: 0; max-width: none; }

/* Inputs */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field label { font-weight: 500; font-size: 0.8rem; color: #374151; }
.field-inline { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 18px; }
@media (max-width: 760px) { .grid-2 { grid-template-columns: 1fr; } }
.input, select.input, .settings-tbl input, .settings-tbl select, .settings-tbl textarea {
    padding: 7px 10px; border: 1px solid #d1d5db; border-radius: 6px; font-size: inherit;
    font-family: inherit; background: #fff; color: #1e293b; width: 100%;
}
select.input, .input { height: 36px; }
select, select.input {
    appearance: none; -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2394a3b8' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 12px center; padding-right: 30px;
}
textarea.input { height: auto; min-height: 70px; resize: vertical; }
.input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent, #3b82f6); box-shadow: 0 0 0 3px rgba(59,130,246,.15); }
.input:disabled, .input[readonly] { background: #f8fafc; color: #64748b; }
.input-color { width: 56px; height: 36px; padding: 3px; }
.readonly-field { height: 36px; display: flex; align-items: center; padding: 0 10px; background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 6px; color: #64748b; }

/* Buttons */
.btn, .btn-primary, .btn-secondary, .btn-dark, .btn-outline, .btn-outline-danger, .btn-delete, .btn-warning {
    padding: 8px 16px; border-radius: 6px; font-size: inherit; font-weight: 500; cursor: pointer;
    text-decoration: none; border: 1px solid transparent; font-family: inherit; display: inline-flex;
    align-items: center; gap: 6px; white-space: nowrap;
}
.btn, .btn-secondary, .btn-outline { background: #fff; color: #374151; border-color: #d1d5db; }
.btn:hover, .btn-secondary:hover, .btn-outline:hover { background: #f9fafb; text-decoration: none; }
/* Primary button follows the brand primary accent; .btn-dark stays a fixed neutral. Declared AFTER
   the generic .btn rule so it wins for `btn btn-primary` (equal specificity → source order). */
.btn-primary { background: var(--accent, #2563eb); color: #fff; border-color: transparent; }
.btn-primary:hover { background: var(--accent, #2563eb); filter: brightness(1.12); text-decoration: none; }
.btn-dark { background: #1e293b; color: #fff; border-color: transparent; }
.btn-dark:hover { background: #334155; text-decoration: none; }
.btn-warning { background: #fff; color: #d97706; border-color: #fbbf24; }
.btn-warning:hover { background: #fffbeb; }
.btn-delete, .btn-outline-danger, .btn-danger { background: #fff; color: #dc2626; border-color: #fca5a5; }
.btn-delete:hover, .btn-outline-danger:hover { background: #fef2f2; border-color: #f87171; }
.btn-block { width: 100%; justify-content: center; }
.btn:disabled, .btn-primary:disabled, .btn-dark:disabled { opacity: .55; cursor: default; }
.btn-sm, .action-btn { display: inline-flex; align-items: center; padding: 4px 10px; font-size: 0.75rem; border-radius: 4px; cursor: pointer; border: 1px solid #d1d5db; background: #fff; color: #374151; }
.btn-sm:hover, .action-btn:hover { background: #f3f4f6; text-decoration: none; }
.btn-sm.btn-danger { color: #dc2626; border-color: #fca5a5; }
.btn-sm:disabled, .action-btn:disabled { opacity: .4; cursor: default; background: #fff; pointer-events: none; }
.svc-status { width: 1%; text-align: right; white-space: nowrap; padding-right: 4px; }
.kv-table { width: 100%; border-collapse: collapse; }
.kv-table th, .kv-table td { padding: 9px 16px; text-align: left; font-size: .85rem; border-bottom: 1px solid #f1f5f9; vertical-align: top; }
.kv-table tr:last-child th, .kv-table tr:last-child td { border-bottom: none; }
.kv-table th { width: 1%; min-width: 260px; color: #64748b; font-weight: 500; white-space: nowrap; padding-right: 24px; }
.kv-table td { color: #1e293b; font-weight: 500; }
.stat-bad { color: #dc2626; font-weight: 600; }

/* Extension status chip (page header) + diagnostics tab */
.ext-status-chip { display: inline-flex; align-items: center; gap: 10px; background: #fff; border: 1px solid #e5e7eb; border-radius: 9999px; padding: 9px 18px; box-shadow: var(--shadow); }
.ext-status-chip .dot { width: 12px; height: 12px; flex-shrink: 0; }
.ext-status-label { font-weight: 600; color: #1e293b; font-size: .92rem; line-height: 1.25; white-space: nowrap; }
.ext-status-sub { font-size: .74rem; color: #64748b; line-height: 1.2; white-space: nowrap; }
.diag-offline { display: flex; align-items: center; gap: 14px; padding: 8px 0; }
.diag-offline .dot { width: 14px; height: 14px; }
.diag-wrap { word-break: break-all; white-space: normal; }

/* Diagnostics summary tiles */
.diag-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; margin-bottom: 18px; }
.diag-tile { background: #fff; border-radius: 8px; box-shadow: var(--shadow); padding: 14px 16px; }
.diag-tile-label { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: #94a3b8; font-weight: 600; margin-bottom: 6px; }
.diag-tile-value { font-size: 1.1rem; font-weight: 700; color: #1e293b; }
.diag-tile-value.ok { color: #16a34a; }
.diag-tile-value.warn { color: #d97706; }

/* Per-call quality metric chips */
.diag-call { padding: 6px 0 14px; border-bottom: 1px solid #f1f5f9; }
.diag-call:last-child { border-bottom: none; }
.diag-call-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.diag-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); gap: 10px; margin-bottom: 12px; }
.qmetric { text-align: center; border-radius: 8px; padding: 10px 6px; background: #f8fafc; border: 1px solid #eef2f7; }
.qmetric .qv { font-size: 1.05rem; font-weight: 700; color: #1e293b; font-variant-numeric: tabular-nums; }
.qmetric .ql { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: #94a3b8; margin-top: 2px; }
.qmetric.q-good { background: #ecfdf5; border-color: #a7f3d0; } .qmetric.q-good .qv { color: #16a34a; }
.qmetric.q-warn { background: #fffbeb; border-color: #fde68a; } .qmetric.q-warn .qv { color: #d97706; }
.qmetric.q-bad  { background: #fef2f2; border-color: #fecaca; } .qmetric.q-bad .qv  { color: #dc2626; }

/* Firewall add-rule rows */
.fw-add { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 4px 0; }

/* Bulk selection bar + edit panel (DID Numbers) */
.bulk-bar { display: flex; align-items: center; gap: 10px; background: #eef2ff; border: 1px solid #c7d2fe; border-radius: 8px; padding: 10px 14px; margin-bottom: 14px; }
.bulk-bar .spacer { flex: 1; }
.bulk-panel { margin-bottom: 16px; }
.bulk-field { padding: 12px 0; border-bottom: 1px solid #f1f5f9; display: flex; flex-direction: column; gap: 10px; }
.bulk-field:last-of-type { border-bottom: none; }
.bulk-check { display: inline-flex; align-items: center; gap: 8px; font-size: .9rem; cursor: pointer; }
.bulk-routing { display: flex; flex-wrap: wrap; gap: 10px; padding-left: 26px; }
/* Bulk-edit grid: each editable field is always shown as [☑ field name] | [control]; the control
   is greyed/inert until its checkbox is ticked, so the modal is compact and a constant height. */
.bulk-grid { margin: 14px 0 4px; }
.bulk-row { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 16px; align-items: start; padding: 14px 0; border-bottom: 1px solid #f1f5f9; }
.bulk-row:last-child { border-bottom: none; }
.bulk-row-head { display: inline-flex; align-items: center; gap: 9px; font-weight: 500; color: #374151; cursor: pointer; user-select: none; padding-top: 7px; }
.bulk-row-control { min-width: 0; }
.bulk-row-control .input { width: 100%; }
.data-table tr.row-selected td { background: #eef2ff; }
/* "Check Route" result: pulse the matched row a few times, then settle on a soft green highlight. */
@keyframes route-pulse { 0%,100% { background: #bbf7d0; } 50% { background: #ecfdf5; } }
.data-table tr.route-pulse td { animation: route-pulse 0.7s ease-in-out 3; animation-fill-mode: forwards; background: #dcfce7; }
.data-table tr.route-pulse td:first-child { box-shadow: inset 4px 0 0 #16a34a; }
/* Drag-and-drop reordering of outbound routes */
.drag-grip { color: #cbd5e1; cursor: grab; user-select: none; font-size: 1rem; line-height: 1; padding: 0 2px; }
.drag-grip:active { cursor: grabbing; }
.data-table tr[draggable="true"]:hover .drag-grip { color: #64748b; }
.data-table tr.dragging td { opacity: .4; }
.data-table tr.drag-over td { box-shadow: inset 0 2px 0 #6366f1; }

/* DID page top settings — wider control column; the unassigned-number row pairs two selects inline.
   Hide the empty SettingRow help cell so the 2-column override doesn't wrap it to an implicit second
   grid row (which added a big row-gap between the rows). */
.did-settings .setting-row { grid-template-columns: 240px minmax(0, 640px); }
/* Stack the routing-type select and its secondary select vertically (second below the first). */
.did-setting-row { display: flex; flex-direction: column; gap: 8px; align-items: stretch; }
@media (max-width: 980px) { .did-settings .setting-row { grid-template-columns: 1fr; } }

/* Click-to-edit inline cell (DID description) */
.inline-edit-cell { position: relative; }
.inline-edit { width: 100%; min-width: 140px; border: 1px solid transparent; background: transparent; border-radius: 5px; padding: 5px 8px; font: inherit; color: #1e293b; }
.inline-edit::placeholder { color: #cbd5e1; }
.inline-edit:hover { border-color: #e2e8f0; background: #f8fafc; }
.inline-edit:focus { outline: none; border-color: #3b82f6; background: #fff; box-shadow: 0 0 0 3px rgba(59,130,246,.12); }
.inline-saved { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); color: #16a34a; font-weight: 700; pointer-events: none; }
.perf-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.perf-col .perf-card .spark { height: 120px; }
.core-grid { display: flex; flex-wrap: wrap; gap: 18px; padding: 18px 20px; }
.core-cell { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.core-label { font-size: .7rem; color: #94a3b8; font-variant-numeric: tabular-nums; }
.core-pct { font-size: .72rem; font-weight: 600; color: #475569; font-variant-numeric: tabular-nums; min-width: 4ch; text-align: center; }
.core-bar { width: 32px; height: 96px; background: #eef2f7; border-radius: 5px; display: flex; align-items: flex-end; overflow: hidden; box-shadow: inset 0 0 0 1px #e2e8f0; }
.core-fill { width: 100%; background: var(--accent, #3b82f6); border-radius: 0 0 5px 5px; transition: height .5s ease; }
.core-fill.warm { background: #f59e0b; }
.core-fill.hot { background: #ef4444; }

/* Per-interface split: details left, live graphs right */
.net-split { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; padding: 14px 16px 16px; align-items: start; }
@media (max-width: 1000px) { .net-split { grid-template-columns: 1fr; } }
.net-left { min-width: 0; }
.net-right { display: flex; flex-direction: column; gap: 16px; }
.graph-card { background: #f9fafb; border: 1px solid #eef2f7; border-radius: 8px; padding: 12px 14px; }
.graph-card .spark { height: 110px; }

/* Live readouts: fixed-width slots so updating figures never shift surrounding text */
.metric-now.legend { display: inline-flex; gap: 14px; }
.metric-now.legend > span { display: inline-block; min-width: 8.5ch; text-align: right; font-variant-numeric: tabular-nums; }
.metric-now.legend .dn { color: #6366f1; }
.metric-now.legend .up { color: #f59e0b; }
.metric-now { font-variant-numeric: tabular-nums; }
.kv-table td, .kv-table th, .data-table td, .data-table th, .mono { font-variant-numeric: tabular-nums; }
.net-title { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.net-table td:first-child, .net-table th:first-child { color: #64748b; }
.net-table tr.net-bad td { color: #dc2626; font-weight: 600; }
.form-card + .form-card { margin-top: 16px; }
.form-actions { display: flex; align-items: center; gap: 8px; margin-top: 20px; flex-wrap: wrap; }

/* Toggle switch */
.toggle, .toggle-switch { position: relative; display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
.toggle input, .toggle-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle-track, .toggle-slider { width: 36px; height: 20px; background: #d1d5db; border-radius: 10px; transition: background .2s; position: relative; flex-shrink: 0; }
.toggle-track::after, .toggle-slider::after { content: ''; position: absolute; width: 16px; height: 16px; background: #fff; border-radius: 50%; top: 2px; left: 2px; transition: transform .2s; }
.toggle input:checked + .toggle-track, .toggle-switch input:checked + .toggle-slider { background: var(--accent, #1e293b); }
.toggle input:checked + .toggle-track::after, .toggle-switch input:checked + .toggle-slider::after { transform: translateX(16px); }
/* Disabled toggle: greyed track, no pointer — reads clearly as locked. */
.toggle input:disabled + .toggle-track, .toggle-switch input:disabled + .toggle-slider { opacity: .4; }
.toggle:has(input:disabled), .toggle-switch:has(input:disabled) { cursor: not-allowed; }
/* A whole card row whose control is locked: dim the label + control together. */
.side-card .body.is-locked { opacity: .55; cursor: not-allowed; }
.side-card .body.is-locked .toggle { pointer-events: none; }

/* Badges */
.badge { display: inline-block; padding: 2px 8px; border-radius: 9999px; font-size: 0.7rem; font-weight: 500; }
.badge-blue { background: #dbeafe; color: #1e40af; }
.badge-green { background: #dcfce7; color: #166534; }
.badge-amber { background: #fef3c7; color: #92400e; }
.badge-gray { background: #f1f5f9; color: #475569; }
.badge-red { background: #fee2e2; color: #991b1b; }
.badge-purple { background: #ede9fe; color: #6d28d9; }
.badge-yellow { background: #fef08a; color: #854d0e; }
.badge-action { background: #e0e7ff; color: #3730a3; }
.data-table .badge + .badge { margin-left: 4px; }

/* Data tables (list pages) */
.data-table { width: 100%; border-collapse: collapse; background: #fff; border-radius: 8px; overflow: hidden; box-shadow: var(--shadow); }
.data-table th { background: #f8fafc; padding: 10px 16px; text-align: left; font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: #64748b; border-bottom: 1px solid #e2e8f0; white-space: nowrap; }
.data-table td { padding: 10px 16px; border-bottom: 1px solid #f1f5f9; }
.data-table tbody tr:hover { background: #f8fafc; }
.data-table tr:last-child td { border-bottom: none; }
.row-actions { display: flex; gap: 6px; white-space: nowrap; align-items: center; justify-content: flex-end; }
/* Keep the actions cell a real table-cell (NOT display:flex) so its bottom border lines up with the
   rest of the row; right-align the inline buttons and space them with a margin instead of flex gap. */
td.actions-cell { white-space: nowrap; text-align: right; vertical-align: middle; }
td.actions-cell .action-btn + .action-btn, td.actions-cell .btn-sm + .btn-sm { margin-left: 6px; }
th.actions-cell { text-align: right; }

/* Tabs */
.tabs, .tab-bar { display: flex; border-bottom: 2px solid var(--tab-line, #e5e7eb); margin-bottom: 20px; gap: 0; flex-wrap: wrap; }
.tab, .tab-btn { padding: 8px 18px; border: none; background: none; font-size: inherit; font-family: inherit; color: var(--tab-inactive, #64748b); cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -2px; font-weight: 500; }
.tab:hover, .tab-btn:hover { opacity: .8; }
.tab.active, .tab-btn.active { color: var(--tab-active, #1e293b); border-bottom-color: var(--tab-active, #1e293b); }
.tab.is-soon { opacity: .5; cursor: default; }

/* Two-column editor (form + right-hand cards) */
/* Extension editor: no help column, wider control so inputs (esp. the SIP secret) use the space. */
.ext-editor .setting-row { grid-template-columns: 190px minmax(0, 640px); }
.ext-editor .setting-row > .help { display: none; }
/* Notes tab (extension + tenant editors): a single full-width free-text field that fills most of the
   viewport. Height tracks the window (like .fill-page): 100vh minus the 44px topbar, the 32px×2
   main-content padding, and the page-header + tabs row above it. Still user-resizable. */
.notes-field { display: block; width: 100%; box-sizing: border-box; height: calc(95vh - 224px);
    min-height: 240px; resize: vertical; padding: 12px 14px; font: inherit; line-height: 1.5;
    border: 1px solid var(--border, #d1d5db); border-radius: 8px; background: var(--input-bg, #fff); color: inherit; }
.notes-field:focus { outline: none; border-color: var(--tab-active, #1e293b); }
.editor-grid { display: flex; gap: 16px; align-items: flex-start; }
.editor-grid > div:first-child { flex: 1; min-width: 0; }
.editor-grid > div:nth-child(2) { width: 340px; flex-shrink: 0; }
@media (max-width: 1100px) { .editor-grid { flex-direction: column; } .editor-grid > div:nth-child(2) { width: 100%; } }
.side-card { background: #fff; border-radius: 8px; box-shadow: var(--shadow); margin-bottom: 16px; }
.side-card .head { padding: 12px 16px; font-weight: 600; font-size: 0.85rem; border-bottom: 1px solid #e5e7eb; background: #f9fafb; color: #1e293b; border-radius: 8px 8px 0 0; }
.side-card .body { padding: 12px 16px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.side-card .body .desc { color: #94a3b8; font-size: 0.78rem; }

/* Chips (legacy assignment control) */
.chips { display: flex; flex-wrap: wrap; gap: 4px; padding: 6px 8px; border: 1px solid #d1d5db; border-radius: 6px; min-height: 36px; background: #fff; }
.chip { display: inline-flex; align-items: center; gap: 4px; background: #dbeafe; color: #1e40af; padding: 2px 8px; border-radius: 9999px; font-size: 0.75rem; white-space: nowrap; }
.chip button { border: none; background: none; cursor: pointer; color: #1e40af; font-size: .9rem; line-height: 1; padding: 0; opacity: .65; }
.chip button:hover { opacity: 1; }
.chips-empty { color: #94a3b8; font-size: 0.8rem; padding: 2px; }

/* Searchable multi-select chip box + checkbox dropdown */
.add-member-row { display: flex; align-items: flex-start; gap: 8px; padding: 12px 0 16px; flex-wrap: nowrap; }
.add-member-type-select { padding: 7px 28px 7px 10px; border: 1px solid #d1d5db; border-radius: 6px; font-size: inherit; font-family: inherit; background: #fff; appearance: none; -webkit-appearance: none; background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%2394a3b8' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; flex-shrink: 0; }
.add-member-number { flex: 1; padding: 8px 10px; border: 1px solid #d1d5db; border-radius: 6px; font-size: inherit; font-family: monospace; }
.add-member-number:focus { outline: none; border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59,130,246,.15); }
.btn-add-member { padding: 8px 14px; border: 1px solid #d1d5db; border-radius: 6px; background: #fff; color: #374151; font-size: inherit; font-family: inherit; cursor: pointer; white-space: nowrap; flex-shrink: 0; }
.btn-add-member:hover { background: #f9fafb; }
.btn-add-member:disabled { opacity: .5; cursor: not-allowed; }
.ext-search-wrap { position: relative; flex: 1; min-width: 0; }
.ext-chip-box { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; padding: 5px 8px; border: 1px solid #d1d5db; border-radius: 6px; background: #fff; cursor: text; min-height: 38px; }
.ext-chip-box:focus-within { border-color: #3b82f6; box-shadow: 0 0 0 3px rgba(59,130,246,.15); }
.ext-sel-chip { display: inline-flex; align-items: center; gap: 4px; background: #dbeafe; color: #1e40af; padding: 2px 8px; border-radius: 9999px; font-size: .75rem; white-space: nowrap; }
.ext-sel-chip-remove { background: none; border: none; color: #1e40af; font-size: .85rem; cursor: pointer; padding: 0; line-height: 1; opacity: .6; }
.ext-sel-chip-remove:hover { opacity: 1; }
.ext-search-input { border: none; outline: none; font-size: inherit; font-family: inherit; padding: 2px 4px; min-width: 120px; flex: 1; background: transparent; }
.ext-search-input::placeholder { color: #94a3b8; }
.ext-search-dropdown { position: absolute; top: calc(100% + 3px); left: 0; right: 0; background: #fff; border: 1px solid #d1d5db; border-radius: 6px; box-shadow: 0 4px 12px rgba(0,0,0,.1); z-index: 200; overflow: hidden; }
.ext-check-header { display: flex; align-items: center; justify-content: space-between; padding: 6px 12px; border-bottom: 1px solid #e5e7eb; background: #f9fafb; }
.ext-check-header-label { font-size: .75rem; color: #94a3b8; }
.ext-select-all { font-size: .75rem; color: var(--accent, #3b82f6); cursor: pointer; border: none; background: none; font-family: inherit; padding: 0; }
.ext-select-all:hover { text-decoration: underline; }
.ext-check-list { max-height: 220px; overflow-y: auto; }
.ext-search-option { display: flex; align-items: center; gap: 8px; padding: 7px 12px; cursor: pointer; font-size: .875rem; color: #1e293b; }
.ext-search-option:hover { background: #f1f5f9; }
.ext-search-option input[type="checkbox"] { flex-shrink: 0; accent-color: var(--accent, #1e293b); width: 14px; height: 14px; cursor: pointer; }
.ext-search-option.no-results { color: #94a3b8; cursor: default; font-style: italic; padding: 12px; }

/* Ordered member list */
.member-list { list-style: none; margin: 0; padding: 0; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; }
.member-item { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid #f1f5f9; background: #fff; }
.member-item:last-child { border-bottom: none; }
.member-empty { padding: 18px 12px; color: #94a3b8; font-style: italic; font-size: .85rem; }
.member-idx { width: 20px; color: #94a3b8; font-size: .8rem; text-align: center; flex-shrink: 0; }
.member-label { color: #1e293b; font-size: .875rem; }
.member-item .spacer { flex: 1 1 auto; }
.member-remove { background: none; border: none; color: #64748b; cursor: pointer; padding: 4px 6px; border-radius: 4px; flex-shrink: 0; font-size: 1rem; line-height: 1; }
.member-remove:hover { color: #dc2626; background: #fef2f2; }
.icon-btn { border: none; background: none; cursor: pointer; color: #64748b; padding: 4px 6px; border-radius: 4px; }
.icon-btn:hover:not(:disabled) { color: #1e293b; background: #f1f5f9; }
.icon-btn:disabled { color: #cbd5e1; cursor: default; }

/* Business-hours day grid */
.quick-actions { display: flex; gap: 6px; flex-wrap: wrap; padding: 12px 16px; border-bottom: 1px solid #f1f5f9; }
.btn-quick { padding: 4px 10px; border: 1px solid #d1d5db; border-radius: 4px; background: #fff; color: #374151; font-size: .78rem; font-family: inherit; cursor: pointer; white-space: nowrap; }
.btn-quick:hover { background: #f9fafb; }
.day-grid { padding: 4px 0; }
.day-row { display: flex; align-items: center; gap: 0; padding: 9px 16px; border-bottom: 1px solid #f1f5f9; }
.day-row:last-child { border-bottom: none; }
.day-row.weekend { background: #fafafa; }
.day-name { width: 110px; font-weight: 500; color: #374151; font-size: .875rem; flex-shrink: 0; }
.day-row.weekend .day-name { color: #64748b; }
.day-times { display: flex; align-items: center; gap: 8px; margin-left: 20px; }
.day-times input[type="time"] { width: 120px; }
.time-sep { color: #94a3b8; font-size: .8rem; flex-shrink: 0; }
.day-closed-label { margin-left: 20px; color: #94a3b8; font-size: .85rem; font-style: italic; }
/* Extension Business Hours schedule: reuse the .setting-row grid so each day's time selectors line up
   vertically with the dropdowns in the cards above, and right-align the open/closed toggle in the
   label column. */
/* Top-align the row so the day label + toggle line up with the FIRST time window (not the vertical
   centre of a multi-window stack); the label cell is 36px tall so its centred text/toggle matches an
   input row. Extra windows stack below with a small gap. */
.bh-day-row { align-items: start; }
.bh-day-row.weekend { background: #fafafa; }
.bh-day-row > .lbl { display: flex; align-items: center; justify-content: space-between; padding-top: 0; min-height: 36px; }
.bh-day-row .day-times, .bh-day-row .day-closed-label { margin-left: 0; }
.bh-day-row .day-times + .day-times { margin-top: 6px; }
.bh-day-row .day-closed-label { display: inline-flex; align-items: center; min-height: 36px; }
/* Compact square icon button (e.g. the ×/+ window controls). */
.btn-icon { padding: 0; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; font-size: 1.05rem; line-height: 1; flex-shrink: 0; }
.holiday-add-row { display: flex; align-items: center; gap: 8px; padding: 12px 16px; background: #f9fafb; border-bottom: 1px solid #e5e7eb; }

/* Profile multi-card grid */
.profile-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: stretch; }
.profile-grid .full-width { grid-column: 1 / -1; }
@media (max-width: 980px) { .profile-grid { grid-template-columns: 1fr; } }
.detail-row { display: flex; align-items: center; padding: 8px 0; border-bottom: 1px solid #f1f5f9; }
.detail-row:last-child { border-bottom: none; }
.detail-label { width: 140px; flex-shrink: 0; font-weight: 500; color: #64748b; font-size: .75rem; text-transform: uppercase; letter-spacing: .03em; }
.detail-value { color: #1e293b; }
.help-text { font-size: .8rem; color: #64748b; margin-top: 8px; }

/* Notification template editor */
.content-layout { display: grid; grid-template-columns: 1fr 260px; gap: 20px; align-items: start; }
@media (max-width: 980px) { .content-layout { grid-template-columns: 1fr; } }
.sidebar-panel { background: #fff; border-radius: 8px; box-shadow: var(--shadow); padding: 20px; }
.sidebar-panel h3 { font-size: .75rem; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; color: #64748b; margin: 0 0 12px; }
.placeholder-list { list-style: none; padding: 0; margin: 0; }
.placeholder-list li { padding: 8px 0; border-bottom: 1px solid #f1f5f9; }
.placeholder-list li:last-child { border-bottom: none; }
.placeholder-code { display: inline-block; font-family: monospace; font-size: .75rem; background: #f1f5f9; color: #1e293b; padding: 2px 6px; border-radius: 4px; user-select: all; }
.placeholder-desc { display: block; font-size: .7rem; color: #64748b; margin-top: 2px; }
.section-title { font-weight: 600; color: #374151; margin-bottom: 16px; padding-bottom: 8px; border-bottom: 1px solid #e5e7eb; }

/* Voicemail greeting controls */
.greeting-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.greeting-filename { color: #374151; font-size: .85rem; font-family: monospace; }
.greeting-none { color: #94a3b8; font-size: .85rem; font-style: italic; }
.btn-upload-greeting { padding: 5px 12px; border: 1px solid #d1d5db; border-radius: 6px; background: #fff; color: #374151; font-size: .8rem; font-family: inherit; cursor: pointer; white-space: nowrap; }
.btn-upload-greeting:hover { background: #f9fafb; }
.btn-record-greeting { padding: 5px 12px; border: 1px solid #d1d5db; border-radius: 6px; background: #fff; color: #374151; font-size: .8rem; font-family: inherit; cursor: pointer; white-space: nowrap; display: inline-flex; align-items: center; gap: 6px; }
.btn-record-greeting:hover { background: #f9fafb; }
.rec-dot { width: 8px; height: 8px; border-radius: 50%; background: #dc2626; flex-shrink: 0; }

/* Modal */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 1000; display: none; align-items: center; justify-content: center; }
.modal-overlay.active { display: flex; }
.modal-box { position: relative; background: #fff; border-radius: 10px; width: 420px; max-width: calc(100vw - 32px); box-shadow: 0 20px 50px rgba(0,0,0,.25); padding: 24px; }
.modal-title { font-weight: 600; color: #1e293b; font-size: 1rem; margin-bottom: 16px; padding-right: 28px; }
.modal-close { position: absolute; top: 14px; right: 14px; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; border: none; background: transparent; color: #64748b; font-size: 1.4rem; line-height: 1; cursor: pointer; border-radius: 6px; }
.modal-close:hover { background: #f1f5f9; color: #1e293b; }
.modal-footer { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }
/* Wide modal hosting a familiar label|control settings table */
.modal-wide { width: 760px; }
.modal-xwide { width: 900px; }
.modal-form { margin: 14px 0 6px; }
/* Modal forms are label | control (no help column). Label is TOP-aligned, never vertically
   centred against a tall control, and the control fills the full available width. */
.modal-form .setting-row { grid-template-columns: 190px minmax(0, 1fr); padding-left: 0; padding-right: 0; align-items: start; }
.modal-form .setting-row > .lbl { padding-top: 8px; }
.modal-form .setting-row > .help { display: none; }
.modal-form .input, .modal-form textarea.input { width: 100%; max-width: 100%; }
/* Add Defaults modal is wide — use ONE fixed label column across all rows (each row is its own grid,
   so a fixed width keeps every control the same width and aligned) wide enough that the longer
   "(optional)" labels don't wrap. */
.defaults-modal .modal-form .setting-row { grid-template-columns: 250px minmax(0, 1fr); }
.defaults-modal .modal-form .setting-row > .lbl { white-space: nowrap; }
/* Cap the modal to the viewport and scroll only the middle, so the title and footer (Create/Cancel)
   stay in view no matter how tall the options + preview grow. */
.defaults-modal { display: flex; flex-direction: column; max-height: calc(100vh - 32px); }
.defaults-modal .modal-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
/* Route picker: route select with its dependent secondary control stacked neatly below */
.route-fields { display: flex; flex-direction: column; gap: 12px; align-items: stretch; width: 100%; }
.route-fields .input { width: 100%; min-width: 0; }
/* Segmented two-option toggle (e.g. Paste text | Upload file) */
.seg-toggle { display: flex; width: max-content; border: 1px solid #d1d5db; border-radius: 8px; overflow: hidden; margin: 16px 0 14px; }
.seg-toggle button { border: none; background: #fff; color: #475569; padding: 7px 16px; font-size: .85rem; cursor: pointer; }
.seg-toggle button + button { border-left: 1px solid #d1d5db; }
.seg-toggle button.active { background: var(--accent, #1e293b); color: #fff; }
/* CSV source area: fixed height so the modal doesn't resize when switching paste/upload. */
/* Add-DID body: fixed height so switching Individual / DID range doesn't resize the modal. */
.didmodal-body { min-height: 420px; }
.csv-source-body { min-height: 200px; }
.csv-source-body textarea.input { height: 192px; resize: none; }
.file-input { display: block; padding: 10px 0; }

/* Auth pages — column layout so optional header/footer bars sit above/below the centred card. */
.auth-shell {
    min-height: 100vh; display: flex; flex-direction: column;
    background-color: var(--login-bg, #f5f5f5);
    background-image: var(--login-bg-image, none); background-size: cover; background-position: center;
}
.auth-main { flex: 1; display: flex; align-items: center; justify-content: center; padding: 20px; }
/* Optional login header/footer bars (content is admin HTML). */
.auth-banner { display: flex; align-items: center; justify-content: center; padding: 10px 20px; text-align: center; }
.auth-banner a { color: inherit; text-decoration: underline; }
.auth-card { width: 400px; background: #fff; border-radius: 10px; box-shadow: 0 4px 24px rgba(0,0,0,.08); padding: 44px 40px; }
.auth-brand { text-align: center; margin-bottom: 32px; }
.auth-logo { max-height: 52px; }
/* Product-name wordmark (shown when no logo is set; both come from branding settings). */
.auth-wordmark { font-size: 2rem; font-weight: 700; color: #1e293b; letter-spacing: -0.01em; }
.auth-title { font-size: 1.15rem; text-align: center; margin-bottom: 24px; color: #1e293b; }

/* Login/account card: roomier layout with bold field titles. Scoped so the app's
   other forms (which share .field/.input) are unaffected. */
.auth-card .field { gap: 8px; margin-bottom: 22px; }
.auth-card .field label { font-weight: 700; font-size: .85rem; color: #1e293b; }
.auth-card .input, .auth-card select.input { height: 44px; }
.auth-card .btn-block { height: 46px; margin-top: 10px; }
/* The sign-in button uses the login-page accent colour (independent of the app accent). */
.auth-card .btn-primary { background: var(--login-accent, #1e293b); }
.auth-card .btn-primary:hover { background: var(--login-accent, #1e293b); filter: brightness(1.15); }

/* Small file-upload button (wraps a hidden InputFile). */
.btn-upload { display: inline-flex; align-items: center; align-self: flex-start; gap: 6px; cursor: pointer;
    font-size: .8rem; color: #334155; background: #f1f5f9; border: 1px solid #e2e8f0;
    border-radius: 6px; padding: 6px 12px; margin-top: 2px; }
.btn-upload:hover { background: #e2e8f0; }

/* Branding settings: logo-on-background preview box. */
.brand-preview { display: flex; align-items: center; gap: 14px; padding: 16px 18px; border-radius: 8px; border: 1px solid #e2e8f0; margin-top: 6px; }
.brand-preview .btn-primary { color: #fff; padding: 8px 16px; border-radius: 6px; border: 0; }
.auth-link { color: #94a3b8; }
.auth-link:hover { color: #64748b; }

/* ── Branding admin: image-upload controls ────────────────────────────── */
.brand-upload { display: flex; gap: 16px; align-items: flex-start; margin-top: 4px; }
.brand-upload-body { display: flex; flex-direction: column; gap: 8px; }
.brand-upload-actions { display: flex; gap: 8px; }
.btn-upload-clear { color: #b91c1c; background: #fef2f2; border-color: #fecaca; }
.btn-upload-clear:hover { background: #fee2e2; }
.brand-hint { margin: 0; font-size: .78rem; color: #64748b; }
/* Current-image thumbnail. Checkerboard shows transparency; contain keeps aspect. */
.brand-thumb { width: 96px; height: 64px; border: 1px solid #e2e8f0; border-radius: 8px; overflow: hidden;
    display: flex; align-items: center; justify-content: center; flex: none; background: #fff; }
.brand-thumb img { max-width: 100%; max-height: 100%; object-fit: contain; }
.brand-thumb-check { background-image:
    linear-gradient(45deg,#eef2f7 25%,transparent 25%), linear-gradient(-45deg,#eef2f7 25%,transparent 25%),
    linear-gradient(45deg,transparent 75%,#eef2f7 75%), linear-gradient(-45deg,transparent 75%,#eef2f7 75%);
    background-size: 14px 14px; background-position: 0 0,0 7px,7px -7px,-7px 0; }
.brand-thumb-empty { font-size: .72rem; color: #94a3b8; }

/* Logo vs. text radio chooser. */
.brand-choice { display: flex; gap: 20px; margin-bottom: 12px; }
.brand-choice label { display: inline-flex; align-items: center; gap: 7px; font-size: .88rem; color: #334155; cursor: pointer; }
.brand-choice input[type=radio] { accent-color: var(--accent, #2563eb); }
/* Every checkbox/radio follows the brand accent unless a more specific rule overrides it. */
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent, #2563eb); }

/* Toggle switch (header/footer on/off) — label sits beside the switch. */
.brand-switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; padding: 6px 0 10px; }
.brand-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.brand-switch-track { position: relative; width: 40px; height: 22px; background: #cbd5e1; border-radius: 999px; transition: background .15s; flex: none; }
.brand-switch-track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; background: #fff; border-radius: 50%; transition: transform .15s; box-shadow: 0 1px 2px rgba(0,0,0,.25); }
.brand-switch input:checked + .brand-switch-track { background: var(--accent, #2563eb); }
.brand-switch input:checked + .brand-switch-track::after { transform: translateX(18px); }
.brand-switch input:focus-visible + .brand-switch-track { outline: 2px solid var(--accent, #2563eb); outline-offset: 2px; }
.brand-switch-label { font-size: .9rem; font-weight: 500; color: #334155; }
.panel-note { margin: 0 0 8px; font-size: .85rem; color: #64748b; }

/* ── Branding admin: faithful previews ────────────────────────────────── */
/* Browser-tab (favicon) preview. */
.bp-tab { display: inline-flex; align-items: center; gap: 8px; max-width: 240px; padding: 8px 10px;
    background: #f1f5f9; border: 1px solid #e2e8f0; border-bottom: none; border-radius: 8px 8px 0 0; }
.bp-tab-icon { width: 16px; height: 16px; object-fit: contain; flex: none; }
.bp-tab-icon-blank { background: #cbd5e1; border-radius: 3px; }
.bp-tab-title { font-size: .82rem; color: #334155; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bp-tab-x { margin-left: auto; color: #94a3b8; font-size: 1rem; line-height: 1; }

/* Login-page preview: a scaled sign-in card on the branded backdrop. */
/* All three previews (login / application / email) share this height so the right column is
   consistent across the tabs — tall enough for the largest. */
.bp-login { display: flex; flex-direction: column; border-radius: 10px;
    border: 1px solid #e2e8f0; min-height: 360px; overflow: hidden; }
.bp-login-main { flex: 1; display: flex; align-items: center; justify-content: center; padding: 24px; }
.bp-login-banner { display: flex; align-items: center; justify-content: center; padding: 8px 16px; text-align: center; }
.bp-login-banner a { color: inherit; text-decoration: underline; }
/* Preview cards keep the real login:email width ratio (~400:600 = 2:3). The email card below
   is 460px, so the login card is ~300px. */
.bp-login-card { width: 300px; max-width: 100%; background: #fff; border-radius: 10px; box-shadow: 0 4px 20px rgba(0,0,0,.12); padding: 26px 24px; }
.bp-login-brand { text-align: center; margin-bottom: 20px; min-height: 34px; display: flex; align-items: center; justify-content: center; }
.bp-login-brand img { max-height: 34px; max-width: 80%; }
.bp-login-wordmark { font-size: 1.3rem; font-weight: 700; color: #1e293b; }
.bp-field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 12px; }
.bp-field-label { font-size: .68rem; font-weight: 700; color: #1e293b; }
.bp-field-box { height: 28px; border: 1px solid #d1d5db; border-radius: 6px; background: #f8fafc; }
.bp-login-btn { text-align: center; color: #fff; font-size: .8rem; font-weight: 600; padding: 9px; border-radius: 6px; margin-top: 4px; }
.bp-login-link { text-align: center; font-size: .72rem; color: #94a3b8; margin-top: 12px; }

/* Application (sidebar) preview. */
.bp-sidebar { width: 200px; border-radius: 10px; overflow: hidden; padding-bottom: 10px; border: 1px solid #e2e8f0; }
.bp-sidebar-head { padding: 16px; font-size: 1rem; font-weight: 600; border-bottom: 1px solid; min-height: 24px; display: flex; align-items: center; }
.bp-sidebar-head img { max-height: 24px; max-width: 90%; }
.bp-sidebar-label { padding: 4px 16px 2px; font-size: .58rem; font-weight: 600; text-transform: uppercase; letter-spacing: .08em; opacity: .6; }
.bp-sidebar-item { margin: 6px 10px 0; padding: 8px 12px; border-radius: 6px; font-size: .82rem; opacity: .85; }
.bp-sidebar-active { opacity: 1; color: #fff; font-weight: 600; }

/* Email/alerts preview: a scaled version of the branded HTML shell. */
.bp-email { padding: 16px; background: #f4f5f7; border-radius: 10px; border: 1px solid #e2e8f0; min-height: 360px; display: flex; align-items: center; justify-content: center; }
/* Real email card is a wide ~600px card with thin margins, so let it fill the backdrop. */
.bp-email-card { width: 460px; max-width: 100%; background: #fff; border: 1px solid #e5e7eb; border-top: 4px solid #2563eb; border-radius: 10px; overflow: hidden; }
.bp-email-head { padding: 18px 22px 4px; min-height: 28px; display: flex; align-items: center; }
.bp-email-head img { max-height: 30px; max-width: 60%; }
.bp-email-wordmark { font-size: 1.1rem; font-weight: 700; }
.bp-email-body { padding: 10px 22px 20px; font-size: .82rem; line-height: 1.55; color: #1f2937; }
.bp-email-body p { margin: 0 0 12px; }
.bp-email-subject { font-weight: 700; font-size: .92rem; color: #111827; }
.bp-email-btn { display: inline-block; color: #fff; font-size: .8rem; font-weight: 600; padding: 9px 18px; border-radius: 6px; }
.bp-email-foot { padding: 14px 22px; border-top: 1px solid #eef0f2; font-size: .72rem; line-height: 1.5; color: #9ca3af; white-space: normal; overflow-wrap: anywhere; word-break: break-word; }
/* A custom footer preserves the admin's line breaks (and still wraps long lines). */
.bp-email-foot-custom { white-space: pre-line; }

/* Email footer textarea: narrow (≈one-third) but multi-line. */
.brand-footer-input { width: 100%; resize: vertical; font-family: inherit; line-height: 1.5; padding: 8px 10px; }

/* Combined application preview: sidebar + header bar + content window, all branded. */
.bp-app { display: flex; border: 1px solid #e2e8f0; border-radius: 10px; overflow: hidden; min-height: 230px; max-width: 560px; }
.bp-app-full { max-width: 100%; min-height: 360px; }
.bp-app-full .bp-app-side { width: 190px; }
.bp-app-side { width: 156px; flex: none; display: flex; flex-direction: column; }
.bp-app-side .bp-sidebar-head { font-size: .9rem; padding: 14px 16px; }
.bp-app-side-foot { margin-top: auto; padding: 12px 14px; border-top: 1px solid; }
.bp-pill { font-size: .55rem; text-transform: uppercase; letter-spacing: .05em; background: rgba(148,163,184,.28); padding: 3px 8px; border-radius: 6px; opacity: .9; }
.bp-app-right { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.bp-app-topbar { height: 36px; flex: none; display: flex; align-items: center; justify-content: space-between; padding: 0 14px; font-size: .72rem; border-bottom: 1px solid rgba(120,120,120,.22); }
.bp-app-topbar-user { opacity: .8; }
.bp-app-content { flex: 1; padding: 16px; background-size: cover; background-position: center; }
/* Tab strip inside the preview — mirrors the real underline-style tabs. */
.bp-tabs { display: flex; gap: 0; border-bottom: 2px solid #e5e7eb; }
.bp-app-content .bp-tabs { margin-bottom: 14px; }
/* Underline-style strip tabs (distinct class from the favicon browser-tab mock .bp-tab). */
.bp-ttab { padding: 8px 18px; font-size: .82rem; font-weight: 500; border-bottom: 2px solid transparent; margin-bottom: -2px; background: none; }
.bp-ttab-active { font-weight: 600; }

/* Compact colour grid — packs several colour pickers into the panel width. The left
   indent (label column 190px + 14px gap + 16px base) lines the pickers up with the
   control column of the SettingRow controls (logo radio, window background). */
.color-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 14px 20px; padding: 8px 16px 14px; }
/* Label sits above its picker, both left-aligned, so each label unambiguously belongs to the
   picker directly beneath it — and lines up with the stacked radio controls above/below. */
.color-field { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; cursor: pointer; }
.color-field > span { font-size: .85rem; color: #334155; }

/* Settings on the left, live preview on the right. Columns size to their own content
   (top-aligned) — no forced equal height. The preview sticks near the top as you scroll. */
/* Left stretches to the taller of the two columns; the right (preview) keeps its natural
   height (align-self: start). So the left column is always at least as tall as the right. */
.brand-split { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: stretch; }
/* Make the left CONTENT fill that stretched height: the last panel grows into any slack, so
   the settings are never visibly shorter than the preview. */
.brand-split-left { min-width: 0; display: flex; flex-direction: column; }
.brand-split-left > .panel:last-child { flex: 1; margin-bottom: 0; }
.brand-split-right { min-width: 0; align-self: start; position: sticky; top: 16px; }
/* In the split, stacked controls drop the fixed label column so they left-align with the colour grid. */
.brand-split .setting-row.row-stacked { grid-template-columns: 1fr; }
@media (max-width: 1100px) { .brand-split { grid-template-columns: 1fr; } .brand-split-right { position: static; } }

.bp-app-h1 { font-size: .95rem; font-weight: 600; margin-bottom: 10px; }
.bp-app-h2 { font-size: .78rem; font-weight: 600; margin-bottom: 6px; }
.bp-app-panel { background: #fff; border: 1px solid #e5e7eb; border-radius: 8px; padding: 16px; font-size: .74rem; color: #475569; box-shadow: 0 1px 3px rgba(0,0,0,.06); }
.bp-app-text { margin: 0 0 12px; }
.bp-app-controls { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.bp-app-btn { display: inline-block; padding: 7px 14px; border-radius: 6px; color: #fff; font-size: .74rem; font-weight: 600; }
.bp-app-toggle { display: inline-flex; align-items: center; gap: 8px; font-size: .74rem; color: #475569; }
.bp-app-toggle-track { position: relative; width: 34px; height: 19px; border-radius: 999px; flex: none; }
.bp-app-toggle-track::after { content: ""; position: absolute; top: 2px; right: 2px; width: 15px; height: 15px; background: #fff; border-radius: 50%; box-shadow: 0 1px 2px rgba(0,0,0,.25); }

/* Centred header block (title + description) used on MFA and similar account pages. */
.auth-header { text-align: center; margin-bottom: 30px; }
.auth-header .auth-title { margin-bottom: 10px; }
.auth-subtitle { margin: 0; color: #64748b; font-size: .9rem; line-height: 1.55; }

/* One-time-code entry: roomy, centred, spaced digits. */
.auth-card .input.auth-code {
    height: 52px; text-align: center; font-size: 1.5rem; letter-spacing: .4em;
    text-indent: .4em; font-variant-numeric: tabular-nums;
}
.auth-card .input.auth-code::placeholder { letter-spacing: .4em; color: #cbd5e1; }

/* Onboarding wizard step indicator (forced password change -> MFA enrolment). */
.auth-steps { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 26px; }
.auth-steps .s { display: flex; align-items: center; gap: 8px; font-size: .8rem; color: #94a3b8; }
.auth-steps .s .n { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center;
    background: #e2e8f0; color: #64748b; font-weight: 700; font-size: .72rem; }
.auth-steps .s.active { color: #1e293b; font-weight: 600; }
.auth-steps .s.active .n { background: var(--login-accent, #1e293b); color: #fff; }
.auth-steps .s.done .n { background: #16a34a; color: #fff; }
.auth-steps .sep { width: 26px; height: 2px; border-radius: 2px; background: #e2e8f0; }

/* Two-factor enrolment block (QR + manual key). */
.mfa-setup { text-align: center; }
.mfa-setup img { border: 1px solid #e2e8f0; border-radius: 8px; padding: 8px; background: #fff; }
.mfa-key { margin: 16px 0 8px; font-size: .8rem; color: #64748b; }
.mfa-key code { display: block; margin-top: 6px; background: #f1f5f9; border: 1px solid #e2e8f0;
    border-radius: 6px; padding: 9px 12px; font-size: .95rem; letter-spacing: .12em; color: #334155; }

.validation-message { color: #dc2626; font-size: 0.78rem; }
#blazor-error-ui { display: none; position: fixed; bottom: 0; left: 0; right: 0; background: #fee2e2; color: #991b1b; padding: 12px 20px; z-index: 1000; }

/* Collapsible nav groups implemented with <details> (works without JS) */
.sidebar-nav details > summary { list-style: none; }
.sidebar-nav details > summary::-webkit-details-marker { display: none; }
.sidebar-nav details[open] > .nav-children { display: block; }
.sidebar-nav details[open] .nav-arrow::after { transform: rotate(90deg); }

/* MOH track upload (drop zone + progress) */
.upload-area { position: relative; border: 2px dashed #cbd5e1; border-radius: 8px; padding: 22px; text-align: center; background: #f9fafb; transition: border-color .15s, background .15s; }
.upload-area:hover { border-color: #3b82f6; background: #f0f6ff; }
.upload-input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }
.upload-input:disabled { cursor: default; }
.upload-inner { display: flex; flex-direction: column; gap: 4px; pointer-events: none; }
.upload-inner strong { color: #1e293b; }
.upload-inner .muted { font-size: .78rem; }
.upload-job { margin-top: 12px; }
.upload-job-head { display: flex; justify-content: space-between; align-items: center; font-size: .82rem; margin-bottom: 4px; }
.progress { height: 8px; background: #e5e7eb; border-radius: 9999px; overflow: hidden; }
.progress-bar { height: 100%; background: #1e293b; border-radius: 9999px; transition: width .15s ease; }
.progress-bar.indeterminate { width: 40% !important; animation: progress-slide 1.1s ease-in-out infinite; }
@keyframes progress-slide { 0% { margin-left: -40%; } 100% { margin-left: 100%; } }

/* Integration pages (e.g. ElevenLabs): 2-col label|value rows, values vertically centred against the
   label — same feel as /admin/host (.host-settings), just a narrower label to suit the 1/3 column. */
.integration-rows .setting-row { grid-template-columns: 205px minmax(0, 1fr); align-items: center; }
.integration-rows .setting-row > .lbl { padding-top: 0; }
.integration-rows .setting-row > .help { display: none; }
/* A row whose value is multi-line (e.g. number + progress bar): top-align so the label lines up with the
   first line of the value, not the vertical centre of the whole block. */
.integration-rows .setting-row.row-top { align-items: start; }

/* ElevenLabs integration page: settings/account (1/3) on the left, "Used by" (2/3) on the right. */
.el-layout { display: grid; grid-template-columns: 1fr 2fr; gap: 16px; align-items: start; }
/* The section-title's default 26px top margin would double up with the page-header gap — drop it for the
   heading at the top of each column so content sits under the page title like elsewhere. */
.el-layout > div > .section-title:first-child { margin-top: 0; }
@media (max-width: 1100px) { .el-layout { grid-template-columns: 1fr; } }

/* MOH track row: [num] [name] ......scrubber(only while playing)...... [play][len][size][up][down][del] */
.track-item { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-bottom: 1px solid #f1f5f9; background: #fff; }
.track-item:last-child { border-bottom: none; }
.track-name { color: #1e293b; font-size: .875rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 280px; flex-shrink: 0; }
.track-scrubber { flex: 1 1 auto; display: flex; align-items: center; gap: 8px; min-width: 40px; padding: 0 20px; visibility: hidden; }
.track-item.playing .track-scrubber { visibility: visible; }
.track-cur { font-size: .72rem; color: #64748b; min-width: 30px; }
.scrubber-bar { flex: 1; height: 6px; background: #e5e7eb; border-radius: 9999px; cursor: pointer; overflow: hidden; }
.scrubber-fill { height: 100%; width: 0%; background: #1e293b; border-radius: 9999px; }
.track-play { width: 30px; height: 30px; flex-shrink: 0; border: 1px solid #d1d5db; background: #fff; border-radius: 50%; color: #1e293b; cursor: pointer; font-size: .7rem; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
.track-play:hover { background: #f1f5f9; }
.track-len, .track-size { font-size: .78rem; white-space: nowrap; flex-shrink: 0; min-width: 42px; text-align: right; }

/* FreeSWITCH live log console */
.log-console { background: #0d1117; color: #d1d5db; border-radius: 8px; padding: 12px 14px; flex: 1 1 auto; min-height: 200px; overflow-y: auto; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .78rem; line-height: 1.5; box-shadow: var(--shadow); }
.log-empty { color: #6b7280; font-style: italic; }
.log-line { display: flex; gap: 10px; padding: 1px 0; align-items: flex-start; }
.log-time { flex-shrink: 0; width: 62px; color: #6b7280; font-variant-numeric: tabular-nums; }
.log-lvl { flex-shrink: 0; width: 64px; color: #6b7280; text-transform: uppercase; font-size: .68rem; padding-top: 1px; }
.log-text { flex: 1 1 auto; min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; }
.log-line.lvl-err { color: #fca5a5; }
.log-line.lvl-err .log-lvl { color: #ef4444; }
.log-line.lvl-warn { color: #fcd34d; }
.log-line.lvl-warn .log-lvl { color: #f59e0b; }
.log-line.lvl-notice .log-lvl { color: #60a5fa; }
.log-line.lvl-debug { color: #94a3b8; }
.log-line.lvl-info { color: #d1d5db; }

/* Hover/focus info tooltip */
.info-tip { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; background: #e2e8f0; color: #475569; font-size: .72rem; cursor: help; flex-shrink: 0; outline: none; }
.info-tip:hover, .info-tip:focus { background: #cbd5e1; color: #1e293b; }
.info-pop { display: none; position: absolute; top: calc(100% + 8px); left: 0; width: 360px; max-width: 70vw; background: #fff; color: #374151; border: 1px solid #d1d5db; border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.14); padding: 12px 14px; z-index: 300; font-size: .78rem; line-height: 1.45; cursor: default; }
.info-tip:hover .info-pop, .info-tip:focus .info-pop, .info-tip:focus-within .info-pop { display: block; }
.info-pop strong { color: #1e293b; }
.info-pop p { margin: 6px 0 8px; color: #64748b; }
.info-pop ul { margin: 0; padding-left: 0; list-style: none; }
.info-pop li { padding: 3px 0; border-top: 1px solid #f1f5f9; }
.info-pop li b { color: #1e293b; }

/* System Health */
.metric-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 16px; }
@media (max-width: 1100px) { .metric-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .metric-grid { grid-template-columns: 1fr; } }
.metric-card { background: #fff; border-radius: 8px; box-shadow: var(--shadow); padding: 14px 16px; }
.metric-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 8px; }
.metric-head > span:first-child { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: #94a3b8; font-weight: 600; }
.metric-now { font-size: 1.15rem; font-weight: 700; color: #1e293b; font-variant-numeric: tabular-nums; }
.spark { width: 100%; height: 44px; display: block; }
.metric-sub { font-size: .72rem; color: #64748b; margin-top: 6px; }

/* Task-manager style Performance tab: big, double-size charts */
.perf-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 18px; }
@media (max-width: 900px) { .perf-grid { grid-template-columns: 1fr; } }
.perf-card { background: #fff; border-radius: 8px; box-shadow: var(--shadow); padding: 18px 20px; }
.perf-card .metric-head > span:first-child { font-size: .8rem; }
.perf-card .metric-now { font-size: 1.4rem; }
.perf-card .spark { height: 150px; margin-top: 8px; }
.perf-card .metric-sub { font-size: .76rem; margin-top: 8px; }

/* Processes tab: scrollable, sortable table */
.proc-scroll { max-height: calc(100vh - 300px); overflow-y: auto; border-radius: 8px; box-shadow: var(--shadow); background: #fff; }
.proc-scroll .data-table { box-shadow: none; }
.proc-scroll thead th { position: sticky; top: 0; z-index: 1; background: #f9fafb; }
.data-table th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.data-table th.sortable:hover { color: #1e293b; }
.data-table th.num, .data-table td.num { text-align: right; }
.data-table th.sort-asc::after { content: " \25B2"; font-size: .6rem; }
.data-table th.sort-desc::after { content: " \25BC"; font-size: .6rem; }
.health-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
@media (max-width: 1000px) { .health-cols { grid-template-columns: 1fr; } }
.disk-row { padding: 8px 0; }
.disk-row:not(:last-child) { border-bottom: 1px solid #f1f5f9; }
.disk-label { display: flex; justify-content: space-between; font-size: .8rem; margin-bottom: 5px; }
.disk-bar { height: 8px; background: #e5e7eb; border-radius: 9999px; overflow: hidden; }
.disk-fill { height: 100%; background: #10b981; border-radius: 9999px; }
.disk-fill.warm { background: #f59e0b; }
.disk-fill.hot { background: #ef4444; }

/* Extension presence traffic-light */
.dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: #cbd5e1; vertical-align: middle; }
.dot-available { background: #22c55e; box-shadow: 0 0 0 2px rgba(34,197,94,.18); }
.dot-busy { background: #ef4444; box-shadow: 0 0 0 2px rgba(239,68,68,.18); }
.dot-ringing { background: #f59e0b; box-shadow: 0 0 0 2px rgba(245,158,11,.18); animation: dot-pulse 1s ease-in-out infinite; }
.dot-offline { background: #cbd5e1; }
.dot-info { background: #3b82f6; box-shadow: 0 0 0 2px rgba(59,130,246,.18); }
@keyframes dot-pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
.trunk-status { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.input.invalid { border-color: #dc2626; box-shadow: 0 0 0 2px rgba(220,38,38,.12); }
/* kfs-flash is toggled by kfsMarkInvalid() to (re)play a brief red pulse when a field is flagged
   invalid on blur/save — the .invalid border persists after the pulse fades. */
.input.invalid.kfs-flash { animation: kfs-invalid-flash .55s ease; }
@keyframes kfs-invalid-flash {
    0%   { background: #fee2e2; box-shadow: 0 0 0 4px rgba(220,38,38,.4); }
    100% { background: #fff;    box-shadow: 0 0 0 2px rgba(220,38,38,.12); }
}
.field-error { color: #dc2626; font-size: .8rem; margin-top: 4px; }

/* Trunk provider picker */
.section-title { font-size: .8rem; text-transform: uppercase; letter-spacing: .04em; color: #64748b; font-weight: 600; margin: 26px 0 12px; }
.provider-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 20px; max-width: 1000px; }
.provider-card { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px;
    position: relative; background: #fff; border: 1px solid #e5e7eb; border-radius: 14px; padding: 40px 24px; min-height: 190px;
    text-decoration: none; color: #1e293b; box-shadow: var(--shadow); transition: border-color .12s, box-shadow .12s, transform .12s; }
.provider-card:hover:not(.disabled) { border-color: #c7d2fe; box-shadow: 0 4px 14px rgba(0,0,0,.08); transform: translateY(-1px); }
.provider-logo { height: 72px; display: flex; align-items: center; justify-content: center; }
.provider-logo img { max-height: 72px; max-width: 220px; object-fit: contain; }
.provider-generic-icon { width: 64px; height: 64px; color: #6366f1; }
.provider-name { font-weight: 600; font-size: 1.05rem; text-align: center; }
.provider-card.disabled { opacity: .55; filter: grayscale(1); cursor: not-allowed; }
.provider-card.disabled .badge-soon { position: absolute; top: 10px; right: 10px; }

/* Trunk gateway event timeline (Diagnostics tab) */
.trunk-events { width: 100%; border-collapse: collapse; }
.trunk-events th, .trunk-events td { text-align: left; padding: 8px 12px; border-bottom: 1px solid #f1f5f9; font-size: .9rem; }
.trunk-events th { color: #64748b; font-weight: 600; }
.trunk-events th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.trunk-events th.sortable:hover { color: #1e293b; }
.trunk-events .when { color: #64748b; white-space: nowrap; }
.evt-badge { display: inline-flex; align-items: center; gap: 7px; }
.evt-empty { color: #94a3b8; padding: 14px 12px; }
.pager { display: flex; align-items: center; gap: 10px; margin-top: 12px; font-size: .85rem; }
.data-table tr.row-muted td { opacity: .55; }
/* Top-align a setting-row's label when its control is tall (e.g. the codec list). */
.setting-row.row-top { align-items: start; }
.setting-row.row-top > .lbl { padding-top: 9px; }
/* Toggle rows: a switch is shorter than a text input, so vertically centre the row and drop the
   label's input-baseline padding — otherwise the toggle sits slightly above the label text. */
.setting-row.row-toggle { align-items: center; }
.setting-row.row-toggle > .lbl { padding-top: 0; }
/* Center a row whose value is short content (text/badges) rather than a full-height input, so the
   label and value sit on the same line (the default start-align + label padding-top reads misaligned). */
.setting-row.row-center { align-items: center; }
.setting-row.row-center > .lbl { padding-top: 0; }
/* A toggle paired with an input on one row (e.g. "Alert on match" + recipients). */
.alert-row { display: flex; align-items: center; gap: 12px; }
.alert-row > .input { flex: 1; min-width: 0; }

.codec-order { display: flex; flex-direction: column; gap: 6px; max-width: 400px; }
.codec-row { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border: 1px solid #e5e7eb; border-radius: 8px; background: #fff; }
.codec-row.on { border-color: #c7d2fe; background: #f5f7ff; }
.codec-row:not(.on) .codec-opt { color: #94a3b8; }
.codec-rank { flex: 0 0 16px; text-align: center; font-size: .78rem; font-weight: 700; color: #6366f1; }
.codec-opt { flex: 1 1 auto; display: inline-flex; align-items: center; gap: 8px; font-size: .9rem; white-space: nowrap; cursor: pointer; }
.codec-move { flex: 0 0 auto; display: flex; align-items: center; }
.codec-row.dragging { opacity: .4; }
.codec-row.drag-over { box-shadow: inset 0 2px 0 #6366f1; }
.status-legend { display: flex; gap: 14px; font-size: .72rem; color: #64748b; }
.status-legend span { display: inline-flex; align-items: center; gap: 5px; }
