/**
 * Back-office tray vocabulary — the shared list surface behind every staff
 * queue / inbox / task tray / correspondence log / search-result / public
 * hearing list. One shape (`TrayDef`), one renderer (`renderTray`,
 * engine-src/staff-page.ts), one set of markup.
 *
 * Rides the design-system source→copy pipeline exactly like be-shell.css /
 * be-content.css: authored here, copied verbatim to /jds/be-tray.css by
 * build.mjs, linked by the app (layout.html, scoped to `.be-tray` so non-list
 * pages render byte-identical).
 *
 * The card surface is the SHARED `.fit-surface-card` (base.css,
 * docs/one-shared-card.md) — the renderer composes it onto `.be-tray`; this
 * file never hand-rolls a radius+shadow container.
 */

.be-tray {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}
/* Tray surface treatment: 12px corner radius, no drop shadow, 1px
   jds/border-color-muted (--jds-border-color-muted = #DFDFDF) border. Overrides
   the shared `.fit-surface-card` recipe (base.css: 8px radius + shadow-regular)
   only on tray-family list surfaces — the card class is still composed, so
   background/padding/inset stay the shared ones. Scope is `.be-tray`, so no
   other page-level card is touched. */
.be-tray.fit-surface-card {
  border-radius: 12px;
  box-shadow: none;
  border: 1px solid var(--jds-border-color-muted);
}

/* Header — the View title + a LIVE result count on the left, search on the
   right. The title is omitted (renderer, showTitle:false) when an outer
   page-hero already carries it (standalone /list); the count is always here. */
.be-tray__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-md);
  flex-wrap: wrap;
}
.be-tray__headings {
  display: flex;
  align-items: baseline;
  gap: var(--space-md);
  min-width: 0;
  flex-wrap: wrap;
}
.be-tray__title { font: var(--font-h4); color: var(--color-black); margin: 0; }
.be-tray__count { font: var(--font-small); color: var(--color-grey-dark); margin: 0; }

/* Search box — inherits the base input chrome; sized only. */
.be-tray__search { flex: 0 1 260px; }
.be-tray__search-input { width: 100%; }

/* Queue tabs — presentational, each IS a saved filter. Same visual grammar as
   the case-workspace tabs (be-content.css .mca-case-tabs). */
/* The strip IS the navigation now — every queue the caller may see is on it,
   across DataTypes, so ten tabs at 1280px is the ordinary case rather than the
   edge. `overflow-x: auto` hid the tail with no affordance. Wrapping kept every
   queue on the page but put the tail BELOW the underline that reads as the
   bottom of the strip, so B1
   (tasks/2026-08-14-more-button-on-the-queue-tab-strip.md) folds the tail
   behind the trailing More control instead.

   The strip nevertheless stays WRAPPABLE, and that is deliberate: what holds a
   queue page to one row is `mountQueueTabOverflow`'s measurement plus
   `.be-tray__tab[hidden] { display: none }` below. `renderTray` / `renderSearch`
   have consumers that never mount that routine — the catalog's tray and search
   demos — and on a container with no `overflow` rule `nowrap` runs their tabs
   straight past the card's right edge and gives the whole page a horizontal
   scrollbar. A second row is the better answer for a strip nobody is measuring.
   Pinned both ways: `test/scenarios/queue-tab-overflow.test.ts` reads this
   declaration, `test/e2e/queue-tab-overflow.spec.ts` renders the unmeasured
   strip in a browser. (`nowrap` on the TAB, further down, is unrelated — it
   stops a label breaking mid-word.) */
.be-tray__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  border-bottom: 1px solid var(--color-border-light);
  position: relative;
}
/* One declaration of the tab's chrome, worn by BOTH things that sit on the row:
   a queue tab, and the trailing More button that folds the rest away (B1). The
   button is the last item on a row of tabs, not a new widget, so it must not
   re-state the grammar — a second copy is how the two drift apart. */
.be-tray__tab,
.be-tray__more-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  text-decoration: none;
  color: var(--color-grey-darkest);
  font: var(--font-small-bold);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
}
.be-tray__tab:hover { color: var(--color-primary-base); }
/* A tab the measuring routine cut. `.be-tray__tab` sets `display: inline-flex`,
   which outranks the UA's `[hidden] { display: none }` — without this the
   "hidden" tabs stay on the row. */
.be-tray__tab[hidden] { display: none; }
/* figma-be-sync: active tab is action maroon-600 (--color-primary-light), not
   the 700 emphasis used for hover/pressed. Scoped to the active tab only. */
.be-tray__tab--active { color: var(--color-primary-light); border-bottom-color: var(--color-primary-light); }
/* Waiting count — the neutral badge from Figma (figma-be-sync-1-dashboard item
   3): squared 4px (not a 999px pill), grey #F3F3F3 fill + 1px #DFDFDF border,
   24px tall. The active tab's pill stays this SAME neutral badge in Figma, so
   the previous brand-tinted override is gone (see the -1-dashboard task).
   bg is --color-grey-light (= jds grey-100 #F3F3F3, Figma jds/neutral/bg-muted;
   NOT --color-grey-lighter, which the app theme remaps to grey-50 #F7F7F7).
   (8px padding-x = Figma jds/badge/padding-x; no matching space token, so a
   documented literal, same convention as the -0b badge dimensions.) */
.be-tray__tab-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 24px;
  padding: 0 8px;
  border: 1px solid var(--color-border-light);
  border-radius: 4px;
  background: var(--color-grey-light);
  color: var(--color-grey-darkest);
  font: var(--font-small);
}
/* The rules above draw the queue navigation in its DEFAULT form. There is a
   second form — the queues as a nested list in the LEFT RAIL
   (jds-side-bar-sub-list / jds-side-bar-sub-item in
   design-system/src/components/jds-side-bar), which carries its own copy of the
   Figma neutral count badge. The two are either/or, chosen per person by the
   switch in tasks/2026-08-14-merge-the-rail-behind-a-feature-switch.md: in rail
   mode the page passes no `queueTabs`, so none of the rules above match
   anything. Neither set of styles is dead, and neither may be deleted while both
   modes exist. */

/* The overflow control (B1). Drawn hidden on every strip; the browser's
   measuring routine (engine-src/queue-tab-overflow.ts) unhides it only when a
   tab actually had to be cut, so a strip that fits is byte-identical to before.
   It wears the TAB's own chrome — same font, same padding, same underline
   grammar — because it is the last thing on the row of tabs, not a new widget.
   Its number is the shared `.be-tray__tab-count` badge, and it means "this many
   more QUEUES" (every other number on the strip means "cases waiting here",
   which is why the button carries an aria-label spelling it out). */
.be-tray__more { position: relative; margin-left: auto; flex: 0 0 auto; }
.be-tray__more[hidden] { display: none; }
/* Only what a <button> needs on top of the tab chrome above: the UA's own border
   and fill, which an anchor does not carry. */
.be-tray__more-btn { border-width: 0 0 2px; border-style: solid; background: none; cursor: pointer; }
/* The two STATE rules are spelled out again rather than folded into the tab's
   (`.be-tray__tab:hover, .be-tray__more-btn:hover { … }`), and that is not an
   oversight: `test/scenarios/figma-be-sync-overrides-pinned.test.ts` pins the
   active tab's maroon-600 by reading the body of the rule whose WHOLE selector
   is `.be-tray__tab--active` (and its hover control), so a selector list would
   make that guard unable to find what it guards. `aria-expanded` is this
   button's "the thing you are on" — lit exactly while its menu is open. */
.be-tray__more-btn:hover { color: var(--color-primary-base); }
.be-tray__more-btn[aria-expanded="true"] {
  color: var(--color-primary-light);
  border-bottom-color: var(--color-primary-light);
}
.be-tray__more-chev { width: 10px; height: 10px; flex: 0 0 auto; }
/* The menu keeps each queue's own waiting count — a list of labels alone is the
   dropdown already rejected, whose whole fault was that the counts disappear
   until you click. */
.be-tray__more-panel {
  position: absolute;
  right: 0;
  top: calc(100% + var(--space-xs));
  z-index: 30;
  min-width: 280px;
  /* The shared surface treatment, by token — same background, border, radius and
     elevation the shared card uses (docs/one-shared-card.md), so the menu is
     the card vocabulary in a floating box rather than a second look. */
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-regular);
  padding: var(--space-xs);
}
.be-tray__more-panel[hidden] { display: none; }
/* One declaration of the menu row's chrome, worn by BOTH things the menu holds:
   a hidden queue's link, and the **Edit the order** control in the footer (B2).
   A second copy is how the two drift apart — the same reasoning the tab and the
   More button share theirs above. */
.be-tray__more-item,
.be-tray__more-edit {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-sm);
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: var(--color-grey-darkest);
  font: var(--font-small-bold);
}
.be-tray__more-item:hover,
.be-tray__more-item:focus-visible,
.be-tray__more-edit:hover,
.be-tray__more-edit:focus-visible {
  background: var(--color-grey-light);
  color: var(--color-primary-base);
}
.be-tray__more-item[aria-current="page"] { color: var(--color-primary-light); }
.be-tray__more-foot {
  border-top: 1px solid var(--color-border-light);
  margin: var(--space-xs) 0 0;
  padding: var(--space-sm) var(--space-sm) var(--space-xs);
  font: var(--font-small);
  color: var(--color-grey-dark);
}
/* The footer as an ACTION rather than a sentence (B2,
   tasks/done/2026-08-14-ordering-the-queue-tabs.md). This slot held a TOTAL of the
   hidden queues' counts until 2026-08-14, when it turned out to count the same
   cases twice and was deleted; the replacement is not a truer number but
   **Edit the order** — because if there is a More there is something hidden,
   and if something is hidden the order is worth changing. Reached from here and
   nowhere else, so it costs the strip no width at all. */
.be-tray__more-foot--action { display: flex; padding: var(--space-xs) 0 0; }
/* Only what a <button> needs on top of the menu-item chrome it shares above:
   the UA's own border, fill and text alignment — the same three things
   `.be-tray__more-btn` undoes against the tab. It is a row of this menu, not a
   new widget, so it must not re-state the grammar. */
.be-tray__more-edit {
  width: 100%;
  border: 0;
  background: none;
  cursor: pointer;
  text-align: left;
  color: var(--color-primary-base);
  /* The item's `space-between` is for a label and its count pill at opposite
     ends; this row is an icon and its words, which belong together. */
  justify-content: flex-start;
  gap: var(--space-sm);
}
/* The two knobs on the grip mark are filled with the surface behind them so
   they punch through the line they sit on. Here rather than on the SVG itself:
   `var()` in a presentation attribute is not reliably honoured, and a hard
   white would be wrong the day the menu's surface is not white. */
.be-tray__more-edit svg circle { fill: var(--color-bg-surface); }
/* The ordering panel itself — same floating-surface treatment as the menu it is
   launched from, and absolutely positioned inside the `<nav>` so it cannot
   change the strip's own box (an in-flow panel would grow the nav and hand the
   measuring routine's ResizeObserver a reason to re-fit the moment it opened).
   Its rows are below. */
.be-tray__order {
  position: absolute;
  right: 0;
  top: calc(100% + var(--space-xs));
  z-index: 30;
  min-width: 320px;
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-regular);
  padding: var(--space-sm);
  /* BOUNDED BY THE SCREEN. A judge holds ten queues; ten rows plus the title,
     the hint, the fold line and the footer runs past the bottom of a 700px
     window — and an absolutely positioned panel neither repositions nor
     scrolls, so the last rows are not merely awkward, they are unreachable.
     The last thing to go is **Reset to automatic**, which is the one control
     that undoes whatever was just done above it.
     The subtraction is the panel's own distance from the top of the viewport
     (the thin top bar, the content gutter, the card head, the strip) with room
     to spare; `dvh` so a mobile browser's retracting toolbar cannot park the
     footer behind itself. The SCROLL is on the row list below, never here:
     scrolling the panel would carry the title and the footer away with the
     rows, which is the same defect one layer in. */
  max-height: calc(100dvh - 16rem);
  display: flex;
  flex-direction: column;
}
.be-tray__order[hidden] { display: none; }
.be-tray__order:focus { outline: none; }
.be-tray__order-title { font: var(--font-small-bold); margin: 0 0 4px; }
.be-tray__order-hint {
  font: var(--font-small);
  color: var(--color-grey-dark);
  margin: 0 0 var(--space-sm);
  max-width: 38ch;
}
/* The panel's ONE scroller. `min-height: 0` is load-bearing and not tidiness:
   a flex item's default `min-height: auto` is content-sized, so without it the
   list simply grows the panel past the bound above and `overflow-y` never
   engages. The FOLD line lives inside this list (`placeFold` inserts it before
   the first hidden row), so it travels with the rows it marks rather than
   floating over them. */
.be-tray__order-list { list-style: none; margin: 0; padding: 0; overflow-y: auto; min-height: 0; }
.be-tray__order-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-xs);
  border-radius: var(--radius-sm);
}
.be-tray__order-row:hover { background: var(--color-grey-light); }
/* The row under the hand while it is being dragged. Faded rather than moved:
   the drop re-orders the list, so the row itself never travels — showing it
   half-there is the whole of the feedback, and it costs no layout. */
.be-tray__order-row--dragging { opacity: 0.5; }
.be-tray__order-label { font: var(--font-small-bold); flex: 1; display: flex; align-items: center; gap: var(--space-xs); }
/* "New" — a queue the stored order never named, which joined at the front. */
.be-tray__order-new {
  font: var(--font-small);
  color: var(--color-primary-base);
  border: 1px solid var(--color-primary-light);
  border-radius: var(--radius-sm);
  padding: 0 4px;
}
.be-tray__order-grip { color: var(--color-grey-dark); display: flex; align-items: center; cursor: grab; }
.be-tray__order-moves { display: flex; gap: 2px; flex: 0 0 auto; }
/* The row's controls arrive on hover, or the moment a keyboard user lands on
   the row. They FADE — a control taken out of the box tree cannot be tabbed to,
   so `display: none` here would leave the only controls this panel has
   reachable with a mouse and by nothing else. */
.be-tray__order-grip, .be-tray__order-moves { opacity: 0; transition: opacity 0.1s linear; }
.be-tray__order-row:hover .be-tray__order-grip,
.be-tray__order-row:hover .be-tray__order-moves,
.be-tray__order-row:focus-within .be-tray__order-grip,
.be-tray__order-row:focus-within .be-tray__order-moves { opacity: 1; }
/* A touch screen has no hover at all — and HTML5 drag does not fire there
   either, so a grip that faded in would be an affordance for something that
   cannot happen. The arrows are the real control; they are simply always on. */
@media (hover: none) {
  .be-tray__order-grip, .be-tray__order-moves { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .be-tray__order-grip, .be-tray__order-moves { transition: none; }
}
.be-tray__order-move {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  background: none;
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  color: var(--color-grey-dark);
  cursor: pointer;
}
.be-tray__order-move:hover:not(:disabled) { border-color: var(--color-primary-base); color: var(--color-primary-base); }
.be-tray__order-move:disabled { opacity: 0.3; cursor: default; }
/* The one exception to the fold line, worn by the queue a person is standing in
   — the fit rule keeps that one on the strip whatever its position, so its row
   can sit below the line and still be on screen. Quiet: it is a footnote on a
   row, not a second badge. */
.be-tray__order-here { font: var(--font-small); color: var(--color-grey-dark); }
/* THE FOLD — where the strip runs out of room at this window width. Dashed
   because it is a cut in a list rather than a border on a box, and it is the
   one thing this panel says that a plain settings screen could not. */
.be-tray__order-fold {
  border-top: 1px dashed var(--color-border-light);
  margin: var(--space-xs) 0;
  padding-top: var(--space-xs);
  font: var(--font-small);
  color: var(--color-grey-dark);
}
.be-tray__order-fold[hidden] { display: none; }
.be-tray__order-foot {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-top: var(--space-sm);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--color-border-light);
}
.be-tray__order-reset {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--color-primary-base);
  font: var(--font-small-bold);
}
.be-tray__order-reset:hover { text-decoration: underline; }
.be-tray__order-live { font: var(--font-small); color: var(--color-grey-dark); margin-left: auto; }

/* Column table — the be-* designs are real tables. Wide tables scroll inside
   the card, never the page body (docs/one-shared-card overflow rule). */
.be-tray__table-wrap { overflow-x: auto; }
.be-tray__table { width: 100%; border-collapse: collapse; }
.be-tray__th {
  text-align: left;
  font: var(--font-small-bold);
  color: var(--color-grey-darkest);
  padding: var(--space-xs) var(--space-sm);
  border-bottom: 1px solid var(--color-border-light);
  white-space: nowrap;
}
.be-tray__th--end { text-align: right; }
.be-tray__cell {
  padding: var(--space-sm);
  border-bottom: 1px solid var(--color-border-light);
  font: var(--font-paragraph);
  vertical-align: baseline;
}
.be-tray__table tbody .list-row:last-child .be-tray__cell { border-bottom: none; }
.be-tray__cell--end { text-align: right; white-space: nowrap; }
.be-tray__cell--link { font: var(--font-small-bold); }
/* Row hover is NEUTRAL, never a maroon tint: a row is a place to go, not an
   action to take, and the brand colour on a whole row reads as a warning.
   Owner's call, 2026-08-21: use jds/bg-translucent-subtle — #0E0E0E at 5%
   opacity — the same variable the sidebar/top-bar hover uses, so the strip,
   the panel and the table all hover the same. Fallback carries the literal
   for consumers of the CSS that don't include the JDS light-theme token file. */
.be-tray__table .list-row:hover { background: var(--jds-bg-translucent-subtle); }
.be-tray__cell--link .list-row__link { color: var(--color-primary-base); text-decoration: none; }
.be-tray__cell--link .list-row__link:hover { text-decoration: underline; }
/* Right-aligned meta (the shared row pill is styled in base.css). */
.be-tray__table .list-row__when { font: var(--font-small); color: var(--color-grey-dark); white-space: nowrap; }

/* Due date + "Due in N days" chip, stacked (figma-be-sync-1-dashboard item 2).
   The due column is right-aligned, so the stack aligns to the cell's end. */
.be-tray__due { display: inline-flex; flex-direction: column; gap: 4px; align-items: flex-end; }
/* The yellow "due soon" chip — the Figma warning badge (jds/badge/warning):
   #FEF4CB fill (jds/yellow-100), 1px #FCDE63 border (jds/yellow-200), #7E6917
   text (jds/warning color-default = jds/yellow-600), 4px radius, 24px tall, 8px
   padding-x. Uses the --jds-yellow-* primitives directly: the app's semantic
   --color-status-pending-* tokens are a MORE saturated pairing (yellow-200 bg)
   than Figma's badge, so the raw palette is the faithful source here. */
.be-tray__due-chip {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  padding: 0 8px;
  border: 1px solid var(--jds-yellow-200);
  border-radius: 4px;
  background: var(--jds-yellow-100);
  color: var(--jds-yellow-600);
  font: var(--font-small);
  white-space: nowrap;
}

/* Empty state — a designed body, never a blank void. The min-height keeps it a
   real surface (and sidesteps the toBeVisible race on a 0-height async box —
   docs project memory: padding-on-empty-placeholder). */
.be-tray__empty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 160px;
  text-align: center;
}
.be-tray__empty-text {
  font: var(--font-paragraph);
  color: var(--color-grey-dark);
  margin: 0;
  max-width: 42ch;
}

/* ── "My tasks" featured cards + the dedicated star picker ──────────────────
   tasks/2026-08-18-my-tasks-featured-cards.md. A row of big number cards ABOVE
   the tray, one per queue the person has starred, plus a picker to choose them.
   Display-only over the same manifest the strip lists; it reorders nothing.

   Not scoped to `.be-tray` like the rest of this file: the featured row is a
   SIBLING above the tray card, on its own `.be-featured` root. Everything below
   targets a `.be-featured*` class, so a page without the row renders
   byte-identical — the same "no matching element ⇒ no effect" discipline. The
   CARDS compose the SHARED `.fit-surface-card` (base.css, docs/one-shared-card.md);
   this file hand-rolls no radius+shadow surface. The picker is the tray family's
   own bespoke popover, styled after `.be-tray__order` above. */
.be-featured { position: relative; display: flex; flex-direction: column; gap: var(--space-sm); }
.be-featured__head { display: flex; align-items: center; gap: var(--space-sm); }
.be-featured__label {
  font: var(--font-xs-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-grey-dark);
}
/* The small "Edit" text link that opens the picker — a link, not a button look,
   so it reads as the quiet third choice the brief intends. */
.be-featured__edit {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--color-primary-base);
  font: var(--font-small-bold);
}
.be-featured__edit:hover, .be-featured__edit:focus-visible { text-decoration: underline; }

/* The cards. At most four (the writer's cap), so a single fluid row always fits;
   they wrap only on a very narrow window rather than overflowing the card. */
.be-featured__cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-md);
}
.be-featured__cards:empty { display: none; }
.be-featured__card {
  /* Denser than the default card — a tile, not a page panel. */
  --fit-card-pad: var(--space-md);
  display: block;
  text-decoration: none;
  color: inherit;
}
.be-featured__card:hover { border-color: var(--color-primary-light); }
.be-featured__card-cap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  font: var(--font-xs-bold);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--color-grey-dark);
}
.be-featured__card-star { color: var(--jds-yellow-600); flex: 0 0 auto; }
.be-featured__card-num {
  font: var(--font-h2);
  color: var(--color-black);
  margin-top: var(--space-xs);
  line-height: 1;
}
/* The empty prompt when nothing is featured yet — the row is never a blank band
   with only the Edit link floating in it. */
.be-featured__empty { font: var(--font-small); color: var(--color-grey-dark); margin: 0; }
.be-featured__empty[hidden] { display: none; }

/* The picker — the tray-family popover, hung under the Edit link. Same look as
   `.be-tray__order`: surface + border + shadow, a scrolling row list, a footer. */
.be-featured__picker {
  position: absolute;
  left: 0;
  top: calc(100% + var(--space-2xs));
  z-index: 30;
  width: 360px;
  max-width: calc(100vw - 2 * var(--space-md));
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-regular);
  padding: var(--space-sm);
  max-height: calc(100dvh - 14rem);
  display: flex;
  flex-direction: column;
}
.be-featured__picker[hidden] { display: none; }
.be-featured__picker-title { font: var(--font-small-bold); margin: 0 0 4px; }
.be-featured__picker-hint {
  font: var(--font-small);
  color: var(--color-grey-dark);
  margin: 0 0 var(--space-2xs);
  max-width: 42ch;
}
.be-featured__picker-note {
  font: var(--font-small-bold);
  color: var(--color-primary-base);
  margin: 0 0 var(--space-xs);
}
.be-featured__list { list-style: none; margin: 0; padding: 0; overflow-y: auto; min-height: 0; }
.be-featured__row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-xs);
  border-radius: var(--radius-sm);
}
.be-featured__row:hover { background: var(--color-grey-light); }
/* A non-starred row once the cap is reached — dimmed, its star not clickable. */
.be-featured__row--disabled .be-featured__row-name,
.be-featured__row--disabled .be-featured__row-count { opacity: 0.5; }
.be-featured__row-star {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
  font: var(--font-h5);
  line-height: 1;
  color: var(--color-grey-dark);
}
.be-featured__row-star--on { color: var(--jds-yellow-600); }
.be-featured__row-star:disabled { cursor: not-allowed; }
.be-featured__row-name { font: var(--font-small-bold); flex: 1; min-width: 0; }
/* The queue's own count, in the neutral pill the tab strip wears. */
.be-featured__row-count {
  flex: 0 0 auto;
  min-width: 20px;
  text-align: center;
  background: var(--color-grey-light);
  color: var(--color-grey-dark);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-xs);
  font: var(--font-xs-bold);
}
.be-featured__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-top: var(--space-sm);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--color-border-light);
}
/* Both footer buttons are jud-button now — `.be-featured__reset` and
   `.be-featured__done` carry no look of their own, only as test/spacing
   hooks. */
