/* The test viewer: the /tests index and one test's overview.

   These two pages deliberately do NOT use .card. A test is a workbench: a
   header, a couple of control blocks and then a dense list of records. Cards
   gave every one of those its own 16px radius, 1.35rem padding and accent
   glow, so four floating panels ate the fold before the first record. What is
   defined here instead is a flat, square "surface" -- hairline border, tight
   padding, no shadow -- plus the controls that sit on it. The result reads as
   a technical tool rather than a feed of cards.

   Two rules of thumb when adding to these pages: reach for .test-surface and
   .test-btn/.test-input rather than .card and .btn--*, and keep new vertical
   padding in the 0.5-0.9rem band the rest of this sheet uses. */

/* ---------------------------------------------------------------- shell --- */

.test-page {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

/* The flat panel these pages are built from. */
.test-surface {
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.85rem 1rem;
}

.test-surface__heading {
  margin: 0 0 0.75rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.test-empty {
  color: var(--text-muted);
  font-size: 0.85rem;
}

/* --------------------------------------------------------- controls --- */

/* Buttons size to their label, never to their container. Both pages put
   buttons inside flex rows (and inside per-action <form> wrappers, which are
   themselves flex items), where the default `stretch` makes a button fill the
   row -- the failure mode that produced a full-width "New test" and a 1700px
   "Search". */
.test-btn {
  flex: 0 0 auto;
  align-self: center;
  width: auto;
  white-space: nowrap;
  padding: 0.38rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface-raised);
  color: var(--text);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 500;
  line-height: 1.4;
  cursor: pointer;
}

.test-btn:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
  color: var(--accent);
}

.test-btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-contrast);
}

.test-btn--primary:hover {
  background: color-mix(in srgb, var(--accent) 88%, black);
  color: var(--accent-contrast);
}

.test-btn--danger {
  color: var(--bad);
  border-color: color-mix(in srgb, var(--bad) 35%, var(--border));
}

.test-btn--danger:hover {
  background: var(--bad-soft);
  color: var(--bad);
}

/* Each action is wrapped in its own <form> for its POST, which makes the FORM
   the flex item -- so without this the forms stretch to the row's width and
   the buttons inside them stretch with them, stacking at ragged widths.
   Sizing the form to its content (rather than display:contents, which older
   Safari drops from the a11y tree) keeps the buttons on one row. */
.test-head__actions form,
.test-form__actions form,
.test-item__controls form {
  display: inline-flex;
  flex: 0 0 auto;
  margin: 0;
}

.test-input {
  padding: 0.38rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface-raised);
  color: var(--text);
  font: inherit;
  font-size: 0.8rem;
  line-height: 1.4;
}

textarea.test-input {
  resize: vertical;
}

.test-input:focus {
  outline: none;
  border-color: var(--accent);
}

.test-input::placeholder {
  color: color-mix(in srgb, var(--text-muted) 75%, transparent);
}

/* --------------------------------------------------------------- head --- */

.test-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.test-head__main {
  min-width: 220px;
}

.test-head .page-eyebrow {
  margin-bottom: 0.3rem;
}

.test-head__titlerow {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* Flat weight, no gradient text fill: the title is an identifier here, and the
   record codes below it are what the eye should land on. */
.test-head__title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.test-head__meta {
  margin: 0.3rem 0 0;
  font-size: 0.78rem;
  color: var(--text-muted);
}

.test-head__desc {
  margin: 0.4rem 0 0;
  font-size: 0.82rem;
  color: var(--text-muted);
  line-height: 1.5;
  max-width: 70ch;
}

.test-head__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.4rem;
  flex: 0 0 auto;
  flex-wrap: wrap;
}

/* ------------------------------------------------------------ toolbar --- */

.test-toolbar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.9rem;
}

/* The search field grows; nothing else in the toolbar does. The form is a flex
   item AND a flex container, so both need saying: without the max-width the
   form takes the whole row and pushes "New test" onto a line of its own, where
   it stretches to full width. */
.test-toolbar__search {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex: 1 1 auto;
  max-width: 30rem;
  margin: 0;
}

.test-toolbar__search .test-input {
  flex: 1 1 auto;
  min-width: 0;
}

/* Pushes "New test" to the far right, whatever the search field's width. */
.test-toolbar__spacer {
  flex: 1 1 auto;
}

.test-tagbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-bottom: 1.1rem;
}

.test-tagbar__tag {
  padding: 0.24rem 0.6rem;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  font-size: 0.76rem;
  text-decoration: none;
  transition: color 0.12s ease, background 0.12s ease, border-color 0.12s ease;
}

.test-tagbar__tag:hover {
  color: var(--text);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
}

.test-tagbar__tag--active {
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  color: var(--accent);
  font-weight: 500;
}

/* ------------------------------------------------------------ sections --- */

.test-section {
  margin: 0.6rem 0 0;
}

/* The heading needs real air beneath it -- the rows below start with a border
   at their very top edge, so a tight margin read as the heading sitting on the
   first record. */
.test-section__heading {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.6rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.test-section__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.3rem;
  height: 1.3rem;
  padding: 0 0.35rem;
  border-radius: 3px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0;
}

/* One bordered block; rows inside share hairlines instead of each carrying a
   border, so the list reads as a table. */
.test-section__rows {
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow: hidden;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
}

.empty-state {
  padding: 1.5rem;
  color: var(--text-muted);
  font-size: 0.88rem;
}

/* --------------------------------------------------------- test cards --- */

.test-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 0.6rem;
}

.test-card {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 0.8rem 0.9rem;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.12s ease, background 0.12s ease;
}

.test-card:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
  background: var(--surface);
}

.test-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.6rem;
}

.test-card__name {
  margin: 0;
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.35;
}

.test-card__desc {
  margin: 0;
  font-size: 0.8rem;
  color: var(--text-muted);
  line-height: 1.45;
  /* Two lines, so a long description cannot make one card tower over its
     neighbours in the grid. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.test-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.test-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  margin-top: auto;
  padding-top: 0.35rem;
  font-size: 0.73rem;
  color: var(--text-muted);
}

/* --------------------------------------------------------------- pills --- */

.test-pill {
  flex-shrink: 0;
  padding: 0.12rem 0.4rem;
  border-radius: 3px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.test-pill--public {
  border-color: color-mix(in srgb, var(--good) 40%, transparent);
  background: var(--good-soft);
  color: var(--good);
}

/* ---------------------------------------------------------- test forms --- */

.test-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Two columns, because these fields are short. As one full-width stack the
   edit block was taller than the record list it sat above. */
.test-form__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.6rem 0.75rem;
}

.test-form__field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  min-width: 0;
}

/* Description spans the grid rather than sitting in a half-width column. */
.test-form__field--wide {
  grid-column: 1 / -1;
}

.test-form__field > span {
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.test-form__field .test-input {
  width: 100%;
}

.test-form__hint {
  font-size: 0.7rem;
  color: var(--text-muted);
}

.test-form__check {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.8rem;
  color: var(--text-muted);
}

/* Checkbox on the left, Save/Cancel on the right, on one line. */
.test-form__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-top: 0.65rem;
  border-top: 1px solid var(--border);
}

.test-form__actions {
  display: flex;
  gap: 0.4rem;
}

.test-attach__form {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
}

.test-attach__type {
  flex: 0 0 auto;
}

/* The three text inputs share the row; the button does not grow with them. */
.test-attach__form .test-input:not(.test-attach__type) {
  flex: 1 1 9rem;
  min-width: 0;
}

/* ----------------------------------------------------------- item rows --- */

/* A row, not a card: no border of its own, no radius, no shadow. The hairline
   comes from the row above it, so a run of records is one continuous list. */
.test-item {
  border-top: 1px solid var(--border);
  background: transparent;
}

.test-item:first-child {
  border-top: none;
}

/* An open row is lifted out of the list so its panel reads as belonging to it
   rather than to the rows either side. */
.test-item--open {
  background: color-mix(in srgb, var(--text) 2%, transparent);
}

.test-item__head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.7rem;
  min-height: 2.35rem;
}

/* Only the row's own hover, not a hover anywhere inside the expanded panel
   below it -- otherwise reading a timeline keeps the row's controls lit. */
.test-item__head:hover {
  background: color-mix(in srgb, var(--text) 3%, transparent);
}

.test-item__ident {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  flex-shrink: 0;
}

.test-item__toggle {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.15rem 0.1rem;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text);
  font: inherit;
}

.test-item__chevron {
  color: var(--text-muted);
  transition: transform 0.15s ease;
  flex-shrink: 0;
}

.test-item__chevron--open {
  transform: rotate(90deg);
}

.test-item__code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  /* A fixed measure keeps the label column aligned down the list rather than
     starting at a different x for every code length. */
  min-width: 10ch;
  text-align: left;
}

.test-item__link {
  display: inline-flex;
  color: var(--text-muted);
  opacity: 0.4;
  transition: opacity 0.12s ease, color 0.12s ease;
}

.test-item:hover .test-item__link,
.test-item__link:focus-visible {
  opacity: 1;
}

.test-item__link:hover {
  color: var(--accent);
}

.test-item__labelwrap {
  flex: 1 1 auto;
  min-width: 0;
  /* Separates the identity from the annotation, so the empty state reads as a
     field to fill rather than as blank space. */
  border-left: 1px solid var(--border);
  padding-left: 0.65rem;
}

.test-item__label {
  font-size: 0.79rem;
  color: var(--text-muted);
}

.test-item__label-form {
  margin: 0;
}

/* Reads as plain text until focused — a label is edited rarely, so an input
   border on every row would make the list look like a form. */
.test-item__label-input {
  width: 100%;
  padding: 0.22rem 0.4rem;
  border: 1px solid transparent;
  border-radius: 4px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 0.79rem;
}

.test-item__label-input::placeholder {
  color: color-mix(in srgb, var(--text-muted) 65%, transparent);
  font-style: italic;
}

.test-item__label-input:hover {
  border-color: var(--border);
}

.test-item__label-input:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--surface);
  color: var(--text);
}

.test-item__controls {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  flex-shrink: 0;
}

.test-item__notes-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.22rem 0.5rem;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.75rem;
  cursor: pointer;
}

/* Sits beside the notes toggle and matches its geometry rather than reusing
   the pill-shaped .admin-link-btn from the detail pages -- at this row height
   an accent-filled pill outweighs the notes button next to it, when the two
   are peers. */
.test-item__admin {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.22rem 0.5rem;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  font-size: 0.75rem;
  text-decoration: none;
}

.test-item__admin:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
}

.test-item__admin svg {
  flex-shrink: 0;
}

/* The words are dropped on narrow screens; the icons carry them. */
.test-item__notes-word,
.test-item__admin-word {
  display: none;
}

@media (min-width: 900px) {
  .test-item__notes-word,
  .test-item__admin-word {
    display: inline;
  }
}

.test-item__notes-toggle:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
}

/* Carries notes: filled, so a scan down the list shows where the evidence is. */
.test-item__notes-toggle--has {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}

.test-item__remove {
  display: inline-flex;
  padding: 0.25rem;
  border: none;
  background: none;
  border-radius: 4px;
  color: var(--text-muted);
  cursor: pointer;
  opacity: 0.35;
  transition: opacity 0.12s ease, color 0.12s ease, background 0.12s ease;
}

.test-item:hover .test-item__remove,
.test-item__remove:focus-visible {
  opacity: 1;
}

.test-item__remove:hover {
  color: var(--bad);
  background: var(--bad-soft);
}

.test-item__loading {
  padding: 0.7rem 0.9rem;
}

/* ---------------------------------------------------------- item panel --- */

.test-panel {
  padding: 0.2rem 0.9rem 0.9rem;
  border-top: 1px solid var(--border);
}

.test-panel .timeline {
  margin-top: 0;
}

.test-panel--empty {
  padding: 0.9rem;
  color: var(--text-muted);
  font-size: 0.85rem;
}

.test-panel__stops {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.test-panel__stop {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.55rem;
  border-radius: 4px;
  background: color-mix(in srgb, var(--text) 3%, transparent);
  font-size: 0.8rem;
}

.test-panel__stop-index {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.3rem;
  height: 1.3rem;
  flex-shrink: 0;
  border-radius: 3px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.72rem;
  font-weight: 600;
}

.test-panel__stop-addr {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* The request this stop belongs to -- the link between an order in a test and
   the requests sitting beside it. */
.test-panel__stop-req {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.75rem;
  color: var(--accent);
  text-decoration: none;
}

.test-panel__stop-req:hover {
  text-decoration: underline;
}

/* The stat row wraps rather than squeezing eight boxes onto one line. */
/* The compact stat bar, used by the test panels. Smaller boxes and values
   than a detail page header: a panel sits inside a row inside a list, so the
   page-header scale would dominate the record it describes. */
.detail-header__stats--compact {
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.85rem 0 1rem;
  width: 100%;
}

.detail-header__stats--compact .detail-stat-box {
  padding: 0.4rem 0.6rem;
  border-radius: 4px;
}

.detail-header__stats--compact .detail-stat-box__label {
  font-size: 0.66rem;
}

.detail-header__stats--compact .detail-stat-box__value {
  font-size: 0.95rem;
  font-weight: 600;
}

.detail-stat-box__value--sm {
  font-size: 0.82rem !important;
  font-weight: 500 !important;
}

/* The route bar reads as supporting detail here, not the headline it is on the
   order page. */
.test-panel .route-progress {
  margin: 0 0 1rem;
}

/* --------------------------------------------------------- item notes --- */

/* The comment modal's body, rendered in place. The modal's own chrome is
   suppressed in the template (no backdrop, no dialog role), so what is left
   needs a container rather than a floating panel. */
.test-item__notes {
  border-top: 1px solid var(--border);
  background: color-mix(in srgb, var(--text) 3%, transparent);
}

/* The composer's footer is space-between, and its Post button is a bare flex
   item -- in the modal a sibling button box holds it to its label, but inline
   there is nothing beside it, so `stretch` blew it out to the full row. Pin it
   to its own width here (and square it, to match this page's controls). */
.test-item__notes .comment-form__foot .btn,
.test-item__notes .comment-form__buttons .btn {
  flex: 0 0 auto;
  align-self: center;
  width: auto;
  border-radius: 4px;
}

/* Same reason, one level up: the composer sits in a column flex container, so
   its full-width inputs are wanted but its footer must not stretch its own
   children vertically. */
.test-item__notes .comment-form__foot {
  align-items: center;
}

.test-item__notes .comment-form input[type="text"],
.test-item__notes .comment-form input:not([type]),
.test-item__notes .comment-form textarea {
  border-radius: 4px;
}

.comment-inline {
  display: block;
}

.comment-inline__panel {
  padding: 0.9rem 1.1rem 1.1rem;
  max-height: none;
  background: transparent;
  border: none;
  box-shadow: none;
}

/* ----------------------------------------------------- tag suggestions --- */

.tag-suggestions {
  list-style: none;
  margin: 0.3rem 0 0;
  padding: 0.3rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface-raised);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.tag-suggestions__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  width: 100%;
  padding: 0.35rem 0.5rem;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 0.82rem;
  cursor: pointer;
  text-align: left;
}

.tag-suggestions__item:hover {
  background: var(--accent-soft);
}

.tag-suggestions__count {
  color: var(--text-muted);
  font-size: 0.74rem;
}

@media (max-width: 720px) {
  .test-item__head {
    flex-wrap: wrap;
    gap: 0.5rem;
  }

  .test-item__labelwrap {
    order: 3;
    flex-basis: 100%;
  }
}

/* ----------------------------------------------------------- tag modal --- */

/* Sits beside the comment badge (see comments/_icon.html), so the pair reads
   as one control group rather than two loose buttons. */
.record-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
}

.tag-badge {
  color: var(--text-muted);
}

.tag-badge:hover {
  color: var(--accent);
  background: var(--accent-soft);
}

.comment-modal__panel--narrow {
  max-width: 26rem;
}

.tag-modal__body {
  padding: 0.9rem 1.1rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.tag-modal__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  max-height: 17rem;
  overflow-y: auto;
}

.tag-modal__row form {
  margin: 0;
}

.tag-modal__toggle {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.5rem 0.55rem;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 0.85rem;
  text-align: left;
  cursor: pointer;
}

.tag-modal__toggle:hover {
  background: var(--accent-soft);
}

.tag-modal__check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.15rem;
  height: 1.15rem;
  flex-shrink: 0;
  border: 1.5px solid var(--border);
  border-radius: 5px;
  color: var(--accent-contrast);
}

.tag-modal__row--on .tag-modal__check {
  background: var(--accent);
  border-color: var(--accent);
}

.tag-modal__name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tag-modal__empty {
  margin: 0;
  font-size: 0.83rem;
  color: var(--text-muted);
}

.tag-modal__new {
  display: flex;
  gap: 0.45rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

.tag-modal__new .test-input {
  flex: 1 1 auto;
  min-width: 0;
}

.tag-modal__link {
  font-size: 0.78rem;
  color: var(--text-muted);
  text-decoration: none;
}

.tag-modal__link:hover {
  color: var(--accent);
}

/* ------------------------------------------------------- test status --- */
/* One modifier per services/tests/status.py value. Used as a pill on cards and
   as the header's <select>, so both read the same at a glance. */
.test-status {
  flex-shrink: 0;
  padding: 0.12rem 0.45rem;
  border-radius: 3px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

select.test-status {
  cursor: pointer;
}

.test-status--active {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: var(--accent-soft);
  color: var(--accent);
}

.test-status--passed {
  border-color: color-mix(in srgb, var(--good) 40%, transparent);
  background: var(--good-soft);
  color: var(--good);
}

.test-status--failed {
  border-color: color-mix(in srgb, var(--bad) 40%, transparent);
  background: var(--bad-soft);
  color: var(--bad);
}

/* The card's left edge carries the status too, so a grid scans by colour. */
.test-card--active { border-left: 3px solid var(--accent); }
/* Planned is queued, not in play: a quieter dashed edge so Active leads. */
.test-card--planned { border-left: 3px dashed var(--border); }
.test-card--passed { border-left: 3px solid var(--good); }
.test-card--failed { border-left: 3px solid var(--bad); }

.test-card__name {
  margin-right: auto;
}

/* The title is an input for collaborators, styled to read as the heading. */
.test-head__title-input {
  width: min(40ch, 100%);
  padding: 0.05rem 0.25rem;
  margin-left: -0.25rem;
  border: 1px solid transparent;
  border-radius: 3px;
  background: transparent;
  color: inherit;
  font: inherit;
}

.test-head__title-input:hover,
.test-head__title-input:focus {
  border-color: var(--border);
  outline: none;
}

.test-archived-note {
  padding: 0.5rem 0.8rem;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.test-tabs {
  display: flex;
  gap: 0.25rem;
  margin: 0 0 1rem;
  border-bottom: 1px solid var(--border);
}

/* Scoped as `.test-tabs button.…` to outrank base.css's app-wide button rules
   (button:not(.stat-chip):active etc.), which round every button's corners and
   paint a full accent border plus a brightness dip on click -- on a tab that
   read as a curved underline and a box left behind after each click. A tab is
   flat: square, no border but its underline, no press effect. */
.test-tabs button.test-tabs__tab,
.test-tabs button.test-tabs__tab:active,
.test-tabs button.test-tabs__tab:focus,
.test-tabs button.test-tabs__tab:focus-visible {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0.7rem;
  margin-bottom: -1px;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  filter: none;
  cursor: pointer;
}

.test-tabs button.test-tabs__tab:hover {
  color: var(--text);
}

.test-tabs button.test-tabs__tab--active,
.test-tabs button.test-tabs__tab--active:active,
.test-tabs button.test-tabs__tab--active:focus,
.test-tabs button.test-tabs__tab--active:focus-visible {
  border-bottom-color: var(--accent);
  color: var(--text);
}

/* Keyboard focus still needs a visible cue, just not the click artefact. */
.test-tabs button.test-tabs__tab:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent) 50%, transparent);
  outline-offset: -2px;
}

.test-archived .test-card {
  opacity: 0.75;
}

.test-attach__or {
  font-size: 0.75rem;
  color: var(--text-muted);
}

/* ---------------------------------------------------- request picker --- */
.pick-modal__body {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 0.8rem 1rem 1rem;
  min-height: 0;
}

.pick-modal__rows {
  overflow-y: auto;
  min-height: 0;
  flex: 1;
}

/* Wide enough for the /requests columns that tell two requests apart. */
.pick-modal__panel {
  width: min(960px, calc(100vw - 2rem));
  max-height: min(760px, calc(100vh - 4rem));
}

.pick-modal__row {
  display: grid;
  grid-template-columns: 1.2rem 7rem 10rem 5.5rem minmax(6rem, 1fr) minmax(9rem, 1.3fr) 3rem;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
  padding: 0.4rem 0.3rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.82rem;
  cursor: pointer;
}

.pick-modal__row:hover {
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}

.pick-modal__row > * {
  min-width: 0;
}

.pick-modal__row--head {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-raised);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  cursor: default;
}

.pick-modal__row--head:hover {
  background: var(--surface-raised);
}

/* Phone width: code, status and created -- enough to pick the right one. */
@media (max-width: 640px) {
  .pick-modal__row {
    grid-template-columns: 1.2rem 1fr auto auto;
  }
  .pick-modal__row > :nth-child(n + 5) {
    display: none;
  }
}

.pick-modal__row--on {
  cursor: default;
  color: var(--text-muted);
}

.pick-modal__code {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-weight: 600;
}


.pick-modal__pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 0.5rem;
  font-size: 0.75rem;
  color: var(--text-muted);
}

.pick-modal__foot {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.pick-modal__paste {
  resize: vertical;
}
