/**
 * MicroBite POS — [pp1b] storefront EPO controls.
 *
 * Loaded ONLY on a single product page that mounts option controls
 * (MBPOS_EPO_Product_Inject::maybe_enqueue). It is not the POS modal's
 * stylesheet: mbpos-epo.css is largely unscoped legacy at (0,1,0) and is
 * written for a lightbox on a POS page. This file follows the isolation
 * standard (CSS-ISOLATION-STANDARD.md) properly:
 *
 *   Rule 1 — the root carries `data-mbpos` (it renders outside the POS layout,
 *            inside an arbitrary theme's form.cart).
 *   Rule 2 — every selector is `[data-mbpos].mbpos-epo--sf .mbpos-*` (0,3,0),
 *            which also means that if a page somehow loads BOTH stylesheets
 *            these rules win deterministically instead of by source order.
 *   Rule 3 — full state contract on the interactive bits.
 *   Rule 3½ — the island declares its own font/size/colour rather than
 *            inheriting whatever the theme put on <body>.
 *
 * The selected/2×-visible states are driven by sibling `:checked` selectors,
 * not by a JS class. The controls therefore stay live with JavaScript off —
 * which matters, because the server accepts a JS-free submit by design.
 *
 * @since 1.69.0-epo.pp1b
 */

/* ── Island root ─────────────────────────────────────────────────────── */

[data-mbpos].mbpos-epo--sf {
	display: flex;
	flex-direction: column;
	gap: var(--mbpos-space-xs, 12px);
	margin: var(--mbpos-space-s, 16px) 0;
	font-family: var(--mbpos-font-body, inherit);
	font-size: var(--mbpos-font-size-base, 15px);
	line-height: 1.4;
	color: var(--mbpos-color-text, #1C1917);
	text-align: left;
	box-sizing: border-box;
}

[data-mbpos].mbpos-epo--sf *,
[data-mbpos].mbpos-epo--sf *::before,
[data-mbpos].mbpos-epo--sf *::after {
	box-sizing: border-box;
}

/* ── Group ───────────────────────────────────────────────────────────── */

[data-mbpos].mbpos-epo--sf .mbpos-epo__group {
	border: 0;
	margin: 0;
	padding: 0;
	min-width: 0;
}

/* [pp2d-a] The legend is now the collapse handle (role="button",
   tabindex="0"), so it carries the Rule 3 full state contract — base +
   :hover + :focus-visible + :active + :disabled. It was previously a plain
   heading; every property below that looks redundant is a theme-bleed hole
   being closed, not decoration. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__group-name {
	display: flex;
	align-items: baseline;
	gap: var(--mbpos-space-2xs, 8px);
	float: none;                       /* some themes float <legend> */
	width: 100%;
	box-sizing: border-box;
	margin: 0 0 var(--mbpos-space-2xs, 8px);
	padding: 10px var(--mbpos-space-s, 14px);
	font-family: inherit;
	font-size: var(--mbpos-epo-head-size, 15px);
	font-weight: var(--mbpos-epo-head-weight, 600);
	line-height: 20px;
	text-align: left;
	color: var(--mbpos-epo-head-color, var(--mbpos-color-heading, #1C1917));
	background: var(--mbpos-epo-head-bg, #EFEDE8);
	border: 0;
	border-radius: var(--mbpos-radius-s, 6px);
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group-name:hover {
	background: var(--mbpos-epo-head-bg-hover, #E7E4DE);
	color: var(--mbpos-color-text, #1C1917);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group-name:active {
	background: var(--mbpos-epo-head-bg-active, #DEDAD3);
	color: var(--mbpos-color-text, #1C1917);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group-name:focus-visible {
	outline: none;
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--mbpos-color-primary, #C2410C) 35%, transparent);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group-name:disabled {
	cursor: default;
	opacity: 0.6;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__req {
	margin-left: 4px;
	color: var(--mbpos-color-danger, #B91C1C);
}

/* ── Flow chrome: summary bar, CTA chip, chevron (pp2d-a) ─────────────
   Ported from the POS modal (mbpos-epo.css) so a product reads the same
   on both surfaces. The collapse itself arrives in the markup from PHP
   (D1) — nothing here runs on load. */

[data-mbpos].mbpos-epo--sf .mbpos-epo__summary {
	margin-left: auto;
	font-size: 13px;
	font-weight: 500;
	line-height: 20px;                 /* match the title so the baseline is exact */
	color: var(--mbpos-color-text-muted, #78716C);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	max-width: 55%;
}

/* A required choice not yet made. Spoken in Primary because it is an
   ACTION the customer must take (v1.20 semantics: action = orange). */
[data-mbpos].mbpos-epo--sf .mbpos-epo__summary.is-prompt {
	color: var(--mbpos-color-primary, #C2410C);
	font-weight: 600;
}

/* [hh2] The verb follows the group type — Change on a radio, Customise on
   a checkbox. Shown only on a collapsed group, where the folded bar would
   otherwise only imply that it opens. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__cta {
	display: none;
	flex: 0 0 auto;
	font-size: 12px;
	font-weight: 600;
	line-height: 20px;
	padding: 3px 12px;
	border: 1px solid var(--mbpos-epo-cta-border, var(--mbpos-color-border-strong, rgba(0,0,0,0.25)));
	border-radius: 999px;
	background: var(--mbpos-epo-cta-bg, var(--mbpos-color-surface, #ffffff));
	color: var(--mbpos-epo-cta-text, var(--mbpos-color-heading, #1C1917));
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group--collapsed .mbpos-epo__cta {
	display: inline;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__chev {
	flex: 0 0 auto;
	align-self: center;                /* rotated box — centring beats baseline */
	width: 10px;
	height: 10px;
	border-right: 2px solid var(--mbpos-color-text-muted, #78716C);
	border-bottom: 2px solid var(--mbpos-color-text-muted, #78716C);
	transform: rotate(45deg) translateY(-2px);   /* open: pointing down */
	transition: transform .2s ease;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group--collapsed .mbpos-epo__chev {
	transform: rotate(-45deg) translate(-1px, 1px);
}

/* The fold itself. .mbpos-epo__error is hidden with the choices so a
   collapsed group cannot show an orphaned error under a folded bar.

   [fold1] Qualified with .mbpos-epo__group as well as its modifier, taking
   this to (0,5,0). It was (0,4,0), which TIED with the combo picker's layout
   rules — [data-mbpos].mbpos-combo--sf .mbpos-combo__slot-epo
   .mbpos-epo__choices { display: grid } and its shared-panel twin — and
   mbpos-combo-sf.css is enqueued with mbpos-epo-sf.css as a dependency, so it
   always loads second and won the tie. The fold was inert on every combo
   product page: the class landed, the JS ran, and nothing moved.

   A state rule has to outrank a layout rule regardless of which sheet loads
   last, because sheet order is an enqueue detail and the fold is a promise to
   the customer. Specificity, not !important — the isolation standard forbids
   the latter and combo-fold-cascade-test-fold1.js fences both facts. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__group.mbpos-epo__group--collapsed .mbpos-epo__choices,
[data-mbpos].mbpos-epo--sf .mbpos-epo__group.mbpos-epo__group--collapsed .mbpos-epo__error {
	display: none;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group--error .mbpos-epo__summary {
	color: var(--mbpos-color-danger, #B91C1C);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__choices {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

/* ── Choice row ──────────────────────────────────────────────────────── */

[data-mbpos].mbpos-epo--sf .mbpos-epo__choice {
	display: flex;
	align-items: stretch;
	flex-wrap: wrap;
	gap: 6px;
	margin: 0;
	min-width: 0;
}

/* The real input stays in the DOM and the a11y tree — clipped, never
   display:none, so keyboard focus and screen readers still find it. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__input,
[data-mbpos].mbpos-epo--sf .mbpos-epo__row {
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	gap: var(--mbpos-space-2xs, 8px);
	/* [fix1] A width FLOOR, not `min-width: 0`. Zero told the browser this row
	   may shrink to nothing, so when the 2x Extra button appeared beside it the
	   browser squeezed the row instead of wrapping the button — and a long
	   label (a ClO2 product name) re-wrapped to two lines, doubling the height
	   of the selected row. With a floor, wrapping the button to its own line is
	   the cheaper option and the browser picks correctly at every width, with
	   no measurement and no JS. */
	min-width: 60%;
	min-height: 44px;                  /* tap target */
	margin: 0;
	padding: 8px var(--mbpos-space-s, 14px);
	font: inherit;
	line-height: 1.35;
	text-align: left;
	color: inherit;
	background: var(--mbpos-color-surface, #FFFFFF);
	border: 1px solid var(--mbpos-color-border, #E3E0DA);
	border-radius: var(--mbpos-radius-s, 6px);
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

/* [epo-sf-fix1] Clip the real input. The shared rule above gives it row
   geometry (display, min-width, min-height) because it was combined with
   .mbpos-epo__row in a comma-separated selector; this rule hides it
   without touching the shared block, which would risk a fence break.
   The <label for="…"> handles the click target; keyboard focus fires
   :focus-visible ~ .mbpos-epo__row from the clipped position, which is
   correct — the visual row gains its focus ring while the input stays
   in the a11y tree. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__input {
	position: absolute;
	width: 1px;
	height: 1px;
	min-width: 0;
	min-height: 0;
	margin: -1px;
	padding: 0;
	border: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__row:hover {
	border-color: var(--mbpos-color-border-strong, #C9C4BA);
	background: var(--mbpos-color-surface-hover, #FAF9F7);
	/* [fix2] (0,4,0) — deliberately BELOW the selected rule's (0,5,0), so
	   hovering a selected row still keeps its white text. */
	color: var(--mbpos-color-text, #1C1917);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__input:focus-visible ~ .mbpos-epo__row,
[data-mbpos].mbpos-epo--sf .mbpos-epo__label {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	min-width: 0;
	font-weight: 500;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__desc {
	margin-top: 2px;
	font-size: var(--mbpos-font-size-s, 13px);
	font-weight: 400;
	color: var(--mbpos-color-text-muted, #6B655C);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__price {
	flex: 0 0 auto;
	font-size: var(--mbpos-font-size-s, 13px);
	font-weight: 600;
	white-space: nowrap;
	color: var(--mbpos-color-text-muted, #6B655C);
}

/* [sale1a] The struck-through was-price, printed ahead of the charged add.
   <del> already carries the semantics for assistive tech, so this rule is
   purely visual: lighter, smaller, and never bolder than the real price. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__was {
	margin-right: 4px;
	font-weight: 400;
	opacity: 0.75;
	text-decoration: line-through;
	/* [fix1] `inherit`, NOT the muted token. sale1a hardcoded a grey here,
	   which beat the white a selected row hands down — and because opacity
	   MULTIPLIES down the tree it landed at .85 x .65 = .55 effective, i.e.
	   dark grey at 55% on near-black. Inheriting means one declaration covers
	   both states and no state-specific rule is ever needed. */
	color: inherit;
}

/* Visual control indicator (the real input is clipped). */
[data-mbpos].mbpos-epo--sf .mbpos-epo__control {
	position: relative;
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	border: 2px solid var(--mbpos-color-border-strong, #C9C4BA);
	border-radius: 50%;
	background: transparent;
	transition: border-color .15s ease, background-color .15s ease;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group[data-type="checkbox"] .mbpos-epo__control {
	border-radius: var(--mbpos-radius-xs, 4px);
}

/* ── Selected ────────────────────────────────────────────────────────── */

[data-mbpos].mbpos-epo--sf .mbpos-epo__input:checked ~ .mbpos-epo__row {
	background: var(--mbpos-color-selected-bg, #1C1917);
	border-color: var(--mbpos-color-selected-bg, #1C1917);
	color: var(--mbpos-color-selected-text, #FFFFFF);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__input:checked ~ .mbpos-epo__row .mbpos-epo__desc,
[data-mbpos].mbpos-epo--sf .mbpos-epo__input:checked ~ .mbpos-epo__row .mbpos-epo__price {
	color: inherit;
	opacity: .85;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__input:checked ~ .mbpos-epo__row .mbpos-epo__control {
	border-color: currentColor;
	background: currentColor;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__input:checked ~ .mbpos-epo__row .mbpos-epo__control::after {
	content: "";
	position: absolute;
	inset: 0;
	margin: auto;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group[data-type="radio"] .mbpos-epo__input:checked ~ .mbpos-epo__row .mbpos-epo__control::after {
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: var(--mbpos-color-selected-bg, #1C1917);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group[data-type="checkbox"] .mbpos-epo__input:checked ~ .mbpos-epo__row .mbpos-epo__control::after {
	width: 5px;
	height: 10px;
	border: solid var(--mbpos-color-selected-bg, #1C1917);
	border-width: 0 2px 2px 0;
	transform: translateY(-1px) rotate(45deg);
}

/* ── [px1] The price cell ─────────────────────────────────────────────
   ONE number per row, and it is what the row costs. The cell renders in
   every state — including when it is empty — because the alternative is a
   box that appears when a free choice is doubled, and a box appearing is a
   width change on interaction: exactly the shift xtra2 and xtra3 spent two
   arcs removing.

   `min-width` is therefore load-bearing, not cosmetic. It is sized for the
   longest thing the cell can hold ("Included"), so the label's width never
   depends on which state the row is in. tabular-nums keeps prices aligned
   down the list and stops +$1.50 → +$3.00 jittering.

   The doubled figure is revealed by :has() rather than written by JS, so
   the number stays honest with scripts off — where the Extra checkbox is a
   real posting control and can genuinely be ticked. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__price {
	flex: 0 0 auto;
	min-width: 7ch;
	text-align: right;
	font-variant-numeric: tabular-nums;
}

/* [tri1] px1's `--x` amount and the `:has()` reveal were HERE, and both are
   gone because the problem they solved no longer exists. One control had to
   describe two prices while staying correct with scripts off, so both figures
   were printed and CSS chose between them. A segment carries its own price;
   there is nothing left to reveal.

   px1's RULE survives below, per segment: the cell renders in EVERY state
   including empty, and no state rule may set a width on it. A figure that
   appears on interaction is a width change on interaction, which is the
   xtra2 shift arriving by a new route. */

/* ── [tri1] The segmented level control ────────────────────────── */

/* D13 — THE ROW WRAPS. The name takes its own line and the segments wrap
   beneath it, which is what makes four levels survivable on a phone. Peter
   chose this against the alternative (collapse to one button, tap to expand)
   on a rendered comparison: collapse fits ~7 toppings in the vertical space
   wrap fits ~4, but it hides every price until a row is opened, and on an
   ordering page that is the wrong trade. Collapse returns later as an
   Appearance toggle for venues with genuinely long lists — a shop knows its
   own menu better than a media query does — and NOT as a breakpoint here. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__choice--seg {
	display: flex;
	flex-direction: column;
	gap: 6px;
	min-width: 0;
	padding: 10px var(--mbpos-space-s, 14px);
	background: var(--mbpos-color-surface, #FFFFFF);
	/* Longhands, not the `border` shorthand: a var() colour inside a shorthand
	   is fragile to parse and the width/style must survive independently of
	   whether the token resolves. Carried forward from the xtra1 block this
	   replaced — the note outlived the rule. */
	border-width: 1px;
	border-style: solid;
	border-color: var(--mbpos-color-border, #E3E0DA);
	border-radius: var(--mbpos-radius-s, 6px);
	/* [hov1] so the hover tint below fades rather than snaps. */
	transition: background-color .15s ease, border-color .15s ease;
}

/* [hov1] The card answers the pointer, the same as `.mbpos-epo__row:hover`
   above. A multi-level topping has no `__row` inside it, so before this the
   only thing that moved under the cursor was whichever pill you were directly
   over — the line itself was inert on both surfaces.

   `@media (hover: hover) and (pointer: fine)`: a tapped element keeps :hover
   on touch until something else is tapped, and a tint parked on the
   last-touched row reads as a second selected state.

   (0,5,0) via `.mbpos-epo__choices`: above the card's base at (0,3,0) and
   above box1's `background: transparent` section override at (0,4,0), so one
   rule serves both places a card can sit and the winner is decided by RANK
   rather than by which block sits later in the file.

   [hov1-a] NO `:not(.is-selected)`. Every topping in an Included section is
   selected at render, so guarding on it switched hover off for a whole
   section — Peter saw exactly that. A card's selected state is a border
   colour, which a background tint does not fight; the plain row's is a
   near-black fill, which it would, so that rule keeps its guard.

   `color` is restated because fix2's invariant says a rule that moves a
   background states the colour it moves it under; `inherit` is the honest
   value here, since nothing about the text changes. */
@media (hover: hover) and (pointer: fine) {
	[data-mbpos].mbpos-epo--sf .mbpos-epo__choices .mbpos-epo__choice--seg:hover {
		background: var(--mbpos-color-surface-hover, #FAF9F7);
		color: inherit;
	}
}

/* The row's own selected state moves COLOUR ONLY — xtra2's D2 invariant, and
   the reason it applies here is that this box now contains the control rather
   than sitting beside it. A padding or border-width on this rule would move
   every segment inside it. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__choice--seg.is-selected {
	border-color: var(--mbpos-color-border-strong, #C9C4BA);
}

/* [epo-sf-fix2] The seg path has no .mbpos-epo__row wrapper, so the
   .mbpos-epo__control indicator never receives its selected-state styling
   — it shows as a permanently empty circle. The segments ARE the control;
   this indicator is redundant and adds visual noise. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__choice--seg .mbpos-epo__control {
	display: none;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__choice--seg .mbpos-epo__label {
	flex: 0 0 auto;
	font-weight: 600;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__segs {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: 6px;
	min-width: 0;
}

/* The real radios stay in the DOM and the a11y tree — clipped, never
   display:none, so keyboard focus and screen readers still find them. Same
   treatment the choice inputs already get above; a segmented group's radios
   ARE the posting controls and hiding them properly is load-bearing for the
   scripts-off path. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__seg-input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	border: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
}

/* THE INVARIANT, inherited from xtra2 D2 and now carrying more weight because
   there are N of these per row instead of one: this box is IDENTICAL in every
   state. Width, padding, border-width, min-height and font do not vary
   between unpressed, hovered and pressed. Only colour moves. If you find
   yourself adding geometry to a state rule below, you are reintroducing the
   shift xtra2 removed. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__seg {
	display: inline-flex;
	flex: 0 1 auto;
	/* [fix5] CENTRE, not baseline — see the POS twin. The floor here is 44px
	   against ~16px of text, so the off-centre gap was the wider of the two. */
	align-items: center;
	justify-content: center;
	gap: 5px;
	box-sizing: border-box;
	/* [seg2d] anchors the tick; the symmetric padding below is its gutter. */
	position: relative;
	min-height: 44px;
	margin: 0;
	padding: 8px 20px;
	font: inherit;
	font-size: var(--mbpos-font-size-s, 13px);
	font-weight: 600;
	line-height: 1.2;
	text-align: center;
	color: var(--mbpos-color-text-muted, #6B655C);
	background: var(--mbpos-color-surface, #FFFFFF);
	border: 1px solid var(--mbpos-color-border, #E3E0DA);
	/* The literal 999px is required, not stylistic: jsdom does not resolve
	   var() in a computed border-radius and reports the longhands as "0"
	   regardless, so a tokenised value here is unfenceable (xtra1 D3). It also
	   keeps both surfaces on one shape — the POS sheet uses the same literal. */
	border-radius: 999px;
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__seg:hover {
	color: var(--mbpos-color-text, #1C1917);
	background: var(--mbpos-color-surface-hover, #FAF9F7);
	border-color: var(--mbpos-color-border-strong, #C9C4BA);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__seg-input:focus-visible + .mbpos-epo__seg {
	outline: 2px solid var(--mbpos-color-focus, #1C1917);
	outline-offset: 2px;
}

/* PRESSED. [tok1] accent / selected-text / selected-bg are all emitted by the
   skin builder now and all follow the venue's Selected colour, so this pair
   cannot come apart the way the old 2x pill did (its text was themed and its
   background was a hardcoded brown — pick a light Selected colour and you got
   dark on dark, which is the bug that blocked this arc). */
[data-mbpos].mbpos-epo--sf .mbpos-epo__seg-input:checked + .mbpos-epo__seg {
	color: var(--mbpos-color-selected-text, #FFFFFF);
	background: var(--mbpos-color-accent, #7A6A53);
	border-color: var(--mbpos-color-accent, #7A6A53);
}

/* [fix2] A pressed segment, hovered. Brightens the accent rather than
   restating a second hand-matched literal — the pair stays intact by
   construction. Specificity (0,4,0) beats the unpressed hover at (0,3,0) and
   sits after it, so source order settles the rest. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__seg-input:checked + .mbpos-epo__seg:hover {
	color: var(--mbpos-color-selected-text, #FFFFFF);
	background: var(--mbpos-color-accent, #7A6A53);
	border-color: var(--mbpos-color-accent, #7A6A53);
	filter: brightness(1.08);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__seg:active {
	transform: translateY(0.5px);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__seg:disabled {
	opacity: .55;
	cursor: default;
}

/* px1's cell, per position. tabular-nums keeps +$1.50 and +$3.00 the same
   width so pressing a segment cannot re-flow the strip. NO width, min-width or
   display is set by any state rule — see §2D of the fence. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__seg-price {
	font-weight: 500;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__seg .mbpos-epo__was {
	margin-right: 4px;
	font-weight: 400;
	opacity: .7;
}

/* ── Note ────────────────────────────────────────────────────────────── */

[data-mbpos].mbpos-epo--sf .mbpos-epo__note {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__note-label {
	margin: 0;
	font-size: var(--mbpos-font-size-s, 13px);
	font-weight: 600;
	color: var(--mbpos-color-text-muted, #6B655C);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__note-input {
	display: block;
	width: 100%;
	margin: 0;
	padding: 10px var(--mbpos-space-s, 14px);
	font: inherit;
	line-height: 1.4;
	color: var(--mbpos-color-text, #1C1917);
	background: var(--mbpos-color-surface, #FFFFFF);
	border: 1px solid var(--mbpos-color-border, #E3E0DA);
	border-radius: var(--mbpos-radius-s, 6px);
	resize: vertical;
	-webkit-tap-highlight-color: transparent;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__note-input:focus {
	outline: 2px solid var(--mbpos-color-focus, #1C1917);
	outline-offset: 1px;
}

/* ── Errors + total ──────────────────────────────────────────────────── */

[data-mbpos].mbpos-epo--sf .mbpos-epo__error {
	margin: 6px 0 0;
	font-size: var(--mbpos-font-size-s, 13px);
	font-weight: 500;
	color: var(--mbpos-color-danger, #B91C1C);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__error[hidden] {
	display: none;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group--error .mbpos-epo__group-name {
	box-shadow: inset 0 0 0 1px var(--mbpos-color-danger, #B91C1C);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__total {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--mbpos-space-2xs, 8px);
	margin: 0;
	padding: 10px var(--mbpos-space-s, 14px);
	font-weight: 600;
	background: var(--mbpos-epo-head-bg, #EFEDE8);
	border-radius: var(--mbpos-radius-s, 6px);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__total-value {
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

/* [fix1] The grand total. `space-between` on the parent would strand four
   children awkwardly, so the Total label takes the auto margin and the pair
   sits hard right — Options on the left, Total on the right, one line.
   The value is the loudest thing in the block because it is the number the
   customer is actually deciding about; the options delta is supporting
   detail and keeps its weight. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__grand-label {
	margin-left: auto;
	color: var(--mbpos-color-text-muted, #6B655C);
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__grand-value {
	font-size: var(--mbpos-font-size-l, 17px);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

/* Narrow columns: let the two pairs stack rather than crush the numbers. */
@media (max-width: 380px) {
	[data-mbpos].mbpos-epo--sf .mbpos-epo__total { flex-wrap: wrap; }
	[data-mbpos].mbpos-epo--sf .mbpos-epo__grand-label { margin-left: 0; }
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__blocked {
	margin: 0;
	padding: 10px var(--mbpos-space-s, 14px);
	font-weight: 500;
	color: var(--mbpos-color-danger, #B91C1C);
	background: var(--mbpos-color-danger-bg, #FEF2F2);
	border-radius: var(--mbpos-radius-s, 6px);
}

/* =====================================================================
   [tri1] WHAT USED TO BE HERE, AND WHY IT IS NOT
   =====================================================================
   This tail carried xtra1/xtra2/fix1's grouping-border rules: a selected
   choice gained a border and padding so the topping and its 2x pill read as
   one control, and `:has(.mbpos-epo__extra)` gated that so an ordinary group
   did not gain ~5px a side on tick (Peter's reported height shift, third
   cause).

   The segmented control makes all of it unnecessary rather than wrong:

     - THE GROUPING IS STRUCTURAL NOW. `.mbpos-epo__choice--seg` is a real
       box containing the name and every level, so nothing has to be drawn
       around two siblings to say they belong together.
     - THE SHIFT IS IMPOSSIBLE BY CONSTRUCTION. xtra2's shift #1 was "tick a
       topping, the control appears". Segments are always present, so nothing
       appears on tick and no state rule adds geometry. That is why xtra2's
       fence SURVIVES this arc — its §3 asks whether any state rule moves the
       box, which is a requirement, not a description of the old markup.
     - THE `· Extra` SUFFIX STAYS DELETED. xtra1's D6 attribution rule was
       already removed on both surfaces; the level's word now appears on the
       segment the customer pressed, which is one state with one encoding.

   The POS twin lives in mbpos-epo.css and got the same treatment in the same
   arc, deliberately — a window where one surface shows segments and the other
   shows a 2x checkbox is two surfaces answering one question differently,
   which is what pp2d-a's cross-surface parity exists to prevent.
   ===================================================================== */

/* ── [seg2a/seg2b] Derived sections + the pressed tick ───────────────────
   Storefront twin of the POS block. Root-scoped like the rest of this
   sheet; selection here is :checked-driven so the tick reveal is JS-off
   safe, matching how every other state on this surface works. */
/* [seg2d] Storefront twin of the POS section box + legend heading. */
/* [stk1] The storefront twin of the sticky group heading. This was missed when
   stk1 shipped — the rule went into the POS sheet only, and Peter found it:
   "on single product there is not sticky on toppings". The two surfaces have
   separate sheets by design, which is exactly why a change to one has to be
   asked of the other every time. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__group-name {
	position: sticky;
	top: 0;
	z-index: 2;
}
[data-mbpos].mbpos-epo--sf .mbpos-epo__section-body {
	/* [hov1-a] One writer for the inner gutter — see the POS twin. */
	--mbpos-epo-section-pad: 10px;
	margin: 16px 0 0;
	padding: 16px var(--mbpos-epo-section-pad) var(--mbpos-epo-section-pad);
	border: 1px solid var(--mbpos-color-border, #E3E0DA);
	border-radius: var(--mbpos-radius-s, 6px);
}
[data-mbpos].mbpos-epo--sf .mbpos-epo__section-body:first-child {
	margin-top: 0;
}
/* [tot1] Storefront twin — see the POS block for why the cell renders empty
   rather than disappearing. */
/* [sum1] Collapsed-only summary — see the POS twin. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__group:not(.mbpos-epo__group--collapsed) .mbpos-epo__summary {
	display: none;
}

[data-mbpos].mbpos-epo--sf .mbpos-epo__group-total {
	min-width: 56px;
	margin-left: 8px;
	text-align: right;
	font-variant-numeric: tabular-nums;
	font-weight: 700;
}
[data-mbpos].mbpos-epo--sf .mbpos-epo__section {
	display: inline-flex;
	align-items: baseline;
	gap: 10px;
	margin: -25px 0 8px 4px;
	padding: 2px 8px;
	/* [def1] Tinted, opaque — see the POS twin. */
	background: color-mix(in srgb, var(--mbpos-color-border, #E3E0DA) 55%, var(--mbpos-color-surface, #FFFFFF));
	border-radius: var(--mbpos-radius-s, 6px);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 0.4px;
	text-transform: uppercase;
	color: var(--mbpos-color-text-muted, rgba(29,28,27,0.6));
}
/* [seg2d] Out of flow — see the POS twin for why a reserved slot was not
   enough and why this is not a checkbox. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__seg-tick {
	position: absolute;
	left: 7px;
	top: 50%;
	transform: translateY(-50%);
	font-size: 11px;
	line-height: 1;
	opacity: 0;
}
[data-mbpos].mbpos-epo--sf .mbpos-epo__seg-input:checked + .mbpos-epo__seg .mbpos-epo__seg-tick {
	opacity: 1;
}

/* [box1] Storefront twin — one level of boxing inside a section. */
[data-mbpos].mbpos-epo--sf .mbpos-epo__section-body .mbpos-epo__choice {
	border-width: 0 0 1px;
	border-radius: 0;
	background: transparent;
	/* [hov1-a] Bleeds to the section border, pays the gutter back as padding —
	   see the POS twin for why. Nothing moves; the tint gains room. */
	margin-left: calc(-1 * var(--mbpos-epo-section-pad, 10px));
	margin-right: calc(-1 * var(--mbpos-epo-section-pad, 10px));
	padding-left: var(--mbpos-epo-section-pad, 10px);
	padding-right: var(--mbpos-epo-section-pad, 10px);
}
[data-mbpos].mbpos-epo--sf .mbpos-epo__section-body .mbpos-epo__choice:last-child {
	border-width: 0;
}
