/* Dopamine Control — calm, neutral, status-driven. Color is reserved for status;
   the only loud objects are GO and Panic. */
:root {
  --bg: #f6f6f4;
  --surface: #ffffff;
  --surface-2: #f0f0ed;
  --hover: #f2f2ef;
  --sel-bg: #e9e9e5;
  --border: #e3e3df;
  --border-strong: #cfcfca;
  --text: #19191b;
  --text-2: #55555c;
  --text-3: #6e6e75;
  --ok: #18794a;
  --warn: #8f5c07;
  --crit: #b8322a;
  --ok-bg: #eaf5ef;
  --warn-bg: #fbf3e4;
  --crit-bg: #fbecea;
  --primary: #19191b;
  --primary-text: #ffffff;
  --panic: #b8322a;
  --panic-hover: #9e2a23;
  --focus: #19191b;
  --shadow: 0 2px 4px rgba(0,0,0,.04), 0 12px 28px rgba(0,0,0,.10);
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", "Helvetica Neue", system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, monospace;
  --fs-1: 12px;   /* meta */
  --fs-2: 13px;   /* secondary */
  --fs-3: 14px;   /* body */
  --fs-4: 16px;   /* names, titles */
  --fs-5: 22px;   /* headline */
  --ctl: 34px;    /* control height */
  --ctl-lg: 46px; /* GO / Panic */
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f0f10;
    --surface: #161617;
    --surface-2: #1d1d1f;
    --hover: #1b1b1d;
    --sel-bg: #26262b;
    --border: #2a2a2d;
    --border-strong: #3c3c41;
    --text: #ececed;
    --text-2: #a3a3aa;
    --text-3: #8a8a92;
    --ok: #3fbf7f;
    --warn: #e0a43a;
    --crit: #f0605a;
    --ok-bg: #12241a;
    --warn-bg: #2a2214;
    --crit-bg: #2c1716;
    --primary: #ececed;
    --primary-text: #111112;
    --panic: #c4302b;
    --panic-hover: #d63a34;
    --focus: #ececed;
    --shadow: 0 2px 4px rgba(0,0,0,.3), 0 14px 34px rgba(0,0,0,.5);
    color-scheme: dark;
  }
}
@media (max-width: 860px) {
  :root { --fs-2: 14px; --fs-3: 15px; --fs-4: 17px; --ctl: 40px; --ctl-lg: 48px; }
}

* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--text); font: var(--fs-3)/1.45 var(--font); -webkit-font-smoothing: antialiased; font-variant-numeric: tabular-nums; }
button, input, select { font: inherit; color: inherit; }
h1, h2, h3, h4, p { margin: 0; }
a { color: inherit; }
[hidden] { display: none !important; }
::selection { background: var(--text); color: var(--bg); }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 6px; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.mono { font-family: var(--mono); font-size: 0.92em; }
.muted { color: var(--text-2); }
.faint { color: var(--text-3); }
.wrap { max-width: 1180px; margin: 0 auto; padding: 0 24px; }
@media (max-width: 860px) { .wrap { padding: 0 16px; } }

/* ---------- buttons ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: var(--ctl); padding: 0 14px; border-radius: 7px; border: 1px solid var(--border); background: var(--surface); font-size: var(--fs-2); font-weight: 550; cursor: pointer; white-space: nowrap; text-decoration: none; transition: background .12s, border-color .12s, color .12s; }
.btn:hover { background: var(--hover); border-color: var(--border-strong); }
.btn:active { transform: translateY(.5px); }
.btn:disabled { opacity: .45; cursor: default; pointer-events: none; }
.btn.primary { background: var(--primary); border-color: var(--primary); color: var(--primary-text); }
.btn.primary:hover { opacity: .88; }
.btn.danger-text { color: var(--crit); }
.btn.sm { height: 28px; padding: 0 10px; font-size: var(--fs-1); border-radius: 6px; }
.btn.icon { width: var(--ctl); padding: 0; flex: none; }
.btn.icon svg { width: 16px; height: 16px; }
.link { background: none; border: 0; padding: 0; cursor: pointer; color: var(--text-2); font-size: var(--fs-2); text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 3px; }
.link:hover { color: var(--text); text-decoration-color: currentColor; }
.link:disabled { opacity: .45; pointer-events: none; }

/* GO and Panic: the only loud controls in the product. */
.btn.go { height: var(--ctl-lg); min-width: 128px; padding: 0 24px; font-size: var(--fs-4); font-weight: 700; letter-spacing: .04em; background: var(--primary); border-color: var(--primary); color: var(--primary-text); border-radius: 9px; }
.btn.go:hover { opacity: .88; background: var(--primary); }
.btn.panic { position: relative; overflow: hidden; height: var(--ctl-lg); width: 172px; padding: 0 12px; font-size: var(--fs-4); font-weight: 700; background: var(--panic); border-color: var(--panic); color: #fff; border-radius: 9px; }
.btn.panic:hover { background: var(--panic-hover); border-color: var(--panic-hover); }
/* Fixed width: arming must never move the button out from under the second click. */
.btn.panic.armed { font-size: var(--fs-3); box-shadow: 0 0 0 4px var(--crit-bg), 0 0 0 5px var(--panic); }
.btn.panic.armed::after { content: ""; position: absolute; left: 0; bottom: 0; height: 3px; width: 100%; background: rgba(255,255,255,.85); transform-origin: left; animation: panic-window var(--arm-window, 2500ms) linear forwards; }
@keyframes panic-window { to { transform: scaleX(0); } }
@media (prefers-reduced-motion: reduce) { .btn.panic.armed::after { animation: none; } }

input, select { height: var(--ctl); border-radius: 7px; border: 1px solid var(--border); background: var(--surface); padding: 0 10px; min-width: 0; font-size: var(--fs-3); }
input:focus-visible, select:focus-visible { outline-offset: 0; border-color: var(--focus); }
input::placeholder { color: var(--text-3); }
select[multiple] { height: auto; padding: 4px; }

/* ---------- header ---------- */
.app-header { border-bottom: 1px solid var(--border); background: var(--bg); position: sticky; top: 0; z-index: 20; }
.app-header .wrap { display: flex; align-items: center; gap: 28px; height: 56px; }
.wordmark { font-weight: 650; font-size: var(--fs-4); letter-spacing: -.01em; white-space: nowrap; }
.wordmark span { color: var(--text-3); font-weight: 450; font-size: var(--fs-2); margin-left: 8px; }
.tabs { display: flex; gap: 4px; height: 100%; }
.tabs button { background: none; border: 0; padding: 0 10px; cursor: pointer; color: var(--text-2); font-size: var(--fs-3); font-weight: 550; border-bottom: 2px solid transparent; margin-bottom: -1px; border-radius: 0; }
.tabs button:hover { color: var(--text); }
.tabs button[aria-selected="true"] { color: var(--text); border-bottom-color: var(--text); }
.header-right { margin-left: auto; display: flex; align-items: center; gap: 18px; font-size: var(--fs-2); }
.conn { display: inline-flex; align-items: center; gap: 7px; color: var(--text-2); white-space: nowrap; }
.conn::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--text-3); }
.conn.on::before { background: var(--ok); }
.conn.off { color: var(--crit); }
.conn.off::before { background: var(--crit); }
@media (max-width: 860px) {
  .app-header .wrap { gap: 14px; }
  .wordmark span, .hide-sm { display: none !important; }
  #user .name { display: none; }
  .header-right { gap: 12px; }
}

/* ---------- overview ---------- */
.overview { padding: 32px 0 20px; display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.overview h1 { font-size: var(--fs-5); font-weight: 650; letter-spacing: -.015em; }
.overview p { color: var(--text-2); margin-top: 4px; font-size: var(--fs-3); }
.stale-banner { margin: 16px 0 0; padding: 10px 14px; border-radius: 8px; background: var(--warn-bg); color: var(--warn); font-size: var(--fs-2); font-weight: 550; }
body.stale .list, body.stale .activity { opacity: .55; }

/* ---------- room list ---------- */
.list { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.list-head, .room { display: grid; grid-template-columns: 44px minmax(140px, 1fr) minmax(220px, 1.6fr) minmax(180px, 1.3fr) 96px 150px; align-items: center; column-gap: 12px; padding: 0 16px 0 10px; }
.list-head { height: 38px; font-size: var(--fs-1); color: var(--text-3); border-bottom: 1px solid var(--border); }
.room { position: relative; min-height: 58px; border-bottom: 1px solid var(--border); cursor: pointer; transition: background .3s; }
.room:last-child { border-bottom: 0; }
.room:hover { background: var(--hover); }
.room.sel { background: var(--sel-bg); box-shadow: inset 0 0 0 1.5px var(--text-2); }
.room.flash-ok { background: var(--ok-bg); transition: none; }
.room.flash-err { background: var(--crit-bg); transition: none; }
.pick { width: 34px; height: 34px; margin-left: -4px; border: 0; background: none; padding: 0; display: grid; place-items: center; cursor: pointer; border-radius: 7px; }
.pick span { width: 22px; height: 22px; border-radius: 5px; border: 1.5px solid var(--border-strong); display: grid; place-items: center; font: 600 11px/1 var(--mono); color: var(--text-2); }
.pick:hover span { border-color: var(--text-2); color: var(--text); }
.pick[aria-pressed="true"] span { background: var(--text); border-color: var(--text); color: var(--bg); }
.room-name { justify-self: start; max-width: 100%; background: none; border: 0; padding: 4px 0; font-weight: 600; font-size: var(--fs-3); text-align: left; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.status { display: flex; align-items: center; gap: 8px; min-width: 0; color: var(--text-2); font-size: var(--fs-3); }
.status { flex-wrap: wrap; row-gap: 2px; }
.status .label { overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.status.warn { color: var(--warn); font-weight: 550; }
.status.crit, .status.offline { color: var(--crit); font-weight: 550; }
.status.setup { color: var(--text-2); }
.status .extra { color: var(--text-2); flex: none; font-size: var(--fs-2); font-weight: 450; }
.status .extra.crit { color: var(--crit); font-weight: 550; }
.dot { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--text-3); }
.dot.ok { background: var(--ok); } .dot.warn { background: var(--warn); } .dot.crit, .dot.offline { background: var(--crit); }
.dot.setup, .dot.info { background: transparent; box-shadow: inset 0 0 0 1.5px var(--text-3); }
.cue { display: flex; align-items: baseline; gap: 8px; min-width: 0; font-size: var(--fs-3); }
.cue .k { color: var(--text-3); font-size: var(--fs-2); flex: none; }
.cue .n { font-family: var(--mono); font-size: var(--fs-2); color: var(--text-2); flex: none; }
.cue .t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cue .r { margin-left: auto; font-family: var(--mono); font-size: var(--fs-2); color: var(--text-2); flex: none; padding-left: 8px; }
.cue .ty { margin-left: auto; color: var(--text-3); font-size: var(--fs-2); flex: none; padding-left: 8px; }
.cue.playing .k { color: var(--ok); font-weight: 600; }
.qcell { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.progress { height: 3px; background: var(--border); border-radius: 2px; overflow: hidden; }
.progress i { display: block; height: 100%; background: var(--ok); transition: width .25s linear; }
.progress.paused i { background: var(--warn); }
.seen { color: var(--text-2); font-size: var(--fs-2); }
.actions { display: flex; justify-content: flex-end; gap: 6px; }
.group-row { display: flex; align-items: center; gap: 10px; width: 100%; padding: 14px 16px; border: 0; border-top: 1px solid var(--border); background: var(--surface-2); color: var(--text-2); font-size: var(--fs-2); cursor: pointer; text-align: left; border-radius: 0; }
.group-row:hover { color: var(--text); }
.group-row .chev { width: 12px; height: 12px; transition: transform .15s; }
.group-row[aria-expanded="true"] .chev { transform: rotate(90deg); }
.skeleton { height: 58px; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 24px; padding: 0 16px; }
.skeleton i { display: block; height: 10px; border-radius: 5px; background: var(--surface-2); }
.empty { padding: 48px; text-align: center; color: var(--text-2); }
main.wrap { padding-bottom: calc(var(--dock-h, 96px) + 32px); }

@media (max-width: 860px) {
  .list-head { display: none; }
  .room { grid-template-columns: 40px 1fr auto; grid-template-areas: "pick name actions" "pick status status" "pick qlab qlab"; row-gap: 6px; padding: 12px 12px 14px 8px; align-items: start; }
  .room > .pick { grid-area: pick; margin: -4px 0 0 -4px; width: 44px; height: 44px; }
  .room > .pick span { width: 26px; height: 26px; }
  .room > .room-name { grid-area: name; align-self: center; font-size: var(--fs-4); }
  .room > .status { grid-area: status; }
  .room > .qcell { grid-area: qlab; }
  .room > .qcell:has(> .faint:only-child) { display: none; }
  .room > .seen { display: none; }
  .room > .actions { grid-area: actions; }
}

/* ---------- activity ---------- */
.activity { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; }
.activity ol, .events { list-style: none; margin: 0; padding: 0; }
.activity li, .events li { display: grid; grid-template-columns: 58px 12px 1fr auto; gap: 10px; align-items: baseline; padding: 10px 16px; border-bottom: 1px solid var(--border); font-size: var(--fs-2); }
.activity li:last-child, .events li:last-child { border-bottom: 0; }
.activity li.day, .events li.day { display: block; padding: 14px 16px 6px; font-size: var(--fs-1); font-weight: 600; color: var(--text-3); background: var(--surface-2); }
.activity li .dot, .events li .dot { width: 7px; height: 7px; transform: translateY(-1px); }
.activity li.warn .msg, .events li.warn .msg { color: var(--warn); }
.activity li.crit .msg, .events li.crit .msg { color: var(--crit); }
.time { font-family: var(--mono); font-size: var(--fs-1); color: var(--text-3); }
.who { color: var(--text-3); font-size: var(--fs-1); white-space: nowrap; }
.events li { padding-left: 0; padding-right: 0; }
.events li.day { padding-left: 0; background: none; }
@media (max-width: 860px) {
  .activity li, .events li { grid-template-columns: 50px 10px 1fr; }
  .activity li .who, .events li .who { grid-column: 3; }
}
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; padding: 3px; background: var(--surface); gap: 2px; }
.seg button { border: 0; background: none; height: 28px; padding: 0 12px; border-radius: 5px; font-size: var(--fs-2); color: var(--text-2); cursor: pointer; }
.seg button[aria-pressed="true"] { background: var(--sel-bg); color: var(--text); font-weight: 550; }

/* ---------- dock ---------- */
.dock { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; background: var(--surface); border-top: 1px solid var(--border); box-shadow: 0 -8px 24px rgba(0,0,0,.04); }
.dock .wrap { display: flex; align-items: center; gap: 12px; min-height: 72px; flex-wrap: wrap; padding-top: 12px; padding-bottom: 12px; }
.target { display: flex; flex-direction: column; min-width: 160px; max-width: 240px; }
.target small { font-size: var(--fs-1); color: var(--text-3); }
.target b { font-weight: 650; font-size: var(--fs-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.target .links { display: flex; gap: 12px; }
.dock-hint { color: var(--text-2); font-size: var(--fs-2); }
.group { display: flex; gap: 6px; align-items: center; }
.sep { width: 1px; height: 28px; background: var(--border); margin: 0 2px; }
.cue-input { width: 72px; }
.sp { flex: 1; }
.last { display: flex; align-items: center; gap: 8px; font-size: var(--fs-2); color: var(--text-2); min-width: 0; }
.dock .last { order: 10; flex: 1 0 100%; margin-top: -4px; }
.last span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.last.ok { color: var(--ok); } .last.warn { color: var(--warn); } .last.crit { color: var(--crit); }
.last .dot.sending { background: var(--text-3); animation: blink 1s ease-in-out infinite; }
@keyframes blink { 50% { opacity: .3; } }
@media (max-width: 860px) {
  .dock .wrap { gap: 8px; min-height: 0; }
  .target { flex: 1 0 100%; max-width: none; flex-direction: row; align-items: baseline; gap: 8px; }
  .target .links { margin-left: auto; }
  .dock .btn.go { flex: 1; min-width: 0; }
  .dock .btn.panic { flex: 1; width: auto; min-width: 0; }
  .dock .sp { display: none; }
}

/* ---------- menu ---------- */
.menu { position: fixed; z-index: 60; min-width: 240px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow); padding: 6px; }
.menu .menu-head { margin: 8px 10px 4px; font-size: var(--fs-1); font-weight: 600; color: var(--text-3); }
.menu [role="menuitem"] { display: flex; width: 100%; align-items: center; gap: 10px; background: none; border: 0; text-align: left; padding: 8px 10px; border-radius: 6px; cursor: pointer; font-size: var(--fs-2); }
.menu [role="menuitem"]:hover, .menu [role="menuitem"]:focus-visible { background: var(--hover); outline: none; }
.menu [role="menuitem"]:disabled { opacity: .45; pointer-events: none; }
.menu .hint { margin-left: auto; color: var(--text-3); font-size: var(--fs-1); }
.menu hr { border: 0; border-top: 1px solid var(--border); margin: 6px 0; }
.menu-row { display: flex; align-items: center; }
.menu-row [role="menuitem"]:first-child { flex: 1; }
.menu-row .edit { width: auto; flex: none; color: var(--text-3); }
.menu-empty { margin: 4px 10px 6px; color: var(--text-3); font-size: var(--fs-2); }
.menu-mobile { display: none; }
@media (max-width: 860px) { .menu-mobile { display: block; } }

/* ---------- room panel ---------- */
.panel { position: fixed; inset: 0; z-index: 50; }
.panel-bg { position: absolute; inset: 0; background: rgba(0,0,0,.3); }
.panel-body { position: absolute; top: 0; right: 0; bottom: 0; width: min(620px, 100vw); background: var(--bg); border-left: 1px solid var(--border); display: flex; flex-direction: column; animation: in .18s cubic-bezier(.16,1,.3,1); }
@keyframes in { from { transform: translateX(24px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .panel-body { animation: none; } }
.panel-head { padding: 18px 24px 0; background: var(--bg); }
.panel-title { display: flex; align-items: flex-start; gap: 12px; }
.panel-title > div { flex: 1; min-width: 0; }
.panel-title h2 { font-size: var(--fs-5); font-weight: 650; letter-spacing: -.01em; }
.panel-title .status { margin-top: 4px; }
.room-bar { margin-top: 16px; padding: 14px 16px; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; display: flex; flex-direction: column; gap: 12px; }
.room-bar .readout { display: flex; flex-direction: column; gap: 8px; }
.room-bar .controls { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.room-bar .controls .sp { flex: 1; }
.panel-head .tabs { height: 44px; margin-top: 8px; margin-left: -10px; border-bottom: 1px solid var(--border); margin-right: -24px; padding-right: 24px; }
.panel-scroll { flex: 1; overflow-y: auto; padding: 4px 24px 48px; }
.section { padding: 22px 0; border-bottom: 1px solid var(--border); }
.section:last-child { border-bottom: 0; }
.section h3 { font-size: var(--fs-3); font-weight: 650; margin-bottom: 12px; display: flex; align-items: center; gap: 8px; }
.section h3 .sp { flex: 1; }
.kv { display: grid; grid-template-columns: 160px 1fr; gap: 9px 16px; margin: 0; font-size: var(--fs-3); }
.kv dt { color: var(--text-2); }
.kv dd { margin: 0; display: flex; align-items: center; gap: 10px; min-width: 0; flex-wrap: wrap; }
.v-ok { color: var(--ok); } .v-warn { color: var(--warn); } .v-bad { color: var(--crit); }
.copy { background: none; border: 0; padding: 0; color: var(--text-3); cursor: pointer; font-size: var(--fs-1); white-space: nowrap; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--border-strong); }
.copy:hover { color: var(--text); }
.issues { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.issues li { padding: 12px 14px; border-radius: 9px; background: var(--surface); border: 1px solid var(--border); display: grid; grid-template-columns: 12px 1fr; gap: 3px 10px; align-items: baseline; }
.issues li b { font-weight: 600; }
.issues li.crit b { color: var(--crit); } .issues li.warn b { color: var(--warn); }
.issues li p { grid-column: 2; color: var(--text-2); font-size: var(--fs-2); }
.issues li .who-fix { grid-column: 2; font-size: var(--fs-1); color: var(--text-3); margin-top: 2px; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }
.text-actions { display: flex; gap: 20px; flex-wrap: wrap; }
.vol { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.vol input[type=range] { flex: 1; min-width: 160px; height: auto; padding: 0; border: 0; background: none; accent-color: var(--text); }
.vol output { width: 44px; text-align: right; color: var(--text-2); }
.cue-search { width: 100%; }
.cue-list { border: 1px solid var(--border); border-radius: 9px; background: var(--surface); max-height: 440px; overflow: auto; margin-top: 10px; }
.cue-list table { width: 100%; border-collapse: collapse; font-size: var(--fs-2); }
.cue-list td { padding: 8px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.cue-list tr:last-child td { border-bottom: 0; }
.cue-list td.n { font-family: var(--mono); color: var(--text-2); width: 52px; white-space: nowrap; }
.cue-list td.nm { word-break: break-word; }
.cue-list td.ty { color: var(--text-3); width: 64px; }
.cue-list td.a { width: 1%; white-space: nowrap; text-align: right; }
.cue-list tr:hover td { background: var(--hover); }
.cue-list tr.ph td { background: var(--sel-bg); }
.cue-list tr.ph td.n { color: var(--text); font-weight: 700; }
.cue-list .ph-tag { font-size: var(--fs-1); color: var(--text-2); margin-left: 8px; font-weight: 450; }
.cue-list tr.list-row td { color: var(--text-3); font-size: var(--fs-1); background: var(--surface-2); font-weight: 600; }
@media (hover: hover) and (pointer: fine) {
  .cue-list td.a .btn { opacity: 0; }
  .cue-list tr:hover td.a .btn, .cue-list tr:focus-within td.a .btn { opacity: 1; }
}
@media (max-width: 860px) {
  .panel-head { padding: 14px 16px 0; }
  .panel-head .tabs { margin-right: -16px; padding-right: 16px; }
  .panel-scroll { padding: 4px 16px 40px; }
  .kv { grid-template-columns: 1fr; gap: 2px; }
  .kv dt { font-size: var(--fs-1); margin-top: 8px; }
  .room-bar { padding: 12px; }
  .room-bar .btn.go { flex: 1 1 40%; }
  .room-bar .btn.panic { flex: 1 1 40%; width: auto; }
  .room-bar .controls .sp { display: none; }
  .cue-list td.ty { display: none; }
}

/* ---------- dialogs ---------- */
dialog { background: var(--surface); color: var(--text); border: 1px solid var(--border); border-radius: 14px; padding: 24px; width: min(480px, calc(100vw - 32px)); box-shadow: var(--shadow); }
dialog::backdrop { background: rgba(0,0,0,.4); }
dialog h2 { font-size: var(--fs-4); font-weight: 650; }
dialog form { display: flex; flex-direction: column; gap: 14px; }
dialog label { display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-2); color: var(--text-2); flex: 1; }
dialog label.check { flex-direction: row; align-items: center; gap: 8px; }
dialog label.check input { height: auto; }
dialog .row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
dialog .row.end { justify-content: flex-end; align-items: center; }
dialog p { color: var(--text-2); font-size: var(--fs-3); }
dialog pre { background: var(--surface-2); border-radius: 8px; padding: 12px; margin: 0; font: var(--fs-1)/1.5 var(--mono); white-space: pre-wrap; word-break: break-all; }
.target-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--border); border-radius: 9px; max-height: 260px; overflow: auto; }
.target-list li { display: flex; gap: 12px; align-items: baseline; padding: 9px 12px; border-bottom: 1px solid var(--border); font-size: var(--fs-2); }
.target-list li:last-child { border-bottom: 0; }
.target-list li b { font-weight: 600; flex: none; }
.target-list li span { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.skip-note { font-size: var(--fs-2); color: var(--warn); }
.steps { margin: 0; padding-left: 18px; color: var(--text-2); display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-2); }
.steps b, .steps code { color: var(--text); font-weight: 550; }
.keys { display: grid; grid-template-columns: auto 1fr; gap: 9px 18px; font-size: var(--fs-3); align-items: baseline; margin: 0; }
.keys dt { font-family: var(--mono); font-size: var(--fs-1); color: var(--text); background: var(--surface-2); border: 1px solid var(--border); border-radius: 5px; padding: 3px 8px; justify-self: start; }
.keys dd { margin: 0; color: var(--text-2); }
.note { color: var(--text-3); font-size: var(--fs-2); }

/* ---------- toasts ---------- */
.toasts { position: fixed; bottom: 96px; left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; gap: 8px; z-index: 100; align-items: center; pointer-events: none; }
.toast { background: var(--primary); color: var(--primary-text); padding: 10px 16px; border-radius: 9px; font-size: var(--fs-2); box-shadow: var(--shadow); animation: up .2s cubic-bezier(.16,1,.3,1); max-width: calc(100vw - 32px); }
.toast.err { background: var(--panic); color: #fff; }
@keyframes up { from { transform: translateY(6px); opacity: 0; } }
@media (max-width: 860px) { .toasts { bottom: 150px; } }

/* ---------- login ---------- */
.login-body { min-height: 100vh; display: grid; place-items: center; padding: 16px; }
.login { width: min(340px, 100%); display: flex; flex-direction: column; gap: 16px; }
.login h1 { font-size: var(--fs-5); font-weight: 650; }
.login h1 + p { color: var(--text-2); margin-top: -10px; }
.login label { display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-2); color: var(--text-2); }
.login input, .login .btn { height: 42px; }
.err { color: var(--crit); min-height: 1.2em; font-size: var(--fs-2); }
.room-bar .btn.go { min-width: 110px; padding: 0 18px; }
.link { white-space: nowrap; }
@media (max-width: 860px) {
  /* Phone: GO and Panic share the top row; the quieter transport sits below. */
  .room-bar .controls .btn.go { order: 1; flex: 1 1 45%; }
  .room-bar .controls .btn.panic { order: 2; flex: 1 1 45%; }
  .room-bar .controls .btn:not(.go):not(.panic) { order: 3; flex: 1 1 28%; }
  .room > .room-name { white-space: normal; }
  .group-row .faint { display: none; }
}

/* ---------- phone / desktop variants ---------- */
.phone-only { display: none !important; }
@media (max-width: 860px) {
  .phone-only { display: revert !important; }
  .btn.phone-only { display: inline-flex !important; }
  .desk-only { display: none !important; }
}
.bar-hint { font-size: var(--fs-1); color: var(--text-2); margin: -2px 0 0; text-wrap: pretty; }
.bar-hint .link { font-size: var(--fs-1); margin-left: 6px; }
.overview p, .issues li p, .note, .dock-hint { text-wrap: pretty; }
/* Faint text on tinted backgrounds gets the stronger secondary grey to hold 4.5:1. */
.group-row .faint, .cue-list tr.ph td.ty, .cue-list tr.list-row td { color: var(--text-2); }
.dock-hint.v-warn { font-weight: 550; }
@media (prefers-color-scheme: dark) { .panel-bg { background: rgba(0,0,0,.6); } }
@media (max-width: 860px) {
  .progress { height: 5px; border-radius: 3px; }
  .room-bar .controls .btn.panic.phone-only { order: 2; flex: 1 1 45%; width: auto; }
  .room-bar .controls .btn.go { order: 1; }
  .dock .btn.panic.phone-only { flex: 1; width: auto; min-width: 0; }
}
@media (max-width: 420px) {
  .conn { font-size: 0; gap: 0; }
  .header-right { gap: 10px; }
}
/* Screen Share (vnc://) and setup do nothing useful on a phone — keep rows clean there. */
@media (max-width: 860px) and (pointer: coarse) {
  .room > .actions { display: none; }
  .room { grid-template-columns: 40px 1fr; grid-template-areas: "pick name" "pick status" "pick qlab"; }
}
.btn.phone-only[hidden], .btn.desk-only[hidden], .phone-only[hidden] { display: none !important; }

/* Armed: a darker, unmistakable state that names its target. Width never changes. */
:root { --panic-armed: #6e1712; }
@media (prefers-color-scheme: dark) { :root { --panic-armed: #8a1d18; } }
.btn.panic.armed { background: var(--panic-armed); border-color: var(--panic-armed); flex-direction: column; gap: 1px; line-height: 1.15; }
.btn.panic.armed::after { height: 5px; }
.arm-l1 { font-size: var(--fs-2); font-weight: 700; }
.arm-l2 { font-size: var(--fs-1); font-weight: 500; opacity: .9; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The target label has a fixed width so GO never slides as the label changes. */
@media (min-width: 861px) { .target { width: 230px; min-width: 230px; max-width: 230px; flex: none; } }
dialog pre { word-break: normal; overflow-wrap: anywhere; }
.issues code, .setup-card code { font: var(--fs-1) var(--mono); background: var(--surface-2); border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px; user-select: all; }
.setup-card p { font-size: var(--fs-3); color: var(--text-2); text-wrap: pretty; }
.setup-card p b { color: var(--text); font-weight: 600; }

/* ---------- setup view ---------- */
.setup-list .setup-row { display: grid; grid-template-columns: 36px minmax(160px, 1.3fr) minmax(170px, 1.3fr) minmax(120px, .9fr) minmax(160px, 1.2fr) auto; align-items: center; column-gap: 12px; padding: 12px 16px 12px 12px; border-bottom: 1px solid var(--border); min-height: 60px; }
.setup-list .setup-row:last-child { border-bottom: 0; }
.setup-list .setup-head { min-height: 38px; padding-top: 0; padding-bottom: 0; font-size: var(--fs-1); color: var(--text-3); }
.setup-row .num { font: 600 11px/1 var(--mono); color: var(--text-2); }
.setup-row .who b { display: block; font-weight: 600; }
.setup-row .who .mono { color: var(--text-2); font-size: var(--fs-1); }
.setup-row .hw { font-size: var(--fs-2); color: var(--text-2); }
.setup-row .row-actions { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
.btn.icon.sm { width: 28px; height: 28px; }
.btn.icon.sm svg { width: 14px; height: 14px; }
.tag-new { font-size: var(--fs-1); color: var(--warn); font-weight: 550; margin-left: 6px; }
dialog.wide { width: min(560px, calc(100vw - 32px)); }
dialog fieldset { border: 1px solid var(--border); border-radius: 9px; padding: 10px 14px 14px; margin: 0; display: flex; flex-direction: column; gap: 10px; }
dialog legend { font-size: var(--fs-2); color: var(--text); font-weight: 600; padding: 0 6px; }
dialog textarea { border-radius: 7px; border: 1px solid var(--border); background: var(--surface); padding: 8px 10px; font: inherit; color: inherit; resize: vertical; }
dialog .note { margin-top: -8px; }
dialog input:disabled { color: var(--text-2); background: var(--surface-2); }
@media (max-width: 860px) {
  .setup-list .setup-head { display: none; }
  .setup-list .setup-row { grid-template-columns: 28px 1fr auto; grid-template-areas: "num who actions" "num status status" "num hw hw"; row-gap: 6px; align-items: start; }
  .setup-row .num { grid-area: num; padding-top: 4px; }
  .setup-row .who { grid-area: who; }
  .setup-row .status { grid-area: status; }
  .setup-row .ts { display: none; }
  .setup-row .hw { grid-area: hw; }
  .setup-row .row-actions { grid-area: actions; }
}
dialog { max-height: calc(100dvh - 32px); overflow-y: auto; overscroll-behavior: contain; }
/* Setup is configuration, not show control: no dock there. */
body.view-setup .dock { display: none; }

/* ---------- room camera ---------- */
#camHost .section { border-bottom: 1px solid var(--border); padding-bottom: 18px; }
#camHost .cam-none { padding: 14px 0; color: var(--text-2); font-size: var(--fs-2); }
.cam { position: relative; aspect-ratio: 16 / 9; background: #0c0c0d; border-radius: 10px; overflow: hidden; color: #f2f2f3; }
.cam room-camera, .cam video { display: block; width: 100%; height: 100%; }
.cam video { object-fit: contain; background: #0c0c0d; }
.cam-msg { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; padding: 24px; text-align: center; font-size: var(--fs-2); color: #c9c9ce; pointer-events: none; }
.cam-msg b { color: #f2f2f3; font-weight: 600; font-size: var(--fs-3); }
.cam[data-state="live"] .cam-msg { display: none; }
.cam-bar { position: absolute; right: 10px; bottom: 10px; display: flex; gap: 6px; opacity: 0; transition: opacity .15s; }
.cam:hover .cam-bar, .cam:focus-within .cam-bar, .cam[data-state="error"] .cam-bar { opacity: 1; }
@media (pointer: coarse) { .cam-bar { opacity: 1; } }
.cam-btn { height: 30px; min-width: 30px; padding: 0 9px; border-radius: 6px; border: 1px solid rgba(255,255,255,.18); background: rgba(12,12,13,.72); color: #f2f2f3; font: 600 var(--fs-1)/1 var(--font); letter-spacing: .04em; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.cam-btn.icon { padding: 0; }
.cam-btn svg { width: 15px; height: 15px; }
.cam-btn[aria-pressed="true"] { background: #f2f2f3; color: #0c0c0d; border-color: #f2f2f3; }
.cam-btn:focus-visible, .cam-start:focus-visible { outline: 2px solid #f2f2f3; outline-offset: 2px; }
.cam-start { position: absolute; inset: 0; width: 100%; border: 0; background: transparent; color: #f2f2f3; font: 600 var(--fs-3)/1 var(--font); cursor: pointer; display: flex; align-items: center; justify-content: center; }
.cam-start span { padding: 10px 16px; border-radius: 8px; border: 1px solid rgba(255,255,255,.22); }
.cam-note { margin-top: 10px; }
.cam:fullscreen { border-radius: 0; aspect-ratio: auto; }

/* ---------- camera recorder (Setup) ---------- */
.setup-h { font-size: var(--fs-4); font-weight: 650; margin: 36px 0 12px; }
.nvr-card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 16px; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.nvr-card .nvr-main { flex: 1; min-width: 240px; }
.nvr-card .nvr-title { font-size: var(--fs-3); color: var(--text); display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.nvr-card .nvr-title b { font-weight: 600; }
.nvr-card .status { font-size: var(--fs-2); }
.nvr-card .status.ok { color: var(--ok); font-weight: 550; }
.nvr-card .sub { margin-top: 4px; color: var(--text-2); font-size: var(--fs-2); }
.nvr-card .row-actions { display: flex; gap: 6px; }
dialog label.narrow { flex: 0 0 110px; }

/* ---------- room snapshots (Rooms list) ---------- */
.list.with-cams .list-head, .list.with-cams .room { grid-template-columns: 44px 96px minmax(130px, 1fr) minmax(200px, 1.5fr) minmax(170px, 1.2fr) 96px 150px; }
.thumb { position: relative; width: 96px; aspect-ratio: 16 / 9; margin: 8px 0; border-radius: 6px; overflow: hidden; background: var(--surface-2); }
.thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.thumb.no-cam { background: none; box-shadow: inset 0 0 0 1px var(--border); }
.thumb.stale img { opacity: .4; filter: grayscale(1); }
.thumb .age { position: absolute; left: 4px; bottom: 4px; padding: 1px 5px; border-radius: 4px; background: rgba(12,12,13,.78); color: #f2f2f3; font-size: 10.5px; font-weight: 550; line-height: 15px; white-space: nowrap; }
@media (max-width: 860px) {
  .list.with-cams .room { grid-template-columns: 40px 72px 1fr auto; grid-template-areas: "pick thumb name actions" "pick thumb status status" "pick qlab qlab qlab"; }
  .room > .thumb { grid-area: thumb; width: 72px; margin: 2px 0 0; align-self: start; }
}
@media (max-width: 860px) {
  .thumb .age { left: 3px; bottom: 3px; padding: 0 4px; font-size: 9.5px; line-height: 14px; }
}
@media (max-width: 860px) and (pointer: coarse) {
  .list.with-cams .room { grid-template-columns: 40px 72px 1fr; grid-template-areas: "pick thumb name" "pick thumb status" "pick qlab qlab"; }
}

/* ---------- view only (public visitors through Tailscale Funnel) ---------- */
/* The layout stays the same as for operators; controls are greyed out. Buttons rendered by the app get a real
   disabled state; these are the few it can't disable (links, Setup), and the hub refuses the actions anyway. */
body.view-only #setupView .btn, body.view-only #setupView .link,
body.view-only [data-setup], body.view-only [data-edit-room], body.view-only [data-move],
body.view-only [data-nvr-edit], body.view-only [data-nvr-scan],
body.view-only a[href^="vnc:"], body.view-only a[href^="ssh:"] { opacity: .45; cursor: not-allowed; }
body.view-only a[href^="vnc:"], body.view-only a[href^="ssh:"] { pointer-events: none; }
.view-tag { display: inline-flex; align-items: center; white-space: nowrap; flex: none; height: 22px; padding: 0 8px; margin-right: 10px; border-radius: 6px; border: 1px solid var(--border-strong); color: var(--text-2); font-size: var(--fs-1); font-weight: 550; }
#user { display: inline-flex; align-items: center; white-space: nowrap; }
@media (max-width: 420px) { .view-tag { margin-right: 8px; padding: 0 6px; } }

/* ---------- phone header: two rows (brand + status, then the tabs across the full width) ---------- */
@media (max-width: 600px) {
  .app-header .wrap { flex-wrap: wrap; height: auto; column-gap: 12px; row-gap: 0; padding-top: 10px; }
  .app-header .wordmark { order: 1; line-height: 32px; }
  .app-header .header-right { order: 2; min-width: 0; }
  .app-header .tabs { order: 3; flex: 1 0 100%; height: 44px; gap: 0; margin: 2px -10px 0; }
  .app-header .tabs button { flex: 1; padding: 0 6px; }
}
@media (max-width: 600px) {
  .setup-list .setup-row { grid-template-columns: 28px 1fr; grid-template-areas: "num who" "num status" "num hw" "num actions"; }
  .setup-row .row-actions { justify-content: flex-start; flex-wrap: wrap; margin-top: 4px; }
  .nvr-card .row-actions { flex-wrap: wrap; }
}
/* Short screens (a phone in landscape): the room's header and controls would leave almost no room for the
   content below, so the whole panel scrolls as one instead. */
@media (max-height: 520px) {
  .panel-body { overflow-y: auto; overscroll-behavior: contain; }
  .panel-scroll { flex: none; overflow: visible; }
}
