/* =========================================================================
   BradleyPens — Studio shell (direction round)
   =========================================================================
   Loaded AFTER style.css. Adds the shell grid, the Output Deck, the
   filmstrip and the craft layer from the identity round. Touches none of
   style.css's own tokens: the two-palette architecture there is what makes
   an anchor rasterize identically in both themes, and it stays as it is.

   What this file adds on top:
     - a four-step SURFACE LADDER. Elevation is luminance, not shadow.
     - THREE hairline tiers, used deliberately: hard between panels,
       standard between rows, soft within a group. Choosing at random
       between them is what makes a dense UI read as noisy.
     - a type scale with real tracking. Positive-tracked uppercase mono
       eyebrows against negative-tracked headings is the contrast that
       keeps a panel-dense screen legible.
     - ONE accent. The running job, the primary action, the focus ring.
       Nothing else, and it is enforced structurally: the arc colour rule
       is keyed on [data-running] on the deck itself.
   ========================================================================= */

:root {
  /* Surface ladder, light. Roughly 2.5% luminance per step. */
  --st-surf-0: #E9EAE5;   /* app ground, behind everything */
  --st-surf-1: #F2F3EF;   /* rails, deck, filmstrip */
  --st-surf-2: #F9FAF7;   /* rows at rest */
  --st-surf-3: #FFFFFF;   /* row hover, accordion body, popovers */
  --st-surf-4: #FFFFFF;   /* the sheet itself */

  /* Three hairline tiers. */
  --st-line-hard: #D2D6CD;   /* structural: between panels */
  --st-line: #E0E3DC;        /* standard: between rows */
  --st-line-soft: #EAECE6;   /* soft: within a group */

  /* 4px spacing scale. These values only. */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px; --sp-9: 96px;

  /* Shell metrics. */
  --st-topbar-h: 52px;
  --st-signrail-w: 72px;
  --st-specrail-w: 300px;
  --st-deck-w: 320px;
  --st-strip-h: 104px;
  --st-row-h: 48px;
  --st-status-w: 64px;

  /* Catch-light: a lit top edge reads as physical where a drop shadow reads
     as floating. Paired with two low-alpha layers, never one fat one. */
  --st-lift: inset 0 1px 0 rgba(255,255,255,.72),
             0 1px 1px rgba(16,26,43,.04),
             0 6px 18px -10px rgba(16,26,43,.18);
}

:root[data-theme="dark"] {
  --st-surf-0: #070D16;
  --st-surf-1: #0C1421;
  --st-surf-2: #111B2A;
  --st-surf-3: #172335;
  --st-surf-4: #141F31;
  --st-line-hard: #24334A;
  --st-line: #1D2B3F;
  --st-line-soft: #172232;
  --st-lift: inset 0 1px 0 rgba(255,255,255,.055),
             0 1px 1px rgba(0,0,0,.34),
             0 8px 22px -12px rgba(0,0,0,.6);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --st-surf-0: #070D16;
    --st-surf-1: #0C1421;
    --st-surf-2: #111B2A;
    --st-surf-3: #172335;
    --st-surf-4: #141F31;
    --st-line-hard: #24334A;
    --st-line: #1D2B3F;
    --st-line-soft: #172232;
    --st-lift: inset 0 1px 0 rgba(255,255,255,.055),
               0 1px 1px rgba(0,0,0,.34),
               0 8px 22px -12px rgba(0,0,0,.6);
  }
}

/* ── Type scale ────────────────────────────────────────────────────────
   Utility classes rather than tokens, because every one carries a size, a
   weight AND a tracking, and splitting those into three variables is how a
   scale drifts. */

.st-eyebrow {
  font-family: var(--font-mono);
  font-size: 9.5px; font-weight: 500; line-height: 1.3;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--bp-steel-soft);
}
.st-meta   { font-size: 11px;   line-height: 1.4; color: var(--bp-steel-soft); }
.st-ui     { font-size: 12.5px; line-height: 1.45; letter-spacing: -.005em; }
.st-body   { font-size: 13.5px; line-height: 1.55; letter-spacing: -.01em; }
.st-h2     { font-size: 20px;   line-height: 1.25; letter-spacing: -.02em; font-weight: 600; margin: 0; }
.st-h1     { font-size: 30px;   line-height: 1.15; letter-spacing: -.03em; font-weight: 650; margin: 0; }
.st-num    { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* ═══════════════════════════════════════════════════════════════════════
   SHELL GRID
   Both directions share every component below. Only this block differs.
   ═══════════════════════════════════════════════════════════════════════ */

body.st-shell { background: var(--st-surf-0); overflow: hidden; }

.st-app {
  height: 100dvh;
  display: grid;
  grid-template-rows: var(--st-topbar-h) 1fr;
  background: var(--st-surf-0);
}

/* Left rail of signs, spec rail, canvas, output deck. */
.st-work {
  display: grid; min-height: 0;
  grid-template-columns: var(--st-signrail-w) var(--st-specrail-w) 1fr var(--st-deck-w);
  grid-template-areas: "signs spec stage deck";
}

.st-signs { grid-area: signs; }
.st-spec  { grid-area: spec; }
.st-stage { grid-area: stage; }
.st-deck  { grid-area: deck; }

.st-stage {
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-width: 0; min-height: 0;
}

/* ═══════════════════════════════════════════════════════════════════════
   TOP BAR
   ═══════════════════════════════════════════════════════════════════════ */

.st-topbar {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: 0 var(--sp-3) 0 var(--sp-4);
  background: var(--st-surf-1);
  border-bottom: 1px solid var(--st-line-hard);
}
.st-brand { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.st-brand-mark { display: block; }
.st-brand-name {
  font-size: 13.5px; font-weight: 650; letter-spacing: -.02em;
  line-height: 1.1; color: var(--bp-ink);
}
.st-brand-tag {
  font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase;
  font-family: var(--font-mono); color: var(--bp-steel-soft); line-height: 1.4;
}

.st-project { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; }
.st-project input {
  width: 100%; max-width: 320px;
  background: transparent; border: 0; padding: 6px 0;
  font-size: 13.5px; font-weight: 500; letter-spacing: -.01em;
  border-bottom: 1px solid transparent;
  transition: border-color var(--bp-dur-fast) var(--bp-ease-out);
}
.st-project input::placeholder { color: var(--bp-steel-soft); }
.st-project input:hover { border-bottom-color: var(--st-line); }
.st-project input:focus { outline: none; border-bottom-color: var(--bp-amber); }

/* A selected control is FILLED, not tinted. BarryBids' rule, carried. */
.st-modes {
  display: flex; gap: 2px; padding: 2px;
  background: var(--st-surf-0); border: 1px solid var(--st-line);
  border-radius: var(--bp-radius-control);
}
.st-mode {
  appearance: none; border: 0; background: transparent;
  padding: 5px 11px; border-radius: 5px;
  font-size: 12px; font-weight: 500; letter-spacing: -.005em;
  color: var(--bp-steel);
  transition: background 100ms var(--bp-ease-out), color 100ms var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .st-mode:hover { background: var(--st-surf-2); color: var(--bp-ink); }
}
.st-mode[aria-selected="true"] { background: var(--bp-ink-navy); color: #fff; }
:root[data-theme="dark"] .st-mode[aria-selected="true"] { background: var(--bp-card); color: var(--bp-ink); }

.st-topbar-actions { display: flex; align-items: center; gap: var(--sp-2); }

.st-tbtn {
  appearance: none; height: 30px; padding: 0 11px;
  background: transparent; border: 1px solid var(--st-line-hard);
  border-radius: var(--bp-radius-control);
  font-size: 12px; font-weight: 500; color: var(--bp-steel);
  display: inline-flex; align-items: center; gap: 6px;
  transition: border-color var(--bp-dur-fast) var(--bp-ease-out), color var(--bp-dur-fast) var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .st-tbtn:hover { border-color: var(--bp-steel); color: var(--bp-ink); }
}
.st-tbtn-icon { width: 30px; padding: 0; justify-content: center; }

/* A job running anywhere stays visible from everywhere, so scrolling the
   filmstrip never loses the thread. */
.st-jobpill {
  display: none; align-items: center; gap: 7px;
  height: 28px; padding: 0 11px 0 9px;
  border: 1px solid var(--st-line-hard); border-radius: var(--bp-radius-pill);
  background: var(--st-surf-2);
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--bp-steel);
}
.st-app[data-busy="1"] .st-jobpill { display: inline-flex; }

/* ═══════════════════════════════════════════════════════════════════════
   SIGN RAIL — the project's signs, down the left edge.
   A trade type code in mono reads faster than a truncated name, and it is
   the language on the drawing anyway.
   ═══════════════════════════════════════════════════════════════════════ */

.st-signs {
  background: var(--st-surf-1);
  border-right: 1px solid var(--st-line-hard);
  display: flex; flex-direction: column;
  padding: var(--sp-2) 0;
  overflow-y: auto; overscroll-behavior: contain;
}
.st-signtile {
  position: relative;
  appearance: none; background: transparent; border: 0;
  width: 100%; padding: 9px 0 8px;
  display: grid; justify-items: center; gap: 4px;
  color: var(--bp-steel);
  transition: background 100ms var(--bp-ease-out), color 100ms var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .st-signtile:hover { background: var(--st-surf-2); color: var(--bp-ink); }
}
.st-signtile[aria-selected="true"] { color: var(--bp-ink); background: var(--st-surf-3); }
/* The selected sign is marked on its edge, not flooded — a flooded tile in
   a rail of eight reads as eight chosen things. */
.st-signtile[aria-selected="true"]::before {
  content: ""; position: absolute; left: 0; top: 6px; bottom: 6px;
  width: 2px; background: var(--bp-ink-navy); border-radius: 0 2px 2px 0;
}
:root[data-theme="dark"] .st-signtile[aria-selected="true"]::before { background: var(--bp-blueprint); }
.st-signtile svg { display: block; }
.st-signtile-code {
  font-family: var(--font-mono); font-size: 8.5px; font-weight: 500;
  letter-spacing: .08em; text-transform: uppercase;
}
.st-signs-add {
  margin: var(--sp-2) auto 0; width: 40px; height: 40px;
  display: grid; place-items: center;
  background: transparent; border: 1px dashed var(--st-line-hard);
  border-radius: var(--bp-radius-control); color: var(--bp-steel-soft);
  transition: border-color var(--bp-dur-fast) var(--bp-ease-out), color var(--bp-dur-fast) var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .st-signs-add:hover { border-color: var(--bp-steel); color: var(--bp-ink); }
}

/* ═══════════════════════════════════════════════════════════════════════
   DESIGN BAR
   Standing requirement (PRODUCT.md 46-52). Every control redraws on the
   spot. Direction B slims it. Neither direction removes it.
   ═══════════════════════════════════════════════════════════════════════ */

.st-designbar {
  display: flex; align-items: center; gap: var(--sp-5);
  padding: 0 var(--sp-4); height: 56px;
  background: var(--st-surf-1);
  border-bottom: 1px solid var(--st-line-hard);
  overflow-x: auto; overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.st-designbar::-webkit-scrollbar { display: none; }
.st-bargroup { display: flex; align-items: center; gap: var(--sp-3); flex: 0 0 auto; }
.st-bargroup + .st-bargroup { border-left: 1px solid var(--st-line); padding-left: var(--sp-5); }
.st-barspacer { flex: 1 1 auto; min-width: var(--sp-4); }

.st-dim { display: grid; gap: 2px; }
.st-dim-head { display: flex; align-items: center; gap: 5px; }
.st-dim-label {
  font-family: var(--font-mono); font-size: 8.5px; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase; color: var(--bp-steel-soft);
}
/* Confidence is carried by SHAPE, never colour alone: a filled square is a
   surveyed dimension, hollow is an estimate. */
.st-conf {
  width: 7px; height: 7px; flex: 0 0 auto;
  border: 1px solid var(--bp-steel-soft); background: transparent;
  padding: 0; cursor: pointer;
}
.st-conf[data-c="confirmed"] { background: var(--bp-steel); border-color: var(--bp-steel); }
.st-dim-input {
  width: 76px; height: 30px; padding: 0 8px;
  background: var(--st-surf-3); border: 1px solid var(--st-line);
  border-radius: var(--bp-radius-control);
  font-family: var(--font-mono); font-size: 13px; font-variant-numeric: tabular-nums;
  -moz-appearance: textfield;
  transition: border-color var(--bp-dur-fast) var(--bp-ease-out);
}
.st-dim-input::-webkit-outer-spin-button,
.st-dim-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.st-dim-input:hover { border-color: var(--st-line-hard); }
.st-dim-input:focus { outline: none; border-color: var(--bp-amber); }
.st-dim-ftin {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .05em;
  color: var(--bp-steel-soft); padding-left: 1px; min-height: 12px;
}

/* Segmented control — one outline round the group, not eight lozenges. */
.st-seg {
  display: inline-flex; padding: 2px; gap: 2px;
  background: var(--st-surf-0); border: 1px solid var(--st-line);
  border-radius: var(--bp-radius-control);
}
.st-seg button {
  appearance: none; border: 0; background: transparent;
  height: 26px; padding: 0 10px; border-radius: 5px;
  font-size: 11.5px; font-weight: 500; letter-spacing: -.005em; color: var(--bp-steel);
  transition: background 100ms var(--bp-ease-out), color 100ms var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .st-seg button:hover { background: var(--st-surf-2); color: var(--bp-ink); }
}
.st-seg button[aria-pressed="true"] { background: var(--bp-ink-navy); color: #fff; }
:root[data-theme="dark"] .st-seg button[aria-pressed="true"] { background: var(--bp-card); color: var(--bp-ink); }

.st-toggle {
  appearance: none; height: 30px; padding: 0 13px;
  background: transparent; border: 1px solid var(--st-line-hard);
  border-radius: var(--bp-radius-pill);
  font-size: 11.5px; font-weight: 500; color: var(--bp-steel);
  transition: background var(--bp-dur-fast) var(--bp-ease-out),
              color var(--bp-dur-fast) var(--bp-ease-out),
              border-color var(--bp-dur-fast) var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .st-toggle:hover:not(:disabled) { border-color: var(--bp-steel); color: var(--bp-ink); }
}
.st-toggle[aria-pressed="true"] {
  background: var(--bp-ink-navy); border-color: var(--bp-ink-navy); color: #fff;
}
:root[data-theme="dark"] .st-toggle[aria-pressed="true"] {
  background: var(--bp-card); border-color: var(--bp-hairline); color: var(--bp-ink);
}
.st-toggle:disabled { opacity: .38; cursor: not-allowed; }

/* ═══════════════════════════════════════════════════════════════════════
   SPEC RAIL — direction B only.
   ═══════════════════════════════════════════════════════════════════════ */

.st-spec {
  background: var(--st-surf-1);
  border-right: 1px solid var(--st-line-hard);
  overflow-y: auto; overscroll-behavior: contain;
  padding-bottom: var(--sp-6);
}
.st-spec-sect { padding: var(--sp-4); border-bottom: 1px solid var(--st-line); }
.st-spec-sect > .st-eyebrow { display: block; margin-bottom: var(--sp-3); }
.st-field { display: grid; gap: 5px; margin-bottom: var(--sp-3); }
.st-field:last-child { margin-bottom: 0; }
.st-field-label { font-size: 11px; font-weight: 500; color: var(--bp-steel); }
.st-input, .st-select {
  width: 100%; height: 32px; padding: 0 9px;
  background: var(--st-surf-3); border: 1px solid var(--st-line);
  border-radius: var(--bp-radius-control); font-size: 12.5px;
  transition: border-color var(--bp-dur-fast) var(--bp-ease-out);
}
.st-input:hover, .st-select:hover { border-color: var(--st-line-hard); }
.st-input:focus, .st-select:focus { outline: none; border-color: var(--bp-amber); }
.st-textarea {
  width: 100%; min-height: 60px; padding: 8px 9px; resize: vertical;
  background: var(--st-surf-3); border: 1px solid var(--st-line);
  border-radius: var(--bp-radius-control); font-size: 12.5px; line-height: 1.5;
  transition: border-color var(--bp-dur-fast) var(--bp-ease-out);
}
.st-textarea:focus { outline: none; border-color: var(--bp-amber); }
/* Chips over dropdowns wherever the option set is small enough to show — a
   select hides the alternatives behind a click. */
.st-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.st-chip {
  appearance: none; height: 26px; padding: 0 9px;
  background: var(--st-surf-3); border: 1px solid var(--st-line);
  border-radius: var(--bp-radius-chip);
  font-size: 11px; font-weight: 500; color: var(--bp-steel);
  transition: background var(--bp-dur-fast) var(--bp-ease-out),
              color var(--bp-dur-fast) var(--bp-ease-out),
              border-color var(--bp-dur-fast) var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .st-chip:hover { border-color: var(--bp-steel); color: var(--bp-ink); }
}
.st-chip[aria-pressed="true"] {
  background: var(--bp-ink-navy); border-color: var(--bp-ink-navy); color: #fff;
}
:root[data-theme="dark"] .st-chip[aria-pressed="true"] {
  background: var(--bp-card); border-color: var(--bp-hairline); color: var(--bp-ink);
}
.st-readout {
  display: grid; grid-template-columns: 1fr auto; gap: 3px var(--sp-3);
  font-size: 11px;
}
.st-readout dt { color: var(--bp-steel-soft); }
.st-readout dd {
  margin: 0; font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--bp-ink); text-align: right;
}

/* ═══════════════════════════════════════════════════════════════════════
   CANVAS
   ═══════════════════════════════════════════════════════════════════════ */

.st-canvas {
  position: relative; min-height: 0;
  overflow: auto; overscroll-behavior: contain;
  display: grid; place-items: center;
  padding: var(--sp-5);
  background: var(--st-surf-0);
  background-image:
    linear-gradient(var(--bp-grid-minor) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-grid-minor) 1px, transparent 1px),
    linear-gradient(var(--bp-grid-major) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-grid-major) 1px, transparent 1px);
  background-size: 16px 16px, 16px 16px, 96px 96px, 96px 96px;
}
.st-mat {
  width: min(100%, 920px);
  background: var(--st-surf-4);
  border: 1px solid var(--st-line);
  border-radius: var(--bp-radius-sheet);
  box-shadow: var(--st-lift);
  padding: var(--sp-3);
}
.st-mat svg { display: block; width: 100%; height: auto; }
.st-mat-foot {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-4); padding: var(--sp-2) var(--sp-1) 0;
  border-top: 1px solid var(--st-line-soft); margin-top: var(--sp-2);
}

/* ═══════════════════════════════════════════════════════════════════════
   FILMSTRIP
   ═══════════════════════════════════════════════════════════════════════ */

.st-strip {
  height: var(--st-strip-h);
  background: var(--st-surf-1);
  border-top: 1px solid var(--st-line-hard);
  display: grid; grid-template-columns: 148px 1fr; align-items: stretch;
  min-width: 0;
}
.st-strip-head {
  display: grid; align-content: center; gap: 3px;
  padding: 0 var(--sp-3); border-right: 1px solid var(--st-line);
  min-width: 0;
}
.st-strip-title {
  font-size: 11.5px; font-weight: 500; letter-spacing: -.005em; color: var(--bp-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.st-strip-scroll {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: 0 var(--sp-3); overflow-x: auto; overscroll-behavior-x: contain;
  min-width: 0;
}
.st-tile {
  position: relative; flex: 0 0 auto; height: 72px; padding: 0; border: 0;
  /* The aspect ratio is declared by the deliverable and reserved the moment
     the job is enqueued, so nothing shifts when the image lands. */
  aspect-ratio: var(--a, 4/3);
  border: 1px solid var(--st-line); border-radius: 5px;
  background: var(--st-surf-2); overflow: hidden; cursor: pointer;
  transition: border-color var(--bp-dur-fast) var(--bp-ease-out);
}
.st-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
.st-tile-svg { width: 100%; height: 100%; display: block; overflow: hidden; }
.st-tile-svg svg { width: 100%; height: 100%; object-fit: cover; }
@media (hover: hover) and (pointer: fine) {
  .st-tile:hover { border-color: var(--bp-steel-soft); }
}
.st-tile[data-pinned="1"]::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: var(--bp-ink-navy); z-index: 2;
}
.st-tile-tag {
  position: absolute; right: 3px; bottom: 3px; z-index: 2;
  font-family: var(--font-mono); font-size: 8px; letter-spacing: .06em;
  padding: 1px 4px; border-radius: 2px;
  background: rgba(16,26,43,.74); color: #fff;
}
.st-tile-dot {
  position: absolute; left: 5px; top: 5px; z-index: 2;
  width: 5px; height: 5px; border-radius: 50%; background: var(--bp-steel-soft);
}
.st-tile-dot[data-s="session"] { background: transparent; box-shadow: inset 0 0 0 1px var(--bp-steel-soft); }
.st-tile-dot[data-s="approved"] { background: var(--bp-success); }

/* Skeleton. Shimmer alpha above ~.06 on dark reads as cheap; 1.8s is the
   sweet spot — 1s is frantic, 2.5s reads as stalled. */
.st-skel { position: relative; overflow: hidden; background: var(--st-surf-2); }
.st-skel::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(16,26,43,.05) 50%, transparent 80%);
  transform: translateX(-100%);
  animation: st-shimmer 1.8s linear infinite;
}
:root[data-theme="dark"] .st-skel::after {
  background: linear-gradient(100deg, transparent 20%, rgba(255,255,255,.045) 50%, transparent 80%);
}
@keyframes st-shimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .st-skel::after { animation: none; opacity: .5; } }

.st-strip-empty {
  display: grid; place-items: center; width: 100%; height: 100%;
  font-size: 11.5px; color: var(--bp-steel-soft);
}

/* ═══════════════════════════════════════════════════════════════════════
   OUTPUT DECK
   Not a toolbar. Every row is an output slot carrying its own state, which
   is the whole reason ten of them read as instrumentation rather than as a
   wall of buttons.
   ═══════════════════════════════════════════════════════════════════════ */

.st-deck {
  background: var(--st-surf-1);
  border-left: 1px solid var(--st-line-hard);
  display: grid; grid-template-rows: auto 1fr auto;
  min-height: 0;
}
.st-deck-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--st-line-hard);
}
.st-deck-scroll { overflow-y: auto; overscroll-behavior: contain; min-height: 0; }

.st-group + .st-group { border-top: 1px solid var(--st-line-hard); }
.st-group-head {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: var(--sp-4) var(--sp-4) var(--sp-2);
}
.st-group-count { font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em; color: var(--bp-steel-soft); }

/* Rows are full-bleed with the padding INSIDE the hit target, so there are
   no dead zones between them, and separated by hairlines rather than gaps:
   a gap between every row is what makes a stack of controls read as
   floating chiclets. */
.st-row { border-top: 1px solid var(--st-line-soft); }
.st-group .st-row:first-of-type { border-top: 0; }

.st-row-main {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) var(--st-status-w) 20px;
  align-items: center; gap: var(--sp-2);
  min-height: var(--st-row-h); padding: 0 var(--sp-3) 0 var(--sp-4);
  transition: background 100ms var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .st-row-main:hover { background: var(--st-surf-3); }
}
.st-row[data-avail="0"] .st-row-main { opacity: .66; }

.st-row-check {
  appearance: none; margin: 0; width: 16px; height: 16px; flex: 0 0 auto;
  border: 1px solid var(--st-line-hard); border-radius: 3px;
  background: var(--st-surf-3); cursor: pointer;
  display: grid; place-items: center;
  transition: background var(--bp-dur-fast) var(--bp-ease-out), border-color var(--bp-dur-fast) var(--bp-ease-out);
}
.st-row-check:checked { background: var(--bp-ink-navy); border-color: var(--bp-ink-navy); }
:root[data-theme="dark"] .st-row-check:checked { background: var(--bp-blueprint); border-color: var(--bp-blueprint); }
.st-row-check:checked::after {
  content: ""; width: 8px; height: 4px; margin-top: -2px;
  border-left: 1.6px solid #fff; border-bottom: 1.6px solid #fff;
  transform: rotate(-45deg);
}

.st-row-run {
  appearance: none; border: 0; background: transparent; padding: 6px 0;
  min-width: 0; text-align: left; color: inherit; display: grid; gap: 1px;
}
.st-row-label {
  font-size: 13px; font-weight: 450; letter-spacing: -.01em; color: var(--bp-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.st-row[data-avail="0"] .st-row-label { color: var(--bp-steel); }
.st-row-why {
  font-size: 10.5px; color: var(--bp-steel-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* The status column is a COLUMN, at a fixed width, so it can never shift
   the label as a job moves through its states. */
.st-status {
  width: var(--st-status-w); justify-self: end;
  display: flex; align-items: center; justify-content: flex-end; gap: 5px;
  font-family: var(--font-mono); font-size: 9px; font-weight: 500;
  letter-spacing: .09em; text-transform: uppercase;
  font-variant-numeric: tabular-nums; color: var(--bp-steel-soft);
}
.st-status-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--bp-steel-soft); opacity: .45; }
.st-status[data-s="queued"] .st-status-dot { opacity: .9; }
.st-status[data-s="done"] { color: var(--bp-steel); }
.st-status[data-s="failed"] { color: var(--bp-danger); }
.st-status-check { color: var(--bp-success); flex: 0 0 auto; }

/* The running arc is the ONLY accent-coloured pixel in the rail, and the
   rule is keyed on the deck's own [data-running] attribute so a second one
   is structurally impossible. */
.st-arc { display: block; transform: rotate(-90deg); flex: 0 0 auto; }
.st-arc circle { fill: none; stroke-width: 2; }
.st-arc-track { stroke: var(--st-line-hard); }
.st-arc-head { stroke: var(--bp-steel); transition: stroke-dashoffset 240ms var(--bp-ease-out); }
.st-deck[data-running] .st-row[data-running="1"] .st-arc-head { stroke: var(--bp-amber); }
.st-deck[data-running] .st-row[data-running="1"] .st-status { color: var(--bp-amber); }

.st-row-chev {
  appearance: none; border: 0; background: transparent; padding: 0;
  width: 20px; height: 20px; display: grid; place-items: center;
  color: var(--bp-steel-soft);
  transition: transform var(--bp-dur-fast) var(--bp-ease-out), color var(--bp-dur-fast) var(--bp-ease-out);
}
.st-row-chev[aria-expanded="true"] { transform: rotate(180deg); color: var(--bp-ink); }

/* Accordion. grid-template-rows 0fr → 1fr animates a height we never have
   to measure. Content opacity trails by 50ms so text does not smear. */
.st-row-body {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 200ms var(--bp-ease-out);
}
.st-row[data-open="1"] .st-row-body { grid-template-rows: 1fr; }
.st-row-body > div { overflow: hidden; }
.st-row-body-inner {
  padding: var(--sp-1) var(--sp-4) var(--sp-4) 40px;
  background: var(--st-surf-3);
  opacity: 0; transition: opacity 150ms 50ms var(--bp-ease-out);
}
.st-row[data-open="1"] .st-row-body-inner { opacity: 1; }
.st-param { display: grid; gap: 5px; margin-bottom: var(--sp-3); }
.st-param:last-child { margin-bottom: 0; }
.st-param-label {
  font-family: var(--font-mono); font-size: 8.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--bp-steel-soft);
}
.st-adv { margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid var(--st-line-soft); }
.st-adv summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between;
  font-size: 11px; color: var(--bp-steel);
}
.st-adv summary::-webkit-details-marker { display: none; }
/* A hidden parameter that silently changes the output is the worst property
   of progressive disclosure, so a non-default is announced on the closed
   header. */
.st-adv-mod { font-family: var(--font-mono); font-size: 8.5px; letter-spacing: .08em; color: var(--bp-steel-soft); }
.st-adv-body { padding-top: var(--sp-3); display: grid; gap: var(--sp-3); }

.st-deck-foot {
  border-top: 1px solid var(--st-line-hard);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  background: var(--st-surf-1);
  display: grid; gap: var(--sp-3);
}
.st-runsets { display: flex; flex-wrap: wrap; gap: 5px; }
.st-runset {
  appearance: none; height: 26px; padding: 0 10px;
  background: transparent; border: 1px solid var(--st-line-hard);
  border-radius: var(--bp-radius-pill);
  font-size: 11px; font-weight: 500; color: var(--bp-steel);
  transition: border-color var(--bp-dur-fast) var(--bp-ease-out), color var(--bp-dur-fast) var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .st-runset:hover { border-color: var(--bp-steel); color: var(--bp-ink); }
}
.st-runall {
  appearance: none; width: 100%; height: 38px;
  border: 1px solid transparent; border-radius: var(--bp-radius-control);
  background: var(--bp-amber); color: var(--bp-amber-ink);
  font-size: 13px; font-weight: 600; letter-spacing: -.01em;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.24), 0 1px 2px rgba(22,20,16,.16);
  transition: filter var(--bp-dur-fast) var(--bp-ease-out), transform var(--bp-dur-press) var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) { .st-runall:hover:not(:disabled) { filter: brightness(1.08); } }
.st-runall:active:not(:disabled) { transform: scale(.985); }
/* Disabled is not a faded accent — it is a different, quieter control.
   A washed-out amber slab is the loudest inert thing on the screen. */
.st-runall:disabled {
  background: transparent; color: var(--bp-steel-soft);
  border-color: var(--st-line); box-shadow: none;
  cursor: not-allowed; filter: none; font-weight: 500;
}
/* While anything runs, the primary drops to an outline so the running arc
   keeps the one accent. */
.st-deck[data-running] .st-runall {
  background: transparent; color: var(--bp-steel);
  border-color: var(--st-line-hard); box-shadow: none;
}
.st-deck-status {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--bp-steel-soft);
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
}
.st-linkbtn {
  appearance: none; border: 0; background: transparent; padding: 0;
  font-family: inherit; font-size: inherit; letter-spacing: inherit;
  text-transform: inherit; color: var(--bp-steel);
  text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}
@media (hover: hover) and (pointer: fine) { .st-linkbtn:hover { color: var(--bp-ink); } }
.st-deck-note {
  font-size: 11px; line-height: 1.45; color: var(--bp-steel-soft);
  border-top: 1px solid var(--st-line-soft); padding-top: var(--sp-2);
}

/* ═══════════════════════════════════════════════════════════════════════
   THE CALM PASS
   The first build put everything on screen at full weight at once, and it
   read as cluttered even though nothing on it was wrong. Nothing below is
   removed — things are given a resting weight and a reveal.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Spec lines ────────────────────────────────────────────────────────
   A value, not a form field, until you click it. Three permanently open
   textareas gave twenty readings the visual weight of one edit. */

.st-spec-sect + .st-spec-sect { border-top: 1px solid var(--st-line); }
.st-spec-type {
  font-size: 12.5px; font-weight: 550; letter-spacing: -.01em;
  color: var(--bp-ink); margin-bottom: var(--sp-3);
}
.st-line { display: grid; gap: 1px; margin-bottom: var(--sp-3); }
.st-line:last-child { margin-bottom: 0; }
.st-line-label {
  font-family: var(--font-mono); font-size: 8.5px; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--bp-steel-soft);
}
.st-line-value {
  appearance: none; border: 0; background: transparent;
  padding: 2px 6px 3px; margin-left: -6px; width: calc(100% + 12px);
  border-radius: 4px; text-align: left; cursor: text;
  font: inherit; font-size: 12px; line-height: 1.45; color: var(--bp-ink);
  transition: background 100ms var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .st-line-value:hover { background: var(--st-surf-3); }
}
.st-spec .st-textarea { font-size: 12px; min-height: 54px; }

/* ── Collapsing groups ─────────────────────────────────────────────────
   You are selling or you are permitting, rarely both in the same minute.

   The 0fr -> 1fr trick needs ONE child that clips. Without the wrapper
   every row becomes a grid item in the same single row and they draw on
   top of each other — which is exactly what shipped in the first pass. */

.st-group-head {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-4);
  transition: background 100ms var(--bp-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .st-group-head:hover { background: var(--st-surf-2); }
}
.st-group-right { display: flex; align-items: center; gap: var(--sp-2); }
.st-group-chev {
  color: var(--bp-steel-soft);
  transition: transform var(--bp-dur-fast) var(--bp-ease-out);
}
.st-group[data-open="1"] .st-group-chev { transform: rotate(180deg); }
.st-group-rows {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 200ms var(--bp-ease-out);
}
.st-group[data-open="1"] .st-group-rows { grid-template-rows: 1fr; }
.st-group-rows-inner { overflow: hidden; min-height: 0; }

/* ── Selection is a mode, not a permanent row of boxes ─────────────────
   The checkbox keeps its column, so nothing shifts when it appears. */

.st-row-check { opacity: 0; transition: opacity var(--bp-dur-fast) var(--bp-ease-out); }
.st-deck[data-select="1"] .st-row-check,
.st-row-main:hover .st-row-check,
.st-row-check:focus-visible,
.st-row-check:checked { opacity: 1; }

/* ── The filmstrip collapses when it has nothing to show ───────────────
   An empty 104px band announcing that it is empty is the most expensive
   way to say nothing. */

.st-strip { transition: height 200ms var(--bp-ease-out); }
.st-strip[data-empty="1"] { height: 38px; }
.st-strip[data-empty="1"] .st-strip-scroll { display: none; }
.st-strip[data-empty="1"] .st-strip-title { display: none; }
.st-strip[data-empty="1"] .st-strip-head { border-right: 0; width: auto; }

/* ── Site photo, offered by the row that needs it ──────────────────── */

.st-sitephoto {
  appearance: none; width: 100%; height: 30px;
  background: transparent; border: 1px solid var(--st-line-hard);
  border-radius: var(--bp-radius-control);
  font-size: 11.5px; font-weight: 500; color: var(--bp-steel);
}

/* ── The ground stops competing ────────────────────────────────────────
   Two grids behind a drawing is one grid too many, and texture behind the
   thing you are judging is noise. One faint grid, wide enough to read as
   a ground rather than a pattern. */

.st-canvas {
  background-image:
    linear-gradient(var(--bp-grid-minor) 1px, transparent 1px),
    linear-gradient(90deg, var(--bp-grid-minor) 1px, transparent 1px);
  background-size: 120px 120px, 120px 120px;
}

/* The ft-in readout under a dimension is a confirmation, not a label. */
.st-dim-ftin { opacity: .72; }

/* ═══════════════════════════════════════════════════════════════════════
   THE APP SHELL
   index.html keeps its own top bar and slide-over panels; the studio,
   fabrication and package sections sit beneath them in this grid.
   ═══════════════════════════════════════════════════════════════════════ */

.bp-app {
  height: 100dvh;
  display: grid; grid-template-rows: auto 1fr;
  background: var(--st-surf-0);
}
.bp-main { min-height: 0; display: grid; }
.bp-main > section { min-height: 0; }

/* Fabrication has no Output Deck: the sheets are the output, and they are
   computed, not generated. */
.st-work-fab {
  grid-template-columns: var(--st-signrail-w) 264px 1fr;
  grid-template-areas: "signs spec stage";
}

/* The package is a book, so it scrolls where the studio does not. */
#bp-package { overflow-y: auto; padding-bottom: var(--sp-9); }

/* The design bar keeps its own look; the grid only gives it a row. */
.bp-design-bar { flex: 0 0 auto; }

/* The caption under the drawing sits on the mat, matching the sheet foot. */
.bp-canvas-caption {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--sp-4); padding: var(--sp-2) var(--sp-1) 0;
  border-top: 1px solid var(--st-line-soft); margin-top: var(--sp-2);
  font-size: 12.5px; color: var(--bp-steel);
}
.bp-canvas-caption b { color: var(--bp-ink); font-weight: 550; }

/* The empty state lives on the canvas, not on a sheet. */
.st-canvas .bp-empty { max-width: 420px; text-align: center; }

/* Shop sheets are 1190px of paper. Actual size drops them to 1:1 in a
   scroll frame rather than squeezing them into the column. */
#bp-fab-mat.bp-mat-scroll { width: 100%; max-width: none; overflow: auto; }
#bp-fab-mat.bp-mat-scroll .bp-engine-sheet { width: 1190px; }

/* The sheet list in fabrication is a list of rows, not chips. */
.st-sheetrow {
  appearance: none; width: 100%; border: 0; background: transparent;
  display: grid; grid-template-columns: 26px 1fr; align-items: center; gap: var(--sp-2);
  padding: 9px var(--sp-4); text-align: left; cursor: pointer;
  border-top: 1px solid var(--st-line-soft);
  transition: background 100ms var(--bp-ease-out);
}
.st-spec .st-sheetrow:first-of-type { border-top: 0; }
@media (hover: hover) and (pointer: fine) {
  .st-sheetrow:hover { background: var(--st-surf-3); }
}
.st-sheetrow[aria-selected="true"] { background: var(--st-surf-3); }
.st-sheetrow[aria-selected="true"] .st-sheetrow-name { color: var(--bp-ink); font-weight: 550; }
.st-sheetrow-num {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .06em;
  color: var(--bp-steel-soft);
}
.st-sheetrow-name {
  font-size: 12.5px; letter-spacing: -.005em; color: var(--bp-steel);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ═══════════════════════════════════════════════════════════════════════
   THE SIGN-IN GATE
   Painted over the app from the first frame and removed only once a session
   resolves. A signed-in reload must never flash the login form, and a
   signed-out one must never flash the studio with the last project still on
   the canvas.
   ═══════════════════════════════════════════════════════════════════════ */

.bp-gate {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center;
  padding: var(--sp-5);
  background: var(--st-surf-0);
  overflow-y: auto;
}
.bp-gate[hidden] { display: none !important; }

.bp-gate-inner { width: 100%; max-width: 340px; display: grid; gap: var(--sp-5); }

.bp-gate-brand { display: flex; align-items: center; gap: var(--sp-3); justify-content: center; }
.bp-gate-name {
  font-size: 19px; font-weight: 650; letter-spacing: -.025em;
  line-height: 1.1; color: var(--bp-ink);
}
.bp-gate-tag {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--bp-steel-soft); line-height: 1.5;
}

.bp-gate-card {
  display: grid; gap: 6px;
  padding: var(--sp-5);
  background: var(--st-surf-2);
  border: 1px solid var(--st-line);
  border-radius: var(--bp-radius-card);
  box-shadow: var(--st-lift);
}
.bp-gate-card .bp-field-label { margin-top: var(--sp-2); }
.bp-gate-card .bp-field-label:first-child { margin-top: 0; }
.bp-gate-card .bp-btn { margin-top: var(--sp-4); width: 100%; justify-content: center; }

.bp-gate-error {
  margin: var(--sp-2) 0 0; min-height: 17px;
  font-size: 12px; line-height: 1.4; color: var(--bp-danger); text-align: center;
}
.bp-gate-alt {
  margin: var(--sp-2) 0 0;
  font-size: 11.5px; line-height: 1.5; color: var(--bp-steel-soft); text-align: center;
}
.bp-gate-alt a { color: var(--bp-steel); text-underline-offset: 2px; }

.bp-gate-wait {
  margin: 0; text-align: center;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--bp-steel-soft);
}
.bp-gate-wait[hidden] { display: none !important; }

/* Save state. It reports what is true and takes no action, so it is a line of
   text and not a control. */
.bp-save-state {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--bp-steel-soft);
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
}
.bp-save-state[data-s="error"] { color: var(--bp-danger); }

/* The demo marker. Quiet, but never absent: somebody being shown this should
   not have to guess whether their work is going anywhere. */
.bp-demo-chip {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--bp-steel);
  padding: 4px 9px; border-radius: var(--bp-radius-pill);
  border: 1px solid var(--st-line-hard); background: var(--st-surf-2);
  white-space: nowrap;
}
.bp-demo-chip[hidden] { display: none !important; }
