/* Converse Studio — the back-office workspace. Its own system, shared with no other page:
   IBM Plex Sans, dense tables, quiet chrome, brand navy and flame. The lab pages keep lab.css. */

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap');

/* Brand theme: the deep navy carries the interface, the flame orange is spent sparingly —
   an accent used everywhere is an accent used nowhere. Palette from the brand, no logo art. */
:root{
  --ink:#1A1F2B; --muted:#5B6373; --faint:#8A92A3; --line:#E3E7EE; --hair:#EEF1F5;
  --bg:#F5F7FA; --card:#FFFFFF; --accent:#1B4272; --accent-ink:#132F53; --accent-soft:#E9EFF7;
  --flame:#F4791F; --flame-soft:#FDEEDF;
  --ok:#16A34A; --ok-soft:#EAF7EF; --warn:#B45309; --warn-soft:#FEF3E2;
  --bad:#DC2626; --bad-soft:#FDECEC; --mono:'IBM Plex Mono',ui-monospace,monospace;
}
*{box-sizing:border-box;margin:0}
html,body{height:100%}
body{font:13.5px/1.55 'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
     color:var(--ink);background:var(--bg)}
a{color:var(--accent);text-decoration:none} a:hover{color:var(--accent-ink)}
::placeholder{color:var(--faint)}

/* ---------------------------------------------------------------- frame */
.frame{display:grid;grid-template-columns:232px 1fr;min-height:100vh}
.side{background:var(--card);border-right:1px solid var(--line);padding:14px 10px 12px;
      display:flex;flex-direction:column;gap:2px;position:sticky;top:0;height:100vh;overflow-y:auto}
.main{min-width:0;display:flex;flex-direction:column}

.ws{display:flex;align-items:center;gap:10px;padding:6px 10px 14px}
.ws-mark{width:30px;height:30px;border-radius:8px;background:var(--accent);color:#fff;
         display:flex;align-items:center;justify-content:center;font-weight:700;font-size:14px}
.ws-name{display:flex;flex-direction:column;line-height:1.25}
.ws-name b{font-size:13.5px;font-weight:600}
.ws-name span{font-size:11px;color:var(--faint)}
.ws-dot{color:var(--flame);font-weight:700}
/* The one flame inside the instructions card (P5-01): "instructions changed -- N things". A button that
   reads as a line, because it is a note about the text above it, not a second call to action. */
.flame-note{background:none;border:0;padding:4px 0;margin-top:8px;color:var(--flame);font-weight:600;cursor:pointer;text-align:left}
.flame-note:hover{text-decoration:underline}
/* One change in the wizard's "what the edit changed" sheet. NOT .plan-card: that is Billing's plan
   picker further down, and while this card shared the name the later rule gave it 18px padding, a
   12px radius and a flex column. */
.wiz-plan-card{border:1px solid var(--line);border-radius:8px;padding:10px 12px;margin-top:8px;background:var(--card)}
.wiz-plan-card .glyph{display:inline-block;width:18px;font-weight:700}

.sect{font-size:10.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;
      color:var(--faint);padding:14px 10px 5px}
.nav-i{display:flex;align-items:center;gap:9px;padding:7px 10px;border-radius:7px;color:var(--ink);
       font-size:13px;cursor:pointer;border:0;background:none;width:100%;text-align:left}
.nav-i:hover{background:var(--hair);color:var(--ink)}
.nav-i.on{background:var(--accent-soft);color:var(--accent-ink);font-weight:600}
.nav-i svg{flex:none;color:var(--muted)} .nav-i.on svg{color:var(--accent-ink)}
.nav-i .soon{margin-left:auto;font-size:9.5px;font-weight:600;letter-spacing:.05em;color:var(--faint);
             border:1px solid var(--line);border-radius:5px;padding:1px 5px}
.side-foot{margin-top:auto;padding:10px;border-top:1px solid var(--hair);font-size:11.5px;color:var(--muted)}

/* ---------------------------------------------------------------- topbar */
.top{display:flex;align-items:center;gap:14px;padding:14px 28px;background:var(--card);
     border-bottom:1px solid var(--line);position:sticky;top:0;z-index:10}
.top h1{font-size:16px;font-weight:600;letter-spacing:-.01em}
.crumb{font-size:12px;color:var(--faint)}
.top .grow{flex:1}

.content{padding:22px 28px 60px;max-width:1180px;width:100%}
.content.wide{max-width:none}

/* ---------------------------------------------------------------- controls */
button,.btn{font:inherit;font-size:12.5px;font-weight:600;border-radius:8px;padding:8px 14px;
       border:1px solid var(--accent);background:var(--accent);color:#fff;cursor:pointer;
       display:inline-flex;align-items:center;gap:7px}
button:hover,.btn:hover{background:var(--accent-ink);border-color:var(--accent-ink);color:#fff}
button.ghost{background:var(--card);color:var(--ink);border-color:var(--line)}
button.ghost:hover{background:var(--hair);color:var(--ink)}
button.quiet{background:none;border:0;color:var(--accent);padding:4px 6px}
button.quiet:hover{background:var(--accent-soft);color:var(--accent-ink)}
button.danger-q{background:none;border:0;color:var(--bad);padding:4px 6px}
button.danger-q:hover{background:var(--bad-soft);color:var(--bad)}
button:disabled{opacity:.45;cursor:not-allowed}

input[type=text],input[type=number],input[type=search],select,textarea{
  font:inherit;font-size:13px;padding:8px 11px;border:1px solid var(--line);border-radius:8px;
  background:var(--card);color:var(--ink);width:100%}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
textarea{min-height:84px;resize:vertical;line-height:1.5}
input[type=range]{width:100%;accent-color:var(--accent)}

.f{display:flex;flex-direction:column;gap:5px;min-width:0}
.f>label{font-size:12px;font-weight:600;color:var(--ink)}
.help{font-size:11.5px;color:var(--faint);line-height:1.5}
.grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:16px}
.wide-f{grid-column:1/-1}

.sw{display:flex;align-items:center;gap:9px;font-size:13px;cursor:pointer}
.sw input{width:auto;accent-color:var(--accent)}

/* ---------------------------------------------------------------- surfaces */
.card{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:20px;
      box-shadow:0 1px 2px rgba(16,24,40,.04)}
.card+.card{margin-top:16px}
.card h2{font-size:14.5px;font-weight:600;margin-bottom:2px}
.card .sub{font-size:12px;color:var(--muted);line-height:1.55;max-width:88ch;margin-bottom:12px}
.card h3{font-size:12.5px;font-weight:600;margin:0 0 8px}

.tile{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:16px 18px}
.tile .v{font-size:24px;font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.tile .k{font-size:11.5px;color:var(--muted);margin-top:2px}
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:14px}

.banner{display:flex;align-items:center;gap:12px;border:1px solid var(--line);background:var(--card);
        border-radius:10px;padding:12px 16px;font-size:12.5px;color:var(--muted)}
.banner.warn{background:var(--warn-soft);border-color:#F3DDB8;color:var(--warn)}
.banner.bad{background:var(--bad-soft);border-color:#F5C6C2;color:var(--bad)}
.banner.accent{background:var(--accent-soft);border-color:#C6D4E6;color:var(--accent-ink)}

/* ---------------------------------------------------------------- data */
table.data{width:100%;border-collapse:collapse;font-size:13px}
.data th{text-align:left;font-size:10.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
         color:var(--faint);padding:0 14px 9px 0;border-bottom:1px solid var(--line)}
.data td{padding:11px 14px 11px 0;border-bottom:1px solid var(--hair);vertical-align:middle}
.data tr:last-child td{border-bottom:0}
.data tr.rowlink{cursor:pointer} .data tr.rowlink:hover td{background:var(--hair)}

.pill{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;
      padding:2px 9px;border-radius:999px;white-space:nowrap}
.pill.ok{background:var(--ok-soft);color:var(--ok)}
.pill.warn{background:var(--warn-soft);color:var(--warn)}
.pill.bad{background:var(--bad-soft);color:var(--bad)}
.pill.mute{background:var(--hair);color:var(--muted)}
.pill.accent{background:var(--accent-soft);color:var(--accent-ink)}

.avatar{width:32px;height:32px;border-radius:8px;color:#fff;font-size:13px;font-weight:700;
        display:flex;align-items:center;justify-content:center;flex:none}

.kbd,code{font-family:var(--mono);font-size:12px;background:var(--hair);padding:1px 6px;border-radius:5px}
pre.code{font-family:var(--mono);font-size:12px;background:#12203A;color:#D9DFEA;border-radius:10px;
         padding:16px 18px;overflow-x:auto;line-height:1.6}

/* ---------------------------------------------------------------- tabs & segments */
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);margin-bottom:18px}
.tabs button{background:none;border:0;border-bottom:2px solid transparent;border-radius:0;
             color:var(--muted);font-size:13px;font-weight:500;padding:9px 14px}
.tabs button:hover{background:none;color:var(--ink)}
.tabs button.on{color:var(--accent-ink);border-bottom-color:var(--flame);font-weight:600}

.seg{display:inline-flex;border:1px solid var(--line);border-radius:8px;overflow:hidden;background:var(--card)}
.seg button{border:0;border-radius:0;background:var(--card);color:var(--muted);font-size:12px;padding:6px 13px}
.seg button:hover{background:var(--hair);color:var(--ink)}
.seg button.on{background:var(--accent);color:#fff}

.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{font-size:11.5px;padding:4px 10px;border-radius:999px;background:var(--hair);color:var(--muted);
      border:1px solid transparent;cursor:default}
.chip.pick{cursor:pointer;background:var(--card);border-color:var(--line)}
.chip.pick:hover{border-color:var(--accent);color:var(--accent-ink)}
.chip.on{background:var(--accent);color:#fff}
.chip.tok{font-family:var(--mono);font-size:11px;background:var(--accent-soft);color:var(--accent-ink);cursor:pointer}

/* ---------------------------------------------------------------- builder specifics */
.rec{border:1px solid var(--line);border-radius:9px;padding:14px 16px;background:#FBFCFD;margin-top:10px}
.rec-h{display:flex;align-items:center;gap:9px;margin-bottom:4px}
.rec-h strong{font-size:13px;font-weight:600}
.rec .grid2{margin-top:8px}
/* ListEditor's two compact shapes (14 Sep 2026). dense: the fields are the row, so a variable
   is one line and not a boxed card that repeats its own name. collapsible: a summary line with
   the badges, opening to the grid; a closed row costs one line. Nothing new in colour. */
.rec.dense{display:flex;align-items:center;gap:6px;padding:7px 8px 7px 12px;margin-top:6px}
.rec.dense .rec-line{display:flex;flex:1;gap:10px;align-items:center;min-width:0}
.rec.dense .rec-line .f{flex:1;min-width:0}
.rec.dense .rec-line input,.rec.dense .rec-line select{width:100%;box-sizing:border-box;padding:7px 10px}
.rec.dense .rec-line .f>label{display:none}
.rec.dense .rec-line .help{display:none}
.rec.dense .pill,.rec.dense .mono{margin-right:4px}
.dense-head{display:flex;gap:10px;padding:0 8px 0 12px;margin-top:12px}
.dense-head span{flex:1;font-size:10.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--faint)}
.dense-head .ctl{flex:none;width:109px}
.rec.shut{padding-top:9px;padding-bottom:9px}
.rec.shut .rec-h{margin-bottom:0}
.rec-h.tog{cursor:pointer;user-select:none}
.rec-h.tog .tw{color:var(--muted);width:10px;font-size:12px}
.rec-h.tog .pill{font-weight:500}
.rec-h.tog:hover strong{color:var(--accent-ink)}
/* One line of small controls inside an open row: a checkbox and two or three selects that
   would otherwise each take a grid cell and a label of their own. */
.opts{display:flex;flex-wrap:wrap;gap:8px 18px;align-items:center;font-size:13px}
.grid2 .opts select,.grid2 .opts input[type=number]{width:auto}
.opts .sw{font-size:13px}
.numbered{display:flex;align-items:center;gap:9px;font-size:13px;font-weight:600;margin:18px 0 8px}
.numbered .n{width:20px;height:20px;border-radius:50%;background:var(--ink);color:#fff;font-size:11px;
             display:flex;align-items:center;justify-content:center;flex:none}

/* the right-hand Test Agent panel */
.tester{position:fixed;top:0;right:0;width:420px;height:100vh;background:var(--card);
        border-left:1px solid var(--line);box-shadow:-8px 0 24px rgba(16,24,40,.08);z-index:40;
        display:flex;flex-direction:column;transform:translateX(100%);transition:transform .18s ease}
.tester.open{transform:none}
.tester-h{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--line)}
.tester-h b{font-size:14px}
.tester-body{flex:1;overflow-y:auto;padding:14px 16px;display:flex;flex-direction:column;gap:10px}
.tester-foot{border-top:1px solid var(--line);padding:12px 16px;display:flex;flex-direction:column;gap:9px}
.msg{max-width:85%;padding:8px 12px;border-radius:12px;font-size:13px;line-height:1.5}
.msg.agent{background:var(--hair);border-bottom-left-radius:4px;align-self:flex-start}
.msg.caller{background:var(--accent);color:#fff;border-bottom-right-radius:4px;align-self:flex-end}
.msg.sys{align-self:center;font-size:11px;color:var(--faint);background:none;padding:2px}

.spin{width:14px;height:14px;border:2px solid var(--flame-soft);border-top-color:var(--flame);
      border-radius:50%;animation:spin .8s linear infinite;display:inline-block;vertical-align:-2px}
@keyframes spin{to{transform:rotate(360deg)}}

.toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:var(--ink);color:#fff;
       font-size:12.5px;padding:9px 16px;border-radius:8px;z-index:60;opacity:0;transition:opacity .15s}
.toast.show{opacity:1}

/* The narrow-window shell lives at the END of this file ("the shell on a narrow window"), because
   the sharpened pass below re-states .frame and .content and would otherwise win. What used to be
   here was a 960px collapse that had been dead for exactly that reason — .frame{1fr} written
   before .frame{224px 1fr}, so the sidebar kept its column at every width and main was left with
   151px on a phone. Only the panel that has nowhere else to go stays. */
@media(max-width:960px){
  .tester{width:100vw}
}

/* ---- Platform: workspace switcher, user menu, login (fork additions) ---- */
.wsw{position:relative}
.wsw-btn{display:flex;align-items:center;gap:8px;background:var(--card);color:var(--ink);
  border:1px solid var(--line);border-radius:8px;padding:6px 12px;font-size:13px;font-weight:600}
.wsw-btn:hover{background:var(--hair);color:var(--ink);border-color:var(--line)}
.wsw-dot{width:8px;height:8px;border-radius:50%;background:var(--accent)}
.wsw-caret{color:var(--faint);font-size:11px}
.wsw-menu,.usr-menu{position:absolute;right:0;top:calc(100% + 6px);background:var(--card);
  border:1px solid var(--line);border-radius:10px;box-shadow:0 12px 30px rgba(20,30,50,.14);
  min-width:230px;padding:6px;z-index:50}
.wsw-item{display:flex;flex-direction:column;align-items:flex-start;gap:1px;width:100%;
  background:none;border:0;color:var(--ink);text-align:left;padding:8px 10px;border-radius:7px}
.wsw-item:hover{background:var(--hair);color:var(--ink)}
.wsw-item.on{background:var(--accent-soft)}
.wsw-item b{font-size:13px}
.wsw-item span{font-size:11.5px;color:var(--muted)}
.wsw-add{color:var(--accent);font-weight:600;border-top:1px solid var(--hair);margin-top:4px;border-radius:0 0 7px 7px}
.usr{position:relative}
.usr-btn{width:34px;height:34px;border-radius:50%;background:var(--accent);color:#fff;
  border:0;font-size:12px;font-weight:700;padding:0}
.usr-head{font-weight:700;font-size:13px;padding:8px 10px 2px}
.usr-sub{font-size:11.5px;color:var(--muted);padding:0 10px 8px;border-bottom:1px solid var(--hair)}
.usr-item{display:block;width:100%;background:none;border:0;color:var(--ink);text-align:left;
  padding:8px 10px;border-radius:7px;font-size:13px}
.usr-item:hover{background:var(--hair);color:var(--ink)}
.role-pill{display:inline-block;font-size:11px;font-weight:600;padding:1px 8px;border-radius:20px;
  background:var(--accent-soft);color:var(--accent-ink)}
.role-super{background:#F3E3C4;color:#8A5A12}
.role-owner{background:#E4EEDD;color:#3B6B2C}

/* Login */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;background:var(--bg);padding:24px}
.login-card{background:var(--card);border:1px solid var(--line);border-radius:16px;
  box-shadow:0 20px 50px rgba(20,30,50,.10);width:100%;max-width:400px;padding:34px}
.login-mark{display:flex;align-items:center;gap:11px;margin-bottom:24px}
.login-mark .m{width:38px;height:38px;border-radius:10px;background:var(--accent);color:#fff;
  display:flex;align-items:center;justify-content:center;font-weight:700;font-size:19px}
.login-mark b{font-size:17px}
.login-mark .ws-dot{color:var(--accent)}
.login-card label{display:block;font-size:12.5px;font-weight:600;color:var(--muted);margin:14px 0 5px}
.login-card input{width:100%;box-sizing:border-box;padding:11px 12px;border:1px solid var(--line);
  border-radius:9px;font-size:14px;background:var(--card);color:var(--ink)}
.login-card input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.login-card .btn{width:100%;justify-content:center;margin-top:20px;padding:11px}
.login-err{background:#FBE9E9;color:#9B2C2C;border:1px solid #F3CFCF;border-radius:9px;
  padding:10px 12px;font-size:13px;margin-top:16px}
.login-note{font-size:12px;color:var(--faint);margin-top:18px;text-align:center;line-height:1.5}

/* ---- Premium console layer (fork) ---- */
/* Sidebar brand becomes an org identity block */
.side{background:linear-gradient(180deg,#fff,#FCFDFE)}
.ws{padding:8px 10px 16px;border-bottom:1px solid var(--hair);margin-bottom:6px}
.ws-mark{background:linear-gradient(135deg,var(--accent),#2D6FA8);box-shadow:0 2px 6px rgba(27,66,114,.28)}
.ws-name b{font-size:14px;letter-spacing:-.01em}
.ws-name span{font-size:11px;color:var(--muted);font-weight:500}

/* Topbar org > workspace context */
.ctx{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--muted);
  background:var(--hair);border-radius:8px;padding:5px 8px 5px 11px}
.ctx b{color:var(--ink);font-weight:600}
.ctx .sep{color:var(--faint)}
.top{gap:12px;box-shadow:0 1px 0 rgba(16,24,40,.03)}
.wsw-btn{box-shadow:0 1px 2px rgba(16,24,40,.05)}
.usr-btn{box-shadow:0 2px 6px rgba(27,66,114,.25)}

/* Dashboard hero */
.dash-hero{background:linear-gradient(120deg,var(--accent) 0%,#20548C 55%,#2D6FA8 100%);
  color:#fff;border-radius:16px;padding:26px 28px;box-shadow:0 10px 30px rgba(27,66,114,.22);
  position:relative;overflow:hidden}
.dash-hero::after{content:"";position:absolute;right:-40px;top:-40px;width:220px;height:220px;
  border-radius:50%;background:rgba(255,255,255,.06)}
.dash-hero .eyebrow{font-size:11px;letter-spacing:.1em;text-transform:uppercase;opacity:.75;font-weight:600}
.dash-hero h2{font-size:23px;font-weight:700;margin:6px 0 4px;letter-spacing:-.02em}
.dash-hero p{font-size:13px;opacity:.85;max-width:60ch;line-height:1.55}
.dash-hero .cta{display:flex;gap:10px;margin-top:18px;position:relative;z-index:1}
.dash-hero .cta a{background:#fff;color:var(--accent-ink);font-weight:600;font-size:12.5px;
  padding:9px 15px;border-radius:9px;display:inline-flex;align-items:center;gap:7px}
.dash-hero .cta a.outline{background:rgba(255,255,255,.12);color:#fff;border:1px solid rgba(255,255,255,.3)}
.dash-hero .cta a:hover{transform:translateY(-1px);transition:transform .12s}

/* Stat cards with an icon chip */
.stat{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:16px 18px;
  display:flex;align-items:center;gap:14px;box-shadow:0 1px 2px rgba(16,24,40,.04)}
.stat-i{width:40px;height:40px;border-radius:11px;background:var(--accent-soft);color:var(--accent-ink);
  display:flex;align-items:center;justify-content:center;flex:none}
.stat .v{font-size:22px;font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:-.01em;line-height:1}
.stat .k{font-size:11.5px;color:var(--muted);margin-top:3px}
.stats-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin:18px 0}

/* Channel toggle chips */
.chtog{display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;padding:3px 10px;
  border-radius:999px;border:1px solid var(--line);background:var(--card);color:var(--faint);cursor:pointer}
.chtog.on{background:var(--accent-soft);border-color:#C6D4E6;color:var(--accent-ink)}
.chtog:hover{border-color:var(--accent)}
.chtog .d{width:6px;height:6px;border-radius:50%;background:var(--faint)}
.chtog.on .d{background:var(--ok)}
.chset{display:inline-flex;gap:6px}

/* Section heading */
.sec-title{display:flex;align-items:center;gap:10px;margin:26px 0 12px}
.sec-title h2{font-size:15px;font-weight:600}
.sec-title .grow{flex:1}

/* ---- In-page dialogs (replacing native alert/confirm/prompt) ---- */
/* A MODAL TALLER THAN THE WINDOW MUST STILL BE READABLE. `align-items:center` with no overflow
   is the classic trap: the box grows past the top of the viewport, and the part above the centre
   line cannot be scrolled to at all. Anchoring to the start and letting the backdrop scroll,
   with `margin:auto` on the panel, centres what fits and scrolls what does not. */
.vlp-modal-back{position:fixed;inset:0;background:rgba(20,30,50,.38);display:flex;align-items:flex-start;
  justify-content:center;overflow-y:auto;overscroll-behavior:contain;
  z-index:200;padding:20px;animation:vlpfade .12s ease}
@keyframes vlpfade{from{opacity:0}to{opacity:1}}
.vlp-modal{background:var(--card);border-radius:14px;padding:24px;max-width:440px;width:100%;
  margin:auto;box-shadow:0 24px 60px rgba(20,30,50,.28)}
.vlp-modal h3{font-size:16px;font-weight:600;margin:0 0 8px}
.vlp-modal-msg{font-size:13.5px;color:var(--ink);line-height:1.55;margin:0}
.vlp-modal-label{display:block;font-size:12.5px;font-weight:600;color:var(--muted);margin:6px 0 6px}
.vlp-modal-input{width:100%;box-sizing:border-box;padding:10px 12px;border:1px solid var(--line);
  border-radius:9px;font-size:14px;background:var(--card);color:var(--ink)}
.vlp-modal-input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.vlp-modal textarea.vlp-modal-input{min-height:120px;resize:vertical;line-height:1.5}
.vlp-modal-row{display:flex;justify-content:flex-end;gap:8px;margin-top:18px}
.vlp-danger{background:var(--bad);border-color:var(--bad)}
.vlp-danger:hover{background:#b91c1c;border-color:#b91c1c}

/* ---- Blazor admin panel additions ---- */
.boot{padding:40px;color:var(--muted);font:14px/1.5 system-ui,-apple-system,Segoe UI,Roboto,sans-serif}
#blazor-error-ui{position:fixed;bottom:0;left:0;right:0;display:none;background:var(--bad-soft);
  color:var(--bad);padding:10px 16px;font-size:13px;box-shadow:0 -1px 6px rgba(0,0,0,.06);z-index:2000}
#blazor-error-ui .reload,#blazor-error-ui .dismiss{color:var(--bad);text-decoration:underline;cursor:pointer;margin-left:10px}
td.num{text-align:right;font-variant-numeric:tabular-nums;color:var(--muted)}
td.mute{color:var(--muted)}
.topbar{display:flex;align-items:center;gap:12px;padding:16px 26px;border-bottom:1px solid var(--line);background:var(--card)}
.topbar h1{font-size:16px;font-weight:600}
.topbar .crumb{font-size:11px;color:var(--faint);text-transform:uppercase;letter-spacing:.06em}
.topbar .grow{flex:1}
.content{padding:22px 26px;overflow:auto}
.flabel{display:block;font-size:12px;font-weight:600;color:var(--muted);margin-bottom:5px}
.grid2 input{width:100%;box-sizing:border-box;padding:9px 10px;border:1px solid var(--line);border-radius:8px;font-size:13px;background:var(--card);color:var(--ink)}
/* Login */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}
.login-card{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:30px;max-width:380px;width:100%;box-shadow:0 12px 40px rgba(20,30,50,.08)}
.login-card .brand{display:flex;align-items:center;gap:10px;margin-bottom:22px}
.login-card input{width:100%;box-sizing:border-box;padding:11px 12px;border:1px solid var(--line);border-radius:9px;font-size:14px;margin-bottom:14px;background:var(--card);color:var(--ink)}
.login-card label{display:block;font-size:12px;font-weight:600;color:var(--muted);margin-bottom:6px}
.login-note{font-size:11.5px;color:var(--faint);line-height:1.5;margin-top:16px;text-align:center}
.secret-code{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:18px;background:var(--accent-soft);color:var(--accent-ink);border-radius:9px;padding:14px;margin-top:14px;text-align:center;letter-spacing:1px;user-select:all}

/* ---- Roles matrix + API key scopes ---- */
.table-scroll{overflow-x:auto}
table.matrix th.rolehead{min-width:112px;text-align:center;vertical-align:bottom}
table.matrix th.rolehead .help{font-weight:400;text-transform:none;letter-spacing:0;margin-top:2px}
table.matrix td.cell{text-align:center;vertical-align:middle}
table.matrix tr.grouprow td{background:var(--hair);font-size:10.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);padding:6px 14px 6px 0}
.mono{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11px}
.scopes{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px 20px;margin-top:8px}
.scopegroup .sect{margin-bottom:6px}
.scope{display:flex;gap:8px;align-items:center;font-size:13px;padding:3px 0}

/* ==== Blazor port: Knowledge base ==== */
/* Knowledge base - retrieval-preview hits (ported from wwwroot/app/knowledge.html; td.mute already exists) */
.kbhit{border-left:3px solid var(--accent);background:var(--hair);border-radius:8px;padding:11px 14px;margin-bottom:8px}
.kbhit-t{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:11.5px;font-weight:600;color:var(--accent);margin-bottom:4px}
.kbhit-s{font-weight:500;color:var(--faint);font-variant-numeric:tabular-nums}
.kbhit-x{font-size:12.5px;line-height:1.5;color:var(--ink);white-space:pre-wrap}

/* ==== Blazor port: Inbound calls ==== */
code.inline{font-size:11.5px;word-break:break-all}
.media-url{font-family:var(--mono);font-size:12.5px;background:var(--accent-soft);color:var(--accent-ink);border-radius:9px;padding:12px 14px;margin-top:14px;word-break:break-all;line-height:1.5;user-select:all}

/* ==== Blazor port: Outbound calls ==== */
.grid2 select{width:100%;box-sizing:border-box}

/* ==== Blazor port: Call logs ==== */
/* ---- Call logs: transcript viewer ---- */
/* THE CALL DRAWER: a document with two jobs - what was said, and what came of it.
   One column each, side by side, each scrolling on its own inside a dialog of fixed height. The
   conversation is on the LEFT and first because it is what somebody opens a call to read; it
   used to sit at the bottom under five cards, inside a 50vh box that scrolled separately from
   the dialog around it, which is two scrollbars for one document. */
.vlp-modal.call-modal{max-width:1120px;width:100%;height:min(88vh,940px);
  display:flex;flex-direction:column;padding:0;overflow:hidden}
.call-head{flex:none;display:flex;align-items:flex-start;gap:10px;
  background:var(--card);padding:15px 20px 12px;
  border-radius:14px 14px 0 0;border-bottom:1px solid var(--line)}
.call-head .call-id{min-width:0}
.call-head h3{margin:0 0 3px;line-height:1.4}
.call-head .sub{margin:0;font-size:11.5px;max-width:none}
.call-head .grow{flex:1}
.call-head .call-x{font-size:15px;line-height:1;padding:4px 8px;color:var(--muted);flex:none}
.call-head .call-x:hover{color:var(--ink);background:var(--hair)}

.call-body{flex:1;min-height:0;display:grid;grid-template-columns:minmax(0,1.06fr) minmax(0,.94fr)}
.call-left{min-height:0;overflow-y:auto;padding:14px 18px 20px;border-right:1px solid var(--line)}
.call-right{min-height:0;overflow-y:auto;padding:14px 18px 20px;background:var(--hair)}
.call-right>.card{background:var(--card)}
.call-right .clog-facts{background:var(--card)}
.call-right table.data{background:var(--card);border-radius:8px}

.call-rec{margin-bottom:14px}
.call-rec audio{width:100%;height:34px;display:block}

.ctr-head{display:flex;align-items:center;gap:8px;margin-bottom:11px;
  font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.ctr-head .grow{flex:1}
.ctr-head .help{text-transform:none;letter-spacing:0;font-weight:400}
.ctr-head button.quiet{text-transform:none;letter-spacing:0;font-size:11.5px;font-weight:600}

/* Turns as sides of a conversation, not rows of a table: who spoke is the first thing the eye
   needs and a 56-pixel label column made every line start in the same place. */
.ctr{display:flex;flex-direction:column;gap:11px}
.ctr-turn{max-width:86%}
.ctr-turn.agent{align-self:flex-start}
.ctr-turn.caller{align-self:flex-end}
.ctr-turn.caller .ctr-who{text-align:right}
.ctr-who{font-size:9.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  margin-bottom:3px;color:var(--accent)}
.ctr-turn.caller .ctr-who{color:var(--flame)}
.ctr-who .n{font-weight:500;color:var(--faint);margin-left:5px}
.ctr-text{font-size:13px;line-height:1.6;padding:9px 13px;border-radius:12px;
  background:var(--card);border:1px solid var(--line)}
.ctr-turn.agent .ctr-text{border-bottom-left-radius:4px}
.ctr-turn.caller .ctr-text{border-bottom-right-radius:4px;background:var(--accent-soft);
  border-color:color-mix(in srgb,var(--accent) 20%,transparent)}
.ctr-turn.system{align-self:center;max-width:100%}
.ctr-turn.system .ctr-text{background:none;border:0;color:var(--faint);font-style:italic;
  font-size:11.5px;padding:2px;text-align:center}

/* Narrow: one column, the conversation still first, the dialog scrolling once. */
@media (max-width:1000px){
  .vlp-modal.call-modal{height:min(92vh,940px)}
  .call-body{grid-template-columns:1fr;overflow-y:auto}
  .call-left,.call-right{overflow:visible;border-right:0}
  .call-right{border-top:1px solid var(--line)}
  .ctr-turn{max-width:100%}
}
.transcript{margin-top:14px;max-height:50vh;overflow-y:auto;display:flex;flex-direction:column;gap:8px}
.trow{display:flex;gap:10px;align-items:baseline;font-size:13px}
.trow .who{font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;flex:none;width:56px}
.trow.agent .who{color:var(--accent)}
.trow.caller .who{color:var(--flame)}
.trow .txt{line-height:1.5}

/* ==== Blazor port: Agent analytics ==== */
/* ---- Agent analytics ---- */
.volchart{display:block;width:100%;height:224px;margin-top:14px;overflow:visible}
.volchart .grid{stroke:var(--hair);stroke-width:1;shape-rendering:crispEdges}
.volchart .base{stroke:var(--line);stroke-width:1;shape-rendering:crispEdges}
.volchart .axis{font-size:10px;fill:var(--faint);font-variant-numeric:tabular-nums}
.volchart .bar{fill:var(--accent)}
.volchart .bar.zero{fill:var(--line)}
.volchart .col:hover .bar{fill:var(--accent-ink)}
.volchart .val{font-size:10.5px;fill:var(--muted);font-variant-numeric:tabular-nums}
.volchart .lab{font-size:9.5px;fill:var(--faint)}
.donut{margin-top:14px}
.donut-bar{display:flex;height:14px;border-radius:99px;overflow:hidden;background:var(--hair)}
.donut-seg{height:100%}
.donut-legend{display:flex;flex-direction:column;gap:6px;margin-top:14px}
.donut-item{display:flex;align-items:center;gap:8px;font-size:12.5px}
.donut-dot{width:9px;height:9px;border-radius:50%;flex:none}
.donut-item b{margin-left:auto;font-variant-numeric:tabular-nums}

/* ==== Blazor port: Settings ==== */
/* ---- Organization settings ---- */
.setlist{margin-top:4px}
.setrow{display:grid;grid-template-columns:1fr 260px;gap:16px;align-items:start;padding:16px 0;border-top:1px solid var(--hair)}
.setlist .setrow:first-child{border-top:0}
.toggle-col{display:flex;flex-direction:column;gap:10px}
.toggle-col .sw{justify-content:flex-start}
.sw.off{color:var(--muted);cursor:not-allowed}
.swatch-row{display:flex;align-items:center;gap:8px}
.swatch{flex:none;width:18px;height:18px;border-radius:5px;border:1px solid var(--line)}
@media (max-width:720px){.setrow{grid-template-columns:1fr}}

/* ==== Blazor port: Billing & usage ==== */
/* ---- Billing & usage (ported from the inline styles of wwwroot/app/billing.html) ---- */
.plan-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
.plan-name{font-size:22px;font-weight:700;letter-spacing:-.01em;margin-top:2px}
.plan-price{font-size:16px;font-weight:600;color:var(--accent)}
.meters{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px;margin:20px 0 14px}
/* Each usage meter's box is .usage-meter, NOT .meter: .meter is the 6px progress track further
   down (Compliance, Home, Analytics, Monitor), and while this box shared the name the track's
   height:6px + overflow:hidden clipped every Billing meter to a sliver. */
.usage-meter{min-width:0}
.meter-top{display:flex;justify-content:space-between;font-size:12px;margin-bottom:5px}
.meter-k{color:var(--muted)} .meter-v{font-weight:600;font-variant-numeric:tabular-nums}
.meter-bar{height:7px;background:var(--hair);border-radius:99px;overflow:hidden}
.meter-fill{height:100%;background:var(--accent);border-radius:99px;transition:width .3s}
.meter-fill.warn{background:var(--warn)} .meter-fill.hot{background:var(--bad)}
.meter-note{font-size:10.5px;color:var(--faint)}
.feat-row{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.plan-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px}
.plan-card{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:18px;display:flex;flex-direction:column;gap:10px}
.plan-card.current{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}
.plan-card-name{font-size:15px;font-weight:700}
.plan-card-price{font-size:18px;font-weight:700;color:var(--accent)}
.plan-limits{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:4px;font-size:12px;color:var(--muted)}
.plan-limits li::before{content:"\2713  ";color:var(--ok);font-weight:700}
.plan-feats{display:flex;flex-wrap:wrap;gap:4px}
.feat-chip{font-size:10px;background:var(--hair);color:var(--muted);border-radius:5px;padding:1px 6px}
.plan-card button{margin-top:auto;justify-content:center}
.plan-current-badge{margin-top:auto;font-size:12px;font-weight:600;color:var(--accent);text-align:center;padding:8px;background:var(--accent-soft);border-radius:8px}
.plan-current-badge.pending{color:var(--warn);background:var(--warn-soft)}
.banner .grow{flex:1}
.banner a{font-weight:600}

/* ==== Blazor port: Compliance ==== */
/* Compliance: rate meters against a regulatory ceiling, and the dry-run verdict */
.meter{height:6px;border-radius:999px;background:var(--hair);overflow:hidden;margin-top:8px}
.meter>span{display:block;height:100%;border-radius:999px;background:var(--ok);transition:width .3s}
.meter>span.warn{background:var(--warn)}
.meter>span.bad{background:var(--bad)}
.tile .help{margin-top:6px}
.verdict{display:flex;align-items:flex-start;gap:12px;border:1px solid var(--line);border-radius:9px;padding:14px 16px;background:#FBFCFD;margin-top:14px}
.verdict .v{font-size:13px;font-weight:600;line-height:1.45}
.verdict .pill{flex:none;margin-top:1px}

/* ==== Blazor port: Campaigns ==== */
/* ---- Campaigns: per-contact progress bar (done / failed / skipped / in flight; remainder = waiting) ---- */
.prog{display:flex;height:8px;border-radius:4px;overflow:hidden;background:var(--hair);min-width:180px}
.prog i{display:block;height:100%;flex:none}
.prog .done{background:var(--ok)}
.prog .fail{background:var(--bad)}
.prog .skip{background:var(--warn)}
.prog .live{background:var(--accent)}
.prog-k{display:flex;flex-wrap:wrap;gap:4px 10px;margin-top:5px;font-size:11px;color:var(--faint);font-variant-numeric:tabular-nums;white-space:nowrap}
.prog-k b{font-weight:600;color:var(--muted)}

/* ==== Blazor port: Webhooks ==== */
/* ---- Webhooks page ---- */
.wh-url{word-break:break-all;max-width:44ch}
tr.wh-drawer>td{background:var(--hair);padding:12px 14px}
.wh-drawer-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.wh-drawer-head .wh-grow{flex:1}
tr.wh-drawer table.data{background:var(--card);border-radius:8px}
tr.wh-drawer table.data th,tr.wh-drawer table.data td{padding-left:10px}
.wh-events .scope{align-items:flex-start}
.wh-events .scope input{margin-top:3px}

/* ==== Blazor port: Agent builder ==== */
/* The five rules the vanilla agent.html kept in its own page-local <style>. Everything else on
   the builder is already above: cards, tabs, pills, rec, grid2, chips, seg, tester. */

/* The agent's name and purpose written straight into the page. A form field around them would
   make the title of the thing look like one of its settings. */
.name-in{font:inherit;font-size:18px;font-weight:600;border:0;border-bottom:1px dashed transparent;
         background:none;min-width:160px;max-width:420px;padding:2px 0;color:var(--ink)}
.name-in:hover,.name-in:focus{border-bottom-color:var(--line);outline:none}
.purpose-in{font:inherit;font-size:12px;color:var(--faint);border:0;background:none;width:100%;
            max-width:76ch;padding:0 0 10px}
.purpose-in:focus{outline:none;color:var(--muted)}

/* The version dropdown, anchored to its button so it travels with the header when the name wraps. */
.bd-scrim{position:fixed;inset:0;z-index:29}
.bd-menu{position:absolute;top:100%;left:0;margin-top:6px;background:var(--card);
         border:1px solid var(--line);border-radius:8px;box-shadow:0 8px 20px rgba(16,24,40,.12);
         z-index:30;min-width:340px;padding:8px;display:flex;flex-direction:column;gap:2px}

/* A test transcript as it streams. Capped and scrolling: a twelve-turn call otherwise pushes the
   verdicts — the part being waited for — off the bottom of the screen. */
.bd-log{border:1px solid var(--hair);border-radius:8px;padding:10px 12px;margin-top:8px;
        max-height:260px;overflow-y:auto;display:flex;flex-direction:column;gap:6px;background:#FBFCFD}
.bd-line{font-size:12.5px;line-height:1.5}
.bd-line b{font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--faint);margin-right:6px}
.bd-verdict{display:flex;gap:8px;align-items:flex-start;padding:7px 0;border-top:1px solid var(--hair);font-size:12.5px}

/* ==== Blazor port: phone number health ==== */
/* A rated row with nothing to compare against - the only number in the workspace, or the bucket
   of calls that recorded no caller ID. Grey, not green: it has not passed a check, it has not
   had one, and a green bar there reads as a verdict the data cannot support. */
.meter>span.mute{background:var(--faint)}

/* ==== Blazor port: the conversation funnel ==== */
/* Horizontal, not the usual tapering trapezoid. A trapezoid encodes the drop in an area nobody
   can read off the screen; bars on a shared baseline let an operator compare two steps by
   looking at where they end. Every bar is a percentage of ATTEMPTED, so the first is always
   full width and the shortening IS the loss. */
.funnel{display:flex;flex-direction:column;gap:14px;margin-top:6px}
.funnel-head{display:flex;align-items:baseline;gap:10px;font-size:12.5px;margin-bottom:5px}
.funnel-head .k{font-weight:600}
.funnel-head .v{margin-left:auto;font-size:16px;font-weight:700;font-variant-numeric:tabular-nums}
.funnel-head .p{color:var(--muted);font-variant-numeric:tabular-nums}
.funnel-track{height:22px;border-radius:6px;background:var(--hair);overflow:hidden}
.funnel-track>span{display:block;height:100%;border-radius:6px;background:var(--accent);transition:width .3s}
.funnel-track>span.mid{background:#2D6FA8}
.funnel-track>span.end{background:var(--ok)}
/* The step that is the point of the chart. A drop nobody looks at is a chart nobody needed. */
.funnel-step.key .funnel-head .v{color:var(--ok)}

/* ==== Phase 5: concurrency over time ==== */
/* Columns on a shared baseline, drawn with divs like every other chart in this panel — there is
   no charting package and there is not going to be one. Two bars per bucket, nested rather than
   side by side: the sampled figure is always inside the bucket's upper bound, and nesting shows
   that containment instead of inviting a reader to compare two independent series. */
.cc-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap;margin-bottom:6px}
.cc-head h2{margin:0}
.cc-controls{margin-left:auto;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.cc-plot{position:relative;display:flex;align-items:flex-end;gap:2px;height:180px;
         padding:10px 0 0;border-bottom:1px solid var(--line)}
.cc-col{position:relative;flex:1;min-width:3px;height:100%;display:flex;align-items:flex-end;justify-content:center}
/* The bucket's upper bound. Deliberately the paler of the two: it is the number that is allowed
   to be too high, so it must not be the one that shouts. */
.cc-outer{position:absolute;bottom:0;width:100%;background:var(--accent-soft);border-radius:3px 3px 0 0}
.cc-outer.hot{background:var(--bad-soft)}
/* The exact figure, drawn over it. */
.cc-inner{position:absolute;bottom:0;width:100%;background:var(--accent);border-radius:3px 3px 0 0}
.cc-cap{position:absolute;left:0;right:0;border-top:1px dashed var(--bad);pointer-events:none}
.cc-cap span{position:absolute;right:0;top:-16px;font-size:10.5px;font-weight:600;color:var(--bad);
             background:var(--card);padding:0 4px}
.cc-axis{display:flex;justify-content:space-between;font-size:10.5px;color:var(--faint);margin-top:6px}
.cc-axis-mid{color:var(--faint)}
.cc-legend{display:flex;flex-direction:column;gap:7px;margin-top:14px}
.cc-key{display:flex;align-items:baseline;gap:8px;font-size:11.5px;color:var(--faint);line-height:1.5}
.cc-key b{color:var(--ink);font-size:12px}
.cc-key i{width:12px;height:12px;border-radius:3px;flex:0 0 auto;position:relative;top:2px}
.cc-sw-inner{background:var(--accent)}
.cc-sw-outer{background:var(--accent-soft)}
.cc-caveats{margin-top:14px;font-size:11.5px;color:var(--faint)}
.cc-caveats summary{cursor:pointer;color:var(--muted);font-size:12px}
.cc-caveats ul{margin:8px 0 0;padding-left:18px;line-height:1.6}
.cc-caveats li{margin-bottom:5px}

/* ==== Phase 5: the do-not-call screen ==== */
/* A masked number is the content of the whole table, so it is set in the mono face at a size a
   reader can compare two of at a glance — the last four digits are the only part that
   distinguishes two rows, and they must not be the smallest thing on the page. */
.dnc-num{font-family:var(--mono);font-size:12.5px;letter-spacing:.02em}
.dnc-revealed{background:var(--accent-soft);color:var(--accent-ink);border-radius:5px;padding:1px 6px}
.dnc-origins{display:flex;gap:8px;flex-wrap:wrap;margin:2px 0 14px}
.dnc-origin{border:1px solid var(--line);background:var(--card);border-radius:8px;padding:8px 12px;
            font-size:11.5px;color:var(--muted);cursor:pointer;text-align:left;min-width:150px}
.dnc-origin:hover{background:var(--hair)}
.dnc-origin.on{border-color:var(--accent);background:var(--accent-soft);color:var(--accent-ink)}
.dnc-origin b{display:block;font-size:16px;color:var(--ink);font-variant-numeric:tabular-nums}
.dnc-origin.on b{color:var(--accent-ink)}
.dnc-search{display:flex;gap:8px;align-items:flex-end;flex-wrap:wrap;margin-bottom:12px}
.dnc-search .grow{flex:1;min-width:240px}

/* ==== the Test agent panel ==== */
/* It reuses .tester, .tester-h, .tester-body, .tester-foot, .msg and .chip wholesale — it is the
   same drawer the assistant lives in and must not read as a different product. What is added here
   is the strip between the header and the transcript, which the assistant has no equivalent of:
   the panel has to say WHICH DOCUMENT it is about to run before it runs it, and that claim has to
   survive scrolling the conversation. Hence a fixed band rather than a first message. */
.tp-strip{display:flex;align-items:center;gap:8px;padding:9px 16px;border-bottom:1px solid var(--hair);
          background:var(--bg)}
.tp-note{padding:8px 16px;font-size:11.5px;color:var(--faint);line-height:1.5;
         border-bottom:1px solid var(--hair)}
.tp-note b{color:var(--ink)}
.tp-warn{background:var(--warn-soft);color:var(--warn)}
.tp-warn b{color:var(--warn)}
.tp-warn div + div{margin-top:5px}
/* What went wrong for the caller, inline in the conversation (Voice/CallQuality.cs): a system line
   that must be SEEN, so the warn tokens on the dim .msg.sys shape. And the small tag under an agent
   bubble the platform spoke because no model answered. */
.msg.sys.tp-quality{background:var(--warn-soft);color:var(--warn);padding:4px 10px;border-radius:8px;
                    font-size:11.5px;max-width:92%;text-align:center}
.tp-mark{display:block;margin-top:3px;font-size:10.5px;color:var(--faint);font-style:italic}

/* The leg switch sits in the foot, where .tabs' 18px bottom margin would leave a hole. */
.tp-tabs{margin-bottom:0}

/* Microphone level. Painted by wwwroot/js/voicebench.js rather than by Blazor: it moves four
   times a second and re-rendering the builder at that rate to set one width is not a trade worth
   making. */
.tp-level{height:5px;background:var(--hair);border-radius:3px;overflow:hidden}
.tp-level > div{height:100%;width:0;background:var(--ok);transition:width .08s linear}

/* Development quick-fill on the sign-in page. Only ever rendered when VOICELAB_DEV_LOGINS is set;
   styled as a visibly separate strip so nobody mistakes it for part of the product. */
.dev-fill { border: 1px dashed var(--line); border-radius: 8px; padding: 10px 12px; margin-bottom: 16px; }
.dev-fill-note { display: block; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--faint); margin-bottom: 8px; }
.dev-fill-row { display: flex; flex-wrap: wrap; gap: 6px; }
.dev-fill-chip { font-size: 12px; padding: 5px 10px; }

/* =====================================================================================
   Studio, sharpened. The console keeps its faces and its two colours and changes how
   they are spent: full-bleed layout, a right rail, denser tables, sparklines on tiles,
   counts in the sidebar, one rule for flame (it marks the live or primary thing and nothing
   else), a palette on Ctrl+K, and a dark theme cut from the same tokens.
   ===================================================================================== */

/* ---- tokens: the light set is the one above. --btn is the one colour that must stay dark
   enough to carry white text in BOTH themes, which --accent (also a link colour) cannot. ---- */
:root{--card-2:#FBFCFD; --btn:#1B4272; --btn-ink:#132F53; --flame-ink:#B4500A; color-scheme:light}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --ink:#E8ECF3; --muted:#A6AFBF; --faint:#7C8697; --line:#2A313D; --hair:#212730;
    --bg:#12161C; --card:#181D25; --card-2:#1D232C; --accent:#8AB4E8; --accent-ink:#B4CDF0; --accent-soft:#1F2C3F;
    --flame:#F79A4D; --flame-soft:#3A2712; --flame-ink:#F9B27A;
    --ok:#4CCB86; --ok-soft:#173225; --warn:#F0B35B; --warn-soft:#3A2A12; --bad:#FF7B7B; --bad-soft:#3D1D1D;
    --btn:#2F6DB5; --btn-ink:#3D7ECB; color-scheme:dark}
}
:root[data-theme="dark"]{
  --ink:#E8ECF3; --muted:#A6AFBF; --faint:#7C8697; --line:#2A313D; --hair:#212730;
  --bg:#12161C; --card:#181D25; --card-2:#1D232C; --accent:#8AB4E8; --accent-ink:#B4CDF0; --accent-soft:#1F2C3F;
  --flame:#F79A4D; --flame-soft:#3A2712; --flame-ink:#F9B27A;
  --ok:#4CCB86; --ok-soft:#173225; --warn:#F0B35B; --warn-soft:#3A2A12; --bad:#FF7B7B; --bad-soft:#3D1D1D;
  --btn:#2F6DB5; --btn-ink:#3D7ECB; color-scheme:dark}

/* Everything that painted a literal, re-pointed at a token so the dark set resolves as a set. */
button,.btn{background:var(--btn);border-color:var(--btn)}
button:hover,.btn:hover{background:var(--btn-ink);border-color:var(--btn-ink)}
button.ghost{background:var(--card);color:var(--ink);border-color:var(--line)}
button.ghost:hover{background:var(--hair);color:var(--ink);border-color:var(--line)}
button.quiet{background:none;border:0;color:var(--accent)}
button.quiet:hover{background:var(--accent-soft);color:var(--accent-ink)}
button.danger-q{background:none;border:0;color:var(--bad)}
button.danger-q:hover{background:var(--bad-soft);color:var(--bad)}
.seg button.on,.chip.on,.usr-btn,.msg.caller{background:var(--btn);color:#fff}
.ws-mark{background:linear-gradient(135deg,var(--btn),var(--btn-ink));box-shadow:none}
.side{background:var(--card)}
.rec,.verdict,.bd-log{background:var(--card-2)}
.role-super{background:var(--warn-soft);color:var(--warn)}
.role-owner{background:var(--ok-soft);color:var(--ok)}
.login-err{background:var(--bad-soft);color:var(--bad);border-color:var(--bad-soft)}
.banner.warn{border-color:color-mix(in srgb,var(--warn) 28%,transparent)}
.banner.bad{border-color:color-mix(in srgb,var(--bad) 28%,transparent)}
.banner.accent{border-color:color-mix(in srgb,var(--accent) 28%,transparent)}
.chtog.on{border-color:color-mix(in srgb,var(--accent) 35%,transparent)}
.card,.stat,.tile{box-shadow:none}
input[type=text],input[type=number],input[type=search],input[type=password],input[type=email],select,textarea{background:var(--card);color:var(--ink);border-color:var(--line)}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent-soft);border-color:var(--accent)}
.login-card{box-shadow:0 20px 50px rgba(0,0,0,.14)}
.vlp-modal,.wsw-menu,.usr-menu,.bd-menu{box-shadow:0 24px 60px rgba(0,0,0,.32)}
.tester{box-shadow:-8px 0 24px rgba(0,0,0,.18)}
.toast{background:var(--ink);color:var(--bg)}
.tp-strip{background:var(--bg)}

/* ---- frame: the width cap goes; the page is content plus an optional rail ---- */
.frame{grid-template-columns:224px 1fr}
.content{max-width:none;padding:20px 26px 64px}
.page{display:grid;grid-template-columns:minmax(0,1fr);align-items:start}
.page.with-rail{grid-template-columns:minmax(0,1fr) 272px}
.rail{position:sticky;top:57px;align-self:start;border-left:1px solid var(--line);background:var(--card);
      min-height:calc(100vh - 57px);padding:18px 18px 40px;display:flex;flex-direction:column;gap:6px}
.rail-h{font-size:10.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);margin-bottom:2px}
.rail-empty{font-size:12.5px;color:var(--muted)}
.chk{display:flex;gap:9px;align-items:flex-start;font-size:12.5px;line-height:1.4;color:var(--ink);
     padding:6px 8px;margin:0 -8px;border-radius:7px}
.chk:hover{background:var(--hair);color:var(--ink)}
.chk i{width:10px;height:10px;border-radius:50%;flex:none;margin-top:4px;background:var(--ok)}
.chk i.no{background:transparent;border:2px solid var(--flame)}
.chk i.info{background:var(--faint)}
.chk span{display:block;font-size:11.5px;color:var(--muted)}
@media(max-width:1180px){.page.with-rail{grid-template-columns:1fr}.rail{position:static;min-height:0;border-left:0;border-top:1px solid var(--line)}}

/* ---- sidebar counts ---- */
.nav-i .n{margin-left:auto;font-family:var(--mono);font-size:10.5px;color:var(--faint);white-space:nowrap}
.nav-i.on .n{color:var(--accent-ink)}
.nav-i .n.hot{color:var(--flame-ink);font-weight:500}
.nav-i .n.warn{color:var(--warn);font-weight:500}

/* ---- topbar: the palette button and the theme switch ---- */
.topbar{padding:12px 26px;position:sticky;top:0;z-index:10}
.topbar h1{font-size:16px;font-weight:600;letter-spacing:-.01em}
.kbtn{display:inline-flex;align-items:center;gap:8px;background:var(--hair);border:1px solid var(--line);color:var(--muted);
      border-radius:8px;padding:6px 8px 6px 10px;font-size:12px;font-weight:500;min-width:190px}
.kbtn:hover{background:var(--card);color:var(--ink);border-color:var(--line)}
.kbtn span{flex:1;text-align:left}
.kbtn kbd,.pal-in kbd{font-family:var(--mono);font-size:10px;border:1px solid var(--line);border-radius:4px;padding:1px 5px;
      color:var(--faint);background:var(--card)}
.theme-btn{width:32px;height:32px;padding:0;border-radius:8px;background:var(--card);border:1px solid var(--line);
      color:var(--muted);font-size:14px;justify-content:center}
.theme-btn:hover{background:var(--hair);color:var(--ink);border-color:var(--line)}
.topbar a.btn{color:#fff}

/* The row may wrap. On a wide window it never needs to, so nothing above moves; on a narrow one
   the actions drop to a second line instead of leaving the window. The palette button gives up
   its 190px floor at the same width -- a search box that will not shrink is what pushed the
   buttons off in the first place. */
.topbar{flex-wrap:wrap;row-gap:10px}
@media (max-width:900px){
  .topbar .kbtn{min-width:0}
  .topbar .grow{flex-basis:100%;height:0}
}

/* ---- the palette ---- */
.pal-back{position:fixed;inset:0;background:rgba(10,16,28,.42);z-index:300;display:flex;align-items:flex-start;
          justify-content:center;padding:12vh 20px 20px;animation:vlpfade .1s ease}
.pal{width:100%;max-width:560px;background:var(--card);border:1px solid var(--line);border-radius:12px;
     box-shadow:0 30px 80px rgba(0,0,0,.35);overflow:hidden}
.pal-in{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line);color:var(--faint)}
.pal-in input{flex:1;border:0;background:none;font:inherit;font-size:14px;color:var(--ink);padding:2px 0}
.pal-in input:focus{outline:none;border:0}
.pal-list{max-height:52vh;overflow-y:auto;padding:6px}
.pal-item{display:grid;grid-template-columns:96px 1fr;column-gap:12px;align-items:baseline;width:100%;text-align:left;
          background:none;border:0;border-radius:7px;padding:8px 10px;color:var(--ink);font-weight:500;font-size:13px}
.pal-item:hover,.pal-item.on{background:var(--accent-soft);color:var(--accent-ink)}
.pal-g{font-size:10.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--faint)}
.pal-s{grid-column:2;font-size:11.5px;font-weight:400;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pal-empty{padding:16px 12px;font-size:13px;color:var(--muted)}

/* ---- status: three shapes for three facts. Outcome is a pill; direction is a mono glyph;
   the live thing wears flame. ---- */
.dirx{font-family:var(--mono);font-size:11px;color:var(--muted);white-space:nowrap}
.pill.live{background:var(--flame-soft);color:var(--flame-ink)}
.pill.live::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--flame);display:inline-block}
.num-m{font-family:var(--mono);font-size:12px;color:var(--ink)}

/* ---- tables: denser, and numbers that line up ---- */
table.data{font-size:12.5px}
.data th{padding:0 12px 7px 0}
.data td{padding:8px 12px 8px 0}
.data td.mute{color:var(--muted)}

/* ---- tiles with a trend ---- */
.stats-row{grid-template-columns:repeat(auto-fit,minmax(168px,1fr));gap:12px;margin:0 0 18px}
.stat{display:block;padding:14px 16px 12px;border-radius:10px}
.stat .k{font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin:0}
.stat .v{font-size:24px;line-height:1.1;margin-top:6px;display:flex;align-items:baseline;gap:8px;white-space:nowrap}
.stat .v small{font-size:11.5px;font-weight:600;letter-spacing:0;color:var(--muted)}
.stat .v small.up{color:var(--ok)} .stat .v small.dn{color:var(--bad)}
.stat .spark{display:block;width:100%;height:24px;margin-top:8px;overflow:visible}
.stat .spark path{fill:none;stroke:var(--accent);stroke-width:1.5;stroke-linejoin:round;stroke-linecap:round;vector-effect:non-scaling-stroke}
.stat .spark .area{fill:var(--accent-soft);stroke:none}
.stat .spark circle{fill:var(--accent)}
.stat .meter{margin-top:10px}
.stat .sub{font-size:11.5px;color:var(--faint);margin-top:6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.stat.live{border-color:var(--flame);box-shadow:inset 3px 0 0 var(--flame)}
.stat.live .v{color:var(--flame-ink)}
.stat.live .v small{color:var(--flame-ink)}

.sec-title{margin:22px 0 10px}
.sec-title h2{font-size:14px}

@media(prefers-reduced-motion:reduce){.pal-back,.vlp-modal-back{animation:none}.tester{transition:none}}

/* The "+ New workspace" control is a link that happens to be a button: no fill, no border. */
.btn-link,.btn-link:hover{background:none;border:0;color:var(--accent);font-weight:600;padding:0}
.btn-link:hover{color:var(--accent-ink);text-decoration:underline}

/* The turn waterfall in the test panel. Ported from the vanilla bench: a 14px stacked bar whose
   segments are the four stages of one turn, so the eye lands on the widest one. */
.tp-wf { display: flex; gap: 2px; height: 14px; border-radius: 7px; overflow: hidden;
         background: var(--hair); margin-top: 6px; }
.tp-wf > div { height: 100%; min-width: 2px; }

/* =====================================================================================
   Managed voice: the flow screens (catalogue, packages, a package, a customer).
   A flash is the receipt for an action; a step rail says where in the sequence a
   person is; a drawer is the expanded row where the two-press actions live; a kv list
   is "what will be sent", shown before anything is.
   ===================================================================================== */

/* ---- aliases. Three pages were written against table and pill classes the stylesheet never
   defined (grid, pick, pill.good, banner.good), so their tables rendered with browser defaults
   and their "good" states carried no colour. Defined once here so those pages and the campaign
   wizard read the same as every other listing. ---- */
table.grid{width:100%;border-collapse:collapse;font-size:12.5px}
.grid th{text-align:left;font-size:10.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
         color:var(--faint);padding:0 12px 7px 0;border-bottom:1px solid var(--line)}
.grid td{padding:8px 12px 8px 0;border-bottom:1px solid var(--hair);vertical-align:middle}
.grid tr:last-child td{border-bottom:0}
.grid tr.pick,.data tr.pick{cursor:pointer}
.grid tr.pick:hover td,.data tr.pick:hover td{background:var(--hair)}
.data th.num,.grid th.num{text-align:right}
.data tr.open td,.grid tr.open td{background:var(--hair)}
.data tr.drawer-row td,.grid tr.drawer-row td{padding:0 0 10px;background:transparent}
.data tr.drawer-row:hover td{background:transparent}
.pill.good{background:var(--ok-soft);color:var(--ok)}
.pill.dim{background:var(--hair);color:var(--faint)}
.pill.draft{background:var(--warn-soft);color:var(--warn)}
.banner.good{background:var(--ok-soft);border-color:color-mix(in srgb,var(--ok) 28%,transparent);color:var(--ok)}
.banner>div{flex:1}

/* ---- the flash: one action's receipt ---- */
.flash{display:flex;align-items:flex-start;gap:12px;border:1px solid var(--line);border-radius:10px;
       padding:11px 14px;font-size:12.5px;background:var(--card);color:var(--ink);margin-bottom:14px;
       animation:vlpfade .12s ease}
.flash .flash-i{flex:none;width:20px;height:20px;border-radius:50%;display:flex;align-items:center;
                justify-content:center;font-size:11px;font-weight:700;margin-top:1px;background:var(--hair);color:var(--muted)}
.flash .flash-b{flex:1;line-height:1.5;min-width:0}
.flash .flash-b b{font-weight:600}
.flash .flash-b a{font-weight:600;white-space:nowrap}
.flash .flash-x{background:none;border:0;color:var(--faint);padding:0 4px;font-size:16px;line-height:1;flex:none}
.flash .flash-x:hover{color:var(--ink);background:none;border:0}
.flash.good{background:var(--ok-soft);border-color:color-mix(in srgb,var(--ok) 30%,transparent)}
.flash.good .flash-i{background:var(--ok);color:#fff}
.flash.accent{background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 28%,transparent)}
.flash.accent .flash-i{background:var(--btn);color:#fff}
.flash.warn{background:var(--warn-soft);border-color:color-mix(in srgb,var(--warn) 30%,transparent)}
.flash.warn .flash-i{background:var(--warn);color:#fff}
.flash.bad{background:var(--bad-soft);border-color:color-mix(in srgb,var(--bad) 30%,transparent)}
.flash.bad .flash-i{background:var(--bad);color:#fff}

/* ---- the step rail ---- */
.steps{list-style:none;padding:0;margin:0 0 16px;display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:8px}
.step{border:1px solid var(--line);border-radius:9px;background:var(--card);min-width:0}
.step-in{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;color:var(--ink);min-width:0}
a.step-in:hover,button.step-in:hover{background:var(--hair);color:var(--ink);border-radius:9px}
/* A rail step that JUMPS rather than links — a seven- or eight-step wizard lives on one page, so its rail
   cannot be anchors. Reset only what a <button> brings with it; every colour stays the div's. */
button.step-in{width:100%;text-align:left;background:none;border:0;font:inherit;cursor:pointer}
.step-n{flex:none;width:22px;height:22px;border-radius:50%;background:var(--hair);color:var(--muted);
        font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;margin-top:1px}
.step.done .step-n{background:var(--ok);color:#fff}
.step.current{border-color:var(--flame);box-shadow:inset 3px 0 0 var(--flame)}
.step.current .step-n{background:var(--flame);color:#fff}
.step.blocked .step-n{background:var(--warn-soft);color:var(--warn)}
.step.blocked{border-style:dashed}
.step-t{display:flex;flex-direction:column;gap:1px;min-width:0;line-height:1.35}
.step-t b{font-size:12.5px;font-weight:600}
.step-t span{font-size:11.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis}
.steps.vertical{grid-auto-flow:row;grid-auto-columns:auto;gap:0;margin:0 0 12px}
.steps.vertical .step{border:0;border-radius:0;background:none}
.steps.vertical .step.current{box-shadow:none;border-left:3px solid var(--flame)}
.steps.vertical .step-in{padding:7px 10px}
.steps.vertical .step+.step{border-top:1px solid var(--hair)}
@media(max-width:1100px){.steps{grid-auto-flow:row}}

/* ---- the drawer: an expanded row where the two-press actions live ---- */
.drawer{background:var(--card-2);border:1px solid var(--line);border-radius:10px;padding:16px 18px;margin:4px 0 6px}
.drawer h3{font-size:13px;font-weight:600;margin:0 0 3px}
.drawer .sub{font-size:12px;color:var(--muted);line-height:1.5;margin-bottom:10px}
.drawer .f+.f{margin-top:10px}
.drawer-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:22px}
.drawer-cols>div{min-width:0}

/* ---- "what will be sent": a fact list shown before a telephone rings ---- */
.kv{display:grid;grid-template-columns:max-content 1fr;gap:4px 16px;font-size:12.5px;margin:10px 0 0;
    padding:10px 12px;border:1px solid var(--line);border-radius:8px;background:var(--card)}
.kv dt{color:var(--muted);font-weight:500}
.kv dd{margin:0;font-variant-numeric:tabular-nums;min-width:0;word-break:break-word}
.kv dd code{font-size:11px}

/* ---- the page head of a package ---- */
.lead{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;flex-wrap:wrap}
.lead h2{margin:0;font-size:16px}
.lead .sub{margin:4px 0 0;max-width:none}
.lead .pills{display:flex;gap:6px;align-items:center;flex-wrap:wrap;flex:none}

/* ---- action rows and their reasons ---- */
.actions{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:14px}
.actions .why{font-size:12px;color:var(--muted)}
.unsaved{font-size:11px;font-weight:600;padding:2px 9px;border-radius:999px;background:var(--flame-soft);color:var(--flame-ink)}

/* ---- the three variable sources, as pills ---- */
.src{display:inline-flex;font-size:11px;font-weight:600;padding:2px 8px;border-radius:999px;white-space:nowrap}
.src.fixed{background:var(--accent-soft);color:var(--accent-ink)}
.src.contact{background:var(--ok-soft);color:var(--ok)}
.src.returned{background:var(--hair);color:var(--muted)}

/* ---- a radio row in a chooser table ---- */
.data tr.choice td:first-child,.grid tr.choice td:first-child{width:28px;padding-right:4px}
.data tr.choice.off{opacity:.55}
.data tr.choice input[type=radio]{accent-color:var(--btn)}

/* ---- inline definition: a label over a value, for read-only facts inside a form grid ---- */
.fact{display:flex;flex-direction:column;gap:3px;min-width:0}
.fact>label{font-size:12px;font-weight:600;color:var(--ink)}
.fact .v{font-size:13px;padding:8px 0;font-variant-numeric:tabular-nums}
.fact .v.big{font-size:15px;font-weight:600}

/* ==== Live calls: the floor and the monitor panel ==== */
.mon-grid{display:grid;grid-template-columns:minmax(0,2fr) minmax(280px,1fr);gap:16px}
@media (max-width:960px){.mon-grid{grid-template-columns:1fr}}
.mon-head{display:flex;flex-wrap:wrap;gap:8px 14px;align-items:center;margin-bottom:10px}
.mon-head .grow{flex:1}
.mon-lvl{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:4px 0 10px}
.mon-lvl .k{font-size:10.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:4px}
.mon-lvl .meter{margin-top:0}
.mon-lvl .meter>span{width:0;background:var(--flame);transition:width .08s linear}
.mon-lvl .agent .meter>span{background:var(--accent)}
.mon-lvl .human .meter>span{background:var(--ok)}
.mon-tx{max-height:58vh;margin-top:0}
.trow.system .who{color:var(--faint)} .trow.system .txt{color:var(--faint);font-style:italic}
.trow .cut{color:var(--warn);font-size:11px;margin-left:6px}
.mon-ctl .card{padding:14px 16px}
.mon-ctl .card+.card{margin-top:12px}
.mon-ctl textarea,.mon-ctl input{width:100%;box-sizing:border-box;padding:8px 10px;border:1px solid var(--line);border-radius:8px;font-size:13px;background:var(--card);color:var(--ink);margin-top:8px;font-family:inherit}
.mon-ctl .row{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}
/* No solid .pill.live here: the monitor marks its state with accent / human, and a second, global
   .pill.live written this late overrode the status vocabulary's flame-soft one on every page -- white
   text on solid flame, with the ::before dot the same flame and so invisible. */
.pill.human{background:var(--ok);color:#fff}
.state-dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--muted);margin-right:6px;vertical-align:middle}
.state-dot.speaking{background:var(--accent)} .state-dot.listening{background:var(--flame)} .state-dot.thinking{background:var(--warn)}
.state-dot.human{background:var(--ok)} .state-dot.ended,.state-dot.closing{background:var(--faint)}
.data tr.rowlink.on td{background:var(--accent-soft)}

/* ==== Agent insights ==== */
.ins-list{display:flex;flex-direction:column;gap:8px;margin-bottom:16px}
.ins{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;border:1px solid var(--line);border-radius:10px;background:var(--card);font-size:13px;line-height:1.5}
.ins.good{border-color:color-mix(in srgb,var(--ok) 45%,transparent)}
.ins.warn{border-color:color-mix(in srgb,var(--warn) 45%,transparent)}
.ins.bad{border-color:color-mix(in srgb,var(--bad) 45%,transparent)}
.ins .dot{width:8px;height:8px;border-radius:50%;flex:none;margin-top:7px;background:var(--muted)}
.ins.good .dot{background:var(--ok)} .ins.warn .dot{background:var(--warn)} .ins.bad .dot{background:var(--bad)}
.bars{display:flex;flex-direction:column;gap:6px}
.bars .b{display:grid;grid-template-columns:150px 1fr 90px;gap:10px;align-items:center;font-size:12px}
.bars .b .meter{margin-top:0}
.bars .b .num{text-align:right;font-variant-numeric:tabular-nums}
.hours{display:grid;grid-template-columns:repeat(24,1fr);gap:3px;margin-top:10px}
.hours .h{height:34px;border-radius:4px;background:var(--hair);position:relative}
.hours .h span{position:absolute;bottom:-16px;left:0;right:0;text-align:center;font-size:9px;color:var(--faint)}
.delta.up{color:var(--ok);font-weight:600} .delta.down{color:var(--bad);font-weight:600}
td.num.bad{color:var(--bad);font-weight:600} td.num.warn{color:var(--warn);font-weight:600}

/* ==== Call log: one block per call, not sixteen columns ====
   The table this replaces had grown a column per feature until the newest two — the cost and
   the AI summary — sat past the right edge of every screen it was opened on. A call is a
   record with a headline and a story, which is a list, not a spreadsheet: seven things on the
   row, one line of what the call was about underneath, everything else in the drawer. */
.clog-bar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:2px 0 14px}
.clog-bar .grow{flex:1}
.clog-search{flex:1 1 240px;min-width:200px;max-width:400px;box-sizing:border-box;padding:8px 12px;
  border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--ink);font-size:13px}
.clog-search::placeholder{color:var(--faint)}
.clog-search:focus{outline:none;border-color:var(--accent)}

.clog{border:1px solid var(--line);border-radius:10px;background:var(--card);overflow:hidden}
.clog-head,.clog-row{display:grid;
  grid-template-columns:76px minmax(132px,1.05fr) minmax(118px,.95fr) 118px 104px 68px 84px;
  gap:4px 12px;padding:9px 14px;align-items:start}
.clog-head{font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);background:var(--hair);border-bottom:1px solid var(--line)}
.clog-row{border-top:1px solid var(--line);cursor:pointer;font-size:12.5px;line-height:1.45}
.clog-head+.clog-row{border-top:0}
.clog-row:hover{background:var(--hair)}
.clog-head .r,.clog-row .r{text-align:right;font-variant-numeric:tabular-nums}
.clog-row .l2{display:block;font-size:10.5px;color:var(--faint);margin-top:2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.clog-row .c-num{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11.5px}
.clog-row .dirx{color:var(--muted);font-size:10.5px;margin-right:5px;white-space:nowrap}
.clog-row .pill{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* The summary spans the row. A sentence inside a 200-pixel column is a sentence nobody reads. */
.c-sum{grid-column:1/-1;margin-top:5px;padding-top:6px;border-top:1px dashed var(--line);
  font-size:12px;color:var(--muted);line-height:1.5}
.c-sum .next{color:var(--accent-ink);margin-left:6px}
.c-sum .waiting{color:var(--faint);font-size:11px}

/* Narrow: one header row cannot label two columns, so each cell carries its own label. Without
   them a bare "unpriced" under a bare "Neutral" is two facts with no questions attached. */
@media (max-width:1040px){
  .clog-head{display:none}
  .clog-row{grid-template-columns:repeat(2,minmax(0,1fr));padding:12px 14px;gap:10px 14px}
  .clog-head .r,.clog-row .r{text-align:left}
  .clog-row>div[data-k]::before{content:attr(data-k);display:block;margin-bottom:2px;
    font-size:9px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
}

/* The facts the row no longer spends a column on, in the drawer where there is room. */
.clog-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:10px 18px;
  margin:12px 0;padding:12px 14px;border:1px solid var(--line);border-radius:10px;background:var(--hair)}
.clog-facts .k{display:block;font-size:9.5px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.clog-facts .v{display:block;font-size:12.5px;margin-top:3px}
.clog-facts .v .help{display:block;margin-top:1px}

/* ==== Phone numbers: an inventory, and two ways to get one ====
   The page used to be four equal cards in one scroll: the inventory, a usually-empty Groups
   table, and — below both — the two acquisition forms, which look alike and do opposite things.
   One of them charges a carrier account every month; the other only writes a row. Weighting them
   the same, at the bottom, past a table of nothing, is where an expensive mistake gets made.
   Acquisition is now two buttons in the topbar that open panels, and the page is the inventory. */
.num-bar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:14px 0 12px}
.num-bar .grow{flex:1}
.num-search{flex:1 1 240px;min-width:200px;max-width:380px;box-sizing:border-box;padding:8px 12px;
  border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--ink);font-size:13px}
.num-search::placeholder{color:var(--faint)}
.num-search:focus{outline:none;border-color:var(--accent)}
.num-bar .seg button.empty{color:var(--faint)}
.num-group{padding:7px 10px;border:1px solid var(--line);border-radius:8px;
  background:var(--card);color:var(--ink);font-size:12.5px}

.numlist{border:1px solid var(--line);border-radius:10px;background:var(--card);overflow:hidden}
.numlist-head,.numlist-row{display:grid;
  grid-template-columns:minmax(180px,1.1fr) minmax(120px,1fr) minmax(120px,.9fr) 130px minmax(200px,auto);
  gap:6px 14px;padding:11px 14px;align-items:start}
.numlist-head{font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);background:var(--hair);border-bottom:1px solid var(--line)}
.numlist-row{border-top:1px solid var(--line);font-size:12.5px;line-height:1.45}
.numlist-head+.numlist-row{border-top:0}
.numlist-row:hover{background:var(--hair)}

/* The number is the row's name, so it is set like one: bigger, monospaced, and grouped. */
.num-e164{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:14px;font-weight:600;
  letter-spacing:.01em;color:var(--ink)}
.num-tags{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:4px;font-size:11px}
.num-tags .s{color:var(--muted)}
.num-tags .chip{padding:1px 7px;border-radius:99px;background:var(--accent-soft);
  color:var(--accent-ink);font-size:10.5px;font-weight:600}
.num-tags .dot{width:7px;height:7px;border-radius:50%;background:var(--muted);flex:none}
.num-tags .dot.ok{background:var(--ok)} .num-tags .dot.warn{background:var(--warn)}
.num-tags .dot.bad{background:var(--bad)} .num-tags .dot.mute{background:var(--faint)}
.numlist-row .l2{display:block;font-size:10.5px;color:var(--faint);margin-top:2px}
.numlist-row .l2.warnish{color:var(--warn)}
.num-idle{color:var(--faint)}
.num-acts{display:flex;gap:2px;flex-wrap:wrap;justify-content:flex-end}
.num-acts button{font-size:11.5px;padding:3px 7px}

.num-empty{text-align:left;max-width:60ch}

/* Groups is a tool, not a destination: folded away with its count on the summary line. */
.fold{padding:0;overflow:hidden}
.foldhead{display:flex;align-items:center;gap:10px;width:100%;padding:14px 20px;background:none;
  border:0;text-align:left;font-size:13px;color:var(--ink);cursor:pointer}
.foldhead:hover{background:var(--hair)}
.foldhead .tw{color:var(--muted);width:10px}
.foldhead .grow{flex:1}
.foldbody{padding:0 20px 18px;border-top:1px solid var(--line)}
.foldbody .sub{margin-top:12px}

@media (max-width:1080px){
  .numlist-head{display:none}
  .numlist-row{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 14px;padding:13px 14px}
  .numlist-row>div[data-k]::before{content:attr(data-k);display:block;margin-bottom:2px;
    font-size:9px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
  .num-acts{grid-column:1/-1;justify-content:flex-start}
}

/* ---- the rent panel: search, choose, review ---- */
.vlp-modal.rent-modal{max-width:720px;padding:0;display:flex;flex-direction:column;max-height:88vh}
.rent-head{display:flex;align-items:flex-start;gap:10px;padding:18px 22px 12px}
.rent-head h3{margin:0 0 3px}
.rent-head .sub{margin:0;font-size:12px}
.rent-head .grow{flex:1}
.rent-steps{display:flex;gap:0;padding:0 22px;border-bottom:1px solid var(--line)}
.rent-steps span{font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--faint);padding:0 14px 10px;border-bottom:2px solid transparent;margin-bottom:-1px}
.rent-steps span:first-child{padding-left:0}
.rent-steps span.on{color:var(--accent-ink);border-bottom-color:var(--accent)}
.rent-body{padding:18px 22px;overflow-y:auto;flex:1;min-height:0}
.rent-foot{display:flex;align-items:center;gap:8px;padding:14px 22px;border-top:1px solid var(--line);
  background:var(--hair)}
.rent-foot .grow{flex:1}

.stock{display:flex;flex-direction:column;gap:8px}
.stock-row{display:grid;grid-template-columns:1fr auto auto;gap:16px;align-items:center;
  padding:11px 14px;border:1px solid var(--line);border-radius:10px;background:var(--card)}
.stock-row:hover{border-color:var(--accent)}
.stock-row.held{opacity:.6}
.stock-row .l2{display:block;font-size:10.5px;color:var(--faint);margin-top:3px}
/* The price is the headline, and the monthly one is the headline of the price. */
.stock-price{text-align:right}
.stock-price .m{font-size:15px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--ink)}
.stock-price .m span{font-size:11px;font-weight:500;color:var(--muted);margin-left:2px}

.review{max-width:52ch}
.review-num{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:22px;font-weight:700;
  letter-spacing:.01em}
.review-cost{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:16px 0;
  padding:14px 16px;border:1px solid var(--line);border-radius:10px;background:var(--hair)}
.review-cost .k{display:block;font-size:9.5px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.review-cost .v{display:block;font-size:19px;font-weight:700;font-variant-numeric:tabular-nums;
  margin-top:3px}
.review-cost .l2{display:block;font-size:10.5px;color:var(--faint);margin-top:1px}
.review-facts{margin:0;padding-left:18px;font-size:12.5px;line-height:1.65;color:var(--muted)}
.review-facts b{color:var(--ink)}
.rent-from{padding:8px 0;font-size:13px;font-weight:600;color:var(--ink)}

/* Every stat tile names the window it measures. Five figures over five different spans - now,
   today, a fortnight, all time, the last day - were previously distinguishable only on two of
   them, so a reader compared numbers that were never comparable. Same type scale and the same
   muted token as the rest of the tile; this adds a word, not a colour. */
.stat .k .w{font-weight:500;color:var(--faint);margin-left:5px}
.stat .k .w::before{content:"· "}

/* ==== A long explanation, folded ==== */
/* Several screens open with five or six sentences of standing explanation. Every sentence is
   true and worth keeping, and together they push the controls they describe below the fold, so
   the page reads as a wall and the explanation gets skipped by the people who most needed it.
   The first two sentences stay in view; the rest goes behind a disclosure in the same paragraph.
   Nothing is deleted and nothing new is invented: any .sub may now carry a <details>, so this
   costs no class name and cannot drift out of step with the one it would have duplicated. */
.sub details{margin-top:7px}
.sub details>summary{cursor:pointer;color:var(--muted);font-weight:500;width:max-content;
  list-style:none;padding:1px 0}
.sub details>summary::-webkit-details-marker{display:none}
.sub details>summary::after{content:" \25B8";color:var(--faint);font-size:10px}
.sub details[open]>summary::after{content:" \25BE"}
.sub details>summary:hover{color:var(--ink)}
.sub details>div{margin-top:6px}

/* P3-02 — LiveTrace: what a long request is doing, one line per stage. Existing tokens only, so
   the dark block keeps working with no change; the host decides where it sits. */
.lt{display:flex;flex-direction:column;gap:2px;margin-top:8px;font-size:13px}
.lt-h{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--faint);margin-bottom:2px}
.lt-l{display:flex;justify-content:space-between;gap:12px;color:var(--faint)}
.lt-l b{font-family:var(--mono);font-variant-numeric:tabular-nums;font-weight:400}
.lt-l.now{color:var(--ink);font-weight:600}
.lt-l.near{color:var(--muted)}
.lt-l.bad{color:var(--warn);font-weight:600}

/* ================================================================ the shell on a narrow window */
/* 22 Sep 2026. Measured at 375x812 the frame was 375px wide, the sidebar kept its whole 224px
   column, and `main` was left with 151px — a card inside it was 99px across and a two-column
   .grid2 row ran to x=501 and was simply cut off, with no page scroll to reach it. The collapse
   that was meant to prevent this had been written EARLIER in the file than the sharpened pass's
   `.frame{224px 1fr}`, so it had never once applied. This block is last on purpose.
                                                                                                
   Below 720px — the breakpoint the settings rows above already use — the sidebar leaves the grid
   entirely and becomes a drawer over the page, opened by the Menu button AdminShell puts first in
   the topbar. `main` then has the full width, with a 16px gutter on both sides from the topbar
   down through the content and the rail. Nothing above 720px moves. */

/* Hidden by default and shown only in the drawer state, so a desk window renders exactly what it
   rendered before: no menu button, no scrim, one grid with two columns. */
.nav-btn{display:none}
.side-scrim{display:none}

@media (max-width:720px){
  .frame{grid-template-columns:minmax(0,1fr)}

  /* Off-canvas rather than merely narrow: `position:fixed` takes the rail out of the grid, so the
     single column is the whole window. `height:auto` is not decoration — the base rule sets
     `height:100vh`, which beats `bottom:0` and would leave the drawer short of the fold on a
     phone whose URL bar is showing. `visibility` is what keeps a shut drawer out of the tab
     order; a translated one is off the screen but still reachable by Tab, which is how a keyboard
     ends up typing into twenty-five links nobody can see. */
  .side{position:fixed;top:0;left:0;bottom:0;height:auto;width:min(288px,84vw);z-index:210;
        transform:translateX(-100%);visibility:hidden;
        transition:transform .18s ease,visibility 0s linear .18s;
        border-right:1px solid var(--line);overflow-y:auto;overscroll-behavior:contain}
  /* `visibility 0s` on the way IN and `0s linear .18s` on the way OUT, never a timed fade of it:
     visibility is a discrete property, so a transition on it still reads `hidden` at progress
     zero — which is the frame the shell focuses the drawer in, and a hidden element cannot take
     focus. Flipping it at once on open and holding it until the slide-out finishes gives both the
     animation and a drawer the keyboard can land in. */
  .side.open{transform:none;visibility:visible;transition:transform .18s ease,visibility 0s;
             box-shadow:14px 0 34px rgba(16,24,40,.22)}

  /* A button, not a styled div: the drawer must be dismissable by Enter as well as by a tap. */
  .side-scrim{display:block;position:fixed;inset:0;z-index:200;padding:0;border:0;border-radius:0;
              background:rgba(10,16,28,.42)}
  .side-scrim:hover{background:rgba(10,16,28,.42)}

  .nav-btn{display:inline-flex;align-items:center;justify-content:center;flex:none;
           width:32px;height:32px;padding:0;border-radius:8px;
           background:var(--card);border:1px solid var(--line);color:var(--muted)}
  .nav-btn:hover{background:var(--hair);color:var(--ink);border-color:var(--line)}

  /* The 16px gutter, every surface the page owns. */
  .topbar{padding:12px 16px;gap:10px}
  .content,.content.wide{padding:18px 16px 56px}
  .rail{padding:16px 16px 36px}

  /* The title shares its row with the menu button and must be allowed to shrink; without
     min-width:0 a long agent name holds the row open and pushes the button off the screen. */
  .topbar>div{min-width:0}
  .topbar h1{font-size:15px;overflow-wrap:anywhere}

  /* 20px of card padding on each side is 40px of a 343px line. The card keeps its shape and gives
     the form back the width. Wide tables need nothing here: `.table-scroll` already wraps them
     and is what keeps a 1030px roster off the page's own scrollbar. */
  .card{padding:16px}
  .tiles,.stats-row,.meters{grid-template-columns:repeat(auto-fit,minmax(min(100%,150px),1fr))}
  .grid2{grid-template-columns:minmax(0,1fr);gap:12px}

  /* A five-segment filter is wider than a phone, and `.seg` is `overflow:hidden` for its rounded
     ends — so the last segment was not narrow, it was gone. It scrolls inside its own pill now;
     the segment cut by the right edge is the only affordance such a control has ever needed. */
  .seg{max-width:100%;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}
  .seg::-webkit-scrollbar{display:none}
  .seg button{flex:none}

  .pal-back{padding:10vh 16px 16px}
  .vlp-modal-back{padding:16px}
}

/* The drawer slides; with the system asking for less motion it simply is or is not there. */
@media (prefers-reduced-motion:reduce){.side,.side.open{transition:none}}
