/* 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.
 *
 * Helvetica Neue everywhere, and no webfont: it is already on the machines
 * this panel is reviewed on.
 *
 * The cost, stated because it is visible: Helvetica Neue carries no tabular
 * figures, so the seven font-variant-numeric: tabular-nums rules below now ask
 * for something the family cannot give and the times and counts set
 * proportionally. They no longer form an exact column. The rules stay because
 * they cost nothing and come back the moment a face with tnum is used; a
 * second family loaded for four digits would cost more than the column is
 * worth.
 */

.is-lab {
  /* artifactory sets .74 because its canvas is already #0c0d10. This pod sits
     over a warm-white prototype, where .74 lands at mid-gray 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 color. 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;
  /* White is the whole accent now. It was two -- a pale green for the lab's
     own marks and white for the capture button -- and the green was borrowed
     from the app's SHOWING chip, which is the prototype's language, not this
     panel's. One emphatic color means the panel ranks by treatment instead:
     filled for a state, outlined for a choice, plain for everything else. */
  --lab-signal:  #fff;
  --lab-on-sig:  #0b0c0e;
  --lab-well:    rgba(0, 0, 0, .22);

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

  --lab-r:       12px;
  /* Three radii and a pill, named by what they wrap. Eight distinct values had
     grown here -- calc(--lab-r - 4), -6, -8, a bare 5px -- each chosen at the
     component rather than from a scale, which is how a corner ends up 9px. */
  --r-panel:     12px;   /* the rail, the flag, the about sheet */
  --r-card:      8px;    /* a revision row, a doc, a button */
  --r-inset:     5px;    /* something inside a card: a preview, a chip well */
  /* One focus ring. Three were in use -- white here, green there, signal in a
     third place -- which teaches nobody where focus is. */
  --lab-focus:   #fff;              /* artifactory --r-pill */
  --lab-edge-p:  9px;
  --lab-tight:   3px;
  --lab-lock:    6px;
  --lab-group:   9px;

  --lab-rail:    396px; /* was 340, and 304 before that: 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 14px;
  border-radius: var(--r-panel);
  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: 400; 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: 400; letter-spacing: .12em;
  text-transform: uppercase; color: var(--lab-ink-3);
}

.is-lab .lab-body {
  overflow-y: auto; padding: var(--lab-edge-p);
  /* No grid gap. One value between every pair of groups is what made the rail a
     stack; the spacing belongs to the groups, which know which register they
     are in. */
  display: grid; gap: 0; align-content: start;
}


.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: 400; 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 var(--lab-focus); 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: var(--r-card);
  background: transparent; color: var(--lab-ink-3);
  font-size: 11px; font-weight: 400; box-shadow: none; cursor: pointer;
}
.is-lab .lab-rail .proto-switch-set button.is-active {
  background: var(--lab-signal); 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: var(--r-card);
  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, colored and bigger than its lane. top moves up by the two pixels
   the extra height adds, so the dot stays centerd 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-signal);
  box-shadow: 0 0 0 1px var(--lab-signal), 0 0 0 4px rgba(19, 21, 25, .9);
}
/* The current revision paints its dot white; a merge keeps its color. */
.is-lab .is-here .lab-dot.is-merge { background: var(--lab-signal); }
/* 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 centerd 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: 400; 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: 400;
}
/* 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 .lab-rev.is-unbuilt .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: 400; color: var(--lab-ink);
  font-variant-numeric: tabular-nums; letter-spacing: .01em;
}
/* The domain, as a control. It sizes to its word rather than taking the
   row: it is one short token now, and the space it used to claim belongs
   to the subject under it. */
.is-lab .lab-rev-mod {
  flex: none; padding: 3px 6px; border-radius: 20px;
  border: 1px solid var(--lab-ink-3); background: none;
  font: 400 11px/1 var(--lab-font); color: var(--lab-ink-3);
  cursor: pointer;
}
/* The chip on a row takes its domain's color too, so a row scrolled away from
   its heading still says which domain it belongs to. Border and text only --
   filling it would make every row compete with the one filled chip that means
   CURRENT. */
.is-lab .lab-rev-mod[data-domain="url-"]   { border-color: var(--d-url);   color: var(--d-url); }
.is-lab .lab-rev-mod[data-domain="id-"]    { border-color: var(--d-id);    color: var(--d-id); }
.is-lab .lab-rev-mod[data-domain="ds-"]    { border-color: var(--d-ds);    color: var(--d-ds); }
.is-lab .lab-rev-mod[data-domain="about-"] { border-color: var(--d-about); color: var(--d-about); }
.is-lab .lab-rev-mod[data-domain="lab-"]   { border-color: var(--d-lab);   color: var(--d-lab); }
.is-lab .lab-rev-mod[data-domain="p-"]     { border-color: var(--d-p);     color: var(--d-p); }
.is-lab .lab-rev-mod:hover { border-color: var(--lab-ink-2); color: var(--lab-ink-2); }
.is-lab .lab-rev-mod[aria-pressed="true"] {
  border-color: var(--lab-signal); color: var(--lab-signal);
}
.is-lab .lab-rev-mod:focus-visible { border-radius: 20px; }
.is-lab .lab-ship { flex: none; }
/* Where a revision stands against production, carried by a dot rather than by
   a second color: 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: 400; }
.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: 400; }
.is-lab .lab-rev.is-waiting .lab-rev-subject { color: #fff; }
.is-lab .lab-rev.is-waiting .lab-rev-tag { color: #fff; }
.is-lab .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 .lab-open:hover { 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: var(--r-card);
  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: 400; }
.is-lab .lab-standing.is-behind { background: rgba(255, 255, 255, .07); }
/* A filled chip rather than a line of colored 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. */
/* On the modules line now, so it sits with the chip rather than competing with
   the date. align-self keeps it from stretching to the chip's taller box. */
.is-lab .lab-rev-here {
  flex: none; align-self: center;
  padding: 2px 6px; border-radius: var(--lab-tight);
  background: var(--lab-signal); color: var(--lab-on-sig);
  font-size: 9px; font-style: normal; font-weight: 400;
  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 centerd 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 .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 color, 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-focus);
  outline-offset: 2px;
  border-radius: var(--r-card);
}
.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: 400; 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-signal);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--lab-signal) 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 color 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: var(--r-card);
  background: rgba(255, 255, 255, .06); color: #fff;
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  backdrop-filter: blur(14px) saturate(160%);
  font: 400 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 var(--lab-focus); 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: 400 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-focus); 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-signal); }


/* ---- 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 Commit a note. */
/* ---- 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(--r-card);
  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: var(--r-inset);
  background: transparent; color: var(--lab-ink-2);
  font: 400 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-signal); color: var(--lab-on-sig); font-weight: 400;
}
.is-lab .lab-view:focus-visible { outline: 2px solid var(--lab-focus); 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 color. */
.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);
}

/* A control that cannot act, still in its place. It drops to the quiet ink and
   the flattest ground on the pod, so it reads as unavailable rather than as
   another button you have not noticed, and it stops answering the pointer --
   hover on something that cannot be pressed is a promise the control breaks. */
.is-lab .lab-capture.is-inert,
.is-lab .lab-capture.is-portal.is-inert {
  background: rgba(255, 255, 255, .04);
  border-color: rgba(255, 255, 255, .10);
  color: var(--lab-ink-3);
  cursor: default;
}
.is-lab .lab-capture.is-inert:hover,
.is-lab .lab-capture.is-portal.is-inert:hover {
  background: rgba(255, 255, 255, .04);
  border-color: rgba(255, 255, 255, .10);
}
/* The reason, under the control it explains and at the rail's quiet step --
   the same treatment the capture hint already uses, because it is the same
   kind of sentence. */
.is-lab .lab-capture-why {
  margin: 0 0 6px;
  font: 400 11px/1.45 var(--lab-font);
  color: var(--lab-ink-3);
}


/* ---- The badge stops landing on the navbar --------------------------------
   The LAB flag is fixed to the top-left and the nav pill centers 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 centers, now within
   what is left, so on the lab surface it sits a little right of the page center
   -- 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 center 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: var(--r-card);
  background: transparent; color: var(--lab-ink-3);
  font: 400 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-focus); 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 colors -------------------------------------------
   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 color than by reading five near-identical
   prefixes. The color 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 color, read at
   the weight the ground allows. */
.is-lab {
  /* The swatches, exactly: what a filled pill carries. */
  --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);

  /* One color per domain, and every place a domain appears reads it from
     here: the tab, the segment heading in the trail, and the chip on a row.
     Before this, three of the six were colored in the trail and three were
     not, the tabs keyed off one set of names (app, identity, system) and the
     trail off another (url-, id-, ds-), and about-, p- and lab- were all
     white. Six domains cannot be told apart by three colors and a repeat.

     Each value is the one the near-black rail can actually hold. The true
     swatch stays above for the filled state, where the ground is the color
     and contrast runs the other way. */
  --d-url:   var(--s-url);
  --d-id:    var(--s-id-lit);
  --d-ds:    var(--s-ds);
  /* about- had no color of its own and took white, which is the panel's
     accent and now also lab-'s. Amber is the gap in a palette that runs
     acid, magenta, cyan, blue. */
  --d-about: oklch(0.8000 0.1500 67);
  --d-lab:   #fff;
  --d-p:     var(--s-p-lit);
}
/* Resting magenta and blue are lifted casts: the true #EA3BCB measures 4.4:1
   on this ground and #0209F5 measures 1.3:1, so at 11px the labels would be a
   smudge. The pill carries the swatch exactly; the label carries as much of it
   as the rail can hold. */
.is-lab .lab-view[data-view="app"]      { color: var(--d-url); }
.is-lab .lab-view[data-view="identity"] { color: var(--d-id); }
.is-lab .lab-view[data-view="system"]   { color: var(--d-ds); }
.is-lab .lab-view[data-view="about"]    { color: var(--d-about); }

.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: var(--d-about); color: #181818; }

/* p- rested white until lab- became white too, and about- was white already:
   three domains wearing the panel's accent and none of them distinguishable.
   The lifted blue was rejected once for reading as a different color rather
   than as the same one dimmed, which is true and is the smaller cost. A hue
   that is nearly right still says p-; a third white says nothing. */
.is-lab a.lab-view.is-away {
  color: var(--d-p);
  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: var(--r-card);
  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: 400 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: 400 11px/1 var(--lab-font); color: var(--lab-ink-2);
}
.is-lab .lab-signout {
  margin-left: auto; padding: 0; border: 0; background: none;
  font: 400 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 gray.

   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: var(--r-inset);
  background: rgba(255, 255, 255, .035);
  border: 1px solid rgba(255, 255, 255, .06);
}
.is-lab .lab-revs .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
   color 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 color here that already means the lab itself. */
/* The pill takes the room it needs; the button sits beside it. */
.is-lab .lab-viewbar { display: flex; align-items: center; gap: 6px; }
.is-lab .lab-viewbar .lab-views { flex: 1 1 auto; min-width: 0; }



/* A domain segment header. It carries a count, because "how much is under
   here" is the question a segment invites. */
/* .lab-day-cell > span, not > span. The heading gained a graph column and a
   cell wrapper, which made the span a grandchild -- so this rule and the six
   below it stopped matching and every segment heading fell back to plain ink.
   The colors had been gone for a while and nothing said so, because a
   heading with no color still reads as a heading. */
.is-lab .lab-day.is-domain .lab-day-cell > span {
  color: var(--lab-ink-2); font-weight: 400; letter-spacing: .04em;
  text-transform: none;
}
/* One weight. The panel used 400 through 800 and leaned on weight to rank
   everything -- a heading, a tag, a count, a name -- which on Helvetica Neue
   at 10 and 11px reads as four kinds of heavy rather than four levels. Rank
   comes from the ink scale and from space instead, both of which this file
   already had. b and strong are reset with it: they are markup for what a
   thing is, and the UA's bold is not this design's decision to make. */
.is-lab, .is-lab b, .is-lab strong, .is-lab summary, .is-lab h2, .is-lab h3 {
  font-weight: 400;
}

/* Set aside from the domains: lab- is this panel's own chrome and "—" is
   bookkeeping, and neither is a surface anyone ships. The rule above them is
   where the product's history ends. */
.is-lab .lab-day.is-domain.is-aside {
  margin-top: var(--lab-group);
  padding-top: var(--lab-group);
  border-top: 1px solid var(--lab-hair);
}

/* All six, not the three that happened to get one. A segment heading is the
   first thing read when the trail is scrolled, so a domain with no color here
   was a domain you had to read the word to identify. */
.is-lab .lab-day.is-domain[data-domain="url-"]   .lab-day-cell > span { color: var(--d-url); }
.is-lab .lab-day.is-domain[data-domain="id-"]    .lab-day-cell > span { color: var(--d-id); }
.is-lab .lab-day.is-domain[data-domain="ds-"]    .lab-day-cell > span { color: var(--d-ds); }
.is-lab .lab-day.is-domain[data-domain="about-"] .lab-day-cell > span { color: var(--d-about); }
.is-lab .lab-day.is-domain[data-domain="lab-"]   .lab-day-cell > span { color: var(--d-lab); }
.is-lab .lab-day.is-domain[data-domain="p-"]     .lab-day-cell > span { color: var(--d-p); }
.is-lab .lab-day-n {
  margin-left: auto; padding: 1px 6px; border-radius: var(--lab-tight);
  background: rgba(255, 255, 255, .08);
  font: 400 10px/1.6 var(--lab-font); color: var(--lab-ink-3);
}
.is-lab .lab-day.is-domain.is-current > span { text-decoration: underline; text-underline-offset: 3px; }
.is-lab .lab-day.is-domain { align-items: center; }


/* ---- Notes ----------------------------------------------------------------
   Two documents in a 340px rail. Set narrow and quiet: this is reference you
   drop into, not something anybody reads top to bottom here. */
.is-lab .lab-doc { margin: 0 0 6px; }
.is-lab .lab-doc > summary {
  display: flex; align-items: baseline; gap: 7px;
  padding: 7px 9px; border-radius: var(--r-inset);
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .07);
  cursor: pointer; list-style: revert;
}
.is-lab .lab-doc > summary:hover { background: rgba(255, 255, 255, .08); }
.is-lab .lab-doc > summary b { font: 400 11px/1 var(--lab-font); color: #fff; }
.is-lab .lab-doc > summary span {
  font: 400 11px/1 var(--lab-font); color: var(--lab-ink-3);
}
.is-lab .lab-doc-body {
  margin: 6px 0 2px; padding: 2px 9px 8px;
  max-height: 320px; overflow: auto;
  font: 400 11px/1.55 var(--lab-font); color: var(--lab-ink-2);
}
.is-lab .lab-doc-body h4 {
  margin: 12px 0 4px; font-size: 11px; font-weight: 400; color: #fff;
  letter-spacing: .04em; text-transform: uppercase;
}
.is-lab .lab-doc-body h5 {
  margin: 10px 0 3px; font-size: 11px; font-weight: 400; color: var(--lab-ink);
}
.is-lab .lab-doc-body p { margin: 0 0 7px; }
.is-lab .lab-doc-body ul { margin: 0 0 7px; padding-left: 15px; }
.is-lab .lab-doc-body li { margin: 0 0 3px; }
.is-lab .lab-doc-body strong { color: #fff; font-weight: 400; }
.is-lab .lab-doc-body code {
  padding: 1px 4px; border-radius: 4px;
  background: rgba(255, 255, 255, .08);
  font: 400 10px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
  color: #fff;
}
.is-lab .lab-doc-row { color: var(--lab-ink-3); }


/* The line under the compare toggle says what the rows will do, because a
   Before/After pair with no object is a question, not a control. */
.is-lab .lab-sidenote {
  margin: 4px 0 0;
  font: 400 11px/1.45 var(--lab-font); color: var(--lab-ink-3);
}
/* Oldest in its segment: there is nothing under it to compare against, so the
   row stops pretending it leads somewhere new. */
.is-lab .lab-rev.is-oldest { opacity: .55; }

/* Sections carry their own numbers from the page; screens do not and take the
   list's. Two numbers on one row is a bug, not a style. */
.is-lab .lab-seq.is-sections button::before { content: none; }
.is-lab .lab-seq.is-sections button { gap: 0; }
.is-lab .lab-empty-row {
  padding: var(--lab-lock); font: 400 11px/1.4 var(--lab-font);
  color: var(--lab-ink-3);
}


/* What moved. Monospace because these are lines of a file, clipped to one line
   each because six wrapped lines of CSS is the diff, not a preview of it. */
.is-lab .lab-preview {
  display: grid; gap: 1px; margin: 5px 0 0;
  padding: 5px 7px; border-radius: var(--r-inset);
  background: rgba(0, 0, 0, .28);
}
.is-lab .lab-pv {
  font: 400 10px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.is-lab .lab-pv.is-add { color: #9fe6a0; }
.is-lab .lab-pv.is-cut { color: #e79a9a; }
.is-lab .lab-pv.is-add::before { content: "+ "; opacity: .6; }
.is-lab .lab-pv.is-cut::before { content: "- "; opacity: .6; }



/* The (i), sitting inside the flag it explains. */
.is-lab .lab-flag { gap: 10px; }
.is-lab .lab-info {
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; padding: 0;
  border: 1px solid rgba(255, 255, 255, .34); border-radius: 50%;
  background: none; color: var(--lab-ink-2);
  font: 400 10px/1 var(--lab-font); font-style: italic;
  cursor: pointer;
}
.is-lab .lab-info:hover { border-color: #fff; color: #fff; }
.is-lab .lab-info:focus-visible { outline: 2px solid var(--lab-focus); outline-offset: 2px; }

/* What this is. Under the flag, at the width of a paragraph rather than the
   width of the window: this is read once, by somebody who just arrived. */
/* ---- The views, previewed -------------------------------------------------
   Five clones of the real sections, scaled down. Two columns because the panel
   is 360px wide and one column would make each thumbnail taller than the panel
   allows; the scale itself is measured in lab.js off the frame this gives it,
   so the number lives in one place.

   pointer-events on the clone, not just tabindex: a preview is a picture, and
   a hover state firing inside a thumbnail is a control the card does not have.
   The card is the control. */
.is-lab .lab-views-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 2px 0 14px; }
.is-lab .lab-view-card {
  display: grid; gap: 5px; padding: 0; border: 0; background: none;
  font: inherit; color: var(--lab-ink); cursor: pointer; text-align: left; }
.is-lab .lab-view-frame {
  position: relative; overflow: hidden;
  border-radius: 7px; border: 1px solid var(--lab-hair);
  background: #fff; }
.is-lab .lab-view-card:hover .lab-view-frame { border-color: var(--lab-edge); }
.is-lab .lab-view-card:focus-visible { outline: 2px solid var(--lab-focus); outline-offset: 3px; }
.is-lab .lab-view-scaler {
  position: absolute; top: 0; left: 0; transform-origin: 0 0;
  pointer-events: none; }
.is-lab .lab-view-name {
  font-family: var(--lab-font); font-size: 10px; letter-spacing: .04em;
  color: var(--lab-ink); opacity: .72; }

.is-lab .lab-about {
  position: fixed; z-index: 61;
  top: calc(var(--lab-group) + 46px); left: var(--lab-group);
  width: min(360px, calc(100vw - var(--lab-group) * 2));
  max-height: 70vh; overflow: auto;
  padding: 16px 18px 14px;
  border-radius: var(--lab-r);
  border: 1px solid var(--lab-edge);
  background: rgba(13, 14, 17, .93);
  -webkit-backdrop-filter: blur(26px) saturate(150%);
  backdrop-filter: blur(26px) saturate(150%);
  box-shadow: var(--lab-sh);
}
.is-lab .lab-about h3 {
  margin: 0 0 4px; font: 400 12px/1.3 var(--lab-font); color: #fff;
}
.is-lab .lab-about h3 + p { margin: 0 0 13px; }
.is-lab .lab-about p {
  margin: 0; font: 400 11px/1.55 var(--lab-font); color: var(--lab-ink-2);
}
.is-lab .lab-about-foot {
  margin-top: 4px; padding-top: 10px;
  border-top: 1px solid var(--lab-edge);
  color: var(--lab-ink-3);
}
.is-lab .lab-about-foot a { color: var(--lab-ink-2); }
.is-lab .lab-about-foot a:hover { color: #fff; }


/* ---- The parts nobody drew -------------------------------------------------
   Selection, the caret and the scrollbar ship with browser defaults that belong
   to no design system, and on a dark rail the default blue selection is the
   loudest color on the page. */
.is-lab ::selection { background: var(--lab-signal); color: var(--lab-on-sig); }
.is-lab input, .is-lab textarea { caret-color: var(--lab-signal); }

/* ---- Pressable boxes -------------------------------------------------------
   The drawn control stays the size the design wants; the box you can hit grows
   to 44. A rail of 34px tabs and a 17px (i) is fine with a mouse and hostile
   with a thumb, and growing the visible control instead would wreck the
   density this panel is for. */
.is-lab .lab-view,
.is-lab .lab-info,
.is-lab .lab-seq button,
.is-lab .lab-doc > summary,
.is-lab .lab-group > summary { position: relative; }
/* ::before, not ::after. Three of these elements already carry content on
   ::after -- the p- tab's outbound arrow, the disclosure mark on a foldable
   group -- and this rule's position:absolute leaked onto them through
   specificity: the content stayed, the layout did not, so an arrow and a plus
   sign were pinned to the center of a 44px box and painted above their own
   labels. A hit area should never share a pseudo-element with a glyph.
   .lab-seq button keeps ::after because its ::before is the step counter. */
.is-lab .lab-view::before,
.is-lab .lab-info::before,
.is-lab .lab-seq button::after,
.is-lab .lab-doc > summary::before,
.is-lab .lab-group > summary::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: max(100%, 44px); height: max(100%, 44px);
  transform: translate(-50%, -50%);
}
/* The checkbox is the one control small enough that the hit area has to be
   bigger than its own row is tall, so it takes a fixed box instead.

   It does NOT get position:relative here. It is already absolutely positioned
   at the row's left edge, and an absolutely positioned element is a containing
   block for its own ::after, so the box below works either way. Setting
   relative did not make it relative -- it took the absolute off, and the
   checkbox left the row entirely: it became the third item in the row's grid,
   landed at the right-hand edge, a hundred pixels above its own card. A later
   rule of equal specificity silently winning is the oldest bug in a stylesheet
   and I wrote it into this one. */
.is-lab .lab-pick::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 44px; height: 44px; transform: translate(-50%, -50%);
}
/* The counter pseudo-element on a screen row would be eaten by the hit box
   above it, so it keeps its own stacking. */
.is-lab .lab-seq button::before { position: relative; z-index: 1; }

/* Two of those controls clip their own hit box. .lab-view carries
   overflow:hidden for its ellipsis and a summary establishes its own painting,
   so the pseudo-element stops at the border and the 44px never existed --
   measured, not assumed: a probe 19px below a tab's center landed on the track
   behind it.

   Where the box cannot grow outward, the control grows instead, and only where
   it matters. A mouse does not need 44px and this panel is built for density;
   a thumb does. Nothing moves on a machine with a pointer. */
@media (pointer: coarse) {
  .is-lab .lab-views { padding: 5px; }
  .is-lab .lab-view { min-height: 44px; }
  .is-lab .lab-seq button { padding-block: 15px; }
  .is-lab .lab-doc > summary,
  .is-lab .lab-group > summary { padding-block: 13px; }
  .is-lab .lab-info { width: 28px; height: 28px; }
  .is-lab .lab-capture { padding-block: 15px; }
}


/* ---- The compare lens ------------------------------------------------------
   Bottom left: the flag holds top left, the rail holds the right edge and the
   studio mark sits by it, so this corner is the only one free. It reads the
   whole surface rather than the list, which is why it is not in the list. */
.is-lab .lab-compare {
  position: fixed; z-index: 56;
  left: var(--lab-group); bottom: var(--lab-group);
  width: 232px; padding: 11px 13px 12px;
  border-radius: var(--r-panel);
  border: 1px solid var(--lab-edge);
  background: rgba(13, 14, 17, .87);
  -webkit-backdrop-filter: blur(26px) saturate(150%);
  backdrop-filter: blur(26px) saturate(150%);
  box-shadow: var(--lab-sh);
}
.is-lab .lab-compare .lab-sidenote { margin-top: 7px; }

/* At the width where the flag drops to the bottom of the page, the two would
   sit on top of each other. The lens goes above it rather than beside it --
   there is no room beside it. */
@media (max-width: 900px) {
  .is-lab .lab-compare {
    left: var(--lab-group); right: var(--lab-group); width: auto;
    bottom: calc(var(--lab-group) + 52px);
  }
}

/* Label and count share the content cell. */
.is-lab .lab-day-cell {
  display: flex; align-items: center; gap: 8px; min-width: 0;
}
.is-lab .lab-day-cell > span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}


/* ---- Two registers --------------------------------------------------------
   Controls are set; the record is read. They had one heading style and one 22px
   gap between all six groups, which is a stack rather than a hierarchy: blurred,
   there was no way to tell the thing you steer with from the thing you consult.

   Rhythm carries the distinction before any label does. Tight inside a register,
   generous between them. */
.is-lab .lab-group + .lab-group { margin-top: 12px; }
.is-lab .lab-group.is-reference { margin-top: 26px; }
.is-lab .lab-group.is-record { margin-top: 32px; }

/* A heading is the top edge of its component, so it sits on one. The rule stops
   at the label rather than running the full width: a full rule reads as a
   divider between two things, and this is the start of one thing. */
/* The edge belongs to the group, not to the heading. As a pseudo-element
   inside the summary it shared a flex line with the disclosure mark, and both
   ended up on a line above the label instead of on it. A border cannot collide
   with anything. */
/* A transparent border on all four sides, not just the top, and the same
   twelve pixels of inset the record carries. The record sits on its own ground
   and is padded away from its edge; the groups above it were flush to theirs,
   so every heading and every + sat thirteen pixels left of the Revisions
   heading below them and the column had two left edges. Matched by
   construction -- one border plus one padding on every group -- rather than by
   a thirteen nobody could later explain. The border stays transparent
   everywhere except the top, which is where the dividing rule lives. */
.is-lab .lab-group {
  border: 1px solid transparent;
  padding-top: 11px; padding-left: 12px; padding-right: 12px;
}
.is-lab .lab-group + .lab-group { border-top-color: var(--lab-edge); }
/* :first-child, not :first-of-type. Of-type matches the first element of each
   tag name among its siblings, so the moment a group became a <details> it
   became "first of type" alongside the first <section> and silently dropped its
   rule and its padding -- which is what left States & feature flags with no
   dividing line above it and its heading hard against the domains. Only the
   group that is genuinely first has nothing to be divided from. */
.is-lab .lab-body > .lab-group:first-child { border-top: 0; padding-top: 0; }

/* The record is a surface of its own, not more stack. Seven thousand pixels of
   history reading as the sixth item in a list of controls is what made the rail
   feel like one long column. */
.is-lab .lab-group.is-record {
  padding: 14px 12px 12px;
  border-radius: var(--r-panel);
  background: rgba(255, 255, 255, .03);
  border: 1px solid rgba(255, 255, 255, .06);
}
/* The record has a ground of its own, so it needs no rule above it too. */
.is-lab .lab-group.is-record { border-top-color: transparent; }

/* The two registers take different ink. Controls name themselves quietly; the
   record announces a surface you are about to read. */
.is-lab .lab-group.is-record > h2 { color: #fff; letter-spacing: .14em; }

/* Foldable groups say so with a consistent mark, rather than leaving it to the
   default triangle on some and nothing on others. */
.is-lab .lab-group.is-foldable > summary { list-style: none; }
.is-lab .lab-group.is-foldable > summary::marker { content: ""; }
.is-lab .lab-group.is-foldable > summary::after {
  content: "+"; margin-left: auto; padding-left: 8px;
  font: 400 13px/1 var(--lab-font); color: var(--lab-ink-3);
}
.is-lab .lab-group.is-foldable[open] > summary::after { content: "\2212"; }
.is-lab .lab-group.is-foldable > summary {
  display: flex; align-items: center;
}


/* ---- The record folds -----------------------------------------------------
   Thirty-eight cards, nineteen of them carrying a hundred pixels of diff, is
   seven thousand pixels of history under three hundred of controls. The diff is
   worth having and not worth having open thirty-eight times, so a card shows
   its identity and its subject, and opens to show the rest. The current version
   starts open because it is the row the rail exists to point at.

   Folding is display:none by class; hiding is the hidden attribute. Two
   channels, never crossed, so "why can I not see this row" has one answer. Both
   take the subtree out of the tab order, which is the behaviour wanted in each
   case. */
.is-lab { --lab-lime: #dbfe57; }

/* The rail owns its own hiding. [hidden] is forced to display:none in
   styles.css, a file this one does not own, and it is only needed there because
   .lab-revs li is display:grid. Stated here so the filter -- and the tab order
   that follows it -- cannot be broken by an edit to somebody else's stylesheet. */
.is-lab .lab-revs li[hidden] { display: none; }

.is-lab .lab-build:not(.is-expanded) .lab-rev > .lab-preview,
.is-lab .lab-build:not(.is-expanded) .lab-rev > .lab-rev-foot,
.is-lab .lab-build:not(.is-expanded) .lab-rev > .lab-changes { display: none; }

/* An open card takes the bright edge, so which one you are reading is legible
   at the edge of vision rather than only by its contents. A ticked card keeps
   the selection border either way -- .has-pick:has(:checked) out-specifies this
   deliberately: a pending promotion outranks a fold. */
.is-lab .lab-revs .is-expanded .lab-rev { border-color: var(--lab-ink); }

/* The fold is the row's identity -- version, current, date -- because that is
   the part you press when you mean "show me this one". Reset to the text it
   already was, so the head looks exactly as it did before it became pressable. */
.is-lab .lab-fold {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: var(--lab-lock);
  margin: 0; padding: 0; border: 0; background: none;
  font: inherit; color: inherit; text-align: left; cursor: pointer;
}

/* Opening the build, in the head where folding cannot reach it. */
.is-lab .lab-open { flex: none; text-decoration: none; }

/* The face is the contributor control. A lime initial would say nothing once
   the photo loads -- and it always loads -- so the state is a ring, borrowing
   the halo the spine's pending dot already uses. Raised above its neighbours
   because the stack overlaps by six pixels and would clip it. */
.is-lab button.lab-avatar {
  border: 0; padding: 0; appearance: none; cursor: pointer;
}
.is-lab .lab-avatar[aria-pressed="true"] {
  position: relative; z-index: 1; color: var(--lab-lime);
  box-shadow: 0 0 0 2px var(--lab-lime), 0 0 0 4px rgba(19, 21, 25, .9);
}
.is-lab .lab-avatar:focus-visible { border-radius: 50%; }

/* Not the 44px box the other controls get: thirty-eight rows at seventy-seven
   pixels would have those boxes overlapping the cards above and below and
   stealing their fold. The controls grow themselves instead, and the card is
   already a very large target for the fold. */
@media (pointer: coarse) {
  .is-lab .lab-rev-mod { padding-block: 7px; }
  .is-lab button.lab-avatar { width: 24px; height: 24px; }
}


/* ---- The header carries the trail ----------------------------------------
   Collapsing is gone, so the slot the arrow held goes to the one control that
   changes what the record below is showing. It is the same switch the feature
   flags are, because it is the same kind of thing -- a state you set -- and it
   had been a button with three states where a two-option well can only ever be
   in one of two. Stripped of the row padding and the rule those carry inside a
   group: in the header it is the only thing there. */
/* Label beside the well, not above it. Inside a group a switch stacks, because
   there is a column of them and the labels want to line up down its left edge.
   Here there is one, in a row that is already reading left to right, and a
   label on its own line spent a whole row saying one word and pushed the
   header taller than the thing it names. */
.is-lab .lab-head .proto-switch.is-trail {
  display: flex; align-items: center;
  flex: none; padding: 0; margin: 0; border-bottom: 0;
  gap: var(--lab-lock);
}
.is-lab .lab-head .proto-switch.is-trail .proto-switch-label {
  color: var(--lab-signal); font-weight: 400;
}

/* ---- p- has a track of its own -------------------------------------------
   A pill track means "one of these at a time", and p- is not one of them: it
   leaves for another site rather than swapping what the phone shows. Its own
   track keeps the promise the shared one was breaking, and the gap between
   them says so before the arrow has to. */
.is-lab .lab-viewbar { gap: var(--lab-lock); }
.is-lab .lab-views.is-away-track { flex: none; }
.is-lab .lab-views.is-away-track .lab-view { flex: none; padding: 0 10px; }

/* ---- States and flags are one folded group -------------------------------
   Three switches on a row, not stacked. Each is a label over a well no wider
   than its words, so stacked they spent sixty-six pixels apiece leaving most
   of the rail empty. A hairline between them does the separating the three
   headings used to. */
.is-lab .lab-switches {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: 0;
}
/* The tight step around the dividers, not the lock step. Inset the groups to
   line up with the record and the row lost thirteen pixels a side, which was
   one more than the three switches had to spare -- Now playing dropped to a
   second line. Six pixels of air around a hairline reads as separation just as
   well as twelve, and it is the same scale. */
.is-lab .lab-switches .proto-switch {
  padding: var(--lab-group) var(--lab-tight) var(--lab-group) 0;
  border-bottom: 0;
  border-right: 1px solid var(--lab-hair);
}
.is-lab .lab-switches .proto-switch + .proto-switch { padding-left: var(--lab-tight); }
.is-lab .lab-switches .proto-switch:last-child { border-right: 0; padding-right: 0; }
.is-lab .lab-switches .proto-switch-set { width: auto; }


/* ---- The folded groups share one rhythm -----------------------------------
   Three dropdowns carrying three different spacings: twelve above the line for
   the two controls and twenty-six for the reference, eleven below it for the
   two that had a line at all. Read down the rail they looked like an accident,
   because they are the same kind of object -- a heading you open. Twenty-four
   on both sides of the rule, so the line sits in the middle of its own space
   and the three of them read as one series.

   Last, so it beats the register margins above: Notes carries is-reference and
   is-foldable at the same specificity, and the one that wins should be the one
   describing what it looks like. */
.is-lab .lab-group.is-foldable {
  margin-top: 24px;
  padding-top: 24px;
}

/* ---------------------------------------------------------------------------
 * People: the collaborator tabs above the trail.
 *
 * The same track and the same tabs as Domains, with three differences the
 * content forces. They wrap, because a cast grows and a name is longer than a
 * domain. They size to their name rather than splitting the track evenly,
 * since two contributors would otherwise each take half the panel. And each
 * one carries a face and a count, which is what makes it readable as a person
 * rather than another filter key.
 */
.is-lab .lab-sub {
  margin: var(--lab-group) 0 var(--lab-tight);
  font: 400 10px/1 var(--lab-font);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--lab-ink-3);
}
.is-lab .lab-views.is-people { flex-wrap: wrap; gap: 2px; }
.is-lab .lab-view.is-who {
  flex: 0 1 auto;
  gap: 6px; padding: 0 8px;
  overflow: visible;
}
.is-lab .lab-view.is-who .lab-avatar { width: 18px; height: 18px; font-size: 8px; }
.is-lab .lab-who-name {
  max-width: 11ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The count is the quiet half of the tab: it ranks the cast without competing
   with the name it belongs to, so it steps down a tone rather than taking a
   ground of its own. */
.is-lab .lab-who-n {
  font-variant-numeric: tabular-nums;
  font-weight: 400; color: var(--lab-ink-4);
}
/* Selected, not primary. The domains own the color axis on this panel -- each
   one carries its own hue and that is how you tell them apart -- so a person
   cannot take a hue without setting up a second color system competing with
   the first. And filled white belongs to Note this view: isolating someone is
   a change of view, not an action, so it must not rank with the one button
   here that does something. It lifts out of the track instead. */
.is-lab .lab-view.is-who.is-active {
  background-color: rgba(228, 236, 248, .10);
  color: #e7eaee;
  box-shadow: inset 0 0 0 1px var(--lab-edge);
}
.is-lab .lab-view.is-who.is-active .lab-who-n { color: var(--lab-ink-2); }
.is-lab .lab-view.is-who:focus-visible {
  outline: 2px solid var(--lab-focus); outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
 * The console, on its own page.
 *
 * The panel was a fixed rail down the right of the prototype: two jobs on one
 * screen, and the record is the longer of them by an order of magnitude --
 * 14,000 characters of it against 120 of controls. Here the rail is the
 * document. It is not fixed to an edge, it sits over nothing, and it takes a
 * reading measure rather than a panel's width.
 *
 * The three control groups leave with the prototype. Domains, the state flags
 * and Screens all read their options off the app, and the app is not on this
 * page -- they rendered as three empty headings. What is left is the record,
 * which is the whole reason for a second page.
 */
/* The page is the panel. A dark card centered on a slightly different dark
   ground would be the rail again, one screen further out -- a window onto the
   record rather than the record. So the rail gives up its own ground, edge and
   blur here and the document carries them, and only the measure is held. */
.is-console body {
  background: var(--lab-pod);
  margin: 0;
  /* The rail is not fixed here, so the gutter the page was holding open for it
     is 414px of nothing pushing the measure off center. */
  padding-right: 0;
}
.is-console .lab-rail {
  position: static;
  width: min(880px, 100% - 48px);
  margin: 0 auto;
  padding-block: 40px 96px;
  height: auto; max-height: none;
  background: none; border: 0; box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border-radius: 0;
}
/* Nothing is left in the body's first slot once the control groups go, and the
   gap they were separated by stayed behind as a band under the header. */
.is-console .lab-body > .lab-group.is-control + * { margin-top: 0; }
.is-console .lab-group.is-control { display: none; }
/* The flag names the surface you are standing on, and the compare lens swaps
   that surface underneath you. Neither has a surface to speak of here. */
.is-console .lab-flag,
.is-console .lab-about-sheet,
.is-console .lab-compare { display: none; }

.is-lab .lab-cross {
  margin-left: auto;
  color: var(--lab-ink-3); text-decoration: none;
  font-size: 11px; letter-spacing: .04em;
}
.is-lab .lab-cross::after { content: " \2192"; }
.is-lab .lab-cross:hover { color: var(--lab-ink); }
.is-lab .lab-cross:focus-visible { outline: 2px solid var(--lab-focus); outline-offset: 2px; }
/* The head is label, switch, link. The switch keeps the middle; the link takes
   the end the switch used to have. */
.is-lab .lab-head .proto-switch.is-trail { margin-left: auto; }
.is-lab .lab-head .lab-cross { margin-left: var(--lab-group); }

/* lab- is the last view and the only one that is not a surface of the product.
   It takes white, which is this panel's own color, and the same fill every
   other view takes when it is the one you are in. */
.is-lab .lab-view.is-lab-view { color: var(--d-lab); }
.is-lab .lab-view.is-lab-view.is-active { background: var(--d-lab); color: var(--lab-on-sig); }
