/* Part of the APK.audio project — http://APK.audio — made by Anthony Kuzub
   MIT Licence. Free, for everyone, for ever. Full text in LICENSE at the root.
   Same dark shell and orange accent as CAD.Like.audio, so the two read as one tool. */

:root {
  --bg: #1e1e1e;
  --panel: #252526;
  --panel-2: #2d2d30;
  --line: #3a3a3d;
  --text: #d4d4d4;
  --muted: #9aa4b2;
  --accent: #f4902c;
  --ok: #22c55e;
  --warn: #f59e0b;
  --bad: #ef4444;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text); font: 13px/1.4 system-ui, -apple-system, Segoe UI, sans-serif; }
body { display: grid; grid-template-rows: auto 1fr auto; overflow: hidden; }
/* the meters float over the views' bottom edge, above the frequency strip: the views keep the whole height */
#scaleStrip { position: relative; }
.foot { position: absolute; left: 0; right: var(--inspector-w, 360px); bottom: 100%; height: var(--foot-h, 210px); z-index: 25; display: flex; align-items: flex-end; gap: 6px; padding: 0 6px 6px; pointer-events: none; }
body:has(main.inspector-out) .foot { right: 0; }
.foot > * { pointer-events: auto; }
#meters { transition: opacity .2s ease, transform .2s ease; }
/* a new frequency rendering: the meters fade out of the way so the field is seen as it paints (ui/meterFold.js) */
body.meters-folded #meters { opacity: 0; transform: translateY(12px); pointer-events: none; }
/* hidden by hand (📈), or every meter popped out: only Undo / Redo / Save are left */
body.meters-hidden #meters, body.meters-hidden .foot > .sash, body.meters-empty #meters, body.meters-empty .foot > .sash { display: none; }
body.meters-hidden .foot, body.meters-empty .foot { justify-content: flex-end; }
#graphsBtn.on { background: var(--panel-2); color: var(--accent); border-color: var(--accent); }

button, select, input, .button { font: inherit; color: var(--text); background: var(--panel-2); border: 1px solid var(--line); border-radius: 4px; padding: 3px 8px; }
button, .button { cursor: pointer; }
button:hover, .button:hover { border-color: var(--accent); }
button.on { background: var(--accent); color: #111; border-color: var(--accent); font-weight: 600; }
button.danger:hover { border-color: var(--bad); color: var(--bad); }
.button input[type=file] { display: none; }

/* wrapped rows sit 4 px apart, not the 14 between groups; the forced break adds no gap of its own */
.bar { display: flex; align-items: center; gap: 4px 14px; padding: 4px 12px; background: var(--panel); border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.rowEnd { flex-basis: 100%; height: 0; margin-top: -4px; }
/* a toolbar strip folded behind a button, opened over the views (ui/fold.js) */
.fold { position: relative; display: flex; }
.foldBtn.on { background: var(--panel-2); border-color: var(--accent); color: var(--accent); }
.foldPanel { position: absolute; top: calc(100% + 6px); left: 0; z-index: 60; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; width: max-content; max-width: min(840px, calc(100vw - 32px)); padding: 10px 12px; background: var(--panel); border: 1px solid var(--line); border-radius: 6px; box-shadow: 0 8px 24px rgba(0, 0, 0, .55); }
.foldPanel[hidden] { display: none; }
.foldPanel.group { gap: 4px; }
.foldPanel.group button { border-radius: 4px; }
.brand { font-weight: 800; letter-spacing: .04em; color: var(--accent); }
.brand span { color: var(--text); font-weight: 500; }
.group { display: flex; gap: 2px; }
.group button { border-radius: 0; }
.group button:first-child { border-radius: 4px 0 0 4px; }
.group button:last-child { border-radius: 0 4px 4px 0; }
/* a fold closing a group (＋ Furniture ▾) is its last button */
.group > .fold:last-child > .foldBtn { border-radius: 0 4px 4px 0; }
/* the speaker sets, a row each: the one that sounds bright, the others' picks dimmed */
#arrangement { display: flex; flex-direction: column; gap: 2px; }
.speakerSet button { padding: 1px 7px; }
.speakerSet .setLetter { min-width: 26px; font-weight: 700; }
.speakerSet:not(.live) button.on:not(.setLetter) { background: var(--panel-2); color: var(--accent); }
.freq { display: flex; align-items: center; gap: 6px; font-family: var(--mono); }
.freq input { width: 100%; margin: 0; accent-color: #fde047; }
#freqOut { min-width: 70px; color: #fde047; display: flex; flex-direction: column; line-height: 1.05; }
.reveal { display: flex; align-items: center; gap: 4px; font-size: 11px; color: var(--muted); }
.reveal input { width: 70px; }
.reveal output { min-width: 26px; font-family: var(--mono); color: var(--text); }
#freqOut small { font-size: 8px; color: var(--muted); }
.status { margin-left: auto; color: var(--muted); font-family: var(--mono); font-size: 11px; }

main { position: relative; display: grid; grid-template-columns: 1fr var(--inspector-w, 360px); min-height: 0; }

#views { position: relative; display: grid; gap: 1px; padding: 0; min-height: 0; background: var(--line); }
/* the six views in pairs that look alike: the two looking down (plan over ceiling), the long walls, the short walls */
#views.six { grid-template-columns: 1.3fr 1.3fr 1fr; grid-template-rows: 1.5fr 1fr; grid-template-areas: "plan left front" "ceiling right back"; }
/* the CAD out, the plan is small: even rows — only in the default shape, the wide and tall ones keep their own rows */
#views.six:not([data-shape=wide], [data-shape=tall]):has(.tile.plan.cad-out) { grid-template-rows: 1fr 1fr; }
/* a letterbox of a screen: one row, still in pairs */
#views.six[data-shape=wide] { grid-template-columns: 1.6fr 1fr 1.3fr 1.3fr 1fr 1fr; grid-template-rows: 1fr; grid-template-areas: "plan ceiling left right front back"; }
/* a tall one: the pairs side by side, one under another */
#views.six[data-shape=tall] { grid-template-columns: 1fr 1fr; grid-template-rows: 1.4fr 1fr 1fr; grid-template-areas: "plan ceiling" "left right" "front back"; }
#views.six .t3d { display: none; }
#views.three { grid-template-columns: 1fr 1.5fr; grid-template-areas: "plan d3"; }
#views.three .face { display: none; }
#views .tile.wall { display: none; }
/* 🧱 Wall: the CAD's plan beside one wall planned on a page of its own */
#views.wall { grid-template-columns: minmax(280px, 1fr) 2.4fr; grid-template-areas: "plan wall"; }
#views.wall .face, #views.wall .t3d { display: none; }
#views.wall .tile.wall { display: block; grid-area: wall; overflow: auto; }
#views.wall:has(.tile.plan.cad-out) .tile.plan { display: none; }
#views.wall:has(.tile.plan.cad-out) { grid-template-columns: 1fr; grid-template-areas: "wall"; }
/* a tile out in a window of its own: the rest share the space it left (main.js relayoutViews) */
#views.loose { grid-template-areas: none !important; }
#views.loose > .tile { grid-area: auto !important; }
#views.maxed { grid-template-columns: 1fr !important; grid-template-rows: 1fr !important; grid-template-areas: "max" !important; }
#views.maxed .tile:not(.max) { display: none; }
#views.maxed .tile.max { grid-area: max; }

.tile { position: relative; background: #0f1218; border: 0; border-radius: 0; min-width: 0; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
.tile.plan { grid-area: plan; }
.tile[data-face=ceiling] { grid-area: ceiling; }
.tile[data-face=front] { grid-area: front; }
.tile[data-face=back] { grid-area: back; }
.tile[data-face=left] { grid-area: left; }
.tile[data-face=right] { grid-area: right; }
.tile.t3d { grid-area: d3; }
.tile header { padding: 3px 8px; background: var(--panel); border-bottom: 1px solid var(--line); font-weight: 600; font-size: 12px; cursor: default; user-select: none; }
.tile header .sub, .sub { color: var(--muted); font-weight: 400; font-size: 11px; }
.tile > canvas { flex: 1; width: 100%; min-height: 0; display: block; cursor: crosshair; }
/* the 3-D room's bar: the method always, the shows behind ⋯ — and all of it, roomier, in a window of its own */
.tile .viewbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-right: 28px; }
.viewbar button { padding: 1px 8px; font-size: 11px; }
.viewbar .shows { display: none; }
.viewbar.open .shows, .popped .viewbar .shows, .tile.max .viewbar .shows { display: flex; }
.popped .viewbar .viewMore, .tile.max .viewbar .viewMore { display: none; }
body.popout .viewbar { gap: 14px; padding: 6px 12px; font-size: 14px; }
body.popout .viewbar button { padding: 4px 14px; font-size: 13px; }
.readout { position: absolute; right: 8px; top: 6px; font: 11px var(--mono); color: #fde047; pointer-events: none; }

.stage { position: relative; flex: 1; min-height: 0; }
.stage iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: #1e1e1e; }
.stage canvas.overlay { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.stage .hits { position: absolute; inset: 0; pointer-events: none; }
.stage .hit { position: absolute; left: 0; top: 0; width: 24px; height: 24px; border-radius: 50%; pointer-events: auto; cursor: grab; }
.stage .hit:active { cursor: grabbing; }
.stage .hit.locked, .stage .hit.locked:active { cursor: not-allowed; }
.stage .hit.locked::after { content: '🔒'; position: absolute; right: -10px; top: -10px; font-size: 11px; pointer-events: none; }
.stage .plan-menu { position: absolute; z-index: 20; display: flex; flex-direction: column; min-width: 120px; padding: 3px; background: var(--panel); border: 1px solid var(--line); border-radius: 6px; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5); pointer-events: auto; }
.stage .plan-menu button { text-align: left; border: 0; background: none; padding: 5px 10px; }
.stage .plan-menu button:hover:not(:disabled) { background: var(--panel-2); color: var(--accent); }
.stage .plan-menu button:disabled { opacity: 0.4; }
/* the CAD's gear (a library room's console, desks, rack, couch): a ring at its centre, under any speaker or seat standing on it */
.stage .hit { z-index: 1; }
.stage .hit[data-kind="gear"] { z-index: 0; border: 1px dashed rgba(251, 191, 36, 0.75); }
/* the people over the boxes and the furniture, the mix seat over everyone: grabbed first where they overlap */
.stage .hit[data-kind="mic"] { z-index: 2; }
.stage .hit.mix { z-index: 3; }
.stage .capture { position: absolute; inset: 0; display: none; cursor: crosshair; background: rgba(244,144,44,.04); outline: 2px dashed rgba(244,144,44,.5); outline-offset: -3px; }
.stage .capture.on { display: block; }
/* a speaker turning after Ctrl-click: this sheet takes the pointer from the CAD's iframe until a click sets it */
.stage .spin { position: absolute; inset: 0; z-index: 6; cursor: crosshair; }

#inspector { background: var(--panel); border-left: 1px solid var(--line); display: flex; flex-direction: column; min-height: 0; }
.tabs { display: flex; flex-wrap: wrap; gap: 2px; padding: 6px; border-bottom: 1px solid var(--line); }
.tabs button { padding: 3px 7px; font-size: 12px; position: relative; }
.tabs button.file { margin-left: auto; }
#inspector .tabs > .popbtn { position: static; opacity: 1; padding: 3px 7px; font-size: 12px; line-height: normal; }
.badge { font-style: normal; background: var(--warn); color: #111; border-radius: 8px; padding: 0 5px; margin-left: 4px; font-size: 10px; font-weight: 700; }
.body { overflow-y: auto; padding: 8px 12px 24px; }
h3 { margin: 10px 0 6px; font-size: 13px; color: var(--accent); }
h4 { margin: 12px 0 4px; font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
/* a row keeps to a docked inspector's width: popped out wide, its dropdowns don't run the width of the window */
.row { display: grid; grid-template-columns: 120px 1fr auto; align-items: center; gap: 6px; margin: 3px 0; max-width: 480px; }
.row > span { color: var(--muted); font-size: 12px; }
.row input[type=number], .row input[type=text], .row select { width: 100%; min-width: 0; }
.row input[type=range] { width: 100%; accent-color: var(--accent); }
.unit { display: flex; align-items: center; gap: 4px; }
.unit input { width: 90px !important; }
.unit em { color: var(--muted); font-style: normal; font-size: 11px; white-space: nowrap; }
.check { display: flex; align-items: center; gap: 6px; }
.toggles { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }
.actions { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.adders { display: grid; grid-template-columns: 1fr auto; gap: 4px; }
.devlist { display: flex; flex-wrap: wrap; gap: 4px; margin: 8px 0; }
/* the acoustic groups: Room, Surfaces, Sources (a branch per speaker set), Receivers — folded per branch */
.tree { margin: 8px 0; display: flex; flex-direction: column; gap: 2px; }
.branch > summary { cursor: pointer; padding: 3px 2px; font-weight: 600; user-select: none; }
.branch > summary small { font-weight: 400; color: var(--muted); }
.branch .branch > summary { font-weight: 500; font-size: 12px; }
.branch.live > summary { color: var(--accent); }
.leaves { display: flex; flex-wrap: wrap; gap: 4px; padding: 2px 0 6px 14px; border-left: 1px solid var(--line); margin-left: 5px; }
.leaves > .branch { flex-basis: 100%; }
.leaves > .hint { margin: 2px 0; }
.leaves .dev small { color: var(--muted); }
.dev { border-left: 3px solid var(--c); font-size: 12px; }
.dev i { font-style: normal; color: #00f7ff; margin-left: 4px; }
.dev.on { background: #3a3a3d; border-color: var(--c); }
.hint { color: var(--muted); font-size: 12px; }
.stat { font-family: var(--mono); font-size: 11px; color: var(--text); }
table.grid { width: 100%; border-collapse: collapse; font: 11px var(--mono); margin: 4px 0; }
table.grid th, table.grid td { border-bottom: 1px solid #333; padding: 2px 4px; text-align: right; }
table.grid th:first-child, table.grid td:first-child { text-align: left; }
table.grid tr.ok td:first-child { color: var(--ok); }
table.grid tr.bad td:first-child { color: var(--bad); }
/* the Furniture tab: a row a piece, its numbers on one line, its material and absorption under it */
table.grid.furniture tr.name, table.grid.furniture tr.at { cursor: pointer; }
table.grid.furniture tr.name td { border-bottom: 0; padding-top: 6px; font-family: system-ui, sans-serif; }
table.grid.furniture tr.on td { color: var(--accent); }
table.grid.furniture tr.at td { border-bottom: 0; white-space: nowrap; }
table.grid.furniture tr.sub td { text-align: left; color: var(--muted); font-size: 10px; padding-bottom: 6px; }
table.grid tr[onclick], table.grid tr.ok, table.grid tr.bad { cursor: pointer; }
table.modes tr.axial td:nth-child(3) { color: #ef4444; }
table.modes tr.tangential td:nth-child(3) { color: #f59e0b; }
table.modes button { padding: 0 5px; font-size: 10px; }
.advice { list-style: none; padding: 0; margin: 0; }
.advice li { border-left: 3px solid var(--muted); padding: 4px 8px; margin: 4px 0; background: #202022; }
.advice li.ok { border-color: var(--ok); }
.advice li.warn { border-color: var(--warn); }
.advice li b { display: block; font-size: 12px; }
.advice li span { color: var(--muted); font-size: 12px; }

/* the colour scale over the frequency slider, column for column: dB ends / Sweep and the readout, the ramp / the slider */
#scaleStrip { display: grid; grid-template-columns: max-content 1fr minmax(70px, max-content); align-items: center; column-gap: 8px; row-gap: 22px; padding: 14px 8px 12px; background: #121418; border-top: 1px solid var(--line); font: 10px var(--mono); color: #ddd; }
#fieldScale, #fieldScale[hidden], #freqRow { display: contents; }
#fieldScale[hidden] { visibility: hidden; }
#freqRow #sweep { padding: 1px 8px; font-size: 11px; }
#fieldScale .ramp { flex: 1; height: 8px; border: 1px solid rgba(255,255,255,.4); position: relative; }
/* where the mix seat and the room sit on the scale, at the current frequency */
/* the dB scale over the ramp, and what the mix seat and the room read: a small triangle under it each, pointing up at its level */
#fieldScale .ramp { cursor: crosshair; touch-action: none; }
#fieldScale .ramp::after { content: ''; position: absolute; inset: -8px 0; }
#fieldScale .dbTick { position: absolute; bottom: 100%; width: 1px; height: 3px; background: var(--muted); transform: translateX(-.5px); }
#fieldScale .dbTick.major { height: 5px; background: #ddd; }
#fieldScale .dbNum { position: absolute; bottom: calc(100% + 5px); transform: translateX(-50%); font-size: 8px; line-height: 1; color: var(--muted); pointer-events: none; }
#fieldScale .mark { position: absolute; top: calc(100% + 2px); width: 0; height: 0; border: 5px solid transparent; border-top: 0; border-bottom: 7px solid var(--c); transform: translateX(-5px); z-index: 1; }
#fieldScale .mark span { position: absolute; top: 6px; left: 5px; transform: translateX(-50%); white-space: nowrap; font-size: 8px; line-height: 1; color: var(--c); }
#fieldScale .mark.off { opacity: .45; }
#fieldScale .sel { position: absolute; top: -3px; bottom: -3px; background: rgba(255, 255, 255, .18); border: 1px solid #fff; pointer-events: none; z-index: 2; font-size: 8px; line-height: 1; color: #fff; white-space: nowrap; }
#fieldScale .scaleAll { padding: 0 5px; font-size: 10px; line-height: 14px; }
/* the file end of the app: open on the top left, save and export on the bottom right */
#saves { align-self: flex-end; box-shadow: 0 4px 14px rgba(0, 0, 0, .5); border-radius: 4px; }
/* a warning about the last change, with its undo: one speaker of an arrangement moved on its own */
#notice { position: fixed; top: 56px; left: 50%; transform: translateX(-50%); z-index: 40; max-width: min(720px, calc(100vw - 32px)); display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: #2a1d0b; color: #fde68a; border: 1px solid var(--warn); border-radius: 6px; box-shadow: 0 4px 18px rgba(0, 0, 0, 0.5); font-size: 12px; }
#notice[hidden] { display: none; }
/* a newer app on the server (ui/freshness.js): the same place as a notice, in the accent */
#updated { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); z-index: 45; max-width: min(720px, calc(100vw - 32px)); display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: #2a1a0b; color: #fed7aa; border: 1px solid var(--accent); border-radius: 6px; box-shadow: 0 4px 18px rgba(0, 0, 0, 0.5); font-size: 12px; }
#updated[hidden] { display: none; }
#updated [data-act=refresh] { background: var(--accent); color: #111; border-color: var(--accent); font-weight: 600; }
#meters { flex: 1; min-width: 0; height: 100%; display: flex; gap: 3px; padding: 0; overflow-x: auto; background: transparent; }
/* the meters flex to fill the strip, each in proportion to what it needs; a sash between two trades their share (ui/sashes.js) */
.meter { position: relative; flex: 200 1 0; min-width: 60px; display: flex; flex-direction: column; background: rgba(11, 13, 18, .84); backdrop-filter: blur(4px); border: 1px solid rgba(255, 255, 255, .08); border-radius: 6px; box-shadow: 0 6px 18px rgba(0, 0, 0, .45); padding: 4px 6px; min-height: 0; }
.meter.wide { flex-grow: 320; }
.meter.m-spl { flex-grow: 112; }
.meter h4 { margin: 0 0 2px; font-size: 10px; color: #cbd5e1; display: flex; gap: 6px; align-items: center; }
.meter h4 .sub { text-transform: none; letter-spacing: 0; }
.meter canvas { flex: 1; width: 100%; min-height: 0; }
.m-fr canvas { cursor: pointer; }
.tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; overflow: auto; }
.tiles .tile { display: block; background: #151a23; border: 1px solid #262b36; border-radius: 4px; padding: 2px 4px; text-align: center; overflow: visible; }
.tiles .tile b { display: block; font: 600 12px var(--mono); color: #7dd3fc; }
.tiles .tile span { font-size: 9px; color: var(--muted); }
.tiles .tile.wide { grid-column: 1 / -1; }
.meter.m-iso { flex-grow: 230; }
.listen { margin-left: auto; padding: 0 6px; font-size: 10px; }
#meters.empty .meter canvas { opacity: .6; }

@media (max-width: 900px) {
  main { grid-template-columns: 1fr; grid-template-rows: 1fr 300px; }
  #views.six { grid-template-columns: 1fr 1fr; grid-template-areas: "plan ceiling" "left right" "front back"; grid-template-rows: 1.4fr 1fr 1fr; }
}

/* The CAD holds the plan and every wall's elevation; these jump it between them. */
.sheets { display: flex; flex-wrap: wrap; gap: 3px; grid-column: 2 / -1; }
.sheets button { padding: 1px 6px; font-size: 11px; }
#toPlan { margin-left: 8px; padding: 0 6px; font-size: 11px; }
.tile.face > canvas { cursor: pointer; }
.tile.face.editing { outline: 2px solid #7dd3fc; outline-offset: -2px; }

/* Treatments: painted in the CAD, read here. The swatch is drawn the way the views draw the patch. */
canvas.swatch { display: inline-block; vertical-align: -2px; border-radius: 2px; }
/* the Acoustics tab's two halves (ui/inspector.js) */
.subtabs { display: flex; gap: 2px; margin: 2px 0 8px; }
.subtabs button { padding: 2px 10px; font-size: 12px; }
.subtabs button.on, .actions button.on { border-color: var(--accent); color: var(--accent); }
table.wall-bands td:nth-child(3) { width: 40%; }
.abar { display: block; height: 8px; border-radius: 2px; background: linear-gradient(90deg, #7dd3fc var(--v), var(--panel-2) var(--v)); }
/* what a transducer looks like and how it throws (views/transducer.js): four tenths of the pane under its numbers */
.tx-card { display: grid; grid-template-rows: minmax(0, 1fr) auto; height: max(300px, 40vh); margin-top: 12px; padding: 8px; border: 1px solid var(--line); border-radius: 6px; background: #17181b; }
.tx-views { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; min-height: 0; }
.tx-views svg { width: 100%; height: 100%; min-height: 0; }
.tx-card .t { fill: var(--muted); font: 10px var(--mono); }
.tx-card .t.mid { text-anchor: middle; }
.tx-card .t.end { text-anchor: end; }
.tx-card .t.db { font-size: 7px; opacity: .7; }
.tx-card .ring { fill: none; stroke: var(--line); stroke-width: .8; }
.tx-card .ring.six { stroke: #57606d; stroke-dasharray: 3 3; }
.tx-card .cov { stroke: var(--muted); stroke-dasharray: 2 3; stroke-width: .8; }
.tx-card .hi { fill-opacity: .18; stroke-width: 1.6; }
.tx-card .lo { fill: none; stroke: var(--muted); stroke-dasharray: 4 3; stroke-width: 1.2; }
.tx-face .box { fill: #23252b; stroke: #5b616b; stroke-width: 3; }
.tx-face .surround { fill: #101114; stroke-width: 4; }
.tx-face .cone { fill: #1a1c20; stroke: #2e3137; stroke-width: 2; }
.tx-face .cap, .tx-face .dome { fill: #2a2d33; stroke-width: 3; }
.tx-face .plate { fill: #15161a; stroke: #2e3137; stroke-width: 2; }
.tx-face .horn, .tx-face .throat { fill: #101114; stroke-width: 3; }
.tx-foot .stat { margin: 6px 0 2px; }
.tx-bands { display: block; width: 100%; height: auto; max-height: 60px; }
.tx-bands .xo { stroke: #facc15; stroke-dasharray: 3 2; }
.tx-legend { display: flex; flex-wrap: wrap; gap: 2px 14px; margin: 4px 0 0; padding: 0; list-style: none; font-size: 11px; color: var(--muted); }
.tx-legend i { display: inline-block; width: 9px; height: 9px; margin-right: 5px; border-radius: 2px; background: var(--c); }
.tx-legend b { color: var(--text); font-weight: 600; }
.spark { display: inline-flex; align-items: flex-end; gap: 1px; height: 14px; vertical-align: middle; }
.spark i { display: block; width: 4px; background: #7dd3fc; border-radius: 1px 1px 0 0; }
table.surfaces td .sub { font: 10px system-ui, sans-serif; }
table.surfaces tr.treated td:first-child { color: #fde047; }
table.treat tr.name td { padding-top: 5px; border-bottom: 0; text-align: left; font: 12px system-ui, sans-serif; color: var(--text); }
table.treat tr.vals td { color: var(--muted); }
table.treat tr.name, table.treat tr.vals { cursor: default; }
table.treat tr.name td { overflow-wrap: anywhere; }
table.grid.treat tr[class~=on] td { background: #3a3a3d; }
table.grid.treat tr.on td:first-child { color: var(--accent); }
table.treat.pick tr.name, table.treat.pick tr.vals { cursor: pointer; }
/* the Materials tab's charts (ui/alphaChart.js): the reflect ↔ absorb dial beside the α graph */
.mat-charts { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: flex-start; margin: 4px 0 8px; }
.mat-dial { flex: 0 1 260px; min-width: 200px; }
.mat-dial .hint { margin-top: 2px; }
.intent-dial { display: block; width: 100%; height: auto; font-family: var(--mono); }
.intent-dial .slice { cursor: pointer; transition: fill-opacity .12s; }
.intent-dial .slice:hover, .intent-dial .slice:focus-visible { fill-opacity: 1; outline: none; stroke: #f4f4f4; }
.intent-dial .count { font-size: 13px; font-weight: 700; fill: #ffffff; pointer-events: none; }
.intent-dial .end { font-size: 10px; fill: var(--muted); }
.intent-dial .pick { font: 600 14px system-ui, sans-serif; fill: var(--text); }
.intent-dial .sub { font-size: 10px; fill: var(--muted); }
.alpha-graph-wrap { position: relative; flex: 1 1 300px; min-width: 0; }
.alpha-graph { display: block; width: 100%; height: auto; font-family: var(--mono); }
.alpha-graph .tick { font-size: 11px; fill: var(--muted); }
.alpha-graph .label { font-size: 11px; fill: var(--text); }
.alpha-tip { position: absolute; top: 6px; z-index: 5; min-width: 150px; max-width: 220px; padding: 6px 8px; background: #1e1e1e; border: 1px solid var(--line); border-radius: 4px; box-shadow: 0 4px 14px rgba(0, 0, 0, .5); font-size: 11px; pointer-events: none; }
.alpha-tip[hidden] { display: none; }
.alpha-tip .head { color: var(--muted); margin-bottom: 3px; font-family: var(--mono); }
.alpha-tip .row { display: flex; align-items: center; gap: 6px; }
.alpha-tip .v { font: 700 12px var(--mono); color: #f4f4f4; }
.alpha-tip .n { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.alpha-tip .key, .alpha-legend .key { flex: none; width: 12px; border-top: 2px solid; }
.alpha-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 11px; color: var(--text); margin-top: 2px; }
.alpha-legend .item { display: flex; align-items: center; gap: 5px; }
.alpha-legend button { padding: 0 4px; font-size: 10px; line-height: 14px; }
.alpha-legend .empty { color: var(--muted); }
table.treat td.spark { text-align: right; padding: 2px 4px 0; }
.alpha-spark { display: inline-block; vertical-align: middle; }
table.treat tr.plotted td { background: #2d2d30; }
table.treat .linekey { display: inline-block; width: 12px; border-top: 2px solid; vertical-align: middle; margin-right: 4px; }
table.surfaces td, table.surfaces th { white-space: nowrap; vertical-align: top; }
.hint.warn { color: var(--warn); }

/* the array wider than the room: the room it would need (acoustics/roomFit.js) */
.roomGrow { align-self: center; font-size: 11px; color: var(--warn); border: 1px dashed var(--warn); border-radius: 4px; padding: 1px 6px; white-space: nowrap; cursor: help; }
.hint.grow { color: var(--warn); }

/* ---------------------------------------------------------------- pop-outs (ui/popout.js) */
/* the CAD tile too narrow to work in: Pop out asks to be pressed */
#popCad.ask { border-color: var(--accent); color: var(--accent); animation: ask-pop 1.2s ease-in-out infinite; }
@keyframes ask-pop { 50% { background: var(--accent); color: #111; box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 35%, transparent); } }
@media (prefers-reduced-motion: reduce) { #popCad.ask { animation: none; background: var(--accent); color: #111; } }
.poppable { position: relative; }
.popbtn { position: absolute; top: 2px; right: 2px; z-index: 5; padding: 0 5px; font-size: 11px; line-height: 16px; opacity: .55; }
.poppable:hover > .popbtn { opacity: 1; }
/* a meter's – sits left of its ⇱ and tucks it into the tray by Undo, as an icon (ui/meters.js) */
.meter > .minbtn { position: absolute; top: 2px; right: 26px; z-index: 5; padding: 0 5px; font-size: 11px; line-height: 16px; opacity: .55; }
.meter:hover > .minbtn { opacity: 1; }
.meter.min, body.popout .meter > .minbtn, #meterTray > [hidden] { display: none; }
#meterTray { display: flex; gap: 2px; }
/* the last meter still open has no sash after it: nothing to trade with */
.meter:not(:has(~ .meter:not(.min))) > .sash { display: none; }
#meterTray:not(:has(> :not([hidden]))) { display: none; }
#meterTray button { padding: 1px 6px; font-size: 11px; }
/* the plan pops out only while the CAD is in a window of its own (main.js) */
.tile.plan:not(.cad-out) > .popbtn { display: none; }
.meter h4 { cursor: zoom-in; }
body.popout { display: flex; flex-direction: column; height: 100vh; margin: 0; overflow: hidden; }
body.popout .popbar { display: flex; gap: 6px; align-items: center; padding: 4px 8px; background: var(--panel); border-bottom: 1px solid var(--line); }
body.popout .popbar b { margin-right: auto; }
body.popout .popbar .tools { display: flex; gap: 6px; }
body.popout .host { flex: 1; display: flex; min-height: 0; padding: 4px; }
body.popout .host > * { flex: 1 1 auto !important; width: auto; height: auto; min-height: 0; }
body.popout .meter h4 { font-size: 13px; cursor: default; }
body.popout #inspector { overflow: auto; }
main.inspector-out { grid-template-columns: 1fr; }

/* ---------------------------------------------------------------- the frequency slider, read as a log scale */
.freq { position: relative; }
/* the cache under the slider: a tick for each frame painted */
.freq #freqCache { position: absolute; left: 0; width: 100%; top: 50%; height: 8px; transform: translateY(-50%); pointer-events: none; }
.freq input { position: relative; }
/* the tour's button fills as the frames come in, and breathes while they do */
#tour { background-image: linear-gradient(90deg, rgba(253, 224, 71, .28) calc(var(--cache, 0) * 100%), transparent 0); }
#tour.filling { animation: cacheBreath 1.6s ease-in-out infinite; }
#tour.full { border-color: #fde047; }
@keyframes cacheBreath { 50% { box-shadow: 0 0 10px rgba(253, 224, 71, .55); } }
.freq .ticks { position: absolute; left: 0; width: 100%; top: 100%; height: 10px; pointer-events: none; font: 8px var(--mono); color: var(--muted); }
.freq .ticks i { position: absolute; top: -3px; width: 1px; height: 4px; background: var(--muted); }
.freq .ticks span { position: absolute; top: 1px; transform: translateX(-50%); }
#tour.on, #sweep.on { background: var(--accent); color: #111; }

/* ---------------------------------------------------------------- the build, as a stack of layers */
.build { display: flex; flex-direction: column; gap: 1px; margin: 4px 0; font-size: 10px; }
.build div { display: flex; justify-content: space-between; padding: 1px 6px; border-left: 4px solid; background: #151a23; }
.checks { display: flex; flex-direction: column; gap: 2px; margin: 2px 0 6px; }
td.bad { color: var(--bad); }
td.ok { color: #4ade80; }
.stage .hit.holding { outline: 2px solid #22d3ee; outline-offset: 4px; box-shadow: 0 0 14px #22d3ee; }
.arrayFields { gap: 6px; align-items: center; }
#spreader[hidden] { display: none; }
.arrayField { display: flex; align-items: center; gap: 3px; color: var(--muted); font-family: var(--mono); font-size: 11px; }
.arrayField input { width: 64px; padding: 2px 4px; }
.arrayFields input[type="range"] { width: 100%; margin: 0; }
/* the Width slider with its scale under it (main.js syncWidthScale): the thumb is 16px, so everything sits 8px in */
.widthScale { display: flex; flex-direction: column; width: 300px; }
.widthScale .lanes { position: relative; height: 26px; font: 8px/1 var(--mono); color: var(--muted); cursor: help; }
.widthScale .lanes .foot { position: absolute; left: 8px; right: 8px; top: 0; height: 3px; opacity: .7; }
.widthScale .lanes .tick { position: absolute; top: 3px; width: 1px; height: 3px; background: var(--muted); }
.widthScale .lanes .tick.major { height: 5px; background: var(--text); }
.widthScale .lanes .m { position: absolute; top: 9px; transform: translateX(-50%); }
.widthScale .lanes .mark { position: absolute; transform: translateX(-50%); top: 17px; font-weight: 600; }
.widthScale .lanes .mark.direct { color: #7dd3fc; }
.widthScale .lanes .mark.gap { color: #fbbf24; }

/* ---------------------------------------------------------------- the song player (ui/player.js) */
.player { flex-basis: 100%; display: flex; align-items: center; gap: 8px; min-width: 0; }
.player[hidden] { display: none; }
.player .name { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.player .wave { flex: 3 1 200px; height: 34px; min-width: 0; cursor: pointer; background: #0b0d12; border-radius: 3px; }
.player .spec { flex: 2 1 160px; height: 34px; min-width: 0; cursor: ew-resize; background: #0b0d12; border-radius: 3px; }
.player .time, .player .hz { font: 11px ui-monospace, monospace; color: #9aa4b2; white-space: nowrap; }
.tree .dev.lost, .devlist .dev.lost { border-style: dashed; opacity: .75; }

/* ------------------------------------------------------------------ the wall builder (views/wallBuilder.js) */
.wb { padding: 10px 14px 18px; display: flex; flex-direction: column; gap: 10px; color: var(--text); }
.wb-empty { padding: 24px; color: var(--muted); }
.wb-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; border-bottom: 1px solid var(--line); padding-bottom: 8px; }
.wb-head h2 { margin: 0; font-size: 18px; font-weight: 600; }
.wb-meta { font: 11px var(--mono); color: var(--muted); }
.wb-meta b { color: var(--accent); font-weight: 400; }
.wb-faces { display: flex; gap: 2px; }
.wb-faces button { padding: 1px 8px; font-size: 11px; }
.wb-faces button.on { background: var(--panel-2); border-color: var(--c); color: var(--c); }
.wb-count { margin-left: auto; font-size: 11px; color: var(--muted); }
.wb-grid { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 12px; align-items: start; }
@container (max-width: 900px) { .wb-grid { grid-template-columns: 1fr; } }
.tile.wall { container-type: inline-size; }
.wb-col { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.wb-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: 12px; }
@container (max-width: 640px) { .wb-row { grid-template-columns: 1fr; } }
.wb-card { background: #181818; border: 1px solid var(--line); border-radius: 6px; padding: 10px 12px; min-width: 0; }
.wb-card h4 { margin: 0 0 8px; font-size: 10px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.wb-svg { display: block; width: 100%; height: auto; max-height: 70vh; font-family: var(--mono); }
.wb-region, .wb-tag, .wb-callout { cursor: pointer; }
/* the ruler and the pencil (views/wallBuilder.js): the elevation is drawn on, not picked from */
.wb-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin-bottom: 6px; }
.wb-tools button { padding: 1px 8px; font-size: 11px; }
.wb-tools button.on { background: var(--panel-2); border-color: #facc15; color: #facc15; }
.wb-legend { font-size: 10px; color: var(--muted); display: flex; align-items: center; gap: 3px 6px; flex-wrap: wrap; }
.wb-legend i { display: inline-block; width: 12px; border-top: 2px dashed var(--c); }
.wb-read { margin-left: auto; font: 11px var(--mono); color: #facc15; }
.wb-svg.drawing { cursor: crosshair; }
.wb-svg.drawing .wb-region, .wb-svg.drawing .wb-tag, .wb-svg.drawing .wb-callout { cursor: crosshair; }
.wb-region:hover { fill-opacity: .7; }
.wb-keysvg { display: block; width: 100%; max-width: 300px; height: auto; margin: 0 auto; }
.wb-detail { display: block; width: 100%; height: auto; font-family: var(--mono); }
.wb-bars { display: block; width: 100%; max-width: 380px; height: auto; font-family: var(--mono); margin: 6px 0; }
.wb-dhead { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.wb-dhead .wb-small { margin-left: auto; }
.wb-bubble { display: inline-grid; place-items: center; width: 22px; height: 22px; border: 1.5px solid #f4f4f4; border-radius: 50%; font: 700 11px var(--mono); }
.wb-small { font-size: 11px; color: var(--muted); margin: 4px 0 0; }
.wb-hint { font-size: 12px; color: var(--muted); margin: 6px 0 0; }
.wb-mono { font: 12px var(--mono); margin: 0 0 8px; }
.wb-calc { font: 11px var(--mono); color: var(--muted); margin: 6px 0 0; line-height: 1.5; }
.wb-label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.wb-label select { width: 100%; }
.wb-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; }
.wb-actions .wb-small { margin: 0 auto 0 0; }
.wb-scroll { overflow-x: auto; }
.wb-table { width: 100%; border-collapse: collapse; font: 11px var(--mono); }
.wb-table th { text-align: left; font-weight: 400; color: var(--muted); padding: 3px 5px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.wb-table td { padding: 3px 5px; vertical-align: top; }
.wb-table .n { text-align: right; white-space: nowrap; }
.wb-table .tag { font-weight: 700; color: #f4f4f4; }
.wb-table .muted { color: var(--muted); font-size: 10px; }
.wb-table tr[data-act] { cursor: pointer; }
.wb-table tr[data-act]:hover { background: var(--panel-2); }
.wb-table tr.on { background: #3a2a1a; }
.wb-table tr.on .tag { color: var(--accent); }
.wb-table tr.base td, .wb-table tr.share td { color: var(--muted); }
.wb-table tr.total td { border-top: 1px solid var(--line); font-weight: 700; }

/* ---------------------------------------------------------------- sashes (ui/sashes.js): every hairline between panels drags */
.sash { position: absolute; z-index: 30; touch-action: none; }
.sash::after { content: ''; position: absolute; background: transparent; transition: background .1s; }
.sash:hover::after, .sash.drag::after { background: var(--accent); }
.sash.v { top: 0; bottom: 0; width: 7px; margin-left: -3px; cursor: col-resize; }
.sash.v::after { top: 0; bottom: 0; left: 2px; width: 3px; }
.sash.h { left: 0; right: 0; height: 7px; margin-top: -3px; cursor: row-resize; }
.sash.h::after { left: 0; right: 0; top: 2px; height: 3px; }
#views > .sashes { position: absolute; inset: 0; pointer-events: none; z-index: 30; }
#views > .sashes > .sash { pointer-events: auto; }
.inspector-sash { right: var(--inspector-w, 360px); margin-left: 0; margin-right: -4px; }
main.inspector-out > .inspector-sash, .popped > .sash, body.popout .sash { display: none; }
.foot > .sash.h { position: absolute; top: 0; }
.meter > .sash.v { right: -4px; margin-left: 0; }
.meter:last-child > .sash, #meters > .meter:last-of-type > .sash { display: none; }
/* while a sash drags, the CAD's iframe must not swallow the pointer */
body.sashing-v, body.sashing-v * { cursor: col-resize !important; }
body.sashing-h, body.sashing-h * { cursor: row-resize !important; }
body.sashing-v iframe, body.sashing-h iframe { pointer-events: none; }

/* the monitor controller (ui/monitor.js): its rows, and a strip per channel */
.monitor { flex-direction: column; align-items: stretch; gap: 8px; min-width: 360px; }
.monRow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.monLabel { color: var(--muted); font-size: 11px; min-width: 38px; }
.monVol { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--muted); }
.monVol input { width: 140px; }
.monVol output, .monitor .mono { font-family: var(--mono); color: var(--text); min-width: 56px; }
.monRead { margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--muted); }
.monRead b { color: #f43f5e; }
.monitor button.on.mute { background: var(--bad); border-color: var(--bad); }
.monitor button.on.solo { background: #facc15; border-color: #facc15; }
.monitor button.on.dim { background: #fb923c; border-color: #fb923c; }
.monStrips { border-collapse: collapse; font-size: 12px; }
.monStrips th { color: var(--muted); font-weight: 500; text-align: left; padding: 0 4px; }
.monStrips td { padding: 1px 4px; }
.monStrips td.name { font-family: var(--mono); min-width: 44px; }
.monStrips button { padding: 0 6px; }
.monStrips input { width: 56px; }
.monStrips tr.silent td.name, .monStrips tr.silent td.mono { opacity: .4; }

/* the wizard (ui/wizard.js): steps 1 and 5 a dialog over the app, 2–4 a card beside the views so the plan stays clickable */
#wizardShade { position: fixed; inset: 0; z-index: 3000; background: rgba(0, 0, 0, .55); }
#wizardShade[hidden], #wizard[hidden] { display: none; }
#wizard { position: fixed; z-index: 3001; display: flex; flex-direction: column; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 16px 48px rgba(0, 0, 0, .6); }
#wizard.big { left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(960px, calc(100vw - 32px)); max-height: calc(100vh - 48px); }
#wizard.side { right: calc(var(--inspector-w, 360px) + 12px); top: 96px; width: min(400px, calc(100vw - 32px)); max-height: calc(100vh - 140px); }
#wizard > header { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--line); }
#wizard > header nav { display: flex; gap: 2px; flex-wrap: wrap; }
#wizard > header nav button { font-size: 11px; padding: 2px 8px; border-radius: 10px; }
#wizard > header nav button.done { color: var(--ok); border-color: var(--ok); }
#wizard > header .x { margin-left: auto; }
#wizard > h3 { margin: 10px 14px 0; font-size: 16px; }
#wizard .wizBody { padding: 4px 14px 10px; overflow: auto; min-height: 0; display: flex; flex-direction: column; gap: 8px; }
#wizard .wizBody > p { margin: 4px 0; }
#wizard > footer { display: flex; align-items: center; gap: 6px; padding: 8px 10px; border-top: 1px solid var(--line); }
#wizard > footer i { flex: 1; }
#wizard .check { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); font-size: 12px; }
.wizActs { display: flex; flex-wrap: wrap; gap: 6px; }
.wizGrid { display: flex; flex-wrap: wrap; gap: 4px; }
.wizScroll { overflow: auto; max-height: calc(100vh - 300px); padding-right: 4px; }
.wizScroll h4:first-child { margin-top: 0; }
.wizRooms { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.wizRoom { display: grid; grid-template-columns: 44px 1fr; grid-template-rows: auto 1fr; column-gap: 8px; align-items: start; text-align: left; padding: 6px; border-radius: 6px; }
.wizRoom svg { grid-row: span 2; width: 44px; height: 44px; }
.wizRoom svg polygon { fill: rgba(244, 144, 44, .15); stroke: var(--accent); stroke-width: 2; vector-effect: non-scaling-stroke; }
.wizRoom b { font-size: 12px; line-height: 1.25; }
.wizRoom span { font: 10px var(--mono); color: var(--muted); }
.wizLive { font-size: 12px; padding: 4px 8px; border-left: 3px solid var(--muted); background: #202022; }
.wizLive.ok { border-color: var(--ok); }
.wizLive.warn { border-color: var(--warn); color: #fde68a; }
.wizSet { display: flex; flex-direction: column; gap: 3px; }
.wizSet > span { font-size: 11px; color: var(--muted); }
.wizFaces { width: 100%; border-collapse: collapse; }
.wizFaces td { padding: 2px 4px; }
.wizFaces td:first-child { white-space: nowrap; }
.wizFaces select { width: 100%; }
.wizFaces .swatch { display: inline-block; width: 10px; height: 10px; margin-right: 6px; border-radius: 2px; vertical-align: -1px; }
.wizRead { display: grid; grid-template-columns: 96px 1fr; gap: 10px; align-items: center; }
.wizSti { display: flex; flex-direction: column; align-items: center; padding: 6px; border-radius: 6px; border: 2px solid var(--muted); text-align: center; }
.wizSti b { font: 700 26px var(--mono); }
.wizSti span { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; }
.wizSti small { font-size: 10px; color: var(--muted); }
.wizSti.bad, .wizSti.poor { border-color: var(--bad); color: var(--bad); }
.wizSti.fair { border-color: var(--warn); color: var(--warn); }
.wizSti.good, .wizSti.excellent { border-color: var(--ok); color: var(--ok); }
.rtChart { width: 100%; height: auto; display: block; }
.rtChart .aim { fill: rgba(34, 197, 94, .15); stroke: rgba(34, 197, 94, .5); }
.rtChart .ok { fill: var(--ok); }
.rtChart .off { fill: var(--warn); }
.rtChart text { fill: var(--text); font: 9px var(--mono); text-anchor: middle; }
.rtChart text.hz { fill: var(--muted); }
.wizAsks { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 8px; }
.wizAsk { display: grid; grid-template-columns: 32px 1fr; column-gap: 8px; text-align: left; padding: 10px; border-radius: 8px; }
.wizAsk i { grid-row: span 2; font-style: normal; font-size: 22px; line-height: 1; }
.wizAsk span { font-size: 11px; color: var(--muted); font-weight: 400; }
.wizAsk.on { background: rgba(244, 144, 44, .14); color: var(--text); border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.wizGo { display: flex; justify-content: center; padding: 6px 0 2px; }
.wizGo .go { font-size: 18px; font-weight: 800; padding: 10px 48px; border-radius: 24px; background: var(--accent); color: #111; border-color: var(--accent); }
@media (max-width: 700px) { #wizard.side { right: 16px; left: 16px; width: auto; } }

/* the monitor controller at the end of the last set's row, set apart from its Place and Empty */
.speakerSet > .fold { margin-left: 10px; }
.speakerSet > .fold > .foldBtn { border-radius: 4px !important; }

/* the rack (ui/rackPanel.js): its front U by U and its side, depth by depth */
svg.rack-drawing { display: block; margin: 6px 0; background: #14171d; border-radius: 4px; font: 9px var(--mono); }
svg.rack-drawing .rk-head { fill: #94a3b8; font: 600 9px system-ui, sans-serif; }
svg.rack-drawing .rk-frame { fill: none; stroke: #4b5563; }
svg.rack-drawing .rk-u { fill: #6b7280; }
svg.rack-drawing .rk-free { fill: rgba(74, 222, 128, 0.08); stroke: rgba(74, 222, 128, 0.6); stroke-dasharray: 3 2; }
svg.rack-drawing .rk-free-t { fill: #86efac; }
svg.rack-drawing .rk-item { fill: #334155; stroke: #64748b; }
svg.rack-drawing .rk-item.unknown { fill: #3f3f46; stroke: #a1a1aa; stroke-dasharray: 2 2; }
svg.rack-drawing .rk-item.bad { fill: #7f1d1d; stroke: #f87171; }
svg.rack-drawing .rk-item-t { fill: #e5e7eb; }
svg.rack-drawing .rk-cable { fill: rgba(148, 163, 184, 0.35); }
svg.rack-drawing .rk-limit { stroke: #fbbf24; stroke-dasharray: 4 3; }
svg.rack-drawing .rk-limit-t { fill: #fbbf24; }
table.rack-items { table-layout: fixed; }
table.rack-items th:nth-child(1), table.rack-items th:nth-child(2) { width: 3.4em; }
table.rack-items th:nth-child(4) { width: 4.4em; }
table.rack-items th:nth-child(5) { width: 3.6em; }
table.rack-items th:nth-child(6) { width: 2.2em; }
table.rack-items input { width: 100%; min-width: 0; box-sizing: border-box; padding: 1px 3px; }
table.rack-items button { padding: 0 4px; }
table.rack-items tr.bad td { color: var(--bad); }
ul.warn { color: var(--bad); margin: 4px 0; padding-left: 16px; font-size: 11px; }
table.rack-items input[type=number] { -moz-appearance: textfield; appearance: textfield; text-align: right; }
table.rack-items input[type=number]::-webkit-inner-spin-button, table.rack-items input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
