@import url("./studio2-intake.css");
@import url("./studio2-information.css");
/* Studio 2 — the Darkroom.
   Law: MASTER-PROMPT-STUDIO2-DARKROOM.md. Boards: docs/design/studio-darkroom
   (Main.dc.html = state 1 at rest, After.dc.html = state 2 the moment after).
   Phase 1 builds the desk only; zoom, marks, the list and the phone are
   phases 2 to 5 and their hooks are marked below.

   The look, locked: every control is a pill (radius 999) or a plain word.
   No four-sided bordered boxes, no dashed placeholders, no icons, no green,
   no status dots, no helper copy. Copper touches the one primary pill, the
   rail bar, the progress fills and (phase 2) the rings.

   Box-sizing note: admin.css sets `* { box-sizing: border-box }` globally and
   the Darkroom inherits it. The boards are content-box, so every height here
   is the board's number PLUS its border (pill 52+2 = 54, chip 34+2 = 36,
   strip 88+1 = 89). BUILD-MAP section 2.1. */

/* The two faces, self-hosted beside the shell's other five. The admin never
   makes an external font request (admin.css:19-57 states that law). The
   Manrope file is Google's variable one, so a single face serves 400/500/600. */
@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("./fonts/instrument-serif-400.woff2") format("woff2");
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("./fonts/manrope-variable.woff2") format("woff2");
}

.dk {
  --dk-bg: #0c0b0a;         /* ground, warm near-black, never pure black */
  --dk-hair: #1d1a18;       /* the strip's top hairline */
  --dk-hair2: #2a2624;      /* pill borders, the words underline, the track */
  --dk-surf: #141210;       /* the zoom bar (phase 2) */
  --dk-sel: #1f1b18;        /* picked-chip fill */
  --dk-copper: #d9a06e;
  --dk-copper-ink: #1a120b;
  --dk-text: #efe9e1;
  --dk-muted: #9a938a;
  --dk-dim: #6f6961;
  --dk-sans: "Manrope", "Segoe UI", system-ui, sans-serif;
  --dk-serif: "Instrument Serif", Georgia, serif;
  /* The header's height (Wave 2, item 9): the strip moved to the top of the
     room, and the drawer's edge moves down by exactly this. */
  --dk-head: 64px;

  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  background: var(--dk-bg);
  color: var(--dk-text);
  font-family: var(--dk-sans);
  font-size: 15px;
  -webkit-font-smoothing: antialiased;
}

/* The shell's own img rule caps pictures at 100% of their box; the render is
   deliberately taller than the stage. */
.dk img { max-width: none; }

/* MEASURED 2026-09-05, and it cost an hour: admin.css:6188 gives EVERY element
   a forced `transition-duration: .01ms` under prefers-reduced-motion, and
   the initial `transition-property` is `all` — so the zoom transform, the mark
   layer's box and every badge position became transitioned properties. A
   transition in the animation origin outranks an inline style, so with the
   document timeline stalled (a hidden tab, a backgrounded pane) the render
   stayed pinned at scale 1 while its inline transform read 2.7x. Duration
   cannot win against a forced declaration; the PROPERTY list can, and nothing
   in this room is ever meant to ease anywhere.
   The same stall makes the room unmeasurable: a class flip on a word stays
   pinned to its old colour, so the picked tool and the lit zoom stop read as
   the previous ones. Every element whose state is a class flip is on this
   list for that reason; nothing here was ever meant to ease. */
.dk-render,
.dk-view,
.dk-marklayer,
.dk-rings,
.dk-badge,
.dk-map-over,
.dk-tool,
.dk-zoomstop,
.dk-chip,
.dk-pill,
.dk-words,
.dk-chips,
.dk-list,
.dk-tab,
.dk-row,
.dk-rowact,
.dk-card,
.dk-uploading,
.dk-none-word,
.dk-count { transition-property: none; }

/* :where() so this reset carries NO specificity — a plain .dk-pill / .dk-chip
   class below must win on padding, border and background, and a type selector
   would quietly outrank it. */
:where(.dk button) {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  margin: 0;
  padding: 0;
  text-align: inherit;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

/* Keyboard focus is a mark, never a box. Only the pills and the chips are
   radius-999 controls an outline can follow; the rail thumb takes the board's
   own 2 px copper bar (Main.dc.html, left:-12 top:26 2x44) and Undo takes an
   underline. A 1 px outline on a radius-0 button is a four-sided bordered
   box — banned. The words line takes NO focus mark: Markup.dc.html draws it
   mid-sentence with its hairline still #2a2624 and the copper caret doing the
   work, and a 400 px hairline lifted to text colour was the brightest line on
   the screen (judged 2026-09-05). */
.dk-pill:focus-visible,
.dk-chip:focus-visible { outline: 1px solid var(--dk-hair2); outline-offset: 3px; }

/* Every plain word that acts takes the same mark as Undo: an underline, never
   a box. The UA's own focus ring on a radius-0 word is a four-sided border. */
.dk-count:focus-visible,
.dk-tab:focus-visible,
.dk-rowact:focus-visible,
.dk-none-word:focus-visible,
.dk-tool:focus-visible,
.dk-zoomstop:focus-visible,
.dk-close:focus-visible,
.dk-stop:focus-visible {
  outline: none;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.dk-thumb:focus-visible { outline: none; }
.dk-thumb:focus-visible::after {
  content: "";
  position: absolute;
  left: -12px;
  top: 26px;
  width: 2px;
  height: 44px;
  background: var(--dk-copper);
  border-radius: 2px;
}

.dk-undo:focus-visible {
  outline: none;
  text-decoration: underline;
  text-underline-offset: 3px;
}


/* ── the desk ───────────────────────────────────────────────────────────── */

.dk-desk {
  display: flex;
  flex: 1;
  min-height: 0;
  padding: 34px 44px 0 40px;
  gap: 30px;
  align-items: flex-start;
}

/* ── the rail ───────────────────────────────────────────────────────────── */

.dk-rail {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 96px;            /* 84 + the 12 of padding the copper bar hangs in */
  padding: 0 0 0 12px;
  flex: none;
  align-self: stretch;
  position: relative;
  overflow: hidden;
}

.dk-thumb {
  position: relative;
  width: 72px;
  height: 96px;
  flex: none;
  display: block;
}

.dk-thumb-img,
.dk-station-img {
  display: block;
  object-fit: cover;
  /* feather(30, 8, 22) — two intersected linear masks, never a radial oval.
     Both spellings, webkit first, or Safari drops the second layer. */
  -webkit-mask-image:
    linear-gradient(to right, rgba(0, 0, 0, 0) 0%, #000 30%, #000 70%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #000 8%, #000 78%, rgba(0, 0, 0, 0) 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, rgba(0, 0, 0, 0) 0%, #000 30%, #000 70%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #000 8%, #000 78%, rgba(0, 0, 0, 0) 100%);
  mask-composite: intersect;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

.dk-thumb-img { width: 72px; height: 96px; opacity: .38; }
.dk-thumb.is-current .dk-thumb-img { opacity: 1; }

/* The map (zoom only, the current thumb only): the whole thumb at 32 per cent
   with the part he is looking at at 100. No stroke anywhere — and in map mode
   the current thumb's ground copy is deliberately DIMMER than its neighbours,
   so the bright patch is the only thing the eye lands on. */
.dk-thumb.is-current .dk-map-under { opacity: .32; }
.dk-thumb.is-current .dk-map-over {
  position: absolute;
  left: 0;
  top: 0;
  opacity: 1;
}

.dk-rail-bar {
  position: absolute;
  left: -12px;
  top: 26px;
  width: 2px;
  height: 44px;
  background: var(--dk-copper);
  border-radius: 2px;
}

.dk-rail-fade {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 110px;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(12, 11, 10, 0) 0%, #0c0b0a 85%);
}

/* A thumb whose artifact is missing leaves a hole in the ground, never a
   broken-image icon and never a dashed box. It holds the same 72 x 96 slot the
   thumb had and carries the bottle's name, so the rail still reads as a rail
   (pass two, item 1: it used to collapse to 0 x 0 and leave a bare copper
   bar). Two lines, then the name is clipped.
   The mask and the opacity are reset on purpose: this is text, not a picture,
   and .dk-thumb-img's feather would fade the first and last 21 px of every
   line to nothing while its .38 dim put the name at about 1.8:1 on the ground.
   The class is stripped in phClass() too — this is the belt to that brace.
   The dim-then-lit step is in COLOUR, not opacity (judges' round, 2026-09-05):
   a flat opacity 1 painted a name slot that is NOT the picked bottle at the
   same strength as the picked one, and brighter than the real thumbs beside it
   at .38, so on a rail where several bottles have no thumb the eye landed on
   the wrong slots. Dim on the ground is about 3.6:1, the text colour about
   14:1, and the 2 px copper bar is no longer the only current-marker. */
.dk-thumb-ph {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  width: 72px;
  height: 96px;
  padding: 2px 3px;
  overflow: hidden;
  font-size: 13px;
  font-weight: 500;
  line-height: 17px;
  color: var(--dk-dim);
  text-overflow: ellipsis;
  opacity: 1;
  -webkit-mask-image: none;
  mask-image: none;
}

.dk-thumb.is-current .dk-thumb-ph { color: var(--dk-text); }

/* ── the stage ──────────────────────────────────────────────────────────── */

.dk-stage {
  flex: 1;
  min-width: 0;
  align-self: stretch;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: radial-gradient(ellipse 56% 40% at 50% 84%, #211b16 0%, #151210 34%, #0c0b0a 70%);
}

/* No picture for this try (pass two, items 1 and 7). The warm pool and the
   floor are the light under a bottle; with no bottle they read as a brown
   smear across a black void, so both stand down and the stage is plain
   ground with three lines on it. */
.dk-stage.is-empty { background: var(--dk-bg); }
.dk-stage.is-empty .dk-floor { display: none; }

/* The three lines sit where the bottle's shoulders would be — the upper third,
   left of centre on the render's own column. No box, no rule, no pill. */
.dk-none {
  position: absolute;
  left: 14%;
  top: 26%;
  right: 14%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}

.dk-none-head {
  font-size: 15px;
  font-weight: 600;
  color: var(--dk-text);
}

.dk-none-why {
  font-size: 15px;
  font-weight: 500;
  color: var(--dk-muted);
  /* 44, not 34: job 27's line is 40 characters and "three lines and nothing
     else" folded to four at the tighter cap. */
  max-width: 44ch;
}

.dk-none-word {
  font-size: 15px;
  font-weight: 600;
  color: var(--dk-text);
}

/* The render's own viewport. It exists so the zoom crop feather can sit on the
   STAGE: a mask on the picture scales with the transform, so at Actual its
   fade would be off the screen and the crop would read as a hard rectangle. */
.dk-view {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  overflow: hidden;
}

/* Past Fit the picture fills the stage, so the feather moves here — the
   zoom crop, feather(20, 16, 18) (Zoom.dc.html) — and the picture's own
   feather stands down rather than fading a second time. */
.dk-view.is-crop {
  -webkit-mask-image:
    linear-gradient(to right, rgba(0, 0, 0, 0) 0%, #000 20%, #000 80%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #000 16%, #000 82%, rgba(0, 0, 0, 0) 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, rgba(0, 0, 0, 0) 0%, #000 20%, #000 80%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #000 16%, #000 82%, rgba(0, 0, 0, 0) 100%);
  mask-composite: intersect;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

.dk-view.is-crop .dk-render {
  -webkit-mask-image: none;
  mask-image: none;
}

/* Wave 3 (2026-09-09): the source photo shows whole. The render fit above is
   built for a 3:4 render standing on the floor; a square shop photo at that
   height runs off both sides and a phone snap loses its cap. With the
   original up the picture fits inside the stage on both axes, centred, at
   Fit (setOriginal puts the zoom back to Fit, so the inline transform is the
   identity), with no feather taking its edges. */
.dk-stage.is-original .dk-view {
  align-items: center;
}
.dk-stage.is-original .dk-view,
.dk-stage.is-prepared .dk-view {
  top: 62px;
  bottom: 76px;
}
.dk-stage.is-original,
.dk-stage.is-prepared {
  background-color: #42454a;
  background-image:
    linear-gradient(45deg, #4b4e53 25%, transparent 25%, transparent 75%, #4b4e53 75%),
    linear-gradient(45deg, #4b4e53 25%, transparent 25%, transparent 75%, #4b4e53 75%);
  background-position: 0 0, 10px 10px;
  background-size: 20px 20px;
}
.dk-stage.is-original .dk-floor,
.dk-stage.is-prepared .dk-floor { display: none; }
.dk-stage.is-original .dk-view.is-crop,
.dk-stage.is-prepared .dk-view.is-crop {
  -webkit-mask-image: none;
  mask-image: none;
}
.dk-stage.is-original .dk-render {
  height: auto;
  width: auto;
  max-width: 100%;
  max-height: 100%;
  margin-bottom: 0;
  -webkit-mask-image: none;
  mask-image: none;
  filter: none;
}

.dk-stage.is-prepared .dk-view { align-items: center; }
.dk-stage.is-prepared .dk-render {
  height: auto;
  width: auto;
  max-width: 100%;
  max-height: 100%;
  margin-bottom: 0;
  -webkit-mask-image: none;
  mask-image: none;
  filter: none;
}

.dk-render {
  height: auto;
  width: auto;
  max-width: 100%;
  max-height: 100%;
  display: block;
  margin-bottom: 0;
  flex: none;
  /* Fit is the identity transform and every stop grows out of the spot the
     bottle already stands on: the floor, centred. */
  transform-origin: 50% 100%;
  /* The board's renders were lifted by prep.py's desk_black(bp=8.0): the
     render's darkest pixel is remapped onto the ground colour so the photo's
     own frame can never read darker than the desk. The render itself is never
     edited (the law) — the same arithmetic runs here, built in studio2.js. */
  filter: url(#dk-desk-black);
  /* feather(32, 0, 14). The top stop is hard on purpose — the bottle's top is
     already outside the stage. The black point sits on the ground colour, so
     the photo's own frame never shows. */
  -webkit-mask-image:
    linear-gradient(to right, rgba(0, 0, 0, 0) 0%, #000 32%, #000 68%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom, rgba(0, 0, 0, 1) 0%, #000 0%, #000 86%, rgba(0, 0, 0, 0) 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(to right, rgba(0, 0, 0, 0) 0%, #000 32%, #000 68%, rgba(0, 0, 0, 0) 100%),
    linear-gradient(to bottom, rgba(0, 0, 0, 1) 0%, #000 0%, #000 86%, rgba(0, 0, 0, 0) 100%);
  mask-composite: intersect;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

.dk-floor {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 120px;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(12, 11, 10, 0) 0%, #0c0b0a 100%);
}

/* The mark layer is kept exactly over the render's own box by
   attachOverlayLayout() in studio2.js — through every resize, every zoom step
   and every picture swap — so a ring recorded in render pixels lands on the
   same pixel at every stage size. */
.dk-marklayer {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}
/* The viewBox is render pixels, so the circles are written in render pixels
   and scale for free; the halo needs to draw outside the box. */
.dk-rings { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.dk-badges { position: absolute; inset: 0; }

/* The number on the rim. HTML, never scaled, and the 3 px ring of ground
   punches a clean hole in the copper line it sits on. */
.dk-badge {
  position: absolute;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: var(--dk-copper);
  color: var(--dk-copper-ink);
  font-size: 12px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 3px var(--dk-bg);
}

/* Marking is a crosshair, panning a hand. Cursors are not icons. */
.dk-stage.is-mark { cursor: crosshair; }
.dk-stage.is-pan { cursor: grab; }
.dk-stage.is-panning { cursor: grabbing; }

.dk-tools {
  position: absolute;
  top: 22px;
  right: 26px;
  display: flex;
  gap: 16px;
  align-items: baseline;
}

.dk-toolgroup { display: flex; align-items: baseline; gap: 16px; }
.dk-inspect-tools { padding-left: 16px; border-left: 1px solid var(--dk-hair2); }
.dk-source-tools { gap: 12px; }

.dk-tool {
  font-size: 13px;
  font-weight: 500;
  color: var(--dk-muted);
  padding-bottom: 4px;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
}

/* Undo belongs to the inspection group and appears only once a ring exists. */
.dk-tool-undo { margin-left: 2px; }

.dk-tool.is-on {
  font-weight: 600;
  color: var(--dk-text);
  border-bottom: 1px solid var(--dk-text);
  padding-bottom: 3px;
}

.dk-view-caption {
  position: absolute;
  left: 24px;
  bottom: 24px;
  max-width: 38ch;
  margin: 0;
  padding: 7px 10px;
  color: #f2f2f2;
  background: rgba(20, 22, 25, .88);
  font-size: 12px;
  line-height: 1.35;
  pointer-events: none;
}

/* ── the zoom bar (state 3) ─────────────────────────────────────────────── */
/* The picked stop differs by COLOUR only — no fill, no underline, no copper.
   Height 42 = the board's 40 plus its border, the box-sizing rule above. */
.dk-zoombar {
  position: absolute;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  height: 42px;
  display: flex;
  align-items: center;
  border-radius: 999px;
  background: rgba(20, 18, 16, .85);
  border: 1px solid var(--dk-hair2);
  padding: 0 6px;
}

.dk-zoomstop {
  padding: 0 14px;
  font-size: 13px;
  font-weight: 600;
  color: var(--dk-muted);
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
}

.dk-zoomstop.is-on { color: var(--dk-text); }

/* ── the column ─────────────────────────────────────────────────────────── */

.dk-col {
  width: 400px;
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 26px;
  padding-top: 78px;
}

/* The board's name block is 78 px tall (serif 48.96 + gap 8 + meta 21) and the
   decide row sits 26 below it at y 215.95. A real bottle's name is longer than
   the board's two words and wraps, so the box keeps the board's height and
   packs its content at the bottom: a second serif line grows UP into the
   column's own 78 px of top padding and nothing below the name ever moves. */
.dk-name {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 8px;
  height: 78px;
  flex: none;
}

.dk-serif {
  font-family: var(--dk-serif);
  font-size: 48px;
  line-height: 1.02;
  letter-spacing: -.005em;
  color: var(--dk-text);
}

.dk-meta { font-size: 15px; font-weight: 500; color: var(--dk-muted); }

.dk-decide { display: flex; gap: 10px; }

.dk-pill {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 54px;
  padding: 0 26px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .01em;
  background: transparent;
  color: var(--dk-text);
  border: 1px solid var(--dk-hair2);
  white-space: nowrap;
  flex: none;
}

.dk-pill.is-primary {
  background: var(--dk-copper);
  color: var(--dk-copper-ink);
  border-color: var(--dk-copper);
}

.dk-pill.is-small { height: 42px; padding: 0 18px; font-size: 13px; }
.dk-pill.is-wide { width: 100%; }

.dk-key { font-size: 13px; font-weight: 500; margin-left: 8px; color: var(--dk-dim); }
.dk-pill.is-primary .dk-key { color: rgba(26, 18, 11, .55); }

.dk-words {
  padding: 0 0 4px;
  font-size: 15px;
}

.dk-wordslabel { display: block; margin-bottom: 8px; font-weight: 600; }
.dk-reject-actions { display: flex; gap: 10px; margin-top: 12px; }

/* Wave 3 (2026-09-09): a box he can see. Six rejects went out with no words
   because the line under the chips read as decoration ("I didn't see a spot
   to"). Hairline all round, room to tap, sharp corners (DESIGN-RULES). */
.dk-wordsinput {
  display: block;
  width: 100%;
  box-sizing: border-box;
  min-height: 92px;
  line-height: 1.45;
  padding: 10px 12px;
  border: 1px solid var(--dk-hair2);
  background: none;
  color: var(--dk-text);
  font-family: inherit;
  font-size: 15px;
  font-weight: 400;
  caret-color: var(--dk-copper);
  outline: none;
}

.dk-wordsinput::placeholder { color: var(--dk-dim); opacity: 1; }
.dk-wordsinput:focus { border-color: var(--dk-copper); }

/* ── the numbered list (state 4) ────────────────────────────────────────── */
/* One row per ring: its number, the line he types or dictates, and the ×
   that removes it. The picture carries the ring and the number, never words. */
.dk-marklist { display: flex; flex-direction: column; gap: 12px; }

.dk-markrow { display: flex; gap: 12px; align-items: flex-start; }

.dk-num {
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: var(--dk-copper);
  color: var(--dk-copper-ink);
  font-size: 12px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}

/* No box, no border, no placeholder, no label — a new ring simply opens a new
   row with the caret already in it. The caret here is text colour; the
   "your words" caret below the chips is the copper one. */
.dk-marktext {
  flex: 1;
  min-width: 0;
  height: auto;
  padding: 1px 0 0;          /* the board's own padding-top on the row's text */
  border: 0;
  background: none;
  color: var(--dk-text);
  caret-color: var(--dk-text);
  font-family: inherit;
  font-size: 15px;
  line-height: 1.45;         /* 21.75 px, measured off Markup.dc.html */
  font-weight: 400;
  outline: none;
}

/* The character U+00D7, plain — not an icon, not a bordered button. */
.dk-x {
  font-size: 15px;
  line-height: 1.45;
  color: var(--dk-dim);
  padding: 1px 4px 0;
  flex: none;
}

.dk-x:focus-visible {
  outline: none;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── the strip ──────────────────────────────────────────────────────────── */

/* The strip is the HEADER (Wave 2, item 9: "put needs photo, held, nothing
   running in the header, not the bottom"): the back word, the receipt, the
   robot's word and its stations, and the three counts on the right. Its
   hairline is under it now. */
.dk-strip {
  display: flex;
  align-items: center;
  gap: 24px;
  height: var(--dk-head);
  padding: 0 44px;
  border-bottom: 1px solid var(--dk-hair);
  flex: none;
}

/* The way back to the admin room (Wave 2, item 8), the first word in the
   header: muted like a tool, bright on hover, never a box. */
.dk-back {
  font-size: 13px;
  font-weight: 500;
  color: var(--dk-muted);
  white-space: nowrap;
  cursor: pointer;
  padding: 0;
  margin-right: 8px;
  background: none;
  border: 0;
  font-family: inherit;
}
.dk-back:hover { color: var(--dk-text); }
.dk-back:focus-visible { outline: 1px solid var(--dk-hair2); outline-offset: 3px; }

.dk-receipt { font-size: 15px; font-weight: 500; color: var(--dk-text); white-space: nowrap; }
.dk-undo { font-size: 15px; font-weight: 600; color: var(--dk-text); }

.dk-receipt-div {
  display: block;
  width: 1px;
  height: 22px;
  background: var(--dk-hair2);
  margin: 0 4px;
  flex: none;
}

.dk-running {
  font-size: 13px;
  font-weight: 500;
  color: var(--dk-dim);
  margin-right: -6px;
  white-space: nowrap;
}

.dk-stations { display: flex; align-items: center; gap: 24px; }
.dk-station { display: flex; flex-direction: column; gap: 6px; align-items: center; }
.dk-station-img { width: 30px; height: 40px; }
.dk-station-ph { width: 30px; height: 40px; }

.dk-track {
  width: 30px;
  height: 2px;
  background: var(--dk-hair2);
  border-radius: 2px;
  overflow: hidden;
}

.dk-fill {
  height: 2px;
  background: var(--dk-copper);
  animation: dk-breathe 2.4s ease-in-out infinite;
}

@keyframes dk-breathe {
  0%, 100% { opacity: .45; }
  50% { opacity: 1; }
}

.dk-counts { margin-left: auto; display: flex; align-items: center; gap: 32px; }
.dk-queue-open { min-height: 44px; padding-inline: 20px; white-space: nowrap; }
.dk-queue-open .dk-count-n { color: inherit; margin-left: 8px; }

.dk-count { font-size: 15px; font-weight: 400; color: var(--dk-muted); white-space: nowrap; }
.dk-count-n { font-weight: 600; color: var(--dk-text); }
/* Copper is only the primary pill and the marks (the master prompt's locked
   look). An open count is marked the way an on tool is: the text-colour
   underline. Phase 3 turns this class on. */
.dk-count.is-open .dk-count-n { border-bottom: 1px solid var(--dk-text); }

/* ── the list (state 5) ────────────────────────────────────────────────── */
/* The queue uses the room below its heading. No scrim or modal: Close queue
   returns to the same review bottle and unsent feedback. */
.dk-list {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--dk-head);
  bottom: 0;
  z-index: 1;
  background: var(--dk-bg);
  border-top: 1px solid var(--dk-hair2);
  padding: 20px 40px 0;
  display: flex;
  flex-direction: column;
}

/* A tool he cannot reach past the drawer is clutter (BUILD-MAP 8.7, and the
   board draws no tools on state 5). */
.dk.is-listopen .dk-tools { display: none; }

/* The chips sit at y 296 and are 76 tall, so with the drawer's edge at y 300
   the top 4 px of Edges / Foggy glass / The floor / The cap showed above the
   hairline as four cut-off curved nubs (measured 2026-09-05). RunList.dc.html
   draws no chips at all, the same argument as the tools above.
   `visibility`, not `display`: the column is a flex stack with a 26 px gap, so
   removing the chips from the flow would pull the words line UP into the same
   4 px and simply change which element pokes out. */

.dk-tabs {
  display: flex;
  gap: 26px;
  overflow-x: auto;
  align-items: flex-end;
  border-bottom: 1px solid var(--dk-hair);
  flex: none;
}

/* A narrow desktop panel must still expose every queue tab without a
   horizontal scrollbar. Phone styling keeps its existing compact behavior. */
.dk:not(.is-phone) .dk-tabs {
  flex-wrap: wrap;
  overflow-x: visible;
  row-gap: 0;
}

/* The picked tab is text colour and underlined in text colour — never copper
   (the locked look keeps copper for the primary pill and the marks). The 11 +
   1 px of the underlined tab equals the 12 px of the others, so every word
   sits on the same baseline. */
.dk-tab {
  min-height: 44px;
  font-size: 15px;
  font-weight: 600;
  color: var(--dk-muted);
  padding-bottom: 12px;
  white-space: nowrap;
}

.dk-tab.is-on {
  color: var(--dk-text);
  border-bottom: 1px solid var(--dk-text);
  padding-bottom: 11px;
}

.dk-tab-n { font-weight: 500; color: var(--dk-muted); }

.dk-queuetable { position: relative; display: flex; flex: 1; min-height: 0; flex-direction: column; overflow-x: auto; overflow-y: hidden; scrollbar-color: var(--dk-hair2) transparent; }
.dk-rowswrap { position: relative; flex: 1; min-height: 0; margin-top: 4px; width: 100%; }

/* The rows scroll under the fade, so the fade is a sibling of the scroller,
   never inside it. No bar: the board draws none, and a classic one is 10 px of
   the row's own width — measured 2026-09-05, it pulled every action word 10 px
   in from the right edge the board puts it on. The fade is the affordance. */
.dk-rows {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;
}

.dk-rows::-webkit-scrollbar { width: 0; height: 0; }

.dk-rows-fade {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 60px;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(12, 11, 10, 0) 0%, #0c0b0a 100%);
}

/* 58 + 1 of hairline; the board is content-box and this room is not
   (BUILD-MAP 2.1). */
.dk-row {
  display: grid;
  grid-template-columns: 44px minmax(240px, 34%) 76px 96px minmax(180px, 1fr) minmax(112px, 260px);
  align-items: center;
  column-gap: 16px;
  min-height: 66px;
  padding: 8px 0;
  border-bottom: 1px solid var(--dk-hair);
}

/* The board's 260 px was drawn against "Deltetto Barbera d'Alba"; measured
   against the real catalogue on 2026-09-05 it cut 498 of 2,670 names (18.7%)
   mid-word — "1792 Small Batch Kentucky Straigh…" — while the why column
   beside them was empty ground on every never-run row. Content widths
   measured in the tab: 99.2% of names fit in 420 px, the longest is 501.
   Fixed, not flexible: a per-row width would slide the size and why columns
   left and right down a 2,670-row list. */
.dk-rowname {
  font-size: 15px;
  font-weight: 600;
  width: auto;
  min-width: 0;
  white-space: normal;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dk-rowname.has-image { display: flex; align-items: center; gap: 12px; }
.dk-rowname-copy { min-width: 0; overflow-wrap: anywhere; }
.dk-queue-image-wrap { flex: 0 0 58px; width: 58px; height: 64px; display: flex; align-items: center; justify-content: center; }
.dk-queue-image { width: 100%; height: 100%; object-fit: contain; }
.dk-queue-image-empty { color: var(--dk-muted); font-size: 12px; font-weight: 400; line-height: 1.15; text-align: center; }
.dk-queue-image-kind { display: block; margin-top: 4px; color: var(--dk-muted); font-size: 12px; font-weight: 400; }

.dk-rowsize {
  font-size: 13px;
  color: var(--dk-muted);
  width: auto;
  white-space: nowrap;
}

/* The register count (Wave 2, item 5): "12 in store", blank when the
   register has no row. Fixed like the size column, so the why column starts
   on one line down the whole list. */
.dk-rowqty {
  font-size: 13px;
  color: var(--dk-muted);
  width: auto;
  white-space: nowrap;
}

.dk-rowwhy {
  font-size: 13px;
  color: var(--dk-muted);
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  white-space: normal;
  overflow: hidden;
}

.dk-rowstatus { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dk-rowdate { color: var(--dk-muted); font-size: 12px; line-height: 1.25; }
.dk-rowmessage { color: var(--dk-copper); font-size: 12px; line-height: 1.25; }

/* Bright and heavy means you can act; muted and light means it is only news
   (BUILD-MAP 8.8, and the board's own Run against Queued). */
.dk-rowact {
  font-size: 13px;
  font-weight: 600;
  color: var(--dk-text);
  white-space: nowrap;
  justify-self: end;
}

.dk-rowact.is-news { font-weight: 500; color: var(--dk-muted); }
.dk-rowact[disabled] { cursor: default; }
.dk-rowactions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px 12px; width: 100%; max-width: 260px; justify-self: end; }
.dk-rowhead { min-height: 34px; padding: 0 0 6px; border-bottom-color: var(--dk-hair2); color: var(--dk-muted); font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.dk-rowhead .dk-rowname, .dk-rowhead .dk-rowsize, .dk-rowhead .dk-rowqty, .dk-rowhead .dk-rowwhy { color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit; }
.dk-sorthead { appearance: none; border: 0; background: none; color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit; white-space: nowrap; padding: 7px 0; min-height: 44px; text-align: left; cursor: pointer; }
.dk-sorthead.is-on { color: var(--dk-copper); }
.dk-sorthead:focus-visible, .dk-sort-reset:focus-visible { outline: 2px solid var(--dk-copper); outline-offset: 3px; }
.dk-rowactionhead { justify-self: end; }

.dk-rowactions .dk-rowact { min-height: 44px; white-space: normal; text-align: right; }

/* 94 = 16 + the 54 px pill + 24, the board's own footer. The pill is only
   drawn on a tab that has something to run, so without this the footer
   collapsed to 61 px and the rows, the fade and Close all slid 33 px down the
   screen as he tapped from Needs a photo to Held (measured 2026-09-05). The
   height is reserved on every tab instead. */
.dk-queue-explanation { margin: 0 0 12px; color: var(--dk-muted, #a99b87); font-size: 13px; line-height: 1.5; }
.dk-run-scope {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 22px;
  padding: 15px 0 5px;
  border-top: 1px solid var(--dk-line, #61584e);
  color: var(--dk-text);
}
.dk-run-scope-title { font-size: 14px; font-weight: 600; white-space: nowrap; }
.dk-run-scope-modes, .dk-run-scope-fields { display: flex; flex-wrap: wrap; gap: 8px 16px; }
.dk-run-scope-fields { flex-basis: 100%; padding-left: 0; }
.dk-run-scope-choice { display: inline-flex; align-items: center; gap: 7px; font-size: 14px; cursor: pointer; }
.dk-run-scope-choice input { accent-color: var(--dk-copper, #c9986d); }
.dk-run-scope-help { flex-basis: 100%; font-size: 12px; line-height: 1.45; color: var(--dk-muted); }
.dk-listfoot {
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 16px 0 24px;
  min-height: 94px;
  flex: none;
}

.dk-close { font-size: 15px; font-weight: 500; color: var(--dk-muted); white-space: nowrap; }

/* The strip's loud slot is behind the drawer, so the one honest line follows
   him in here rather than being said to a covered screen. */
.dk-listnote {
  font-size: 13px;
  font-weight: 500;
  color: var(--dk-muted);
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dk-stop { font-size: 15px; font-weight: 600; color: var(--dk-text); white-space: nowrap; }

.dk-listfoot .dk-pill { margin-left: auto; }

/* ── the phone (state 7, Phone.dc.html) ─────────────────────────────────── */
/* At 1023px and under, or when the shell requests a phone layout, the
   existing compact review grid keeps the photo stage and its controls usable.
   studio2.js owns the breakpoint and puts .is-phone on the root. */

.dk-phone { display: none; }

/* The board's own box: 390 wide, padding 70/16/0, the blocks 48 apart. The
   bottom padding is this room's (the board is one screen tall and does not
   scroll; 28 bottles do), and the bar is hidden the way the drawer's rows
   are — the board draws none and it would eat 10 px of every line. */
.dk.is-phone .dk-phone {
  display: none;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 70px 16px 48px;
  gap: 48px;
  scrollbar-width: none;
}

.dk.is-phone .dk-phone::-webkit-scrollbar { width: 0; height: 0; }

/* "Needs a store photo  2" — dim, 13/500, and the negative margin pulls the
   48 px gap under it back to the board's 24. */
.dk-phone-head {
  font-size: 13px;
  font-weight: 500;
  color: var(--dk-dim);
  padding: 0 8px;
  margin-bottom: -24px;
  flex: none;
}

.dk-card {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: 0 8px;
  flex: none;
}

.dk-card-head { display: flex; flex-direction: column; gap: 6px; }

/* The serif is 34 on the phone, not the desk's 48 (Phone.dc.html). */
.dk-card .dk-serif { font-size: 34px; line-height: 1.05; }

/* The bot's own words, cut to what to shoot. It wraps rather than dying in an
   ellipsis — a line he cannot finish reading is a line that did not tell him
   what to shoot. */
.dk-card-why { font-size: 15px; color: var(--dk-muted); }

.dk-card-foot { display: flex; flex-direction: column; gap: 10px; }

/* The board draws this pill at 56 with 16 px type — taller and bigger than the
   desk's 52, because it is the only thing on the screen his thumb can hit. */
.dk-card-foot .dk-pill.is-wide { height: 56px; font-size: 16px; }

/* Uploading / In the studio / Refused · … / Didn't send, tap to retry. */
.dk-card-state { display: flex; flex-direction: column; gap: 10px; padding: 0 2px; }

.dk-uploading { font-size: 15px; color: var(--dk-muted); }

/* "tap to retry" is the words themselves, and the room's rule is that bright
   and heavy means you can act while muted and light means it is news
   (BUILD-MAP 8.8; the room's own acting plain word is .dk-rowact at 600 and
   #efe9e1). MEASURED 2026-09-05 by the design judge and changed: this line was
   a live 338 x 21 tap target drawn in the news treatment — 15 / 400 / #9a938a,
   invisible at rest, ten pixels above a full-width copper pill — with an
   underline only on :focus-visible, which a thumb never fires. It is an act,
   so it is drawn as one. Never a second pill. */
.dk-retry { cursor: pointer; font-weight: 600; color: var(--dk-text); }
.dk-retry:focus-visible {
  outline: none;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* The hairline under Uploading runs the width of the block, and it does not
   breathe: the board's fill carries no animation (BUILD-MAP 3.10). */
.dk-track.is-wide { width: 100%; }
.dk-fill.is-static { width: 58%; animation: none; }
.dk-lanes { display: flex; gap: 6px; flex: none; align-items: center; }
.dk-lane { min-height: 44px; padding: 0 13px; border: 1px solid var(--dk-hair2); border-radius: 999px; background: transparent; color: var(--dk-muted); font: 500 13px var(--dk-sans, sans-serif); cursor: pointer; }
.dk-lane[aria-pressed="true"] { background: var(--dk-text); color: var(--dk-bg, #10100f); border-color: var(--dk-text); }
.dk-lane:disabled { cursor: wait; opacity: .6; }
.dk-lane:focus-visible { outline: 2px solid var(--dk-text); outline-offset: 3px; }
.dk-by { display: inline-block; margin-left: 10px; font-size: 12px; font-weight: 400; color: var(--dk-muted); }
.dk.is-phone .dk-lanes { margin: -46px 8px -24px; }

/* Phone review uses the existing final, Original, zoom, feedback and decisions.
   Store-photo uploads remain available in the normal Shoot in store list. */
.dk.is-phone { overflow-y: auto; overflow-x: hidden; }
.dk.is-phone .dk-strip {
  height: auto;
  min-height: 132px;
  padding: 12px 16px;
  flex-wrap: wrap;
  align-content: flex-start;
  column-gap: 16px;
  row-gap: 0;
}
.dk.is-phone .dk-lanes { margin: 0; }
.dk.is-phone .dk-strip .dk-intake-link { margin: 0; }
.dk.is-phone .dk-back,
.dk.is-phone .dk-running,
.dk.is-phone .dk-count { min-height: 44px; display: inline-flex; align-items: center; }
.dk.is-phone .dk-counts { width: 100%; margin-left: 0; gap: 20px; flex-wrap: wrap; }
.dk.is-phone .dk-stations { display: none; }
.dk.is-phone .dk-receipt { white-space: normal; width: 100%; }
.dk.is-phone .dk-receipt-div { display: none; }
.dk.is-phone .dk-desk {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  flex: none;
  gap: 12px;
  padding: 12px 16px calc(24px + env(safe-area-inset-bottom));
}
.dk.is-phone .dk-rail {
  grid-row: 1;
  flex-direction: row;
  width: 100%;
  height: 68px;
  padding: 0 0 0 4px;
  overflow-x: auto;
  overflow-y: hidden;
  gap: 10px;
}
.dk.is-phone .dk-thumb,
.dk.is-phone .dk-thumb-img { width: 48px; height: 64px; }
.dk.is-phone .dk-rail-fade { display: none; }
.dk.is-phone .dk-col { display: contents; }
.dk.is-phone .dk-name { grid-row: 2; height: auto; min-height: 64px; gap: 6px; }
.dk.is-phone .dk-name .dk-serif { font-size: 32px; overflow-wrap: anywhere; }
.dk.is-phone .dk-meta { font-size: 13px; }
.dk.is-phone .dk-stage { grid-row: 3; width: 100%; height: 400px; min-height: 400px; }
.dk.is-phone .dk-view { align-items: center; top: 92px; bottom: 44px; }
.dk.is-phone .dk-stage.is-original .dk-view,
.dk.is-phone .dk-stage.is-prepared .dk-view { top: 92px; bottom: 64px; }
.dk.is-phone .dk-render {
  height: auto;
  width: auto;
  max-width: 100%;
  max-height: 100%;
  margin-bottom: 0;
  -webkit-mask-image: none;
  mask-image: none;
}
.dk.is-phone .dk-stage .dk-floor { display: none; }
.dk.is-phone .dk-view-caption { left: 12px; bottom: 8px; max-width: calc(100% - 24px); }
.dk.is-phone .dk-tools { top: 0; right: 0; left: 0; bottom: auto; display: flex; flex-direction: column; align-items: stretch; gap: 0; padding: 0 8px; background: rgba(20, 18, 16, .92); }
.dk.is-phone .dk-toolgroup { width: 100%; display: flex; align-items: center; justify-content: space-around; gap: 2px; }
.dk.is-phone .dk-inspect-tools { padding-left: 0; border-left: 0; border-top: 1px solid var(--dk-hair2); }
.dk.is-phone .dk-tool { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0 2px; }
.dk.is-phone .dk-zoombar { bottom: 44px; height: 44px; }
.dk.is-phone .dk-zoomstop { display: inline-flex; min-height: 44px; align-items: center; padding: 0 10px; }
.dk.is-phone .dk-decide { grid-row: 4; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.dk.is-phone .dk-decide .dk-pill { width: 100%; height: 48px; padding: 0 8px; font-size: 13px; }
.dk.is-phone .dk-key { display: none; }
.dk.is-phone .dk-marklist { grid-row: 7; }
.dk.is-phone .dk-words { grid-row: 5; padding-top: 0; }
.dk.is-phone .dk-wordsinput { font-size: 16px; }
.dk.is-phone.is-listopen .dk-desk { display: none; }
.dk.is-phone .dk-list { position: relative; top: auto; bottom: auto; padding: 12px 16px 0; min-height: 60dvh; }
.dk.is-phone .dk-tabs { overflow-x: auto; gap: 24px; scrollbar-width: none; }
.dk.is-phone .dk-tabs::-webkit-scrollbar { display: none; }
.dk.is-phone .dk-tab { min-height: 44px; flex: none; }
.dk.is-phone .dk-rowswrap { min-height: 52dvh; }
.dk.is-phone .dk-queuetable { overflow-x: hidden; min-height: 52dvh; }
.dk.is-phone .dk-row { height: auto; min-height: 76px; display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; padding: 12px 0; }
.dk.is-phone .dk-rowname { width: auto; min-width: 0; white-space: normal; grid-column: 1; }
.dk.is-phone .dk-rowsize,
.dk.is-phone .dk-rowqty,
.dk.is-phone .dk-rowwhy { width: auto; white-space: normal; grid-column: 1; }
.dk.is-phone .dk-rowact { grid-column: 2; grid-row: 1 / span 4; min-height: 44px; display: inline-flex; align-items: center; }
.dk.is-phone .dk-rowactions { grid-column: 1 / -1; justify-content: flex-start; max-width: none; }
.dk.is-phone .dk-rowactions .dk-rowact { text-align: left; }
.dk.is-phone .dk-listfoot { min-height: 56px; flex-wrap: wrap; gap: 12px; padding-bottom: env(safe-area-inset-bottom); }
.dk.is-phone .dk-listfoot .dk-pill { min-height: 44px; }

/* Durable approval delivery status, shared by phone and desktop. */
.dk-queue-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.dk-queue-heading h2 { font: 500 25px/1.3 var(--dk-serif, Georgia, serif); margin: 0; }
.dk-queue-heading button, .dk-queue-controls button, .dk-listfoot button, .dk-count { min-height: 44px; }
.dk-queue-controls { display: flex; flex-wrap: wrap; gap: 16px; padding: 16px 0; }
.dk-queue-controls input, .dk-queue-controls select { min-height: 44px; border: 1px solid var(--dk-hair2); border-radius: 8px; background: var(--dk-bg); color: var(--dk-text); font: inherit; font-size: 15px; padding: 8px 12px; }
.dk-queue-controls input { flex: 1; min-width: 0; }
.dk-queue-controls select { max-width: 360px; }
.dk-sort-reset { border: 1px solid var(--dk-hair2); border-radius: 8px; background: var(--dk-bg); color: var(--dk-text); font: inherit; font-size: 13px; padding: 8px 12px; cursor: pointer; }
.dk-select-next:disabled { opacity: .5; cursor: default; }
.dk-queue-controls input:focus-visible, .dk-queue-controls select:focus-visible, .dk-rowcheck:focus-visible { outline: 2px solid var(--dk-copper); outline-offset: 3px; }
.dk-rowselect { display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; cursor: pointer; }
.dk-rowselect.is-empty { cursor: default; }
.dk-rowcheck { width: 22px; height: 22px; margin: 0; accent-color: var(--dk-copper); cursor: pointer; }
.dk-queue-origin { display: block; margin-top: 4px; color: var(--dk-muted); font-size: 12px; font-weight: 400; }
.dk-listfoot { flex-wrap: wrap; gap: 12px; }
.dk-listfoot .dk-listnote { white-space: normal; overflow: visible; }
.dk-listfoot .dk-pill:disabled { opacity: .5; cursor: default; }
.dk-queue-empty { padding: 28px 0; color: var(--dk-muted); font-size: 15px; }
.dk.is-phone .dk-queue-heading h2 { font-size: 23px; }
.dk.is-phone .dk-rowhead { display: none; }
.dk.is-phone .dk-row > .dk-rowselect.is-empty { display: none; }
.dk.is-phone .dk-queue-controls { flex-direction: column; gap: 10px; }
.dk.is-phone .dk-queue-controls select { max-width: none; width: 100%; }
.dk.is-phone .dk-queue-controls input { font-size: 16px; }
.dk.is-phone .dk-row.is-selectable { grid-template-columns: 44px minmax(0, 1fr); }
.dk.is-phone .dk-row.is-selectable .dk-rowselect { grid-column: 1; grid-row: 1 / span 4; align-self: center; }
.dk.is-phone .dk-row.is-selectable .dk-rowname,
.dk.is-phone .dk-row.is-selectable .dk-rowsize,
.dk.is-phone .dk-row.is-selectable .dk-rowqty,
.dk.is-phone .dk-row.is-selectable .dk-rowwhy { grid-column: 2; }
.dk.is-phone .dk-listfoot .dk-listnote { flex-basis: 100%; order: 3; }
.dk.is-phone .dk-listfoot .dk-pill { margin-left: auto; }

.dk-publications { padding: 12px 18px; border-bottom: 1px solid currentColor; font: 13px/1.5 var(--font-sans, sans-serif); overflow-wrap: anywhere; }
.dk-publications[hidden] { display: none; }
.dk-publication-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; padding-top: 8px; }
.dk-publication-row > span:first-child { font-weight: 600; }

/* Desktop review has one scroll owner: the room. Expanded information grows
   the page instead of creating scrollbars inside the column and details. */
.dk:not(.is-phone):not(.is-listopen) { overflow-y: auto; }
.dk:not(.is-phone):not(.is-listopen) .dk-desk {
  flex: 0 0 calc(100dvh - var(--dk-head));
  height: calc(100dvh - var(--dk-head));
  min-height: 0;
}
.dk:not(.is-phone) .dk-col:has(> .dk-information) {
  align-self: flex-start;
  overflow: visible;
  min-height: auto;
}
.dk:not(.is-phone) .dk-information-body {
  max-height: none;
  overflow: visible;
  padding-right: 0;
}
.dk-publication-row > span:nth-child(2) { flex: 1 1 220px; }
.dk-publication-row > button { min-height: 44px; }

/* Queue issue inspection keeps the table and its selection in place. */
.dk-issue-panel { position: fixed; inset: 112px 0 0 auto; z-index: 12; width: min(520px, 90vw); box-sizing: border-box; padding: 24px 32px; overflow-y: auto; background: var(--dk-bg, #0d0c0b); color: inherit; border-left: 1px solid #40382d; box-shadow: -16px 0 40px #0008; }
.dk-issue-panel[hidden] { display: none; }
.dk-issue-title { font-size: 28px; line-height: 1.2; margin: 24px 0 16px; }
.dk-issue-reason { white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.55; }
.dk-issue-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; margin: 24px 0; }
.dk-issue-actions button { min-height: 44px; }
.dk-issue-panel .dk-information { margin-top: 24px; }
.dk-rowdetail { border: 0; background: transparent; color: inherit; font: inherit; text-align: left; padding: 0; cursor: pointer; min-height: 44px; }
.dk-rowdetail:hover .dk-rowname-copy, .dk-rowdetail:focus-visible { color: var(--dk-accent, #d8a16b); text-decoration: underline; text-underline-offset: 4px; }
.dk-issue-work { display: grid; grid-template-columns: 120px 1fr; gap: 14px 20px; margin: 24px 0; font-size: 14px; line-height: 1.5; }
.dk-issue-work dt { font-weight: 600; }
.dk-issue-work dd { margin: 0; color: var(--dk-dim); }
.dk-issue-work .is-needed { color: var(--dk-accent, #d8a16b); }

.dk-issue-panel { scrollbar-width: none; }
.dk-issue-panel::-webkit-scrollbar { width: 0; height: 0; }
.dk-issue-title { font-family: var(--dk-serif); font-weight: 500; }
.dk-history { flex: 1; min-height: 0; overflow-y: auto; padding: 8px 0 28px; }
.dk-history[hidden] { display: none; }
.dk-queue-controls[hidden], .dk-queuetable[hidden], .dk-run-scope[hidden], .dk-listfoot[hidden] { display: none; }
.dk-history-heading { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 18px; margin: 8px 0 14px; color: var(--dk-muted); font-size: 13px; }
.dk-history-heading h3 { margin: 0; color: var(--dk-text); font: 500 21px/1.3 var(--dk-serif); }
.dk-history-heading button { min-height: 44px; margin-left: auto; }
.dk-history-row { width: 100%; min-height: 70px; display: grid; grid-template-columns: minmax(170px, 2fr) minmax(180px, 1fr) minmax(105px, .7fr) minmax(170px, 1.5fr); align-items: center; gap: 8px 16px; padding: 12px 4px; border: 0; border-bottom: 1px solid var(--dk-hair); background: transparent; color: var(--dk-text); font: inherit; text-align: left; cursor: pointer; }
.dk-history-row:hover, .dk-history-row:focus-visible { background: var(--dk-surf); outline: 2px solid var(--dk-copper); outline-offset: -2px; }
.dk-history-name { font-weight: 600; overflow-wrap: anywhere; }
.dk-history-meta, .dk-history-context { color: var(--dk-muted); font-size: 13px; line-height: 1.4; overflow-wrap: anywhere; }
.dk-history-outcome { font-size: 13px; }
.dk-history-id { color: var(--dk-muted); font-size: 12px; line-height: 1.5; overflow-wrap: anywhere; }
.dk-history-inventory { display: inline-flex; align-items: center; min-height: 44px; margin: 4px 0 18px; }
.dk-history-section { margin: 22px 0 10px; font-size: 15px; font-weight: 600; }
.dk-history-muted { color: var(--dk-muted); font-size: 12px; line-height: 1.5; }
.dk-history-gallery { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.dk-history-stage { margin: 0; min-width: 0; border: 1px solid var(--dk-hair2); border-radius: 8px; padding: 8px; background: var(--dk-surf); }
.dk-history-stage figcaption { margin-bottom: 8px; font-weight: 600; font-size: 13px; }
.dk-history-stage img { display: block; width: 100%; aspect-ratio: 3 / 4; object-fit: contain; background: #e9e7e2; }
.dk-history-full { display: inline-flex; align-items: center; min-height: 44px; margin-top: 4px; color: var(--dk-accent); font-size: 12px; }
.dk-history-stage p { min-height: 96px; margin: 0; display: grid; place-items: center; color: var(--dk-muted); text-align: center; font-size: 12px; }
.dk-history-usage { margin: 0; padding-left: 20px; line-height: 1.6; font-size: 13px; }
.dk-history-feedback { padding: 8px 0; border-bottom: 1px solid var(--dk-hair); font-size: 13px; line-height: 1.5; overflow-wrap: anywhere; }
.dk-history-feedback p { margin: 4px 0; white-space: pre-wrap; }
.dk-history-summary { margin-top: 18px; }
.dk-history-technical { margin-top: 20px; }
.dk-history-technical > summary { min-height: 44px; padding: 12px 0; cursor: pointer; font-size: 13px; }
@media (max-width: 760px) {
  .dk-history-row { grid-template-columns: minmax(0, 1fr) auto; gap: 3px 10px; }
  .dk-history-name { grid-column: 1; }
  .dk-history-outcome { grid-column: 2; grid-row: 1; }
  .dk-history-meta, .dk-history-context { grid-column: 1 / -1; }
  .dk-history-gallery { grid-template-columns: 1fr; }
  .dk-history-stage img { max-height: 360px; aspect-ratio: auto; }
}
/* Neutral empty review geometry; these are display-only, never fake jobs. */
.dk-none.is-placeholder { inset:8% 12%; transform:none; width:auto; display:flex; flex-direction:column; align-items:center; justify-content:center; border:1px solid var(--dk-hair2); border-radius:12px; background:var(--dk-surf); }
.dk-none.is-placeholder .dk-none-head { color:var(--dk-dim); font-size:32px; }
.dk-none.is-placeholder .dk-none-why { color:var(--dk-dim); }
.dk-information.is-placeholder .dk-information-field { opacity:.65; }
.dk-information-placeholder { color:var(--dk-dim); min-height:24px; border-bottom:1px solid var(--dk-hair2); }
.dk-provider { font-size:12px; color:var(--dk-muted); max-width:200px; }
.dk-notifications .dk-notification-heading { max-width:1100px; margin:30px auto 4px; font:500 18px/1.5 var(--dk-sans); }
.dk-addition-detail summary { cursor:pointer; font:400 26px/1.3 var(--dk-serif); padding:6px 0; overflow-wrap:anywhere; }
.dk-addition-detail[open] .dk-intake-meta { margin:8px 0; }
.dk-notifications > .dk-pill { display:block; margin:28px auto; padding:12px 24px; }
.dk-notifications button:disabled { opacity:.5; cursor:default; }
.dk.is-phone .dk-strip .dk-intake-link { display:inline-block; margin:0; }
.dk-provider { max-width:290px; display:flex; flex-direction:column; gap:4px; }
.dk-provider-choices { display:flex; gap:12px; }
.dk-provider-choice { color:var(--dk-dim); white-space:nowrap; }
.dk-provider-choice[aria-pressed="true"], .dk-provider-lane { color:var(--dk-copper); }
.dk-provider-choice:focus-visible { outline:1px solid var(--dk-muted); outline-offset:3px; }

.dk-notifications > .dk-pill[hidden] { display:none; }

.dk.dk.is-notifications { overflow:hidden; }

.dk-addition-source { display:block; width:100px; height:140px; object-fit:contain; margin-top:12px; }
.dk-tab.is-browse { margin-left:auto; }
.dk-tab.is-browse:not(.is-on) { color:var(--dk-muted); }
