/* Operator console — cellular call bridge.
   Control-room ink-teal with a single signal-amber accent; monospace is the
   hero voice because the data here (numbers, durations, CDRs) is equipment
   readout. Deliberately dark: this is a NOC console, not a marketing page. */

:root {
  --ink:    #0E1518;   /* control-room background        */
  --ink-2:  #0A1013;   /* deepest wells (inputs, chart)  */
  --panel:  #141E23;   /* raised surfaces                */
  --panel-2:#17242A;   /* hover / inset surfaces         */
  --line:   #22323A;   /* hairlines / borders            */
  --line-2: #2E434D;   /* stronger dividers, hovers      */
  --text:   #E6EEF0;
  --muted:  #7C9199;
  --faint:  #4E626B;

  --signal: #F4B740;   /* THE accent: active line / signal / amber phosphor */
  --signal-dim: #7a5f22;
  --live:   #35C08A;   /* connected / completed          */
  --drop:   #E5484D;   /* dropped / hang up              */
  --in:     #4CC9F0;   /* inbound direction              */

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

  --r: 10px;           /* radius */
  --gap: 18px;
}

* { box-sizing: border-box; }
/* A class that sets its own `display` (e.g. .topbar { display: flex }) beats
   the browser's default [hidden] rule — author styles win over the
   user-agent stylesheet regardless of selector specificity. Without this,
   toggling `.hidden = true` on an element that also carries such a class
   (like the login screen's .topbar) silently does nothing. */
[hidden] { display: none !important; }
html, body { height: 100%; }
body {
  margin: 0;
  background: radial-gradient(1200px 600px at 78% -8%, #16262d 0%, var(--ink) 55%);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }

/* ---- type helpers ---- */
.mono { font-family: var(--mono); }
.eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ---- info icon + tooltip ----
   A small (ⓘ) trigger next to a label/heading that reveals an explanatory
   sentence on hover, keyboard focus, or tap, instead of that sentence
   permanently taking up its own visible line under every control. CSS-only
   (:hover/:focus reveal a nested .tip) — no JS, and :focus (not just
   :focus-visible) means tapping on touch works too, with tapping elsewhere
   dismissing it for free since that blurs the button. */
.info-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border-radius: 50%; margin-left: 5px;
  border: 1px solid var(--line-2); background: transparent; color: var(--muted);
  font-family: var(--mono); font-size: 9px; line-height: 1; vertical-align: middle;
  cursor: help; flex: none; position: relative; padding: 0;
}
.info-icon:hover, .info-icon:focus { color: var(--signal); border-color: var(--signal-dim); outline: none; }
.info-icon .tip {
  position: absolute; left: 50%; bottom: calc(100% + 8px); transform: translateX(-50%);
  width: max-content; max-width: 260px;
  background: var(--panel-2); border: 1px solid var(--line-2); border-radius: 8px;
  color: var(--text); font-family: var(--sans); font-size: 12.5px; font-weight: 400;
  letter-spacing: normal; text-transform: none; line-height: 1.4;
  padding: 9px 11px; text-align: left;
  box-shadow: 0 8px 24px rgba(0,0,0,.4);
  opacity: 0; pointer-events: none; transition: opacity .1s;
  z-index: 20;
}
.info-icon:hover .tip, .info-icon:focus .tip { opacity: 1; }
/* Generic muted secondary text (hint lines, error text) — a base rule so it
   works everywhere it's used, not just nested under specific components
   (.tile .sub below adds its own smaller size for that one context). Before
   this rule existed, any bare `class="sub"` outside .tile — e.g. every login
   screen's "press Enter to sign in" hint and error line — silently rendered
   with no styling applied at all. */
.sub { color: var(--muted); font-size: 12.5px; }
.sub.err { color: var(--drop); }

/* ---- app shell ---- */
.app { display: grid; grid-template-columns: 232px 1fr; min-height: 100%; }

.rail {
  border-right: 1px solid var(--line);
  padding: 22px 18px;
  display: flex; flex-direction: column; gap: 26px;
  background: linear-gradient(180deg, rgba(255,255,255,.015), transparent);
  position: sticky; top: 0; height: 100vh;
}
.brand { display: flex; align-items: center; gap: 11px; }
.brand .glyph {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  border: 1px solid var(--signal-dim); border-radius: 9px;
  color: var(--signal);
  background: radial-gradient(circle at 50% 30%, rgba(244,183,64,.16), transparent 70%);
}
.brand .glyph img { width: 24px; height: 24px; object-fit: contain; }
.brand b { font-family: var(--mono); font-size: 14px; letter-spacing: .02em; }
.brand b .brand-lynx { color: var(--signal); }
.brand b .brand-project { color: var(--muted); }
.brand small { display: block; color: var(--faint); font-family: var(--mono); font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase; }

.nav { display: flex; flex-direction: column; gap: 3px; }
.nav a {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px; border-radius: 8px;
  color: var(--muted); font-family: var(--mono); font-size: 13px;
  border: 1px solid transparent;
}
.nav a:hover { color: var(--text); background: var(--panel); }
.nav a.active { color: var(--text); background: var(--panel); border-color: var(--line); }
.nav a.active .dot { background: var(--signal); box-shadow: 0 0 10px var(--signal); }
.nav .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--faint); flex: none; }

.rail .spacer { flex: 1; }
.rail-signout { margin-top: 10px; width: 100%; }

/* Capped and centered rather than stretching edge-to-edge — on a 14"
   laptop the content column is naturally close to this width already, but
   on a 27"+ display an uncapped 1fr column drags tiles/tables/the dialer
   row absurdly wide with everything inside them staying the same size, so
   it reads as "stretched out and small" instead of just having more room.
   Extra width beyond max-width becomes calm empty margin on both sides
   instead of stretching content. */
.main { padding: 30px 34px 60px; min-width: 0; max-width: 1400px; margin: 0 auto; }

/* Admin-triggered maintenance warning — pushed live over the same WS
   connection as call control, so it shows the moment it's announced. */
.maintenance-banner {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  background: rgba(244,183,64,.1); border: 1px solid var(--signal-dim);
  border-radius: var(--r); color: var(--signal);
  padding: 12px 16px; margin-bottom: 20px; font-family: var(--mono); font-size: 13px;
}
#maintenance-countdown { font-weight: 600; }
#maintenance-msg { color: var(--text); }

.topbar { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 26px; flex-wrap: wrap; }
.topbar h1 { font-family: var(--mono); font-size: 27px; font-weight: 700; letter-spacing: -.01em; margin: 4px 0 0; }
.topbar p { margin: 3px 0 0; color: var(--muted); font-size: 13px; }

/* Sign-in / password screens (admin panel, dashboard) — the rail is hidden
   entirely rather than just covered, so this centers in the full viewport,
   not just .main's content column. */
.center-screen {
  position: fixed; inset: 0; z-index: 40; background: var(--ink);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}
.center-screen .center-screen-inner { width: 100%; max-width: 480px; }
.center-screen .brand-logo-big {
  display: block; width: 100%; max-width: 200px; margin: 0 auto 22px;
  border: 1px solid var(--line); border-radius: var(--r);
}
.center-screen .topbar { justify-content: center; text-align: center; margin-bottom: 22px; }
/* Every login/password screen (dialer, dashboard, admin, manager) built the
   same form wrapper + text input from an identical inline style="..." block
   — one definition here instead of four copies that could quietly drift. */
.form-grid { padding: 18px; display: grid; gap: 12px; }
.field-input {
  width: 100%; background: var(--ink-2); border: 1px solid var(--line); border-radius: var(--r);
  color: var(--text); padding: 11px 14px; font-size: 16px; font-family: var(--mono);
}
.field-input:focus { border-color: var(--line-2); outline: none; }
.field-input::placeholder { color: var(--faint); }
/* Fallback native-select styling for .room-select — only ever visible for
   the instant before web/ui-select.js runs and hides the real <select>
   behind its own custom trigger+menu (see .ui-select below), or if that
   script somehow fails to load. */
select.room-select {
  appearance: none; -webkit-appearance: none;
  background-color: var(--ink-2);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6'><path d='M0 0 L5 6 L10 0 Z' fill='%23F4B740'/></svg>");
  background-repeat: no-repeat; background-position: right 12px center;
  border: 1px solid var(--line); border-radius: var(--r);
  color: var(--signal); padding: 6px 28px 6px 10px; font-size: 16px; margin-left: 6px;
  cursor: pointer; transition: border-color .12s;
}
select.room-select:hover { border-color: var(--line-2); }
select.room-select:focus { border-color: var(--signal-dim); outline: none; }
select.room-select option { background: var(--panel); color: var(--text); }

/* ---- custom dropdown menu (web/ui-select.js) ----
   Replaces a native <select>'s own rendering with a real popup menu; the
   <select> itself stays in the DOM (invisible) as the actual state. Base
   look here; .room-select/.admin-input on the SAME wrapper (see
   enhanceSelect's className copy) pick the per-context sizing below. */
.ui-select { position: relative; display: inline-block; }
.ui-select-trigger {
  display: inline-flex; align-items: center; gap: 8px; width: 100%;
  background: var(--ink-2); border: 1px solid var(--line); border-radius: var(--r);
  color: var(--text); font-family: var(--mono); font-size: 16px;
  padding: 10px 13px; cursor: pointer; transition: border-color .12s;
}
.ui-select-trigger:hover { border-color: var(--line-2); }
.ui-select-trigger.open, .ui-select-trigger:focus-visible { border-color: var(--signal-dim); outline: none; }
.ui-select-label { flex: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-select-arrow {
  width: 10px; height: 6px; flex: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6'><path d='M0 0 L5 6 L10 0 Z' fill='%237C9199'/></svg>");
  background-repeat: no-repeat; transition: transform .12s;
}
.ui-select-trigger.open .ui-select-arrow { transform: rotate(180deg); }
.ui-select-menu {
  position: absolute; top: calc(100% + 6px); left: 0; min-width: 100%;
  background: var(--panel-2); border: 1px solid var(--line-2); border-radius: var(--r);
  box-shadow: 0 14px 32px rgba(0,0,0,.5);
  padding: 5px; z-index: 30; max-height: 260px; overflow-y: auto;
}
.ui-select-option {
  padding: 8px 11px; border-radius: 7px; font-family: var(--mono); font-size: 14px;
  color: var(--text); cursor: pointer; white-space: nowrap;
}
.ui-select-option:hover, .ui-select-option.active { background: var(--panel); color: var(--signal); }
.ui-select-option.selected { color: var(--signal); font-weight: 600; }
.ui-select-option.selected::after { content: '✓'; float: right; margin-left: 14px; }

/* Compact amber pill variant — the room/line picker (dialer topbar+login
   screen, dashboard topbar), same footprint as the old native .room-select. */
.ui-select.room-select { display: inline-block; margin-left: 6px; }
.ui-select.room-select .ui-select-trigger {
  width: auto; padding: 6px 10px; color: var(--signal); border-radius: var(--r);
}
.ui-select.room-select .ui-select-menu { min-width: 140px; }
/* An explanatory line right under a section's <header> — was two subtly
   different inline paddings depending on which file it got copy-pasted
   into; one shared value now. */
.section-hint { margin: 0; padding: 12px 18px 16px; }

/* ---- connection pill ---- */
.pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 13px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel);
  font-family: var(--mono); font-size: 12px; color: var(--muted);
}
.pill-stack { display: flex; flex-direction: column; gap: 8px; }
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--faint); }
.pill.ok   { color: var(--text); }
.pill.ok   .dot { background: var(--live); box-shadow: 0 0 8px var(--live); }
.pill.busy .dot, .pill.busy { color: var(--signal); }
.pill.busy .dot { background: var(--signal); box-shadow: 0 0 8px var(--signal); animation: pulse 1.4s infinite; }
.pill.err  { color: var(--drop); border-color: #4a2224; }
.pill.err  .dot { background: var(--drop); }

/* ---- readout tiles ---- */
.readouts { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap); }
.tile {
  border: 1px solid var(--line); border-radius: var(--r);
  background: linear-gradient(180deg, var(--panel), var(--panel-2));
  padding: 16px 17px; position: relative; overflow: hidden;
}
.tile .label { display: flex; align-items: center; justify-content: space-between; }
.tile .value { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 32px; line-height: 1.1; margin-top: 12px; letter-spacing: -.02em; }
.tile .value .unit { font-size: 15px; color: var(--muted); margin-left: 3px; }
.tile .sub { color: var(--faint); font-family: var(--mono); font-size: 11.5px; margin-top: 7px; }
/* the signature tile — live talk-time glows amber */
.tile.signal { border-color: var(--signal-dim); }
.tile.signal::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: linear-gradient(var(--signal), transparent);
}
.tile.signal .value { color: var(--signal); }

/* ---- panels ---- */
.panel {
  border: 1px solid var(--line-2); border-radius: var(--r); background: var(--panel);
  box-shadow: 0 10px 24px -16px rgba(0,0,0,.6);
}
/* Header gets its own (slightly lighter) surface so a section reads as a
   distinct card at a glance, not just a hairline dividing one long column —
   this is the fix for panels looking flat/samey on large monitors. */
.panel > header {
  display: flex; align-items: center; justify-content: space-between; padding: 16px 18px;
  background: var(--panel-2); border-bottom: 1px solid var(--line-2);
}
/* Only the panel's own top header gets rounded corners to match the panel
   shape — sections like Tokens stack several <header>s as sub-dividers
   (Viewer links, Sender lines) further down, and those stay square. */
.panel > header:first-child { border-radius: calc(var(--r) - 1px) calc(var(--r) - 1px) 0 0; }
.panel > header h2 { font-family: var(--mono); font-size: 15px; font-weight: 700; letter-spacing: .03em; margin: 0; text-transform: uppercase; }
.grid-2 { display: grid; grid-template-columns: 1fr; gap: var(--gap); margin-top: var(--gap); }
/* Stacked top-level sections get their gap from adjacency, not a
   style="margin-top:var(--gap)" repeated on every single one (admin's page
   alone had it on 7 sections) — a section added later gets it for free. */
.panel + .panel { margin-top: var(--gap); }

/* ---- activity chart (SVG injected by JS) ---- */
.chart { padding: 12px 14px 6px; }
.chart svg { width: 100%; height: 150px; display: block; }
.chart .axis { fill: var(--faint); font-family: var(--mono); font-size: 9.5px; letter-spacing: .04em; }
/* Amber phosphor glow on the line itself — this chart is the one place the
   "signal" accent is the actual subject, not just a highlight color, so it
   gets a little more presence than a flat 2px stroke. */
.chart .sig-line {
  fill: none; stroke: var(--signal); stroke-width: 2.25; stroke-linejoin: round; stroke-linecap: round;
  filter: drop-shadow(0 0 5px rgba(244, 183, 64, .35));
}
.chart .sig-area { fill: url(#sigfill); }
.chart .sig-dot { fill: var(--signal); filter: drop-shadow(0 0 4px rgba(244, 183, 64, .6)); }
.chart .baseline { stroke: var(--line); stroke-width: 1; }
/* Faint horizontal rules at 25/50/75% height — a bare baseline alone gives
   no sense of scale partway up the chart when eyeballing a value. */
.chart .gridline { stroke: var(--line); stroke-width: 1; opacity: .55; }

/* ---- CDR ledger ---- */
.ledger-wrap { overflow-x: auto; }
table.ledger { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 13px; }
table.ledger th {
  text-align: left; padding: 11px 18px; color: var(--muted);
  font-weight: 500; font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
table.ledger td { padding: 12px 18px; border-bottom: 1px solid var(--line); white-space: nowrap; }
table.ledger tr:last-child td { border-bottom: none; }
table.ledger tbody tr:hover { background: var(--panel-2); }
.ledger .time { color: var(--muted); }
.ledger .number { color: var(--text); font-variant-numeric: tabular-nums; }
.ledger .dur { color: var(--text); font-variant-numeric: tabular-nums; }
.ledger .room { color: var(--faint); }

/* direction glyph */
.dir { display: inline-flex; align-items: center; gap: 7px; }
.dir .arrow { font-size: 13px; }
.dir.out .arrow { color: var(--signal); }
.dir.in  .arrow { color: var(--in); }

/* outcome badges */
.badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px; border-radius: 6px; font-size: 11px; border: 1px solid; }
.badge.completed { color: var(--live); border-color: #234a3c; background: rgba(53,192,138,.07); }
.badge.dropped   { color: var(--drop); border-color: #4a2224; background: rgba(229,72,77,.07); }
.badge.live      { color: var(--signal); border-color: var(--signal-dim); background: rgba(244,183,64,.08); }
.badge.live .d, .row.live .num-live { position: relative; }
.badge.live::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--signal); box-shadow: 0 0 8px var(--signal); animation: pulse 1.3s infinite; }

.empty { padding: 46px 18px; text-align: center; color: var(--muted); font-family: var(--mono); font-size: 13px; }
.empty b { color: var(--text); display: block; margin-bottom: 6px; }

/* ---- lines · audio health ---- */
.lines-panel { margin-top: var(--gap); }
.lines { display: grid; gap: 1px; background: var(--line); }
.line {
  display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: 14px;
  padding: 13px 18px; background: var(--panel);
}
.line-badge { width: 9px; height: 9px; border-radius: 50%; background: var(--faint); }
.line-badge.live     { background: var(--live); box-shadow: 0 0 9px var(--live); animation: pulse 1.6s infinite; }
.line-badge.degraded { background: var(--signal); box-shadow: 0 0 9px var(--signal); animation: pulse 1s infinite; }
.line-badge.offline  { background: var(--drop); }
.line-badge.idle     { background: var(--faint); }
.line-room { font-family: var(--mono); font-size: 13px; color: var(--text); letter-spacing: .02em; }
.line-state { font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.line-state.live { color: var(--live); }
.line-state.degraded { color: var(--signal); }
.line-state.offline { color: var(--drop); }
.line-rates { font-family: var(--mono); font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; display: flex; gap: 12px; align-items: center; }
.line-codec { color: var(--faint); padding-left: 12px; border-left: 1px solid var(--line-2); }
@media (max-width: 560px) {
  .line { grid-template-columns: auto 1fr auto; }
  .line-rates { display: none; }
}

/* ---- buttons ---- */
button { font-family: var(--sans); cursor: pointer; }
.btn {
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  border-radius: 9px; padding: 11px 16px; font-size: 14px; font-family: var(--mono);
  transition: border-color .12s, background .12s, transform .05s;
}
.btn:hover { border-color: var(--line-2); background: var(--panel-2); }
.btn:active { transform: translateY(1px); }
.btn.call   { background: var(--live); border-color: var(--live); color: #05130d; font-weight: 600; }
.btn.call:hover { background: #43d29a; }
.btn.hangup { background: transparent; border-color: #4a2224; color: var(--drop); }
.btn.hangup:hover { background: rgba(229,72,77,.1); }
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn:disabled:hover { border-color: var(--line); background: var(--panel); }
.btn.call:disabled:hover { background: var(--live); }

:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; border-radius: 6px; }

/* ---- dialer ---- */
.dialer-row { display: flex; gap: var(--gap); align-items: stretch; }
.dialer { flex: 0 1 400px; max-width: 400px; margin: 0; }
/* Stretched to the same height as .dialer by the flex row above, and
   scrolls internally rather than growing the page — a section, not a
   modal. Capped at 680px for the same reason .main itself is capped: a
   5-column CDR table (time/dir/number/duration/outcome) doesn't need much
   more than that to read comfortably, so past this width it's calm margin
   in .dialer-row rather than every column stretching out with mostly-empty
   padding — the same "stretched and sparse" look .main's own cap already
   fixes, just one level deeper, on a wide (27"+) monitor. */
.call-history { flex: 1 1 360px; max-width: 680px; min-width: 0; display: flex; flex-direction: column; margin: 0; position: relative; }
.call-history::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: linear-gradient(var(--signal), transparent);
  border-radius: var(--r) 0 0 var(--r);
}
.call-history .ledger-wrap.call-history-scroll { flex: 1; min-height: 0; overflow-y: auto; }
.call-history .number { display: flex; align-items: center; gap: 6px; }
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; padding: 0; border-radius: 6px;
  border: 1px solid transparent; background: transparent; color: var(--faint);
  transition: border-color .12s, background .12s, color .12s;
}
.icon-btn:hover { border-color: var(--line); background: var(--panel-2); color: var(--text); }
.icon-btn svg { width: 12px; height: 12px; }
.icon-btn.ok { color: var(--live); border-color: #234a3c; } /* brief copy-confirmation flash */
@media (max-width: 900px) {
  .dialer-row { flex-direction: column; }
  .dialer { flex: 1 1 auto; max-width: none; }
}
.readout-line {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--ink-2); padding: 18px 20px; margin-bottom: 18px;
}
.readout-line .digits {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 30px; letter-spacing: .04em; min-height: 38px; word-break: break-all;
  color: var(--signal); text-shadow: 0 0 18px rgba(244,183,64,.25);
}
.readout-line .digits:empty::before { content: "—"; color: var(--faint); text-shadow: none; }
.readout-line .caption { display: flex; justify-content: space-between; margin-top: 8px; }
.keypad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.keypad button {
  aspect-ratio: 1.7 / 1; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--panel); color: var(--text);
  font-family: var(--mono); font-size: 22px; display: grid; place-items: center;
  transition: border-color .1s, background .1s, transform .04s;
}
.keypad button .sub { font-size: 9px; color: var(--faint); letter-spacing: .18em; margin-top: 2px; }
.keypad button:hover { border-color: var(--line-2); background: var(--panel-2); }
.keypad button:active,
.keypad button.flash { transform: translateY(1px); border-color: var(--signal-dim); background: var(--panel-2); }
.actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 14px; }
.actions .full { grid-column: 1 / -1; }

/* ---- sms compose ---- */
.sms { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line); display: grid; gap: 10px; }
.sms label { display: flex; justify-content: space-between; }
.sms textarea {
  width: 100%; resize: vertical; min-height: 62px;
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--ink-2); color: var(--text);
  font-family: inherit; font-size: 16px; line-height: 1.5; padding: 12px 14px;
}
.sms textarea::placeholder { color: var(--faint); }
.sms textarea:focus { border-color: var(--line-2); }

/* ---- responsive ----
   Below 760px the sidebar rail collapses into a sticky top bar: brand row,
   then the nav as a horizontally-scrolling strip of pills (rather than
   wrapping vertically) so a longer nav — admin's 6 sections vs. the
   dialer/dashboard's 2 — stays a single compact row instead of pushing
   page content down a variable amount. Sticky so jumping between anchor
   sections on a long page (admin) never means scrolling back to the top
   first. */
@media (max-width: 760px) {
  .app { grid-template-columns: 1fr; }
  .rail {
    position: sticky; top: 0; z-index: 30; height: auto;
    padding: 14px 16px; gap: 12px;
    background: var(--ink);
    border-right: none; border-bottom: 1px solid var(--line);
  }
  .rail .spacer { display: none; }
  .nav {
    flex-direction: row; flex-wrap: nowrap; overflow-x: auto;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
    margin: 0 -16px; padding: 0 16px 2px;
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { flex: none; padding: 10px 13px; }
  .main { padding: 20px 16px 50px; }
  .readouts { grid-template-columns: repeat(2, 1fr); }
  table.ledger th, table.ledger td { padding: 10px 12px; }
  /* Headings were a single fixed desktop size (22px) with no mobile step
     down at all — on a narrow phone that reads disproportionately large
     next to everything else on the page, not just "big text". */
  .topbar h1 { font-size: 22px; }
  .panel > header h2 { font-size: 14px; }
}

@media (max-width: 420px) {
  .readouts { grid-template-columns: 1fr; }
  .topbar h1 { font-size: 19px; }
}

@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; } .btn, .keypad button { transition: none; } }
