/**
 * Back-office action-panel vocabulary — the shared layout for every staff
 * "do something" surface (minute sheet, finalise orders, order panel, approve
 * hearing, task detail). One anatomy: an optional INSTRUCTION strip, the form in
 * the sanctioned CARD, the ONE action bar as the card's flush bottom band, and an
 * optional RELATED-context slot below (timeline / log).
 *
 * The `FormDef`/`Bar` half of docs/design/backoffice-page-type.md
 * (tasks/2026-08-01-be-layouts-action-panel.md). The typed value is rendered by
 * `renderBar` / `renderAsk` (engine-src/staff-page.ts — docs/action-bar-is-a-type.md;
 * they replaced `renderActionBar` when the look stopped being authorable); the
 * form itself stays a View
 * rendered by the existing fill runtime. This file standardises only the CARD +
 * the ONE bar — it kills the three bespoke pink-band variants.
 *
 * Rides the design-system source→copy pipeline exactly like be-tray.css /
 * be-content.css: authored here, copied verbatim to /jds/be-action.css by
 * build.mjs, linked by the app (layout.html, scoped to `.be-form-panel` so
 * non-panel pages render byte-identical).
 *
 * Card chrome itself comes from the COMPOSED `.form-card-frame` (fill.css) /
 * `.fit-surface-card` (base.css) — this file never hand-rolls a radius+shadow
 * surface (docs/one-shared-card.md).
 */

/* The panel — a single centred column that stacks instruction → form card →
   related context with one standard rhythm. Max-width aligns with the JDS fill
   content column (body.jds-fill .container, fill.css) so the instruction strip
   and the related slot line up with the card edges. */
.be-form-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  width: 100%;
  max-width: 1168px;
  margin: 0 auto;
}
/* `width: 100%` is load-bearing, not cosmetic. `.be-content` (chrome.css) is a
   `display: flex; flex-direction: column` container, so this panel is a flex
   item. With only `margin: 0 auto` and an auto width, the auto side-margins
   DISABLE the flex stretch and the panel shrinks to its content — which then
   sizes every centred child (the `.be-record-layout` grid) to its content too,
   so the case read card visibly widened/narrowed as sections opened and closed
   (queue-detail). A definite `width: 100%` keeps the panel filling its column
   up to max-width while the auto margins still centre it — in the flex context
   AND in a plain block one. Pinned by test/e2e/case-view-layout-width.spec.ts. */
/* Inside the panel the fill runtime's `.container` no longer owns the centring
   or the horizontal inset — the panel does — so the card spans the panel width
   and the sibling slots align with it. */
.be-form-panel .container {
  max-width: none;
  margin: 0;
  padding-left: 0;
  padding-right: 0;
}

/* Instruction strip — the standard slot for the explanatory note a surface needs
   (e.g. the SCHED-003 note on Approve hearing), replacing ad-hoc info boxes. A
   quiet tinted strip with a maroon accent rule; sits ABOVE the form card. */
.be-instruction {
  display: flex;
  gap: var(--space-sm);
  padding: var(--space-md) var(--space-lg);
  background: var(--color-primary-superlight);
  border-left: 3px solid var(--color-primary-base);
  border-radius: var(--radius-sm);
  color: var(--color-grey-darkest);
  font: var(--font-paragraph);
}
.be-instruction__title {
  font: var(--font-small-bold);
  color: var(--color-primary-base);
  margin: 0 0 var(--space-2xs);
}
.be-instruction p { margin: 0; }
.be-instruction > * + * { margin-top: 0; }

/* Related-context slot — the standard "form + related timeline/log" stacking
   (the minutes page pattern): a titled block below the form card with the same
   left/right alignment as the card body. Never its own card — the pieces inside
   (timeline items) carry their own surface. */
.be-related { margin: 0; }
.be-related__title {
  font: var(--font-h4);
  color: var(--color-black);
  margin: 0 0 var(--space-md);
}

/* The ONE Form action bar strip — the shared save/submit chrome at the bottom of
   every fill page (single-page AND multipage) AND the markup renderBar
   emits. Its layout lives HERE (the single owner of the action-bar vocabulary,
   linked on every page) rather than in fill.css, so the catalog demo, the JDS
   reference, and the public + staff fills all get one definition. `flex: 1 1 100%`
   makes the strip span the whole content column inside `.action-bar` (a maroon
   footer band, not a shrink-to-content pill); `space-between` splits the groups.
   The `body.fill-palette` band-shed override + the `.action-bar` container stay
   in fill.css (page-local); the sticky behaviour is below. */
.form-action-bar {
  flex: 1 1 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-lg);
  background: var(--color-primary-superlight);
}
.form-action-bar__left,
.form-action-bar__right {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}
/* Wrapping so a Disabled action's reason line (below) can take a row of its own
   above the buttons — SCOPED to a group that actually has one.

   Unscoped, `flex-wrap: wrap` lands on the live `/fill` strip of every public
   and staff form. `.jud-button` is `white-space: nowrap`, so on a narrow
   viewport buttons that used to overflow the strip would instead fold onto a
   second row: a real layout change on a production surface whose only baselines
   were regenerated at desktop width. `:has(.be-action-reason)` binds the change
   to the shape it was written for; a strip with no reason is byte-identical to
   what it was, which is what the comment used to claim unconditionally.
   Pinned in a real browser at 420px by test/e2e/action-bar-wrap-scope.spec.ts.

   THE OWNER CONFIRMED THIS RULE ON 2026-08-19, and it is worth recording where
   the next person will look, because it was challenged and it held. Part 4 of
   the public-shell brief found the payment advice clipping a button off the card
   at 390 and fixed it by wrapping THIS strip below 480px. That turned the spec
   above red — stacking the two groups IS the wrap this rule forbids — and the
   change was reverted. Asked to choose, the owner took option 1 of
   tasks/done/2026-08-19-the-payment-advice-clips-a-button-at-390.md: the rule is
   right, the BUTTON was wrong. So a page whose labels do not fit shrinks and
   wraps its own buttons (see the `[data-chit]` block in
   cmd/server/static/css/pages/fill.css) and this strip is left alone. Do not
   re-open it by adding a width-bounded wrap here. */
.form-action-bar__left:has(.be-action-reason),
.form-action-bar__right:has(.be-action-reason) { flex-wrap: wrap; }
.form-action-bar__right:has(.be-action-reason) { justify-content: flex-end; }

/* Destructive-action separation — the "destructive separated" rule: the bar's
   `escalate` slot (renderBar tags it `.be-action-sep`) gets a clear gap from the
   rest of the left group, so the destructive route reads as set apart. Only the
   renderer emits this hook, so no other button on any page is affected. */
.form-action-bar__left .jud-button.be-action-sep { margin-right: var(--space-xl); }

/* A Disabled action's REASON. `renderBar` collects the reasons per GROUP and
   emits them as sibling spans before that group's buttons — not inline before
   each button, which put a whole sentence in the middle of the button row and
   split it across three lines. A greyed-out button with no explanation is a
   dead end, so the renderer prints the sentence and a page cannot forget it.

   It takes a LINE OF ITS OWN above its group rather than a slot in the button
   row (`flex-basis: 100%` against the wrapping groups above). Inline, a sentence
   competing with two buttons for one row squeezed to five words-per-line the
   moment the strip was narrower than a full page column. */
.form-action-bar .be-action-reason {
  flex: 1 0 100%;
  font: var(--font-small);
  color: var(--color-grey-darkest);
}
.form-action-bar__right .be-action-reason { text-align: right; }

/* Action bar sits in NORMAL FLOW at the natural end of the form content — NOT
   sticky. A sticky bar permanently occupies vertical space on every long staff
   panel; the deliberate call (tasks/2026-08-01-be-action-not-sticky-natural-
   page-bottom.md) is to reclaim that space and let the user scroll to the bar at
   the true end of the content. The bar is still the card's flush bottom band via
   the shared `.action-bar` container (fill.css); it just no longer pins. */

/* The `Ask` — the confirmation surface an `escalate` opens
   (tasks/2026-08-16-the-action-bar-is-a-type.md). It is NOT a special shape: it
   is a title, a consequence, and the SAME `.form-action-bar` strip read on the
   `ask` surface, which is why its own rules stop at spacing. `renderAsk`
   (engine-src/staff-page.ts) owns the markup; the caller owns the modality.

   The panel is the shared `.fit-surface-card` (docs/one-shared-card.md) with its
   padding moved onto the two text rows, so the strip stays the card's flush
   bottom band — the same anatomy the action panel has. This is deliberately NOT
   a third modal shell: a native <dialog> supplies the centring and the
   backdrop, so the only thing declared here is the reset that lets the card
   show through. */
dialog.be-ask-dialog {
  border: 0;
  padding: 0;
  background: transparent;
  width: min(560px, calc(100vw - 2 * var(--space-lg)));
  max-width: min(560px, calc(100vw - 2 * var(--space-lg)));
  /* Centring is stated, not inherited: the first render of this dialog landed
     top-left with only the UA's own `margin: auto` behind it. Declaring the
     width and the margin here is what pins it, whatever a page's own dialog
     rules say. */
  margin: auto;
}
dialog.be-ask-dialog::backdrop { background: var(--color-scrim); }

.be-ask { padding: 0; overflow: hidden; }
.be-ask__title { margin: var(--space-lg) var(--space-lg) var(--space-sm); }
.be-ask__consequence { margin: 0 var(--space-lg) var(--space-lg); }
/* THE ASK'S BODY — an ask that COLLECTS something before it commits.
 *
 * The two rules above inset the title and the consequence by `--space-lg`,
 * because `.be-ask` itself is `padding: 0` (the strip has to stay the card's
 * flush bottom band). An ask with nothing but words needs no third rule, and
 * until 2026-09-01 no ask had anything else — `renderAsk` emitted title +
 * consequence + strip and that was the whole anatomy.
 *
 * The changeset REJECT ask does have something else: rejecting is refused
 * without a typed reason, so the ask carries a label and a textarea. Those had
 * no rule at all, and `padding: 0` is inherited by everything — so the label and
 * the box rendered FLUSH TO BOTH WALLS of the modal while the two lines above
 * them sat correctly inset. The owner saw it in a screenshot before this file
 * did.
 *
 * It is the SAME inset as `__consequence`, deliberately: the point is one
 * anatomy, not a third value. `renderAsk` takes an optional `body` that emits
 * this class, so the next ask that collects something gets the padding by using
 * the shared renderer rather than by remembering this rule exists. */
.be-ask__body { margin: 0 var(--space-lg) var(--space-lg); }

/* A COMPANION in the strip — markup that is NOT an action but must travel with
   the lead, rendered in the lead's own group because the two are one act
   (internal/actionbar, docs/action-bar-is-a-type.md).

   NOTHING EMITS ONE TODAY. Its one caller was the four-character code box on the
   MCP confirmation card, and that whole per-card decision row was deleted on
   2026-09-01 when the approval UI became two screens. The rules stay with the
   mechanism they belong to — `internal/actionbar` still renders a companion it
   is given, and TestTheCompanionRidesWithTheLead pins that — so a future one
   arrives laid out rather than as a full-width row.

   It needs a rule because base.css gives every text input `width: 100%`, and a
   100%-wide flex item eats the strip: the code box rendered as a full-width row
   with the buttons stranded above and below it. Sizing to content is what makes
   it read as a control beside a button rather than as a field of its own.

   `renderStrip` is the only thing that emits this class, and only for a bar
   that was GIVEN a companion — so a strip without one is byte-identical. */
.be-action-companion { display: flex; align-items: center; gap: var(--space-sm); }
/* A DIRECT CHILD, not a descendant. A descendant `input` selector inside a
   wrapper is how per-page chrome leaks into a Fit* widget's own internal input
   (.claude/memory/feedback_no_per_page_input_chrome.md); nothing mounts a
   widget in a companion today, and this makes sure a future one keeps its own
   sizing. Layout only — no border, no radius, no padding, no focus ring: those
   are base.css's and stay base.css's. */
.be-action-companion > input { width: auto; flex: 0 0 auto; }
