/* =========================================================================
 * The console shell
 * =========================================================================
 * This is a tool, not a page. It fills the viewport, nothing stacks, and every
 * region scrolls on its own. If somebody has to scroll a page to find the thing
 * that is on fire, the console has already failed.
 *
 * Two axes over one model: seats across the top for who you are, views down the
 * rail for what you are looking at. Switching seat reframes the view you are on
 * rather than navigating away from it.
 *
 * The blockers rail and the clock are always present, because "what is wrong"
 * and "as at when" are true of every view and should never be somewhere else.
 */

.consolepage main,
.consolepage .lead-section { max-width: none; }

.cx {
  display: grid;
  grid-template-columns: 216px minmax(0, 1fr) 344px;
  grid-template-rows: 54px minmax(0, 1fr) auto;
  grid-template-areas:
    "top   top   top"
    "rail  main  aside"
    "clock clock clock";
  /* Sized to what is left under the site header, not to the whole viewport.
     On a 1366 by 768 laptop there is about 566px below the nav, and the console
     was asking for 744 with a 660 floor. It overflowed, the page scrolled, and
     the clock fell off the bottom, which is the one control you want in front of
     you while you are talking. A laptop across a table is the case this has to
     work in. */
  height: calc(100dvh - var(--cx-offset, 88px));
  min-height: 460px;
  margin: 0 0 40px;
  border-radius: 16px;
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 18% 0%, rgba(63, 189, 240, .08), transparent 58%),
    rgba(255, 255, 255, .02);
  border: 1px solid var(--hair);
}

/* ---- Top bar: the seats -------------------------------------------------- */
.cx-top {
  grid-area: top;
  display: flex; align-items: center; gap: 18px;
  padding: 0 16px;
  border-bottom: 1px solid var(--hair);
  background: rgba(255, 255, 255, .022);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
}
.cx-brand { display: flex; align-items: baseline; gap: 10px; flex: none; }
.cx-mark {
  font-family: var(--font-display); font-weight: 700; font-size: 15px; letter-spacing: -.01em;
}
.cx-camp { font-size: 12px; color: rgba(255, 255, 255, .48); white-space: nowrap; }

.cx-seats { display: flex; gap: 3px; align-items: center; overflow-x: auto; scrollbar-width: none; }
.cx-seats::-webkit-scrollbar { display: none; }
.cx-seats button {
  position: relative; white-space: nowrap; cursor: pointer;
  padding: 7px 14px; border-radius: 8px; font-size: 13.5px;
  background: transparent; border: 1px solid transparent; color: rgba(255, 255, 255, .6);
}
.cx-seats button:hover { color: #fff; background: rgba(255, 255, 255, .05); }
.cx-seats button.on {
  color: #fff; background: rgba(63, 189, 240, .14); border-color: rgba(63, 189, 240, .34);
}
.cx-seats button .sq { display: block; font-size: 10.5px; color: rgba(255, 255, 255, .42); }
.cx-seats button.on .sq { color: rgba(63, 189, 240, .85); }

.cx-meta {
  margin-left: auto; display: flex; align-items: center; gap: 14px; flex: none;
  font-size: 11.5px; color: rgba(255, 255, 255, .5);
}
.cx-meta .live { display: inline-flex; align-items: center; gap: 6px; }
.cx-meta .live i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--ok);
  box-shadow: 0 0 0 3px rgba(47, 224, 189, .18);
}
.cx-meta .ill {
  padding: 2px 9px; border-radius: 999px;
  border: 1px solid rgba(242, 163, 60, .32); color: var(--warn); background: rgba(242, 163, 60, .09);
}

/* ---- Rail: the views ----------------------------------------------------- */
.cx-rail {
  grid-area: rail;
  border-right: 1px solid var(--hair);
  background: rgba(0, 0, 0, .14);
  overflow-y: auto; padding: 12px 10px 16px;
}
.cx-rail .rg {
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: rgba(255, 255, 255, .34); padding: 12px 10px 6px;
}
.cx-rail .rg:first-child { padding-top: 2px; }
.cx-rail button {
  display: flex; align-items: center; gap: 10px; width: 100%; cursor: pointer;
  padding: 9px 11px; border-radius: 9px; margin-bottom: 2px; text-align: left;
  font-size: 13.5px; background: transparent; border: 1px solid transparent;
  color: rgba(255, 255, 255, .66);
}
.cx-rail button:hover { background: rgba(255, 255, 255, .05); color: #fff; }
.cx-rail button.on {
  background: linear-gradient(90deg, rgba(63, 189, 240, .18), rgba(63, 189, 240, .05));
  border-color: rgba(63, 189, 240, .3); color: #fff;
}
.cx-rail button .ri { flex: none; width: 16px; height: 16px; opacity: .7; }
.cx-rail button.on .ri { opacity: 1; }
.cx-rail button .ri svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.7; }
.cx-rail button .rc {
  margin-left: auto; font-size: 11px; font-variant-numeric: tabular-nums;
  padding: 1px 7px; border-radius: 999px; background: rgba(255, 255, 255, .07);
  color: rgba(255, 255, 255, .55);
}
.cx-rail button .rc.bad { background: var(--bad-soft); color: var(--bad); }

/* ---- Main: the selected view --------------------------------------------- */
.cx-main {
  grid-area: main;
  overflow-y: auto; overflow-x: hidden;
  padding: 18px 22px 28px;
  scroll-behavior: smooth;
}
.cx-main:focus { outline: none; }
.cx-main > .sec:first-child { margin-top: 0; }

/* ---- Aside: blockers and tasks, always present --------------------------- */
.cx-aside {
  grid-area: aside;
  border-left: 1px solid var(--hair);
  background: rgba(0, 0, 0, .14);
  overflow-y: auto; padding: 14px 14px 20px;
}
.cx-aside h3 {
  margin: 0 0 4px; font-size: 12.5px; letter-spacing: .06em; text-transform: uppercase;
  color: rgba(255, 255, 255, .5); font-weight: 500;
}
.cx-aside .ax-sub { margin: 0 0 11px; font-size: 11.5px; color: rgba(255, 255, 255, .38); line-height: 1.5; }
.cx-aside .ax-group { margin-bottom: 20px; }

/* A blocker card. Ordered by what it costs, so the worst thing is at the top
   rather than the loudest thing. */
.blk {
  width: 100%; text-align: left; cursor: pointer; display: block;
  padding: 11px 12px; border-radius: 10px; margin-bottom: 8px;
  background: rgba(255, 255, 255, .03); border: 1px solid var(--hair);
  border-left: 3px solid var(--warn);
  /* A button does not inherit colour. Without this the UA hands it buttontext,
     which is black, and anything inside that does not set its own colour is
     black on a near-black card. That is what happened to .blk-t: 1.32:1, the
     one line that says what the blocker actually is. Set here as well as on
     .blk-t so the next thing added inside a card cannot fall into it again. */
  color: var(--dim);
}
.blk.blocked { border-left-color: var(--bad); }
.blk:hover { background: rgba(255, 255, 255, .06); }
.blk.on { border-color: rgba(63, 189, 240, .45); background: rgba(63, 189, 240, .09); }
.blk-h { display: flex; align-items: center; gap: 7px; margin-bottom: 5px; }
.blk-tag {
  font-size: 9.5px; letter-spacing: .09em; text-transform: uppercase; font-weight: 600;
  padding: 2px 7px; border-radius: 4px;
}
.blk.blocked .blk-tag { background: var(--bad-soft); color: var(--bad); }
.blk.at-risk .blk-tag { background: var(--warn-soft); color: var(--warn); }
.blk-id { font-size: 11px; color: rgba(255, 255, 255, .45); font-variant-numeric: tabular-nums; }
.blk-due { margin-left: auto; font-size: 11px; color: rgba(255, 255, 255, .42); }
/* The sentence that says what the blocker is. It is the reason the card exists,
   so it is the most legible thing on it: everything else here is metadata and
   sits below it deliberately. */
.blk-t { font-size: 13px; line-height: 1.45; margin-bottom: 5px; color: rgba(255, 255, 255, .9); }
.blk-cost {
  display: flex; flex-wrap: wrap; gap: 4px 10px;
  font-size: 11px; color: rgba(255, 255, 255, .5); font-variant-numeric: tabular-nums;
}
.blk-cost b { color: var(--bad); font-weight: 600; }

/* ---- Clock: always visible ----------------------------------------------- */
.cx-clock {
  grid-area: clock;
  border-top: 1px solid var(--hair);
  background: rgba(0, 0, 0, .2);
  padding: 9px 16px 10px;
}
.cx-clock .clock { margin: 0; padding: 0; background: none; border: none; backdrop-filter: none; }

/* ---- Below the console --------------------------------------------------- */
.cx-below { max-width: 74ch; margin: 0 auto; padding: 0 0 40px; }

/* ---- Narrow ---------------------------------------------------------------
 * Below this the three-column console stops being a console. Rather than
 * squeezing it, the rail becomes a horizontal strip and the aside moves under
 * the main view, which is the honest thing to do: this is a desktop tool and
 * the phone shell at /app is deliberately a teaser rather than this.
 */
/* Short screens. A laptop is not a small screen, it is a short one, and the
   answer is to give the chrome less and the content the same rather than to
   start hiding things. */
@media (max-height: 860px) {
  .cx { grid-template-rows: 46px minmax(0, 1fr) auto; }
  .cx-top { padding: 0 12px; gap: 12px; }
  .cx-seats button { padding: 5px 11px; font-size: 12.5px; }
  .cx-seats button .sq { display: none; }
  .cx-main { padding: 13px 16px 20px; }
  .cx-rail { padding: 8px 8px 12px; }
  .cx-rail button { padding: 7px 10px; font-size: 12.5px; }
  .cx-rail .rg { padding: 8px 10px 4px; }
  .cx-aside { padding: 10px 11px 14px; }
  .cx-clock { padding: 6px 14px 7px; }
  .buildview .clock .ck-head { margin-bottom: 7px; gap: 10px; }
  .buildview .ck-play { width: 28px; height: 28px; }
  .buildview .ck-now b { font-size: 14px; }
  .buildview .ck-ends { display: none; }
  .buildview .cake-head p, .buildview .bt-n { display: none; }
}

/* Shorter still, or a laptop with a lot of browser chrome. */
@media (max-height: 700px) {
  .cx { grid-template-rows: 42px minmax(0, 1fr) auto; }
  .buildview .twonum .tn-v { font-size: 30px; }
  .buildview .twonum .tn { padding: 11px 14px; }
  .buildview .lay-row { padding: 7px 12px; gap: 12px; }
  .buildview .lay-ic { width: 32px; height: 32px; }
  .buildview .lay-pct { font-size: 20px; }
}

@media (max-width: 1100px) {
  .cx {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr) auto auto;
    grid-template-areas: "top" "rail" "main" "aside" "clock";
    height: auto; min-height: 0;
  }
  .cx-rail {
    border-right: none; border-bottom: 1px solid var(--hair);
    display: flex; gap: 4px; overflow-x: auto; padding: 10px;
  }
  .cx-rail .rg { display: none; }
  .cx-rail button { width: auto; white-space: nowrap; margin: 0; }
  .cx-rail button .rc { margin-left: 6px; }
  .cx-aside { border-left: none; border-top: 1px solid var(--hair); }
  .cx-main { max-height: none; }
}

/* ---- Phone: stop the header taking the page with it -----------------------
 * The rule above handles the layout. It does not touch .cx-top, and nothing
 * below 1100px does.
 *
 * That row is a flex with two flex:none children and a nowrap campus line, so
 * its min-content sits around 700px and it cannot shrink. On a phone it
 * overflowed the stacked column, the page grew to roughly twice the width of
 * the screen, and the browser zoomed out to fit the whole scrollable width.
 * Every panel then painted at the true column width inside a page scaled to
 * about a fifth, which is why the blockers panel read as though it had never
 * been made responsive. It had. It was the symptom. The header was the cause,
 * and the one-word-per-line wrapping everywhere else was the tell.
 *
 * Three rows on a phone: who and where, then the seats, then the meta. The
 * campus line is allowed to wrap, the seats keep the horizontal scroll they
 * already had, and the meta wraps instead of pinning right. Illustrative stays
 * visible. That one is a disclaimer, not decoration.
 */
@media (max-width: 900px) {
  .cx-top {
    flex-wrap: wrap; align-items: flex-start;
    row-gap: 7px; column-gap: 12px;
    padding: 9px 13px;
  }
  .cx-top > * { min-width: 0; }
  .cx-brand { flex: 1 1 100%; }
  .cx-camp { white-space: normal; }
  .cx-seats { flex: 1 1 100%; }
  .cx-meta { flex: 1 1 100%; margin-left: 0; flex-wrap: wrap; gap: 8px 12px; }

  /* The guard, not the fix. The console carries a lot of nowrap chips and any
     one of them could do this again. Clipping the shell means a wide child
     overflows its own panel rather than the page. clip and not hidden, so no
     new scroll container appears and the sticky timeline label keeps working.
     Panels that need to scroll sideways, the timeline especially, already own
     their own scroller and are unaffected. */
  .cx { overflow-x: clip; }
  .cx > * { min-width: 0; }
}

/* The Build, console styling.
 *
 * Loaded after build.css and scoped to .buildview like everything else. This
 * file owns the v2 console: the stage ribbon, the isometric layer cake, and the
 * glass surfaces they sit on.
 *
 * ---------------------------------------------------------------------------
 * On the aesthetic
 * ---------------------------------------------------------------------------
 * Dark ground, frosted glass, a single accent, and light used to mean something
 * rather than to decorate. Glow is reserved: a slab glows when it is selected or
 * when it is blocked, and nothing else does. If everything glows, the glow stops
 * carrying information and the thing turns into a screensaver.
 *
 * Colour comes from the brand tokens. --cyan is the accent, --mint is the good
 * state, and the RAG variables below are the dark-ground versions of the ones
 * build.css defines for charts, which are tuned for a light ground and read
 * muddy against navy.
 */

.buildview {
  /* RAG tuned for the dark console. build.css keeps its own set for charts,
     which need the light-ground contrast ratios. */
  --ok: #2fe0bd;
  --warn: #f2a33c;
  --bad: #ff5f6d;
  --ok-soft: rgba(47, 224, 189, .13);
  --warn-soft: rgba(242, 163, 60, .13);
  --bad-soft: rgba(255, 95, 109, .13);
  --glass: rgba(255, 255, 255, .034);
  --glass-2: rgba(255, 255, 255, .055);
  --hair: rgba(255, 255, 255, .085);
  --hair-2: rgba(255, 255, 255, .14);
}

/* Frosted surface. Used for every panel in the console so the layering reads
   consistently, with a hairline that lifts it off the ground. */
.buildview .glass {
  background: var(--glass);
  border: 1px solid var(--hair);
  border-radius: 14px;
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
}

/* ---- The stage ribbon -----------------------------------------------------
 * Quote to live, across the top. A cold viewer should know where the programme
 * is before they know anything else about it.
 */
.buildview .ribbon {
  display: grid;
  grid-template-columns: minmax(190px, 232px) 1fr minmax(180px, 216px);
  gap: 14px;
  align-items: stretch;
  margin: 0 0 20px;
}
.buildview .rb-lead,
.buildview .rb-end {
  padding: 15px 18px;
  border-radius: 14px;
  background: linear-gradient(150deg, rgba(63, 189, 240, .11), rgba(63, 189, 240, .03));
  border: 1px solid rgba(63, 189, 240, .22);
  display: flex; flex-direction: column; justify-content: center; gap: 3px;
}
.buildview .rb-end {
  background: linear-gradient(150deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .015));
  border-color: var(--hair);
  text-align: right;
}
.buildview .rb-lead .k,
.buildview .rb-end .k {
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  color: rgba(255, 255, 255, .5);
}
.buildview .rb-lead b { font-family: var(--font-display); font-size: 19px; line-height: 1.2; }
.buildview .rb-end b { font-size: 18px; font-variant-numeric: tabular-nums; }
.buildview .rb-end b.good { color: var(--ok); }
.buildview .rb-end b.bad { color: var(--bad); }
.buildview .rb-sub { font-size: 11.5px; color: rgba(255, 255, 255, .5); line-height: 1.45; }

.buildview .rb-steps {
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  gap: 5px; list-style: none; margin: 0; padding: 0;
}
/* Chevrons. The notch on the right of each step and the matching notch cut out
   of the left of the next one is what makes the row read as a direction. */
.buildview .rb-step {
  position: relative;
  padding: 13px 16px 13px 26px;
  background: var(--glass);
  border: 1px solid var(--hair);
  border-left: none;
  clip-path: polygon(0 0, calc(100% - 13px) 0, 100% 50%, calc(100% - 13px) 100%, 0 100%, 13px 50%);
  display: flex; flex-direction: column; gap: 2px;
}
.buildview .rb-step:first-child { clip-path: polygon(0 0, calc(100% - 13px) 0, 100% 50%, calc(100% - 13px) 100%, 0 100%); }
.buildview .rb-step:last-child { clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 13px 50%); }

.buildview .rb-step.done { background: rgba(47, 224, 189, .09); }
.buildview .rb-step.now {
  background: linear-gradient(120deg, rgba(63, 189, 240, .18), rgba(63, 189, 240, .06));
  box-shadow: inset 0 0 0 1px rgba(63, 189, 240, .34), 0 0 22px rgba(63, 189, 240, .16);
}
.buildview .rb-n {
  font-size: 10.5px; letter-spacing: .1em; color: rgba(255, 255, 255, .38);
  font-variant-numeric: tabular-nums;
}
.buildview .rb-step.done .rb-n { color: var(--ok); }
.buildview .rb-step.now .rb-n { color: var(--cyan); }
.buildview .rb-t { font-size: 14.5px; font-weight: 560; line-height: 1.2; }
.buildview .rb-s { font-size: 11px; color: rgba(255, 255, 255, .46); line-height: 1.35; }
.buildview .rb-bar {
  display: block; height: 3px; margin-top: 7px; border-radius: 999px;
  background: rgba(255, 255, 255, .1); overflow: hidden;
}
.buildview .rb-bar i {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--cyan), var(--ok));
}
.buildview .rb-step.done .rb-bar i { background: var(--ok); }
.buildview .rb-p {
  position: absolute; top: 12px; right: 15px;
  font-size: 11.5px; color: rgba(255, 255, 255, .5); font-variant-numeric: tabular-nums;
}
@media (max-width: 1180px) {
  .buildview .ribbon { grid-template-columns: 1fr; }
  .buildview .rb-end { text-align: left; }
  .buildview .rb-steps { grid-auto-flow: row; grid-auto-columns: auto; }
  .buildview .rb-step, .buildview .rb-step:first-child, .buildview .rb-step:last-child { clip-path: none; border-left: 1px solid var(--hair); border-radius: 9px; padding-left: 16px; }
}

/* ---- The layer detail ----------------------------------------------------- */
.buildview .cake-detail { margin-top: 14px; }
.buildview .cake-hint {
  margin: 0; padding: 14px 16px; border-radius: 11px;
  background: rgba(255, 255, 255, .022); border: 1px dashed var(--hair-2);
  font-size: 13px; color: rgba(255, 255, 255, .5);
}
.buildview .ld {
  padding: 16px 18px; border-radius: 12px;
  background: var(--glass-2); border: 1px solid var(--hair);
  border-left: 3px solid rgba(255, 255, 255, .2);
}
.buildview .ld.rag-green { border-left-color: var(--ok); }
.buildview .ld.rag-amber { border-left-color: var(--warn); }
.buildview .ld.rag-red { border-left-color: var(--bad); }
.buildview .ld-h { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 7px; }
.buildview .ld-h h3 { margin: 0; font-size: 17px; font-family: var(--font-display); font-weight: 600; }
.buildview .ld-drive {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 12px;
  margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--hair);
}
.buildview .ld-drive .k { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: rgba(255, 255, 255, .45); }
.buildview .ld-drive b { font-size: 14px; font-weight: 550; }
.buildview .ld-d { font-size: 12.5px; color: rgba(255, 255, 255, .55); font-variant-numeric: tabular-nums; }
.buildview .ld-blocked { margin-top: 11px; display: flex; flex-direction: column; gap: 8px; }
.buildview .ldb {
  display: flex; align-items: flex-start; gap: 9px; flex-wrap: wrap;
  font-size: 13px; line-height: 1.55; color: rgba(255, 255, 255, .68);
}

@media (max-width: 1080px) {
  /* The leaders stop being readable long before the slabs do, so below this the
     labels stack under the picture rather than crowding it. */
  .buildview .cake-body { grid-template-columns: 1fr; }
  .buildview .lk-label, .buildview .lk-stat {
    position: static; transform: none; text-align: left; padding: 0;
  }
  .buildview .cake-side { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
  .buildview .cake-side.left { margin-bottom: 12px; }
  .buildview .cake-side.right { margin-top: 14px; }
  .buildview .lk-stat { padding: 10px 12px; border: 1px solid var(--hair); border-radius: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .buildview .lk-label, .buildview .lk-stat, .buildview .slab .edge { transition: none; }
}

/* ---- Floor plan lens ------------------------------------------------------
 * The hall as a hall. Rows in pairs across a cold aisle, in-row CDUs, power
 * rooms on the wall, the storage pod with its own positions, and every
 * rectangle a real element with a barcode behind it.
 *
 * Colour is lifecycle state, and there are six of them rather than ten because
 * a floor plan that needs a ten-colour legend is one nobody reads.
 */
.buildview .fp-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 10px; margin: 0 0 12px;
}
.buildview .fp-tabs { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.buildview .fp-tabs .fp-lab {
  font-size: 11px; letter-spacing: .09em; text-transform: uppercase;
  color: rgba(255, 255, 255, .42); margin-right: 4px;
}
.buildview .fp-tabs button {
  padding: 6px 13px; border-radius: 8px; font-size: 13px; cursor: pointer;
  background: var(--glass); border: 1px solid var(--hair); color: rgba(255, 255, 255, .68);
}
.buildview .fp-tabs button:hover { background: var(--glass-2); color: #fff; }
.buildview .fp-tabs button.on {
  background: rgba(63, 189, 240, .16); border-color: rgba(63, 189, 240, .4); color: #fff;
}

.buildview .fp-wrap {
  border-radius: 14px; padding: 10px;
  background:
    radial-gradient(90% 70% at 50% 0%, rgba(63, 189, 240, .06), transparent 60%),
    rgba(255, 255, 255, .022);
  border: 1px solid var(--hair);
}
.buildview .fp-svg { width: 100%; height: auto; display: block; }
.buildview .fp-shell { fill: rgba(255, 255, 255, .015); stroke: rgba(255, 255, 255, .1); stroke-width: 1; }

/* Plant, drawn behind the racks and labelled, because an operator navigates a
   hall by its plant before they navigate it by its racks. */
.buildview .fp-plant rect { fill: rgba(255, 255, 255, .04); stroke: rgba(255, 255, 255, .14); stroke-width: 1; }
.buildview .fp-plant text {
  fill: rgba(255, 255, 255, .5); font-size: 9px; text-anchor: middle;
  font-family: var(--font-body); letter-spacing: .04em;
}
.buildview .fp-plant.k-power rect { fill: rgba(242, 163, 60, .09); stroke: rgba(242, 163, 60, .3); }
.buildview .fp-plant.k-cooling rect { fill: rgba(63, 189, 240, .09); stroke: rgba(63, 189, 240, .32); }
.buildview .fp-plant.k-network rect { fill: rgba(160, 130, 255, .09); stroke: rgba(160, 130, 255, .32); }
.buildview .fp-plant.k-storage rect { fill: rgba(47, 224, 189, .09); stroke: rgba(47, 224, 189, .32); }
.buildview .fp-plant.k-mmr rect { fill: rgba(255, 255, 255, .06); stroke: rgba(255, 255, 255, .24); }

/* Overhead runs, dimmed when a gantry tier filter is on. */
.buildview .fp-run { fill: none; stroke-width: 2; stroke-linecap: round; opacity: .75; }
.buildview .fp-run.k-tray { stroke: rgba(160, 130, 255, .5); stroke-dasharray: 6 4; }
.buildview .fp-run.k-pipe { stroke: rgba(63, 189, 240, .5); }
.buildview .fp-run.k-busway { stroke: rgba(242, 163, 60, .5); stroke-width: 3; }
.buildview .fp-run.k-containment { stroke: rgba(255, 255, 255, .3); stroke-dasharray: 3 3; }
.buildview .fp-run.dim { opacity: .12; }

.buildview .fp-cdu { fill: rgba(63, 189, 240, .35); stroke: rgba(63, 189, 240, .6); stroke-width: .6; }

/* Racks, by lifecycle. Nothing on the floor is a ghost outline, and serving is
   the only state that reads as solid, because it is the only one that pays. */
.buildview .fp-rack { stroke-width: .6; cursor: pointer; transition: fill .15s ease; }
.buildview .fp-rack.s-none { fill: rgba(255, 255, 255, .028); stroke: rgba(255, 255, 255, .1); }
.buildview .fp-rack.s-delivered { fill: rgba(255, 255, 255, .1); stroke: rgba(255, 255, 255, .22); }
.buildview .fp-rack.s-installed { fill: rgba(63, 189, 240, .22); stroke: rgba(63, 189, 240, .4); }
.buildview .fp-rack.s-connected { fill: rgba(63, 189, 240, .45); stroke: rgba(63, 189, 240, .7); }
.buildview .fp-rack.s-ready { fill: rgba(47, 224, 189, .45); stroke: rgba(47, 224, 189, .7); }
.buildview .fp-rack.s-serving { fill: var(--ok); stroke: var(--ok); }
.buildview .fp-rack.held { stroke: var(--bad); stroke-width: 1.1; }
.buildview .fp-rack.on { stroke: #fff; stroke-width: 1.6; }
.buildview .fp-rack:hover { fill: rgba(255, 255, 255, .5); }
.buildview .fp-pod { stroke-dasharray: 2 1.5; }

.buildview .fp-legend {
  display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 12px;
  font-size: 12px; color: rgba(255, 255, 255, .58);
}
.buildview .fpl { display: inline-flex; align-items: center; gap: 7px; }
.buildview .fpl i {
  width: 11px; height: 11px; border-radius: 2px;
  background: rgba(255, 255, 255, .04); border: 1px solid rgba(255, 255, 255, .16);
}
.buildview .fpl.s-delivered i { background: rgba(255, 255, 255, .12); }
.buildview .fpl.s-installed i { background: rgba(63, 189, 240, .28); border-color: rgba(63, 189, 240, .45); }
.buildview .fpl.s-connected i { background: rgba(63, 189, 240, .5); border-color: rgba(63, 189, 240, .75); }
.buildview .fpl.s-ready i { background: rgba(47, 224, 189, .5); border-color: rgba(47, 224, 189, .75); }
.buildview .fpl.s-serving i { background: var(--ok); border-color: var(--ok); }
.buildview .fpl.held i { background: transparent; border-color: var(--bad); border-width: 1.5px; }
.buildview .fpl b { font-variant-numeric: tabular-nums; color: rgba(255, 255, 255, .85); font-weight: 550; }

.buildview .fp-tier {
  margin-top: 12px; padding: 14px 16px; border-radius: 11px;
  background: var(--glass-2); border: 1px solid var(--hair);
}
.buildview .ft-h { display: flex; align-items: baseline; flex-wrap: wrap; gap: 9px; margin-bottom: 7px; }
.buildview .ft-n {
  font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--cyan); padding: 2px 8px; border-radius: 4px; background: rgba(63, 189, 240, .12);
}
.buildview .ft-h b { font-size: 15.5px; }
.buildview .ft-c { font-size: 12px; color: rgba(255, 255, 255, .48); font-variant-numeric: tabular-nums; }

/* ---- The golden thread, reached from a rack ------------------------------- */
.buildview .fp-detail { margin-top: 14px; }
.buildview .fd { padding: 16px 18px; border-radius: 12px; background: var(--glass-2); border: 1px solid var(--hair); }
.buildview .fd-h { display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; }
.buildview .fd-h h3 { margin: 0; font-size: 17px; font-family: var(--font-display); font-weight: 600; }
.buildview .fd-bc {
  font-size: 11.5px; color: rgba(255, 255, 255, .46); font-variant-numeric: tabular-nums;
  padding: 2px 8px; border-radius: 4px; background: rgba(255, 255, 255, .05);
}
.buildview .fd-ord { font-size: 13px; color: rgba(255, 255, 255, .66); }
.buildview .fd-ord.quiet { color: rgba(255, 255, 255, .38); }

.buildview .thread { display: flex; flex-direction: column; margin: 12px 0 8px; }
.buildview .hop { display: flex; gap: 12px; padding-bottom: 12px; position: relative; }
.buildview .hop:not(:last-child)::before {
  content: ''; position: absolute; left: 5px; top: 14px; bottom: 0; width: 1px;
  background: rgba(255, 255, 255, .12);
}
.buildview .hop.done:not(:last-child)::before { background: rgba(47, 224, 189, .35); }
.buildview .hop-dot {
  flex: none; width: 11px; height: 11px; border-radius: 50%; margin-top: 3px; z-index: 1;
  background: var(--navy-2); border: 1.5px solid rgba(255, 255, 255, .22);
}
.buildview .hop.done .hop-dot { background: var(--ok); border-color: var(--ok); }
.buildview .hop-b { min-width: 0; }
.buildview .hop-t { font-size: 13.5px; font-weight: 540; color: rgba(255, 255, 255, .5); }
.buildview .hop.done .hop-t { color: #fff; }
.buildview .hop-m { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 3px; }
.buildview .hop-sys { font-size: 11.5px; color: rgba(255, 255, 255, .48); }
.buildview .hop-at { font-size: 11.5px; color: rgba(255, 255, 255, .6); font-variant-numeric: tabular-nums; }
.buildview .hop-at.quiet { color: rgba(255, 255, 255, .3); }
.buildview .hop-syn {
  font-size: 10.5px; color: rgba(255, 255, 255, .4); padding: 1px 7px;
  border-radius: 999px; border: 1px dashed rgba(255, 255, 255, .2);
}
.buildview .hop-ref { font-size: 11.5px; color: rgba(255, 255, 255, .4); margin-top: 3px; }

/* ---- The clock -------------------------------------------------------------
 * Moving this is not an animation. Every state is derived from dated facts, so
 * the scrubber genuinely re-answers the question at that moment.
 */
.buildview .clock {
  margin: 0 0 18px; padding: 13px 16px 11px; border-radius: 13px;
  background: var(--glass); border: 1px solid var(--hair);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}
.buildview .ck-head { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; margin-bottom: 11px; }
.buildview .ck-play {
  flex: none; width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  display: grid; place-items: center;
  background: rgba(63, 189, 240, .15); border: 1px solid rgba(63, 189, 240, .4);
}
.buildview .ck-play:hover { background: rgba(63, 189, 240, .26); }
.buildview .ck-play.playing { background: rgba(47, 224, 189, .18); border-color: rgba(47, 224, 189, .45); }
.buildview .ck-play svg { width: 14px; height: 14px; fill: #fff; }
.buildview .ck-now .k {
  display: block; font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: rgba(255, 255, 255, .45);
}
.buildview .ck-now b { font-size: 16px; font-variant-numeric: tabular-nums; }
.buildview .ck-read {
  display: flex; flex-wrap: wrap; gap: 6px 18px; margin-left: auto;
  font-size: 12.5px; color: rgba(255, 255, 255, .62);
}
.buildview .ck-read span { display: inline-flex; align-items: center; gap: 7px; font-variant-numeric: tabular-nums; }
.buildview .ck-read i.d { width: 8px; height: 8px; border-radius: 2px; }
.buildview .ck-read i.serving { background: var(--ok); }
.buildview .ck-read i.built { background: rgba(63, 189, 240, .7); }
.buildview .ck-read i.held { background: transparent; border: 1.5px solid var(--bad); }
.buildview .ck-reset {
  padding: 5px 12px; border-radius: 8px; font-size: 12px; cursor: pointer;
  background: var(--glass-2); border: 1px solid var(--hair); color: rgba(255, 255, 255, .68);
}
.buildview .ck-reset:hover { color: #fff; background: rgba(255, 255, 255, .09); }

.buildview .ck-track {
  position: relative; height: 26px; cursor: pointer; touch-action: none;
  display: flex; align-items: center;
}
.buildview .ck-track::before {
  content: ''; position: absolute; left: 0; right: 0; height: 5px; border-radius: 999px;
  background: rgba(255, 255, 255, .08);
}
.buildview .ck-fill {
  position: absolute; left: 0; height: 5px; border-radius: 999px;
  background: linear-gradient(90deg, rgba(63, 189, 240, .5), var(--ok));
}
.buildview .ck-mark {
  position: absolute; width: 2px; height: 13px; border-radius: 1px; margin-left: -1px;
  background: rgba(255, 255, 255, .35);
}
.buildview .ck-mark.good { background: var(--ok); }
.buildview .ck-mark.bad { background: var(--bad); }
.buildview .ck-live {
  position: absolute; width: 1px; height: 22px; margin-left: -.5px;
  background: rgba(255, 255, 255, .5);
}
.buildview .ck-live::after {
  content: 'today'; position: absolute; top: -13px; left: 50%; transform: translateX(-50%);
  font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: rgba(255, 255, 255, .42);
}
.buildview .ck-thumb {
  position: absolute; width: 15px; height: 15px; border-radius: 50%; margin-left: -7.5px;
  background: #fff; box-shadow: 0 0 0 4px rgba(63, 189, 240, .22), 0 2px 8px rgba(0, 0, 0, .5);
  pointer-events: none;
}
.buildview .ck-track:focus-visible { outline: none; }
.buildview .ck-track:focus-visible .ck-thumb { box-shadow: 0 0 0 5px rgba(63, 189, 240, .5); }
.buildview .ck-ends {
  display: flex; justify-content: space-between; gap: 14px; margin-top: 4px;
  font-size: 11px; color: rgba(255, 255, 255, .38);
}
.buildview .ck-note { text-align: center; flex: 1; }
@media (max-width: 720px) { .buildview .ck-note { display: none; } }


/* ---- Row section ----------------------------------------------------------
 * A longitudinal section along a row, to scale. Slab at the bottom, cabinets on
 * it, the four-tier canopy above, cables dropping through with a real bend
 * radius, dimensions down the left in centimetres.
 *
 * This is the drawing a plan cannot be. At 132 kW a rack there is nothing left
 * on the floor, every route is overhead, and the thing you need to see is
 * vertical. Drawing it to scale is also what caught two tiers specified below
 * the top of the cabinet they hang over.
 */
.buildview .sc-wrap {
  border-radius: 14px; padding: 8px 6px;
  background:
    linear-gradient(180deg, rgba(63, 189, 240, .05), transparent 40%),
    rgba(0, 0, 0, .18);
  border: 1px solid var(--hair);
}
.buildview .sc-svg { width: 100%; height: auto; display: block; }

.buildview .sc-ceil { fill: rgba(255, 255, 255, .07); }
.buildview .sc-slab { fill: rgba(255, 255, 255, .09); }
.buildview .sc-ground {
  fill: rgba(255, 255, 255, .34); font-size: 10px; font-family: var(--font-body);
  letter-spacing: .05em;
}
.buildview .sc-hanger { stroke: rgba(255, 255, 255, .14); stroke-width: 1; stroke-dasharray: 3 3; }

/* Dimension lines, drawn like a drawing rather than like a chart. */
.buildview .sc-dim { stroke: rgba(255, 255, 255, .22); stroke-width: .8; stroke-dasharray: 4 3; }
.buildview .sc-dim.strong { stroke: rgba(255, 255, 255, .4); stroke-dasharray: none; }
.buildview .sc-dim-t {
  fill: rgba(255, 255, 255, .62); font-size: 11px; text-anchor: end;
  font-family: var(--font-body); font-variant-numeric: tabular-nums;
}
.buildview .sc-dim-t.r { text-anchor: start; fill: rgba(255, 255, 255, .5); }
.buildview .sc-tier-n {
  fill: rgba(255, 255, 255, .4); font-size: 10px; text-anchor: end; font-family: var(--font-body);
}

/* The four tiers. Colour is function, not decoration: power, fabric, copper,
   fluid, and it is the same colour wherever that tier appears. */
.buildview .sc-tier { cursor: pointer; }
.buildview .sc-tier.dim { opacity: .16; }
.buildview .sc-tray { fill: none; stroke-width: 1.4; }
.buildview .sc-bundle { opacity: .55; }
.buildview .sc-busway { opacity: .8; }
.buildview .sc-pipe-run { opacity: .75; }

.buildview .t-pw .sc-tray, .buildview .t-pw .sc-drop { stroke: var(--warn); }
.buildview .t-pw .sc-busway, .buildview .t-pw .sc-bundle { fill: rgba(242, 163, 60, .55); }
.buildview .t-pw .sc-tier-n, .buildview .t-pw .sc-dim-t { fill: var(--warn); }

.buildview .t-ew .sc-tray, .buildview .t-ew .sc-drop { stroke: var(--cyan); }
.buildview .t-ew .sc-bundle { fill: rgba(63, 189, 240, .5); }
.buildview .t-ew .sc-tier-n, .buildview .t-ew .sc-dim-t { fill: var(--cyan); }

.buildview .t-mg .sc-tray, .buildview .t-mg .sc-drop { stroke: #a082ff; }
.buildview .t-mg .sc-bundle { fill: rgba(160, 130, 255, .5); }
.buildview .t-mg .sc-tier-n, .buildview .t-mg .sc-dim-t { fill: #a082ff; }

.buildview .t-fl .sc-pipe, .buildview .t-fl .sc-pipe-run { fill: rgba(47, 224, 189, .55); }
.buildview .t-fl .sc-pipe-run.r { fill: rgba(47, 224, 189, .3); }
.buildview .t-fl .sc-drop { stroke: var(--ok); }
.buildview .t-fl .sc-tier-n, .buildview .t-fl .sc-dim-t { fill: var(--ok); }

/* Drops. Wide sweep out of the tray and down into the rack top, because fibre
   does not take a ninety degree turn and drawing it as one is how a pathway
   gets planned that cannot physically be built. */
.buildview .sc-drop { fill: none; stroke-width: 1.6; opacity: .7; stroke-linecap: round; }
.buildview .sc-drop.dim { opacity: .08; }

/* Cabinets. */
.buildview .sc-rack { cursor: pointer; }
.buildview .sc-rack .sc-body { fill: rgba(255, 255, 255, .05); stroke: rgba(255, 255, 255, .18); stroke-width: 1; }
.buildview .sc-rack .sc-u line { stroke: rgba(255, 255, 255, .06); stroke-width: .5; }
.buildview .sc-rack .sc-rn {
  fill: rgba(255, 255, 255, .38); font-size: 9.5px; text-anchor: middle;
  font-family: var(--font-body); font-variant-numeric: tabular-nums;
}
.buildview .sc-rack.s-delivered .sc-body { fill: rgba(255, 255, 255, .1); }
.buildview .sc-rack.s-installed .sc-body { fill: rgba(63, 189, 240, .2); stroke: rgba(63, 189, 240, .4); }
.buildview .sc-rack.s-connected .sc-body { fill: rgba(63, 189, 240, .38); stroke: rgba(63, 189, 240, .65); }
.buildview .sc-rack.s-ready .sc-body { fill: rgba(47, 224, 189, .35); stroke: rgba(47, 224, 189, .65); }
.buildview .sc-rack.s-serving .sc-body { fill: rgba(47, 224, 189, .72); stroke: var(--ok); }
.buildview .sc-rack.held .sc-body { stroke: var(--bad); stroke-width: 1.6; }
.buildview .sc-rack.on .sc-body { stroke: #fff; stroke-width: 2; }
.buildview .sc-rack:hover .sc-body { fill: rgba(255, 255, 255, .28); }

.buildview .sc-cdu rect { fill: rgba(63, 189, 240, .16); stroke: rgba(63, 189, 240, .45); stroke-width: 1; }
.buildview .sc-cdu text {
  fill: rgba(63, 189, 240, .8); font-size: 8.5px; text-anchor: middle;
  font-family: var(--font-body); letter-spacing: .06em;
}

/* Tier key, doubling as the tier filter. */
.buildview .sc-key { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.buildview .sck {
  display: flex; align-items: center; gap: 8px; cursor: pointer; text-align: left;
  padding: 8px 12px; border-radius: 10px; flex: 1 1 210px;
  background: var(--glass); border: 1px solid var(--hair); color: rgba(255, 255, 255, .7);
}
.buildview .sck:hover { background: var(--glass-2); }
.buildview .sck.on { border-color: rgba(63, 189, 240, .45); background: rgba(63, 189, 240, .1); }
.buildview .sck i { width: 10px; height: 10px; border-radius: 2px; flex: none; }
.buildview .sck.t-pw i { background: var(--warn); }
.buildview .sck.t-ew i { background: var(--cyan); }
.buildview .sck.t-mg i { background: #a082ff; }
.buildview .sck.t-fl i { background: var(--ok); }
.buildview .sck b { font-size: 12.5px; flex: none; }
.buildview .sck span { font-size: 11.5px; color: rgba(255, 255, 255, .5); flex: 1; min-width: 0; }
.buildview .sck em {
  font-style: normal; font-size: 10px; letter-spacing: .05em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px; flex: none;
}
.buildview .sck em.b-labour { background: var(--bad-soft); color: var(--bad); }
.buildview .sck em.b-supply { background: var(--warn-soft); color: var(--warn); }
.buildview .sck em.b-commissioning { background: rgba(160, 130, 255, .14); color: #a082ff; }
.buildview .sck em.b-none { background: var(--ok-soft); color: var(--ok); }
.buildview .sc-note { margin-top: 10px; }

/* ---- Blast radius banner ---------------------------------------------------
 * What the selected blocker costs, stated once at the top of whatever view you
 * are on, so the answer travels with you.
 */
.buildview .blast {
  margin: 0 0 16px; padding: 13px 16px; border-radius: 12px;
  background: linear-gradient(120deg, rgba(255, 95, 109, .12), rgba(255, 95, 109, .04));
  border: 1px solid rgba(255, 95, 109, .32);
}
.buildview .bl-h { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.buildview .bl-tag {
  font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; font-weight: 600;
  padding: 2px 8px; border-radius: 4px; background: var(--bad-soft); color: var(--bad);
}
.buildview .bl-h b { font-size: 14.5px; }
.buildview .bl-x {
  margin-left: auto; cursor: pointer; font-size: 11.5px; padding: 3px 10px; border-radius: 7px;
  background: rgba(255, 255, 255, .06); border: 1px solid var(--hair); color: rgba(255, 255, 255, .62);
}
.buildview .bl-x:hover { color: #fff; background: rgba(255, 255, 255, .12); }
.buildview .bl-s { margin: 0 0 9px; font-size: 13.5px; line-height: 1.55; }
.buildview .bl-l { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }
.buildview .bll {
  font-size: 11px; padding: 3px 9px; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .12); color: rgba(255, 255, 255, .34);
}
.buildview .bll.blocked { background: var(--bad-soft); color: var(--bad); border-color: rgba(255, 95, 109, .4); }
.buildview .bll.stranded { background: var(--warn-soft); color: var(--warn); border-color: rgba(242, 163, 60, .38); }
.buildview .bl-m { display: flex; flex-wrap: wrap; gap: 4px 18px; font-size: 11.5px; color: rgba(255, 255, 255, .58); }
.buildview .bl-m b { color: rgba(255, 255, 255, .78); font-weight: 550; }

/* ---- The seat question ----------------------------------------------------- */
.buildview .cx-q {
  margin: 0 0 14px; font-size: 14px; color: rgba(255, 255, 255, .55);
  padding-left: 11px; border-left: 2px solid rgba(63, 189, 240, .4);
}

/* ---- Risks, issues and decisions ------------------------------------------- */
.buildview .rks { display: flex; flex-direction: column; gap: 10px; }
.buildview .rk {
  padding: 13px 16px; border-radius: 11px;
  background: var(--glass); border: 1px solid var(--hair);
  border-left: 3px solid rgba(255, 255, 255, .18);
}
.buildview .rk.blocked, .buildview .rk.s-red { border-left-color: var(--bad); }
.buildview .rk.at-risk, .buildview .rk.s-amber { border-left-color: var(--warn); }
.buildview .rk.dec { border-left-color: var(--cyan); }
.buildview .rk.dec.overdue { border-left-color: var(--bad); background: rgba(255, 95, 109, .05); }
.buildview .rk.on { border-color: rgba(63, 189, 240, .45); background: rgba(63, 189, 240, .07); }
.buildview .rk-h { display: flex; align-items: baseline; flex-wrap: wrap; gap: 9px; margin-bottom: 6px; }
.buildview .rk-h b { font-size: 14.5px; font-weight: 550; }
.buildview .rk-id { font-size: 11.5px; color: rgba(255, 255, 255, .45); font-variant-numeric: tabular-nums; }
.buildview .rk-due { margin-left: auto; font-size: 11.5px; color: rgba(255, 255, 255, .5); }
.buildview .rk-due.bad { color: var(--bad); }
.buildview .rk-cost { display: flex; flex-wrap: wrap; gap: 5px 16px; margin: 8px 0 6px; font-size: 12px; color: rgba(255, 255, 255, .58); }
.buildview .rk-cost b { color: rgba(255, 255, 255, .9); font-weight: 600; font-variant-numeric: tabular-nums; }
.buildview .rk-cost .bad b { color: var(--bad); }
.buildview .blk-tag.red { background: var(--bad-soft); color: var(--bad); }
.buildview .blk-tag.amber { background: var(--warn-soft); color: var(--warn); }


/* ---- The layer view, as rows ----------------------------------------------
 * One grid row per layer: identity, plate, numbers. The rows line up because
 * they are grid rows. The previous version drew a single SVG and positioned the
 * labels over it in CSS percentages, which put all seven layers on the same
 * line the moment those columns had no height of their own. Alignment that
 * depends on two coordinate systems agreeing eventually stops agreeing.
 */
.buildview .lay { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }

.buildview .lay-row {
  display: grid;
  grid-template-columns: minmax(180px, 236px) minmax(220px, 1fr) minmax(200px, 268px);
  align-items: center;
  gap: 18px;
  padding: 10px 14px;
  border-radius: 12px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background .16s ease, border-color .16s ease, opacity .16s ease;
}
.buildview .lay-row:hover { background: rgba(255, 255, 255, .04); }
.buildview .lay-row.on {
  background: rgba(63, 189, 240, .09); border-color: rgba(63, 189, 240, .34);
}
.buildview .lay-row.faded { opacity: .3; }
.buildview .lay-row.b-blocked { background: rgba(255, 95, 109, .07); border-color: rgba(255, 95, 109, .3); }
.buildview .lay-row.b-stranded { background: rgba(242, 163, 60, .06); border-color: rgba(242, 163, 60, .28); }
.buildview .lay-row:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

/* ---- Identity ------------------------------------------------------------- */
.buildview .lay-id { display: flex; align-items: center; gap: 12px; min-width: 0; }
.buildview .lay-ic {
  flex: none; width: 38px; height: 38px; display: grid; place-items: center;
  color: rgba(255, 255, 255, .6);
  background: rgba(255, 255, 255, .05);
  border: 1px solid var(--hair);
  /* A hexagon, so the layer icons read as a family rather than as buttons. */
  clip-path: polygon(50% 0, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
}
.buildview .lay-ic svg { width: 18px; height: 18px; }
.buildview .lay-row.rag-green .lay-ic { color: var(--ok); background: rgba(47, 224, 189, .1); }
.buildview .lay-row.rag-amber .lay-ic { color: var(--warn); background: rgba(242, 163, 60, .1); }
.buildview .lay-row.rag-red .lay-ic { color: var(--bad); background: rgba(255, 95, 109, .1); }
.buildview .lay-t { font-size: 15px; font-weight: 570; line-height: 1.25; }
.buildview .lay-s {
  font-size: 11.5px; color: rgba(255, 255, 255, .46); line-height: 1.4; margin-top: 2px;
}

/* ---- The plate ------------------------------------------------------------
 * Each plate is its own SVG, so no geometry is shared between rows and a layer
 * can never be drawn against another layer's numbers.
 */
.buildview .lay-plate { position: relative; display: flex; justify-content: center; }
.buildview .lp { width: 100%; max-width: 300px; height: auto; display: block; overflow: visible; }
.buildview .lp .plate { fill: rgba(255, 255, 255, .04); }
.buildview .lp .side { fill: rgba(255, 255, 255, .06); }
.buildview .lp .side.dark { fill: rgba(0, 0, 0, .3); }
.buildview .lp .edge { fill: none; stroke: rgba(255, 255, 255, .22); stroke-width: 1; }
.buildview .lp .cell { fill: rgba(255, 255, 255, .022); stroke: rgba(255, 255, 255, .05); stroke-width: .4; }

.buildview .rag-green .lp .cell.on { fill: rgba(47, 224, 189, .55); stroke: rgba(47, 224, 189, .8); }
.buildview .rag-amber .lp .cell.on { fill: rgba(242, 163, 60, .55); stroke: rgba(242, 163, 60, .82); }
.buildview .rag-red   .lp .cell.on { fill: rgba(255, 95, 109, .52); stroke: rgba(255, 95, 109, .82); }
.buildview .rag-green .lp .edge { stroke: rgba(47, 224, 189, .55); }
.buildview .rag-amber .lp .edge { stroke: rgba(242, 163, 60, .58); }
.buildview .rag-red   .lp .edge { stroke: rgba(255, 95, 109, .62); }
.buildview .lay-row.on .lp .edge, .buildview .lay-row.b-blocked .lp .edge { stroke-width: 1.8; }

/* The connector between plates: the dependency, drawn. Nothing in a layer works
   until the layer under it does. */
.buildview .lay-link {
  position: absolute; left: 50%; bottom: -10px; width: 1px; height: 16px;
  transform: translateX(-.5px);
  background: rgba(255, 255, 255, .12);
}
.buildview .lay-link.live { background: linear-gradient(180deg, rgba(63, 189, 240, .5), rgba(63, 189, 240, .1)); }

/* ---- The numbers ----------------------------------------------------------- */
.buildview .lay-facts {
  padding: 9px 12px; border-radius: 10px; min-width: 0;
  background: rgba(255, 255, 255, .03); border: 1px solid var(--hair);
}
.buildview .lay-pct {
  font-size: 24px; font-weight: 600; line-height: 1; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; margin-bottom: 5px;
}
.buildview .lay-pct i { font-size: 12px; font-style: normal; color: rgba(255, 255, 255, .42); margin-left: 2px; }
.buildview .rag-green .lay-pct { color: var(--ok); }
.buildview .rag-amber .lay-pct { color: var(--warn); }
.buildview .rag-red   .lay-pct { color: var(--bad); }
.buildview .lay-facts ul { list-style: none; margin: 0; padding: 0; }
.buildview .lay-facts li {
  font-size: 11.5px; line-height: 1.5; color: rgba(255, 255, 255, .5);
  font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.buildview .lay-facts li::before { content: ''; }
.buildview .lay-flag {
  display: inline-block; margin-top: 6px; padding: 2px 9px; border-radius: 999px;
  font-size: 10px; letter-spacing: .06em; text-transform: uppercase; font-weight: 600;
  background: var(--bad-soft); color: var(--bad); border: 1px solid rgba(255, 95, 109, .34);
}
.buildview .lay-flag.stranded {
  background: var(--warn-soft); color: var(--warn); border-color: rgba(242, 163, 60, .34);
}

@media (max-width: 900px) {
  /* Below this the three columns stop fitting. The plate is the first thing to
     go, because the name and the number are what somebody is reading for. */
  .buildview .lay-row { grid-template-columns: 1fr auto; gap: 12px; }
  .buildview .lay-plate { display: none; }
}

/* ---- Width, and why the console overflowed --------------------------------
 * Two separate faults, both of which showed up as the blockers panel sitting on
 * top of the shipment cards.
 *
 * One: the site wraps every page at 1280px. That is right for a document and
 * wrong for a console, which was using two thirds of a wide screen and leaving
 * dead space either side.
 *
 * Two, and the real one: the grids inside the main pane sized themselves with
 * viewport media queries. On a 2000px screen the three-column rule fired even
 * though the pane it was in was 700px wide, so the content was laid out for a
 * window it was not in and ran underneath the panel next to it. Container
 * queries fix that properly: the grid responds to the box it is in, which is
 * the only thing it can actually see.
 */
/* body. wins the specificity tie with .buildpage main .wrap, which caps every
   page at 1280px. That is right for a document and wrong for a console: on a
   wide screen it was using little more than half the glass and leaving dead
   space either side. */
body.consolepage main .wrap { max-width: none; padding: 0 16px; }
body.consolepage .cx-below { max-width: 74ch; margin: 0 auto; padding: 30px 0 40px; }

/* The site draws a fixed diagonal flow-line backdrop behind every page. The
   console's surfaces were nearly transparent, so it showed straight through
   them and read as lines drawn over the content. A tool is not a translucent
   card floating on a marketing page: it gets its own opaque ground, and the
   frosted-glass effect happens against that rather than against the website. */
body.consolepage .cx {
  background:
    radial-gradient(120% 90% at 18% 0%, rgba(63, 189, 240, .07), transparent 58%),
    linear-gradient(180deg, #0d1e31, #0a1725);
  isolation: isolate;
}
body.consolepage .cx-main,
body.consolepage .cx-top { background-color: rgba(10, 23, 37, .82); }
body.consolepage .cx-rail,
body.consolepage .cx-aside { background-color: rgba(7, 17, 28, .92); }
body.consolepage .cx-clock { background-color: rgba(6, 15, 25, .95); }

.cx-main { container-type: inline-size; container-name: pane; }

/* Neutralise the viewport-driven column counts inside the pane, then restate
   them against the pane's own width. */
.cx-main .shipgrid,
.cx-main .subsys-grid,
.cx-main .tiles,
.cx-main .spare,
.cx-main .digest-grid { grid-template-columns: minmax(0, 1fr); }

@container pane (min-width: 560px) {
  .cx-main .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cx-main .shipgrid,
  .cx-main .subsys-grid,
  .cx-main .spare,
  .cx-main .digest-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container pane (min-width: 920px) {
  .cx-main .tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .cx-main .shipgrid,
  .cx-main .subsys-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Nothing inside the pane may set its own width past the pane. A single wide
   table or SVG was enough to push the whole column under the aside. */
.cx-main > * { min-width: 0; }
.cx-main table { max-width: 100%; }
.cx-main .panel, .cx-main .prow, .cx-main .rk { min-width: 0; }

/* Wide content scrolls inside itself rather than widening the page. */
.cx-main .btab { display: block; overflow-x: auto; }

/* ---- Collapsing the blockers panel ----------------------------------------
 * The panel earns its place most of the time and gets in the way when you are
 * reading something wide. Collapsed it keeps its count, so you can still see
 * that there are seven things wrong without giving up the width.
 */
.cx { transition: grid-template-columns .18s ease; }
.cx.aside-shut { grid-template-columns: 216px minmax(0, 1fr) 44px; }
.cx.rail-shut { grid-template-columns: 52px minmax(0, 1fr) 344px; }
.cx.rail-shut.aside-shut { grid-template-columns: 52px minmax(0, 1fr) 44px; }

.ax-head {
  display: flex; align-items: center; gap: 8px; margin-bottom: 4px;
}
.ax-head h3 { margin: 0; }
.ax-toggle {
  margin-left: auto; flex: none; cursor: pointer;
  width: 26px; height: 26px; border-radius: 7px; display: grid; place-items: center;
  background: rgba(255, 255, 255, .05); border: 1px solid var(--hair);
  color: rgba(255, 255, 255, .6);
}
.ax-toggle:hover { color: #fff; background: rgba(255, 255, 255, .11); }
.ax-toggle svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; }

.cx.aside-shut .cx-aside { padding: 12px 0; overflow: hidden; }
.cx.aside-shut .cx-aside .ax-group,
.cx.aside-shut .cx-aside .ax-sub,
.cx.aside-shut .cx-aside h3 { display: none; }
.cx.aside-shut .ax-shut { display: flex; }
.ax-shut { display: none; flex-direction: column; align-items: center; gap: 10px; }
.ax-shut button {
  cursor: pointer; width: 28px; height: 28px; border-radius: 7px; display: grid; place-items: center;
  background: rgba(255, 255, 255, .05); border: 1px solid var(--hair); color: rgba(255, 255, 255, .6);
}
.ax-shut button:hover { color: #fff; background: rgba(255, 255, 255, .11); }
.ax-shut button svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; }
.ax-shut .ax-n {
  font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums;
  padding: 2px 6px; border-radius: 999px; background: var(--bad-soft); color: var(--bad);
}
.ax-shut .ax-v {
  writing-mode: vertical-rl; text-orientation: mixed;
  font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  color: rgba(255, 255, 255, .4);
}

/* The rail collapses the same way, to icons only. */
.cx.rail-shut .cx-rail { padding: 12px 6px; }
.cx.rail-shut .cx-rail .rg { display: none; }
.cx.rail-shut .cx-rail button { justify-content: center; padding: 9px 0; gap: 0; font-size: 0; }
.cx.rail-shut .cx-rail button .ri { width: 18px; height: 18px; }
.cx.rail-shut .cx-rail button .rc { display: none; }

.cx-railfoot { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--hair); }
.cx-railfoot button {
  width: 100%; display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 8px 11px; border-radius: 9px; font-size: 12.5px;
  background: transparent; border: 1px solid transparent; color: rgba(255, 255, 255, .45);
}
.cx-railfoot button:hover { background: rgba(255, 255, 255, .05); color: #fff; }
.cx-railfoot button .ri svg { fill: none; stroke: currentColor; stroke-width: 1.8; }

@media (max-width: 1100px) {
  /* Collapsing is meaningless once the console has already stacked. */
  .cx.aside-shut, .cx.rail-shut, .cx.rail-shut.aside-shut { grid-template-columns: minmax(0, 1fr); }
  .cx.aside-shut .cx-aside .ax-group,
  .cx.aside-shut .cx-aside .ax-sub,
  .cx.aside-shut .cx-aside h3 { display: revert; }
  .ax-shut { display: none !important; }
  .cx.rail-shut .cx-rail button { font-size: 13.5px; gap: 10px; padding: 9px 11px; }
}

/* ---- Compliance ------------------------------------------------------------ */
.buildview .cmps { display: flex; flex-direction: column; gap: 10px; }
.buildview .cmp {
  padding: 13px 16px; border-radius: 11px;
  background: var(--glass); border: 1px solid var(--hair);
  border-left: 3px solid rgba(255, 255, 255, .16);
}
.buildview .cmp.open { border-left-color: var(--warn); }
.buildview .cmp.gating { border-left-color: var(--bad); }
.buildview .cmp.overdue { background: rgba(255, 95, 109, .05); border-left-color: var(--bad); }
.buildview .cmp.done { border-left-color: var(--ok); opacity: .72; }
.buildview .cmp-h { display: flex; align-items: baseline; flex-wrap: wrap; gap: 9px; margin-bottom: 6px; }
.buildview .cmp-h b { font-size: 14.5px; font-weight: 550; }
.buildview .cmp-k {
  font-size: 9.5px; letter-spacing: .09em; text-transform: uppercase; font-weight: 600;
  padding: 2px 8px; border-radius: 4px;
}
.buildview .cmp-k.k-regulatory { background: rgba(255, 95, 109, .14); color: var(--bad); }
.buildview .cmp-k.k-contractual { background: rgba(242, 163, 60, .14); color: var(--warn); }
.buildview .cmp-k.k-assurance { background: rgba(63, 189, 240, .14); color: var(--cyan); }
.buildview .cmp-e { margin: 6px 0 0; font-size: 12px; color: rgba(255, 255, 255, .48); }
.buildview .cmp-e b { color: rgba(255, 255, 255, .66); font-weight: 550; }
.buildview .cmp-holds {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 9px; margin: 9px 0 4px;
  padding-top: 8px; border-top: 1px solid var(--hair);
}
.buildview .cmp-holds .k {
  font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: rgba(255, 255, 255, .42);
}
.buildview .cmp-holds.none .k { color: rgba(255, 255, 255, .3); }
.buildview .cmp-b {
  font-size: 11.5px; padding: 2px 9px; border-radius: 999px;
  background: rgba(255, 255, 255, .05); border: 1px solid var(--hair);
  color: rgba(255, 255, 255, .68);
}
.buildview .cmp-mw {
  font-size: 11.5px; font-weight: 600; color: var(--bad);
  padding: 2px 9px; border-radius: 999px; background: var(--bad-soft);
}
.buildview .cmp-auth { font-size: 11.5px; color: rgba(255, 255, 255, .45); }

/* ---- Marginal impact ------------------------------------------------------
 * The number that stops every blocker looking identical. Most items behind a
 * single binding constraint save nothing on their own, and saying so is more
 * useful than repeating the hall's exposure on every card.
 */
.buildview .blk-cost .bind b, .buildview .rk-cost .bad b { color: var(--bad); }
.buildview .blk-cost .slack, .buildview .rk-cost .slack {
  color: rgba(255, 255, 255, .38); font-style: italic;
}

/* ---- Stage panel ----------------------------------------------------------- */
.buildview .rb-step[data-stage] { cursor: pointer; }
.buildview .rb-step.sel {
  box-shadow: inset 0 0 0 1.5px rgba(63, 189, 240, .6), 0 0 20px rgba(63, 189, 240, .18);
}
.buildview .rb-step:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
.buildview .stagep {
  margin: 0 0 16px; padding: 13px 16px; border-radius: 12px;
  background: linear-gradient(120deg, rgba(63, 189, 240, .1), rgba(63, 189, 240, .03));
  border: 1px solid rgba(63, 189, 240, .3);
}
.buildview .bl-tag.st { background: rgba(63, 189, 240, .16); color: var(--cyan); }
.buildview .stg-sub { font-size: 12.5px; color: rgba(255, 255, 255, .5); }
.buildview .stg-n { display: flex; flex-wrap: wrap; gap: 10px 28px; margin: 10px 0 4px; }
.buildview .stg-n .k {
  display: block; font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: rgba(255, 255, 255, .42);
}
.buildview .stg-n b { font-size: 22px; font-variant-numeric: tabular-nums; }
.buildview .stg-n b.sm { font-size: 14px; font-weight: 550; }
.buildview .stg-n em {
  display: block; font-style: normal; font-size: 11px; color: rgba(255, 255, 255, .44);
}

/* ---- The seat as a lens ----------------------------------------------------
 * Same racks, same positions, same computed state underneath. What changes is
 * the question being asked of them, so the colours change with the seat and the
 * legend says which question it is. One picture, six questions, and everybody
 * arguing about the same rack.
 */
.buildview .fp-lenshead {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 12px; margin-top: 12px;
}
.buildview .fp-lenshead b { font-size: 13px; font-weight: 560; }
.buildview .fp-lenshead span { font-size: 12px; color: rgba(255, 255, 255, .48); }

/* Commercial: what is sold, what is earning, what is standing idle. */
.buildview .fp-rack.s-earning,    .buildview .sc-rack.s-earning .sc-body { fill: var(--ok); stroke: var(--ok); }
.buildview .fp-rack.s-idle,       .buildview .sc-rack.s-idle .sc-body { fill: rgba(255, 95, 109, .5); stroke: var(--bad); }
.buildview .fp-rack.s-committed,  .buildview .sc-rack.s-committed .sc-body { fill: rgba(63, 189, 240, .3); stroke: rgba(63, 189, 240, .55); }
.buildview .fp-rack.s-sellable,   .buildview .sc-rack.s-sellable .sc-body { fill: rgba(47, 224, 189, .35); stroke: rgba(47, 224, 189, .7); }
.buildview .fp-rack.s-floorspace, .buildview .sc-rack.s-floorspace .sc-body { fill: rgba(255, 255, 255, .03); stroke: rgba(255, 255, 255, .1); }

/* Operations: what could be accepted today. */
.buildview .fp-rack.s-accepted,  .buildview .sc-rack.s-accepted .sc-body { fill: var(--ok); stroke: var(--ok); }
.buildview .fp-rack.s-ready,     .buildview .sc-rack.s-ready .sc-body { fill: rgba(242, 163, 60, .5); stroke: var(--warn); }
.buildview .fp-rack.s-building,  .buildview .sc-rack.s-building .sc-body { fill: rgba(63, 189, 240, .26); stroke: rgba(63, 189, 240, .5); }
.buildview .fp-rack.s-nothing,   .buildview .sc-rack.s-nothing .sc-body { fill: rgba(255, 255, 255, .03); stroke: rgba(255, 255, 255, .1); }

/* Design: which racks sit behind an uncleared control. */
.buildview .fp-rack.s-blocked, .buildview .sc-rack.s-blocked .sc-body { fill: rgba(255, 95, 109, .5); stroke: var(--bad); }
.buildview .fp-rack.s-open,    .buildview .sc-rack.s-open .sc-body { fill: rgba(242, 163, 60, .42); stroke: var(--warn); }
.buildview .fp-rack.s-clear,   .buildview .sc-rack.s-clear .sc-body { fill: rgba(47, 224, 189, .32); stroke: rgba(47, 224, 189, .6); }

/* Programme: float. */
.buildview .fp-rack.s-critical, .buildview .sc-rack.s-critical .sc-body { fill: rgba(255, 95, 109, .48); stroke: var(--bad); }
.buildview .fp-rack.s-tight,    .buildview .sc-rack.s-tight .sc-body { fill: rgba(242, 163, 60, .44); stroke: var(--warn); }
.buildview .fp-rack.s-ok,       .buildview .sc-rack.s-ok .sc-body { fill: rgba(47, 224, 189, .34); stroke: rgba(47, 224, 189, .62); }

/* GRC: outstanding evidence. */
.buildview .fp-rack.s-held,    .buildview .sc-rack.s-held .sc-body { fill: rgba(255, 95, 109, .5); stroke: var(--bad); }
.buildview .fp-rack.s-partial, .buildview .sc-rack.s-partial .sc-body { fill: rgba(242, 163, 60, .42); stroke: var(--warn); }

/* Legend swatches follow the same buckets. */
.buildview .fpl.b-earning i, .buildview .fpl.b-accepted i { background: var(--ok); border-color: var(--ok); }
.buildview .fpl.b-idle i, .buildview .fpl.b-blocked i,
.buildview .fpl.b-critical i, .buildview .fpl.b-held i {
  background: rgba(255, 95, 109, .5); border-color: var(--bad);
}
.buildview .fpl.b-ready i, .buildview .fpl.b-open i,
.buildview .fpl.b-tight i, .buildview .fpl.b-partial i {
  background: rgba(242, 163, 60, .48); border-color: var(--warn);
}
.buildview .fpl.b-committed i, .buildview .fpl.b-building i {
  background: rgba(63, 189, 240, .3); border-color: rgba(63, 189, 240, .55);
}
.buildview .fpl.b-sellable i, .buildview .fpl.b-clear i, .buildview .fpl.b-ok i {
  background: rgba(47, 224, 189, .35); border-color: rgba(47, 224, 189, .7);
}
.buildview .fpl.b-floorspace i, .buildview .fpl.b-nothing i {
  background: rgba(255, 255, 255, .04); border-color: rgba(255, 255, 255, .16);
}

/* ---- Blockers, grouped by who can act ------------------------------------- */
.ax-sub-g {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px;
  margin: 14px 0 7px; padding-top: 10px; border-top: 1px solid var(--hair);
}
.ax-sub-g:first-child { margin-top: 4px; padding-top: 0; border-top: none; }
.ax-gt {
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase; font-weight: 600;
  color: rgba(255, 255, 255, .62);
}
.ax-sub-g.mine .ax-gt { color: var(--cyan); }
.ax-sub-g.other .ax-gt { color: rgba(255, 255, 255, .38); }
.ax-gt b {
  margin-left: 6px; font-weight: 600; padding: 1px 6px; border-radius: 999px;
  background: rgba(255, 255, 255, .08); color: rgba(255, 255, 255, .7);
}
.ax-sub-g.mine .ax-gt b { background: rgba(63, 189, 240, .18); color: var(--cyan); }
.ax-gn { flex-basis: 100%; font-size: 11px; color: rgba(255, 255, 255, .36); line-height: 1.45; }
/* Blockers owned elsewhere are de-emphasised by their ground, not by fading the
   words on them. Whole-card opacity took the description line down with it, so
   the cards a reader most needs to skim were the hardest to read. Owned
   elsewhere is a fact about who moves it, not a reason to make it hard to read.
   The left edge is deliberately untouched: it still carries blocked against at
   risk, which matters whoever owns it. Hover and selected are restated because
   this compound selector outweighs them. */
.ax-sub-g.other ~ .blk { background: rgba(255, 255, 255, .015); }
.ax-sub-g.other ~ .blk:hover { background: rgba(255, 255, 255, .06); }
.ax-sub-g.other ~ .blk.on { background: rgba(63, 189, 240, .09); }

.buildview .fp-tabs button.alt {
  font-size: 12px; color: rgba(255, 255, 255, .52);
  background: transparent; border-style: dashed;
}
.buildview .fp-tabs button.alt:hover { color: #fff; border-style: solid; }
.buildview .fp-rack.s-unsold, .buildview .sc-rack.s-unsold .sc-body {
  fill: rgba(255, 255, 255, .1); stroke: rgba(255, 255, 255, .22);
}
.buildview .fpl.b-unsold i { background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .26); }

/* ---- The walkthrough -------------------------------------------------------
 * Scripted sequences for driving this in front of somebody. Sits above the
 * view, because at a stand the narration is what somebody reads off the screen
 * while talking, and it has to be findable without hunting.
 *
 * Reset is always visible. A stand demo gets run twenty times in a day and the
 * twentieth has to look like the first.
 */
.buildview .beats {
  margin: 0 0 16px; padding: 13px 16px; border-radius: 12px;
  background: rgba(255, 255, 255, .028); border: 1px solid var(--hair);
}
.buildview .beats.on {
  background: linear-gradient(120deg, rgba(63, 189, 240, .12), rgba(63, 189, 240, .03));
  border-color: rgba(63, 189, 240, .34);
}
.buildview .bt-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px; }
.buildview .bt-k {
  font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; font-weight: 600;
  color: var(--cyan);
}
.buildview .beats.on .bt-k { font-size: 14.5px; letter-spacing: 0; text-transform: none; color: #fff; }
.buildview .bt-n { font-size: 12px; color: rgba(255, 255, 255, .5); flex: 1; min-width: 220px; }
.buildview .bt-pos {
  font-size: 11.5px; color: rgba(255, 255, 255, .5); font-variant-numeric: tabular-nums;
  padding: 2px 9px; border-radius: 999px; background: rgba(255, 255, 255, .07);
}
.buildview .bt-x {
  margin-left: auto; cursor: pointer; font-size: 11.5px; padding: 3px 10px; border-radius: 7px;
  background: rgba(255, 255, 255, .06); border: 1px solid var(--hair); color: rgba(255, 255, 255, .62);
}
.buildview .bt-x:hover { color: #fff; background: rgba(255, 255, 255, .12); }

.buildview .bt-list {
  display: grid; gap: 8px; margin-top: 11px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.buildview .bt-pick {
  display: block; text-align: left; cursor: pointer; padding: 11px 13px; border-radius: 10px;
  background: rgba(255, 255, 255, .035); border: 1px solid var(--hair); color: inherit;
}
.buildview .bt-pick:hover { background: rgba(63, 189, 240, .1); border-color: rgba(63, 189, 240, .34); }
.buildview .bt-pick b { display: block; font-size: 13.5px; font-weight: 560; margin-bottom: 4px; }
.buildview .bt-pick span {
  display: block; font-size: 11.5px; line-height: 1.5; color: rgba(255, 255, 255, .48);
}

/* The line somebody reads out loud. Sized to be legible from a step back, which
   is where the person being shown it is standing. */
.buildview .bt-say {
  margin: 12px 0 8px; font-size: 16.5px; line-height: 1.55; font-weight: 450;
  max-width: 68ch;
}
.buildview .bt-watch {
  margin: 0 0 12px; font-size: 13px; line-height: 1.55; color: rgba(255, 255, 255, .62);
  max-width: 68ch; padding-left: 11px; border-left: 2px solid rgba(63, 189, 240, .45);
}
.buildview .bt-watch b { color: var(--cyan); font-weight: 600; }

.buildview .bt-ctl { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.buildview .bt-b {
  cursor: pointer; font-size: 13px; padding: 7px 15px; border-radius: 8px;
  background: rgba(255, 255, 255, .06); border: 1px solid var(--hair); color: rgba(255, 255, 255, .78);
}
.buildview .bt-b:hover:not([disabled]) { background: rgba(255, 255, 255, .12); color: #fff; }
.buildview .bt-b[disabled] { opacity: .35; cursor: default; }
.buildview .bt-b.primary {
  background: rgba(63, 189, 240, .2); border-color: rgba(63, 189, 240, .5); color: #fff; font-weight: 550;
}
.buildview .bt-b.primary:hover { background: rgba(63, 189, 240, .32); }
.buildview .bt-dots { display: flex; gap: 5px; margin-left: auto; }
.buildview .bt-dots i {
  width: 7px; height: 7px; border-radius: 50%; background: rgba(255, 255, 255, .16);
}
.buildview .bt-dots i.on { background: var(--cyan); }

/* ---- The other parties -----------------------------------------------------
 * A party sits on the same bar as an internal seat, because the claim is one
 * team and a party that has to be sent a report is not on the team. Marked as
 * external so nobody mistakes whose organisation they are in, not so they can
 * be given a lesser view.
 */
.cx-div {
  flex: none; width: 1px; height: 22px; margin: 0 6px;
  background: rgba(255, 255, 255, .16);
}
.cx-seats button.ext { color: rgba(255, 255, 255, .52); }
.cx-seats button.ext .sq { color: rgba(255, 255, 255, .3); }
.cx-seats button.ext:hover { color: #fff; }
.cx-seats button.ext.on {
  color: #fff; background: rgba(160, 130, 255, .16); border-color: rgba(160, 130, 255, .4);
}
.cx-seats button.ext.on .sq { color: rgba(160, 130, 255, .9); }

.buildview .party {
  padding: 15px 18px; border-radius: 12px; margin-bottom: 4px;
  background: linear-gradient(120deg, rgba(160, 130, 255, .12), rgba(160, 130, 255, .03));
  border: 1px solid rgba(160, 130, 255, .3);
}
.buildview .pty-tag {
  font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; font-weight: 600;
  padding: 2px 8px; border-radius: 4px; background: rgba(160, 130, 255, .18); color: #c3b0ff;
}
.buildview .pty-h h2 {
  font-family: var(--font-display); font-size: 20px; margin: 8px 0 4px; font-weight: 600;
}
.buildview .pty-q { margin: 0; font-size: 14.5px; color: rgba(255, 255, 255, .72); }

.buildview .pty-grid {
  display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
.buildview .pty-col {
  padding: 14px 16px; border-radius: 11px;
  background: var(--glass); border: 1px solid var(--hair);
}
.buildview .pty-col.waiting { border-color: rgba(242, 163, 60, .3); background: rgba(242, 163, 60, .05); }
.buildview .pty-col h3 {
  margin: 0 0 9px; font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  color: rgba(255, 255, 255, .5); font-weight: 500;
}
.buildview .pty-col.waiting h3 { color: var(--warn); }
.buildview .pty-l { list-style: none; margin: 0; padding: 0; }
.buildview .pty-l li {
  font-size: 13.5px; line-height: 1.55; padding: 5px 0 5px 15px; position: relative;
  color: rgba(255, 255, 255, .78);
}
.buildview .pty-l li::before {
  content: ''; position: absolute; left: 0; top: 12px;
  width: 5px; height: 5px; border-radius: 50%; background: rgba(255, 255, 255, .3);
}
.buildview .pty-col.waiting .pty-l li::before { background: var(--warn); }
.buildview .pty-n {
  margin: 10px 0 0; font-size: 12px; line-height: 1.55; color: rgba(255, 255, 255, .5);
  padding-top: 9px; border-top: 1px solid var(--hair);
}

.buildview .pty-dates { display: grid; gap: 9px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.buildview .ptd {
  padding: 12px 14px; border-radius: 10px;
  background: var(--glass); border: 1px solid var(--hair);
  border-left: 3px solid rgba(255, 255, 255, .2);
}
.buildview .ptd.rag-green { border-left-color: var(--ok); }
.buildview .ptd.rag-amber { border-left-color: var(--warn); }
.buildview .ptd.rag-red { border-left-color: var(--bad); }
.buildview .ptd-t { font-size: 13.5px; line-height: 1.4; margin-bottom: 6px; }
.buildview .ptd-m { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.buildview .ptd-m b { font-size: 15px; font-variant-numeric: tabular-nums; }
.buildview .ptd-m span { font-size: 11.5px; color: rgba(255, 255, 255, .5); }

/* ---- Upside ----------------------------------------------------------------
 * The console spent a long time only able to report bad news. Green here is
 * used deliberately and only here: this is the one view where a number going up
 * is good.
 */
.buildview .ups { display: flex; flex-direction: column; gap: 10px; }
.buildview .up {
  padding: 13px 16px; border-radius: 11px;
  background: var(--glass); border: 1px solid var(--hair);
  border-left: 3px solid var(--ok);
}
.buildview .up.k-method { border-left-color: var(--cyan); }
.buildview .up.k-crew { border-left-color: #a082ff; }
.buildview .up-h { display: flex; align-items: baseline; flex-wrap: wrap; gap: 9px; margin-bottom: 8px; }
.buildview .up-move {
  font-size: 9.5px; letter-spacing: .09em; text-transform: uppercase; font-weight: 600;
  padding: 2px 8px; border-radius: 4px; background: var(--ok-soft); color: var(--ok);
}
.buildview .up.k-method .up-move { background: rgba(63, 189, 240, .14); color: var(--cyan); }
.buildview .up.k-crew .up-move { background: rgba(160, 130, 255, .14); color: #a082ff; }
.buildview .up-h b { font-size: 14.5px; font-weight: 550; }
.buildview .up-v { display: flex; flex-wrap: wrap; gap: 6px 22px; margin-bottom: 7px; }
.buildview .up-v span {
  font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, .82);
}
.buildview .up-v span.big { font-size: 22px; color: var(--ok); }
.buildview .up.k-method .up-v span.big { color: var(--cyan); }
.buildview .up.k-crew .up-v span.big { color: #a082ff; }
.buildview .up-v i {
  display: block; font-style: normal; font-size: 10.5px; font-weight: 400;
  letter-spacing: .05em; text-transform: uppercase; color: rgba(255, 255, 255, .42);
}

/* ---- What unlocks, and when ------------------------------------------------ */
.buildview .rel { display: flex; flex-direction: column; gap: 9px; }
.buildview .rw {
  display: grid; grid-template-columns: 108px 84px minmax(0, 1fr); gap: 14px; align-items: start;
  padding: 13px 16px; border-radius: 11px;
  background: var(--glass); border: 1px solid var(--hair);
  border-left: 3px solid rgba(255, 255, 255, .2);
}
.buildview .rw.s-available { border-left-color: var(--ok); }
.buildview .rw.s-held { border-left-color: var(--bad); }
.buildview .rw.s-buildable { border-left-color: rgba(63, 189, 240, .6); }
.buildview .rw-when { font-size: 13px; font-weight: 550; font-variant-numeric: tabular-nums; }
.buildview .rw-mw {
  font-size: 24px; font-weight: 600; line-height: 1; font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}
.buildview .rw.s-available .rw-mw { color: var(--ok); }
.buildview .rw.s-held .rw-mw { color: var(--bad); }
.buildview .rw-mw i {
  font-style: normal; font-size: 11px; font-weight: 400; margin-left: 3px;
  color: rgba(255, 255, 255, .45);
}
.buildview .rw-t { font-size: 14px; font-weight: 550; margin-bottom: 3px; }
.buildview .rw-s {
  margin-left: 8px; font-size: 10px; letter-spacing: .07em; text-transform: uppercase;
  font-weight: 500; padding: 2px 7px; border-radius: 999px;
  background: rgba(255, 255, 255, .07); color: rgba(255, 255, 255, .55);
}
.buildview .rw-g {
  margin-top: 6px; font-size: 11.5px; color: var(--warn);
  padding: 2px 9px; border-radius: 999px; background: var(--warn-soft); display: inline-block;
}
@media (max-width: 760px) {
  .buildview .rw { grid-template-columns: 1fr; gap: 6px; }
}

/* ---- The blast radius, in the view you are looking at ----------------------
 * Selecting a blocker is supposed to change what you are looking at, not just
 * add a banner above it. On the floor and the section it is the racks it
 * reaches. On the pipeline it is the orders. Untouched things dim rather than
 * disappear, because "this does not affect these forty racks" is information
 * too, and hiding them would misrepresent the size of the hall.
 */
.buildview .fp-rack.bl-out,
.buildview .sc-rack.bl-out .sc-body { opacity: .16; }
.buildview .sc-rack.bl-out .sc-u,
.buildview .sc-rack.bl-out .sc-rn { opacity: .16; }

/* Stranded: finished and cannot be accepted. Outlined rather than filled,
   because the work is done and drawing it as unbuilt would be a lie. */
.buildview .fp-rack.bl-stranded {
  stroke: var(--warn); stroke-width: 1.4; stroke-dasharray: 2 1.4;
}
.buildview .sc-rack.bl-stranded .sc-body {
  stroke: var(--warn); stroke-width: 1.8; stroke-dasharray: 3 2;
}

/* Blocked: cannot proceed. Solid edge, because this is work that is stopped. */
.buildview .fp-rack.bl-blocked { stroke: var(--bad); stroke-width: 1.2; }
.buildview .sc-rack.bl-blocked .sc-body { stroke: var(--bad); stroke-width: 1.6; }

/* Dimming with no explanation reads as a rendering fault. */
.buildview .bl-key {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px;
  margin-top: 10px; padding: 9px 13px; border-radius: 10px;
  background: rgba(255, 95, 109, .07); border: 1px solid rgba(255, 95, 109, .26);
  font-size: 12px; color: rgba(255, 255, 255, .6);
}
.buildview .bl-kt { font-weight: 560; color: #fff; }
.buildview .blk-s { display: inline-flex; align-items: center; gap: 7px; }
.buildview .blk-s i { width: 11px; height: 11px; border-radius: 2px; background: transparent; }
.buildview .blk-s.stranded i { border: 1.5px dashed var(--warn); }
.buildview .blk-s.blocked i { border: 1.5px solid var(--bad); }
.buildview .blk-s.out i { border: 1px solid rgba(255, 255, 255, .16); opacity: .4; }
.buildview .blk-s b {
  font-variant-numeric: tabular-nums; color: rgba(255, 255, 255, .88); font-weight: 600;
}

/* Pipeline rows and compliance items answer the same question. */
.buildview .prow.bl-out,
.buildview .cmp.bl-out { opacity: .3; }
.buildview .prow.bl-hit { border-color: rgba(255, 95, 109, .45); }
.buildview .cmp.bl-hit { border-color: rgba(255, 95, 109, .45); background: rgba(255, 95, 109, .06); }
.buildview .prow-blast {
  display: inline-block; margin-bottom: 8px; padding: 2px 9px; border-radius: 999px;
  font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase; font-weight: 600;
  background: var(--bad-soft); color: var(--bad); border: 1px solid rgba(255, 95, 109, .34);
}

/* ---- The way in ------------------------------------------------------------
 * Somebody arrives cold with nobody next to them to explain it. Four panels,
 * then they drive. It sits in the main pane rather than over the whole console
 * on purpose: the thing behind it is already rendered and working, and a modal
 * that blacks out the product implies the product cannot speak for itself.
 */
.buildview .intro-wrap { margin: 0 0 18px; }
.buildview .intro {
  padding: 22px 26px 20px; border-radius: 14px;
  background:
    radial-gradient(120% 100% at 12% 0%, rgba(63, 189, 240, .16), transparent 62%),
    rgba(10, 23, 37, .96);
  border: 1px solid rgba(63, 189, 240, .34);
  box-shadow: 0 18px 50px rgba(0, 0, 0, .4);
}
.buildview .in-h { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.buildview .in-k {
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; font-weight: 600;
  color: var(--cyan); padding: 3px 10px; border-radius: 999px; background: rgba(63, 189, 240, .12);
}
.buildview .in-c { font-size: 11.5px; color: rgba(255, 255, 255, .42); font-variant-numeric: tabular-nums; }
.buildview .in-x {
  margin-left: auto; cursor: pointer; font-size: 12px; padding: 4px 11px; border-radius: 7px;
  background: rgba(255, 255, 255, .06); border: 1px solid var(--hair); color: rgba(255, 255, 255, .6);
}
.buildview .in-x:hover { color: #fff; background: rgba(255, 255, 255, .13); }
.buildview .intro h2 {
  font-family: var(--font-display); font-size: 25px; line-height: 1.25; margin: 0 0 12px;
  font-weight: 600; max-width: 24ch;
}
.buildview .in-p { margin: 0 0 10px; font-size: 15.5px; line-height: 1.6; max-width: 68ch; color: rgba(255, 255, 255, .82); }
.buildview .in-f {
  margin: 0 0 16px; font-size: 14px; line-height: 1.6; max-width: 66ch;
  color: var(--cyan); padding-left: 12px; border-left: 2px solid rgba(63, 189, 240, .45);
}
.buildview .in-ctl { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.buildview .in-ill {
  margin: 15px 0 0; padding-top: 12px; border-top: 1px solid var(--hair);
  font-size: 11.5px; line-height: 1.55; color: rgba(255, 255, 255, .42); max-width: 76ch;
}

/* Per seat, because "what is this" has a different answer depending on why you
   are looking. Goes away once seen, and does not come back. */
.buildview .seathint {
  margin: 0 0 14px; padding: 12px 15px; border-radius: 11px;
  background: rgba(63, 189, 240, .08); border: 1px solid rgba(63, 189, 240, .28);
}
.buildview .sh-h { display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px; margin-bottom: 5px; }
.buildview .sh-k {
  font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; font-weight: 600;
  color: var(--cyan);
}
.buildview .sh-h b { font-size: 14.5px; font-weight: 560; }
.buildview .seathint p { margin: 0; font-size: 13px; line-height: 1.55; color: rgba(255, 255, 255, .68); max-width: 70ch; }
.buildview .sh-go { margin-top: 10px; }

.cx-help {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: 11.5px; padding: 4px 11px; border-radius: 999px;
  background: rgba(255, 255, 255, .05); border: 1px solid var(--hair); color: rgba(255, 255, 255, .62);
}
.cx-help:hover { color: #fff; background: rgba(255, 255, 255, .12); }
.cx-help svg { width: 13px; height: 13px; }

/* ---- The computed chain ----------------------------------------------------
 * A chain somebody wrote is a story. A chain the graph produces is evidence.
 * Every blocker has one, which is the point: if only three existed, the fair
 * question would be whether those three were the only ones that worked.
 */
.buildview .chain-pick {
  display: grid; gap: 9px; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
}
.buildview .cp {
  display: block; text-align: left; cursor: pointer; padding: 12px 14px; border-radius: 11px;
  background: var(--glass); border: 1px solid var(--hair); color: inherit;
}
.buildview .cp:hover { background: rgba(63, 189, 240, .1); border-color: rgba(63, 189, 240, .34); }
.buildview .cp b { display: block; font-size: 13.5px; font-weight: 550; margin: 6px 0 5px; }
.buildview .cp-v { font-size: 11.5px; color: rgba(255, 255, 255, .5); font-variant-numeric: tabular-nums; }

.buildview .cchain {
  padding: 17px 20px; border-radius: 13px; margin-bottom: 14px;
  background: linear-gradient(130deg, rgba(63, 189, 240, .1), rgba(63, 189, 240, .02));
  border: 1px solid rgba(63, 189, 240, .3);
}
.buildview .cc-head { position: relative; }
.buildview .cc-tag {
  font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; font-weight: 600;
  padding: 2px 9px; border-radius: 4px; background: rgba(63, 189, 240, .16); color: var(--cyan);
}
.buildview .cchain h2 {
  font-family: var(--font-display); font-size: 21px; line-height: 1.3; margin: 9px 0 7px;
  font-weight: 600; max-width: 40ch;
}
.buildview .cc-sum { margin: 0 0 6px; font-size: 14px; line-height: 1.6; color: rgba(255, 255, 255, .78); max-width: 74ch; }
.buildview .cc-go {
  margin: 0 0 10px; font-size: 13.5px; line-height: 1.55; color: var(--bad);
  padding-left: 11px; border-left: 2px solid rgba(255, 95, 109, .5); max-width: 70ch;
}
.buildview .cc-spans { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; }
.buildview .cc-head .bl-x { position: absolute; top: 0; right: 0; }

.buildview .cc-nums {
  display: flex; flex-wrap: wrap; gap: 12px 30px; margin: 14px 0 16px;
  padding: 13px 16px; border-radius: 11px;
  background: rgba(255, 255, 255, .03); border: 1px solid var(--hair);
}
.buildview .cc-nums .k {
  display: block; font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: rgba(255, 255, 255, .42); margin-bottom: 3px;
}
.buildview .cc-nums b { font-size: 19px; font-variant-numeric: tabular-nums; font-weight: 600; }
.buildview .cc-nums b.good { color: var(--ok); }
.buildview .cc-nums b.bad { color: var(--bad); }
.buildview .cc-nums b.quiet { color: rgba(255, 255, 255, .4); font-size: 15px; }

.buildview .cc-steps .step { padding-bottom: 16px; }
.buildview .cc-at {
  font-size: 11.5px; color: rgba(255, 255, 255, .5); font-variant-numeric: tabular-nums;
  margin-left: auto;
}
.buildview .bl-l.big .bll { font-size: 12.5px; padding: 5px 12px; }
/* Whose it is, on any card that is not yours, so it reads as somebody else's
   work rather than as a demand on you. */
.blk-own {
  margin-left: auto; font-size: 10px; letter-spacing: .05em; text-transform: uppercase;
  padding: 1px 7px; border-radius: 999px;
  background: rgba(255, 255, 255, .06); color: rgba(255, 255, 255, .45);
}
.blk-own + .blk-due { margin-left: 6px; }
/* The underlying record, kept visible under the role-framed sentence. The
   commercial officer sees the megawatts and can still see it is a CRAH unit. */
.blk-sub {
  font-size: 11px; color: rgba(255, 255, 255, .42); margin: -2px 0 5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- The stack, in three dimensions ----------------------------------------
 * The view somebody senior reads in three seconds. Everything lives in one SVG,
 * labels included: the first attempt positioned labels in CSS over a scaling
 * SVG and they collapsed onto one line. Text in the same coordinate system as
 * the drawing cannot drift from it, at any size.
 *
 * The cubes are what make it read as depth. Each one is a real unit of its
 * layer, so what is standing is what is actually built.
 */
.buildview .iso { width: 100%; }
.buildview .iso-svg { width: 100%; height: auto; display: block; overflow: visible; }
.buildview .iso-cap {
  fill: rgba(255, 255, 255, .38); font-size: 12px; text-anchor: end;
  font-family: var(--font-body);
}

.buildview .iso-slab { cursor: pointer; }
.buildview .iso-slab .deck { fill: rgba(255, 255, 255, .035); }
.buildview .iso-slab .edge-b { fill: rgba(255, 255, 255, .055); }
.buildview .iso-slab .edge-b.dark { fill: rgba(0, 0, 0, .32); }
.buildview .iso-slab .rim {
  fill: none; stroke: rgba(255, 255, 255, .2); stroke-width: 1.1;
  transition: stroke-width .18s ease;
}
.buildview .iso-slab .slot { fill: rgba(255, 255, 255, .02); stroke: rgba(255, 255, 255, .05); stroke-width: .5; }
.buildview .iso-slab .lead { stroke: rgba(255, 255, 255, .14); stroke-width: 1; fill: none; stroke-dasharray: 2 3; }
.buildview .iso-slab .knot { fill: rgba(255, 255, 255, .3); }
.buildview .iso-slab.faded { opacity: .22; }

/* Three faces per cube, lit as if from the upper left, which is what tells the
   eye it is an object rather than a pattern. */
.buildview .cube .cf.top { fill: rgba(255, 255, 255, .5); }
.buildview .cube .cf.left { fill: rgba(255, 255, 255, .26); }
.buildview .cube .cf.right { fill: rgba(255, 255, 255, .14); }

.buildview .rag-green .cube .cf.top { fill: #38e3c0; }
.buildview .rag-green .cube .cf.left { fill: #1f9a83; }
.buildview .rag-green .cube .cf.right { fill: #14705f; }
.buildview .rag-amber .cube .cf.top { fill: #f7b155; }
.buildview .rag-amber .cube .cf.left { fill: #b0762d; }
.buildview .rag-amber .cube .cf.right { fill: #7d541f; }
.buildview .rag-red .cube .cf.top { fill: #ff6b78; }
.buildview .rag-red .cube .cf.left { fill: #b8404b; }
.buildview .rag-red .cube .cf.right { fill: #822d35; }

.buildview .rag-green .rim { stroke: rgba(47, 224, 189, .55); }
.buildview .rag-amber .rim { stroke: rgba(242, 163, 60, .58); }
.buildview .rag-red .rim { stroke: rgba(255, 95, 109, .6); }
.buildview .rag-green .knot { fill: var(--ok); }
.buildview .rag-amber .knot { fill: var(--warn); }
.buildview .rag-red .knot { fill: var(--bad); }

.buildview .iso-slab.on .rim, .buildview .iso-slab.blocked .rim { stroke-width: 2.2; }
.buildview .iso-slab.on .deck { fill: rgba(255, 255, 255, .07); }
.buildview .iso-slab:hover .rim { stroke-width: 1.8; }
.buildview .iso-slab:focus-visible { outline: none; }
.buildview .iso-slab:focus-visible .rim { stroke: var(--cyan); stroke-width: 2.4; }
.buildview .iso-slab.b-blocked .rim { stroke: var(--bad); stroke-width: 2.4; }
.buildview .iso-slab.b-stranded .rim { stroke: var(--warn); stroke-width: 2.2; stroke-dasharray: 5 3; }

.buildview .beam line { stroke: rgba(255, 255, 255, .1); stroke-width: 1; }
.buildview .beam.live line { stroke: rgba(63, 189, 240, .28); }

/* Labels, in the same coordinate space as the drawing. */
.buildview .iso-lab { pointer-events: none; }
.buildview .il-t {
  fill: #fff; font-size: 17px; font-weight: 560; text-anchor: end;
  font-family: var(--font-body);
}
.buildview .il-s {
  fill: rgba(255, 255, 255, .44); font-size: 11.5px; text-anchor: end;
  font-family: var(--font-body);
}
.buildview .il-p {
  font-size: 27px; font-weight: 600; text-anchor: start; font-family: var(--font-body);
  fill: #fff;
}
.buildview .il-pc { font-size: 13px; fill: rgba(255, 255, 255, .42); }
.buildview .rag-green .il-p { fill: var(--ok); }
.buildview .rag-amber .il-p { fill: var(--warn); }
.buildview .rag-red .il-p { fill: var(--bad); }
.buildview .iso-lab.faded { opacity: .22; }
.buildview .il-f rect { fill: rgba(255, 95, 109, .16); stroke: rgba(255, 95, 109, .4); stroke-width: 1; }
.buildview .il-f text {
  fill: var(--bad); font-size: 9.5px; letter-spacing: .08em; font-weight: 600;
  font-family: var(--font-body);
}
.buildview .il-f.b-stranded rect { fill: rgba(242, 163, 60, .16); stroke: rgba(242, 163, 60, .4); }
.buildview .il-f.b-stranded text { fill: var(--warn); }

.buildview .lay-mode { margin-left: auto; }
.buildview .cake-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px 14px; }
.buildview .cake-head h2 { margin: 0; }
.buildview .cake-head p { flex-basis: 100%; }

/* ---- Systems map -----------------------------------------------------------
 * Every tool this touches, and what flows between them. Laid out as a ring
 * around the model rather than as a hierarchy, because a hierarchy would imply
 * one of them sits above the others and none of them does.
 */
.buildview .sm-wrap {
  border-radius: 14px; padding: 8px;
  background: radial-gradient(80% 60% at 50% 45%, rgba(63, 189, 240, .07), transparent 65%),
    rgba(0, 0, 0, .16);
  border: 1px solid var(--hair);
}
.buildview .sm-svg { width: 100%; height: auto; display: block; }
.buildview .sm-lbl {
  fill: rgba(255, 255, 255, .34); font-size: 11px; text-anchor: middle;
  letter-spacing: .1em; text-transform: uppercase; font-family: var(--font-body);
}
.buildview .sm-edge path { fill: none; stroke: rgba(255, 255, 255, .16); stroke-width: 1.2; }
.buildview .sm-edge.d-out path { stroke: rgba(47, 224, 189, .3); stroke-dasharray: 5 4; }
.buildview .sm-edge.d-both path { stroke: rgba(160, 130, 255, .32); }
.buildview .sm-edge.dim path { opacity: .12; }
.buildview .sm-edge.on path { stroke-width: 1.8; }

.buildview .sm-node { cursor: pointer; }
.buildview .sm-node rect {
  fill: rgba(255, 255, 255, .05); stroke: rgba(255, 255, 255, .16); stroke-width: 1;
}
.buildview .sm-node:hover rect { fill: rgba(255, 255, 255, .1); }
.buildview .sm-node.sel rect { fill: rgba(63, 189, 240, .16); stroke: rgba(63, 189, 240, .55); stroke-width: 1.6; }
.buildview .sm-node.dim { opacity: .22; }
.buildview .sm-n {
  fill: #fff; font-size: 13px; font-weight: 550; text-anchor: middle; font-family: var(--font-body);
}
.buildview .sm-s {
  fill: rgba(255, 255, 255, .44); font-size: 10px; text-anchor: middle; font-family: var(--font-body);
}
.buildview .sm-hub { cursor: pointer; }
.buildview .sm-hub rect {
  fill: rgba(63, 189, 240, .14); stroke: rgba(63, 189, 240, .5); stroke-width: 1.6;
}
.buildview .sm-hub.sel rect { fill: rgba(63, 189, 240, .24); }
.buildview .sm-hn {
  fill: #fff; font-size: 17px; font-weight: 600; text-anchor: middle;
  font-family: var(--font-display);
}
.buildview .sm-hs {
  fill: rgba(255, 255, 255, .58); font-size: 11px; text-anchor: middle; font-family: var(--font-body);
}
.buildview .sm-io { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); margin-top: 12px; }
.buildview .sm-io .k {
  display: block; font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: rgba(255, 255, 255, .42); margin-bottom: 6px;
}
.buildview .sm-f {
  font-size: 12.5px; line-height: 1.5; padding: 4px 0; color: rgba(255, 255, 255, .72);
}
.buildview .sm-f.quiet { color: rgba(255, 255, 255, .38); }
.buildview .sm-tab { margin-top: 4px; }
.buildview .sm-tab tr.dim { opacity: .3; }

/* ---- Standalone, and naturally responsive ----------------------------------
 * The console is shown on its own: no site menu, no footer competing with it.
 * That is not only presentation. The nav was taking 88px off the top and the
 * console was compensating with a magic number, which is the sort of thing that
 * is wrong on the first screen somebody opens it on that is not mine.
 *
 * Sizing is fluid rather than stepped. The rail, the aside, the chrome and the
 * type all scale with the space available, so there is no width or height where
 * it suddenly looks wrong: it degrades continuously instead of jumping at a
 * breakpoint somebody guessed. The only genuine breakpoints left are the two
 * places where the layout changes shape rather than size, because stacking is a
 * decision and not a scale.
 */
body.consolepage .sitenav,
body.consolepage .sitefoot { display: none; }
body.consolepage main { padding-top: 10px; }

/* Wide only. This block sets the console's SHAPE, and it used to do so with no
   media query at all. Sitting after the stacking breakpoint, and with media
   queries adding no specificity, it silently overrode all four of the
   properties that breakpoint sets: the single column, the five rows, height
   auto and min-height 0. The stacked layout was therefore dead at every width.
   On a phone the console kept its three-column, three-row, fixed-height desktop
   shape, the columns resolved to 58px / 178px / 90px, and all five regions were
   placed in the 58px one while the other two sat empty. That was the strip down
   the left, and 100dvh across five stacked regions was the overlap.

   Fluid is still right above the breakpoint, so the rule is kept and scoped
   rather than rewritten. Below it, stacking governs, which is what the comment
   above always said was intended: shape is a decision, size is a scale. */
@media (min-width: 1101px) {
  .cx {
    /* Fluid across the whole range rather than fixed with exceptions. The rail
       collapses toward icons and the aside toward its strip as space runs out,
       without either needing a breakpoint to do it. */
    grid-template-columns:
      clamp(58px, 15vw, 216px)
      minmax(0, 1fr)
      clamp(0px, 25vw, 344px);
    grid-template-rows: clamp(42px, 6vh, 54px) minmax(0, 1fr) auto;
    height: calc(100dvh - 20px);
    min-height: min(420px, 92dvh);
  }
}

/* Chrome that scales with the room it has, so a short laptop gets more content
   and less padding rather than the same padding and a scrollbar. */
.cx-top { padding: 0 clamp(10px, 1.2vw, 16px); gap: clamp(10px, 1.4vw, 18px); }
.cx-seats button { padding: clamp(4px, .8vh, 7px) clamp(9px, 1vw, 14px); font-size: clamp(12px, 1.05vw, 13.5px); }
.cx-rail { padding: clamp(8px, 1.2vh, 12px) clamp(6px, .7vw, 10px) 16px; }
.cx-rail button { padding: clamp(6px, 1vh, 9px) clamp(8px, .8vw, 11px); font-size: clamp(12px, 1vw, 13.5px); }
.cx-rail .rg { padding: clamp(7px, 1.2vh, 12px) 10px 5px; }
.cx-main { padding: clamp(12px, 1.8vh, 18px) clamp(14px, 1.6vw, 22px) 26px; }
.cx-aside { padding: clamp(10px, 1.4vh, 14px) clamp(10px, .9vw, 14px) 18px; }
.cx-clock { padding: clamp(6px, .9vh, 9px) clamp(12px, 1.2vw, 16px) clamp(7px, 1vh, 10px); }

/* The seat abbreviation under each label is the first thing to go when the bar
   gets tight, because the label already says it. */
@media (max-width: 1240px), (max-height: 780px) {
  .cx-seats button .sq { display: none; }
}
/* The clock's caption is explanation, not control. */
@media (max-height: 820px) { .buildview .ck-ends { display: none; } }

/* Fluid type on the things that carry the room: the two numbers, the layer
   percentages, the walkthrough line somebody reads out loud. */
.buildview .twonum .tn-v { font-size: clamp(26px, 3.2vw, 40px); }
.buildview .twonum .tn { padding: clamp(10px, 1.4vh, 16px) clamp(12px, 1.2vw, 18px); }
.buildview .bt-say { font-size: clamp(14.5px, 1.35vw, 16.5px); }
.buildview .intro h2 { font-size: clamp(19px, 2.1vw, 25px); }
.buildview .in-p { font-size: clamp(14px, 1.2vw, 15.5px); }
.buildview .cake-head h2 { font-size: clamp(16px, 1.5vw, 19px); }
.buildview .lay-pct { font-size: clamp(18px, 1.9vw, 24px); }
.buildview .rw-mw { font-size: clamp(19px, 2vw, 24px); }
.buildview .cc-nums b { font-size: clamp(16px, 1.6vw, 19px); }

/* A quiet way home, since there is no menu to get back with. */
.cx-home {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  font-size: 11.5px; color: rgba(255, 255, 255, .42); text-decoration: none;
  padding: 3px 9px; border-radius: 999px; border: 1px solid transparent;
}
.cx-home:hover { color: #fff; border-color: var(--hair); background: rgba(255, 255, 255, .05); }

/* ---- Planned, as against scanned -----------------------------------------
 * The clock runs past today, and past today there is nothing to report except
 * what the schedule says. Every drawing therefore needs a second treatment that
 * cannot be mistaken for the first: hollow rather than solid, short rather than
 * full height, hatched rather than filled. Somebody who walks up to this and is
 * not told which marks are facts will assume all of them are.
 */
.buildview .cube.ghost .cf { fill: none; stroke: rgba(255, 255, 255, .3); stroke-width: .6; }
.buildview .cube.ghost .cf.top { fill: rgba(255, 255, 255, .06); }
.buildview .rag-green .cube.ghost .cf { stroke: rgba(56, 227, 192, .5); }
.buildview .rag-green .cube.ghost .cf.top { fill: rgba(56, 227, 192, .1); }
.buildview .rag-amber .cube.ghost .cf { stroke: rgba(247, 177, 85, .5); }
.buildview .rag-amber .cube.ghost .cf.top { fill: rgba(247, 177, 85, .1); }
.buildview .rag-red .cube.ghost .cf { stroke: rgba(255, 107, 120, .5); }
.buildview .rag-red .cube.ghost .cf.top { fill: rgba(255, 107, 120, .1); }

.buildview .il-pp { font-size: 11px; fill: rgba(255, 255, 255, .34); letter-spacing: .01em; }

.buildview .iso-key {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 20px;
  padding: 10px 4px 2px; border-top: 1px solid var(--line); margin-top: 6px;
}
.buildview .iso-key .ik {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--dim);
}
.buildview .iso-key .ik b { color: var(--ink); font-variant-numeric: tabular-nums; }
.buildview .iso-key .ik-say { flex: 1 1 320px; font-size: 11.5px; color: var(--dim); line-height: 1.5; }
i.ik-solid, i.ik-ghost { width: 11px; height: 11px; border-radius: 2px; flex: none; }
i.ik-solid { background: var(--ok); }
i.ik-ghost {
  border: 1px dashed rgba(255, 255, 255, .5);
  background: repeating-linear-gradient(45deg,
    rgba(255, 255, 255, .16) 0 2px, transparent 2px 4px);
}

/* Hatched on the plan and in section. The hatch is a pattern rather than a
   colour so it survives every lens: the rack keeps whatever colour the seat's
   question gives it, and still reads as not yet real. */
.buildview .fp-rack.plan, .buildview .sc-rack.plan .sc-body {
  fill-opacity: .2; stroke-dasharray: 2 1.6; stroke-opacity: .75;
}
.buildview .fp-rack.plan:hover { fill-opacity: .5; }
.buildview .sc-rack.plan .sc-u line { stroke-opacity: .4; }

.buildview .fp-plan-note {
  display: flex; align-items: center; gap: 8px;
  margin: 8px 0 0; font-size: 11.5px; color: var(--dim); line-height: 1.5;
}
.buildview .ck-read i.plan {
  background: repeating-linear-gradient(45deg,
    rgba(255, 255, 255, .45) 0 2px, transparent 2px 4px);
  border: 1px solid rgba(255, 255, 255, .35);
}
.buildview .ck-read .ck-plan { color: var(--dim); }

/* ---- The chain's verdict, and the queue at each hop -----------------------
 * Three obligations in front of the same gate produced three chains that read
 * identically, which is how somebody ends up chasing the signature that was
 * never the problem. The verdict says what to do; the queue says who else is
 * standing there and which of them is actually holding it.
 */
.buildview .cc-verdict {
  margin: 10px 0 0; padding: 10px 13px; border-radius: 8px;
  font-size: 13px; line-height: 1.55;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .03);
}
.buildview .cc-verdict.binds {
  border-color: rgba(47, 224, 189, .35); background: rgba(47, 224, 189, .07); color: var(--ink);
}
.buildview .cc-verdict.quiet { color: var(--dim); }

.buildview .cc-also {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line);
}
.buildview .cc-also .ca-k {
  font-size: 10px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--faint); margin-right: 2px;
}
.buildview .cc-also .ca {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 3px 8px; border-radius: 999px; font-size: 11.5px;
  border: 1px solid var(--line); color: var(--dim); background: rgba(255, 255, 255, .02);
}
.buildview .cc-also .ca i { font-style: normal; font-size: 10px; color: var(--faint); }
.buildview .cc-also .ca.binds {
  border-color: rgba(255, 95, 109, .45); color: var(--ink); background: rgba(255, 95, 109, .08);
}
.buildview .cc-also .ca.binds i { color: var(--bad); }
.buildview .cc-also .ca.more { border-style: dashed; }
