/*
  The look is a rack panel, not a dashboard: a dark powder-coated ground, hairline seams,
  hard corners, and anodised orange for anything that carries meaning. Colour is scarce on
  purpose — this app already has three colour systems of its own (circuit resistor code,
  tape colours, voltage), so the chrome stays out of their way.
*/
:root {
  --ground: #0b0c0e;
  --panel: #131519;
  --panel-hi: #191c21;
  --seam: #2a2e35;
  --seam-bright: #3a4049;
  --ink: #d7dae0;
  --ink-dim: #7d838d;
  --ink-faint: #565c66;

  --amber: #ff8a1f;
  --amber-hi: #ffc46b;
  --amber-lo: #c25c07;
  --metal: linear-gradient(180deg, var(--amber-hi) 0%, var(--amber) 46%, var(--amber-lo) 100%);
  --plate: linear-gradient(180deg, #23272e 0%, #171a1f 55%, #101317 100%);

  --row: 26px;
  --chrome: ui-sans-serif, "Arial Narrow", "Roboto Condensed", system-ui, sans-serif;
  --data: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background:
    radial-gradient(1200px 600px at 50% -10%, #16191e 0%, transparent 70%),
    var(--ground);
  color: var(--ink);
  font: 13px/1.45 var(--chrome);
  -webkit-font-smoothing: antialiased;
}

/* ---- faceplate ------------------------------------------------------- */

.faceplate {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: stretch; gap: 0;
  background: var(--plate);
  border-bottom: 1px solid #000;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 1px 0 var(--seam), 0 10px 28px rgba(0,0,0,.6);
}

/* A hairline of brushed texture, so the plate reads as metal rather than as a flat bar. */
.faceplate::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(90deg, rgba(255,255,255,.022) 0 1px, transparent 1px 3px);
}

.mark {
  display: flex; align-items: center; gap: 10px;
  padding: 0 18px 0 20px; border-right: 1px solid var(--seam);
}
.mark b {
  font: 700 15px/1 var(--chrome); letter-spacing: .18em; text-transform: uppercase;
  background: var(--metal); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.mark span { color: var(--ink-faint); font-size: 10px; letter-spacing: .22em; text-transform: uppercase; }

.shows { display: flex; align-items: stretch; }
.show-tab {
  display: flex; flex-direction: column; justify-content: center; gap: 1px;
  padding: 9px 20px; min-width: 150px;
  border-right: 1px solid var(--seam);
  background: none; color: var(--ink-dim); text-align: left; cursor: pointer;
  font: inherit; position: relative;
}
.show-tab b { font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink); }
.show-tab i { font-style: normal; font-size: 10px; letter-spacing: .1em; color: var(--ink-faint); }
.show-tab[aria-selected="true"] { background: linear-gradient(180deg, #1d2127, #14171b); }
.show-tab[aria-selected="true"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--metal);
}
.show-tab:hover { color: var(--ink); }

.plate-right { margin-left: auto; display: flex; align-items: center; gap: 16px; padding: 0 20px; }

/* The amber tell-tale a powered panel has. */
.lamp { display: flex; align-items: center; gap: 8px; color: var(--ink-faint); font-size: 9.5px; letter-spacing: .22em; text-transform: uppercase; }
.lamp::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--amber); box-shadow: 0 0 7px 1px rgba(255,138,31,.7), inset 0 0 2px rgba(255,255,255,.6);
}

/* The two screws that stop the plate looking like a web header. */
.screw {
  width: 11px; height: 11px; border-radius: 50%;
  background: radial-gradient(circle at 34% 28%, #5b626d, #24282e 62%, #14171b 100%);
  box-shadow: inset 0 0 0 1px #090b0e, 0 1px 0 rgba(255,255,255,.06);
  position: relative;
}
.screw::after {
  content: ""; position: absolute; inset: 4px 1.5px; border-top: 1.5px solid #0a0c0f; transform: rotate(28deg);
}

/* ---- layout ---------------------------------------------------------- */

.frame { display: grid; grid-template-columns: 188px 1fr; min-height: calc(100vh - 49px); }

.rail {
  position: relative;
  border-right: 1px solid var(--seam);
  background: linear-gradient(180deg, #101317, #0c0e11);
  padding: 14px 0 14px 16px;
}

/*
  A punched rack ear down the left edge. This is the one piece of literal hardware in the
  interface, and it earns its place: it is the shape every one of these objects bolts into.
*/
.rail::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 16px;
  background:
    /* the hole, with a hair of light on its lower lip so it reads as punched */
    radial-gradient(circle at 8px 50%, #04060a 0 3.2px, rgba(255,255,255,.10) 3.2px 4px, transparent 4px)
      0 0 / 16px 44px repeat-y,
    linear-gradient(90deg, #1f242b 0%, #171b21 60%, #101317 100%);
  border-right: 1px solid #090b0e;
  box-shadow: inset -1px 0 0 rgba(255,255,255,.035);
}

.rail h3 {
  margin: 16px 16px 7px; font-size: 9.5px; letter-spacing: .24em; text-transform: uppercase;
  color: var(--ink-faint); font-weight: 600;
}
.rail button {
  display: flex; width: 100%; align-items: baseline; gap: 8px;
  padding: 5px 16px 5px 14px; border: 0; border-left: 2px solid transparent;
  background: none; color: var(--ink-dim); font: inherit; text-align: left; cursor: pointer;
  letter-spacing: .04em;
}
.rail button:hover { color: var(--ink); background: #14171c; }
.rail button[aria-current="true"] { color: var(--amber-hi); border-left-color: var(--amber); background: #16191f; }
.rail button em { margin-left: auto; font-style: normal; font-size: 10.5px; color: var(--ink-faint); font-family: var(--data); }
.rail button[aria-current="true"] em { color: var(--amber); }

main { padding: 22px 26px 70px; overflow-x: auto; }
main > * { max-width: 1180px; }
main > table, main > .cards, main > .sheets, main > .review { max-width: 1180px; }

h2 {
  margin: 0 0 3px; font-size: 17px; letter-spacing: .14em; text-transform: uppercase; font-weight: 700;
  display: flex; align-items: center; gap: 12px;
}
/* A short anodised rule, so a heading reads as stamped rather than typed. */
h2::after { content: ""; flex: 1; height: 2px; background: linear-gradient(90deg, var(--amber-lo), transparent 62%); opacity: .55; }
.sub { color: var(--ink-faint); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 18px; }

/* ---- data ------------------------------------------------------------ */

table { border-collapse: collapse; width: 100%; font-family: var(--data); font-size: 11.5px; }
thead th {
  position: sticky; top: 49px;
  text-align: left; padding: 7px 10px; white-space: nowrap;
  background: #14171c; border-bottom: 1px solid var(--seam-bright);
  font: 600 9.5px/1 var(--chrome); letter-spacing: .18em; text-transform: uppercase; color: var(--ink-faint);
}
tbody td { padding: 0 10px; height: var(--row); border-bottom: 1px solid #1b1e23; white-space: nowrap; color: var(--ink); }
tbody tr:nth-child(even) { background: #101317; }
tbody tr:hover { background: #191d23; box-shadow: inset 2px 0 0 var(--amber); }
td.num { text-align: right; font-variant-numeric: tabular-nums; }
td.dim { color: var(--ink-faint); }

/* A circuit's own colour, shown as the chip the labels print. */
.chip { display: inline-block; width: 9px; height: 9px; margin-right: 7px; vertical-align: -1px; box-shadow: inset 0 0 0 1px rgba(0,0,0,.5); }

.count { font-family: var(--data); color: var(--amber); }

/* ---- panels ---------------------------------------------------------- */

.cards { display: flex; flex-wrap: wrap; gap: 1px; background: var(--seam); border: 1px solid var(--seam); }
.card { background: var(--panel); padding: 13px 16px; flex: 1 1 150px; min-width: 150px; }
.card b {
  display: block; font-family: var(--data); font-size: 22px; font-weight: 500;
  background: var(--metal); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.card span { font-size: 9.5px; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-faint); }

.review { border: 1px solid var(--seam); }
.review-kind {
  padding: 8px 14px; background: #14171c; border-bottom: 1px solid var(--seam);
  font: 600 10px/1 var(--chrome); letter-spacing: .2em; text-transform: uppercase; color: var(--amber);
  display: flex; gap: 10px; align-items: center;
}
.review-kind em { font-style: normal; color: var(--ink-faint); font-family: var(--data); letter-spacing: 0; }
.review-item { padding: 9px 14px; border-bottom: 1px solid #1b1e23; background: var(--panel); font-size: 12px; }
.review-item small { display: block; margin-top: 3px; color: var(--ink-faint); font-family: var(--data); font-size: 10.5px; }

select {
  background: #0e1114; color: var(--ink); border: 1px solid var(--seam-bright);
  font: 11.5px var(--data); padding: 3px 6px; min-width: 210px;
}
select:focus { outline: none; border-color: var(--amber); box-shadow: 0 0 0 1px var(--amber-lo); }
select.unset { color: var(--amber); border-color: var(--amber-lo); }

.sheets { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 1px; background: var(--seam); border: 1px solid var(--seam); }
.sheet { background: var(--panel); padding: 12px 14px; display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--ink); }
.sheet:hover { background: var(--panel-hi); }
.sheet b { font-size: 12px; letter-spacing: .06em; }
.sheet span { margin-left: auto; font-family: var(--data); font-size: 10px; color: var(--ink-faint); }
.sheet i { width: 3px; align-self: stretch; background: var(--metal); font-style: normal; }

.empty { color: var(--ink-faint); padding: 30px 0; font-size: 12px; letter-spacing: .06em; }

/* The house name, alongside the mark. */
.mark span i { font-style: normal; color: var(--ink-dim); }
.mark span i::after { content: " · "; color: var(--seam-bright); }

/* ---- the grid -------------------------------------------------------- */
/*
  A sheet, not a report. It gets the full width of the frame — column count is decided by
  the data, not by a reading measure — and scrolls inside `main`, which is what keeps the
  row-number gutter stuck to the left edge while the header stays stuck to the faceplate.
*/
main > .sheetframe { max-width: none; }

.sheetframe { border: 1px solid var(--seam); background: var(--panel); }

/* The cell bar: the address you are on, and the whole of the value the cell can only clip. */
.cellbar { display: flex; align-items: stretch; border-bottom: 1px solid var(--seam); background: #14171c; }
.cellbar .addr {
  min-width: 190px; padding: 0 12px; display: flex; align-items: center;
  border-right: 1px solid var(--seam); background: var(--plate);
  font: 600 9.5px/1 var(--chrome); letter-spacing: .18em; text-transform: uppercase; color: var(--amber);
}
.cellbar .barvalue {
  flex: 1; min-width: 0; height: 30px; padding: 0 12px;
  border: 0; outline: none; background: transparent; color: var(--ink);
  font-family: var(--data); font-size: 11.5px;
}
.cellbar .barvalue:focus { background: #000; box-shadow: inset 0 0 0 1px var(--amber-lo); }
.cellbar .barvalue:read-only { color: var(--ink-faint); }

/* The grid scrolls in its own frame, so the headings and the cell bar stay put. */
.gridwrap { overflow: auto; max-height: calc(100vh - 236px); }
/*
 * The table is exactly as wide as its columns, never stretched to the pane. Stretched, the
 * browser hands the slack to every column, so dragging one column's edge changed the width
 * of the key column at the far left as well; a spreadsheet's columns are the width they
 * are, and the pane beyond them is just pane.
 */
.gridwrap > table.grid { width: max-content; }
/*
 * The header row sticks as a row, not cell by cell. Sticky cells alone left Chromium
 * painting the body's cells over the header's background while scrolling, so the rows
 * showed through the headings on every sheet; a sticky row keeps its cells' paint together.
 */
.gridwrap thead { position: sticky; top: 0; z-index: 4; }
.gridwrap thead th { top: 0; }

.grid { outline: none; }
.grid thead th:first-child { left: 0; z-index: 3; }
.grid thead th { z-index: 2; }

/* Row numbers: the way you keep your place in a few thousand rows. */
.grid th.rownum {
  position: sticky; left: 0; z-index: 1;
  width: 46px; padding: 0 8px 0 0;
  text-align: right; font: 400 10px/1 var(--data); color: var(--ink-faint);
  background: #14171c; border-right: 1px solid var(--seam);
  border-bottom: 1px solid #1b1e23;
  user-select: none;
}
.grid tbody tr:nth-child(even) th.rownum { background: #121519; }
.grid th.rownum.at { color: var(--ground); background: var(--metal); font-weight: 700; }

.grid tbody td { border-right: 1px solid #1a1d22; cursor: cell; }
.grid td.ro { color: var(--ink-faint); cursor: default; }

/* The focused cell wears the amber, drawn inside so it never shifts the row. */
.grid td.sel { background: #1a1e24; }
.grid th.rownum.sel { color: var(--amber); }
.grid td.at { box-shadow: inset 0 0 0 2px var(--amber); background: #1c2027; color: #fff; }
.grid:focus td.at { box-shadow: inset 0 0 0 2px var(--amber), 0 0 8px rgba(255,138,31,.28); }

/* Columns resize by dragging their edge; the grip is a child so a drag is never a sort.
   The heading is already `sticky`, which is a positioned ancestor — overriding it to
   `relative` here would silently stop the header sticking. */
.grid thead th .grip {
  position: absolute; top: 0; right: -3px; width: 7px; height: 100%;
  cursor: col-resize; z-index: 4;
}
.grid thead th .grip:hover { background: var(--amber-lo); }
.grid.resizing { cursor: col-resize; user-select: none; }
/* Moving a column: the heading is picked up, and a line says where it lands. */
.grid.moving { cursor: grabbing; user-select: none; }
.grid th.picked { opacity: .45; }
.sheetframe { position: relative; }
.dropline {
  position: absolute; width: 2px; background: var(--amber); z-index: 6; pointer-events: none;
}

/* A value that is wrong in a way worth seeing — a duplicate name, say. */
.grid td.warn { color: #ff8f9b; box-shadow: inset 2px 0 0 #d0384a; }

/* A measure drawn behind its number: how full a case is, at a glance. */
.cellbar-track {
  position: absolute; left: 0; right: 0; top: 3px; bottom: 3px;
  background: #0e1114; z-index: 0;
}
.cellbar-fill { position: absolute; left: 0; top: 0; bottom: 0; background: var(--amber-lo); opacity: .5; }
.cellbar-fill.over { background: #d0384a; opacity: .55; }
.grid td { position: relative; }
/*
 * A cell clips what does not fit.
 *
 * Long values used to paint straight over the neighbouring column — a fixture mode ran
 * through the purpose beside it — so two cells read as one word. Excel spills only into an
 * empty neighbour and these sheets are rarely empty, so clipping is the honest behaviour;
 * the whole value is always in the cell bar.
 */
.grid tbody td { overflow: hidden; white-space: nowrap; }
.cellvalue { position: relative; z-index: 2; }
.grid td > .chip { position: relative; z-index: 2; }

/* The right-click menu. */
/* Compact: the whole menu has to fit under the pointer on a laptop screen. */
.cellmenu {
  position: fixed; z-index: 60; min-width: 158px; max-height: calc(100vh - 8px); overflow-y: auto;
  padding: 2px 0;
  background: var(--panel); border: 1px solid var(--seam-bright);
  box-shadow: 0 16px 36px rgba(0,0,0,.62);
}
.cellmenu button {
  display: flex; width: 100%; align-items: center; gap: 12px; padding: 2.5px 9px;
  border: 0; background: transparent; color: var(--ink); cursor: pointer;
  font-size: 10.5px; line-height: 1.35; text-align: left; white-space: nowrap;
}
.cellmenu button:hover { background: var(--panel-hi); color: var(--amber-hi); }
.cellmenu button em { margin-left: auto; font-style: normal; color: var(--ink-faint); font-family: var(--data); font-size: 8.5px; }
.cellmenu hr { margin: 2px 0; border: 0; border-top: 1px solid var(--seam); }

/* A cell edited through a picker rather than typed. */
select.cell-edit {
  width: 100%; height: calc(var(--row) - 2px); margin: 0; padding: 0 4px; border: 0;
  background: #000; color: #fff; font-family: var(--data); font-size: 11.5px;
}

/* Write-through states. A commit is visible for as long as it takes and no longer. */
.grid td.saving { background: #2a2113; }
.grid td.saved { background: #1d2a19; transition: background .6s ease-out; }
.grid td.failed { background: #33161a; box-shadow: inset 0 0 0 2px #d0384a; }

/* The editor sits exactly where the cell was, so nothing jumps on Enter. */
.cell-edit {
  width: 100%; height: calc(var(--row) - 2px);
  margin: 0; padding: 0; border: 0; outline: none;
  background: #000; color: #fff;
  font: inherit; font-family: var(--data); font-size: 11.5px;
}

.keyhint {
  margin: -8px 0 12px;
}
/* Under a section heading it is a caption, not a hint riding up under the page title. */
h3 + .keyhint, .info .keyhint, .loads .keyhint {
  margin: 3px 0 12px; color: var(--ink-faint);
  font-family: var(--data); font-size: 10px; letter-spacing: .04em;
}

/* Click a heading to sort. The view reorders; the row numbers do not, because a write is
   addressed by the row's place in the show file and not by where the sort put it. */
.grid thead th[data-c] { cursor: pointer; user-select: none; }
.grid thead th[data-c]:hover { color: var(--ink-dim); }
.grid thead th.sorted { color: var(--amber); }
.grid thead th.sorted::after { content: " ▲"; font-size: 7px; vertical-align: 1px; }
.grid thead th.sorted[data-dir="desc"]::after { content: " ▼"; }

/* ---- rack builds ------------------------------------------------------ */
/*
  A rack drawn the way it is built: units down the page, one row each. The addressing beside
  a device is read across from the network data, never stored here, so the two cannot drift.
*/
.racks { display: flex; flex-wrap: wrap; gap: 18px; align-items: flex-start; }
.rack { border: 1px solid var(--seam); background: var(--panel); min-width: 340px; }
.rack h3 {
  margin: 0; padding: 9px 12px; background: var(--plate); border-bottom: 1px solid var(--seam);
  font: 700 12px/1 var(--chrome); letter-spacing: .16em; text-transform: uppercase; color: var(--amber);
  display: flex; align-items: baseline; gap: 10px;
}
.rack h3 span { margin-left: auto; color: var(--ink-faint); font-weight: 400; letter-spacing: .1em; }
.rackbody { padding: 4px 0; }
.ru {
  display: flex; align-items: center; gap: 9px; height: 20px; padding: 0 10px;
  font-family: var(--data); font-size: 10.5px; color: var(--ink-faint);
  border-bottom: 1px dashed #1a1d22;
}
.ru i { font-style: normal; width: 18px; text-align: right; color: #3d434c; }
.ru.filled { background: #15181d; color: var(--ink); border-bottom: 1px solid var(--seam); }
.ru b { font-weight: 600; }
.ru span { color: var(--amber); }
.ru em { font-style: normal; color: var(--ink-dim); }
.ru u { text-decoration: none; margin-left: auto; color: var(--ink-faint); font-size: 9.5px; }

/* ---- instructions ------------------------------------------------------ */
.instructions { border: 1px solid var(--seam); }
.instructions details { border-bottom: 1px solid var(--seam); background: var(--panel); }
.instructions summary {
  padding: 11px 14px; cursor: pointer; display: flex; align-items: center; gap: 12px;
  font: 600 12px/1 var(--chrome); letter-spacing: .1em; text-transform: uppercase;
}
.instructions summary em { font-style: normal; color: var(--ink-faint); font-family: var(--data); font-size: 10px; letter-spacing: 0; }
.instructions summary .print {
  margin-left: auto; padding: 3px 12px; border: 1px solid var(--amber-lo); background: transparent;
  color: var(--amber); font: 600 9.5px/1.6 var(--chrome); letter-spacing: .16em; text-transform: uppercase; cursor: pointer;
}
.instructions summary .print:hover { background: var(--amber-lo); color: var(--ground); }
.instructions pre {
  margin: 0; padding: 4px 16px 18px; white-space: pre-wrap;
  font-family: var(--data); font-size: 11px; line-height: 1.5; color: var(--ink-dim);
}

/* ---- show info --------------------------------------------------------- */
/* Section headings inside a view, as opposed to the page's own h2. */
.info h3, .loads h3 {
  margin: 0 0 4px; font: 700 12px/1 var(--chrome); letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink);
}
/* A caption below a table needs air; without it the two run together. */
table + .keyhint { margin-top: 10px; }
/* Anything short of what the show needs. The one place red is allowed. */
td.short { color: #ff6b7a; font-weight: 600; }

/* ---- looms ------------------------------------------------------------- */
/*
  Sparse IDs, so the summary is what you scroll and the bundle is what you open. The note
  belongs to the loom ID: the workbook kept these positionally and renumbering reassigned
  every one of them.
*/
.looms { border: 1px solid var(--seam); }
.loom { border-bottom: 1px solid var(--seam); background: var(--panel); }
.loom summary {
  padding: 8px 14px; cursor: pointer; display: flex; align-items: center; gap: 14px;
  font-family: var(--data); font-size: 11.5px; color: var(--ink-dim);
}
.loom summary b { color: var(--amber); font-size: 13px; min-width: 44px; }
.loom summary span { white-space: nowrap; }
.loom summary u {
  text-decoration: none; color: var(--ground); background: var(--metal); padding: 1px 7px;
  font: 700 9px/1.7 var(--chrome); letter-spacing: .16em; text-transform: uppercase;
}
.loom.singles summary b { color: var(--ink-dim); }
.loom summary .loomnote {
  margin-left: auto; min-width: 220px; padding: 3px 8px;
  border: 1px solid var(--seam); background: #0e1114; color: var(--ink);
  font-family: var(--data); font-size: 11px;
}
.loom summary .loomnote:focus { outline: none; border-color: var(--amber); }
.loom summary .loomnote.saving { border-color: var(--amber-hi); background: #2a2113; }
.loom > table { border-top: 1px solid var(--seam); }

/* ---- the cable master -------------------------------------------------- */
.cable { display: flex; flex-direction: column; gap: 0; }
.modes {
  display: flex; align-items: center; gap: 1px; flex-wrap: wrap;
  background: var(--seam); border: 1px solid var(--seam); border-bottom: 0; padding: 1px;
}
.modes button[data-mode] {
  padding: 7px 16px; border: 0; background: var(--panel); color: var(--ink-dim);
  font: 600 10px/1 var(--chrome); letter-spacing: .16em; text-transform: uppercase; cursor: pointer;
}
.modes button[data-mode]:hover { color: var(--ink); background: var(--panel-hi); }
.modes button[data-mode][aria-current="true"] { color: var(--ground); background: var(--metal); }
.modes .toggle {
  display: flex; align-items: center; gap: 7px; padding: 0 14px; background: var(--panel);
  align-self: stretch; color: var(--ink-faint); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; cursor: pointer;
}
.modes .toggle input { accent-color: var(--amber); }

.cablebody { border: 1px solid var(--seam); }

/* The tree. A run is a line; opening it shows its parts or its circuits. */
.runs { background: var(--panel); }
.run {
  display: flex; align-items: center; gap: 14px; padding: 6px 12px; cursor: pointer;
  border-bottom: 1px solid #1b1e23; font-family: var(--data); font-size: 11.5px; color: var(--ink-dim);
}
.run:hover { background: var(--panel-hi); }
.run i { font-style: normal; width: 10px; color: var(--amber); }
.run b { color: var(--ink); min-width: 62px; }
.run em { margin-left: auto; font-style: normal; color: var(--amber); font-size: 10.5px; }
.grid.sub { border-bottom: 1px solid var(--seam); background: #0e1114; }
.grid.sub thead th { position: static; background: #12151a; }
.grid.sub tbody td { border-bottom: 1px solid #16191e; }
/* A 2FER forks the circuit: the legs after it belong to different sides of the Y. */
td.twofer { color: var(--amber); font-weight: 600; }

/* The Lumenarchy tab, as a panel. */
.commands { margin-left: auto; position: relative; align-self: stretch; }
.commandsbtn {
  height: 100%; padding: 7px 18px; border: 0; background: var(--plate); color: var(--amber);
  font: 600 10px/1 var(--chrome); letter-spacing: .16em; text-transform: uppercase; cursor: pointer;
}
.commandsbtn:hover { color: var(--amber-hi); }
.commandpanel {
  position: absolute; right: 0; top: 100%; z-index: 20; width: 620px; padding: 14px 16px 18px;
  background: var(--panel); border: 1px solid var(--seam-bright); box-shadow: 0 18px 40px rgba(0,0,0,.6);
}
.commandpanel h4 {
  margin: 14px 0 6px; font: 600 9.5px/1 var(--chrome); letter-spacing: .2em;
  text-transform: uppercase; color: var(--ink-faint);
}
.commandpanel h4:first-child { margin-top: 0; }
.command { display: flex; align-items: center; gap: 8px; padding: 4px 0; flex-wrap: wrap; }
.command label { min-width: 168px; font-size: 11.5px; color: var(--ink); }
.command select { width: 106px; }
.command input, .command select {
  width: 92px; padding: 4px 7px; border: 1px solid var(--seam); background: #0e1114;
  color: var(--ink); font-family: var(--data); font-size: 11px;
}
.command input:focus, .command select:focus { outline: none; border-color: var(--amber); }
.command .go {
  padding: 4px 14px; border: 1px solid var(--amber-lo); background: transparent; color: var(--amber);
  font: 600 9.5px/1.6 var(--chrome); letter-spacing: .16em; text-transform: uppercase; cursor: pointer;
}
.command .go:hover { background: var(--amber-lo); color: var(--ground); }
.command .result { flex: 1 0 100%; font-family: var(--data); font-size: 10.5px; color: var(--ink-faint); }
.command .result.did { color: var(--amber-hi); }
.command .result.failed { color: #ff6b7a; }
.command .result small { display: block; color: var(--ink-faint); margin-top: 2px; }

/* ---- loads -------------------------------------------------------------- */
/*
  Three bars against the even third. A balance is a shape, not three numbers, and the rule
  is where the phase would sit if the rack were perfectly even.
*/
.racksload { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 1px; background: var(--seam); border: 1px solid var(--seam); }
/* Vertical: one rack (or service) per row, its bars on the left, what goes with it on the right. */
.racksload.vertical { grid-template-columns: 1fr; }
.racksload.vertical .rackload { display: grid; grid-template-columns: minmax(360px, 3fr) minmax(260px, 2fr); gap: 6px 18px; align-items: start; padding: 8px 12px 10px; }
.rackmoves h4 { margin: 0 0 4px; font: 700 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--amber); }
.rackmoves ul { margin: 0 0 6px; padding: 0; list-style: none; font: 11px/1.6 var(--data); color: var(--ink); columns: 2; column-gap: 16px; }
.rackmoves li b { font-weight: 600; }
.rackmoves li span { color: var(--ink-faint); }
.rackmoves .drow { display: flex; align-items: center; gap: 8px; }
.rackload.service.bad h3 em { color: #ff6b7a; }
.dashrack { margin-bottom: 4px; }
.dashrack h5 { margin: 0 0 1px; display: flex; gap: 8px; align-items: baseline; font: 600 10.5px/1.4 var(--data); color: var(--ink); }
.dashrack h5 span { color: var(--ink-faint); font-weight: 400; font-size: 9.5px; }
.phase.small { margin: 1px 0; }
.phase.small .track { height: 7px; }
.phase.small b { font-size: 9.5px; min-width: 52px; }
.rackload { background: var(--panel); padding: 12px 14px 14px; }
.rackload h3 {
  margin: 0 0 9px; display: flex; align-items: baseline; gap: 10px;
  font: 700 11.5px/1 var(--chrome); letter-spacing: .16em; text-transform: uppercase; color: var(--ink);
}
.rackload h3 span { color: var(--ink-faint); font-weight: 400; letter-spacing: .08em; font-size: 10px; }
.rackload h3 em { margin-left: auto; font-style: normal; color: var(--amber); font-family: var(--data); font-size: 11px; }
.rackload h3 em.bad { color: #ff6b7a; }
.phase { display: flex; align-items: center; gap: 9px; margin: 3px 0; }
.phase i { font-style: normal; width: 22px; color: var(--ink-faint); font: 600 9.5px/1 var(--chrome); letter-spacing: .14em; }
.phase .track { position: relative; flex: 1; height: 12px; background: #0e1114; border: 1px solid #1b1e23; }
.phase .bar { height: 100%; background: var(--metal); }
.phase .bar.over { background: linear-gradient(180deg, #ff9aa4, #d0384a); }
/* The even third, drawn as the rule the bars are read against. */
.phase .track u { position: absolute; top: -2px; bottom: -2px; width: 1px; background: var(--ink-dim); text-decoration: none; }
.phase b { min-width: 68px; text-align: right; font-family: var(--data); font-size: 10.5px; font-weight: 400; color: var(--ink-dim); }

.applybar { display: flex; align-items: center; gap: 14px; margin-top: 16px; }
.applybar .apply {
  padding: 8px 20px; border: 1px solid var(--amber-lo); background: transparent; color: var(--amber);
  font: 600 10px/1.6 var(--chrome); letter-spacing: .16em; text-transform: uppercase; cursor: pointer;
}
.applybar .apply:hover { background: var(--amber-lo); color: var(--ground); }
.applybar .apply:disabled { opacity: .5; cursor: default; }
.applybar .result { font-family: var(--data); font-size: 11px; color: var(--amber-hi); }

/* The generated cases: a proposal beside the list, so both read the same way. */
.caseplan { padding: 14px 16px 18px; }
.caseplan h3 {
  margin: 0 0 4px; font: 700 12px/1 var(--chrome); letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink);
}
.keyhint.short { color: #ff9aa4; }

/* ---- the show record --------------------------------------------------- */
/*
  Editable in place. This is the show's own record and whoever is looking at it owns the
  show, so there is no read-only mode to switch out of.
*/
.record {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1px; background: var(--seam); border: 1px solid var(--seam);
}
.field { display: flex; align-items: center; gap: 10px; padding: 7px 12px; background: var(--panel); }
.field > span {
  min-width: 148px; font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint);
}
.field input, .field select {
  flex: 1; min-width: 0; padding: 5px 8px; border: 1px solid transparent; background: transparent;
  color: var(--ink); font-family: var(--data); font-size: 11.5px;
}
.field input:hover, .field select:hover { border-color: var(--seam); background: #0e1114; }
.field input:focus, .field select:focus { outline: none; border-color: var(--amber); background: #000; }
.field input.saving, .field select.saving { border-color: var(--amber-hi); background: #2a2113; }
.field input.saved, .field select.saved { border-color: #3fbf5f; }
.field em { font-style: normal; font-size: 9.5px; color: var(--ink-faint); max-width: 120px; }

/* One column, top to bottom: a list of documents is read down, not scanned across. */
.sheets.one { grid-template-columns: 1fr; }

/* ---- cable: toggles and commands --------------------------------------- */
.toggles { display: flex; align-items: stretch; gap: 1px; }
.modes .toggles .toggle {
  display: flex; align-items: center; gap: 6px; padding: 0 11px; background: var(--panel);
  color: var(--ink-faint); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase;
  cursor: pointer; white-space: nowrap;
}
.modes .toggles .toggle:hover { color: var(--ink); }
.modes .toggles .toggle input { accent-color: var(--amber); margin: 0; }

/* The Lumenarchy commands, as buttons rather than a dropdown: these are used every day. */
.commands {
  display: flex; align-items: stretch; justify-content: flex-end; gap: 1px; position: relative;
  padding: 1px; background: var(--seam); border: 1px solid var(--seam); border-top: 0; border-bottom: 0;
  flex-wrap: wrap;
}
.commands .cmd {
  padding: 7px 12px; border: 0; background: var(--plate); color: var(--amber);
  font: 600 9.5px/1 var(--chrome); letter-spacing: .12em; text-transform: uppercase;
  cursor: pointer; white-space: nowrap;
}
.commands .cmd:hover { color: var(--ground); background: var(--metal); }
.commands .cmd.running { opacity: .5; }
.commandform {
  position: absolute; right: 0; top: 100%; z-index: 30; display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; background: var(--panel); border: 1px solid var(--seam-bright);
  box-shadow: 0 16px 36px rgba(0,0,0,.6);
}
.commandform b { font-size: 11px; color: var(--ink); white-space: nowrap; }
.commandform input, .commandform select {
  width: 96px; padding: 4px 7px; border: 1px solid var(--seam); background: #0e1114;
  color: var(--ink); font-family: var(--data); font-size: 11px;
}
.commandform input:focus, .commandform select:focus { outline: none; border-color: var(--amber); }
.commandform .go {
  padding: 4px 14px; border: 1px solid var(--amber-lo); background: transparent; color: var(--amber);
  font: 600 9.5px/1.6 var(--chrome); letter-spacing: .16em; text-transform: uppercase; cursor: pointer;
}
/* A command's result sits in the bottom-right corner, fixed, like the print notice: a box
   that came and went beside the toolbar's buttons moved them under the pointer. */
.cmdresult {
  position: fixed; right: 22px; bottom: 22px; z-index: 92; max-width: 560px; padding: 10px 14px;
  background: var(--panel); border: 1px solid var(--seam-bright);
  box-shadow: 0 18px 40px rgba(0,0,0,.6);
  font-family: var(--data); font-size: 11px; color: var(--ink-dim);
}
.cmdresult.did { color: var(--amber-hi); }
.cmdresult.failed { color: #ff6b7a; }
.cmdresult small { display: block; color: var(--ink-faint); margin-top: 2px; }
/* Each warning on its own line: run together, a list of blocking circuits reads as one
   nonsense word. */
.cmdresult em { display: block; font-style: normal; color: var(--ink-faint); margin-top: 2px; }
.cmdresult button { margin-top: 6px; }

/* A heading inside a view, wherever it appears. */
main h3 {
  margin: 0 0 4px; font: 700 12px/1 var(--chrome); letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink);
}

/* ---- the menu bar ------------------------------------------------------- */
/*
  Traditional, because this is an application people build shows in and every command should
  be findable in one obvious place, not only on the sheet that owns it.
*/
.menubar {
  display: flex; align-items: stretch; height: 26px;
  background: #101317; border-bottom: 1px solid var(--seam);
}
.menuwrap { position: relative; }
.menubar .menu {
  height: 100%; padding: 0 13px; border: 0; background: transparent; color: var(--ink-dim);
  font-size: 11.5px; cursor: pointer;
}
.menubar .menu:hover, .menubar .menu[aria-expanded="true"] { background: var(--panel-hi); color: var(--ink); }
.menupanel {
  position: absolute; left: 0; top: 100%; z-index: 80; min-width: 240px; padding: 5px 0;
  background: var(--panel); border: 1px solid var(--seam-bright);
  box-shadow: 0 16px 36px rgba(0,0,0,.62);
}
.menupanel button {
  display: flex; width: 100%; align-items: center; gap: 20px; padding: 6px 14px;
  border: 0; background: transparent; color: var(--ink); cursor: pointer;
  font-size: 12px; text-align: left; white-space: nowrap;
}
.menupanel button:hover { background: var(--panel-hi); color: var(--amber-hi); }
.menupanel button em { margin-left: auto; font-style: normal; color: var(--ink-faint); font-family: var(--data); font-size: 10px; }
.menupanel hr { margin: 4px 0; border: 0; border-top: 1px solid var(--seam); }

/* The frame sits under the faceplate and the menu bar now. */
.frame { min-height: calc(100vh - 75px); }
.gridwrap { max-height: calc(100vh - 262px); }
.grid thead th { top: 0; }

/* ---- the back end ------------------------------------------------------- */
.admin .modes { flex-wrap: wrap; }
.admin .cablebody > .keyhint { margin: 12px 14px 10px; }
.admin > .keyhint { margin-bottom: 14px; }

/* ---- truss, summarised -------------------------------------------------- */
.trussview { padding: 0; }
.trussview > .keyhint { margin: 12px 14px 10px; }
.trusslist { background: var(--panel); }
/* A grid rather than a flex row, so the columns line up down the page. */
.trussrow {
  display: grid; align-items: center; gap: 16px; padding: 7px 12px; cursor: pointer;
  grid-template-columns: 12px 70px 210px 160px 130px 200px 1fr;
  border-bottom: 1px solid #1b1e23; font-family: var(--data); font-size: 11.5px; color: var(--ink-dim);
}
.trussrow:hover { background: var(--panel-hi); }
.trussrow i { font-style: normal; width: 10px; color: var(--amber); }
.trussrow b { color: var(--ink); min-width: 62px; font-size: 13px; }
.trussrow em { text-align: right; font-style: normal; color: var(--amber); }
.trussrow .inline {
  display: flex; align-items: center; gap: 7px; cursor: text;
  font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint);
}
.trussrow .inline input {
  width: 110px; padding: 3px 7px; border: 1px solid transparent; background: transparent;
  color: var(--ink); font-family: var(--data); font-size: 11px;
}
.trussrow .inline input.sticks { width: 68px; text-align: right; }
.trussrow select.ttype {
  /* Held to its column: a select left to size itself spills over the next one. */
  width: 96px; min-width: 0; max-width: 96px; padding: 3px 6px; background: #0e1114;
  border: 1px solid var(--seam); color: var(--ink);
  font-family: var(--data); font-size: 11px;
}
/* The colour is a button because it opens the colour code rather than editing text. */
.trussrow .trusscolour {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 8px;
  background: transparent; border: 1px solid transparent; color: var(--ink-dim);
  font-family: var(--data); font-size: 11px; cursor: pointer;
}
.trussrow .trusscolour:hover { border-color: var(--seam); background: #0e1114; color: var(--ink); }
.trussrow .inline input:hover { border-color: var(--seam); background: #0e1114; }
.trussrow .inline input:focus { outline: none; border-color: var(--amber); background: #000; }
.grid.sub input {
  width: 100%; padding: 2px 6px; border: 1px solid transparent; background: transparent;
  color: var(--ink); font-family: var(--data); font-size: 11px;
}
.grid.sub input:hover { border-color: var(--seam); background: #0e1114; }
.grid.sub input:focus { outline: none; border-color: var(--amber); background: #000; }

/* ---- the rack builder --------------------------------------------------- */
/* A height nobody has stated is an assumption, and it says so rather than reading as fact. */
.shelfunits { display: inline-flex; align-items: center; gap: 4px; }
input.shelfru {
  width: 44px; padding: 2px 4px; background: transparent; border: 1px solid transparent;
  color: var(--ink-dim); font-family: var(--data); font-size: 11px; text-align: right;
}
input.shelfru:hover, input.shelfru:focus {
  border-color: var(--seam); background: #0e1114; color: var(--ink); outline: none;
}
input.shelfru.assumed { color: var(--amber); border-color: var(--amber-lo); }
input.shelfru::-webkit-inner-spin-button { opacity: 0; margin-left: 6px; transform: scale(.8); }
input.shelfru:hover::-webkit-inner-spin-button, input.shelfru:focus::-webkit-inner-spin-button { opacity: 1; }
/* What the builder says when a drop could not land where it was aimed. */
.racksaid {
  margin: 0 0 8px; padding: 7px 12px; background: var(--panel-hi);
  border-left: 2px solid var(--amber); color: var(--ink-dim);
  font-family: var(--data); font-size: 11px;
}
/*
  A rack drawn as a rack. A device is dragged into the unit it should sit at and takes as
  many units as it is tall, which is the thing a table could never show.
*/
.rackpicker { display: flex; gap: 1px; background: var(--seam); padding: 1px; margin-bottom: 12px; }
.rackpicker button {
  padding: 8px 16px; border: 0; background: var(--panel); color: var(--ink-dim); cursor: pointer;
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
}
.rackpicker button b { font: 700 12px/1 var(--chrome); letter-spacing: .12em; }
.rackpicker button span { font-family: var(--data); font-size: 9.5px; color: var(--ink-faint); }
.rackpicker button[aria-current="true"] { background: var(--plate); color: var(--amber); }
.rackpicker button[aria-current="true"] span { color: var(--amber-lo); }

.builder { padding: 12px 14px 16px; }
.buildgrid {
  display: grid; grid-template-columns: 176px 290px 290px minmax(300px, 1fr);
  gap: 14px; align-items: start;
}
.rackdata { overflow-x: auto; }
/* A device fills the units it covers, so the rack reads as blocks rather than lines. */
.builder .ru.filled { min-height: 20px; }
.rackface, .shelf, .rackdata { border: 1px solid var(--seam); background: var(--panel); }
.rackface h4, .shelf h4, .rackdata h4 {
  margin: 0; padding: 8px 12px; background: var(--plate); border-bottom: 1px solid var(--seam);
  font: 700 10px/1 var(--chrome); letter-spacing: .18em; text-transform: uppercase; color: var(--amber);
}
.builder .ru {
  display: flex; align-items: center; gap: 9px; height: 20px; padding: 0 10px;
  font-family: var(--data); font-size: 10.5px; color: var(--ink-faint);
  border-bottom: 1px dashed #1a1d22;
}
.builder .ru.filled {
  background: #15181d; color: var(--ink); border-bottom: 1px solid var(--seam);
  cursor: grab; box-shadow: inset 3px 0 0 var(--amber);
}
.builder .ru.covered { background: #121519; border-bottom: 1px dashed #202429; }
.builder .ru.target { background: #2a2113; box-shadow: inset 0 0 0 1px var(--amber); }
.shelf { padding-bottom: 6px; }
/* The library's folding headings: tight, a caret, deeper ones indented. */
.shelf .libhead {
  display: flex; align-items: center; gap: 6px; width: 100%; padding: 4px 8px; border: 0;
  border-bottom: 1px solid #1b1e23; background: var(--plate); color: var(--amber);
  font: 700 9.5px/1.4 var(--chrome); letter-spacing: .14em; text-transform: uppercase; text-align: left; cursor: pointer;
}
.shelf .libhead::before { content: '\25b8'; font-size: 9px; color: var(--ink-faint); }
.shelf .libhead[aria-expanded="true"]::before { content: '\25be'; }
.shelf .libhead:hover { color: var(--amber-hi); }
.shelf .libhead.depth1 { padding-left: 18px; background: var(--panel); }
.shelfitem .heart { flex: none; border: 0; background: transparent; padding: 0 2px; color: var(--ink-faint); font-size: 11px; cursor: pointer; line-height: 1; }
.shelfitem .heart.on, .shelfitem .heart:hover { color: var(--amber-hi); }
.shelf .libbody .keyhint.short { margin: 4px 12px; }
.shelf .libhead.depth2 { padding-left: 28px; background: var(--panel); }
.shelf .libbody.depth1 .shelfitem { padding-left: 22px; }
.shelf .libbody.depth2 .shelfitem { padding-left: 32px; }
.shelf.takesback { outline: 2px dashed var(--amber); outline-offset: -4px; }
.cellmenu button:disabled { color: var(--ink-faint); cursor: default; }
.shelfitem {
  display: flex; align-items: center; gap: 8px; padding: 6px 12px; cursor: grab;
  border-bottom: 1px solid #1b1e23; font-family: var(--data); font-size: 10.5px; color: var(--ink);
}
.shelfitem:hover { background: var(--panel-hi); }
.shelfitem span { margin-left: auto; color: var(--ink-faint); }
.rackdata table { border: 0; }

/* ---- loading a new bill of materials ------------------------------------ */
.importbar {
  display: flex; align-items: center; gap: 10px; margin-bottom: 12px;
  padding: 8px 12px; background: var(--panel); border: 1px solid var(--seam);
}
.importbar span { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); }
.importbar .bompath {
  flex: 1; min-width: 0; padding: 5px 9px; border: 1px solid var(--seam); background: #0e1114;
  color: var(--ink); font-family: var(--data); font-size: 11px;
}
.importbar .bompath:focus { outline: none; border-color: var(--amber); }
.bomdiff { margin-bottom: 14px; }
/* An addition, a cut and a change each read at a glance. */
tr.diff.added td { color: #6fd48a; }
tr.diff.removed td { color: #ff8f9b; }
tr.diff.changed td { color: var(--amber-hi); }

/* Spares edit either way: set the percentage or set the count. */
.info input.sp {
  width: 74px; padding: 3px 6px; border: 1px solid transparent; background: transparent;
  color: var(--ink); font-family: var(--data); font-size: 11.5px; text-align: right;
}

/*
 * The spinner, out of the way of the number.
 *
 * A browser's stepper sits hard against the digits and is drawn at the browser's own size,
 * which over a right-aligned number reads as part of it — six with two arrows on it is not
 * a number anybody can check at a glance. This shrinks it, holds it away from the text, and
 * only shows it on the field being worked in.
 */
input[type=number].sp, input[type=number].sticks { padding-right: 4px; }
input[type=number].sp::-webkit-inner-spin-button,
input[type=number].sticks::-webkit-inner-spin-button {
  opacity: 0; margin-left: 8px; height: 18px; transform: scale(.85);
  transition: opacity .1s;
}
input[type=number].sp:hover::-webkit-inner-spin-button,
input[type=number].sp:focus::-webkit-inner-spin-button,
input[type=number].sticks:hover::-webkit-inner-spin-button,
input[type=number].sticks:focus::-webkit-inner-spin-button { opacity: 1; }
/* Firefox draws its own, and only honours being asked for it or not. */
input[type=number].sp, input[type=number].sticks { -moz-appearance: textfield; }
input[type=number].sp:hover, input[type=number].sp:focus,
input[type=number].sticks:hover, input[type=number].sticks:focus { -moz-appearance: number-input; }
.info input.sp:hover { border-color: var(--seam); background: #0e1114; }
.info input.sp:focus { outline: none; border-color: var(--amber); background: #000; }
.publishpath {
  flex: 1; min-width: 0; padding: 5px 9px; background: #0e1114; border: 1px solid var(--seam);
  color: var(--ink-dim); font-family: var(--data); font-size: 11px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.importbar .result { font-family: var(--data); font-size: 10.5px; color: var(--ink-faint); }
.importbar .result.did { color: var(--amber-hi); }
.importbar .result.failed { color: #ff6b7a; }
.scalarfield { display: flex; align-items: center; gap: 12px; padding: 10px 14px 16px; }
.scalarfield span { min-width: 130px; font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); }
.scalarfield input.scalar {
  flex: 1; padding: 7px 10px; border: 1px solid var(--seam); background: #0e1114;
  color: var(--ink); font-family: var(--data); font-size: 12px;
}
.scalarfield input.scalar:focus { outline: none; border-color: var(--amber); background: #000; }
.scalarfield input.scalar.saving { border-color: var(--amber-hi); background: #2a2113; }
.scalarfield input.scalar.saved { border-color: #3fbf5f; }

/* ---- sending paperwork out ---------------------------------------------- */
.sendpanel { border: 1px solid var(--seam); background: var(--panel); padding: 12px 14px 14px; margin-bottom: 14px; }
.sendpanel > .keyhint { margin: 0 0 10px; }
.people { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1px; background: var(--seam); border: 1px solid var(--seam); margin-bottom: 12px; }
.person { display: flex; align-items: center; gap: 9px; padding: 7px 11px; background: var(--panel); cursor: pointer; font-size: 11.5px; }
.person:hover { background: var(--panel-hi); }
.person input { accent-color: var(--amber); }
.person b { color: var(--ink); }
.person span { margin-left: auto; color: var(--ink-faint); font-family: var(--data); font-size: 10px; }
.sendpreview {
  margin: 0 0 12px; padding: 12px 14px; max-height: 260px; overflow: auto;
  background: #0e1114; border: 1px solid var(--seam); color: var(--ink-dim);
  font-family: var(--data); font-size: 11px; line-height: 1.55; white-space: pre-wrap;
}

/* ---- the case-is-full prompt -------------------------------------------- */
/*
  Raised at the moment a part is assigned rather than found later on a report, and it stays
  until it is answered — a packing decision should not vanish while you are looking at the
  sheet to make it.
*/
.casefull {
  position: fixed; right: 22px; bottom: 22px; z-index: 90; max-width: 560px;
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  padding: 14px 16px; background: var(--panel); border: 1px solid var(--amber-lo);
  box-shadow: 0 20px 44px rgba(0,0,0,.66);
}
.casefull b {
  flex: 1 0 100%; font: 700 11px/1 var(--chrome); letter-spacing: .16em;
  text-transform: uppercase; color: var(--amber);
}
.casefull > span { flex: 1 0 100%; font-family: var(--data); font-size: 11.5px; color: var(--ink); }
.casefull .cmd {
  padding: 6px 14px; border: 1px solid var(--amber-lo); background: transparent; color: var(--amber);
  font: 600 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; cursor: pointer;
}
.casefull .cmd:hover { background: var(--amber-lo); color: var(--ground); }
.casefull .cmd.dismiss { border-color: var(--seam); color: var(--ink-faint); }
.casefull .cmd.dismiss:hover { background: var(--seam); color: var(--ink); }
.menupanel button:disabled { color: var(--ink-faint); cursor: default; }
.menupanel button:disabled:hover { background: transparent; color: var(--ink-faint); }

/* ---- the sheet is a spreadsheet ---------------------------------------- */
/*
  The chrome stays dark — it is a rack panel and it should look like one. The sheet does not.
  People know what a spreadsheet looks like: a light ground, black text, thin grey rules. Dark
  on dark was the one place the theme cost legibility, and legibility is the whole job here.

  So: black text on white, and white text only where a cell is deliberately dark — a tape
  colour so dark that black would disappear on it.
*/
:root {
  --sheet: #ffffff;
  --sheet-alt: #f4f6f8;
  --sheet-line: #d3d8de;
  --sheet-rule: #b8bfc8;
  --sheet-ink: #14171b;
  --sheet-dim: #5d6672;
  --sheet-head: #e6e9ed;
  --sheet-sel: #cddcef;
  --sheet-at: #a9c6e8;
}

.sheetframe { border-color: var(--seam-bright); }
.gridwrap { background: var(--sheet); }

.grid tbody td {
  background: var(--sheet);
  color: var(--sheet-ink);
  border-right: 1px solid var(--sheet-line);
  border-bottom: 1px solid var(--sheet-line);
}
.grid tbody tr:nth-child(even) td { background: var(--sheet-alt); }
.grid tbody tr:hover td { background: #eaf0f7; }
.grid tbody tr:hover { box-shadow: none; }
.grid td.dim { color: var(--sheet-dim); }
.grid td.ro { color: var(--sheet-dim); background: #eef0f3; }
.grid tbody tr:nth-child(even) td.ro { background: #e9ecef; }
/*
 * Port tints: the same colour on every row, stripe or no stripe.
 *
 * Pale on purpose. What is being read is the universe number; the tint only says which of
 * these are the spares, and a strong green down twenty columns is a wall.
 */
.grid tbody td.tint-active, .grid tbody tr:nth-child(even) td.tint-active { background: #e9f6ec; }
.grid tbody td.tint-spare, .grid tbody tr:nth-child(even) td.tint-spare { background: #fbeafb; }
/* A twofer, and the leg it makes: solid amber with dark ink, which reads at a glance where a
   tinted brown did not. */
.grid tbody td.tint-twofer, .grid tbody tr:nth-child(even) td.tint-twofer { background: #f7a531; color: #101317; }
.grid tbody td.tint-leg, .grid tbody tr:nth-child(even) td.tint-leg { background: #ffd58a; color: #101317; }

.grid thead th {
  background: var(--sheet-head);
  color: #2c333c;
  border-bottom: 1px solid var(--sheet-rule);
  border-right: 1px solid var(--sheet-rule);
}
.grid thead th.sorted { color: #a35200; }
.grid thead th[data-c]:hover { color: #000; background: #dde2e8; }
.grid th.rownum {
  background: var(--sheet-head);
  color: #5d6672;
  border-right: 1px solid var(--sheet-rule);
  border-bottom: 1px solid var(--sheet-line);
}
.grid tbody tr:nth-child(even) th.rownum { background: #dfe3e8; }

/*
  A dragged selection used to smear the browser's own text highlight across the cells. The
  grid does its own selecting, so the native one is turned off — it was never adding
  anything, and over a block of forty cells it was unreadable.
*/
.grid { user-select: none; }
.grid .cell-edit { user-select: text; }

.grid td.sel { background: var(--sheet-sel) !important; }
.grid tbody tr:nth-child(even) td.sel { background: #c6d6e9 !important; }
.grid td.at { background: var(--sheet-at) !important; color: #000; box-shadow: inset 0 0 0 2px #0b63c5; }
.grid:focus td.at { box-shadow: inset 0 0 0 2px #0b63c5, 0 0 0 1px rgba(11,99,197,.35); }
.grid th.rownum.at { color: #fff; background: #0b63c5; }
.grid th.rownum.sel { color: #0b63c5; background: #cddcef; }

.grid td.saving { background: #fff3cd !important; }
.grid td.saved { background: #d6f0d8 !important; }
.grid td.failed { background: #fbd6da !important; box-shadow: inset 0 0 0 2px #c0392b; }
.grid td.warn { color: #a01824; background: #fbe3e5 !important; box-shadow: inset 2px 0 0 #c0392b; }

.cell-edit { background: #fff; color: #10131a; box-shadow: inset 0 0 0 2px #0b63c5; }
select.cell-edit { background: #fff; color: #10131a; }

.cellbar { background: var(--sheet-head); border-bottom: 1px solid var(--sheet-rule); }
.cellbar .addr { background: var(--plate); }
.cellbar .barvalue { color: var(--sheet-ink); }
.cellbar .barvalue:focus { background: #fff; box-shadow: inset 0 0 0 2px #0b63c5; }
.cellbar .barvalue:read-only { color: var(--sheet-dim); }

/* Sub-tables inside a tree are the same sheet. */
.grid.sub tbody td { background: var(--sheet); color: var(--sheet-ink); border-color: var(--sheet-line); }
.grid.sub tbody tr:nth-child(even) td { background: var(--sheet-alt); }
.grid.sub thead th { background: var(--sheet-head); color: #2c333c; border-color: var(--sheet-rule); }
.grid.sub td.dim { color: var(--sheet-dim); }
.grid.sub input { color: var(--sheet-ink); }
.grid.sub input:hover { border-color: var(--sheet-rule); background: #fff; }
.grid.sub input:focus { background: #fff; box-shadow: inset 0 0 0 2px #0b63c5; }

/* A cell filled with its own colour keeps its rules but loses the banding underneath it. */
.grid td.filled { font-weight: 600; }
.grid tbody tr:nth-child(even) td.filled,
.grid tbody tr:hover td.filled { background: inherit; }

/* Positioned, so a fill bar can sit behind the number. */
.grid td { position: relative; }

/* Bars and chips against a light cell. */
.cellbar-track { background: #e3e7ec; }
.cellbar-fill { opacity: .75; background: #f0a02a; }
.cellbar-fill.over { background: #e05a67; }
.chip { box-shadow: inset 0 0 0 1px rgba(0,0,0,.35); }

/* The plain tables that are not grids keep the dark treatment: they are chrome, not sheets. */

/* The cell picker: a list under the cell, not wherever the platform puts a native popup. */
.cellpicker {
  position: fixed; z-index: 70; max-height: 240px; overflow-y: auto;
  background: #fff; border: 1px solid var(--sheet-rule);
  box-shadow: 0 14px 30px rgba(0,0,0,.4);
}
.cellpicker button {
  display: block; width: 100%; padding: 5px 10px; border: 0; background: transparent;
  color: var(--sheet-ink); font-family: var(--data); font-size: 11.5px;
  text-align: left; white-space: nowrap; cursor: pointer;
}
.cellpicker button:hover, .cellpicker button.on { background: var(--sheet-sel); }
/* The multi-select: a tick down the left, and a Done that closes it. */
.cellpicker.checks button { font-family: var(--data); white-space: pre; }
.cellpicker.checks button.done {
  position: sticky; bottom: 0; border-top: 1px solid var(--seam);
  background: var(--panel); font-family: var(--chrome); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; font-size: 9.5px;
}

/* Only the arrow opens a row; the row itself is where the fields are. */
.trussrow { cursor: default; }
.trussrow i.arrow { cursor: pointer; }
.trussrow i.arrow:hover { color: var(--amber-hi); }

/* A question asked where the app is about to do more than the cell implies. */
.askbox {
  position: fixed; left: 50%; top: 26%; transform: translateX(-50%); z-index: 95;
  max-width: 560px; display: flex; flex-wrap: wrap; gap: 10px;
  padding: 18px 20px; background: var(--panel); border: 1px solid var(--amber-lo);
  box-shadow: 0 24px 56px rgba(0,0,0,.7);
}
.askbox p { flex: 1 0 100%; margin: 0 0 4px; font-size: 13px; line-height: 1.5; color: var(--ink); }
.askbox .cmd {
  padding: 7px 16px; border: 1px solid var(--amber-lo); background: transparent; color: var(--amber);
  font: 600 10px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; cursor: pointer;
}
.askbox .cmd:hover { background: var(--amber-lo); color: var(--ground); }
.askbox .cmd.dismiss { border-color: var(--seam); color: var(--ink-faint); }
.askbox .cmd.dismiss:hover { background: var(--seam); color: var(--ink); }
/* The colour-code offer: three bands and a type, laid out as the colour sheet has them. */
.askbox .askrow { flex: 1 0 100%; display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 6px; }
.askbox .askrow label { display: flex; flex-direction: column; gap: 4px; }
.askbox .askrow span {
  font: 700 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-faint);
}
.askbox .askpick {
  padding: 5px 8px; background: #0e1114; border: 1px solid var(--seam);
  color: var(--ink); font-family: var(--data); font-size: 11.5px;
  min-width: 130px; width: 130px;
}
.askbox .askpick option { background: #0e1114; color: var(--ink); }
/* The order's out-of-date bar: what changed, and the two ways to send it on. */
.orderbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 0 0 6px; padding: 6px 10px;
  border: 1px solid var(--amber-lo); background: var(--panel); font: 11px/1.4 var(--data); color: var(--ink);
}
.orderbar b { color: var(--amber); }
.orderbar .dim { color: var(--ink-faint); }
.cellpicker button.painted.on { outline: 2px solid var(--amber-hi); outline-offset: -2px; }
.askbox .askband { display: flex; align-items: center; gap: 6px; }
.askbox .askswatch {
  width: 12px; height: 12px; flex: none; border: 1px solid var(--seam);
}

/* A print goes without a dialog, so it has to say what it did. */
.printsaid {
  position: fixed; right: 22px; bottom: 22px; z-index: 92; max-width: 460px;
  padding: 11px 16px; background: var(--panel); border: 1px solid var(--seam-bright);
  box-shadow: 0 18px 40px rgba(0,0,0,.6);
  font-family: var(--data); font-size: 11.5px; color: var(--ink);
}
.printsaid.ok { border-color: var(--amber-lo); color: var(--amber-hi); }
.printsaid.failed { border-color: #c0392b; color: #ff8f9b; }

.sheet .rowprint {
  margin-left: 14px; padding: 4px 12px; border: 1px solid var(--amber-lo); background: transparent;
  color: var(--amber); font: 600 9px/1.6 var(--chrome); letter-spacing: .16em;
  text-transform: uppercase; cursor: pointer;
}
.sheet .rowprint:hover { background: var(--amber-lo); color: var(--ground); }
.sheet .rowsetup { margin-left: 10px; border-color: var(--seam); color: var(--ink-faint); }
.sheet .rowsetup:hover { background: var(--seam); color: var(--ink); }

/* Page setup: a printer's worth of choices in one box, laid out as a printer dialog is. */
.askbox.asksetup { max-width: 720px; top: 12%; }
.askbox.asksetup .askgrid label.wide .askpick { width: 330px; }
.askbox.asksetup .askfield.options { width: 330px; font-family: var(--data); font-size: 11px; resize: vertical; }
.askbox .setupnote { flex: 1 0 100%; font: 11px/1.5 var(--data); color: var(--ink-faint); font-style: normal; }


/* ---- the chrome, condensed ---------------------------------------------- */
/*
  Three stacked bars became two thin ones. Every row above the sheet is a row of the sheet
  you cannot see, and this app exists to show as much of the sheet as will fit.
*/
.titlebar {
  display: flex; align-items: stretch; height: 28px;
  background: var(--plate); border-bottom: 1px solid var(--seam); position: relative;
}
.titlebar::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.10) 22%, transparent 78%);
}
.titlebar .mark {
  display: flex; align-items: center; gap: 8px; padding: 0 14px 0 16px;
  border-right: 1px solid var(--seam);
}
.titlebar .mark b {
  font: 700 13px/1 var(--chrome); letter-spacing: .16em; text-transform: uppercase;
  background: var(--metal); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.titlebar .mark i {
  font-style: normal; font-size: 9.5px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--ink-faint);
}
.titlebar .menubar { border: 0; background: transparent; height: 100%; }
.titlebar .plate-right { margin-left: auto; display: flex; align-items: center; gap: 14px; padding: 0 16px; }

/* Show tabs: a show is a document, and the tools are the same for every one of them. */
.shows {
  display: flex; align-items: stretch; height: 30px; gap: 1px;
  background: var(--ground); border-bottom: 1px solid var(--seam); padding-left: 8px;
}
/*
 * One line, so a tab is a tab: the name, the venue faint beside it, the close mark. The
 * earlier rule above stacks them in a column; that stack is taller than the 30px strip and,
 * centred, spilled up over the title bar (the owner's screenshot, 2026-09-16), so the row
 * direction is set here where the strip's height is.
 */
.show-tab {
  display: flex; flex-direction: row; align-items: center; justify-content: flex-start;
  gap: 9px; padding: 0 14px; height: 100%; min-width: 0; overflow: hidden;
  border: 0; border-right: 1px solid var(--seam); background: #14171c;
  color: var(--ink-dim); cursor: pointer; white-space: nowrap;
}
.show-tab b { font: 700 11px/1 var(--chrome); letter-spacing: .1em; text-transform: uppercase; }
.show-tab i { font-style: normal; font-size: 9.5px; color: var(--ink-faint); max-width: 180px; overflow: hidden; text-overflow: ellipsis; }
.show-tab u { text-decoration: none; margin-left: 4px; color: var(--ink-faint); font-size: 13px; }
.show-tab u:hover { color: #ff8f9b; }
.show-tab:hover { color: var(--ink); background: var(--panel-hi); }
.show-tab[aria-selected="true"] {
  background: var(--panel); color: var(--ink); box-shadow: inset 0 2px 0 var(--amber);
}
.show-add {
  padding: 0 12px; height: 100%; border: 0; background: transparent; color: var(--ink-faint);
  font-size: 15px; cursor: pointer;
}
.show-add:hover { color: var(--amber); }
.show-share {
  margin-left: auto; padding: 0 12px; height: 100%; border: 0; border-left: 1px solid var(--seam);
  background: transparent; color: var(--ink-faint); font-size: 12px; cursor: pointer;
}
.show-share:hover { color: var(--amber); }
.askbox.share { min-width: 560px; max-width: 720px; }
.askbox.share .sharebody { flex: 1 0 100%; display: flex; flex-wrap: wrap; gap: 10px; }
.askbox.share .sharebody > * { flex: 1 0 100%; }
.askbox.share .floortable { max-height: 280px; overflow: auto; margin: 6px 0; }
.askbox.share tr.pending td { color: var(--ink-dim); font-style: italic; }
.askbox.share select.askfield { width: auto; }
.showpicker {
  position: fixed; z-index: 88; min-width: 240px; padding: 5px 0;
  background: var(--panel); border: 1px solid var(--seam-bright); box-shadow: 0 16px 36px rgba(0,0,0,.6);
}
.showpicker button {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  width: 100%; padding: 7px 14px; border: 0; background: transparent; cursor: pointer; text-align: left;
}
.showpicker button:hover { background: var(--panel-hi); }
.showpicker b { font-size: 12px; color: var(--ink); }
.showpicker span { font-family: var(--data); font-size: 10px; color: var(--ink-faint); }
.showpicker p { margin: 8px 14px; }

/* The contextual toolbar: where you are, and this section's own tools. */
.toolbar {
  display: flex; align-items: stretch; gap: 1px; min-height: 30px;
  background: var(--seam); border-bottom: 1px solid var(--seam); flex-wrap: wrap;
}
.toolbar .where {
  display: flex; align-items: baseline; gap: 10px; padding: 0 16px; background: var(--panel);
}
.toolbar .where b {
  font: 700 12px/30px var(--chrome); letter-spacing: .16em; text-transform: uppercase; color: var(--ink);
}
.toolbar .where span { font-size: 10px; letter-spacing: .06em; color: var(--ink-faint); }
.toolbar .modes, .toolbar .commands { border: 0; padding: 0; background: var(--seam); }
.toolbar .commandform { top: 30px; }
.toolbar .railtoggle, .toolbar .keys {
  width: 30px; border: 0; background: var(--panel); color: var(--ink-faint); cursor: pointer; font-size: 11px;
}
.toolbar .keys { margin-left: auto; font-weight: 700; }
/* What the sheets are doing in the background: behind, rendering, current. */
/* The render status: a fixed box bottom-right, the corner every command's result uses, and
   never in the toolbar's flow (the owner, 2026-09-16). A print notice in the same corner
   lifts it out of the way. */
.renderpill {
  position: fixed; right: 22px; bottom: 22px; z-index: 91; max-width: 460px;
  padding: 9px 14px; background: var(--panel); border: 1px solid var(--seam-bright);
  box-shadow: 0 18px 40px rgba(0,0,0,.6);
  font-family: var(--data); font-size: 11px; color: var(--ink-faint); white-space: nowrap;
}
.renderpill[hidden] { display: none; }
body:has(.printsaid) .renderpill { bottom: 64px; }
.renderpill.behind { color: var(--amber); border-color: var(--amber-lo); }
.renderpill.busy { color: var(--amber-hi); border-color: var(--amber-lo); }
.renderpill.current { color: var(--ink-faint); }
.renderpill.failed { color: #ff6b7a; border-color: #ff6b7a; }
.toolbar .railtoggle:hover, .toolbar .keys:hover { color: var(--amber); background: var(--panel-hi); }
.keyspop {
  position: fixed; z-index: 88; max-width: 380px; padding: 12px 16px;
  background: var(--panel); border: 1px solid var(--seam-bright); box-shadow: 0 16px 36px rgba(0,0,0,.6);
  font-family: var(--data); font-size: 11px; line-height: 1.9; color: var(--ink-dim);
}

/* The rail collapses to nothing, and remembers which it was. */
.frame { grid-template-columns: 188px 1fr; min-height: calc(100vh - 89px); }
/* One column, not a zero-width one: `display:none` takes the rail out of the grid, so a
   two-column template would auto-place the main pane into the empty first column and
   collapse the whole window to nothing. */
body.railshut .frame { grid-template-columns: 1fr; }
body.railshut .rail { display: none; }
main { padding: 14px 18px 60px; }
main > h2, main > .sub { display: none; }
.gridwrap { max-height: calc(100vh - 190px); }


/* ---- every sheet-shaped table reads the same ---------------------------- */
/*
  The interactive grids went light first; the read-only tables that sit beside them — the
  case plan, the review, the balance, the equipment counts — are the same kind of thing and
  were still dark. One look for anything laid out in rows and columns.
*/
main table.grid:not(.sub) tbody td,
.caseplan table tbody td,
.info table tbody td,
.loads table tbody td,
.rackdata table tbody td {
  background: var(--sheet); color: var(--sheet-ink);
  border-right: 1px solid var(--sheet-line); border-bottom: 1px solid var(--sheet-line);
}
main table.grid:not(.sub) tbody tr:nth-child(even) td,
.caseplan table tbody tr:nth-child(even) td,
.info table tbody tr:nth-child(even) td,
.loads table tbody tr:nth-child(even) td,
.rackdata table tbody tr:nth-child(even) td { background: var(--sheet-alt); }
main table.grid:not(.sub) thead th,
.caseplan table thead th,
.info table thead th,
.loads table thead th,
.rackdata table thead th {
  background: var(--sheet-head); color: #2c333c;
  border-bottom: 1px solid var(--sheet-rule); border-right: 1px solid var(--sheet-rule);
}
.caseplan table td.dim, .info table td.dim, .loads table td.dim, .rackdata table td.dim { color: var(--sheet-dim); }
.info table td.short { color: #b3121f; }
.info input.sp { color: var(--sheet-ink); }
.info input.sp:hover { border-color: var(--sheet-rule); background: #fff; }
.info input.sp:focus { background: #fff; box-shadow: inset 0 0 0 2px #0b63c5; }
.rackdata table input { color: var(--sheet-ink); }
tr.diff.added td { color: #1a7a33; }
tr.diff.removed td { color: #b3121f; }
tr.diff.changed td { color: #a35200; }

/* The show record is a form, not a sheet, but it is worked in the same way. */
.record { background: var(--sheet-line); }
.field { background: var(--sheet); }
.field > span { color: #4a525d; }
.field input, .field select { color: var(--sheet-ink); }
.field input:hover, .field select:hover { border-color: var(--sheet-rule); background: #fff; }
.field input:focus, .field select:focus { background: #fff; box-shadow: inset 0 0 0 2px #0b63c5; border-color: #0b63c5; }
.field em { color: #6b7480; }

/* ---- conditional shading on the balance --------------------------------- */
/* Short is red, over is green, exactly right is neither: the colour is how you find the one
   number that matters in a column of eighty. */
.info td.balance.under { background: #fbe3e5; color: #a01824; font-weight: 600; }
.info td.balance.over { background: #ddf1de; color: #1a6b2b; }
.info td.balance.level { color: var(--sheet-dim); }

/* ---- previewing a rendered sheet ---------------------------------------- */
/* Clicking a sheet shows it; only the button prints it. Checking a sheet means looking at it
   before it goes to paper. */
.previewer {
  position: fixed; inset: 60px 40px 40px; z-index: 96; display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--seam-bright); box-shadow: 0 30px 80px rgba(0,0,0,.7);
}
.previewbar {
  display: flex; align-items: center; gap: 12px; padding: 10px 14px;
  background: var(--plate); border-bottom: 1px solid var(--seam);
}
.previewbar b {
  flex: 1; font: 700 12px/1 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink);
}
.previewbar .cmd {
  padding: 6px 16px; border: 1px solid var(--amber-lo); background: transparent; color: var(--amber);
  font: 600 9.5px/1.6 var(--chrome); letter-spacing: .16em; text-transform: uppercase; cursor: pointer;
}
.previewbar .cmd:hover { background: var(--amber-lo); color: var(--ground); }
.previewbar .cmd.dismiss { border-color: var(--seam); color: var(--ink-faint); }
.previewer iframe { flex: 1; width: 100%; border: 0; background: #333; }
/*
 * Pages are pictures on a grey table, as many across as the panel is wide.
 *
 * A strip you scroll rather than one page with arrows: a label sheet is checked by running
 * an eye down it, and a wheel does that in one gesture where a Next button does it three
 * hundred times. `--page-width` is set by the + and - buttons and decides how many fit.
 */
.previewbody {
  flex: 1; min-height: 0; overflow: auto; padding: 18px; background: #2a2d31;
  display: grid; gap: 16px; align-content: start;
  grid-template-columns: repeat(auto-fill, minmax(var(--page-width, 300px), 1fr));
}
.previewbody figure {
  /* The page's own shape, held before its picture arrives, so the sheet lays out once. */
  position: relative; margin: 0; aspect-ratio: var(--page-aspect, 3 / 2);
  background: #21242a; border: 1px solid #34383e;
}
.previewbody figcaption {
  position: absolute; left: 0; top: 0; padding: 2px 7px; z-index: 2;
  background: rgba(0,0,0,.55); color: #c8ccd2;
  font-family: var(--data); font-size: 10.5px;
}
.previewpage {
  display: block; width: 100%; height: 100%; object-fit: contain;
  background: #fff; box-shadow: 0 8px 22px rgba(0,0,0,.45);
}
.previewwhere {
  font-family: var(--data); font-size: 11px; color: var(--ink-faint); min-width: 92px; text-align: center;
}
.previewbar .cmd[disabled] { opacity: .35; cursor: default; }
.previewbar a.cmd { text-decoration: none; }

/* The sections of a sheet, on the preview's bar: where each truss and each type begins. */
.previewjump {
  min-width: 0; width: 160px; padding: 4px 8px; background: #0e1114; border: 1px solid var(--seam);
  color: var(--ink); font-family: var(--data); font-size: 11px;
}

/* A sheet that was rendered before the show was last saved. */
.sheet .stalemark {
  font-style: normal; font-family: var(--data); font-size: 10.5px; color: var(--amber);
}
.sheet.stale { border-left: 2px solid var(--amber); }

/* ---- the review, worked through one at a time --------------------------- */
.reviewhead { display: flex; align-items: center; gap: 14px; margin-bottom: 10px; }
.reviewcount { font-family: var(--data); font-size: 11px; color: var(--ink-faint); }
.wizard { max-width: 760px; }
.wizardbar { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.wizardwhere { font-family: var(--data); font-size: 11px; color: var(--ink-faint); }
.wizardcard {
  padding: 18px 20px; background: var(--panel); border: 1px solid var(--seam-bright);
  border-left: 3px solid var(--amber);
}
.wizardcard h4 {
  margin: 0 0 8px; font: 700 10px/1 var(--chrome); letter-spacing: .16em;
  text-transform: uppercase; color: var(--amber);
}
.wizardsays { margin: 0 0 10px; font-size: 13.5px; line-height: 1.55; color: var(--ink); }
.wizardfix {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 14px 0;
  padding: 12px; background: var(--plate); border: 1px solid var(--seam);
}
.wizardfix > span {
  font: 700 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint);
}
.wizardfix .scalar {
  width: 110px; padding: 5px 8px; background: #0e1114; border: 1px solid var(--seam);
  color: var(--ink); font-family: var(--data); font-size: 11.5px;
}
.wizardfix em { font-style: normal; color: #ff8f9b; font-family: var(--data); font-size: 11px; }
.wizardacts { display: flex; gap: 8px; margin-top: 14px; }
.wizardacts .cmd, .wizardbar .cmd, .wizardfix .cmd {
  padding: 6px 14px; border: 1px solid var(--amber-lo); background: transparent; color: var(--amber);
  font: 600 9.5px/1.6 var(--chrome); letter-spacing: .12em; text-transform: uppercase; cursor: pointer;
}
.wizardacts .cmd.dismiss, .wizardbar .cmd.dismiss { border-color: var(--seam); color: var(--ink-faint); }
.wizardacts .cmd:hover, .wizardbar .cmd:hover, .wizardfix .cmd:hover { background: var(--amber-lo); color: var(--ground); }
.wizarddone { font-size: 15px; color: var(--amber-hi); margin: 20px 0 6px; }
/* The standing note under the card, clear of its edge. */
.wizard > .keyhint { margin-top: 14px; max-width: 620px; }
.review-item { position: relative; }
.review-item.done { opacity: .5; }
.review-kind.aside { color: var(--ink-faint); }
.reviewrowacts { display: flex; gap: 6px; margin-top: 6px; }
.reviewrowacts .cmd {
  padding: 3px 10px; border: 1px solid var(--seam); background: transparent; color: var(--ink-faint);
  font: 600 9px/1.6 var(--chrome); letter-spacing: .12em; text-transform: uppercase; cursor: pointer;
}
.reviewrowacts .cmd:hover { border-color: var(--amber-lo); color: var(--amber); }

/* ---- find and replace, on every sheet ----------------------------------- */
.findbar {
  position: absolute; right: 12px; top: 34px; z-index: 8; display: flex; align-items: center; gap: 6px;
  padding: 6px 8px; background: var(--panel); border: 1px solid var(--seam-bright);
  box-shadow: 0 12px 30px rgba(0,0,0,.5);
}
.findbar .findinput {
  width: 150px; padding: 4px 7px; background: #0e1114; border: 1px solid var(--seam);
  color: var(--ink); font-family: var(--data); font-size: 11.5px;
}
.findbar .findinput:focus { outline: none; border-color: var(--amber); }
/* Replace is hidden until Ctrl+H asks for it: find alone is the common case. */
.findbar .findinput:nth-of-type(2), .findbar .findsep,
.findbar .findgo:nth-of-type(3), .findbar .findgo:nth-of-type(4) { display: none; }
.findbar.replacing .findinput:nth-of-type(2), .findbar.replacing .findsep,
.findbar.replacing .findgo:nth-of-type(3), .findbar.replacing .findgo:nth-of-type(4) { display: inline-flex; }
.findbar .findsep { width: 1px; height: 18px; background: var(--seam); }
.findcount {
  min-width: 62px; text-align: center; font-family: var(--data); font-size: 10.5px; color: var(--ink-faint);
}
.findbar .findgo, .findbar .findopt {
  display: inline-flex; align-items: center; padding: 4px 8px; background: transparent;
  border: 1px solid var(--seam); color: var(--ink-dim);
  font-family: var(--chrome); font-size: 10px; letter-spacing: .08em; cursor: pointer;
}
.findbar .findgo:hover, .findbar .findopt:hover { border-color: var(--amber-lo); color: var(--amber); }
.findbar .findopt[aria-pressed="true"] { border-color: var(--amber); color: var(--amber); background: var(--panel-hi); }
/* A match, and the one the cursor is on. */
.grid tbody td.found { box-shadow: inset 0 0 0 2px #f2c14e; }
.grid tbody td.here { box-shadow: inset 0 0 0 2px #e08a2c; background: #fff4d6 !important; }
/* Where a jump from the review list or the workbook search landed. */
.grid tbody td.landed { animation: landed 1.6s ease-out; }
@keyframes landed {
  0% { background: #ffe9a8 !important; }
  100% { background: transparent; }
}

/* The whole-show find: results grouped by the sheet they are on. */
.findall {
  position: fixed; right: 24px; top: 74px; bottom: 24px; width: 420px; z-index: 94;
  display: flex; flex-direction: column; gap: 8px; padding: 14px;
  background: var(--panel); border: 1px solid var(--seam-bright);
  box-shadow: 0 24px 60px rgba(0,0,0,.6);
}
.findallbar { display: flex; align-items: center; gap: 8px; }
.findallbar b {
  flex: 1; font: 700 11px/1 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink);
}
.findallrow { display: flex; gap: 8px; }
.findallrow .scalar {
  flex: 1; padding: 5px 8px; background: #0e1114; border: 1px solid var(--seam);
  color: var(--ink); font-family: var(--data); font-size: 11.5px;
}
.findallrow .scalar:focus { outline: none; border-color: var(--amber); }
.findall .cmd {
  padding: 5px 12px; border: 1px solid var(--amber-lo); background: transparent; color: var(--amber);
  font: 600 9.5px/1.6 var(--chrome); letter-spacing: .12em; text-transform: uppercase; cursor: pointer;
}
.findall .cmd.dismiss { border-color: var(--seam); color: var(--ink-faint); }
.findall .findopt {
  padding: 4px 8px; background: transparent; border: 1px solid var(--seam); color: var(--ink-dim);
  font-family: var(--chrome); font-size: 10px; cursor: pointer;
}
.findall .findopt[aria-pressed="true"] { border-color: var(--amber); color: var(--amber); }
.findresults { flex: 1; min-height: 0; overflow: auto; }
.findgroup h5 {
  display: flex; gap: 8px; margin: 10px 0 4px;
  font: 700 9.5px/1 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--amber);
}
.findgroup h5 em { font-style: normal; color: var(--ink-faint); }
.findhit {
  display: grid; grid-template-columns: 130px 96px 1fr; gap: 8px; width: 100%; text-align: left;
  padding: 4px 6px; background: transparent; border: 0; border-bottom: 1px solid #14171c;
  color: var(--ink-dim); font-family: var(--data); font-size: 11px; cursor: pointer;
}
.findhit:hover { background: var(--panel-hi); color: var(--ink); }
.findhit b { color: var(--ink); font-weight: 400; }
.findhit span { color: var(--ink-faint); }
.findhit code { color: var(--amber); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- the rail: categories, subcategories, and reordering ---------------- */
.railgroup { border-bottom: 1px solid #14171c; }
.railgroup.dragging { opacity: .45; }
.rail button.sub { padding-left: 34px; font-size: 12px; color: var(--ink-faint); }
.rail button.sub:hover { color: var(--ink); }
.rail button.sub[aria-current="true"] { color: var(--amber-hi); }
.rail button { position: relative; }

/* The grab handle: the row is a button and clicking it must keep meaning "open this", so
   dragging needs a target of its own. */
.grabber {
  position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
  width: 12px; height: 16px; cursor: grab; opacity: 0;
  background-image: radial-gradient(circle, var(--ink-faint) 1px, transparent 1px);
  background-size: 4px 4px; background-position: 1px 2px;
}
.rail button:hover .grabber { opacity: .75; }
.grabber:active { cursor: grabbing; }

/* ---- Settings: a list, not a wall of tiles ------------------------------ */
.adminsplit { display: grid; grid-template-columns: 230px 1fr; gap: 1px; background: var(--seam); border: 1px solid var(--seam); }
.adminlist { display: flex; flex-direction: column; background: var(--panel); }
.adminlist button {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 8px 14px; border: 0; border-bottom: 1px solid #1b1e23; background: transparent;
  color: var(--ink-dim); cursor: pointer; text-align: left;
}
.adminlist button b { font-size: 12px; color: var(--ink); }
.adminlist button span {
  font-size: 9.5px; color: var(--ink-faint); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.adminlist button:hover { background: var(--panel-hi); }
.adminlist button[aria-current="true"] { background: var(--plate); box-shadow: inset 3px 0 0 var(--amber); }
.adminlist button[aria-current="true"] b { color: var(--amber); }
.adminbody { background: var(--panel); min-width: 0; overflow-x: auto; }
.adminbody > .keyhint { margin: 12px 14px 10px; }

/* A yes-or-no cell is coloured rather than spelled out: a column of the word "false" is
   noise, and the point is to see at a glance which boxes have one. */
.grid td.toggle { text-align: center; color: #8b95a1; }
.grid td.toggle .cellcheck { width: 14px; height: 14px; margin: 0; vertical-align: middle; cursor: pointer; accent-color: #0b4f7a; }
.grid td.toggle.locked .cellcheck { cursor: default; }
.asktime .askgrid { flex-direction: row; flex-wrap: wrap; align-items: flex-end; }
.asktime .askgrid label { min-width: 0; }
.asktime .askpick { min-width: 84px; }
.asktime .askfield { width: 110px; }
.grid td.toggle.on { background: #d6ecfb !important; color: #0b4f7a; font-weight: 600; }
.grid tbody tr:nth-child(even) td.toggle.on { background: #cbe6f8 !important; }


/* ---- rail tints ---------------------------------------------------------- */
/* A colour on the section, so the eye finds the two sheets it lives in without reading. */
.rail button.tint-exchange { border-left-color: #e06060; }
.rail button.behind { font-weight: 700; color: var(--amber); }
/* The triangle beside an out-of-date entry; hovering it opens the pop-up that says why. */
.rail button .railwarn { color: var(--amber); font-size: 12px; line-height: 1; cursor: help; margin-right: -2px; }
.rail button .railwarn:hover { color: var(--amber-hi); }
.railtip {
  position: fixed; z-index: 88; max-width: 320px; padding: 8px 12px;
  background: var(--panel); border: 1px solid var(--amber); box-shadow: 0 12px 28px rgba(0,0,0,.6);
  font-family: var(--data); font-size: 11px; line-height: 1.5; color: var(--ink-dim);
  pointer-events: none;
}
.railtip > div + div { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--seam); }
.railtip b { display: block; color: var(--amber); font-weight: 700; margin-bottom: 2px; }
/* The tint is the left rule only, never the text: coloured text read as a second selected
   entry, and only one entry in the rail is ever the current one. */
.rail button.tint-cable { border-left-color: #e08a2c; }
.loom summary .mini {
  padding: 2px 8px; border: 1px solid var(--seam); background: transparent; color: var(--ink-dim);
  font: 600 9px/1.6 var(--chrome); letter-spacing: .12em; text-transform: uppercase; cursor: pointer;
}
.loom summary .mini:hover { border-color: var(--amber-lo); color: var(--amber); }

/* ---- the show record, one column per company ---------------------------- */
.recordcols {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1px; background: var(--seam); border: 1px solid var(--seam);
}
.recordcol { background: var(--sheet, var(--panel)); }
.recordcol h4 {
  margin: 0; padding: 8px 12px; font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint); border-bottom: 1px solid var(--seam);
}
.record.one { grid-template-columns: 1fr; border: 0; }
.recordcol .field > span { min-width: 116px; }


/* ---- settings: what a table is scoped to -------------------------------- */
.scopeline { display: flex; align-items: center; gap: 10px; margin: 0 0 8px; font-size: 11.5px; }
.scopeline b {
  padding: 2px 8px; border-radius: 2px; font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; font-weight: 700;
}
.scopeline b.global { background: #e8ebef; color: #4a525d; }
.scopeline b.pervendor { background: #fde9cf; color: #8a5300; }
.scopeline span { color: #6b7480; }
.scopetoggle {
  margin-left: auto; padding: 3px 10px; border: 1px solid var(--sheet-rule, #c8cdd4);
  background: transparent; color: inherit; font: inherit; font-size: 11px; cursor: pointer;
}
.scopetoggle:hover { background: #fff; border-color: #0b63c5; color: #0b63c5; }


/* ---- the publish panel and its folder chooser --------------------------- */
.publishpanel .scalarfield { margin-bottom: 4px; }
.publishpanel .panelhead {
  margin: 18px 0 4px; font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-faint);
}
.folderpick {
  position: fixed; inset: 12% 28%; z-index: 60; display: flex; flex-direction: column;
  background: var(--sheet, var(--panel)); border: 1px solid var(--sheet-rule, var(--seam));
  box-shadow: 0 18px 60px rgba(0, 0, 0, .45);
}
.folderbar {
  display: flex; align-items: center; gap: 8px; padding: 8px 12px;
  border-bottom: 1px solid var(--sheet-rule, var(--seam));
}
.folderbar b { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--data); font-size: 11.5px; }
.folderlist { flex: 1; overflow: auto; padding: 4px 0; }
.folderlist button {
  display: block; width: 100%; text-align: left; padding: 5px 14px; border: 0;
  background: transparent; color: inherit; font: inherit; font-size: 12px; cursor: pointer;
}
.folderlist button:hover { background: #e8eef7; color: #0b63c5; }
/* The strip while an administrator is viewing as someone else: unmistakable, never in the way. */
.previewbanner {
  position: sticky; top: 0; z-index: 96; display: flex; align-items: center; gap: 14px;
  padding: 5px 14px; background: var(--amber); color: #1a1205; font: 11.5px var(--data);
}
.previewbanner b { font-weight: 700; }
.previewbanner .cmd { margin-left: auto; padding: 3px 10px; border: 1px solid #1a1205; background: transparent; color: #1a1205; font: 600 10px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; cursor: pointer; }
.previewbanner .cmd:hover { background: #1a1205; color: var(--amber-hi); }
/* The access policy matrix and a person's grants. */
.policytable { max-height: none; margin-top: 6px; }
.policytable th { font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); white-space: nowrap; }
.policytable tbody th { text-align: left; color: var(--ink); font-family: var(--data); text-transform: none; letter-spacing: 0; }
.policytable .policypick { padding: 2px 4px; background: #0e1114; border: 1px solid var(--seam); color: var(--ink); font-family: var(--data); font-size: 11px; }
.askbox.askgrants { max-width: 720px; }
.askbox.askgrants .askhint { flex: 1 0 100%; margin: -4px 0 6px; }
.askbox.askgrants .askpick { width: 190px; min-width: 190px; }
.askbox.askgrants .asktrouble { flex: 1 0 100%; font: 11px var(--data); color: #ff6b7a; min-height: 14px; }
/* The Drive picker: the same box, a link to paste under the bar, a kind beside a shared folder. */
.drivepick .drivelink {
  margin: 6px 12px; padding: 5px 8px; background: #0e1114; border: 1px solid var(--seam);
  color: var(--ink); font-family: var(--data); font-size: 11.5px;
}
.drivepick .folderlist button { display: flex; justify-content: space-between; gap: 10px; }
.drivepick .folderlist button em { font-style: normal; font-size: 10px; color: var(--ink-faint); }
.driveblock .drivehead { display: flex; align-items: center; gap: 10px; padding: 8px 14px 4px; font: 11.5px var(--data); color: var(--ink); }
.driveblock .drivedot { width: 8px; height: 8px; border-radius: 50%; background: var(--seam-bright); flex: none; }
.driveblock .drivedot.on { background: #3fbf6a; box-shadow: 0 0 6px rgba(63,191,106,.7); }
.driveblock .drivehead .cmd { padding: 4px 10px; }
.driveblock .drivesaid { font: 10.5px var(--data); color: var(--amber-hi); font-style: normal; }
.driveblock .drivesaid.failed { color: #ff6b7a; }
.driveblock .drivefolder { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11.5px; color: var(--ink); }
.driveblock .scalarfield { padding: 6px 14px; }
.driveblock.compact .scalarfield span { min-width: 110px; }
/* Why the dialog opened, since it is now opened from more than one place. */
.folderwhy {
  padding: 8px 12px 0; font-size: 12px; color: var(--dim, #667);
}
/* A file is a choice, not a step further in, so it reads differently from a folder. */
.folderlist button.folder::before { content: '\1F4C1\A0\A0'; }
.folderlist button.file {
  display: flex; align-items: baseline; gap: 10px; font-family: var(--data);
}
.folderlist button.file span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.folderlist button.file em { font-style: normal; font-size: 11px; color: var(--dim, #778); }


/* ---- select-all corner, row grips, and hiding --------------------------- */
.grid th.corner { cursor: pointer; }
.grid th.corner:hover { background: #dde3ea; }
.rowgrip {
  /* Wholly inside its own row. Hanging over the edge put it under the next row's sticky
     row-number cell, which paints later and swallowed every mousedown. */
  position: absolute; left: 0; right: 0; bottom: 0; height: 5px;
  cursor: row-resize; z-index: 3;
}
.grid th.rownum:hover .rowgrip { background: rgba(11, 99, 197, .35); }
/* Hidden is out of the way, not gone: the cell keeps its index and its value. */
/*
 * A row is as tall as it was dragged to, and no taller. The cell height below is the
 * default for a row nobody has touched; on a row given its own height the cells give way,
 * or the row could be made taller but never shorter than the default.
 */
.grid tbody tr[style*="height"] td, .grid tbody tr[style*="height"] th.rownum { height: auto; line-height: 1.1; }
.grid .colhidden { display: none; }
.grid tr.rowhidden { display: none; }
/* The foot row of a growable sheet: where the next record is typed, not a record itself. */
.grid tr.newrow td { opacity: 0.55; font-style: italic; }
.grid tr.newrow th.rownum { font-weight: 700; }


/* A labelled gap in a row of command buttons, so the groups read apart. */
.commands .cmdsep {
  align-self: center; margin: 0 2px 0 8px; padding-left: 8px;
  border-left: 1px solid var(--seam); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-faint);
}


/* ---- the migrate dialog -------------------------------------------------- */
.dialog {
  position: fixed; inset: 8% 20%; z-index: 60; display: flex; flex-direction: column;
  background: var(--sheet, var(--panel)); border: 1px solid var(--sheet-rule, var(--seam));
  box-shadow: 0 18px 60px rgba(0, 0, 0, .45);
}
.dialogbar {
  display: flex; align-items: center; gap: 10px; padding: 10px 14px;
  border-bottom: 1px solid var(--sheet-rule, var(--seam));
}
.dialogbar b { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; }
.dialogbar .dismiss { margin-left: auto; }
.dialogbody { flex: 1; overflow: auto; padding: 12px 14px; }
.ticklist { margin-bottom: 16px; }
.ticklist h4 {
  margin: 0 0 6px; font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-faint);
}
.tickrow {
  display: grid; grid-template-columns: 18px minmax(180px, auto) 1fr; align-items: baseline;
  gap: 8px; padding: 4px 0; cursor: pointer;
}
.tickrow:hover { background: #eef3f9; }
.tickrow b { font-weight: 600; font-size: 12px; }
.tickrow span { color: #6b7480; font-size: 11.5px; }

.askbox .asktext {
  width: 100%; margin: 8px 0 10px; padding: 6px 8px;
  border: 1px solid var(--sheet-rule, var(--seam)); background: #fff; color: var(--sheet-ink, #10131a);
  font-family: var(--data); font-size: 12px;
}
.askbox .askrow { display: flex; gap: 8px; justify-content: flex-end; }


/* ---- the column caret: sort and filter, where a spreadsheet puts them ---- */
.grid thead th .handle {
  position: absolute; left: 3px; top: 50%; transform: translateY(-50%);
  padding: 0 2px; font-size: 9px; line-height: 1; opacity: .22; cursor: grab; z-index: 2; user-select: none;
}
.grid thead th:hover .handle { opacity: .7; }
.grid thead th .handle:hover { opacity: 1; color: #0b63c5; }
.grid thead th .caret {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  padding: 0 2px; font-size: 9px; line-height: 1; opacity: .35; cursor: pointer; z-index: 2;
}
.grid thead th:hover .caret { opacity: .8; }
.grid thead th .caret:hover { opacity: 1; color: #0b63c5; }
/* A filtered column says so, because a sheet showing a third of its rows must not look
   like a sheet with a third of the rows in it. */
.grid thead th.filtered { color: #0b63c5; }
.grid thead th.filtered .caret { opacity: 1; color: #0b63c5; }

.filterpanel { width: 240px; padding: 4px 0; }
.filterpanel .filtersearch {
  width: calc(100% - 20px); margin: 4px 10px 6px; padding: 4px 6px;
  border: 1px solid var(--sheet-rule, #c8cdd4); background: #fff; color: #10131a;
  font: inherit; font-size: 11.5px;
}
.filterpanel .filterall {
  width: 100%; text-align: left; padding: 4px 12px; border: 0; background: transparent;
  color: inherit; font: inherit; font-size: 11.5px; cursor: pointer;
}
.filterpanel .filterall:hover { background: #e8eef7; color: #0b63c5; }
.filtervalues { max-height: 220px; overflow: auto; padding: 0 6px; }
.filtervalues label {
  display: flex; align-items: center; gap: 7px; padding: 2px 6px;
  font-size: 11.5px; cursor: pointer;
}
.filtervalues label:hover { background: #e8eef7; }
.filtervalues label span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--sheet-ink);
}
.filterbar {
  display: flex; gap: 6px; justify-content: flex-end; padding: 8px 10px 4px;
  border-top: 1px solid var(--seam);
}


/* ---- menus belong to the sheet, so they read like the sheet -------------- */
/* A dark popup over a light spreadsheet reads as a different application. */
.cellmenu {
  /* Colour on the container, so the parts that are not buttons — the value list, the
     search field — read as dark text on the sheet rather than inheriting the dark chrome. */
  background: var(--sheet); border-color: var(--sheet-rule); color: var(--sheet-ink);
  box-shadow: 0 14px 34px rgba(20, 26, 34, .28);
}
.cellmenu button { color: var(--sheet-ink); }
.cellmenu button:hover { background: #e8eef7; color: #0b63c5; }
.cellmenu button em { color: #7b838e; }
.cellmenu hr { border-top-color: var(--sheet-line); }
.cellmenu .go {
  padding: 4px 12px; border: 1px solid #0b63c5; background: #0b63c5; color: #fff;
  font: inherit; font-size: 11.5px; cursor: pointer;
}
.cellmenu .go:hover { background: #0a56ab; }
.cellmenu .dismiss {
  padding: 4px 12px; border: 1px solid var(--sheet-rule); background: transparent;
  color: var(--sheet-ink); font: inherit; font-size: 11.5px; cursor: pointer;
}
.cellmenu .dismiss:hover { border-color: #0b63c5; color: #0b63c5; }
.filterbar { border-top-color: var(--sheet-line); }

/* A value the row does not hold itself — inherited from its type, and greyed to say so. */
.grid td .cellvalue.inherited { color: #8b939e; font-style: italic; }


/* The start-up failure notice. A blank window says nothing at a load-in. */
.fatal { max-width: 620px; padding: 28px 4px; }
.fatal h2 { margin: 0 0 10px; font-size: 16px; font-weight: 600; }
.fatal p { margin: 0 0 10px; font-size: 13px; }

/* ---- the case fill test ---------------------------------------------------- */
.fillpanel h4 { margin: 18px 0 4px; font: 700 11px/1 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink); }
.fillpanel h4:first-child { margin-top: 0; }
.fillrows { display: flex; flex-direction: column; gap: 2px; margin: 6px 0; }
.fillrow {
  display: grid; grid-template-columns: 150px 1fr 70px auto; align-items: center; gap: 10px;
  padding: 3px 8px; background: var(--panel);
}
.fillrow b { font-family: var(--data); font-size: 11.5px; color: var(--ink); }
.fillrow span { font-family: var(--data); font-size: 10.5px; color: var(--ink-faint); }
.fillrow i { font-style: normal; font-size: 10.5px; color: var(--ink-faint); }
.fillrow input.count { width: 64px; text-align: right; }

/* ---- the small stepper ------------------------------------------------------ */
/* The browser's spinner is switched off wherever the stepper is drawn beside the field. */
input.nospin { appearance: textfield; -moz-appearance: textfield; }
input.nospin::-webkit-inner-spin-button, input.nospin::-webkit-outer-spin-button { display: none; margin: 0; }
.stepper { display: inline-flex; flex-direction: column; margin-left: 2px; vertical-align: middle; }
.stepper button {
  width: 11px; height: 8px; padding: 0; border: 0; background: transparent; cursor: pointer;
  font-size: 7px; line-height: 8px; color: var(--ink-faint);
}
.stepper button:hover { color: var(--amber); }
.stepper button:active { color: var(--amber-hi); }

/* ---- the power dashboard, in columns ---------------------------------------- */
.dashwrap { overflow-x: auto; }
table.dash { min-width: 900px; }
table.dash td.num { position: relative; text-align: right; }
/* How full a leg is: a thin bar along the cell's foot, so the number stays on clear ground.
   It was a wash behind the digits, which read as bleed-through and cost legibility. */
table.dash td[style*="--fill"]::after {
  content: ""; position: absolute; left: 6px; bottom: 2px; height: 3px;
  width: calc((100% - 12px) * var(--fill) / 100%); max-width: calc(100% - 12px);
  background: var(--amber-lo); opacity: .8; border-radius: 1px;
}
table.dash td.over { color: #ff6b7a; }
table.dash td.over::after { background: #d0384a; }
table.dash tr.service td { border-top: 1px solid var(--seam-bright); }
table.dash tr.service.bad b { color: #ff6b7a; }
table.dash td.indent { padding-left: 22px; }
table.dash tr.rack td { color: var(--ink-dim); }

/* An empty unit in the rack's addressing table is an empty line, not a missing one. */
.rackdata tr.blank td { height: 20px; color: var(--ink-faint); }

/* ---- settings: the list stays put while the table scrolls ------------------- */
/* Twenty-odd tables down the side put the one you want below the fold and the table you
   are reading above it. The list keeps its own scroll and sticks to the top. */
.adminsplit { align-items: start; }
.adminlist { position: sticky; top: 0; max-height: calc(100vh - 96px); overflow-y: auto; }
.adminlist button { padding: 5px 12px; }
.adminlist button span { display: none; }
.adminlist button[aria-current="true"] span { display: block; }
/* Parents and children: a heading per group that folds, its tables indented under it.
   Only the group being read stays open, so the whole list fits without scrolling. */
.adminlist .admingroup {
  display: block; width: 100%; padding: 5px 10px 4px; border: 0; border-bottom: 1px solid #1b1e23;
  background: var(--panel-hi); color: var(--ink); font: 700 10.5px/1.2 var(--chrome); letter-spacing: .08em;
  text-transform: uppercase; text-align: left; cursor: pointer;
}
.adminlist .admingroup::before { content: "\25B8"; display: inline-block; width: 12px; color: var(--ink-faint); font-size: 9px; }
.adminlist .admingroupbox.open .admingroup::before { content: "\25BE"; }
.adminlist .admingroupbox.holds .admingroup { color: var(--amber); }
.adminlist .admingrouprows { display: none; flex-direction: column; }
.adminlist .admingroupbox.open .admingrouprows { display: flex; }
.adminlist .admingrouprows button { padding: 3px 10px 3px 22px; }
.adminlist .admingrouprows button b { font-size: 11.5px; }

/* ---- reprint ---------------------------------------------------------------- */
.reprint .kinds { display: flex; flex-wrap: wrap; gap: 6px; }
.reprint .kinds .findopt { flex: 1; text-align: center; }
.reprintitem {
  display: grid; grid-template-columns: 92px 1fr auto auto; gap: 8px; align-items: center; width: 100%;
  text-align: left; padding: 6px 6px; background: transparent; border: 0; border-bottom: 1px solid #14171c;
  color: var(--ink-dim); font-family: var(--data); font-size: 11px; cursor: pointer;
}
.reprintitem:hover { background: var(--panel-hi); color: var(--ink); }
.reprintitem b { color: var(--ink); font-weight: 600; }
.reprintitem.parent b::after { content: ' \25B8'; color: var(--ink-faint); }
.reprintitem span { color: var(--ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reprintitem em { font-style: normal; color: var(--ink-faint); white-space: nowrap; font-size: 10px; }
.reprintitem .rowprint { padding: 2px 8px; }
.reprintkids { margin: 0 0 6px 10px; border-left: 2px solid var(--seam); }
.reprintitem.child { grid-template-columns: 92px 1fr auto auto; }
.reprintitem.child.all b { color: var(--amber); }
.reprintmark { display: flex; align-items: center; gap: 10px; margin: 6px 0 10px; font-size: 11px; color: var(--ink-faint); }
.reprint .findgroup h5 { align-items: center; }
.reprint .findgroup h5 .cmd, .reprint .findgroup h5 .rowprint { margin-left: auto; padding: 2px 8px; }
.reprint .findgroup h5 .rowprint { margin-left: 0; }

/* Trucking */
.trucking tr.ontruck td { color: var(--ink); }
.trucking td.act { white-space: nowrap; }
.trucking td.act select {
  min-width: 110px; margin-right: 6px; padding: 2px 4px; font: 11px var(--data);
  background: var(--sheet); color: var(--sheet-ink); border: 1px solid var(--sheet-rule);
}
.trucking td.act button.cmd {
  padding: 3px 8px; border: 1px solid var(--sheet-rule); background: var(--sheet); color: var(--sheet-ink);
  font: 600 9.5px/1.4 var(--chrome); letter-spacing: .1em; text-transform: uppercase; cursor: pointer;
}
.trucking td.act button.cmd:hover { border-color: var(--amber); color: var(--amber-lo); }
.trucking table.grid th:last-child, .trucking table.grid td.act { width: 210px; }
.trucking .commands .scalar { padding: 4px 8px; background: #0e1114; border: 1px solid var(--seam); color: var(--ink); font: 11.5px var(--data); }

/* The patch pill stays in the toolbar: it is a button, and the amber tell-tale that the
   drawing is behind belongs beside the section's tools. */
.toolbar .patchpill {
  display: flex; align-items: center; margin-left: auto; padding: 0 12px; background: var(--panel);
  border: 0; cursor: pointer; font-family: var(--data); font-size: 10.5px; color: var(--ink-faint); white-space: nowrap;
}
.toolbar .patchpill + .keys { margin-left: 0; }
.toolbar .patchpill.behind { color: var(--amber); }
.toolbar .patchpill.current { color: var(--ink-faint); }
.toolbar .patchpill.failed { color: #ff6b7a; }
.toolbar .patchpill.behind:hover { color: var(--amber-hi); background: var(--panel-hi); }
.toolbar .patchpill[hidden] { display: none; }

/* ---- compact ------------------------------------------------------------ */
/*
  The owner's direction, 2026-09-04: the app is for efficiency, and it had become "more
  pretty than efficient" — the rail especially. Everything that is chrome rather than data
  is tightened here, in one place, so the earlier rules above still say what each thing is
  and this block says how much room it gets. Readability was asked for in the same breath,
  so type shrinks less than the space around it.
*/
:root { --row: 23px; }

/* The rail: narrower, tighter rows, groups a hair apart rather than a band apart. */
.frame { grid-template-columns: 156px 1fr; }
.rail { padding: 3px 0 8px 8px; }
.rail::before {
  width: 8px;
  background:
    radial-gradient(circle at 4px 50%, #04060a 0 1.6px, rgba(255,255,255,.10) 1.6px 2.2px, transparent 2.2px)
      0 0 / 8px 28px repeat-y,
    linear-gradient(90deg, #1f242b 0%, #171b21 60%, #101317 100%);
}
.rail h3 { margin: 7px 10px 1px; font-size: 9px; letter-spacing: .14em; }
.rail button {
  padding: 2px 8px 2px 9px; gap: 6px; line-height: 1.3; font-size: 12.5px; letter-spacing: .02em;
}
.rail button.sub { padding-left: 20px; font-size: 12px; }
/* `.sub` is also the page subtitle, which is uppercase, spaced out and 18 px off the next
   thing — none of which a rail row wants. That collision is what had the rail so tall. */
.rail button.sub { margin-bottom: 0; letter-spacing: .02em; text-transform: none; }
.rail button em { font-size: 10px; }
.railgroup { border-bottom: 0; padding-bottom: 2px; }
.grabber { left: 0; width: 8px; }

/* The faceplate and the show tabs. */
.mark { padding: 0 12px; gap: 8px; }
.mark b { font-size: 13px; }
.mark span { font-size: 9px; }
.show-tab { padding: 0 12px; min-width: 0; gap: 8px; }
.show-tab b { font-size: 12px; }
.show-tab i { font-size: 9.5px; }
.plate-right { gap: 10px; padding: 0 12px; }
.screw { width: 9px; height: 9px; }

/* The menu bar and the toolbar. */
.menubar { height: 22px; }
.menubar .menu { padding: 0 10px; font-size: 11px; }
.toolbar { min-height: 26px; }
.toolbar .where { padding: 0 10px; gap: 8px; }
.toolbar .where b { font: 700 11.5px/26px var(--chrome); letter-spacing: .12em; }
.toolbar .commandform { top: 26px; }
.toolbar .railtoggle, .toolbar .keys { width: 26px; }

/* The mode strips, commands and the cell bar. */
.modes button[data-mode] { padding: 5px 12px; }
.modes .toggle { padding: 0 10px; }
.commands .cmd { padding: 5px 10px; }
.cellbar .addr { min-width: 150px; padding: 0 10px; }
.cellbar .barvalue { height: 24px; padding: 0 10px; }

/* The pane, and how much of the window the sheet gets: see the measurement below. */
main { padding: 8px 10px 40px; }
.gridwrap { max-height: calc(100vh - var(--above-sheet, 150px)); }

/* A heading folds its group: the caret says which way it is. */
.rail h3 { cursor: pointer; user-select: none; }
.rail h3::before { content: "\25BE"; display: inline-block; width: 9px; margin-left: -9px; font-size: 8px; }
.railgroup.folded h3::before { content: "\25B8"; }
.railgroup.folded button { display: none; }
/* The Add button above a sheet that grows. */
main > div > .commands:first-child { margin-bottom: 4px; }
/* A group inside a group: its heading and its rows step in once more. */
.rail h3.sub { margin: 4px 10px 1px 20px; }
.rail button.sub2 { padding-left: 30px; }
.railsub.folded button { display: none; }
.railgroup.folded .railsub { display: none; }
/* A heading's grab handle moves its whole group. */
.rail h3 { position: relative; }
.rail h3 .grabber { top: 50%; }
.rail h3:hover .grabber { opacity: .75; }
.railsub.dragging, .rail button.dragging { opacity: .45; }

/* ---- the rack builder: blocks over units, halves, the editor ------------------ */
.rackbody { position: relative; padding: 0; }
.builder .ru { height: 20px; }
.builder .seat {
  position: absolute; left: 0; width: 100%; box-sizing: border-box;
  display: flex; align-items: center; gap: 8px; padding: 0 8px 0 30px;
  background: #15181d; color: var(--ink); border-bottom: 1px solid var(--seam);
  box-shadow: inset 3px 0 0 var(--amber); cursor: grab;
  font-family: var(--data); font-size: 10.5px; overflow: hidden; white-space: nowrap;
}
.builder .seat b { font-weight: 600; }
.builder .seat span { color: var(--amber); }
.builder .seat u { text-decoration: none; margin-left: auto; color: var(--ink-faint); font-size: 9.5px; }
.builder .seat.half { width: 50%; padding-left: 30px; box-shadow: inset 3px 0 0 var(--amber), inset -1px 0 0 var(--seam); }
.builder .seat.half.right { left: 50%; padding-left: 8px; box-shadow: inset 3px 0 0 var(--amber); }
.builder .seat:hover { background: #1a1e24; }
.shelf h4 + h4 { border-top: 1px solid var(--seam); }
.shelf .keyhint.short { margin: 8px 12px; }
/* The table's rows are the rack's units: the same height, and the same start. */
.rackdata { margin-top: 0; }
.rackdata table thead th { height: 27px; padding: 0 8px; box-sizing: border-box; }
.rackdata table tbody td { height: 20px; padding: 0 8px; line-height: 20px; box-sizing: content-box; }
.rackdata table tbody td input { height: 18px; padding: 0 4px; font: inherit; width: 100%; box-sizing: border-box; }
.rackdata td.ports i { font-style: normal; display: inline-block; min-width: 18px; margin-right: 3px; padding: 0 3px; border-radius: 2px; text-align: center; }
.rackdata td.ports i.live, input.portval.live { background: #c8f7c5; color: #1b4d1a; }
.rackdata td.ports i.spare, input.portval.spare { background: #ffc0e0; color: #6b1d45; }
.sidecaret { border: 0; background: none; color: var(--ink-faint); cursor: pointer; padding: 0 4px 0 0; font-size: 10px; }
.sidecaret:hover { color: var(--amber); }
.rackeditor {
  position: absolute; left: 50%; top: 80px; transform: translateX(-50%); z-index: 40; width: 380px;
  padding: 12px 14px 14px; background: var(--panel); border: 1px solid var(--seam-bright);
  box-shadow: 0 16px 36px rgba(0,0,0,.6);
}
.builder { position: relative; }
.rackeditorhead { display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px; }
.rackeditorhead b { font-family: var(--data); font-size: 13px; color: var(--amber-hi); }
.rackeditorhead span { color: var(--ink-faint); font-size: 10.5px; }
.rackeditor .dfield { display: flex; align-items: center; gap: 8px; margin: 4px 0; }
.rackeditor .dfield span { width: 70px; color: var(--ink-faint); font-size: 10.5px; }
.rackeditor .dfield input { flex: 1; }
.rackeditor h5 { margin: 10px 0 4px; font: 700 9.5px/1 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); }
.portsheet { max-height: 260px; overflow-y: auto; border: 1px solid var(--seam); }
.portsheet table { width: 100%; border: 0; }
.portsheet td, .portsheet th { height: 20px; padding: 0 6px; line-height: 20px; }
.portsheet td.num { width: 34px; text-align: right; }
.portsheet input.portval { width: 100%; height: 18px; padding: 0 4px; border: 0; background: #fff; color: #000; font: inherit; box-sizing: border-box; }
.rackeditor .drow { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.rackeditor .drow em { flex: 1; }
/* The footprint of a drag in the air: every unit it would cover, green if it fits, red if not. */
.builder .ru.fits { background: rgba(80, 200, 120, .28); box-shadow: inset 0 0 0 1px #3fbf6f; }
.builder .ru.nofit { background: rgba(220, 60, 80, .28); box-shadow: inset 0 0 0 1px #d0384a; }
.builder .ru.fits.left, .builder .ru.nofit.left { background: linear-gradient(to right, rgba(80, 200, 120, .28) 50%, transparent 50%); }
.builder .ru.nofit.left { background: linear-gradient(to right, rgba(220, 60, 80, .28) 50%, transparent 50%); }
.builder .ru.fits.right { background: linear-gradient(to right, transparent 50%, rgba(80, 200, 120, .28) 50%); }
.builder .ru.nofit.right { background: linear-gradient(to right, transparent 50%, rgba(220, 60, 80, .28) 50%); }
.builder .seat { pointer-events: auto; }
.builder .rackbody.dragging .seat { pointer-events: none; }
/* A seated block carries its unit number where the empty unit would show it. */
.builder .seat { padding-left: 10px; }
.builder .seat i { font-style: normal; width: 18px; text-align: right; color: #3d434c; flex: none; }
.builder .seat.half.right { padding-left: 10px; }
/* Units and blocks share one grid: a unit is exactly 21 px including its rule, so a block
   at (ru - 1) * 21 starts on its unit's top edge and ends on its last unit's rule. */
.builder .ru { box-sizing: border-box; height: 21px; padding-top: 0; padding-bottom: 0; }
.builder .rackbody { padding: 0; margin: 0; }
/* The shelf: tight rows, and it scrolls on its own so the rack stays put beside it. */
.builder .shelf { position: sticky; top: 6px; max-height: calc(100vh - 110px); overflow-y: auto; align-self: start; }
.builder .shelfitem { padding: 2px 8px; gap: 6px; font-size: 10px; line-height: 1.3; }
.builder .shelfitem b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.builder .shelfitem span { flex: none; font-size: 9.5px; }
.builder .shelf h4 { position: sticky; top: 0; z-index: 1; padding: 5px 8px; }
.rackeditor .dfield .sidecaret { flex: none; }
.rackeditor .dfield[hidden], .rackeditor .sidecaret[hidden] { display: none; }

/* ---- the four modes ----------------------------------------------------------- */
.modeswitch { display: flex; gap: 1px; background: var(--seam); border: 1px solid var(--seam); margin-right: 8px; }
.modeswitch[hidden] { display: none; }
/* The app switch beside the mark: CAD, Electrics, Labor. The same metal as the modes, a little larger. */
.appswitch { display: flex; align-self: center; gap: 1px; margin: 0 14px 0 4px; background: var(--seam); border: 1px solid var(--seam); }
.appswitch button {
  padding: 4px 12px; border: 0; background: var(--panel); color: var(--ink-dim);
  font: 700 10px/1 var(--chrome); letter-spacing: .16em; text-transform: uppercase; cursor: pointer;
}
.appswitch button:hover { color: var(--ink); background: var(--panel-hi); }
.appswitch button[aria-current="true"] { color: var(--ground); background: var(--metal); }
.apphome { padding: 18px 22px; max-width: 760px; }
/* The Labor app: a toolbar line, dense lists, the tiers and day types as tints. */
.labor { padding: 10px 14px; }
.labor h3 { margin: 0 0 8px; }
.laborbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 8px; }
.laborbar .keyhint { margin: 0; flex: 1; }
.laborbar .cmd, .clockrow .cmd { padding: 4px 10px; border: 1px solid var(--amber-lo); background: transparent; color: var(--amber); font: 600 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; cursor: pointer; }
.laborbar .cmd:disabled, .clockrow .cmd:disabled { opacity: .45; cursor: default; }
.laborpick, .laborsearch { padding: 4px 7px; background: #0e1114; border: 1px solid var(--seam); color: var(--ink); font-family: var(--data); font-size: 11.5px; }
.laborsearch { width: 220px; }
.laborlist { width: auto; min-width: 520px; }
.laborlist td.num { text-align: right; font-family: var(--data); }
.laborlist td.over, .cards b.over { color: #ff8f9b; }
.laborlist td.under, .cards b.under { color: #6fd08a; }
.laborlist tr.depthead td { font: 700 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-dim); padding-top: 8px; }
.deptdot { display: inline-block; width: 9px; height: 9px; margin-right: 7px; vertical-align: -1px; border-radius: 2px; }
.callmeal { padding: 2px 4px; background: #0e1114; border: 1px solid var(--seam); color: var(--ink); font-family: var(--data); font-size: 11px; }
.clockrow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 8px; }
.clocksaid { min-height: 16px; font: 11.5px var(--data); color: var(--ink-dim); }
.clocksaid.ok { color: var(--amber-hi); }
.clocksaid.failed { color: #ff6b7a; }
.askbox.asklabor { max-width: 720px; }
.askbox .askchecks { display: flex; flex-wrap: wrap; gap: 4px 12px; }
.askbox .askfield.wide { width: 420px; }
.badgegrid { display: flex; flex-wrap: wrap; gap: 8px; }
/* Reviews of proposed rows (imports), and the assistant's thread and proposal card. */
.askbox.askreview { max-width: 900px; width: calc(100vw - 60px); }
.askbox.askreview .floortable { flex: 1 0 100%; max-height: 50vh; }
.laborreview th { white-space: nowrap; }
.directoryresults { margin: 6px 0 12px; }
.assistant { padding: 10px 14px; max-width: 900px; }
.assistantthread { max-height: 420px; overflow: auto; margin: 8px 0; padding: 4px 0; border-top: 1px solid var(--seam); border-bottom: 1px solid var(--seam); }
.assistantsay { display: flex; gap: 10px; padding: 5px 0; font: 12px/1.5 var(--data); color: var(--ink); }
.assistantsay b { flex: none; width: 70px; font: 700 9.5px/1.9 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); }
.assistantsay.you span { color: var(--ink-dim); }
.assistantcard { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin: 6px 0 10px; padding: 8px 10px; border: 1px solid var(--amber-lo); background: var(--panel); font: 12px/1.5 var(--data); color: var(--ink); }
.assistantcard .askrow { margin: 0; flex: 0 0 auto; }
.assistantcard .cmd { padding: 4px 10px; border: 1px solid var(--amber-lo); background: transparent; color: var(--amber); font: 600 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; cursor: pointer; }
.assistantcard .cmd.dismiss { border-color: var(--seam); color: var(--ink-faint); }
.assistantinput { flex: 1; min-width: 240px; }
.badgecard { width: 180px; padding: 10px; border: 1px solid var(--seam); background: var(--panel); text-align: center; display: flex; flex-direction: column; gap: 3px; align-items: center; }
.badgecard b { font-size: 12.5px; }
.badgecard span { font-size: 10.5px; color: var(--ink-dim); }
.badgecard .badgeqr { width: 110px; height: 110px; background: #fff; }
.badgecard code { font-size: 10px; letter-spacing: 1px; color: var(--ink-dim); }
.badgecard small { font-size: 8px; color: var(--ink-faint); word-break: break-all; }
.grid tbody td.tint-tier-ST, .grid tbody tr:nth-child(even) td.tint-tier-ST { background: #d7ede4; color: #1c6d5e; }
.grid tbody td.tint-tier-OT, .grid tbody tr:nth-child(even) td.tint-tier-OT { background: #f5e6c4; color: #8a6412; }
.grid tbody td.tint-tier-DT, .grid tbody tr:nth-child(even) td.tint-tier-DT { background: #f6d5cb; color: #b5522f; }
.grid tbody td.tint-day-0, .grid tbody tr:nth-child(even) td.tint-day-0 { background: #5b8a9e33; color: #5b8a9e; font-weight: 600; }
.grid tbody td.tint-day-1, .grid tbody tr:nth-child(even) td.tint-day-1 { background: #3d5f6b33; color: #3d5f6b; font-weight: 600; }
.grid tbody td.tint-day-2, .grid tbody tr:nth-child(even) td.tint-day-2 { background: #3d6b4f33; color: #3d6b4f; font-weight: 600; }
.grid tbody td.tint-day-3, .grid tbody tr:nth-child(even) td.tint-day-3 { background: #6b665633; color: #6b6656; font-weight: 600; }
.grid tbody td.tint-day-4, .grid tbody tr:nth-child(even) td.tint-day-4 { background: #8a641233; color: #8a6412; font-weight: 600; }
.grid tbody td.tint-day-5, .grid tbody tr:nth-child(even) td.tint-day-5 { background: #a3382a33; color: #a3382a; font-weight: 600; }
.grid tbody td.tint-day-6, .grid tbody tr:nth-child(even) td.tint-day-6 { background: #6b4a8a33; color: #6b4a8a; font-weight: 600; }
.grid tbody td.tint-day-7, .grid tbody tr:nth-child(even) td.tint-day-7 { background: #72B4EB33; color: #72B4EB; font-weight: 600; }
.grid tbody td.tint-day-8, .grid tbody tr:nth-child(even) td.tint-day-8 { background: #F28E8233; color: #F28E82; font-weight: 600; }
.grid tbody td.tint-day-9, .grid tbody tr:nth-child(even) td.tint-day-9 { background: #8CD19D33; color: #8CD19D; font-weight: 600; }
.grid tbody td.tint-day-10, .grid tbody tr:nth-child(even) td.tint-day-10 { background: #F1C23233; color: #F1C232; font-weight: 600; }
.grid tbody td.tint-day-11, .grid tbody tr:nth-child(even) td.tint-day-11 { background: #B68DFF33; color: #B68DFF; font-weight: 600; }
.grid tbody td.tint-day-12, .grid tbody tr:nth-child(even) td.tint-day-12 { background: #66D2CE33; color: #66D2CE; font-weight: 600; }
.grid tbody td.tint-day-13, .grid tbody tr:nth-child(even) td.tint-day-13 { background: #F48FB133; color: #F48FB1; font-weight: 600; }
.grid tbody td.tint-day-14, .grid tbody tr:nth-child(even) td.tint-day-14 { background: #FFB74D33; color: #FFB74D; font-weight: 600; }
.grid tbody td.tint-day-15, .grid tbody tr:nth-child(even) td.tint-day-15 { background: #A0E7E533; color: #A0E7E5; font-weight: 600; }
.grid tbody td.tint-day-16, .grid tbody tr:nth-child(even) td.tint-day-16 { background: #7986CB33; color: #7986CB; font-weight: 600; }
.grid tbody td.tint-day-17, .grid tbody tr:nth-child(even) td.tint-day-17 { background: #E5737333; color: #E57373; font-weight: 600; }
.grid tbody td.tint-day-18, .grid tbody tr:nth-child(even) td.tint-day-18 { background: #AED58133; color: #AED581; font-weight: 600; }
.grid tbody td.tint-day-19, .grid tbody tr:nth-child(even) td.tint-day-19 { background: #BA68C833; color: #BA68C8; font-weight: 600; }

.cadsync { padding: 18px 22px; max-width: 900px; }
.cadsync .cadbatches { width: auto; margin-top: 6px; }
.cadsync .cadbatches td.num { text-align: right; }
.cadbatch { display: inline-block; width: 10px; height: 10px; margin-right: 8px; vertical-align: -1px; border-radius: 2px; }
/* The revision log: a batch is one colour down its first column; a variance reads up or down. */
.grid tbody td.tint-up, .grid tbody tr:nth-child(even) td.tint-up { background: #d9ead3; color: #101317; }
.grid tbody td.tint-down, .grid tbody tr:nth-child(even) td.tint-down { background: #f4cccc; color: #101317; }
.grid tbody td.tint-batch0, .grid tbody tr:nth-child(even) td.tint-batch0 { background: #72B4EB; color: #101317; }
.grid tbody td.tint-batch1, .grid tbody tr:nth-child(even) td.tint-batch1 { background: #F28E82; color: #101317; }
.grid tbody td.tint-batch2, .grid tbody tr:nth-child(even) td.tint-batch2 { background: #8CD19D; color: #101317; }
.grid tbody td.tint-batch3, .grid tbody tr:nth-child(even) td.tint-batch3 { background: #F1C232; color: #101317; }
.grid tbody td.tint-batch4, .grid tbody tr:nth-child(even) td.tint-batch4 { background: #B68DFF; color: #101317; }
.grid tbody td.tint-batch5, .grid tbody tr:nth-child(even) td.tint-batch5 { background: #66D2CE; color: #101317; }
.grid tbody td.tint-batch6, .grid tbody tr:nth-child(even) td.tint-batch6 { background: #F48FB1; color: #101317; }
.grid tbody td.tint-batch7, .grid tbody tr:nth-child(even) td.tint-batch7 { background: #FFB74D; color: #101317; }
.grid tbody td.tint-batch8, .grid tbody tr:nth-child(even) td.tint-batch8 { background: #A0E7E5; color: #101317; }
.grid tbody td.tint-batch9, .grid tbody tr:nth-child(even) td.tint-batch9 { background: #7986CB; color: #101317; }
.grid tbody td.tint-batch10, .grid tbody tr:nth-child(even) td.tint-batch10 { background: #E57373; color: #101317; }
.grid tbody td.tint-batch11, .grid tbody tr:nth-child(even) td.tint-batch11 { background: #AED581; color: #101317; }
.grid tbody td.tint-batch12, .grid tbody tr:nth-child(even) td.tint-batch12 { background: #BA68C8; color: #101317; }
.grid tbody td.tint-batch13, .grid tbody tr:nth-child(even) td.tint-batch13 { background: #4DD0E1; color: #101317; }
.grid tbody td.tint-batch14, .grid tbody tr:nth-child(even) td.tint-batch14 { background: #E0C097; color: #101317; }
.grid tbody td.tint-batch15, .grid tbody tr:nth-child(even) td.tint-batch15 { background: #EF9A9A; color: #101317; }
.grid tbody td.tint-batch16, .grid tbody tr:nth-child(even) td.tint-batch16 { background: #D4E157; color: #101317; }
.grid tbody td.tint-batch17, .grid tbody tr:nth-child(even) td.tint-batch17 { background: #CE93D8; color: #101317; }
.grid tbody td.tint-batch18, .grid tbody tr:nth-child(even) td.tint-batch18 { background: #9FA8DA; color: #101317; }
.grid tbody td.tint-batch19, .grid tbody tr:nth-child(even) td.tint-batch19 { background: #FFE082; color: #101317; }

.apphome h3 { margin: 0 0 8px; }
.modeswitch button {
  padding: 3px 10px; border: 0; background: var(--panel); color: var(--ink-dim);
  font: 600 9.5px/1 var(--chrome); letter-spacing: .14em; text-transform: uppercase; cursor: pointer;
}
.modeswitch button:hover { color: var(--ink); background: var(--panel-hi); }
.modeswitch button[aria-current="true"] { color: var(--ground); background: var(--metal); }
.railgroup.lead button[data-id="review"] em, .railgroup.lead button[data-id="prep"] em { color: var(--amber-hi); font-weight: 700; }
.toolbar .reviewpill {
  border: 0; padding: 0 12px; background: var(--panel); color: var(--ink-faint); cursor: pointer;
  font: 700 10.5px/26px var(--data); letter-spacing: .04em;
}
.toolbar .reviewpill.open { color: #fff; background: #b3273a; }
.toolbar .reviewpill.open:hover { background: #d0384a; }
.prep h3, .floor h3 { margin: 14px 0 2px; font: 700 10.5px/1 var(--chrome); letter-spacing: .16em; text-transform: uppercase; color: var(--amber); }
.prep .prepdoors { justify-content: flex-start; margin: 8px 0 4px; flex-wrap: wrap; }
.floor { display: grid; grid-template-columns: repeat(auto-fit, minmax(560px, 1fr)); gap: 10px 16px; align-items: start; }
.floorpanel h3 { margin-top: 4px; }
.floortable { overflow: auto; max-height: calc(100vh - 220px); border: 1px solid var(--seam); }
.floortable table { width: 100%; border: 0; }
.floortable td.num { text-align: right; }
.rigging .riggingcmds { justify-content: flex-start; margin: 6px 0; }

/* ---- accounts: the foot of the window, the sign-in, the panels --------------------- */
.footer {
  position: fixed; left: 0; bottom: 0; z-index: 5; display: flex; gap: 14px; align-items: baseline;
  padding: 2px 10px; background: rgba(11, 12, 14, .85); border-top: 1px solid var(--seam); border-right: 1px solid var(--seam);
  font: 10px/1.6 var(--data); color: var(--ink-faint); letter-spacing: .02em;
}
.footer .whoami { color: #3d434c; }
.footer[hidden] { display: none; }
.toolbar .rolepill { padding: 0 10px; background: var(--panel); color: var(--amber); font: 700 10px/26px var(--chrome); letter-spacing: .12em; text-transform: uppercase; }
.signin { display: grid; place-items: center; min-height: 60vh; }
.signinbox { width: 380px; padding: 22px 24px 18px; background: var(--panel); border: 1px solid var(--seam-bright); box-shadow: 0 16px 36px rgba(0,0,0,.6); }
.signinbox > b { font: 700 18px/1 var(--chrome); letter-spacing: .18em; text-transform: uppercase; background: var(--metal); -webkit-background-clip: text; background-clip: text; color: transparent; }
.signinbox h2 { margin: 6px 0 4px; font: 600 15px/1.2 var(--chrome); color: var(--ink); }
.signinbox #google-signin { margin: 12px 0; min-height: 40px; }
.signinbox .drow { display: flex; gap: 6px; align-items: center; margin-top: 8px; }
.signinbox .drow input { flex: 1; min-width: 0; }
/* The sign-in's answer: a plain row of its own, never over the fields, read at a glance. */
.signinbox .signsaid { display: block; clear: both; margin: 2em 0 0; padding: 8px 10px; font-size: 12.5px; line-height: 1.45; color: #ffb3bb; background: rgba(255, 107, 122, .08); border-left: 2px solid #ff6b7a; }
.signinbox .signsaid:empty { display: none; }
.acctpanel h4, .userspanel h4 { margin: 4px 0 6px; font: 700 10.5px/1 var(--chrome); letter-spacing: .16em; text-transform: uppercase; color: var(--amber); }
.acctfield { display: flex; align-items: center; gap: 10px; margin: 4px 0; }
.acctfield > span { width: 90px; color: var(--ink-faint); font-size: 10.5px; }
.acctfield input { width: 320px; }
.acctfield em { font-style: normal; }
.acctpanel .drow, .userspanel .drow { display: flex; gap: 6px; align-items: center; margin: 8px 0; flex-wrap: wrap; }
.userspanel td select { font: inherit; }

/* ---- a sheet row's own Render, beside its Print ------------------------- */
.sheet .rowrender { margin-left: 10px; border-color: var(--seam); color: var(--ink-faint); }
.sheet .rowrender:hover { background: var(--seam); color: var(--ink); }
.sheet .rowrender:disabled { opacity: .45; cursor: default; }
.sheet .rowrender:disabled:hover { background: transparent; color: var(--ink-faint); }

/* ---- the Add a case pop-up: the row of the sheet, as a form -------------- */
.askbox.askcase { max-width: 760px; top: 18%; }
/* The New show wizard: four steps in one box, the crumbs across the top. */
.askbox.askwizard { max-width: 820px; width: calc(100vw - 40px); top: 12%; }
.askbox.askwizard .askcrumbs { flex: 1 0 100%; display: flex; gap: 14px; margin-bottom: 2px; }
.askbox.askwizard .askcrumbs span {
  font: 700 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint);
  padding-bottom: 2px; border-bottom: 2px solid transparent;
}
.askbox.askwizard .askcrumbs span.on { color: var(--amber); border-bottom-color: var(--amber); }
.askbox.askwizard .askcrumbs span.done { color: var(--ink-dim); }
.askbox.askwizard .askhint { flex: 1 0 100%; margin: -4px 0 6px; }
.askbox.askwizard .askbody { flex: 1 0 100%; display: flex; flex-direction: column; gap: 10px; }
.askbox.askwizard .askgroup { display: flex; flex-direction: column; gap: 4px; }
.askbox.askwizard .askgroup > span { font: 700 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); }
.askbox.askwizard .askfield.wide { width: 220px; }
.askbox.askwizard .askpath { width: 520px; max-width: calc(100vw - 180px); }
.askbox.askwizard .askband .cmd { padding: 5px 10px; }
.askbox.askwizard .asktrouble { flex: 1 0 100%; font: 11px var(--data); color: var(--amber-hi); min-height: 14px; }
.askbox.askposition { max-width: 640px; top: 18%; }
.askbox .askgrid .askgroup { display: flex; flex-direction: column; gap: 4px; }
.askbox .askgrid .askgroup > span { font: 700 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); }
.askbox .askshares { display: flex; flex-wrap: wrap; gap: 2px 12px; max-width: 560px; }
.askbox .askshares .asktick span { font: 11.5px var(--data); letter-spacing: 0; text-transform: none; color: var(--ink); }
.askbox .askgrid { flex: 1 0 100%; display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: flex-end; }
.askbox .askgrid label { display: flex; flex-direction: column; gap: 4px; }
.askbox .askgrid label > span {
  font: 700 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-faint);
}
.askbox .askfield {
  padding: 5px 8px; background: #0e1114; border: 1px solid var(--seam);
  color: var(--ink); font-family: var(--data); font-size: 11.5px; width: 130px;
}
/* The snake pop-up's strip of ports: a mini sheet, one cell per port, active green, spare pink. */
.askbox.asksnake { max-width: 640px; }
.askbox .askports { display: flex; flex-wrap: wrap; gap: 3px; }
.askbox .askportcell { display: flex; flex-direction: column; gap: 2px; align-items: center; }
.askbox .askportcell > span { font: 700 9px/1.4 var(--chrome); color: var(--ink-faint); }
.askbox .askport {
  width: 38px; padding: 4px 3px; text-align: center; background: #0e1114; border: 1px solid var(--seam);
  color: var(--ink); font-family: var(--data); font-size: 11.5px;
}
.askbox .askport::placeholder { color: var(--ink-faint); font-style: italic; }
.askbox .askfill { padding: 4px 10px; }
.askbox .askconfirm {
  flex: 1 0 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  padding: 8px 10px; border: 1px solid var(--amber); font: 11.5px var(--data); color: var(--ink);
}
.askbox .askport[data-hue="active"] { background: #1c3a26; border-color: #2f7a46; }
.askbox .askport[data-hue="spare"] { background: #3a1c3a; border-color: #7a2f7a; }
.askbox .askfield.narrow { width: 58px; }
.askbox .askfield.short { width: 96px; }
.askbox .askfield.wide { width: 220px; }
.askbox .askgrid .asktick { flex-direction: row; align-items: center; gap: 6px; padding-bottom: 6px; }
.askbox .askgrid .asktick > span { text-transform: none; letter-spacing: 0; font: 11.5px var(--data); color: var(--ink); }
.askbox .askcode { align-self: center; font-style: normal; font-family: var(--data); font-size: 10.5px; color: var(--amber); padding-bottom: 6px; }

/* ---- the preview is modal: the shade takes the click that closes it ------ */
.previewshade { position: fixed; inset: 0; z-index: 95; background: rgba(0, 0, 0, .35); }
.modes .modeactions { display: inline-flex; gap: 4px; margin-left: 6px; }

/* ---- barges: the carts the racks ride on ------------------------------------ */
.bargeview { padding: 12px 14px 16px; }
.bargepicker .bargeactions { margin-left: auto; display: flex; gap: 1px; align-self: stretch; }
.bargepicker .bargeactions .cmd { height: 100%; }
.barge { border: 1px solid var(--seam); background: var(--panel); padding: 10px 14px 14px; }
.bargehead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 16px; margin-bottom: 8px; }
.bargehead h3 { margin: 0; font: 700 15px/1.2 var(--chrome); letter-spacing: .16em; color: var(--amber); }
.bargehead .bargetype { font: 600 11px/1.4 var(--data); color: var(--ink); }
.bargehead .dim { font: 11px/1.4 var(--data); color: var(--ink-faint); }
.bargecode { display: inline-flex; align-items: center; gap: 0; margin-left: auto; font: 10.5px var(--data); color: var(--ink-faint); }
.bargecode i {
  display: inline-flex; align-items: center; justify-content: center; width: 92px; height: 22px;
  border: 1px solid #0006; margin-left: -1px; font: 600 10.5px var(--data); font-style: normal;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0 4px; background: #0e1114;
}
.bargecode em { margin-left: 8px; }
/* The Order column on the inventory sheets: typed here, amber until the sync writes it out. */
.grid td.orderedit input.order { width: 54px; }
.grid td.orderedit.edited input.order { border-color: var(--amber); color: var(--amber); font-weight: 700; }
/* Draggable edges on the plain tables, the same grip the grid draws. */
.grid.resizing th { user-select: none; }
.rackpicker .apply { margin-right: 6px; }
.bargestrip { margin: 4px 0 10px; border: 1px solid var(--seam); background: var(--plate); }
.bargestrip h4, .bargepower h4 {
  margin: 0; padding: 4px 10px; font: 700 9.5px/1.6 var(--chrome); letter-spacing: .16em; text-transform: uppercase; color: var(--amber);
  border-bottom: 1px solid var(--seam);
}
.bargechips { display: flex; flex-wrap: wrap; gap: 4px; padding: 6px 8px; }
.bargechip {
  display: inline-flex; align-items: baseline; gap: 6px; padding: 3px 8px; border: 1px solid var(--seam); background: var(--panel);
  font: 11px/1.3 var(--data); color: var(--ink); cursor: grab;
}
.bargechip b { font-weight: 600; }
.bargechip span { color: var(--ink-faint); font-size: 9.5px; }
.bargechip.kind-build { border-color: #2b5f8a; }
.bargechip.kind-case, .bargechip.kind-empty { border-style: dashed; }
.bargechip.elsewhere { opacity: .45; }
.bargecart { border: 2px solid #6b7280; background: #0e1114; padding: 8px; }
.bargetier { display: grid; gap: 6px; margin-bottom: 6px; }
.bargetier.w4 { grid-template-columns: repeat(4, 1fr); }
/* To scale: the steel cart is eight feet across, so a slot is two feet — a rack's width —
   and a four-foot skid draws at half the cart's width with the same two-foot slots. */
.bargetier.w2 { grid-template-columns: repeat(2, 1fr); width: 50%; }
/* The racks ride below; the lower tier is twice the upper's height, as the cart is. */
.bargetier.upper .bargeslot { height: 110px; }
.bargetier.lower .bargeslot { height: 220px; }
.bargeslot { box-sizing: border-box; overflow: hidden; }
.bargeslot .rackface2d { flex: 1; min-height: 0; overflow: hidden; }
.bargeslot {
  position: relative; min-height: 96px; padding: 6px 8px; border: 1px dashed #3d434c; background: var(--panel);
  display: flex; flex-direction: column; gap: 3px; font: 11px/1.3 var(--data); color: var(--ink);
}
.bargeslot.over { border-color: var(--amber-hi); background: #2a2113; }
.bargeslot.kind-open { justify-content: center; align-items: center; color: #3d434c; font-size: 10px; }
.bargeslot.kind-rack, .bargeslot.kind-build { border-style: solid; border-color: #6b7280; cursor: grab; }
.bargeslot.kind-case, .bargeslot.kind-empty { border-style: solid; border-color: #4a4f57; cursor: grab; }
.bargeslot b { font: 700 12px/1.2 var(--chrome); letter-spacing: .08em; }
.bargeslot .bargecaption { color: var(--amber); font-size: 10px; }
.bargeslot .caseband { display: block; height: 8px; margin-top: auto; }
.rackface2d { margin-top: 4px; border: 1px solid #3d434c; background: #15181d; padding: 4px; }
.rackface2d.distro { display: flex; justify-content: center; padding: 3px; }
/* The distro's back as one drawing: the box scales the viewBox, so every outlet stays round. */
.distro2d { display: block; width: 100%; height: 100%; max-height: 100%; }
.distro2d .panelbg { fill: #0e1114; stroke: #5b6068; stroke-width: 1; }
.distro2d .lbl { fill: var(--ink-faint); font-family: var(--chrome); letter-spacing: .04em; }
.distro2d .soca .shell { fill: #2b2f36; stroke: #b0b6bf; stroke-width: .5; }
.distro2d .soca .face { fill: #1a1d22; stroke: #6b7280; stroke-width: .35; }
.distro2d .pin { fill: #c9a24a; }
.distro2d .bracket { fill: #3d434c; stroke: #8a9099; stroke-width: .3; }
.distro2d .twist .shell { fill: #d8dbe0; stroke: #8a9099; stroke-width: .5; }
.distro2d .white { fill: #eef0f3; stroke: #9aa0a8; stroke-width: .4; }
.distro2d .duplex .faceplate { fill: #f6f7f9; stroke: #b0b6bf; stroke-width: .3; }
.distro2d .slot { fill: #23272e; stroke: #23272e; }
.distro2d .c5 .blue { fill: #2f6fd8; stroke: #9cc0ff; stroke-width: .5; }
.distro2d .c5 .bluehole { fill: #1d4ea3; stroke: #0b2b66; stroke-width: .4; }
.distro2d .cam .camshell { stroke: #0008; stroke-width: .5; }
.distro2d .cam .barrel { fill: #0a0c0f; }
.distro2d .cam .bore { fill: #3d434c; }
.rackface2d.data .seat2d { font: 9.5px/1.5 var(--data); color: var(--ink); border-bottom: 1px solid #23272e; padding: 0 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rackface2d.data .seat2d.dim { color: var(--ink-faint); }
.bargeorient { display: flex; justify-content: space-between; padding: 4px 8px; font: 700 10px/1.4 var(--chrome); letter-spacing: .18em; color: var(--ink-faint); }
.bargepower { margin-top: 8px; border: 1px solid var(--seam); background: var(--plate); }
.bargewires { display: block; background: #0e1114; }
.bargewirectl { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 6px 8px; border-top: 1px solid var(--seam); }
.bargewirectl .wirerow { display: inline-flex; gap: 4px; align-items: center; }
.bargewirectl .askpick, .bargewirectl .askfield {
  padding: 3px 6px; background: #0e1114; border: 1px solid var(--seam); color: var(--ink); font-family: var(--data); font-size: 11px;
}
.bargewirelist { padding: 4px 8px 6px; }
.wireline { display: flex; align-items: center; gap: 8px; font: 11px/1.6 var(--data); color: var(--ink); }
.wireline .cmd { padding: 0 6px; line-height: 1.2; }
.bargenotes { margin-top: 8px; }
.bargenote { width: 100%; box-sizing: border-box; padding: 5px 8px; background: #0e1114; border: 1px solid var(--seam); color: var(--ink); font: 11px/1.4 var(--data); resize: vertical; }
.printonly { display: none; }
@media print {
  /* The barge sheet: one Letter page, landscape — the cart to scale across the top, the
     power diagram under it, tightened so both fit. */
  body.print-barge { --page: 10.2in; }
  @page { size: letter landscape; margin: 0.4in; }
  /* Only the barge sheet prints: everything is hidden, the sheet shown again and laid at
     the top of the page — which holds whatever the app wraps #main in. */
  body.print-barge *:not(:has(.bargeview)):not(.bargeview):not(.bargeview *) { display: none !important; }
  body.print-barge .bargepicker, body.print-barge .bargestrip, body.print-barge .noprint, body.print-barge .bargenote, body.print-barge .bargeopen { display: none !important; }
  body.print-barge, body.print-barge *:has(.bargeview) { display: block; position: static; width: auto; height: auto; padding: 0; margin: 0; overflow: visible; background: #fff; }
  body.print-barge .bargeview { width: var(--page); }
  body.print-barge .barge { border: 0; padding: 0; }
  body.print-barge .bargehead { margin-bottom: 4px; }
  body.print-barge .bargehead h3 { font-size: 14px; }
  body.print-barge .bargecart { padding: 4px; border-width: 2px; }
  body.print-barge .bargetier { gap: 4px; margin-bottom: 4px; }
  body.print-barge .bargetier.upper .bargeslot { height: 0.95in; }
  body.print-barge .bargetier.lower .bargeslot { height: 1.9in; }
  body.print-barge .bargeslot { padding: 3px 5px; font-size: 9px; }
  body.print-barge .bargeslot b { font-size: 10px; }
  body.print-barge .bargeorient { padding: 2px 6px; font-size: 8px; }
  body.print-barge .bargepower { margin-top: 4px; }
  body.print-barge .bargepower h4 { padding: 2px 6px; font-size: 8px; }
  body.print-barge .bargewires { max-height: 2.2in; }
  body.print-barge .bargewirelist { padding: 2px 6px; }
  body.print-barge .wireline { font-size: 9px; line-height: 1.4; }
  body.print-barge .bargenotes { margin-top: 4px; }
  body.print-barge .printonly { display: block; font: 9px/1.3 var(--data); }
  body.print-barge .printonly { display: block; font: 11px/1.4 var(--data); }
  body.print-barge, body.print-barge .barge, body.print-barge .bargeslot, body.print-barge .bargepower, body.print-barge .bargecart { background: #fff !important; color: #000 !important; }
  body.print-barge .bargeslot, body.print-barge .bargecart, body.print-barge .rackface2d { border-color: #000 !important; }
  body.print-barge .bargeslot b, body.print-barge .bargehead h3, body.print-barge .bargeslot .bargecaption { color: #000 !important; }
  body.print-barge .distro2d .panelbg { fill: #fff; stroke: #000; }
  body.print-barge .distro2d .lbl { fill: #000; }
  body.print-barge .distro2d .shell { fill: #fff; stroke: #000; }
  body.print-barge .distro2d .face { fill: #fff; stroke: #000; }
  body.print-barge .distro2d .bracket { fill: #fff; stroke: #000; }
  body.print-barge .distro2d .barrel { fill: #000; }
  body.print-barge .distro2d .bore { fill: #fff; }
  body.print-barge .bargewires { background: #fff; }
  body.print-barge .bargewires text { fill: #000; }
  body.print-barge .bargewires path { stroke: #000; }
  body.print-barge .bargewires rect { fill: #fff; stroke: #000; }
}

/* ---- truck pack ------------------------------------------------------------------- */
/* The trailer is the page; the tally and the sheet flank it, as columns not cards. */
main > .truckpack { max-width: none; }
.truckpack .commands { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; }
.truckstrip { display: flex; flex-wrap: wrap; gap: 1px; background: var(--seam); padding: 1px; }
.trucktab { display: flex; flex-direction: column; gap: 1px; padding: 4px 10px; background: var(--panel); color: var(--ink-dim); border: 0; text-align: left; cursor: pointer; font: inherit; min-width: 96px; }
.trucktab b { font: 700 12px/1 var(--chrome); letter-spacing: .12em; color: var(--ink); }
.trucktab i { font: 10px/1.2 var(--data); font-style: normal; color: var(--amber); }
.trucktab.on { background: var(--panel-hi); box-shadow: inset 0 -2px 0 var(--amber); }
.trucktab.bad b::after { content: ' !'; color: #ff5a3c; }
.truckhead { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 6px 10px; padding: 6px 8px; border: 1px solid var(--seam); background: var(--panel); margin-bottom: 8px; }
.truckfield { display: flex; flex-direction: column; gap: 1px; }
.truckfield span { font: 9px/1 var(--chrome); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); }
.truckfield .scalar { padding: 2px 5px; font-size: 11px; }
.truckcmds { margin-left: auto; display: flex; flex-wrap: wrap; gap: 4px; align-self: center; }
.truckbody { display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 360px); gap: 10px; align-items: start; }
.truckstaging { margin: 6px 0 10px; }
.trucktally, .trucksheet { min-width: 0; overflow-x: auto; }
.truckpack h4 { margin: 0 0 4px; font: 700 10px/1.4 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-dim); }
.truckpack h4.bad { color: #ff5a3c; }
.trucktally .tallygrid, .trucksheet .stackgrid { width: 100%; font-size: 11px; }
.trucktally .tallygrid td, .trucksheet .stackgrid td { padding: 1px 5px; }
.trucktally .tallygrid th, .trucksheet .stackgrid th { padding: 3px 5px; font-size: 9px; }
.trucktally .tallygrid select { width: 66px; }
.trucktally .tallygrid .cmd { padding: 1px 6px; font-size: 11px; }
.trucktally .scalar { padding: 1px 3px; font-size: 11px; }
.stagestrip { display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; min-height: 40px; padding: 6px; border: 1px dashed #3d434c; background: #0e1114; }
.stackchip { position: relative; box-sizing: border-box; display: flex; flex-direction: column; justify-content: center; align-items: center; overflow: hidden; border: 2px solid #6b7280; background: #23272e; color: var(--ink); cursor: grab; user-select: none; min-width: 24px; min-height: 24px; }
.stackchip b { font: 700 9px/1.1 var(--chrome); letter-spacing: .04em; text-align: center; }
.stackchip i { font: 8px/1.1 var(--data); font-style: normal; color: var(--ink-faint); }
.stackchip.on { outline: 2px solid var(--amber); outline-offset: 1px; }
.truckfloorwrap { overflow-x: auto; border: 1px solid var(--seam); background: var(--panel); padding: 6px; }
.truckfloor { display: block; width: 100%; min-width: 560px; max-height: 260px; height: auto; user-select: none; }
.truckfloor .wall { fill: #3d434c; }
.truckfloor .floor { fill: #101317; stroke: #8a9099; stroke-width: 1; }
.truckfloor .wheel { fill: #23272e; stroke: #5b6068; stroke-width: .8; }
.truckfloor .cab { fill: #1a1d22; stroke: #5b6068; stroke-width: .8; }
.truckfloor .kingpin { fill: #5b6068; }
.truckfloor .doors { stroke: #8a9099; stroke-width: 1; fill: none; }
.truckfloor .tick { stroke: #565c66; stroke-width: .8; }
.truckfloor .lbl { fill: var(--ink-faint); font: 7px var(--chrome); letter-spacing: .1em; }
.truckfloor .lbl.dim { font-size: 6px; }
.truckfloor .lbl.lf { fill: var(--amber); font-weight: 700; }
.truckfloor .lfline { stroke: var(--amber); stroke-width: .8; stroke-dasharray: 3 2; }
.truckfloor .stack { cursor: grab; }
.truckfloor .stack .case { fill: #23272e; stroke: #8a9099; stroke-width: 2; }
.truckfloor .stack.on .case { fill: #2a2113; stroke-width: 3; filter: drop-shadow(0 0 3px var(--amber)); }
.truckfloor .stack.bad .case { fill: #2a1313; }
.truckfloor .stack.droptarget .case { fill: #1f3a1f; }
.truckfloor .stacklbl { fill: var(--ink); font: 700 7.5px var(--chrome); letter-spacing: .04em; pointer-events: none; }
.truckfloor .stacksub { fill: var(--ink-dim); font: 6px var(--data); pointer-events: none; }
.truckfloor .stackhigh { fill: var(--amber); font: 700 6px var(--data); pointer-events: none; }
.truckfloor.droptarget .floor { stroke: var(--amber-hi); }
.stackghost { position: fixed; z-index: 60; pointer-events: none; display: flex; align-items: center; justify-content: center; box-sizing: border-box; border: 2px solid var(--amber); background: rgba(255,138,31,.25); color: var(--ink); min-width: 20px; min-height: 20px; }
.stackghost b { font: 700 9px/1 var(--chrome); letter-spacing: .04em; }
.truckpack.dragging { cursor: grabbing; }
.trucktotals { display: grid; grid-template-columns: auto 1fr; gap: 2px 10px; margin: 0 0 6px; font: 11px/1.4 var(--data); }
.trucktotals dt { color: var(--ink-faint); font: 10px/1.6 var(--chrome); letter-spacing: .1em; text-transform: uppercase; }
.trucktotals dd { margin: 0; color: var(--ink); }
.truckproblems { margin: 0 0 6px; padding: 0 0 0 14px; font: 11px/1.4 var(--data); color: #ff8a70; }
.truckproblems li { cursor: pointer; }
.truckproblems li:hover { color: var(--amber-hi); }
.truckprinthead { display: none; }
@media print {
  body.print-truckpack { --page: 10.2in; }
  body.print-truckpack *:not(:has(.truckpack)):not(.truckpack):not(.truckpack *) { display: none !important; }
  body.print-truckpack .noprint, body.print-truckpack .trucktally { display: none !important; }
  body.print-truckpack, body.print-truckpack *:has(.truckpack) { display: block; position: static; width: auto; height: auto; padding: 0; margin: 0; overflow: visible; background: #fff; }
  body.print-truckpack .truckpack { width: var(--page); }
  body.print-truckpack .truckprinthead { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 6px; font: 11px/1.3 var(--data); color: #000; }
  body.print-truckpack .truckprinthead b { font: 700 16px/1.2 var(--chrome); letter-spacing: .08em; }
  body.print-truckpack .truckbody { grid-template-columns: 1fr; gap: 8px; }
  body.print-truckpack .truckfloorwrap { overflow: visible; border-color: #000; background: #fff; padding: 0; }
  body.print-truckpack .truckfloor { min-width: 0; }
  body.print-truckpack .truckfloor .floor { fill: #fff; stroke: #000; }
  body.print-truckpack .truckfloor .wall { fill: #000; }
  body.print-truckpack .truckfloor .cab, body.print-truckpack .truckfloor .wheel { fill: #fff; stroke: #000; }
  body.print-truckpack .truckfloor .stack .case { fill: #fff; stroke-width: 2.5; }
  body.print-truckpack .truckfloor .stacklbl, body.print-truckpack .truckfloor .lbl, body.print-truckpack .truckfloor .stacksub, body.print-truckpack .truckfloor .stackhigh { fill: #000; }
  body.print-truckpack .truckfloor .lfline { stroke: #000; }
  body.print-truckpack .trucksheet, body.print-truckpack .trucksheet * { color: #000 !important; background: #fff !important; border-color: #000 !important; }
  body.print-truckpack .trucksheet .grid { font-size: 9px; }
}

/* ---- the patch window ---------------------------------------------------------------- */
main > .patch { max-width: none; }
.patch .commands { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 8px; }
.patchpicked { font: 11px/1.4 var(--data); color: var(--amber-hi); }
.patchuniverse { margin-bottom: 10px; }
.patchuniverse h3 { margin: 0 0 3px; }
.patchuniverse h3 em { font: 10px var(--data); font-style: normal; color: var(--ink-faint); letter-spacing: 0; text-transform: none; }
.patchgrid { display: grid; grid-template-columns: repeat(32, 17px); gap: 1px; width: max-content; padding: 2px; background: #0e1114; border: 1px solid var(--seam); }
.patchgrid i {
  height: 17px; box-sizing: border-box; background: #191c21; border: 1px solid #23272e; cursor: pointer;
  font: 700 7.5px/15px var(--data); font-style: normal; color: #0b0c0e; text-align: center; overflow: hidden; white-space: nowrap;
}
.patchgrid i:nth-child(32n+1) { position: relative; }
.patchgrid i:hover { border-color: var(--amber-hi); }
.patchgrid i.on { background: hsl(var(--hue) 55% 62%); border-color: hsl(var(--hue) 55% 40%); }
.patchgrid i.on.first { border-left: 2px solid #0b0c0e; }
.patchgrid i.on.last { border-right: 2px solid #0b0c0e; }
.patchgrid i.on.bad { background: #d0384a; border-color: #7a1620; color: #fff; }
.patchgrid i.on.picked { outline: 2px solid var(--amber); outline-offset: -1px; }
.patchunpatched summary { cursor: pointer; font: 11px var(--data); color: var(--amber); margin: 6px 0; }
.patchunpatched div { display: flex; flex-wrap: wrap; gap: 4px; }
.patchchip { font: 10.5px var(--data); padding: 2px 6px; background: var(--panel); border: 1px solid var(--seam-bright); color: var(--ink); cursor: pointer; }
.patchchip:hover { border-color: var(--amber); }

/* ---- phones and tablets ------------------------------------------------------------------ */
/*
  The app is built for a laptop beside a drawing, but it is read on a phone in a truck and
  on a tablet at the dock, and the web app has to hold up there. Nothing is redesigned: the
  rail becomes a drawer, the title bar wraps, and every wide thing — a sheet, the trailer,
  the barge — scrolls inside its own box rather than pushing the page sideways.
*/
@media (max-width: 900px) {
  html, body { max-width: 100vw; overflow-x: hidden; }
  .titlebar { height: auto; flex-wrap: wrap; }
  .titlebar .mark { padding: 0 10px; }
  .titlebar .mark i, .titlebar .screw, .titlebar .lamp { display: none; }
  .titlebar .menubar { height: 28px; }
  .titlebar .plate-right { margin-left: auto; padding: 0 6px; gap: 6px; }
  .modeswitch button { padding: 0 6px; font-size: 9.5px; }
  .shows { overflow-x: auto; }
  .show-tab { min-width: 0; padding: 5px 10px; }
  .toolbar .where span { display: none; }
  .renderpill { right: 10px; bottom: 10px; max-width: calc(100vw - 20px); white-space: normal; }
  /* The rail is a drawer: the toolbar's ▶ opens it, a tap on a section or the shade closes it. */
  .frame { grid-template-columns: 1fr; }
  body.railshut .frame { grid-template-columns: 1fr; }
  .rail, body.railshut .rail {
    display: block; position: fixed; left: 0; top: 0; bottom: 0; z-index: 92; width: 232px;
    overflow-y: auto; padding-bottom: 40px; box-shadow: 0 0 40px rgba(0,0,0,.7);
    transform: translateX(-100%); transition: transform .18s ease-out;
  }
  body.railopen .rail { transform: none; }
  .railshade { display: none; position: fixed; inset: 0; z-index: 91; background: rgba(0,0,0,.45); }
  body.railopen .railshade { display: block; }
  main { padding: 8px 8px 60px; max-width: 100vw; overflow-x: hidden; }
  main > * { max-width: 100%; }
  .sheetframe, .gridwrap, .rackdata, .cablebody, .looms, .caseplan, .trucking { max-width: 100%; overflow-x: auto; }
  .gridwrap { max-height: calc(100vh - 150px); }
  .cards .card { flex: 1 1 42%; min-width: 0; padding: 8px 10px; }
  .previewer { inset: 0; }
  .askbox { left: 8px; right: 8px; top: 12%; transform: none; max-width: none; }
  .keyspop, .cellmenu { max-width: calc(100vw - 16px); }
  .footer { right: 0; border-right: 0; font-size: 9px; gap: 8px; }
  .signinbox { width: min(380px, calc(100vw - 24px)); }
  /* The truck pack stacks its three columns; the trailer keeps its width and scrolls. */
  .truckbody { grid-template-columns: 1fr; }
  .truckhead .truckcmds { margin-left: 0; }
  .truckfloor { min-width: 640px; }
  /* The barge: the cart keeps its eight feet and scrolls; the strip wraps. */
  .bargeview .bargecart { min-width: 560px; }
  .bargeview { overflow-x: auto; }
  .rackpicker, .bargepicker, .truckstrip { flex-wrap: wrap; }
  .toolbar .commands { margin-left: 0; }
  .patchuniverse { overflow-x: auto; }
  .patchgrid { grid-template-columns: repeat(32, 14px); }
  .patchgrid i { height: 14px; font-size: 6.5px; line-height: 12px; }
}
/* A finger is wider than a pointer: room to tap, and inputs big enough that the phone does not zoom. */
@media (max-width: 900px) and (pointer: coarse) {
  .rail button { padding-top: 8px; padding-bottom: 8px; }
  .cmd, .modes button, .trucktab, .rackpicker button { min-height: 34px; }
  input.scalar, select.scalar, .truckfield .scalar, .askbox input, .askbox select { font-size: 16px; }
  tbody td { height: 32px; }
}

/* ---- Home: the shows to open, what the address itself lands on ---- */
.home { padding: 12px 18px; max-width: 980px; }
.home h2 { margin: 0 0 8px; font: 600 14px/1.2 var(--chrome); letter-spacing: .06em; text-transform: uppercase; color: var(--ink); }
.home .importbar { margin-bottom: 10px; }
.homelist tbody tr { cursor: pointer; }
.homelist tbody tr:hover td { background: #171b20; }
.homelist td b { font-weight: 600; }
.homelist td.dim, .homelist .dim { color: var(--ink-faint); }
.homelist td.num { text-align: right; }
.mark { cursor: pointer; }

/* ---- the import wizard: an upload's changes, each confirmed, flagged or denied ---- */
.askbox.importwiz { max-width: 960px; }
.askbox.importwiz .askheading { flex: 1 0 100%; margin: 0; font: 600 14px/1.3 var(--chrome); color: var(--ink); }
/* In the wizard's flex column a scrolling box shrinks to nothing; it keeps its content height. */
.askbox.importwiz .floortable { max-height: 52vh; overflow: auto; flex: 0 0 auto; }
.askbox.importwiz .cards .card.isnew b { color: var(--amber-hi); }
.askbox.importwiz .cards .card.isupdate b { color: #72b4eb; }
.askbox.importwiz .cards .card.isflag b { color: #f1c232; }
.askbox.importwiz .importall { display: flex; gap: 6px; align-items: center; }
.askbox.importwiz .importall .keyhint { margin: 0 4px 0 0; }
.laborreview td.chg { font: 700 9.5px/1.6 var(--chrome); letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; }
.laborreview td.chg.new { color: var(--amber-hi); }
.laborreview td.chg.update { color: #72b4eb; }
.laborreview td.chg.same { color: var(--ink-faint); }
.laborreview td.detail { color: var(--ink-dim); font-size: 11.5px; line-height: 1.4; }
.laborreview td.dim { color: var(--ink-faint); white-space: nowrap; }
.tri { display: inline-flex; gap: 0; }
.tri button { padding: 3px 9px; font: 600 10.5px var(--chrome); letter-spacing: .06em; background: var(--panel); color: var(--ink-dim); border: 1px solid var(--seam); cursor: pointer; }
.tri button + button { border-left: 0; }
.tri button.on.triconfirm { background: var(--amber-lo); color: var(--ground); border-color: var(--amber-lo); }
.tri button.on.triflag { background: #f1c232; color: #1a1400; border-color: #f1c232; }
.tri button.on.trideny { background: #5c2b31; color: #ffd7dc; border-color: #5c2b31; }
.tri button:hover:not(.on) { color: var(--ink); }
/* The review table stays inside the pop-up: the column may not grow past it, and What moves wraps. */
.askbox.importwiz .askbody, .askbox.importwiz .floortable { min-width: 0; max-width: 100%; }
.askbox.importwiz .laborreview td { white-space: normal; }
.askbox.importwiz .laborreview td.chg, .askbox.importwiz .laborreview td:last-child { white-space: nowrap; }
/* A group's field grid sizes to its fields: a percentage basis inside the wizard's column
   spilled each group over the heading below it. */
.askbox.askwizard .askgroup > .askgrid { flex: 0 0 auto; }
.askbox.askwizard .askbody > .askgroup + .askgroup { margin-top: 6px; }

/* The New show wizard's person groups: a heading with From the directory beside it, and the search under it. */
.askbox.askwizard .askgrouphead { display: flex; align-items: center; gap: 10px; }
.askbox.askwizard .askgrouphead > span { font: 700 9.5px/1.6 var(--chrome); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); }
.askbox.askwizard .askgrouphead .cmd { padding: 1px 8px; font-size: 9.5px; }
.askbox.askwizard .askdirsearch { display: flex; flex-direction: column; gap: 4px; margin: 2px 0 4px; }
.askbox.askwizard .askdirresults { display: flex; flex-direction: column; gap: 2px; }
.askbox.askwizard .askdirresults button { display: flex; gap: 10px; align-items: baseline; text-align: left; padding: 4px 8px; background: var(--panel); border: 1px solid var(--seam); color: var(--ink); cursor: pointer; font: 11.5px var(--data); }
.askbox.askwizard .askdirresults button:hover { border-color: var(--amber-lo); }
.askbox.askwizard .askdirresults button span { color: var(--ink-dim); font-size: 10.5px; }
.askbox.askwizard .askdirresults em { font-style: normal; color: var(--ink-faint); font-size: 11px; }
.askbox.askwizard .askdirsearch[hidden] { display: none; }
.askbox.askwizard .askband[hidden] { display: none; }
/* Every child of the wizard's column sizes to its content: a 100% basis in a column of no set height pushed what followed out of the body. */
.askbox.askwizard .askbody > * { flex: 0 0 auto; }
