/* lab.css — chrome for the prototyping surface only.
 *
 * Scoped to .is-lab, which lab.js sets only on lab-maestro, so this file is
 * inert on the three published surfaces.
 *
 * Styled to artifactory's system: a dark translucent pod over the work, hairline
 * edges, a 3/6/9 rhythm, 12px radii, and white as the only signal. Tokens are
 * declared locally rather than imported — the page's :root belongs to Maestro,
 * and overwriting it would restyle the prototype inside the phone.
 *
 * Archivo everywhere, including the numerals, which use tabular figures so the
 * times and revision tags line up without a second family.
 */

.is-lab {
  /* artifactory sets .74 because its canvas is already #0c0d10. This pod sits
     over a warm-white prototype, where .74 lands at mid-grey and the system's
     near-white ink loses its contrast. Raised until the pod carries its own
     ground; the blur stays, so it still reads as glass at the edge. */
  --lab-pod:     rgba(13, 14, 17, .96);
  --lab-edge:    rgba(233, 238, 246, .16);
  --lab-in:      rgba(228, 236, 248, .06);
  --lab-in-2:    rgba(228, 236, 248, .10);
  --lab-hair:    rgba(233, 238, 246, .09);
  --lab-ink:     #e7eaee;
  --lab-ink-2:   #adb2bb;
  --lab-ink-3:   #7c818b;
  /* ink-4 measures 2.63:1 on this pod and is not a text colour. artifactory
     uses it for text; at 9px on a dark pod that fails AA by a wide margin, so
     here it is kept for the graph's strokes and dots and nothing that reads. */
  --lab-ink-4:   #565b64;
  --lab-signal:  #fff;
  /* The app's accent, the pale green the SHOWING chip already uses, brought
     into the lab namespace rather than referenced across it. */
  --lab-green:   oklch(0.9240 0.0984 116.9);
  --lab-on-sig:  #0b0c0e;
  --lab-well:    rgba(0, 0, 0, .22);

  --lab-font:    "Archivo", -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif;
  --lab-blur:    saturate(180%) blur(52px);
  --lab-sh:      inset 0 1px 0 rgba(255, 250, 235, .1);

  --lab-r:       12px;
  --lab-pill:    999px;              /* artifactory --r-pill */
  --lab-edge-p:  9px;
  --lab-tight:   3px;
  --lab-lock:    6px;
  --lab-group:   9px;

  --lab-rail:    340px; /* was 304: the view tabs are the widest thing on
                                the panel and they were being asked to fit a
                                width chosen before they existed */;
}

.is-lab .lab-rail,
.is-lab .lab-flag,
.is-lab .lab-rail * { font-family: var(--lab-font); }

/* The indicator rides in the pod register too, so it reads as one system. */
.is-lab .lab-flag {
  position: fixed; top: var(--lab-group); left: var(--lab-group); z-index: 60;
  display: inline-flex; align-items: center;
  min-height: 34px; padding: 0 18px;
  border-radius: var(--lab-pill);
  background: var(--lab-pod); color: var(--lab-ink);
  border: 1px solid var(--lab-edge);
  box-shadow: var(--lab-sh);
  -webkit-backdrop-filter: var(--lab-blur); backdrop-filter: var(--lab-blur);
  font-size: 13px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
}

.is-lab .lab-rail {
  position: fixed; z-index: 55;
  top: var(--lab-group); right: var(--lab-group); bottom: var(--lab-group);
  width: var(--lab-rail); overflow: hidden;
  display: grid; grid-template-rows: auto 1fr;
  border-radius: var(--lab-r);
  background: var(--lab-pod);
  border: 1px solid var(--lab-edge);
  box-shadow: var(--lab-sh);
  -webkit-backdrop-filter: var(--lab-blur); backdrop-filter: var(--lab-blur);
  color: var(--lab-ink);
}
.is-lab body { padding-right: calc(var(--lab-rail) + var(--lab-group) * 2); }

/* The pod's own header, which is also the collapse control. */
.is-lab .lab-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--lab-lock);
  padding: var(--lab-group) var(--lab-edge-p);
  border-bottom: 1px solid var(--lab-hair);
}
.is-lab .lab-head h1 {
  margin: 0; font-size: 11px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--lab-ink-3);
}
.is-lab .lab-toggle {
  flex: none; width: 24px; height: 24px; padding: 0;
  display: grid; place-items: center;
  border: 1px solid var(--lab-edge); border-radius: var(--lab-r);
  background: var(--lab-in); color: var(--lab-ink-2);
  font-size: 11px; line-height: 1; cursor: pointer;
}
.is-lab .lab-toggle:hover { background: var(--lab-in-2); color: var(--lab-ink); }

.is-lab .lab-body {
  overflow-y: auto; padding: var(--lab-edge-p);
  display: grid; gap: 22px; align-content: start;
}

/* Collapsed: the pod becomes the control that reopens it. */
.is-lab .lab-rail.is-collapsed { width: auto; grid-template-rows: auto; }
.is-lab .lab-rail.is-collapsed .lab-body { display: none; }
.is-lab .lab-rail.is-collapsed .lab-head { border-bottom: 0; }
.is-lab .lab-rail.is-collapsed .lab-head h1 { display: none; }
.is-lab .lab-rail.is-collapsed ~ .lab-mark,
.is-lab body:has(.lab-rail.is-collapsed) { }
.is-lab.is-collapsed body { padding-right: 0; }

.is-lab .lab-group { display: grid; gap: 0; }
.is-lab .lab-group h2,
.is-lab .lab-group > summary {
  margin: 0 0 var(--lab-lock);
  font-size: 11px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--lab-ink-3);
}
/* A closed fold has nothing under it, so the heading's bottom margin would be
   space with no reason. The marker stays: it is the only thing saying the
   heading can be opened. */
.is-lab .lab-group > summary {
  cursor: pointer; list-style: revert;
}
.is-lab .lab-group.is-foldable:not([open]) > summary { margin-bottom: 0; }
.is-lab .lab-group > summary:hover { color: var(--lab-ink-2); }
.is-lab .lab-group > summary:focus-visible {
  outline: 2px solid #fff; outline-offset: 2px;
}

/* Controls. A well holding two states, the active one filled in the pale
   green, so it reads as the same selected state as the view tabs. */
.is-lab .lab-rail .proto-switch {
  display: grid; gap: var(--lab-lock); justify-items: start;
  margin: 0; padding: var(--lab-group) 0; background: none;
  border-radius: 0; border-bottom: 1px solid var(--lab-hair);
}
.is-lab .lab-rail .proto-switch:last-child { border-bottom: 0; }
.is-lab .lab-rail .proto-switch-label {
  font-size: 11px; font-weight: 400; letter-spacing: 0;
  text-transform: none; color: var(--lab-ink-3);
}
.is-lab .lab-rail .proto-switch-set {
  width: 100%; gap: var(--lab-tight); padding: var(--lab-tight);
  border-radius: var(--lab-r); background: var(--lab-well);
}
.is-lab .lab-rail .proto-switch-set button {
  flex: 1; min-height: 24px; padding: 5px 8px; white-space: nowrap;
  border: 0; border-radius: calc(var(--lab-r) - var(--lab-tight));
  background: transparent; color: var(--lab-ink-3);
  font-size: 11px; font-weight: 500; box-shadow: none; cursor: pointer;
}
.is-lab .lab-rail .proto-switch-set button.is-active {
  background: var(--lab-green); color: var(--lab-on-sig); box-shadow: none;
}

/* Screens. */
.is-lab .lab-seq { list-style: none; margin: 0; padding: 0; counter-reset: step; }
.is-lab .lab-seq li { counter-increment: step; }
.is-lab .lab-seq button {
  width: 100%; display: flex; align-items: baseline; gap: var(--lab-group);
  padding: var(--lab-lock) var(--lab-lock); border: 0;
  border-radius: calc(var(--lab-r) - 4px);
  background: none; cursor: pointer; text-align: left;
  font-size: 12px; color: var(--lab-ink-2);
}
.is-lab .lab-seq button::before {
  content: counter(step, decimal-leading-zero);
  font-size: 11px; font-variant-numeric: tabular-nums; color: var(--lab-ink-3);
}
.is-lab .lab-seq button:hover { background: var(--lab-in); color: var(--lab-ink); }
.is-lab .lab-seq button.is-active { background: var(--lab-in-2); color: var(--lab-ink); }
.is-lab .lab-seq button.is-active::before { color: var(--lab-ink-2); }

/* Version history. */
.is-lab .lab-revs { list-style: none; margin: 0; padding: 0; }
.is-lab .lab-revs li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--lab-group); }
.is-lab .lab-revs li > * { min-width: 0; }
.is-lab .lab-rev > * { min-width: 0; }
.is-lab .lab-rev-graph { position: relative; }
.is-lab .lab-rev-graph svg { display: block; width: 100%; height: 100%; }
.is-lab .lab-lane, .is-lab .lab-join {
  fill: none; stroke: var(--lab-edge); stroke-width: 1; vector-effect: non-scaling-stroke;
}
.is-lab .lab-dot {
  position: absolute; top: 15px; width: 5px; height: 5px;
  margin-left: -2.5px; border-radius: 50%;
  background: var(--lab-ink-3); box-shadow: 0 0 0 3px rgba(19, 21, 25, .9);
}
/* A merge is the event on this graph worth finding, so it is the one dot that
   is filled, coloured and bigger than its lane. top moves up by the two pixels
   the extra height adds, so the dot stays centred on the lane it sits in
   rather than drifting below the commits around it. */
.is-lab .lab-dot.is-merge {
  top: 13px; width: 9px; height: 9px; margin-left: -4.5px;
  background: var(--lab-green);
  box-shadow: 0 0 0 1px var(--lab-green), 0 0 0 4px rgba(19, 21, 25, .9);
}
/* The current revision paints its dot white; a merge keeps its colour. */
.is-lab .is-here .lab-dot.is-merge { background: var(--lab-green); }
/* The revision you are looking at is the other event worth finding on this
   graph, so it takes the same size as a merge. Same two-pixel lift, for the
   same reason: the dot stays centred on its lane. It keeps the signal white,
   and a merge that is also the current revision keeps its green: the
   .is-merge rule above carries four classes to this one's three, so it wins on
   specificity rather than on order. */
.is-lab .is-here .lab-dot {
  top: 13px; width: 9px; height: 9px; margin-left: -4.5px;
  background: var(--lab-signal); box-shadow: 0 0 0 3px rgba(19, 21, 25, .9);
}

.is-lab .lab-day { align-items: center; min-height: 26px; }
.is-lab .lab-day span {
  font-size: 11px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--lab-ink-3);
}

.is-lab .lab-rev {
  display: grid; gap: var(--lab-tight);
  padding: var(--lab-group) 0;
  border-bottom: 1px solid var(--lab-hair);
  text-decoration: none; color: inherit;
}
.is-lab .lab-rev-head {
  display: flex; align-items: center; gap: var(--lab-lock);
  font-size: 11px; font-variant-numeric: tabular-nums; color: var(--lab-ink-3);
}
.is-lab .lab-who { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.is-lab .lab-avatar {
  flex: none; width: 16px; height: 16px; border-radius: 50%;
  display: inline-grid; place-items: center;
  background: var(--lab-in-2); color: var(--lab-ink-2);
  font-size: 8px; font-weight: 600;
}
/* When the account has a picture, it replaces the initials rather than sitting
   beside them; the initials stay underneath as the fallback for a broken or
   blocked image. */
.is-lab .lab-avatar.has-photo {
  color: transparent; background-size: cover; background-position: center;
}
.is-lab .lab-who-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.is-lab .lab-rev-subject { font-size: 12px; font-weight: 400; line-height: 1.4; color: var(--lab-ink); }
.is-lab div.lab-rev .lab-rev-subject { color: var(--lab-ink-3); }
.is-lab .lab-rev-foot {
  display: flex; align-items: baseline; gap: var(--lab-lock);
  font-size: 11px; font-variant-numeric: tabular-nums; color: var(--lab-ink-3);
}
/* The version is the row's name: brightest, heaviest, and tabular so the
   column of them reads straight down the rail. */
.is-lab .lab-rev-tag {
  flex: none; font-weight: 700; color: var(--lab-ink);
  font-variant-numeric: tabular-nums; letter-spacing: .01em;
}
.is-lab .lab-rev-mod { flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.is-lab .lab-ship { flex: none; }
/* Where a revision stands against production, carried by a dot rather than by
   a second colour: filled means it is live, hollow means it is not. The words
   already say which; the dot is what makes the column scannable at a glance. */
.is-lab .lab-ship.is-prod { color: var(--lab-ink-2); }
.is-lab .lab-ship.is-lab { color: var(--lab-signal); }
.is-lab .lab-ship.is-live,
.is-lab .lab-ship.is-pending {
  display: inline-flex; align-items: center; gap: 6px;
}
.is-lab .lab-ship.is-live::before,
.is-lab .lab-ship.is-pending::before {
  content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%;
}
/* Outstanding is loud, finished is quiet. A revision waiting to reach the
   portal carries white text and a filled white mark; one already there is
   dimmed to the quiet ink and keeps a hollow mark. Legible, not hidden --
   the point is that it no longer asks anything of you. */
/* The mark for work that has not reached the portal carries a halo, so it
   reads as lit rather than as a full stop. It is the only white circle in the
   list and it has to be findable while scrolling, not only while reading. */
.is-lab .lab-ship.is-pending { color: #fff; font-weight: 600; }
.is-lab .lab-ship.is-pending::before {
  background: #fff;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, .16), 0 0 8px rgba(255, 255, 255, .45);
}
.is-lab .lab-ship.is-live { color: var(--lab-ink-3); }
.is-lab .lab-ship.is-live::before {
  box-shadow: inset 0 0 0 1px var(--lab-ink-3);
}

/* The whole row follows the same rule, so the rail reads as a queue rather
   than as a list everything shouts from equally. */
.is-lab .lab-rev.is-done .lab-rev-subject { color: var(--lab-ink-3); }
.is-lab .lab-rev.is-done .lab-rev-tag { color: var(--lab-ink-2); font-weight: 600; }
.is-lab .lab-rev.is-waiting .lab-rev-subject { color: #fff; }
.is-lab .lab-rev.is-waiting .lab-rev-tag { color: #fff; }
.is-lab a.lab-rev.is-done:hover .lab-rev-subject { color: var(--lab-ink-2); }
.is-lab .lab-ship.is-open { color: var(--lab-ink-3); }
.is-lab a.lab-rev:hover .lab-ship.is-open { color: var(--lab-ink); }

/* The second meta line: what it touched, under who and when. */
.is-lab .lab-rev-head.is-sub { margin-top: 1px; }

/* The standing answer to "what have I not pushed to the portal yet", sitting
   directly above the button that closes the gap. */
.is-lab .lab-standing {
  margin: 0 0 8px; padding: 8px 10px;
  border-radius: calc(var(--lab-r) - 6px);
  background: rgba(255, 255, 255, .04);
  font: 400 11px/1.45 var(--lab-font); color: var(--lab-ink-3);
}
.is-lab .lab-standing b { color: var(--lab-ink); font-weight: 700; }
.is-lab .lab-standing.is-behind { background: rgba(255, 255, 255, .07); }
/* A filled chip rather than a line of coloured text, sitting beside the
   version it names. It is the row you scan for first, so it is the one thing
   in the list that carries a ground of its own. */
.is-lab .lab-rev-here {
  flex: none;
  padding: 2px 6px; border-radius: 999px;
  background: var(--lab-green); color: var(--lab-on-sig);
  font-size: 9px; font-style: normal; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; line-height: 1.5;
}

/* The ROW track has to be pinned, not the li's box. The lane SVG carries a
   0 0 24 100 viewBox and no definite height, so it asserts 100px intrinsic;
   clamping the li to 26px left the grid row at 100 and the label centred in
   it, landing on the version underneath. It is a join between two rows, not a
   row of its own. */
.is-lab .lab-gap { align-items: center; grid-template-rows: 26px; }
.is-lab .lab-gap .lab-rev-graph { align-self: stretch; }
.is-lab .lab-gap .lab-rev-graph svg { height: 100%; }
.is-lab .lab-gap-time { font-size: 11px; font-variant-numeric: tabular-nums; color: var(--lab-ink-3); }
.is-lab .lab-empty { margin: 0; font-size: 11px; color: var(--lab-ink-3); }

.is-lab .lab-mark {
  position: fixed; z-index: 56;
  right: calc(var(--lab-rail) + var(--lab-group) * 3); bottom: var(--lab-group);
  display: block; line-height: 0; opacity: .38;
}
.is-lab.is-collapsed .lab-mark { right: var(--lab-group); }
.is-lab .lab-mark img { display: block; width: 116px; height: auto; }

@media (max-width: 900px) {
  .is-lab .lab-rail { position: static; width: auto; margin: var(--lab-group); }
  .is-lab body { padding-right: 0; }
  .is-lab .lab-mark { right: var(--lab-group); }
}


/* Focus. There was none: no rule in this file mentioned :focus-visible, so a
   keyboard reached every control in the rail and nothing showed where it was.
   One treatment for all of them — the signal colour, offset so it reads on the
   pod rather than merging with a control's own edge. */
.is-lab .lab-rail :is(button, a):focus-visible,
.is-lab .lab-flag:focus-visible {
  outline: 2px solid var(--lab-signal);
  outline-offset: 2px;
  border-radius: calc(var(--lab-r) - 4px);
}
.is-lab .lab-rev:focus-visible { border-radius: var(--lab-r); }

/* Where this build came from. In the pod's header because provenance is a
   property of the panel, not of any one revision in it. */
.is-lab .lab-source {
  display: grid; gap: 1px; min-width: 0; margin-right: auto;
  text-decoration: none; color: var(--lab-ink-3);
}
.is-lab .lab-source b {
  font-size: 11px; font-weight: 600; letter-spacing: .02em; color: var(--lab-ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.is-lab .lab-source span {
  font-size: 11px; font-variant-numeric: tabular-nums; color: var(--lab-ink-3);
}
.is-lab .lab-head h1 { margin-right: var(--lab-lock); }


/* The merge chip carries the same green as the dot it explains, so the mark on
   the graph and the word in the row read as one thing rather than two. Outline
   rather than filled: shipped is the filled state, and a merge is a shape of
   history, not a stage of delivery. */
.is-lab .lab-ship.is-merge {
  color: var(--lab-green);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--lab-green) 45%, transparent);
  background: transparent;
}


/* Capture is the one thing on this rail that writes rather than reads, so it is
   the one filled control. It sits above the history because what it records is
   the state you are in now, not a revision you are looking back at. */
/* The two capture buttons carry their own accent: white, over a translucent
   ground rather than a filled one. The rail's green stays a signal -- the merge
   dot, the active view, "open this build" -- and a green button sitting next to
   a green dot made the loudest colour mean two unrelated things. */
.is-lab .lab-capture {
  display: block; width: 100%;
  margin: 0 0 6px; padding: 9px 12px;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: calc(var(--lab-r) - 4px);
  background: rgba(255, 255, 255, .06); color: #fff;
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  backdrop-filter: blur(14px) saturate(160%);
  font: 600 12px/1 var(--lab-font); letter-spacing: .01em;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease;
}
.is-lab .lab-capture:hover {
  background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .24);
}
.is-lab .lab-capture:focus-visible {
  outline: 2px solid #fff; outline-offset: 2px;
}


/* The hint sits under the control it explains, at the rail's quiet step. It is
   not a tooltip: what a button does before you press it should be readable
   without hovering, and there is nothing to hover on a touch screen. */
.is-lab .lab-capture-hint {
  margin: 0 0 12px;
  font: 400 11px/1.45 var(--lab-font);
  color: var(--lab-ink-3);
}


/* ---- A build is a row -----------------------------------------------------
   Without the commit lanes beside it a build row carries its own left edge, so
   the list still reads as a spine rather than as stacked cards. */
/* The graph column is back, so the row needs no stand-in edge of its own: the
   lanes are the spine, the way a version history draws it. */
.is-lab .lab-build { padding-left: 0; border-left: 0; }

/* The commits inside. Closed by default: a reviewer opens a build first and
   asks what is in it second. */
.is-lab .lab-changes { margin: 6px 0 0; }
.is-lab .lab-changes summary {
  cursor: pointer; list-style: none;
  font: 600 11px/1 var(--lab-font); letter-spacing: .04em;
  text-transform: uppercase; color: var(--lab-ink-3);
  padding: 4px 0;
}
.is-lab .lab-changes summary::-webkit-details-marker { display: none; }
.is-lab .lab-changes summary:hover { color: var(--lab-ink-2); }
.is-lab .lab-changes summary:focus-visible {
  outline: 2px solid var(--lab-green); outline-offset: 2px;
}
.is-lab .lab-changes ul {
  margin: 2px 0 0; padding: 0 0 0 14px;
  font: 400 11.5px/1.5 var(--lab-font); color: var(--lab-ink-2);
}
.is-lab .lab-changes li { margin: 0 0 3px; }
.is-lab .lab-changes li.is-merge-change { color: var(--lab-green); }


/* ---- The views, as tabs ---------------------------------------------------
   Five surfaces, so they wrap rather than scroll: a row you have to drag is a
   row whose last item nobody finds. Quiet until chosen, because the panel's one
   filled control is Note this view. */
/* ---- The views mirror the page's own nav ----------------------------------
   The nav pill is a translucent track holding tabs with the current one filled.
   This is the same object at panel scale: one row, one track, one filled tab.

   It was five stacked rows, which read as a menu of destinations rather than as
   where you are -- the thing a tab bar says and a list does not. Larger than the
   controls under it too, because which view you are in is the coarsest choice on
   the panel and everything below it is read inside that choice.

   The filled tab takes the accent rather than white: white is the capture
   button's, and two filled white things on one panel would rank equally. */
.is-lab .lab-views {
  display: flex; gap: 1px;
  padding: 4px;
  border-radius: var(--lab-pill, 999px);
  background: var(--lab-in);
}
/* Sized to their words, not to an equal fifth. Five equal tabs give "Map" the
   same room as "Prototype", so the long one clips while the short one sits in
   space it does not need. */
/* inline-flex rather than relying on a button's own centring: one of these is
   an anchor, and an anchor sits its text on the baseline instead, which left
   url- riding above its neighbours. */
.is-lab .lab-view {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 1 1 0; min-width: 0;
  min-height: 34px; padding: 0 4px;
  border: 0; border-radius: 999px;
  background: transparent; color: var(--lab-ink-2);
  font: 700 11px/1 var(--lab-font); letter-spacing: .01em;
  text-align: center; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.is-lab .lab-view:hover { color: var(--lab-ink); }
.is-lab .lab-view.is-active {
  background: var(--lab-green); color: var(--lab-on-sig); font-weight: 800;
}
.is-lab .lab-view:focus-visible { outline: 2px solid var(--lab-green); outline-offset: 2px; }


/* The portal button mirrors the capture button: same shape, same measure, sat
   directly under it, because they are the two things you can do with a state
   you are looking at -- note it, or promote it. It takes the accent to separate
   promoting from noting, which is the same green the merge dot uses for the
   same reason: this is the one that moves work between branches. */
/* The CTA. lab now routes straight through to the published surfaces, so
   committing to the portal is the action this panel exists for and it is the
   one button that reads as solid. The other stays frosted, which is what makes
   this one rank -- the pair separates by ground, not by a second colour. */
.is-lab .lab-capture.is-portal {
  margin: 0 0 6px;
  background: rgba(255, 255, 255, .18);
  border-color: rgba(255, 255, 255, .3);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
.is-lab .lab-capture.is-portal:hover {
  background: rgba(255, 255, 255, .26); border-color: rgba(255, 255, 255, .42);
}


/* ---- The badge stops landing on the navbar --------------------------------
   The LAB flag is fixed to the top-left and the nav pill centres in the page,
   so the two met as soon as the window was narrow enough: at 1200 the pill ran
   under the badge, and at 1024 and below the badge sat on the Maestro lockup
   inside it.

   The bar reserves the flag's width instead. The pill still centres, now within
   what is left, so on the lab surface it sits a little right of the page centre
   -- which is honest: the lab chrome is occupying that corner. Reserved with
   max() so the reservation never eats the pill's own room on a narrow window.

   Scoped to .is-lab. The three published surfaces have no flag and centre on
   the page exactly as before. */
.is-lab { --lab-safe: 152px; }
.is-lab .prototype-bar {
  padding-left: max(var(--lab-group), var(--lab-safe));
  box-sizing: border-box;
}
@media (max-width: 760px) {
  /* Below this there is not enough width for both the flag and the pill on one
     line: reserving 152px of a 700px window leaves the pill less than it needs,
     and dropping the reservation just puts them back on top of each other. So
     the flag leaves the row entirely and sits at the bottom of the window,
     where nothing else is. It is an indicator, not a control -- it has to be
     visible, not reachable first. */
  .is-lab { --lab-safe: 0px; }
  .is-lab .lab-flag { top: auto; bottom: var(--lab-group); }
}


/* A surface that is somewhere else rather than a view of here. The arrow says
   so before it is clicked, which a tab that silently changes site does not. */
.is-lab a.lab-view.is-away { text-decoration: none; }
.is-lab a.lab-view.is-away::after { content: " \2197"; opacity: .55; }

/* The navigation map is a description of the surfaces, not one of them, so it
   sits under the row as a quiet line rather than competing as a sixth tab. */
.is-lab .lab-submap {
  display: block; width: 100%; margin: 6px 0 0; padding: 6px 8px;
  border: 0; border-radius: calc(var(--lab-r) - 6px);
  background: transparent; color: var(--lab-ink-3);
  font: 500 11px/1 var(--lab-font); text-align: left; cursor: pointer;
  transition: color 140ms ease, background 140ms ease;
}
.is-lab .lab-submap:hover { color: var(--lab-ink-2); background: var(--lab-in); }
.is-lab .lab-submap:focus-visible { outline: 2px solid var(--lab-green); outline-offset: 2px; }


/* Stacked faces, overlapped the way a repository shows a co-authored commit.
   The ring is the rail's own ground, so the overlap reads as depth rather than
   as two circles touching. */
.is-lab .lab-faces { display: inline-flex; align-items: center; }
.is-lab .lab-faces > .lab-avatar + .lab-avatar { margin-left: -6px; }
.is-lab .lab-faces > .lab-avatar {
  box-shadow: 0 0 0 1.5px var(--lab-in, #131519);
}

/* The meta line never wraps: a date broken across two lines reads as two
   dates. Anything that does not fit is the name, and it ellipsises. */
.is-lab .lab-rev-head { flex-wrap: nowrap; }
.is-lab .lab-rev-head > time { flex: none; white-space: nowrap; }
.is-lab .lab-who { min-width: 0; }
.is-lab .lab-who-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}


/* ---- The surfaces carry colours -------------------------------------------
   The studio's own phase swatches, sampled from the board rather than matched
   by eye: strategy, identity, applications, production. A view is a place, and
   a place is easier to find by colour than by reading five near-identical
   prefixes. The colour is the tab's identity rather than its state, so it shows
   either way -- quiet as a label, filled as a pill when you are standing on it.

   Ink follows the swatch: dark on the chartreuse and the cyan, white on the
   magenta and the blue, which is how the board sets them. about- has no swatch
   of its own and stays white.

   p- is the exception at rest. #0209F5 against a near-black rail is 1.3:1, so
   the label would be a blue smudge; resting it uses a lightened cast of the
   same hue and only the filled pill carries the true blue. Same colour, read at
   the weight the ground allows. */
.is-lab {
  --s-url:  #DBFE57;
  --s-id:   #EA3BCB;
  --s-ds:   #6BE7ED;
  --s-p:    #0209F5;
  --s-p-lit: oklch(0.7200 0.2000 267);
  --s-id-lit: oklch(0.7200 0.2100 337);
}
.is-lab .lab-view[data-view="app"]      { color: var(--s-url); }
/* Resting magenta is lifted for the same reason as the blue: the true #EA3BCB
   measures 4.4:1 on this ground, just under AA at 11px. The pill carries the
   swatch exactly; the label carries as much of it as the rail can hold. */
.is-lab .lab-view[data-view="identity"] { color: var(--s-id-lit); }
.is-lab .lab-view[data-view="system"]   { color: var(--s-ds); }
.is-lab .lab-view[data-view="about"]    { color: #fff; }

.is-lab .lab-view[data-view="app"].is-active      { background: var(--s-url); color: #181818; }
.is-lab .lab-view[data-view="identity"].is-active { background: var(--s-id);  color: #fff; }
.is-lab .lab-view[data-view="system"].is-active   { background: var(--s-ds);  color: #181818; }
.is-lab .lab-view[data-view="about"].is-active    { background: #fff;         color: #181818; }

/* p- rests white. The swatch blue is #0209F5, which is 1.3:1 against this rail
   -- a lightened cast of it read as a different colour rather than as the same
   one dimmed, and the portal is the one surface here that is not a view. White
   at rest, the true blue when it fills. */
.is-lab a.lab-view.is-away {
  color: #fff;
  background-image: none;
  -webkit-text-fill-color: currentColor;
}
.is-lab a.lab-view.is-away:hover { color: var(--s-ds); }
.is-lab a.lab-view.is-away.is-active {
  background: var(--s-p); color: #fff; -webkit-text-fill-color: #fff;
}
.is-lab a.lab-view.is-away::after { -webkit-text-fill-color: currentColor; opacity: .6; }


/* ---- Signing in, in the rail ----------------------------------------------
   The device code has to be read off the screen and typed somewhere else, so
   it is set large and selectable rather than shown in a button label. */
.is-lab .lab-signin {
  display: grid; gap: 4px;
  margin: 0 0 8px; padding: 10px;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: calc(var(--lab-r) - 6px);
  background: rgba(255, 255, 255, .06);
  font: 400 11px/1.4 var(--lab-font); color: var(--lab-ink-3);
}
.is-lab .lab-signin b {
  font: 700 20px/1 var(--lab-font); letter-spacing: .16em; color: #fff;
  user-select: all;
}
.is-lab .lab-signed {
  display: flex; align-items: center; gap: 7px;
  margin: 0 0 8px;
  font: 500 11px/1 var(--lab-font); color: var(--lab-ink-2);
}
.is-lab .lab-signout {
  margin-left: auto; padding: 0; border: 0; background: none;
  font: 500 11px/1 var(--lab-font); color: var(--lab-ink-3);
  text-decoration: underline; cursor: pointer;
}
.is-lab .lab-signout:hover { color: #fff; }


/* ---- The chrome sits on the work, not over it -----------------------------
   Every panel here was effectively opaque, which made the rail a wall beside
   the prototype rather than something laid on it. They all take a real
   translucency and a blur now, so the work reads through the chrome.

   The blur is what makes this safe. Without it, translucency samples whatever
   pixel happens to be behind a glyph and the text crawls as the page scrolls;
   with it, the ground under any given panel is a smooth average and the
   contrast holds still. saturate keeps that average from going flat grey.

   Every text role over these grounds was re-measured after the change rather
   than assumed -- a translucent panel over a light prototype is a lighter
   ground than the token says, and the quiet inks are the ones that fall first. */
.is-lab .lab-rail {
  background: rgba(13, 14, 17, .80);
  -webkit-backdrop-filter: blur(26px) saturate(150%);
  backdrop-filter: blur(26px) saturate(150%);
}
.is-lab .lab-flag {
  background: rgba(13, 14, 17, .74);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  backdrop-filter: blur(18px) saturate(150%);
}
.is-lab .lab-views {
  background: rgba(255, 255, 255, .06);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
/* The rows become panels of their own, so the list reads as stacked cards the
   way a project row sits on its own bar. The spine still runs beside them. */
.is-lab .lab-revs .lab-rev {
  padding: 8px 10px;
  border-radius: calc(var(--lab-r) - 8px);
  background: rgba(255, 255, 255, .035);
  border: 1px solid rgba(255, 255, 255, .06);
}
.is-lab a.lab-revs .lab-rev:hover,
.is-lab .lab-revs a.lab-rev:hover {
  background: rgba(255, 255, 255, .07);
  border-color: rgba(255, 255, 255, .12);
}


/* The spine dot carries the same state the row does. */
.is-lab .lab-dot.is-waiting {
  background: #fff;
  box-shadow: 0 0 0 3px rgba(19, 21, 25, .9), 0 0 7px rgba(255, 255, 255, .5);
}
.is-lab .lab-dot.is-done { background: var(--lab-ink-3); }

/* The checkbox sits in the graph column, on the row it selects. */
.is-lab .lab-revs li.has-pick { position: relative; }
.is-lab .lab-pick {
  position: absolute; left: 0; top: 11px; z-index: 2;
  width: 13px; height: 13px; margin: 0;
  accent-color: #fff; cursor: pointer;
}
.is-lab .lab-revs li.has-pick .lab-rev-graph { opacity: .35; }
.is-lab .lab-revs li.has-pick:has(.lab-pick:checked) .lab-rev {
  background: rgba(255, 255, 255, .1);
  border-color: rgba(255, 255, 255, .22);
}
.is-lab .lab-pick-note {
  margin: 0 0 8px;
  font: 400 11px/1.45 var(--lab-font); color: #fff;
}


/* Translucency lightens the ground, and the quiet inks were set for an opaque
   panel: after the change six roles measured between 2.5 and 2.8 against AA's
   4.5. The rail keeps a real translucency and the ladder is re-pitched to the
   ground it actually sits on. Nothing here is a taste change -- these are the
   values that make the same design legible once you can see through it. */
.is-lab {
  --lab-ink-2: #c6cbd3;
  --lab-ink-3: #9ba1ab;
}
.is-lab .lab-rail { background: rgba(13, 14, 17, .87); }
.is-lab .lab-flag { background: rgba(13, 14, 17, .80); }
.is-lab .lab-rev.is-done .lab-rev-subject { color: #9ba1ab; }


/* lab- is the chrome's own tab. It takes the rail's green, which is the one
   colour here that already means "the lab itself" rather than a client
   surface. It switches no page, only the trail, so it never fills the way a
   view does -- the pill would claim you had navigated somewhere. */
/* lab- stands outside the pill: a quiet line under the views rather than a tab
   among them, because it switches the history and not the page. It takes the
   rail's green, the one colour here that already means the lab itself. */
.is-lab .lab-group h2.has-trail {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.is-lab .lab-trail {
  margin: -2px 0; padding: 3px 8px;
  border: 1px solid transparent; border-radius: 999px;
  background: none; color: var(--lab-green);
  font: 700 11px/1 var(--lab-font); letter-spacing: .01em;
  cursor: pointer;
}
.is-lab .lab-trail:hover { border-color: rgba(255, 255, 255, .16); }
.is-lab .lab-trail.is-active {
  background: rgba(255, 255, 255, .1);
  border-color: var(--lab-green);
}
.is-lab .lab-trail:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
