/* style.css — shared minimal styling for the agent-facing GUI (login +
   softphone pages). No framework/build step, per the project's
   "don't add infrastructure this box doesn't need" precedent (see
   the project log's architecture-decisions section). One stylesheet,
   loaded by both pages. */

:root {
  --bg: #0f172a;
  --panel: #1a2333;
  --panel-border: #2c3a52;
  --text: #e6ebf3;
  --text-dim: #93a1b8;
  --accent: #3b82f6;
  --accent-dim: #1d4ed8;
  --ok: #22c55e;
  --warn: #f59e0b;
  --err: #ef4444;
  /* 'Inter' added 2026-10-12 as part of the Osprey rebrand -- loaded via
     a Google Fonts <link> in each page's <head>; the system-font stack
     stays as the fallback chain if that link is ever slow/unreachable. */
  --font: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

body.top-align { align-items: flex-start; }

.panel {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 12px; /* was 10px -- standardized to the Osprey rebrand's --radius-lg token */
  padding: 28px;
  width: 100%;
  max-width: 420px;
}

.panel.wide { max-width: 640px; }

h1, h2, h3 { margin-top: 0; font-weight: 600; }
h1 { font-size: 1.4rem; }
h2 { font-size: 1.1rem; color: var(--text-dim); }

label {
  display: block;
  font-size: 0.85rem;
  color: var(--text-dim);
  margin: 14px 0 6px;
}

input[type="text"], input[type="password"], select {
  width: 100%;
  padding: 10px 12px;
  border-radius: 6px;
  border: 1px solid var(--panel-border);
  background: #0d1420;
  color: var(--text);
  font-size: 0.95rem;
}

input:focus, select:focus, button:focus { outline: 2px solid var(--accent); }

button {
  cursor: pointer;
  border: none;
  border-radius: 6px;
  padding: 10px 16px;
  font-size: 0.9rem;
  font-weight: 600;
  background: var(--accent);
  color: white;
}

button:hover { background: var(--accent-dim); }
button:disabled { background: #334155; color: var(--text-dim); cursor: not-allowed; }

button.secondary { background: #2c3a52; }
button.secondary:hover { background: #3a4b68; }

button.danger { background: var(--err); }
button.danger:hover { background: #b91c1c; }

.row { display: flex; gap: 10px; flex-wrap: wrap; }
.row button { flex: 1; }

.error-box {
  background: rgba(239, 68, 68, 0.12);
  border: 1px solid var(--err);
  color: #fecaca;
  padding: 10px 12px;
  border-radius: 6px;
  font-size: 0.85rem;
  margin-top: 14px;
  display: none;
}
.error-box.show { display: block; }

.hint {
  font-size: 0.78rem;
  color: var(--text-dim);
  margin-top: 16px;
  line-height: 1.4;
}

.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 18px;
}

.topbar .who { font-size: 0.85rem; color: var(--text-dim); }
.topbar .who strong { color: var(--text); }

/* Groups Profile + Log out together on the right so .topbar's
   space-between doesn't spread Profile out into the middle of the bar
   (added 2026-09-23 alongside the Profile button; fixes it floating away
   from Log out instead of sitting next to it). */
.topbar-actions { display: flex; gap: 14px; }

/* Softphone top-bar action buttons (Voicemail/Contacts/Profile/Sign out)
   -- redesigned 2026-10-12 from plain filled .secondary boxes to icon
   circles with a label underneath (matches the icon-button pattern
   already used in the active-call screen's Mute/Keypad/Transfer row,
   .phone-icon-btn above) after the user felt the old boxes looked
   heavy/cluttered next to the real primary actions (Go Available / On
   Break / Log Out (queue)) below them. Base styling here is theme-
   agnostic (reads the shared --panel/--panel-border/--text/--text-dim
   vars), with the hover color pinned to the softphone page's teal accent
   further down in the body.softphone-page section, since this component
   currently only renders on that page. */
.topbar-icon-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  padding: 2px;
  font-size: 0.66rem;
  font-weight: 600;
  color: var(--text-dim);
  cursor: pointer;
}
.topbar-icon-btn .circle {
  position: relative;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  color: var(--text);
}
.topbar-icon-btn:hover .circle { background: var(--panel-border); }
/* Unread-voicemail count badge, repositioned from an inline pill (next
   to the old "Voicemail" text label) to a small corner badge on the
   icon circle -- same .badge element/classes/JS toggling as before
   (softphone.js still just sets textContent and toggles [hidden]), just
   repositioned and shrunk via this added class. */
.topbar-icon-btn .icon-badge-dot {
  position: absolute;
  top: -4px;
  right: -6px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  font-size: 0.6rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.badge.unknown { background: #334155; color: var(--text-dim); }
.badge.available { background: rgba(34, 197, 94, 0.18); color: #86efac; }
.badge.paused { background: rgba(245, 158, 11, 0.18); color: #fcd34d; }
.badge.logged_out { background: rgba(148, 163, 184, 0.18); color: var(--text-dim); }
.badge.connecting { background: rgba(245, 158, 11, 0.18); color: #fcd34d; }
.badge.registered { background: rgba(34, 197, 94, 0.18); color: #86efac; }
.badge.failed { background: rgba(239, 68, 68, 0.18); color: #fecaca; }
/* Campaign statuses (running/on_hold/stopped were previously unstyled,
   falling back to the plain default badge look -- given badge classes,
   added here rather than left inconsistent now that on_hold needs a
   look of its own to read as distinct from paused). */
.badge.running { background: rgba(34, 197, 94, 0.18); color: #86efac; }
.badge.on_hold { background: rgba(76, 111, 255, 0.18); color: #93c5fd; }
.badge.stopped { background: #334155; color: var(--text-dim); }

.section {
  border-top: 1px solid var(--panel-border);
  padding-top: 16px;
  margin-top: 16px;
}

/* ===================== Phone widget (dialpad + in-call screen) =====================
   Shared by the agent softphone (static/softphone.html) and the admin
   sidebar Dialpad widget (static/dashboard.html's #side-dialpad) --
   redesigned 2026-09-10 after the user shared reference screenshots of
   typical WebRTC softphone apps (Tragofone, Mizu VoIP, 3CX, Simotel) and
   asked for the same look: a self-contained dark "phone" card with a big
   tappable numeric keypad for composing a number, and a dedicated
   in-call screen (caller number, a live duration timer, and icon-style
   controls) rather than the old plain text-input + small-button layout.
   Deliberately hardcoded dark colors (not var(--panel-border) etc.) so
   this reads the same whether it's sitting in the softphone's own dark
   page or floating inside the light dashboard sidebar -- see the old
   .call-panel/.dialpad rules this replaces, which inherited the
   surrounding theme's border color and looked inconsistent once the
   sidebar went light (2026-09-02 visual refresh) while these buttons
   stayed hardcoded dark.
   Deliberately NOT included (per the user's own scoping answers): a
   recent-calls/contacts list, and Hold/Transfer buttons -- neither is
   implemented anywhere in this codebase (JsSIP session has no hold/
   transfer wiring here), so no buttons are shown for capabilities that
   don't exist yet. */
.phone-widget {
  background: #FFFFFF;
  border: 1px solid #DCE3ED;
  border-radius: 14px;
  padding: 14px;
  color: #101A46;
  /* Cap it to a compact phone-card width and center it. Without this the
     admin sidebar's 240px-wide column happened to keep the keypad a
     sensible size, but the agent softphone page places this same
     component inside .panel.wide (640px) with no width limit of its
     own -- the 3-col grid + aspect-ratio:1/1 keys then scale up to fill
     that whole width, rendering an oversized ~200px-diameter keypad
     (reported 2026-09-10). 320px matches the reference softphone
     screenshots (Tragofone/Mizu/3CX) and is still comfortably narrower
     than the 240px sidebar column, so .side-dialpad's own scaled-down
     sizing there is unaffected. */
  max-width: 320px;
  margin: 0 auto;
}
/* Recolored to a light card (2026-10-09, by request) -- this component
   used to be a deliberately dark "phone app" card, kept dark even after
   both pages it lives on (the dashboard sidebar and the agent softphone
   page) went light, which is why its own background/color/border were
   pinned here with !important: the dashboard's light-theme rules
   (body.dashboard-page select / input[type="text"], further down this
   file) are scoped with a "body.classname" prefix, which otherwise beats
   a plain .phone-widget-scoped selector on specificity alone regardless
   of source order (confirmed live 2026-09-10). Now that this component
   is light too, that fight no longer exists -- !important removed, the
   values below are just this component's own light styling. */
.phone-widget select {
  width: 100%;
  background: #F8FAFC;
  border: 1px solid #DCE3ED;
  color: #101A46;
  border-radius: 8px;
  padding: 8px 9px;
  margin-bottom: 10px;
}
.phone-widget .hint { color: #475569; }
.phone-widget .error-box { margin-top: 0; margin-bottom: 10px; }

/* Caller ID (ANI) field -- added 2026-09-11 for the Admin + Agent Dialpad
   mandatory-caller-ID feature (see static/dashboard.html's #dp-caller-id
   and static/softphone.html's #dial-caller-id). Deliberately its OWN
   class rather than a `.phone-widget input[type="text"]` selector: that
   broader selector would be MORE specific than `.phone-display input`
   below and would incorrectly win, clobbering the number-entry field's
   intentional transparent/borderless styling. Styled to match
   `.phone-widget select` above -- recolored light along with the rest
   of the phone card, 2026-10-09; !important no longer needed (see the
   comment on .phone-widget select above). */
.phone-caller-id-input {
  display: block;
  width: 100%;
  background: #F8FAFC;
  border: 1px solid #DCE3ED;
  color: #101A46;
  border-radius: 8px;
  padding: 8px 9px;
  margin-bottom: 10px;
  font-size: 0.95rem;
  box-sizing: border-box;
}
.phone-caller-id-input::placeholder { color: #9AA5B8; }

.phone-display {
  display: flex;
  align-items: center;
  gap: 6px;
  background: #F8FAFC;
  border: 1px solid #DCE3ED;
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 12px;
}
.phone-display input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: none;
  color: #101A46;
  font-size: 1.05rem;
  letter-spacing: 0.02em;
  padding: 0;
  outline: none;
}
.phone-display input::placeholder { color: #9AA5B8; }
.phone-display-backspace {
  flex: none;
  background: transparent;
  border: none;
  color: #475569;
  font-size: 1.15rem;
  line-height: 1;
  padding: 2px 4px;
  cursor: pointer;
}
.phone-display-backspace:hover { color: #101A46; }

.phone-keys {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-bottom: 14px;
}
.phone-keys[hidden] { display: none; }

/* Call Transfer target picker + attended-transfer consult panel -- added
   2026-09-21, recolored light along with the rest of the phone card
   2026-10-09. Uses the same #F8FAFC/#DCE3ED palette as .phone-key below
   so it still reads as part of the same card rather than a mismatched
   insert. */
.phone-transfer-panel {
  background: #F8FAFC;
  border: 1px solid #DCE3ED;
  border-radius: 10px;
  padding: 10px;
  margin-bottom: 14px;
  text-align: left;
}
.phone-transfer-panel[hidden] { display: none; }
/* No longer needs !important (removed 2026-10-09): that was only to
   beat body.softphone-page's light-theme select override on
   specificity while this panel was still deliberately dark (see the
   .phone-widget select comment above for the underlying specificity
   quirk) -- now both rules agree on a light select, so there's nothing
   left to fight. */
.phone-transfer-panel select {
  background: #FFFFFF;
  color: #101A46;
  border: 1px solid #DCE3ED;
  border-radius: 6px;
  padding: 8px;
}
/* Osprey rebrand (2026-10-12): replaces the four prior light-blue/teal
   recolors from earlier the same day. This is a full style change, not
   just a color swap, taken from the Osprey Agent Interface design-token
   doc's "Dialpad-specific tokens" table:
     - Shape: circular keys -> rounded squares (12px radius, doc's
       --dialpad-key-radius).
     - Behavior: no longer a static colored fill at rest. Default is
       white with a thin outline; hover is a pale-blue fill; the key
       only goes solid royal-blue while actually being pressed
       (:active), not as a resting state.
   Hardcoded (not var(--accent)-driven) so it looks the same regardless
   of which page the shared .phone-widget sits in (softphone page or the
   dashboard sidebar's embedded Dialpad) -- same reasoning as every
   previous recolor here, just with doc-specified values now. */
.phone-key {
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  background: #FFFFFF;
  border: 1px solid #DCE3ED;
  color: #101A46;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.1;
  cursor: pointer;
  transition: background 0.1s ease, border-color 0.1s ease, color 0.1s ease;
}
.phone-key:hover { background: #E8EEFF; border-color: #C7D8FF; }
.phone-key:active { background: #2457D6; border-color: #2457D6; color: #fff; }
.phone-key:active .sub { color: rgba(255, 255, 255, 0.85); }
.phone-key .sub { font-size: 0.5rem; font-weight: 500; letter-spacing: 0.05em; color: #64748B; margin-top: 1px; }

.phone-actions { display: flex; justify-content: center; }
.phone-answer-btn,
.phone-hangup-btn,
.phone-reject-btn {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: none;
  color: #fff;
  font-size: 1.3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transform: rotate(0deg);
}
/* .phone-call-btn (the idle dial-form's call button) is split out from
   the shared size rule above and sized smaller on its own, per user
   feedback -- matches the existing .side-dialpad .phone-call-btn size
   (44px) rather than the 52px shared by answer/hangup/reject, which
   live on the active-call screens the user didn't comment on. */
.phone-call-btn {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  color: #fff;
  font-size: 1.15rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transform: rotate(0deg);
}
/* Call/answer buttons recolored from green (#1BAF7A) to royal blue, per
   the design doc's explicit "I would use a solid blue Call button with
   white text and a phone icon" guidance (the doc's broader token table
   elsewhere lists the call button as teal, but its own agent-interface
   section -- the one written specifically about this dial pad -- is
   more specific and overrides that; this also matches the preview the
   user already reviewed and didn't push back on). */
.phone-call-btn,
.phone-answer-btn { background: #2457D6; }
.phone-call-btn:hover,
.phone-answer-btn:hover { background: #1D46B3; }
.phone-call-btn:disabled { background: #F1F5F9; color: #94A3B8; cursor: not-allowed; }
.phone-hangup-btn,
.phone-reject-btn { background: #DC2626; transform: rotate(135deg); }
.phone-hangup-btn:hover,
.phone-reject-btn:hover { background: #B91C1C; }

.phone-call-screen { text-align: center; padding: 6px 2px 2px; }
.phone-call-screen .avatar {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  margin: 0 auto 10px;
  background: #E2E8F0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  color: #475569;
}
.phone-call-screen .number { font-size: 1.1rem; font-weight: 700; margin-bottom: 2px; }
.phone-call-screen .state { color: #475569; font-size: 0.82rem; margin-bottom: 16px; font-variant-numeric: tabular-nums; }

.phone-controls-row { display: flex; justify-content: center; gap: 22px; margin-bottom: 14px; }
.phone-icon-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  color: #475569;
  cursor: pointer;
  font-size: 0.68rem;
}
.phone-icon-btn .circle {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: #F1F5F9;
  border: 1px solid #DCE3ED;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.05rem;
  color: #101A46;
}
.phone-icon-btn:hover .circle { background: #E7EAF2; }
/* Recolored teal -> royal blue, 2026-10-12 Osprey rebrand: this circle
   highlights an ACTIVE TOGGLE (Mute engaged, Keypad open, Transfer
   panel open) -- an in-progress primary-action state, not a "success/
   available" one, so it now matches the page's primary accent instead
   of the teal that's now reserved for availability/success meaning. */
.phone-icon-btn.active .circle { background: #2457D6; border-color: #2457D6; color: #fff; }

/* Recolored light along with the rest of the phone card, 2026-10-09
   (was a dark #0d1420 panel to match the then-dark .phone-widget). */
.log {
  margin-top: 16px;
  background: #F8FAFC;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 10px 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.75rem;
  color: var(--text-dim);
  max-height: 180px;
  overflow-y: auto;
}
.log div { padding: 1px 0; }

a { color: var(--accent); }

/* ============ Dashboard shell (static/dashboard.html + dashboard.js) ============ */

.panel.wide.dashboard-shell { max-width: 1180px; }

.tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--panel-border);
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.tab-btn {
  background: transparent;
  color: var(--text-dim);
  border-radius: 6px 6px 0 0;
  padding: 10px 16px;
  font-weight: 600;
  font-size: 0.85rem;
}
.tab-btn:hover { background: #1f2b40; color: var(--text); }
.tab-btn.active { background: var(--panel-border); color: var(--text); }

.hidden { display: none !important; }

.table-wrap {
  overflow-x: auto;
  margin-top: 12px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
}
table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
thead th {
  text-align: left;
  padding: 10px 12px;
  background: #16223a;
  color: var(--text-dim);
  font-weight: 600;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-bottom: 1px solid var(--panel-border);
  white-space: nowrap;
}
tbody td { padding: 9px 12px; border-bottom: 1px solid var(--panel-border); vertical-align: middle; }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: #16223a; }
table button { padding: 6px 12px; font-size: 0.76rem; margin-right: 4px; }

/* Trunks table gained 5 stat columns (Attempts/ASR/ACD/NER/Completion)
   for per-trunk live stats -- at the default 100% table width that was
   enough columns to wrap the Name/Host cell text and stack the
   Edit/Deactivate buttons onto their own lines, clipped against the
   table-wrap border. A min-width lets the existing
   .table-wrap{overflow-x:auto} do its job (a horizontal scrollbar on a
   narrow viewport) instead of squeezing content illegibly. */
#trunks-table { min-width: 1100px; }
#trunks-table td:last-child { white-space: nowrap; }

.detail-panel {
  margin-top: 18px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  padding: 18px;
  background: #131c2c;
}

.live-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
  margin: 14px 0;
}
.stat-tile {
  background: #0d1420;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  padding: 12px;
}
.stat-label { font-size: 0.68rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.03em; }
.stat-value { font-size: 1.3rem; font-weight: 700; margin-top: 4px; }

.gauge-wrap { margin: 16px 0 4px; }
.gauge-track {
  position: relative;
  height: 10px;
  border-radius: 999px;
  background: #0d1420;
  border: 1px solid var(--panel-border);
  margin-top: 6px;
}
.gauge-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--accent);
  width: 0%;
  transition: width 0.3s ease;
}
.gauge-fill.over-target { background: var(--err); }
.gauge-target {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  background: var(--warn);
  left: 0%;
}

/* --- Overview tab layout: main column + a side panel for System status ---
   System status (CPU/memory/disk/graphs) is background VPS-health info,
   not something a call-center supervisor needs to check every time they
   glance at Overview -- unlike Campaign/Agents/Trunks/Inbound, which
   change with every shift. Putting it in a narrower side panel (reusing
   .detail-panel's existing chrome, so it doesn't need its own theme
   rules) keeps it visually secondary without hiding it. Stacks to a
   single column on narrow viewports via the existing 860px breakpoint
   below. */
.overview-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 20px;
  align-items: start;
}
.overview-aside { padding: 16px; }

/* --- System status graphs (Overview tab, dashboard Group C item) ---
   Plain <canvas>-drawn line charts, no charting library -- see
   static/dashboard.js's drawLineChart() for the renderer. Card chrome
   (border/background/tooltip) is themed here the same way a .stat-tile
   is; the lines themselves are drawn in JS using these same CSS custom
   properties (read via getComputedStyle so they follow whichever theme
   -- dark base or light dashboard-page -- is currently active). */
.chart-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 10px;
  margin: 4px 0 10px;
}
.chart-card {
  background: #0d1420;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  padding: 10px 12px 8px;
}
.chart-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
}
.chart-card-title { font-size: 0.68rem; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.03em; }
.chart-legend { display: flex; gap: 10px; font-size: 0.72rem; color: var(--text-dim); }
.legend-item { display: inline-flex; align-items: center; gap: 4px; }
.legend-swatch { display: inline-block; width: 8px; height: 8px; border-radius: 2px; }
.legend-swatch-1 { background: var(--tile-1, var(--accent)); }
.legend-swatch-2 { background: var(--tile-2, var(--warn)); }
.legend-swatch-3 { background: var(--tile-3, var(--accent)); }
.chart-canvas-wrap { position: relative; height: 90px; }
.chart-canvas { width: 100%; height: 100%; display: block; }
.chart-tooltip {
  position: absolute;
  top: 4px;
  left: 4px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 2px 8px;
  font-size: 0.72rem;
  color: var(--text);
  pointer-events: none;
  white-space: nowrap;
}
.chart-tooltip[hidden] { display: none; }

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(4, 8, 16, 0.65);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 40px 16px;
  overflow-y: auto;
  z-index: 100;
}
.modal-panel { max-width: 560px; width: 100%; }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.form-grid .full { grid-column: 1 / -1; }

.checkbox-row { display: flex; align-items: center; gap: 8px; margin: 14px 0 6px; }
.checkbox-row input[type="checkbox"] { width: auto; }
.checkbox-row label { margin: 0; }

.creds-box {
  background: rgba(34, 197, 94, 0.1);
  border: 1px solid var(--ok);
  border-radius: 6px;
  padding: 12px 14px;
  font-size: 0.82rem;
  line-height: 1.6;
  margin-top: 10px;
}
.creds-box code { background: #0d1420; padding: 2px 6px; border-radius: 4px; }

/* ============ Login page visual refresh (2026-09-02) ============
   Same light palette as the dashboard reskin below, applied to the
   sign-in page only via body.login-page — self-contained (doesn't read
   the dashboard's --db-* tokens, which are scoped to body.dashboard-page)
   so this page has no dependency on the dashboard CSS. The agent
   softphone doesn't carry this class and keeps its original dark theme,
   since only the login + dashboard were asked for. */
/* Osprey rebrand (2026-10-12): unified brand tokens from the design
   doc -- royal blue #2457D6 primary (was a brighter #4C6FFF), deep navy
   #101A46 headings (was #1B2333), #F1F5F9 page background, #DCE3ED
   borders. Kept scoped the same way as before (body.login-page
   reassigns the shared vars), so no other page is affected. */
body.login-page {
  --bg: #F1F5F9;
  --panel: #FFFFFF;
  --panel-border: #DCE3ED;
  --text: #101A46;
  --text-dim: #475569;
  --accent: #2457D6;
  --accent-dim: #1D46B3;
  --ok: #0F766E;
  --warn: #B45309;
  --err: #DC2626;
}
body.login-page input[type="text"],
body.login-page input[type="password"] { background: #FFFFFF; border-color: #DCE3ED; }
/* Royal-blue border + soft focus ring on input focus, per the rebrand
   doc's --focus-ring token (0 0 0 3px rgba(36,87,214,0.22)) -- the base
   input:focus rule elsewhere is just a plain outline, this replaces it
   on the login page specifically with the ring look the doc asked for. */
body.login-page input[type="text"]:focus,
body.login-page input[type="password"]:focus {
  outline: none;
  border-color: #2457D6;
  box-shadow: 0 0 0 3px rgba(36, 87, 214, 0.22);
}
body.login-page .panel {
  box-shadow: 0 1px 2px rgba(16, 26, 70, 0.04), 0 8px 24px -12px rgba(16, 26, 70, 0.12);
  /* Widened 420px -> 480px (2026-10-09, follow-up) so the logo above
     "Sign in" has room to grow past the shared .panel's default
     max-width -- see .login-logo below. */
  max-width: 480px;
}
body.login-page .hint { line-height: 1.6; } /* more comfortable line spacing, per the rebrand doc */
body.login-page .error-box { background: #FEE2E2; color: #B91C1C; }

/* ============ Dashboard visual refresh (2026-09-02) ============
   Light, colorful theme for the supervisor dashboard only — scoped
   entirely under body.dashboard-page so the login page and the agent
   softphone (neither carries this class) keep their original dark
   theme untouched. Every rule here either reassigns the shared CSS
   variables (so components above pick up the new colors automatically)
   or overrides a hardcoded dark-theme hex the base rules use, so no
   existing element ID, class name, or dashboard.js behavior changes —
   this is a reskin, not a rebuild. Tile accent colors are the
   dataviz-skill reference categorical palette (validated CVD-safe),
   reused verbatim rather than invented. */

/* Osprey rebrand (2026-10-12): same unified token set as the login page
   -- royal blue primary, navy ink, #F1F5F9 background. tile-1/tile-2/
   tile-3 are kept -- tile-1/tile-2 are read by both the Network chart's
   Down/Up legend swatches (blue=download/orange=upload) and
   dashboard.js's drawLineChart() call for the CPU chart; tile-3 is read
   by that same call for the Live Channels chart (violet, kept distinct
   from CPU/network's blue+orange). (tile-3 was briefly dropped earlier
   in this same rebrand pass -- dashboard.js still reads it via
   cssVar("--tile-3") for that chart's line color, which silently
   resolved to an empty/invalid strokeStyle with it gone. Re-added.)
   tile-4/5 are genuinely unused now -- they only ever fed the old
   5-color decorative per-metric stat-tile borders; see the .stat-tile
   override further down, which now uses one standardized border instead
   of cycling colors across unrelated metrics, per the rebrand doc's
   "use color selectively for status rather than assigning a different
   accent to every metric" guidance. */
body.dashboard-page {
  --db-bg: #F1F5F9;
  --db-surface: #FFFFFF;
  --db-surface-2: #F8FAFC;
  --db-border: #DCE3ED;
  --db-ink: #101A46;
  --db-ink-dim: #475569;
  --db-accent: #2457D6;
  --db-accent-dim: #1D46B3;
  --db-accent-soft: #E8EEFF;
  --db-ok-soft: #CCFBF1;
  --db-warn-soft: #FEF3C7;
  --db-err-soft: #FEE2E2;
  --db-neutral-soft: #E2E8F0;
  --tile-1: #2457D6; /* blue -- CPU, network "down" */
  --tile-2: #EA580C; /* orange -- network "up" */
  --tile-3: #7C3AED; /* violet -- live channels */

  /* Reassign the base theme vars every shared component already reads. */
  --bg: var(--db-bg);
  --panel: var(--db-surface);
  --panel-border: var(--db-border);
  --text: var(--db-ink);
  --text-dim: var(--db-ink-dim);
  --accent: var(--db-accent);
  --accent-dim: var(--db-accent-dim);
  --ok: #0CA30C;
  --warn: #B8790A;
  --err: #D03B3B;

  display: block;
  padding: 0;
  min-height: 100vh;
}

body.dashboard-page input[type="text"],
body.dashboard-page select { background: var(--db-surface); }

body.dashboard-page .panel.wide.dashboard-shell {
  margin: 28px auto 60px;
  padding: 0 20px;
  border: none;
  background: transparent;
}

/* --- overall shell: left sidebar (nav + persistent Dialpad widget) +
   main content column (slim top bar for the account cluster + the
   existing tab-panel content). Replaces the old horizontal top-nav
   layout (2026-09-08, review-team round 2). --- */
.dash-shell {
  display: flex;
  align-items: flex-start;
  min-height: 100vh;
}
.dash-main {
  flex: 1;
  min-width: 0;
}

.dash-sidebar {
  flex: 0 0 240px;
  width: 240px;
  min-height: 100vh;
  position: sticky;
  top: 0;
  align-self: flex-start;
  background: var(--db-surface);
  border-right: 1px solid var(--db-border);
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 16px 14px;
  overflow-y: auto;
}

.brand { display: flex; align-items: center; gap: 6px; padding: 4px 2px; }
/* 2026-10-09: brand-mark used to be a plain "PD" text badge on a gradient
   square (see git history / the zip from that date if this ever needs
   reverting). It's now an <img> pointing at static/brand/osprey-mark.png
   (the blue hawk-head + phone-handset mark, cropped square and cleaned up
   from the user-supplied brand kit -- a stray disconnected shape and a
   faint transparent-edge fringe were removed; see
   claude/reference-platform-review-2026-10-09.md), transparent background
   so it just sits on whatever the page's own background is (white on the
   dashboard/login pages, the dark default theme on the softphone page).
   The full detailed version with the "Osprey / Predictive Dialer"
   wordmark (static/brand/osprey-logo-full.png) is used on the login page
   only, where there's room for it -- neither this flat mark nor that
   fuller one should be redrawn smaller than this; an earlier orange/
   metallic brand-kit candidate was tried here first and turned out to be
   illegible once shrunk to 30px/16px, which is why this one went through
   a size check (16 through 256px) before being wired in.
   Bumped 30px -> 48px (2026-10-09, follow-up) per user request ("option
   B" of 4 sidebar-mark size options shown) -- gap tightened 10px -> 6px
   and brand-name knocked down a touch (0.95rem -> 0.9rem) so the bigger
   icon doesn't read as crowding the text. Bumped again 48px -> 60px
   (same day, user asked for it still bigger) -- gap/text left as-is,
   still comfortably inside the 240px sidebar's usable width. */
.brand-mark {
  display: block;
  width: 60px;
  height: 60px;
  object-fit: contain;
  flex: none;
}
.brand-name { font-weight: 700; font-size: 0.9rem; color: var(--db-ink, var(--text)); white-space: nowrap; }

/* Login page's full detailed logo -- the one spot with enough room for
   the whole brand-kit mark + wordmark image rather than the flat
   favicon-safe version above. */
.login-logo { display: block; max-width: 420px; width: 100%; height: auto; margin: 0 auto 20px; } /* bottom margin 8px -> 20px, more breathing room per Osprey rebrand */

/* --- sidebar nav: top-level items + the collapsible Dialplan group --- */
.side-nav { display: flex; flex-direction: column; gap: 2px; }
.side-nav-btn,
.side-nav-subbtn {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  color: var(--db-ink-dim);
  border-radius: 8px;
  padding: 10px 12px;
  font-weight: 600;
  font-size: 0.85rem;
}
.side-nav-btn:hover,
.side-nav-subbtn:hover { background: var(--db-surface-2); color: var(--db-ink); }
.side-nav-btn.active,
.side-nav-subbtn.active { background: var(--db-accent-soft); color: var(--db-accent-dim); }

.side-nav-group-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}
.side-nav-group-toggle .chevron { font-size: 0.7rem; color: var(--db-ink-dim); transition: transform 0.15s; }
.side-nav-group.open .side-nav-group-toggle .chevron { transform: rotate(180deg); }
.side-nav-submenu {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-left: 14px;
  margin-top: 2px;
}
.side-nav-submenu[hidden] { display: none; }
.side-nav-subbtn { font-weight: 500; font-size: 0.8rem; padding: 8px 12px; }

/* --- sidebar Dialpad widget (admin/super_admin only, always visible) ---
   Pinned to the bottom of the sidebar via margin-top:auto so it reads as
   a persistent tool distinct from page navigation above it, not just
   another nav row. The widget is a .phone-widget card (see that
   component above) -- originally a deliberately dark "phone app" card
   floating in the light sidebar, recolored light on 2026-10-09 along
   with the rest of the shared .phone-* component -- these rules only
   handle the widget's own header/log chrome and scale the shared
   .phone-* component down to fit the sidebar's 240px width. */
.side-dialpad {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--db-border);
}
.side-dialpad-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.side-dialpad-title-group { display: flex; align-items: center; gap: 6px; }
.side-dialpad-title {
  font-weight: 700;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--db-ink-dim);
}
/* Opens the "my caller ID (ANI)" self-service modal (added 2026-09-10 --
   see PUT /api/agents/me/caller-id). Sits on the .phone-widget header,
   recolored light along with it on 2026-10-09. */
.side-dialpad-settings-btn {
  background: none;
  border: none;
  color: var(--db-ink-dim);
  font-size: 0.82rem;
  line-height: 1;
  padding: 2px;
  cursor: pointer;
}
.side-dialpad-settings-btn:hover { color: var(--db-ink); }
.side-dialpad .phone-keys { gap: 6px; margin-bottom: 10px; }
.side-dialpad .phone-key { font-size: 0.88rem; }
.side-dialpad .phone-key .sub { font-size: 0.44rem; }
.side-dialpad .phone-call-btn,
.side-dialpad .phone-answer-btn,
.side-dialpad .phone-hangup-btn,
.side-dialpad .phone-reject-btn { width: 44px; height: 44px; font-size: 1.1rem; }
.side-dialpad .phone-controls-row { gap: 16px; }
.side-dialpad .phone-icon-btn .circle { width: 36px; height: 36px; font-size: 0.92rem; }
.side-dialpad-log-wrap { font-size: 0.72rem; margin-top: 10px; }
.side-dialpad-log-wrap summary { cursor: pointer; color: var(--db-ink-dim); padding: 2px 0; }
.side-dialpad .log { max-height: 110px; margin-top: 6px; }
.side-dialpad .phone-widget .error-box { margin-top: 0; font-size: 0.75rem; padding: 8px 10px; }

/* --- top app bar: now just the account cluster (brand + nav moved into
   the sidebar) --- */
.dash-topbar {
  background: var(--db-surface);
  border-bottom: 1px solid var(--db-border);
  position: sticky;
  top: 0;
  z-index: 40;
}
.dash-topbar-inner {
  padding: 0 20px;
  display: flex;
  align-items: center;
  gap: 24px;
  min-height: 60px;
}

.account-cluster { display: flex; align-items: center; gap: 10px; padding: 10px 0; }
.account-menu { position: relative; }
.account-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--db-surface-2);
  border: 1px solid var(--db-border);
  border-radius: 999px;
  padding: 6px 10px 6px 14px;
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--db-ink);
}
.account-trigger:hover { background: #EEF1F8; }
.account-trigger .who { color: var(--db-ink-dim); }
.account-trigger .who strong { color: var(--db-ink); }
.account-trigger .chevron { color: var(--db-ink-dim); font-size: 0.7rem; transition: transform 0.15s; }
.account-menu.open .chevron { transform: rotate(180deg); }

.account-dropdown {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  background: var(--db-surface);
  border: 1px solid var(--db-border);
  border-radius: 10px;
  box-shadow: 0 8px 24px -8px rgba(27, 35, 51, 0.18);
  padding: 8px;
  min-width: 180px;
  z-index: 50;
}
.account-dropdown[hidden] { display: none; }
.account-dropdown button { width: 100%; }

/* License status row inside the account dropdown (moved out of its own
   tab + top-bar badge, 2026-09-08) -- click opens the view/edit modal
   (openLicenseModal() in dashboard.js). */
.account-dropdown-license {
  display: flex;
  justify-content: center;
  background: transparent;
  border: none;
  padding: 6px 8px;
  margin-bottom: 6px;
  border-radius: 6px;
  cursor: pointer;
}
.account-dropdown-license:hover { background: var(--db-surface-2); }

/* --- KPI stat tiles (live-grid: Overview, campaign detail, license tab) ---
   Standardized 2026-10-12, replacing a 5-color rainbow that cycled a
   different accent onto every tile by position regardless of what the
   metric meant -- per the rebrand doc's "use color selectively for
   status rather than assigning a different accent to every metric"
   guidance. Every tile now gets the same treatment: one consistent
   royal-blue top border, standardized radius/padding. A tile can still
   be given real semantic color later (e.g. red when a rate is over
   target) by adding a class from dashboard.js, the same way
   .gauge-fill.over-target already does -- that's a deliberate choice by
   state, not a decorative default. */
body.dashboard-page .stat-tile {
  background: var(--db-surface);
  border: 1px solid var(--db-border);
  border-top: 3px solid var(--db-accent);
  border-radius: 12px;
  padding: 14px 16px;
  box-shadow: 0 1px 2px rgba(16, 26, 70, 0.04);
}
body.dashboard-page .live-grid { gap: 12px; }

/* --- badges, recolored for the light surface (status-palette based) --- */
body.dashboard-page .badge.unknown { background: var(--db-neutral-soft); color: var(--db-ink-dim); }
body.dashboard-page .badge.available,
body.dashboard-page .badge.registered { background: var(--db-ok-soft); color: #0F766E; }
body.dashboard-page .badge.paused,
body.dashboard-page .badge.connecting { background: var(--db-warn-soft); color: #B45309; }
body.dashboard-page .badge.logged_out { background: var(--db-neutral-soft); color: var(--db-ink-dim); }
body.dashboard-page .badge.failed { background: var(--db-err-soft); color: #B91C1C; }
body.dashboard-page .badge.running { background: var(--db-ok-soft); color: #0F766E; }
body.dashboard-page .badge.on_hold { background: var(--db-accent-soft); color: var(--db-accent-dim); }
body.dashboard-page .badge.stopped { background: var(--db-neutral-soft); color: var(--db-ink-dim); }

/* --- surfaces: tables, detail panel, gauge, modal, misc hardcoded hexes --- */
body.dashboard-page .table-wrap { background: var(--db-surface); border-color: var(--db-border); }
body.dashboard-page thead th { background: var(--db-surface-2); border-bottom-color: var(--db-border); }
body.dashboard-page tbody td { border-bottom-color: var(--db-border); }
body.dashboard-page tbody tr:hover { background: var(--db-surface-2); }

body.dashboard-page .detail-panel {
  background: var(--db-surface);
  border-color: var(--db-border);
  box-shadow: 0 1px 2px rgba(27, 35, 51, 0.04);
}

body.dashboard-page .gauge-track { background: var(--db-surface-2); border-color: var(--db-border); }

body.dashboard-page .chart-card {
  background: var(--db-surface);
  border-color: var(--db-border);
  box-shadow: 0 1px 2px rgba(27, 35, 51, 0.04);
}
body.dashboard-page .chart-tooltip { background: var(--db-surface); border-color: var(--db-border); box-shadow: 0 4px 12px -4px rgba(27, 35, 51, 0.18); }

body.dashboard-page .modal-backdrop { background: rgba(27, 35, 51, 0.35); }
body.dashboard-page .modal-panel.panel { background: var(--db-surface); border: 1px solid var(--db-border); box-shadow: 0 20px 48px -16px rgba(27, 35, 51, 0.28); }

body.dashboard-page .creds-box { background: var(--db-ok-soft); }
body.dashboard-page .creds-box code { background: var(--db-surface-2); color: var(--db-ink); }

body.dashboard-page .error-box { background: var(--db-err-soft); color: #8A1F1F; }

body.dashboard-page button.secondary { background: var(--db-surface-2); color: var(--db-ink); border: 1px solid var(--db-border); }
body.dashboard-page button.secondary:hover { background: #EEF1F8; }
body.dashboard-page button.danger:hover { background: #B91C1C; }
body.dashboard-page button:disabled { background: var(--db-neutral-soft); color: var(--db-ink-dim); }

/* Bug found live 2026-09-23: .account-dropdown-license (base rule, line
   ~883) only overrides `background`, not `color` -- the plain `button`
   rule's `color: white` (line ~79) was showing through on the light
   dashboard theme's own white/near-white dropdown surface. Invisible for
   the License row purely by accident (its content is a colored .badge
   pill, which supplies its own contrasting text color), but the new
   plain-text "My Profile" row (added 2026-09-23, requirements-doc item
   7e) had nothing to hide behind -- white-on-white, unreadable.
   `.account-dropdown-license` is only ever used inside dashboard.html's
   account dropdown (confirmed via grep -- softphone.html has no dropdown
   of its own), so this could have just as easily been fixed on the base
   rule instead; scoped under body.dashboard-page anyway to match where
   every other button-in-dashboard color override already lives, in case
   this class is ever reused somewhere else later. */
body.dashboard-page .account-dropdown-license { color: var(--db-ink); }

/* Section header rows (h2/h3 + one action button) shouldn't stretch that
   button across the whole row just because .row's "button{flex:1}" rule
   is written for multi-button action groups. Same fix for inline
   input+button rows (add caller ID, upload a lead file, assign an agent,
   save license fields) where the trailing button was inheriting flex:1
   and stretching to fill whatever space the fixed-width inputs left. */
.section-header-row button,
.inline-action-row button { flex: none; min-width: 100px; }

@media (max-width: 860px) {
  .overview-layout { grid-template-columns: 1fr; }
  .dash-topbar-inner { gap: 12px; }
  .account-trigger .who { display: none; }
}

/* --- narrow-viewport sidebar collapse (2026-09-08) ---
   Below 900px the left sidebar stops being a fixed-height side column
   (no room for it next to the main content) and becomes a normal
   top-of-page block instead: nav items wrap into a horizontal strip
   (same "wrap instead of squeeze" precedent the old mobile top-nav used),
   the Dialplan submenu drops onto its own full-width row when expanded,
   and the persistent Dialpad widget moves to the bottom, full width,
   rather than being pinned via margin-top:auto (there's no leftover
   vertical space to pin it against once the sidebar isn't full-height). */
@media (max-width: 900px) {
  .dash-shell { flex-direction: column; }
  .dash-sidebar {
    width: 100%;
    flex: none;
    min-height: 0;
    position: static;
    border-right: none;
    border-bottom: 1px solid var(--db-border);
  }
  .side-nav { flex-direction: row; flex-wrap: wrap; }
  .side-nav-group { flex: 0 0 100%; }
  .side-nav-submenu { flex-direction: row; flex-wrap: wrap; padding-left: 0; }
  .side-dialpad { margin-top: 0; }
}

/* ============ Agent softphone light theme (2026-10-09, recolored 2026-10-09) ============
   Same reskin approach as the dashboard's white theme above (reassign the
   shared base tokens, then override the handful of hardcoded dark hexes
   the base rules use), under its own --sp- (softphone) token namespace.

   UPDATE, 2026-10-12 Osprey rebrand: the paragraph below describes why
   this page was given its OWN teal accent, distinct from the
   dashboard's blue -- that decision is now reversed. The rebrand's
   whole premise is one brand color across every page, so --sp-accent is
   back to the same royal blue as --db-accent/the login page, and teal
   is reserved purely for "available/success" meaning (see
   button#btn-available and the badge rules below, both explicit rather
   than accent-driven). Left the original reasoning in place underneath
   for history, since it explains why this page has its own --sp-*
   namespace at all, even though the specific "different from blue on
   purpose" conclusion no longer holds.

   Original (2026-10-09) reasoning: the dashboard's --db-accent and this
   page's original --sp-accent were both the same brand blue (#4C6FFF)
   as the Osprey logo at the time. The user asked for the agent page's
   light chrome to get a genuinely different color scheme rather than
   align with that blue, so this page ran its own teal accent instead of
   reusing the brand blue. Everything else (surfaces, borders, ink, the
   ok/warn/err semantic colors) was unchanged from the original
   light-chrome pass so the two pages still read as the same product,
   just with a distinct accent on this one -- that structural point
   (same product, own --sp- namespace) still holds even though the
   accent itself no longer differs.

   Originally the dial pad / active-call UI (.phone-widget, .phone-key,
   .phone-display, .phone-call-screen, .phone-icon-btn,
   .phone-answer-btn, .phone-reject-btn, .phone-caller-id-input,
   .phone-transfer-panel and everything inside them) was deliberately
   left as the same dark "phone app" card it had always been, matching
   the admin dashboard's own embedded Dialpad widget (dash-sidebar's
   .phone-widget). By further explicit request (2026-10-09, follow-up),
   that dark card has now also been recolored light -- see the component
   rules themselves (near the top of this file) for the new light
   values; the !important flags that used to protect its hardcoded dark
   colors from the page-level light-theme selectors were removed at the
   same time, since both now agree on a light look. This applies to both
   places the component is used: this page's dial pad/call screen, and
   the dashboard sidebar's embedded Dialpad widget (dash-sidebar's
   .phone-widget) above. */

/* Osprey rebrand (2026-10-12): the softphone's own distinct teal accent
   (--sp-accent, set 2026-09-?? specifically to differ from the
   dashboard's blue) is retired here. The rebrand doc's whole point is
   ONE brand color across every page -- royal blue -- with teal demoted
   to a purely semantic "success/available" status color instead of a
   page identity. So --sp-accent now equals the same royal blue the
   login/dashboard pages use, and anything that still needs to read as
   "healthy/available" (the Go Available button, the available/
   registered badges) gets an explicit teal value instead of reading the
   page accent -- see button#btn-available below and the badge rules
   further down, both already explicit rather than accent-driven. */
body.softphone-page {
  --sp-bg: #F1F5F9;
  --sp-surface: #FFFFFF;
  --sp-surface-2: #F8FAFC;
  --sp-border: #DCE3ED;
  --sp-ink: #101A46;
  --sp-ink-dim: #475569;
  --sp-accent: #2457D6;
  --sp-accent-dim: #1D46B3;
  --sp-accent-soft: #E8EEFF;
  --sp-ok-soft: #CCFBF1;
  --sp-warn-soft: #FEF3C7;
  --sp-err-soft: #FEE2E2;
  --sp-neutral-soft: #E2E8F0;

  /* Reassign the base theme vars every shared component already reads. */
  --bg: var(--sp-bg);
  --panel: var(--sp-surface);
  --panel-border: var(--sp-border);
  --text: var(--sp-ink);
  --text-dim: var(--sp-ink-dim);
  --accent: var(--sp-accent);
  --accent-dim: var(--sp-accent-dim);
  --ok: #0F766E;
  --warn: #B45309;
  --err: #DC2626;
}

/* "Go Available" is a plain, class-less <button id="btn-available">, so
   it normally inherits the page's general button color -- which is now
   royal blue, the primary-action color, not a status color. The doc is
   explicit that this one should stay teal (button-success-bg) since it
   means "available/healthy", a different meaning from "primary action".
   Explicit override so it doesn't just silently follow the accent. */
body.softphone-page button#btn-available { background: #0F766E; }
body.softphone-page button#btn-available:hover { background: #0C5F58; }

/* "Log Out (queue)" sits directly next to Go Available (teal) and On
   Break (white/outline) -- the doc's reasoning is that a solid red
   button there reads as a THIRD prominent primary action, when it's
   really a lower-emphasis way out. Pale-red chip instead, scoped to
   just this button (not a blanket change to every .danger button --
   Reset greeting/Leave Bridge elsewhere on this page keep the normal
   solid-red treatment, since those aren't sitting in that same row). */
body.softphone-page button#btn-logged-out {
  background: #FEE2E2;
  color: #B91C1C;
}
body.softphone-page button#btn-logged-out:hover { background: #FECACA; }

body.softphone-page input[type="text"],
body.softphone-page input[type="password"],
body.softphone-page select { background: var(--sp-surface); }

/* --- badges (reg-badge, status-badge, voicemail-unheard-badge),
   recolored for the light surface -- same mapping as the dashboard's --- */
body.softphone-page .badge.unknown { background: var(--sp-neutral-soft); color: var(--sp-ink-dim); }
body.softphone-page .badge.available,
body.softphone-page .badge.registered { background: var(--sp-ok-soft); color: #0F766E; }
body.softphone-page .badge.paused,
body.softphone-page .badge.connecting { background: var(--sp-warn-soft); color: #B45309; }
body.softphone-page .badge.logged_out { background: var(--sp-neutral-soft); color: var(--sp-ink-dim); }
body.softphone-page .badge.failed { background: var(--sp-err-soft); color: #B91C1C; }
body.softphone-page .badge.running { background: var(--sp-ok-soft); color: #0F766E; }
body.softphone-page .badge.on_hold { background: var(--sp-accent-soft); color: var(--sp-accent-dim); }
body.softphone-page .badge.stopped { background: var(--sp-neutral-soft); color: var(--sp-ink-dim); }

/* --- tables (voicemail-table, contacts-table, my-calls-table) --- */
body.softphone-page .table-wrap { background: var(--sp-surface); border-color: var(--sp-border); }
body.softphone-page thead th { background: var(--sp-surface-2); border-bottom-color: var(--sp-border); }
body.softphone-page tbody td { border-bottom-color: var(--sp-border); }
body.softphone-page tbody tr:hover { background: var(--sp-surface-2); }

body.softphone-page .detail-panel {
  background: var(--sp-surface);
  border-color: var(--sp-border);
  box-shadow: 0 1px 2px rgba(27, 35, 51, 0.04);
}

body.softphone-page .gauge-track { background: var(--sp-surface-2); border-color: var(--sp-border); }

body.softphone-page .creds-box { background: var(--sp-ok-soft); }
body.softphone-page .creds-box code { background: var(--sp-surface-2); color: var(--sp-ink); }

body.softphone-page .error-box { background: var(--sp-err-soft); color: #8A1F1F; }

body.softphone-page button.secondary { background: var(--sp-surface-2); color: var(--sp-ink); border: 1px solid var(--sp-border); }
body.softphone-page button.secondary:hover { background: #EEF1F8; }
body.softphone-page button.danger:hover { background: #B91C1C; }
body.softphone-page button:disabled { background: var(--sp-neutral-soft); color: var(--sp-ink-dim); }

body.softphone-page .tab-btn:hover { background: var(--sp-surface-2); color: var(--sp-ink); }
body.softphone-page .tab-btn.active { background: var(--sp-border); color: var(--sp-ink); }

/* Top-bar icon buttons (see .topbar-icon-btn above) -- hover tint reads
   from --sp-accent-soft/--sp-accent-dim, so it followed automatically
   when the Osprey rebrand changed those from teal to royal blue. */
body.softphone-page .topbar-icon-btn:hover .circle { background: var(--sp-accent-soft); color: var(--sp-accent-dim); border-color: var(--sp-accent-soft); }
body.softphone-page .topbar-icon-btn .icon-badge-dot { background: var(--err); color: #fff; }
