/* ══════════════════════════════════════════════════════════════════════
   GA Drawings Agent — "scroll to build a sheet set"
   Narrow, restrained stage column pinned left. Enormous graphic right.
   Monochrome + GA red only. Hairlines, never shadows.
   ══════════════════════════════════════════════════════════════════════ */

.pipe {
  --colw: 342px;          /* the stage column stays narrow, on purpose      */
  --headh: 182px;         /* fixed heading zone so the hairline never moves */
  --pad: 64px;
  --gbot: 54px;          /* bottom air under every graphic, matches .pp-head top */
  --ease: cubic-bezier(.22, .61, .36, 1);

  --stage-off:  #e3e5e8;  /* not run yet — very light                       */
  --stage-done: #cbced3;  /* already run                                    */
  --stage-on:   #111113;  /* running now — near black                       */

  position: relative;
  background: var(--bg);
}

.pipe-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ── intro ─────────────────────────────────────────────────────────── */
.pipe-intro {
  max-width: 1440px;
  margin: 0 auto;
  padding: 128px var(--pad) 86px;
}
.pipe-intro .kicker { margin-bottom: 22px; }
.pipe-intro h2 { max-width: 20ch; font-size: clamp(30px, 2.9vw, 42px); }
.pipe-intro h2 .dim { max-width: none; }

/* ── the scroll track ──────────────────────────────────────────────── */
.pipe-scroll {
  position: relative;
  height: calc(9 * max(94vh, 660px));
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 24px;
}

.pipe-steps { position: absolute; inset: 0 24px; display: flex; flex-direction: column; pointer-events: none; }
.pipe-step  { flex: 1 1 0; }

/* ── the sticky frame ──────────────────────────────────────────────── */
/* The nav is sticky and opaque; a frame stuck to top:0 puts its panel heading
   underneath it and crops the first line. Clear it. */
.pipe-frame {
  position: sticky;
  top: var(--navh);
  height: calc(100vh - var(--navh));
  min-height: 620px;
  display: grid;
  grid-template-columns: var(--colw) minmax(0, 1fr);
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  border-top: 1px solid var(--line);
  background: var(--bg);
}

/* ── stage column ──────────────────────────────────────────────────── */
.pipe-nav {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 28px 0 58px;
  border-right: 1px solid var(--line);
}

/* honest progress: the hairline fills to where the run has got to */
.pipe-rail {
  position: absolute;
  left: -1px; top: 0;
  width: 1px; height: 0;
  background: rgba(0, 0, 0, .26);
  transition: height .6s var(--ease);
}

.ph { margin-bottom: 26px; }
.ph:last-of-type { margin-bottom: 0; }

.ph-name {
  display: block;
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -0.022em;
  color: var(--stage-off);
  transition: color .45s ease;
}
.ph.done .ph-name { color: var(--stage-done); }
.ph.on   .ph-name { color: var(--ink); }

.ph-stages { list-style: none; margin: 9px 0 0; padding: 0; }
.ph-stages li {
  position: relative;
  font-family: var(--mono);
  font-size: 12.5px;
  font-weight: 400;
  line-height: 2.02;
  letter-spacing: -0.002em;
  color: var(--stage-off);
  transition: color .45s ease;
}
.ph-stages li.done { color: var(--stage-done); }
.ph-stages li.on   { color: var(--stage-on); }

/* one short accent tick on the rule, spanning whatever is running now */
.pipe-tick {
  position: absolute;
  left: -1px; top: 0;
  width: 2px; height: 0;
  background: var(--red);
  opacity: 0;
  transition: top .5s var(--ease), height .5s var(--ease), opacity .3s ease;
}
.pipe-tick.on { opacity: 1; }

.pipe-count {
  margin-top: 30px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .04em;
  color: var(--ink-ghost);
}
.pipe-count b { font-weight: 500; color: var(--ink-mute); }

/* ── panels ────────────────────────────────────────────────────────── */
.pipe-stack { position: relative; overflow: hidden; }

.pipe-panel {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-rows: var(--headh) minmax(0, 1fr);
  opacity: 0;
  visibility: hidden;
  transform: translateY(18px);
  transition: opacity .40s ease, transform .62s var(--ease), visibility 0s .45s;
  will-change: opacity, transform;
}
.pipe-panel.on {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity .52s ease .05s, transform .72s var(--ease) .05s, visibility 0s;
}

.pp-head {
  padding: 54px var(--pad) 0;
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.pp-head h3 {
  max-width: 30ch;
  font-size: clamp(23px, 1.95vw, 29px);
  line-height: 1.24;
  letter-spacing: -0.028em;
  font-weight: 500;
}
.pp-stages {
  display: none;
  margin-top: 14px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .02em;
  color: var(--ink-faint);
}

.pp-graphic {
  position: relative;
  overflow: hidden;
  background: var(--bg-sunken);
}
.pg-pad    { display: flex; gap: 26px; padding: 44px var(--pad) var(--gbot); }
.pg-centre { display: grid; place-items: center; padding: 30px var(--pad) calc(30px + var(--gbot)); }

.pg { position: absolute; inset: 0; width: 100%; height: calc(100% - var(--gbot)); }
.pg-bleed { inset: 0 -1px 0 0; }

/* ── drawing line weights: heavy cut, medium object, light hatch ───── */
svg .w0, svg .w1, svg .w2 { fill: none; vector-effect: non-scaling-stroke; }
svg .w0 { stroke: rgba(0, 0, 0, .17); stroke-width: 1; }
svg .w1 { stroke: #22252a;            stroke-width: 1; }
svg .w2 { stroke: #0b0c0e;            stroke-width: 2; }
svg .pf { fill: #fff; }
svg .dash { stroke-dasharray: 6 5; }

.pg .lbl, .pg .rm, .pg .gh, .pg .sn, .pg .vt {
  font-family: var(--mono);
  fill: var(--ink-mute);
  stroke: none;
}
.pg .lbl { font-size: 11px; letter-spacing: .1em; fill: var(--ink-faint); }
.pg .rm  { font-size: 12px; letter-spacing: .07em; fill: #3c4048; text-anchor: middle; }
.pg .gh  { font-size: 11px; text-anchor: middle; fill: var(--ink-mute); }
.pg .sn  { font-size: 12px; letter-spacing: .06em; text-anchor: end; fill: #3c4048; }
.pg .vt  { font-size: 7px; letter-spacing: .05em; fill: var(--ink-faint); }
.pg .sh  { fill: #fff; }
.pg .vp  { fill: #fbfbfc; stroke: rgba(0,0,0,.3); }
.pg .crop { stroke: var(--red); opacity: .55; }
.pg .slab { fill: #fff; }

/* ── readouts ──────────────────────────────────────────────────────── */
.pg-readout {
  position: absolute;
  right: 40px; top: 40px;
  min-width: 226px;
  padding: 16px 18px 14px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}
.ro-flat { top: auto; bottom: 36px; right: 40px; }
.ro-title {
  font-family: var(--mono);
  font-size: 9.5px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 10px;
}
.pg-readout dl { margin: 0; }
.pg-readout dl > div {
  display: flex; align-items: baseline; justify-content: space-between; gap: 20px;
  padding: 5px 0;
  border-top: 1px solid var(--line);
}
.pg-readout dl > div:first-child { border-top: 0; }
.pg-readout dt { font-size: 12.5px; color: var(--ink-mute); }
.pg-readout dd { margin: 0; font-family: var(--mono); font-size: 13px; color: var(--ink); font-variant-numeric: tabular-nums; }
.ro-foot { margin-top: 12px; font-family: var(--mono); font-size: 10px; letter-spacing: .06em; color: var(--ink-ghost); }

.num { font-variant-numeric: tabular-nums; }
.num.big { font-size: 19px; letter-spacing: -0.02em; }
.num.xl  { font-family: var(--mono); font-size: 34px; letter-spacing: -0.03em; color: var(--ink); }

/* ── cards (setup, manifest, approve) ──────────────────────────────── */
.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.card-bar {
  display: flex; align-items: center; justify-content: space-between;
  height: 40px; padding: 0 16px;
  border-bottom: 1px solid var(--line);
  background: #fcfcfd;
}
.card-t { font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em; color: var(--ink-faint); }
.card-x { font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em; color: var(--ink-ghost); }

/* setup */
.card-setup { flex: 1 1 auto; min-width: 0; align-self: flex-start; }
.setup-rows { list-style: none; margin: 0; padding: 0; }
.setup-rows li {
  display: grid;
  grid-template-columns: 190px 1fr 20px;
  align-items: center;
  gap: 16px;
  padding: 0 18px;
  height: 66px;
  border-top: 1px solid var(--line);
}
.setup-rows li:first-child { border-top: 0; }
.sr-k { font-size: 14px; color: var(--ink-mute); }
.sr-v { font-family: var(--mono); font-size: 14px; letter-spacing: -0.01em; color: var(--ink); }
.tick { width: 14px; height: 14px; border-radius: 50%; background: #16171a; position: relative; }
.tick::after {
  content: ''; position: absolute; left: 4.5px; top: 2.6px;
  width: 4px; height: 7px; border: solid #fff; border-width: 0 1.5px 1.5px 0;
  transform: rotate(42deg);
}

.card-types { flex: 0 0 288px; align-self: flex-start; }
.type-rows { list-style: none; margin: 0; padding: 0; }
.type-rows li {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 0 16px; height: 56px;
  border-top: 1px solid var(--line);
}
.type-rows li:first-child { border-top: 0; }
.ty-f { font-family: var(--mono); font-size: 11.5px; color: var(--ink); }
.ty-t { font-family: var(--mono); font-size: 11.5px; color: var(--ink-faint); }

/* manifest */
.card-manifest { flex: 1 1 auto; min-width: 0; align-self: flex-start; }
.mf-head, .mf-rows li {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr) 176px 62px;
  gap: 18px;
  padding: 0 18px;
  align-items: center;
}
.mf-head {
  height: 32px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .13em;
  color: var(--ink-ghost);
  border-bottom: 1px solid var(--line);
}
.mf-rows { list-style: none; margin: 0; padding: 0; counter-reset: r; }
.mf-rows li {
  height: 34px;
  border-bottom: 1px solid var(--line);
  font-family: var(--mono); font-size: 11.5px;
  color: var(--ink);
  white-space: nowrap;
}
.mf-rows li span:first-child { color: var(--ink); }
.mf-rows li span:nth-child(2) { overflow: hidden; text-overflow: ellipsis; }
.mf-rows li span:nth-child(3) { color: var(--ink-faint); }
.mf-rows li span:nth-child(4) { color: var(--ink-faint); text-align: right; }

.card-tally { flex: 0 0 246px; align-self: flex-start; padding: 16px 18px 14px; }
.tally > div { display: flex; align-items: baseline; justify-content: space-between; padding: 8px 0; border-top: 1px solid var(--line); }
.tally > div:first-child { border-top: 0; }
.tally dt { font-size: 13px; color: var(--ink-mute); }
.tally dd { margin: 0; font-family: var(--mono); color: var(--ink); }

/* ── approve ───────────────────────────────────────────────────────── */
.approve-wrap { width: min(660px, 100%); }
.card-approve { margin-bottom: 26px; }
.pill-stack { display: grid; }
.pill {
  grid-area: 1 / 1;
  justify-self: end;
  display: inline-flex; align-items: center; gap: 7px;
  height: 24px; padding: 0 11px;
  border-radius: 6px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em;
}
.pill-review { background: #fff; border: 1px solid var(--line-strong); color: var(--ink-mute); }
.pill-review::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--dot-idle); }
.pill-ok { background: #16171a; color: #fff; opacity: 0; }
.pill-ok::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--red); }

.ap-stats { display: grid; grid-template-columns: repeat(4, 1fr); margin: 0; }
.ap-stats > div { padding: 20px 18px; border-left: 1px solid var(--line); }
.ap-stats > div:first-child { border-left: 0; }
.ap-stats dt { font-size: 12px; color: var(--ink-faint); margin-bottom: 6px; }
.ap-stats dd { margin: 0; font-family: var(--mono); font-size: 22px; letter-spacing: -0.03em; color: var(--ink); }

.ap-actions { display: flex; justify-content: flex-end; gap: 10px; padding: 14px 18px; border-top: 1px solid var(--line); background: #fcfcfd; }
.ap-btn { display: inline-flex; align-items: center; height: 34px; padding: 0 16px; border-radius: var(--r-ctl); font-size: 13.5px; }
.ap-ghost { border: 1px solid var(--line-strong); color: var(--ink-mute); background: #fff; }
.ap-red { background: var(--red); color: #fff; }

.barrier { display: flex; align-items: center; gap: 14px; margin-bottom: 24px; }
.barrier-line { flex: 1; height: 1px; background: repeating-linear-gradient(90deg, rgba(237,28,36,.5) 0 6px, transparent 6px 11px); }
.barrier-tag { font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em; color: var(--red); }

.locks { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 3px 28px; }
.locks li {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--mono); font-size: 11.5px;
  color: var(--ink-mute);
  opacity: .3;
}
.lk { width: 12px; height: 12px; border-radius: 3px; background: #dcdee2; position: relative; flex: none; }
.lk::after {
  content: ''; position: absolute; left: 4px; top: 2px;
  width: 3px; height: 6px; border: solid #fff; border-width: 0 1.4px 1.4px 0;
  transform: rotate(42deg); opacity: 0;
}

/* ── view tiles ────────────────────────────────────────────────────── */
/* Symmetric padding. These used to set an explicit width — `calc(100% + 96px)`
   on the room grid — which pushed the last column clean off the panel. */
.tiles {
  position: absolute; inset: 0;
  display: grid;
  grid-auto-rows: minmax(0, 1fr);
  padding: 46px var(--pad) var(--gbot);
}
.tiles-ga   { grid-template-columns: repeat(5, 1fr); gap: 22px; }
.tiles-room { grid-template-columns: repeat(8, 1fr); gap: 16px 14px; }

.tile { margin: 0; min-width: 0; }
.tiles > *, .wall > * { min-width: 0; }
.tile svg { display: block; width: 100%; height: auto; background: #fff; border: 1px solid var(--line); border-radius: 4px; }
/* Real drawings swapped in from sheets.js vary wildly in proportion — a room
   plan is nearly square, an interior elevation is a long strip. Left to size
   themselves they ragged every row. One frame proportion for all of them; the
   drawing letterboxes inside it via preserveAspectRatio="xMidYMid meet". */
.tile svg.rv-thumb {
  padding: 6px;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
}
.tiles-room .tile svg.rv-thumb { padding: 4px; aspect-ratio: 5 / 4; }
.tile figcaption {
  margin-top: 7px;
  font-family: var(--mono);
  font-size: 8.5px;
  letter-spacing: .04em;
  color: var(--ink-faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tiles-room figcaption { font-size: 7.5px; margin-top: 5px; }

/* Each tile owns one grid row and hands the whole of it to the drawing, which
   letterboxes inside via preserveAspectRatio. Nothing is ever sliced, and the
   drawing is always as large as the row allows. */
.tile { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.tile svg, .tile svg.rv-thumb {
  flex: 1 1 auto;
  width: 100%; height: 100%;
  min-height: 0;
  aspect-ratio: auto;
}
.tile figcaption { flex: none; }

.tilecount {
  position: absolute; right: 40px; bottom: 34px; z-index: 2;
  display: flex; align-items: baseline; gap: 10px;
  padding: 12px 18px;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-card);
  box-shadow: var(--shadow-card);
}
.tilecount .num { font-family: var(--mono); font-size: 26px; letter-spacing: -0.03em; color: var(--ink); }
.tilecount em { font-style: normal; font-size: 12.5px; color: var(--ink-mute); }

/* ── the finished set ──────────────────────────────────────────────── */
.wall {
  position: absolute; inset: 0;
  display: grid;
  /* 30 sheets over 10 columns is exactly three rows, so the set reads whole
     instead of having its bottom row sliced by the panel. */
  grid-template-columns: repeat(10, 1fr);
  grid-auto-rows: minmax(0, 1fr);
  gap: 18px 14px;
  padding: 44px var(--pad) var(--gbot);
}
.wall svg { display: block; width: 100%; height: auto; background: #fff; border: 1px solid var(--line); border-radius: 3px; }

.setstats {
  position: absolute; left: var(--pad); bottom: 34px; z-index: 2;
  display: flex; align-items: flex-end; gap: 34px;
  padding: 20px 28px;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-card);
  box-shadow: var(--shadow-win);
}
.setstats > div { display: flex; flex-direction: column; gap: 2px; }
.setstats em { font-style: normal; font-size: 12.5px; color: var(--ink-mute); }
.ss-run { flex-direction: row !important; align-items: center; gap: 9px !important; font-family: var(--mono); font-size: 11px; letter-spacing: .05em; color: var(--ink-faint); padding-bottom: 6px; }
.ss-run .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--red); }

/* ══ motion ═══════════════════════════════════════════════════════════ */
@keyframes aRise   { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes aTile   { from { opacity: 0; transform: translateY(10px) scale(.96); } to { opacity: 1; transform: none; } }
@keyframes aRow    { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
@keyframes aSettle { from { opacity: 0; filter: blur(5px); transform: translateY(6px); } to { opacity: 1; filter: blur(0); transform: none; } }
@keyframes aDraw   { from { stroke-dashoffset: 1000; } to { stroke-dashoffset: 0; } }
@keyframes aLv     { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
@keyframes aScope  { from { opacity: 0; transform: scale(.86); } to { opacity: 1; transform: none; } }
@keyframes aTag    { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; transform: none; } }
@keyframes aSnap   { from { transform: translateY(-104px); } to { transform: none; } }
@keyframes aSnapX  { from { transform: translateX(-118px); } to { transform: none; } }
@keyframes aSheet  { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
@keyframes aVp     { from { opacity: 0; transform: translate(-54px, 12px); } to { opacity: 1; transform: none; } }
@keyframes aTtl    { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes aFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes aFadeOut{ from { opacity: 1; } to { opacity: 0; } }
@keyframes aUnlock { from { opacity: .3; } to { opacity: 1; } }
@keyframes aTick   { from { background: #dcdee2; } to { background: #16171a; } }
@keyframes aCrop   { from { opacity: 0; transform: scale(1.03); } to { opacity: .55; transform: none; } }

.pipe-panel.on .a-rise   { animation: aRise   .70s var(--ease) var(--d, 0s) both; }
.pipe-panel.on .a-tile   { animation: aTile   .52s var(--ease) var(--d, 0s) both; }
.pipe-panel.on .a-row    { animation: aRow    .46s var(--ease) var(--d, 0s) both; }
.pipe-panel.on .a-settle { animation: aSettle .58s var(--ease) var(--d, 0s) both; }
.pipe-panel.on .a-lv     { animation: aLv     .80s var(--ease) var(--d, 0s) both; }
.pipe-panel.on .a-tag    { animation: aTag    .48s var(--ease) var(--d, 0s) both; }
.pipe-panel.on .a-sheet  { animation: aSheet  .70s var(--ease) var(--d, 0s) both; }
.pipe-panel.on .a-vp     { animation: aVp     .62s var(--ease) var(--d, 0s) both; }
.pipe-panel.on .a-ttl    { animation: aTtl    .50s var(--ease) var(--d, 0s) both; }

.pipe-panel.on .a-scope  { animation: aScope  .60s var(--ease) var(--d, 0s) both; transform-box: fill-box; transform-origin: 50% 50%; }
.pipe-panel.on .a-snap   { animation: aSnap   .70s var(--ease) var(--d, 0s) both; }
.pipe-panel.on .a-snapx  { animation: aSnapX  .70s var(--ease) var(--d, 0s) both; }
.pipe-panel.on .a-crop   { animation: aCrop   .60s var(--ease) .95s both; }
.a-crop { opacity: 0; }
.pipe-panel.on .draw     { stroke-dasharray: 1000; animation: aDraw 1.1s var(--ease) var(--d, 0s) both; }

.pipe-panel.on .pill-review { animation: aFadeOut .30s ease .80s both; }
.pipe-panel.on .pill-ok     { animation: aFadeIn  .34s ease .92s both; }
.pipe-panel.on .barrier     { animation: aFadeOut .50s ease .80s both; }
.pipe-panel.on .a-unlock    { animation: aUnlock .40s ease var(--d, 0s) both; }
.pipe-panel.on .a-unlock .lk{ animation: aTick   .34s ease var(--d, 0s) both; }
.pipe-panel.on .a-unlock .lk::after { animation: aFadeIn .24s ease calc(var(--d, 0s) + .16s) both; }

/* ══ degradation: anyone who asked for less motion ══
   No sticky, no scroll animation — every state in order, graphic then label.
   Narrow screens no longer land here: they run the same scroll mechanism in a
   single column, laid out further down. */
@media (prefers-reduced-motion: reduce) {
  .pipe-scroll { height: auto; padding: 0; }
  .pipe-steps  { display: none; }

  .pipe-frame {
    position: static;
    display: block;
    height: auto; min-height: 0;
    border: 0;
  }
  .pipe-nav { display: none; }
  .pipe-stack { overflow: visible; }

  .pipe-panel {
    position: relative;
    inset: auto;
    display: flex;
    flex-direction: column-reverse;
    opacity: 1; visibility: visible; transform: none;
    border-top: 1px solid var(--line);
  }
  .pp-head { border: 0; padding: 30px var(--gutter) 40px; }
  .pp-head h3 { max-width: 26ch; }
  .pp-stages { display: block; }
  .pp-graphic { height: min(60vh, 440px); }
  .pg-pad { padding: 24px 0 0 var(--gutter); }
  .pg-centre { padding: 20px var(--gutter); }
  .tiles, .wall { padding-left: var(--gutter); padding-top: 24px; }

  .pill-review { opacity: 0; }
  .pill-ok     { opacity: 1; }
  .barrier     { opacity: 0; }
  .locks li    { opacity: 1; }
  .lk          { background: var(--red); }
  .lk::after   { opacity: 1; }
  .a-crop      { opacity: .55; }
}

/* ══ narrow screens: the same scroll mechanism, in one column ══════════════
   The rail cannot be 17 items tall on a phone, so it collapses to a one-line
   status strip — active phase, active stage, count — with a progress bar drawn
   from --pipe-progress (set by pipeline.js). Everything below the strip is the
   panel: compact heading, then the graphic filling the rest of the frame. */
@media (max-width: 900px) {
  .pipe {
    --navh: 56px;         /* chrome.css drops the bar to 56px at this width */
    --pad: 20px;          /* graphics get the width back */
    --gbot: 20px;
    --headh: auto;        /* the heading sets its own height here */
  }

  .pipe-intro { padding: 72px var(--gutter) 40px; }
  .pipe-intro h2 { max-width: none; }

  /* One scroll step per panel, a little shorter than desktop so the section
     does not become an endless swipe on a phone. */
  .pipe-scroll { height: calc(9 * max(86vh, 580px)); padding: 0; }
  .pipe-steps  { inset: 0; }

  .pipe-frame {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    height: calc(100vh - var(--navh));
    height: calc(100dvh - var(--navh));
    min-height: 0;
    border-left: 0;
    border-right: 0;
  }

  /* ── the 17-stage rail becomes a status strip ── */
  .pipe-nav {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 9px;
    height: 44px;
    padding: 0 var(--pad);
    border-right: 0;
    border-bottom: 1px solid var(--line);
    overflow: hidden;
  }
  /* the vertical hairline and its accent tick have no meaning laid out flat */
  .pipe-rail, .pipe-tick { display: none; }
  .pipe-nav::after {
    content: '';
    position: absolute;
    left: 0; bottom: 0;
    width: 100%; height: 2px;
    background: var(--red);
    transform: scaleX(var(--pipe-progress, 0));
    transform-origin: left center;
    transition: transform .55s var(--ease);
  }

  .pipe-navinner {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    min-width: 0;
  }

  /* only the running phase and the running stage are shown */
  .ph { display: none; margin: 0; }
  .ph.on { display: flex; align-items: baseline; gap: 9px; min-width: 0; }
  .ph-name { font-size: 13px; letter-spacing: -0.01em; flex: none; }
  .ph-stages { display: flex; gap: 8px; margin: 0; min-width: 0; }
  .ph-stages li { display: none; }
  .ph-stages li.on {
    display: block;
    font-size: 12px;
    line-height: 1.4;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* Several stages run in one panel; after the first, the rest would overflow
     the strip. The heading already names them. */
  .ph-stages li.on ~ li.on { display: none; }

  .pipe-count { margin: 0 0 0 auto; flex: none; font-size: 10.5px; }

  /* ── panels ── */
  .pp-head {
    padding: 17px var(--pad) 15px;
  }
  .pp-head h3 {
    max-width: none;
    font-size: clamp(19px, 5.2vw, 23px);
    line-height: 1.26;
  }
  /* The strip already names the running stage, so repeating it here only eats
     height the graphic needs. */
  .pp-stages { display: none; }

  .pg-pad    { padding: 20px var(--pad) var(--gbot); gap: 14px; }
  .pg-centre { padding: 16px var(--pad) calc(16px + var(--gbot)); }
  .tiles, .wall { padding: 20px var(--pad) var(--gbot); }

  /* Column counts chosen so every drawing fits at its natural size — no
     squashing, and nothing sliced off the bottom. The old rules bled the grid
     40px past the right edge, which cropped the last column. */
  .tiles-ga   { grid-template-columns: repeat(4, 1fr); gap: 12px 10px; width: auto; }
  .tiles-room { grid-template-columns: repeat(5, 1fr); gap: 9px 8px;   width: auto; }
  .wall       { grid-template-columns: repeat(5, 1fr); gap: 9px 8px;   width: auto; }

  .card-types, .card-tally { display: none; }
  .setstats { left: var(--pad); right: var(--pad); bottom: 14px; gap: 18px; padding: 12px 15px; }
  .setstats .num.xl { font-size: 22px; }
  .ss-run { display: none; }
  .tilecount { right: 14px; bottom: 14px; padding: 8px 13px; }
  .tilecount .num { font-size: 18px; }
  .locks { grid-template-columns: 1fr; }
  .ap-stats { grid-template-columns: repeat(2, 1fr); }

  /* Cards live in a 350px-wide column here, so every fixed-width column and
     fixed row height below had to be reworked. */

  /* The 190px label column left ~120px for the value, so anything longer than
     two words wrapped — and the fixed 66px row height meant the wrap spilled
     over the row beneath it. Proportional columns, and rows that grow. */
  .setup-rows li {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr) 15px;
    align-items: start;
    gap: 10px;
    height: auto;
    padding: 11px 14px;
  }
  .sr-k { font-size: 12.5px; line-height: 1.35; }
  .sr-v { font-size: 12px; line-height: 1.4; }
  .tick { margin-top: 2px; }

  /* 88 + 176 + 62 of fixed columns plus gaps needed 416px. The 1fr view-name
     column was squeezed to nothing and the scale column fell off the right
     edge. Sheet and view name are the two the heading actually promises. */
  .mf-head, .mf-rows li {
    grid-template-columns: 74px minmax(0, 1fr);
    gap: 12px;
    padding: 0 14px;
  }
  .mf-head span:nth-child(3), .mf-head span:nth-child(4),
  .mf-rows li span:nth-child(3), .mf-rows li span:nth-child(4) { display: none; }
  .mf-head { height: 28px; font-size: 9px; }
  .mf-rows li { height: 30px; font-size: 10.5px; }

  /* All 14 stages have to clear the bottom of the frame once the write lock
     fades, so the stack above them tightens up. */
  .pg-centre { align-items: start; }
  .card-approve { margin-bottom: 16px; }
  .barrier { margin-bottom: 13px; }
  .locks { gap: 2px; }
  .locks li { font-size: 11px; }

  /* Only the three SVG panels use .pg, and each carries a stats card. Reserve
     the card its own band at the bottom so it stops landing on the drawing. */
  .pg { height: calc(100% - var(--gbot) - 124px); }
  .pg-readout, .ro-flat {
    left: var(--pad); right: var(--pad);
    top: auto; bottom: 14px;
    min-width: 0;
    padding: 12px 15px 11px;
  }
  .pg-readout dt { font-size: 12px; }
  .pg-readout dd { font-size: 12.5px; }
  .ro-title { margin-bottom: 7px; }

  /* .setstats > div is one class plus an element, so it outranked a bare
     .ss-run and the run label kept showing and wrapping under the figures. */
  .setstats .ss-run { display: none; }

  /* Panels 0 and 6 are single wide diagrams. A 2:1 drawing in a portrait area
     leaves room whatever you do, so the drawing and its stats card group at the
     top of a full-height block: content that hugs the top of a short grey block
     reads as the section ending early. */
  .pipe-panel[data-panel="0"] .pp-graphic,
  .pipe-panel[data-panel="6"] .pp-graphic { align-self: stretch; height: auto; }
  .pipe-panel[data-panel="0"] .pg,
  .pipe-panel[data-panel="6"] .pg { top: 14px; bottom: auto; height: 226px; }
  .pipe-panel[data-panel="0"] .pg-readout,
  .pipe-panel[data-panel="6"] .pg-readout { top: 252px; bottom: auto; }
}


/* ══ narrow AND short: the card panels need a tighter fit ══════════════════
   At 360x640 the frame is only 584px tall, which leaves roughly 400px for a
   graphic. The three card panels are the only ones that do not fit in that:
   the drawing walls scale by column count, but a settings list, a manifest and
   a 14-stage checklist all have a fixed number of rows. */
@media (max-width: 900px) and (max-height: 740px) {
  .pipe { --gbot: 14px; }

  /* claw back some height from the heading */
  .pp-head { padding: 13px var(--pad) 12px; }
  .pp-head h3 { font-size: clamp(17px, 4.6vw, 20px); line-height: 1.24; }

  .tiles, .wall { padding-top: 14px; }
  .pg-pad { padding-top: 14px; }

  /* every setting still has to be readable, so this tightens rather than hides */
  .setup-rows li { padding: 8px 12px; }
  .sr-k { font-size: 11.5px; }
  .sr-v { font-size: 11px; }
  .card-bar { height: 34px; }

  /* Eight rows of room drawings need ~575px and there are ~410 here. Showing
     30 of the 40 keeps six complete rows at a legible size; the counter card
     still reports the real total. */
  .tiles-room .tile:nth-child(n+31) { display: none; }

  /* A manifest is a long list by nature, so showing fewer rows reads as
     "and so on" — unlike the settings card, where a hidden row is a lie. */
  .mf-rows li { height: 27px; font-size: 10px; }
  .mf-rows li:nth-child(n+12) { display: none; }

  /* two columns halves the checklist's height, which is what was pushing the
     last stages past the bottom of the frame */
  .locks { grid-template-columns: 1fr 1fr; gap: 2px 14px; }
  .locks li { font-size: 10px; gap: 7px; }
  .lk { width: 10px; height: 10px; }
  .card-approve { margin-bottom: 12px; }
  .barrier { margin-bottom: 10px; }
  .ap-stats > div { padding: 12px 14px; }
  .ap-stats dt { font-size: 11px; margin-bottom: 3px; }
  .ap-stats dd { font-size: 18px; }
  .ap-stats .num.xl { font-size: 24px; }

  /* the stats cards shrink with everything else */
  .pg { height: calc(100% - var(--gbot) - 104px); }
  .pipe-panel[data-panel="0"] .pg,
  .pipe-panel[data-panel="6"] .pg { top: 10px; height: 180px; }
  .pipe-panel[data-panel="0"] .pg-readout,
  .pipe-panel[data-panel="6"] .pg-readout { top: 200px; }
  .pg-readout { padding: 10px 13px 9px; }
  .pg-readout dt { font-size: 11px; }
  .pg-readout dd { font-size: 11.5px; }
  .pg-readout dl > div { padding: 3px 0; }
  .ro-title { font-size: 9px; margin-bottom: 5px; }
}


/* Laptop-height desktops: the card panels have a fixed number of rows, so
   unlike the drawing walls they cannot scale by column count. A 900px-tall
   window leaves ~556px for a graphic, and nine 66px setting rows plus a card
   bar need 634 — the last row was cut off. */
@media (min-width: 901px) and (max-height: 950px) {
  .setup-rows li { height: 54px; }
  .type-rows li  { height: 50px; }
  .mf-rows li    { height: 29px; }
}

/* short viewports: tighten the column so 17 stages still fit */
@media (min-width: 901px) and (max-height: 820px) {
  .setup-rows li { height: 44px; }
  .type-rows li  { height: 42px; }
  .mf-rows li    { height: 25px; font-size: 10.5px; }
  .mf-rows li:nth-child(n+15) { display: none; }
  .card-bar { height: 34px; }
  .pipe { --headh: 158px; }
  .ph { margin-bottom: 18px; }
  .ph-name { font-size: 16.5px; }
  .ph-stages li { font-size: 11.5px; line-height: 1.86; }
  .pipe-count { margin-top: 20px; }
  .pp-head { padding-top: 42px; }
}
