[hidden] {
  display: none !important;
}

body.my-stall-page {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  overflow: hidden;
}

.my-stall-page .atmosphere {
  position: fixed;
  z-index: 0;
  top: -150px;
  right: -130px;
  width: 430px;
  height: 430px;
  border-radius: 48% 52% 58% 42%;
  background: radial-gradient(
    circle at 35% 35%,
    var(--color-accent-300),
    var(--color-accent-200) 55%,
    transparent 75%
  );
  filter: blur(16px);
  opacity: 0.55;
  pointer-events: none;
}

body.my-stall-page > header,
body.my-stall-page > main {
  position: relative;
  z-index: 1;
}

/* ------------------------------------------------------------------ *
 * Header — the pattern every staff surface repeats.
 * ------------------------------------------------------------------ */

body.my-stall-page > header {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6) var(--space-3);
}

.my-stall-page .brand {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 20px;
  color: var(--color-text);
  text-decoration: none;
}

.my-stall-page .role-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
}

.my-stall-page .role-nav .role {
  font-size: 12px;
  margin-right: var(--space-2);
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* .role-nav-link itself now lives in organic-system.css, composed
 * unqualified (SURF-4f standards remediation) — identical here to the
 * other three surfaces, so one shared definition replaces four copies. */

/* `#staff-logout` composes `.logout-link` (organic-system.css), which carries
 * the ghost shape, the body face and the mark's sizing. The `.text-button`
 * block that stood here restated a third of that over `.btn .btn-ghost` —
 * whose heading face was the thing it was fighting. */

/* ------------------------------------------------------------------ *
 * Route state, connectivity, status.
 * ------------------------------------------------------------------ */

.my-stall-page main {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.intro {
  flex: none;
  padding: 0 var(--space-6) var(--space-3);
}

.intro .eyebrow {
  margin: 0;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-accent-700);
}

.intro h1 {
  margin: var(--space-1) 0 var(--space-2);
  font-size: 30px;
}

.intro h1 em {
  font-style: normal;
  color: var(--color-accent);
}

.intro p:not(.eyebrow) {
  margin: 0;
  max-width: 60ch;
  font-size: 13.5px;
  color: color-mix(
    in srgb,
    var(--color-text) 55%,
    transparent
  ); /* .text-muted */
}

.connectivity-status {
  flex: none;
  margin: 0 var(--space-6) var(--space-3) !important;
}

.my-stall-route-state {
  flex: none;
  margin: 0 var(--space-6) var(--space-3);
  padding: var(--space-4);
  border-radius: calc(var(--radius-lg) * 1.15); /* the .card/.dialog radius */
  background: var(--color-surface);
  font-size: 13.5px;
  line-height: 1.5;
}

.my-stall-route-state .eyebrow {
  margin: 0;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-accent-700);
}

.my-stall-route-state h2 {
  margin: var(--space-1) 0 var(--space-2);
  font-size: 27px;
}

.my-stall-page .status {
  position: sticky;
  z-index: 2;
  top: 12px;
  flex: none;
  margin: 0 var(--space-6);
  font-size: 13px;
  color: var(--color-accent-700);
}

.my-stall-page .status:empty {
  margin: 0;
  visibility: hidden;
}

/* ------------------------------------------------------------------ *
 * The workspace: scrolls inside the fixed shell.
 * ------------------------------------------------------------------ */

.my-stall-workspace {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--space-3) var(--space-6) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.hint {
  font-size: 12.5px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

.empty-state {
  padding: var(--space-4);
  border-radius: 24px;
  background: var(--color-surface);
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* — active-stall picker — */

.active-stall-picker {
  padding: var(--space-4) var(--space-6);
  border-radius: calc(var(--radius-lg) * 1.15); /* the .card/.dialog radius */
  background: var(--color-surface);
}

.active-stall-picker h2 {
  margin: 0 0 var(--space-3);
  font-size: 19px;
}

.stall-form label {
  display: block;
  margin: 0 0 var(--space-3);
  font-size: 12px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}

.stall-form select,
.stall-form input:not([type="checkbox"]) {
  display: block;
  width: 100%;
  min-height: 48px;
  margin-top: 5px;
  padding: 0 14px;
  font: inherit;
  font-size: 14px;
  color: var(--color-text);
  background: var(--color-bg);
  border: 1px solid var(--color-divider);
  border-radius: 999px;
}

/* No page-local :focus-visible override here (SURF-4f standards
 * remediation): the global rule in organic-system.css already gives every
 * control on this page the documented 2px accent ring at the documented
 * 2px offset — this used to restate it with the offset silently zeroed,
 * with no comment or test defending the difference. */

/* Every .stall-form submit already composes .clipped/.primary
 * (handoff-organic.css) in the markup, and #cancel-stall-change now does
 * too — this duplicated that shape instead of relying on it. */

/* — active stall header — */

.active-stall {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  border-radius: calc(var(--radius-lg) * 1.15); /* the .card/.dialog radius */
  background: var(--color-surface);
}

.active-stall-identity {
  min-width: 0;
  flex: 1 1 auto;
}

.active-stall-identity .eyebrow {
  margin: 0;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-accent-700);
}

.active-stall-identity h2 {
  margin: 2px 0 0;
  overflow-wrap: anywhere;
  font-size: 24px;
}

/* #change-stall now lives in organic-system.css, identical to Stalls
 * Overview's #change-stalls (SURF-4f standards remediation). */

.event-state {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--color-accent-2-200);
  color: var(--color-accent-2-800);
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 13px;
}

.event-state::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: currentColor;
}

.queue-counts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  margin: 0;
  width: 100%;
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
}

/* — queue lanes — */

/*
 * No card around the queues. `Stall Queue.dc.html` lays Ready, Received and
 * In Prep straight onto the page ground — Ready carries its own accent panel
 * and every ticket is a `--color-surface` card on the cream — and wraps none
 * of it in a third container. The wrapper this replaces also titled the
 * surface a third time ("Current work / Stall Orders") and forced every
 * ticket onto `--color-bg` to stay visible against it, which is the inverse
 * of what the artboard draws.
 *
 * `#queues-heading` survives, clipped, as the section's accessible name.
 */
.stall-queues {
  padding: 0;
}

.queue-heading-row h3 {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.queue-panel + .queue-panel,
.queue-pair + .queue-panel {
  margin-top: var(--space-4);
}

/*
 * Heading then count, adjacent and flush left at a 10px gap — the artboard's
 * `Received` / `In Prep` pattern. Ready is the exception below: its kicker
 * sits opposite an "Oldest first" note, so that one row is spread.
 */
.queue-panel-heading {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: var(--space-2);
  padding: 0 var(--space-2);
}

/* 19px, as the artboard sets the Received and In Prep headings. */
.queue-panel-heading h4 {
  margin: 0;
  font-size: 19px;
}

/*
 * The count beside the heading, as `Stall Queue.dc.html` draws it: a
 * `.tag.tag-accent-2` carrying the number and nothing else. It replaced two
 * phrases the artboard does not draw ("Make next", "Making now") which
 * restated what the two headings already say in order.
 */
.queue-panel-heading .tag {
  flex: none;
  font-variant-numeric: tabular-nums;
}

.queue-priority {
  font-size: 12.5px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

.queue-list {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

/*
 * The ticket, as the artboard draws it: a 28px `--color-surface` card on the
 * cream ground with `--shadow-sm`. It was a `--color-bg` card, which is what
 * the removed `.stall-queues` surface wrapper forced — the inverse of the
 * design, and invisible once the wrapper went.
 */
.queue-row {
  position: relative;
  padding: var(--space-3) var(--space-4);
  border-radius: 28px;
  background: var(--color-surface);
  box-shadow: var(--shadow-sm);
}

/*
 * In Prep tickets carry a hairline accent border and Received tickets do not
 * — the artboard's only difference between the two columns' rows, and the one
 * that says at a glance which tickets somebody has already picked up.
 */
#in-prep-orders .queue-row {
  border: 1px solid var(--color-accent-200);
}

.queue-row[data-arrived] {
  border-left: 3px solid #ea580c;
  background: linear-gradient(90deg, #fff7ed, transparent 60%);
}

@media (prefers-reduced-motion: no-preference) {
  @keyframes stall-order-arrived {
    from {
      background-color: #fdba74;
    }
    to {
      background-color: transparent;
    }
  }
  .queue-row[data-arrived] {
    animation: stall-order-arrived 1.2s ease-out 1;
  }
}

/* `#122` at the left edge, the elapsed clock at the right, as the design draws
 * the row. They packed together on the left before, which put the two numbers
 * a runner compares — which order, how long — in the same place instead of at
 * the two ends of a line their eye already travels. */
.queue-strip {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
}

/*
 * The timer is not a direct child of the strip — it sits inside `.queue-meta`
 * with the LATE tag and the state word — so pushing `.queue-timer` right did
 * nothing. It is the meta group that travels to the right edge.
 */
.queue-strip .queue-meta {
  margin: 0 0 0 auto;
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
}

.queue-number {
  flex: none;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  /* 18px, as the design sets it. */
  font-size: 18px;
}

.queue-timer {
  margin-left: auto;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
}

/*
 * The root artboard uses base accent; this ramp step keeps its hue and
 * raises small-text contrast above 4.5:1.
 *
 * `docs/agents/design.md` states the rule this file was breaking:
 * "Accent-to-ground is tuned to 3:1 - fine for icons, large text and chrome,
 * not for body copy: paragraph-size accent text uses --color-accent-700."
 * Bare `--color-accent` on `--color-surface` computes 2.69:1, which fails
 * WCAG AA's 4.5:1 for text this size.
 *
 * The artboard does draw these in the base accent. Deepening a step within the
 * same ramp is a deliberate departure from it, not the app quietly choosing a
 * different colour - the hue and the escalation it signals are unchanged.
 */
[data-wait="warn"] .queue-timer {
  color: var(--color-accent-700); /* 5.09:1 on --color-surface */
}

/*
 * Late was the BASE accent, which made the more urgent tier the *lower*
 * contrast of the two - 2.69:1 against warn's 5.09:1. One ramp step deeper
 * than warn restores the escalation in the channel the tier is carried in.
 */
[data-wait="late"] .queue-timer {
  color: var(--color-accent-800); /* 7.75:1 on --color-surface */
}

.queue-meta {
  margin: var(--space-2) 0 0;
  font-size: 12.5px;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
}

.queue-lines {
  display: grid;
  gap: 1px;
  margin: var(--space-2) 0 0;
  padding: 0;
  list-style: none;
  font-size: 14px;
  line-height: 1.5;
}

/* One line per order line, the quantity tinted and tabular so a column of
 * them lines up — the artboard's ticket body. */
.queue-line {
  display: flex;
  gap: 6px;
}

.queue-line-qty {
  font-variant-numeric: tabular-nums;
  color: var(--color-accent-700);
}

.recalled-flag {
  display: block;
  margin: 0 0 6px;
  padding: 4px 8px;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: #b91c1c;
  background: #fef2f2;
  border-left: 3px solid #b91c1c;
  border-radius: 0;
  overflow-wrap: anywhere;
}

/* .fulfilment-actions and its buttons now live in handoff-organic.css
 * (SURF-4f standards remediation) — shared with Stalls Overview, which
 * renders the same handoff.js markup. */

/*
 * The ticket's one forward action, as `Stall Queue.dc.html` draws it:
 * `.btn.btn-primary`, full width, 52px. It was an outlined pill at 44px,
 * indistinguishable from the Cancel Order Line controls stacked under it —
 * the artboard gives the move-it-along action the weight and the backwards
 * controls the outline.
 */
.my-stall-page .fulfilment-actions > button.start-prep,
.my-stall-page .fulfilment-actions > button.mark-ready {
  min-height: 52px;
  border-color: var(--color-accent);
  background: var(--color-accent);
  color: var(--color-bg);
}

/*
 * The dialog's own hierarchy, at the artboard's three heights: the commit at
 * 56px, the backwards action at 52px, the way out at 48px.
 *
 * The child combinator is load-bearing. `handoff.js` appends an open
 * confirmation panel into the same container as the controls, so a descendant
 * selector also resizes the `Yes — #122` button inside that panel — which
 * `browser/my-stall-handoff.spec.js` measures on the device at 44px, and
 * which the artboards do not draw at all (Return to Received is app-only).
 */
#handoff-dialog .confirm-handoff,
#handoff-dialog .confirm-exceptional {
  min-height: 56px;
}

#handoff-dialog .fulfilment-actions > button.fulfilment-control {
  min-height: 52px;
}

.handoff {
  margin-top: var(--space-3);
  padding: var(--space-3);
  border-radius: 20px;
  background: var(--color-accent-100);
}

.handoff input {
  display: block;
  width: 100%;
  min-height: 44px;
  margin-top: var(--space-2);
  padding: 0 14px;
  border: 1px solid var(--color-divider);
  border-radius: 999px;
  font: inherit;
  font-size: 14px;
}

/* — readiness — */

.readiness {
  padding: var(--space-4) var(--space-6);
  border-radius: calc(var(--radius-lg) * 1.15); /* the .card/.dialog radius */
  background: var(--color-surface);
}

.readiness h3 {
  margin: 0 0 var(--space-3);
  font-size: 19px;
}

.blocker-list {
  display: grid;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
  padding: 0;
  list-style: none;
}

.blocker {
  padding: var(--space-3) var(--space-4);
  border-radius: 20px;
  background: var(--color-accent-100);
  color: var(--color-accent-800);
  font-size: 13px;
}

.enable-orders-panel,
.activation-undo {
  margin-top: var(--space-3);
}

#activate-stall,
#undo-activation {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 var(--space-6);
  border: none;
  border-radius: 999px;
  background: var(--color-accent);
  color: var(--color-bg);
  font: inherit;
  font-weight: 600;
  font-size: 14.5px;
  cursor: pointer;
}

#undo-activation {
  background: transparent;
  border: 1px solid var(--color-divider);
  color: var(--color-text);
}

/* — capacity — */

.capacity-panel {
  padding: var(--space-4) var(--space-6);
  border-radius: calc(var(--radius-lg) * 1.15); /* the .card/.dialog radius */
  background: var(--color-surface);
}

.capacity-panel h3 {
  margin: 0 0 var(--space-2);
  font-size: 19px;
}

.capacity-controls {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* min-width:0 — same fix as .active-stall-identity (745dacb): flex:1 sets
 * flex-basis:0%, but without this the item's automatic minimum still
 * floors at its content's min-content width, and at 200% zoom's narrow
 * effective viewport two of these side by side don't fit, overflowing
 * the row instead of shrinking. */
.capacity-choice {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  padding: 0 var(--space-3);
  border: 1px solid var(--color-divider);
  border-radius: 999px;
  background: var(--color-bg);
  color: var(--color-text);
  font: inherit;
  font-weight: 600;
  font-size: 13.5px;
  cursor: pointer;
}

.capacity-choice[aria-pressed="true"] {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-bg);
}

/* — setup: menu + ingredients — */

.stall-setup-review {
  padding: var(--space-4) var(--space-6);
  border-radius: calc(var(--radius-lg) * 1.15); /* the .card/.dialog radius */
  background: var(--color-surface);
}

.stall-setup-review h3 {
  margin: 0 0 var(--space-2);
  font-size: 19px;
}

.setup-list {
  display: grid;
  gap: var(--space-2);
  margin: var(--space-2) 0 0;
  padding: 0;
  list-style: none;
}

.setup-row {
  padding: var(--space-3) var(--space-4);
  border-radius: 20px;
  background: var(--color-bg);
}

/* flex-wrap: .menu-item-price and .menu-item-availability are flex:none
 * (never shrink), so at 200% zoom's narrow effective viewport, letting
 * .menu-item-name collapse to 0 (below) is not enough on its own — the
 * two fixed-size figures on the right can still exceed what's left and
 * need to wrap onto their own line rather than overflow the row. */
.menu-item-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  font-size: 13.5px;
}

.menu-item-name {
  flex: 1;
  min-width: 0;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 15px;
}

.menu-item-price {
  flex: none;
  font-variant-numeric: tabular-nums;
}

.menu-item-availability {
  flex: none;
  font-size: 11px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

.recipe-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 13px;
}

.recipe-ingredient-name {
  flex: 1;
  min-width: 0;
}

details > summary {
  min-height: 44px;
  display: flex;
  align-items: center;
  margin-top: var(--space-3);
  color: var(--color-accent-700);
  font-weight: 600;
  font-size: 13.5px;
  cursor: pointer;
  list-style: none;
}

details > summary::-webkit-details-marker {
  display: none;
}

.stall-setup-review .stall-form {
  margin-top: var(--space-3);
}

.stall-setup-review .stall-form label {
  margin-bottom: var(--space-2);
}

.recipe-fieldset {
  margin: var(--space-3) 0 0;
  padding: var(--space-3);
  border: 1px solid var(--color-divider);
  border-radius: 20px;
}

.recipe-fieldset legend {
  padding: 0 6px;
  font-size: 12px;
  font-weight: 600;
}

.menu-enabled-option {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  font-size: 13px;
}

.menu-control {
  margin-top: var(--space-2);
}

/* — ingredient stock — */

.ingredient-stock-card {
  padding: var(--space-3) var(--space-4);
  border-radius: 20px;
  background: var(--color-bg);
}

.ingredient-stock-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}

.ingredient-stock-name {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 15px;
}

.ingredient-stock-status {
  font-size: 11px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

.stock-counts {
  margin: 4px 0 0;
  font-size: 12.5px;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
}

.ingredient-threshold {
  margin: 2px 0 0;
}

.restock-alert {
  margin: var(--space-2) 0 0;
  padding: var(--space-2) var(--space-3);
  border-radius: 16px;
  background: var(--color-accent-100);
  color: var(--color-accent-800);
}

.restock-alert-text {
  margin: 2px 0 0;
  font-size: 12.5px;
}

.stock-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

.stock-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-2);
}

.stock-form-title {
  flex: 1 0 100%;
  margin: 0;
  font-size: 12px;
  font-weight: 600;
}

.stock-field-label {
  display: block;
  font-size: 11.5px;
  color: color-mix(
    in srgb,
    var(--color-text) 70%,
    transparent
  ); /* .field > label */
}

.stock-control {
  min-height: 44px;
}

.stock-control.stock-units,
.stock-control.corrected-available,
.stock-control.correction-reason {
  width: 100%;
  padding: 0 12px;
  border: 1px solid var(--color-divider);
  border-radius: 999px;
  font: inherit;
  font-size: 13px;
}

button.stock-control {
  padding: 0 var(--space-3);
  border: 1px solid var(--color-divider);
  border-radius: 999px;
  background: transparent;
  color: var(--color-text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

button.stock-control.primary {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-bg);
}

.stock-form-hint {
  flex: 1 0 100%;
  margin: 0;
  font-size: 11.5px;
}

/* ------------------------------------------------------------------ *
 * handoff.js's shared button family and forms (My Stall and All Stalls
 * both use it) now live in handoff-organic.css, loaded before this
 * file (SURF-4f standards remediation) — only this surface's own
 * genuine deltas stay here.
 * ------------------------------------------------------------------ */

.handoff-form,
.exceptional-form,
.fulfilment-panel {
  padding: var(--space-3);
}

.handoff-grace {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  font-size: 12.5px;
  color: var(--color-accent-700);
}

@media (prefers-reduced-motion: reduce) {
  .my-stall-page * {
    transition: none;
  }
}

/* ------------------------------------------------------------------ *
 * Header pattern and the designed queue layout
 * (Stall Queue.dc.html option 4a, NAVIGATION.md "Header pattern")
 * ------------------------------------------------------------------ */

/* `min-width: 0` on a flex child that is allowed to grow is what lets the
 * stall name ellipsis instead of pushing the nav on top of it. The nav keeps
 * its own `margin-left: auto`, so the two never share space. */
/*
 * `flex: 0 1 auto` — shrink, never grow. With `1 1 auto` this block expanded
 * to fill the bar, which pushed Operations and Log out onto a second row even
 * though everything fits at 834px. The nav's own `margin-left: auto` is what
 * holds them apart.
 */
/*
 * The pill wraps rather than overflowing. `min-width: 0` lets this group be
 * squeezed below its content, and the Capacity State pill inside it cannot
 * shrink — its text does not break — so at 834px the pill ran out under the
 * Operations link beside it. Wrapping puts it on a second line of its own
 * group instead, which is what the artboard's header does at the width where
 * it stops fitting.
 */
.queue-identity {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  row-gap: var(--space-2);
  min-width: 0;
  flex: 0 1 auto;
}

/* The role label repeats what the peer pair already says and was the thing
 * colliding with the surface name at tablet width. The pair carries it. */
.my-stall-page .role-nav .role {
  display: none;
}

/*
 * The back pill itself is `.back-pill` in organic-system.css now — the
 * canonical copy carries every value this page-local block restated, plus the
 * body face. Only the header-layout delta stays: in this bar the pill must
 * never grow or shrink, because the stall's name is the one thing allowed to
 * give (see the `min-width: 701px` block at the foot of this file).
 */
.my-stall-page .back-pill {
  flex: none;
}

/*
 * The marks in the bar and on the Ready panel: inline `<svg>` sized here, at
 * the system's 2.75 stroke. They were CSS masks over `data:image/svg+xml`
 * URIs, which the server's `img-src 'self'` blocks outright — a mask is
 * fetched under `img-src`, so all three were dead in production and failed
 * silently. Same treatment as `.back-pill svg` on Stock and Menu.
 */
.my-stall-page .back-pill svg,
.my-stall-page .queue-panel-ready .queue-panel-heading h4 svg {
  flex: none;
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The stall's name is this surface's brand — 24px, as the artboard sets it. */
.queue-stall-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 24px;
}

.queue-stall-name:empty {
  display: none;
}

.queue-surface-name {
  flex: none;
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

/* The peer pair is `.peer-pair` in organic-system.css now, shared by every
 * staff surface rather than restated per page. */

.my-stall-page .queue-operations {
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--color-accent-200);
  border-radius: 999px;
  font-size: 13px;
}

/* ---- Ready for Pickup, promoted ---- */

/* Ready is the only queue with a Guest already standing at the counter, so
 * the design gives it the top of the surface, a tinted ground of its own,
 * and the largest targets. */
.queue-panel-ready {
  margin-bottom: var(--space-3);
  padding: var(--space-4);
  border-radius: 32px;
  background: var(--color-accent-100);
  box-shadow: var(--shadow-sm);
}

/* The one spread heading row: the kicker on the left, "Oldest first" opposite. */
.queue-panel-ready .queue-panel-heading {
  justify-content: space-between;
  padding: 0;
}

/*
 * The artboard titles this panel with a `.card-kicker` and a serving-hand
 * mark, not with a heading at row size: inside a tinted panel whose tiles
 * carry 34px numbers, the title is the quietest thing there. It stays an `h4`
 * so the surface keeps its heading order; only its type changes.
 */
.queue-panel-ready .queue-panel-heading h4 {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* 10px uppercase on --color-accent-100: the base accent gives 3.29:1 here.
     Same exception as the queue timers above. */
  color: var(--color-accent-700); /* 6.21:1 */
}

/*
 * The tile grid, as `Stall Queue.dc.html` draws it: `auto-fill minmax(150px,
 * 1fr)` at an 8.8px gap, each tile 96px tall minimum on the accent ground.
 * What used to make this impossible was the handoff living inside the row;
 * that flow is a dialog now, and a tile is the thing that opens it.
 */
.ready-tiles {
  grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr));
  gap: var(--space-2);
  align-content: start;
}

.ready-tile-cell {
  display: grid;
}

.ready-tile {
  display: grid;
  align-content: center;
  justify-items: start;
  gap: 2px;
  min-height: 96px;
  padding: var(--space-3) var(--space-4);
  border: 0;
  border-radius: 26px;
  /*
   * The artboard grounds this tile in the base accent. `--color-neutral-100`
   * on it is 3.30:1 - enough for the 34px number, which is large text, and not
   * enough for the 10px label or the 12px timer beneath it, which after their
   * own opacity computed 2.67:1 and 2.81:1.
   *
   * Unlike the timers above, the text here cannot be deepened: it sits ON the
   * accent, and no step of any ramp reaches 4.5:1 against the base accent from
   * either direction (accent-900 on it is 3.97:1). So the GROUND takes the
   * ramp step instead, which carries all three pieces of text over the line at
   * once - number 6.22:1, timer 4.99:1, label 4.63:1 - and keeps the tile a
   * terracotta tile. The measured ratios are documented above.
   */
  background: var(--color-accent-700);
  /*
   * `--color-neutral-100`, as the artboard sets it. This said
   * `--color-accent-50` — a step the ramp does not have (it starts at 100).
   * An undefined custom property is invalid at computed-value time, so
   * `color` fell back to the inherited ink and every tile printed dark text
   * on terracotta.
   */
  color: var(--color-neutral-100);
  box-shadow: var(--shadow-sm);
  text-align: left;
  cursor: pointer;
}

.ready-tile:disabled {
  cursor: default;
  opacity: 0.6;
}

.ready-tile-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  opacity: 0.8;
}

/* The number is what is read across a counter, so it takes the display face at
 * the size the design sets. */
.ready-tile-number {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 34px;
  line-height: 1.02;
  font-variant-numeric: tabular-nums;
}

.ready-tile-timer {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  opacity: 0.85;
}

/* ---- The handoff dialog the tiles open ---- */

#handoff-dialog {
  width: min(420px, calc(100vw - var(--space-6)));
  max-height: calc(100vh - var(--space-6));
  overflow-y: auto;
  /* 36px and `--space-6` inside, as the tablet artboards draw the dialog;
   * the 390px artboard drops to `--space-4`, which is what the phone rule
   * below keeps. */
  padding: var(--space-6);
  border: 0;
  border-radius: 36px;
  background: var(--color-bg);
  color: var(--color-text);
}

@media (max-width: 700px) {
  #handoff-dialog {
    padding: var(--space-4);
  }
}

#handoff-dialog::backdrop {
  background: color-mix(in srgb, var(--color-neutral-900) 45%, transparent);
}

.handoff-dialog-head {
  display: grid;
  gap: 2px;
  margin-bottom: var(--space-3);
}

.handoff-dialog-eyebrow {
  margin: 0;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-accent-700);
}

/*
 * The Stall Order number at the size the artboard gives the figure this
 * dialog is about. The artboard's own figure is the Pickup Code at 62px,
 * which this surface cannot print (see the markup comment: staff type what
 * the Guest states, and the server compares) — so the number the Guest and
 * the stall are matching takes the display weight instead, at the size of the
 * tile that opened the dialog.
 */
.handoff-dialog-head h4 {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 34px;
  line-height: 1.02;
  font-variant-numeric: tabular-nums;
}

.handoff-dialog-head .queue-lines {
  margin: 0;
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 65%, transparent);
}

/*
 * `.secondary` is a Guest-surface class; here it left the dismissal as the
 * browser's default grey button, the loudest thing in a dialog whose subject
 * is the Stall Order above it. It takes the same quiet outline the fulfilment
 * controls beside it wear.
 */
#handoff-dialog-close {
  margin-top: var(--space-3);
  width: 100%;
  min-height: 48px;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--color-neutral-300);
  border-radius: 999px;
  background: transparent;
  color: color-mix(in srgb, var(--color-text) 75%, transparent);
  font: inherit;
  cursor: pointer;
}

#handoff-dialog-close:hover {
  border-color: var(--color-accent-400);
}

/* ---- Received and In Prep, side by side ---- */

/* Two columns where there is room for two. Below that they stack, because a
 * queue squeezed into half a phone is unreadable and the stall works them in
 * order anyway. */
/*
 * `min(280px, 100%)` rather than a bare 280px: a bare track minimum is a hard
 * floor the grid cannot go under, so at 200% zoom — where a 390px viewport is
 * 195 CSS pixels — the pair forced the page 498px wide and the surface needed
 * horizontal scrolling. Wrapping the minimum in `min()` lets the column shrink
 * past its preferred width instead of pushing the document.
 */
.queue-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: var(--space-4);
  align-items: start;
}

/* The stacking margin between panels was written when all four queues were
 * one column. Inside the pair the grid gap does that job, and Ready has its
 * own margin above. */
.queue-pair .queue-panel + .queue-panel {
  margin-top: 0;
}

/* Named for assistive technology, drawn by the header instead. Clipped rather
 * than display:none, which would silence it too. */
.queue-page-title {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/*
 * Phone. The header pattern is drawn for a tablet held upright; at 390px the
 * back pill, brand, stall name, peer pair and Operations cannot share a row
 * without overflowing it, and a staff surface must never scroll sideways.
 *
 * The identity wraps to its own line and the stall name is allowed to shrink,
 * so what gets shorter is the name rather than the row. Nothing is removed:
 * every destination in NAVIGATION.md's pattern is still reachable.
 */
@media (max-width: 700px) {
  .queue-identity {
    flex-wrap: wrap;
    row-gap: var(--space-2);
    flex-basis: 100%;
  }

  .queue-stall-name {
    flex: 0 1 auto;
    font-size: 19px;
  }

  .my-stall-page .role-nav {
    flex-wrap: wrap;
    row-gap: var(--space-2);
  }
}

/* ------------------------------------------------------------------ *
 * The phone count bar (Stall Queue.dc.html option 3b)
 * ------------------------------------------------------------------ */

/*
 * Absent above 700px: the tablet and desktop layouts show all three queues at
 * once, so a bar summarising them would repeat what is already on screen. It
 * exists at counter width, where the queues run past the fold.
 */
.queue-jump {
  display: none;
}

/*
 * The phone layout shows one queue at a time (`Stall Queue.dc.html` option
 * 3b). This is the only place the tab attribute selects anything: above 700px
 * the bar is not drawn and the three queues are laid out together, as the
 * tablet artboards show.
 */
@media (max-width: 700px) {
  .stall-queues[data-queue-tab="received"] .queue-panel-ready,
  .stall-queues[data-queue-tab="prep"] .queue-panel-ready,
  .stall-queues[data-queue-tab="ready"] .queue-pair {
    display: none;
  }

  .stall-queues[data-queue-tab="received"] .queue-pair > :nth-child(2),
  .stall-queues[data-queue-tab="prep"] .queue-pair > :nth-child(1) {
    display: none;
  }
}

/* The Ready shortcut: an accent bar carrying the count, a cue and a chevron,
 * as the artboard draws it. It only exists at phone width — above that Ready
 * is on the screen already. */
.ready-jump {
  display: none;
}

@media (max-width: 700px) {
  .ready-jump {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    min-height: 52px;
    margin: 0 0 var(--space-3);
    padding: var(--space-2) var(--space-4);
    border: 0;
    border-radius: 999px;
    background: var(--color-accent);
    color: var(--color-neutral-100);
    box-shadow: var(--shadow-sm);
    font: inherit;
    text-align: left;
    cursor: pointer;
  }

  .ready-jump[hidden] {
    display: none;
  }

  .ready-jump-text {
    flex: 1;
    min-width: 0;
    font-family: var(--font-heading);
    font-weight: var(--font-heading-weight);
    font-size: 15px;
  }

  .ready-jump-cue {
    flex: none;
    font-size: 12.5px;
    opacity: 0.85;
  }

  /* The chevron is drawn, not written: a `›` in the text would be read out. */
  .ready-jump-chevron {
    flex: none;
    width: 9px;
    height: 9px;
    border-top: 2.5px solid currentColor;
    border-right: 2.5px solid currentColor;
    transform: rotate(45deg);
  }
}

@media (max-width: 700px) {
  .queue-jump {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 3;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-1);
    margin: var(--space-3) calc(-1 * var(--space-3)) calc(-1 * var(--space-3));
    padding: var(--space-2) var(--space-3)
      max(var(--space-2), env(safe-area-inset-bottom));
    border-radius: 28px 28px 0 0;
    background: var(--color-surface);
    box-shadow: var(--shadow-md);
  }

  .queue-jump-link {
    display: grid;
    border: 0;
    background: transparent;
    font: inherit;
    cursor: pointer;
    justify-items: center;
    align-content: center;
    gap: 1px;
    /* Above the 44px touch floor: these are the three targets a volunteer
       reaches for one-handed while holding something. */
    min-height: 52px;
    padding: 0 var(--space-2);
    border-radius: 22px;
    color: var(--color-text);
    text-decoration: none;
  }

  .queue-jump-link:hover {
    background: var(--color-accent-100);
  }

  /* The tab being read is tinted, as the artboard draws it. */
  .queue-jump-link[aria-current="true"] {
    background: var(--color-accent);
    color: var(--color-neutral-100);
  }

  .queue-jump-value {
    font-family: var(--font-heading);
    font-weight: var(--font-heading-weight);
    font-size: 20px;
    line-height: 1;
    font-variant-numeric: tabular-nums;
  }

  .queue-jump-label {
    font-size: 11.5px;
    color: color-mix(in srgb, var(--color-text) 60%, transparent);
  }

  /* On the tinted tab the label rides the tab's own colour; muted ink on
     terracotta is the one combination this bar must not print. */
  .queue-jump-link[aria-current="true"] .queue-jump-label {
    color: inherit;
    opacity: 0.85;
  }

  /* The jump lands on a heading that would otherwise sit under the sticky
     bar's own height. */
  #ready-heading,
  #received-heading,
  #in-prep-heading {
    scroll-margin-bottom: 96px;
  }
}

/* Clear the fixed bar, so the last row of a queue is not sitting under it. */
@media (max-width: 700px) {
  .my-stall-workspace {
    padding-bottom: 104px;
  }
}

/*
 * Phone: the back pill drops to its chevron alone, as the design's 390px
 * artboard draws it. Four header rows on a 844px screen is most of the fold
 * spent on chrome before a volunteer sees a single order.
 *
 * The label is clipped, not removed — the pill keeps its accessible name, so
 * it still announces as "Stalls overview" rather than as a bare arrow.
 */
@media (max-width: 700px) {
  .my-stall-page .back-pill {
    gap: 0;
    /* Square, not just tall: with the label clipped the pill measured 41x44
       and fell under the 44px touch floor in the direction nobody checks.
       `justify-content` keeps the chevron centred once the box is wider than
       its content. */
    min-width: 44px;
    justify-content: center;
    padding: 0 12px;
  }

  .my-stall-page .back-pill span {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* The Capacity State pill in the bar, as the artboard draws it: a dot, the
 * state in the display face, and a quiet detail saying how much work stands
 * behind it. Colours follow the same mapping the board uses, so a stall reads
 * the same on both surfaces. */
.queue-status-pill {
  display: inline-flex;
  align-items: baseline;
  gap: 9px;
  padding: 9px 16px;
  border-radius: 999px;
  background: var(--color-accent-2-200);
  color: var(--color-accent-2-800);
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 16px;
}

.queue-status-pill[data-capacity-state="Busy"] {
  background: var(--color-accent-200);
  color: var(--color-accent-800);
}

.queue-status-pill[data-capacity-state="Paused"] {
  background: var(--color-neutral-800);
  color: var(--color-neutral-100);
}

.queue-status-dot {
  align-self: center;
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: currentColor;
}

/*
 * At the width the surface is drawn for, the bar is one row.
 *
 * `Stall Queue.dc.html` sets `flex-wrap: wrap` with a row-gap as insurance and
 * then never uses it: at 834px the back pill, the stall's name, the surface
 * name, the status pill, Operations and Log out all fit. Leaving the wrap
 * enabled here let a few pixels of the status pill tip the whole nav onto a
 * second row, which costs 44px of a queue and reads as a mistake.
 *
 * The stall name is the one thing allowed to give: it shrinks and ellipsises,
 * because "Roti Corner" losing a letter is better than Log out losing its row.
 */
@media (min-width: 701px) {
  body.my-stall-page > header {
    flex-wrap: nowrap;
  }

  .queue-identity {
    flex: 0 1 auto;
    min-width: 0;
  }

  /* It may give, but not first and not far: a stall's name is its identity,
     and "Chaat Cor…" while the bar still has whitespace is worse than a
     slightly tighter Operations. */
  .queue-stall-name {
    flex: 0 1 auto;
    min-width: 14ch;
  }

  .queue-status-pill,
  .queue-surface-name,
  .my-stall-page .back-pill {
    flex: none;
  }

  .my-stall-page .role-nav {
    flex: none;
    flex-wrap: nowrap;
  }
}
/* ------------------------------------------------------------------ *
 * Stall settings — `Stall Queue.dc.html` 4a, lines 58 and 214-222.
 *
 * A right-hand drawer over the full height of the surface, 460px wide, behind
 * the header gear. Everything that configures the stall is inside it; the
 * lanes own the screen.
 * ------------------------------------------------------------------ */

.my-stall-page .queue-settings-gear {
  flex: none;
  width: 52px;
  height: 52px;
}

/* Lucide marks are stroked, not filled, and nothing on this page gives an
   inline `<svg>` that treatment by default — `fill` defaults to black and
   `stroke` to none, so an unstyled icon renders as a solid blob or as nothing
   at all. Same treatment as `.back-pill svg` above. */
.my-stall-page .queue-settings-gear svg,
.stall-settings-close svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.my-stall-page .queue-settings-gear[hidden] {
  display: none;
}

.stall-settings {
  /* `inset: 0` with `margin-left: auto` rather than a width and a position:
     a top-layer dialog is centred by the UA default, and the artboard pins it
     to the right edge over the whole height. */
  width: min(460px, 100%);
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  margin: 0 0 0 auto;
  padding: var(--space-6);
  border: none;
  border-radius: 0;
  background: var(--color-bg);
  color: var(--color-text);
  box-shadow: var(--shadow-lg);
  overflow-y: auto;
}

.stall-settings::backdrop {
  background: color-mix(in srgb, var(--color-neutral-900) 42%, transparent);
}

.stall-settings-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.stall-settings-head h2 {
  margin: 0;
  font-size: 26px;
}

.stall-settings-close {
  flex: none;
  width: 48px;
  height: 48px;
}

.stall-settings-body {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

/* Each section inside the drawer takes the artboard's own panel treatment
   rather than whatever it inherited from sitting under the lanes. */
.stall-settings-body > section {
  margin: 0;
  padding: var(--space-4);
  border: 0;
  border-radius: 30px;
  background: var(--color-surface);
  box-shadow: none;
}

.stall-settings-body > section > h2,
.stall-settings-body > section > h3 {
  margin: 0;
  font-size: 18px;
}

/* The drawer is one narrow column, so nothing inside it keeps a multi-column
   layout it was given for the full width of the page. */
.stall-settings-body .stall-form,
.stall-settings-body .setup-list {
  grid-template-columns: minmax(0, 1fr);
}
