/**
 * mbb-hire.css — the hire island's self-contained stylesheet.
 * CSS-ISOLATION-STANDARD: every rule scoped [data-mbb] .mbb-hire-*, own
 * typography floor, full state contract (hover/focus-visible/disabled/
 * aria-pressed), zero theme assumptions. Loads ONLY on range-kind mounts.
 */

[data-mbb].mbb-hire-widget {
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
	font-size: 15px;
	line-height: 1.45;
	color: var(--mbpos-color-heading, #1d2327);
	margin: 0 auto;
}
[data-mbb] .mbb-hire-error,
[data-mbb] .mbb-hire-msg:not(:empty) {
	padding: 10px 12px;
	border-radius: 8px;
	background: var(--mbpos-color-danger-subtle, #fbeaea);
	color: var(--mbpos-color-danger, #8a1f1f);
	margin-top: 10px;
}
[data-mbb] .mbb-hire-lbl {
	display: block;
	font-weight: 600;
	font-size: 13px;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--mbpos-color-text-soft, #50575e);
	margin: 14px 0 6px;
}

/* Blocks */
[data-mbb] .mbb-hire-blocks { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 4px; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-block {
	appearance: none; border: 1px solid var(--mbpos-color-border, #c3c4c7); background: var(--mbpos-color-surface, #fff); color: var(--mbpos-color-heading, #1d2327);
	border-radius: 999px; padding: 7px 14px; font: inherit; cursor: pointer;
}
/* [hp5/D65] Re-asserts background AND colour, not just the border — the block chooser
   has the same exposure the add-on rows did: the base rule sets a background,
   the hover rule did not, so the THEME's button:hover supplied one and the
   plugin's text colour was left sitting on it. Found by scanning for the
   shape rather than by a second report. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-block:hover {
	border-color: var(--mbpos-color-border-strong, #8c8f94);
	background: var(--mbpos-color-surface-2, #f6f7f7);
	color: var(--mbpos-color-heading, #1d2327);
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-block:focus-visible { outline: 2px solid var(--mbpos-color-primary, #2271b1); outline-offset: 2px; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-block.is-sel { background: var(--mbpos-color-selected, #1d2327); border-color: var(--mbpos-color-selected, #1d2327); color: var(--mbpos-color-selected-text, #fff); }

/* Stepper */
[data-mbb] .mbb-hire-units { display: flex; align-items: center; gap: 10px; }
[data-mbb] .mbb-hire-units .mbb-hire-lbl { margin: 0 auto 0 0; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-step {
	appearance: none; width: 36px; height: 36px; border-radius: 50%;
	border: 1px solid var(--mbpos-color-border, #c3c4c7); background: var(--mbpos-color-surface, #fff); font-size: 18px; line-height: 1;
	cursor: pointer; color: var(--mbpos-color-heading, #1d2327);
}
/* [hp5/D65] Re-asserts background AND colour, not just the border — the +/- stepper
   has the same exposure the add-on rows did: the base rule sets a background,
   the hover rule did not, so the THEME's button:hover supplied one and the
   plugin's text colour was left sitting on it. Found by scanning for the
   shape rather than by a second report. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-step:hover {
	border-color: var(--mbpos-color-border-strong, #8c8f94);
	background: var(--mbpos-color-surface-2, #f6f7f7);
	color: var(--mbpos-color-heading, #1d2327);
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-step:focus-visible { outline: 2px solid var(--mbpos-color-primary, #2271b1); outline-offset: 2px; }
[data-mbb] .mbb-hire-count { min-width: 72px; text-align: center; font-weight: 600; font-variant-numeric: tabular-nums; }

/* Calendar */
[data-mbb] .mbb-hire-cal { margin-top: 10px; border: 1px solid var(--mbpos-color-border, #e0e0e0); border-radius: 10px; padding: 10px; }
[data-mbb] .mbb-hire-cal-head,
[data-mbb] .mbb-hire-cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
[data-mbb] .mbb-hire-cal-head span {
	text-align: center; font-size: 11px; font-weight: 600; color: var(--mbpos-color-text-muted, #787c82);
	text-transform: uppercase; padding-bottom: 4px;
}
/* Paint only. Box and flow live in the containment chain at the foot of this
   file — see [p3a15]; a (0,2,0) selector cannot hold them against a theme. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day {
	appearance: none; border: 1px solid transparent; background: var(--mbb-cell-bg); color: var(--mbb-cell-text);
	border-radius: 8px; font: inherit; cursor: pointer; gap: 0;
}
[data-mbb] .mbb-hire-day-n { font-weight: 600; font-variant-numeric: tabular-nums; }
[data-mbb] .mbb-hire-day-m { font-size: 10px; color: currentColor; opacity: .7; text-transform: uppercase; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day:hover:not(:disabled) { border-color: var(--mbpos-color-border-strong, #8c8f94); background: var(--mbb-cell-hover); color: var(--mbpos-color-primary-hover-text, #1d2327); }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day:focus-visible { outline: 2px solid var(--mbpos-color-primary, #2271b1); outline-offset: 1px; }
/* [p3a35] The pickup and return days carry a ring so the two ENDS of a range
   are distinguishable from the days between them. Inset, so it costs no
   layout — an outer ring would shift the grid the moment a date is picked,
   which is the bug p3a28 removed. The held ring (p3a25) is declared later
   and deliberately wins: "someone else is booking this" outranks "you picked
   this". */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-sel {
	background: var(--mbpos-color-selected, #1d2327);
	color: var(--mbpos-color-selected-text, #fff);
	box-shadow: inset 0 0 0 2px var(--mbpos-color-selected-strong, #1d2327);
}
[data-mbb] .mbb-hire-day.is-sel .mbb-hire-day-m { color: var(--mbpos-color-selected-text, #c3c4c7); opacity: .8; }
[data-mbb] .mbb-hire-day.is-off { opacity: .35; cursor: not-allowed; text-decoration: line-through; }
[data-mbb] .mbb-hire-cal-pad { min-height: 1px; }

/* Extras */
[data-mbb] .mbb-hire-extras { display: flex; flex-direction: column; gap: 6px; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-extra {
	appearance: none; display: flex; align-items: center; gap: 10px; text-align: left;
	border: 1px solid var(--mbpos-color-border, #c3c4c7); background: var(--mbb-field-bg); color: var(--mbpos-color-text, #1d2327);
	border-radius: 8px; padding: 9px 12px; font: inherit; cursor: pointer;
}
/* [hp5/D65] The add-on price. Was --mbpos-color-text-soft, which is
   rgba(29,28,27,0.35) — a token for PLACEHOLDERS. A price is not a
   placeholder: it is the second thing the customer reads on that row, and at
   35% it was the faintest text in the widget. --text-muted is the token for
   real-but-secondary copy and is what this always wanted. */
[data-mbb] .mbb-hire-extra em {
	font-style: normal;
	color: var(--mbpos-color-text-muted, #50575e);
	margin-left: auto;
	font-weight: 600;
}
/* [hp5/D65] HOVER RE-ASSERTS BACKGROUND AND COLOUR, not just the border.
   Only border-color was set here, so the THEME's own `button:hover` supplied a
   background — and a 35%-opacity price on a theme-coloured hover background
   was invisible. That is the whole bug Peter saw, and the lesson is the
   general one this stylesheet is organised around: a widget that sets a
   property in its resting state must set it in every state the theme also
   styles, or the theme wins exactly one of them.
   currentColor on the em keeps the pair legible whatever the surface. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-extra:hover {
	border-color: var(--mbpos-color-border-strong, #8c8f94);
	background: var(--mbpos-color-surface-2, #f6f7f7);
	color: var(--mbpos-color-text, #1d2327);
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-extra:hover em { color: currentColor; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-extra:focus-visible { outline: 2px solid var(--mbpos-color-primary, #2271b1); outline-offset: 2px; }
[data-mbb] .mbb-hire-extra-tick {
	width: 18px; height: 18px; border: 2px solid var(--mbpos-color-border, #c3c4c7); border-radius: 4px; flex: 0 0 auto;
	display: inline-block; position: relative;
}
/* [hp5/D65] Same re-assertion for the chosen state — a theme that styles
   [aria-pressed="true"] would otherwise own the background of a row the
   plugin has already coloured. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-extra.is-sel {
	border-color: var(--mbpos-color-selected, #1d2327);
	background: var(--mbb-field-bg);
	color: var(--mbpos-color-text, #1d2327);
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-extra.is-sel em { color: var(--mbpos-color-text, #1d2327); }
[data-mbb] .mbb-hire-extra.is-sel .mbb-hire-extra-tick { background: var(--mbpos-color-selected, #1d2327); border-color: var(--mbpos-color-selected, #1d2327); color: var(--mbpos-color-selected-text, #fff); }
[data-mbb] .mbb-hire-extra.is-sel .mbb-hire-extra-tick::after {
	content: ""; position: absolute; left: 4px; top: 0; width: 5px; height: 10px;
	border: solid currentColor; border-width: 0 2px 2px 0; transform: rotate(45deg);
}

/* Quote */
[data-mbb] .mbb-hire-quote {
	margin-top: 14px; padding: 12px 14px; border-radius: 10px; background: var(--mbpos-color-surface-2, #f6f7f7);
	display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
[data-mbb] .mbb-hire-quote--empty { color: var(--mbpos-color-text-muted, #787c82); justify-content: center; }
[data-mbb] .mbb-hire-price { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }
[data-mbb] .mbb-hire-price em { font-size: 12px; font-weight: 400; font-style: normal; color: var(--mbpos-color-text-soft, #50575e); }

/* Form */
[data-mbb] .mbb-hire-form { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 12px; }
[data-mbb] .mbb-hire-in {
	appearance: none; border: 1px solid var(--mbpos-color-border, #c3c4c7); border-radius: 8px; padding: 9px 11px;
	font: inherit; color: var(--mbpos-color-text, #1d2327); background: var(--mbb-field-bg); width: 100%; box-sizing: border-box;
}
[data-mbb] .mbb-hire-in:focus-visible { outline: 2px solid var(--mbpos-color-primary, #2271b1); outline-offset: 1px; }
[data-mbb] .mbb-hire-in[data-hf="name"], [data-mbb] .mbb-hire-in[data-hf="notes"] { grid-column: 1 / -1; }
[data-mbb] .mbb-hire-hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
/* [ct3] The save-details opt-in. Full width like the notes field, and placed
   in source order between notes and the submit button so the customer reads
   what is about to be remembered before the button that does it.

   The colour is the form's own text token, NOT a muted grey: this is consent
   copy, and the cx1 waiver list already carries four cases of small text at
   marginal contrast — adding a fifth deliberately, on the one line that says
   what happens to someone's details, would be the wrong place to save a shade.
   `currentColor` on the box keeps it matched to the label under any theme,
   the same reasoning cx2 applied to the combo ring.

   [ct3b] EXPLICIT APPEARANCE AND SIZING, and the doubled-attribute selector.
   Reported by Peter: invisible in the POS product modal while fine on the
   product page. This is a defect class this codebase has already met and
   written down — see the ap2 express-wallet tick box in mbpos-lightbox.css,
   whose comment says it plainly: an unstyled checkbox rendered INVISIBLY in
   testing, structure correct, simply not seeable, because themes and the POS
   layout routinely reset label display and checkbox appearance. Its
   conclusion applies here unchanged: "A DOM fence cannot catch that, so the
   styling is deliberately explicit."

   The first draft used the plain `[data-mbb] .mbb-hire-save` form. Every rule
   in this file that has to survive a hostile cascade uses
   `[data-mbb][data-mbb].mbb-hire-widget` instead — the submit button, the day
   cells, the nav. The tick box needs it for the same reason and did not have
   it, which is the whole of the bug. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-save {
	grid-column: 1 / -1;
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0;
	font: inherit; font-size: .9em;
	color: var(--mbpos-color-text, #1d2327);
	min-width: 0;             /* Hello Elementor sets min-width:0 on flex kids */
	cursor: pointer;
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-save input {
	-webkit-appearance: checkbox;
	appearance: checkbox;
	width: 17px;
	height: 17px;
	min-width: 17px;          /* stops flex from collapsing it to zero */
	margin: 0;
	padding: 0;
	flex: 0 0 auto;
	opacity: 1;
	position: static;         /* some themes absolutely position form inputs */
	accent-color: currentColor;
	cursor: pointer;
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-submit {
	grid-column: 1 / -1; appearance: none; border: 0; border-radius: 8px;
	background: var(--mbpos-color-primary, #1d2327); color: var(--mbpos-color-primary-text, #fff); padding: 12px; font: inherit; font-weight: 600; cursor: pointer;
}
/* [p3a31] Was `background: #000` — darkening an already-dark button reads as
   "less available", and it left the label's contrast unre-checked. The
   hover shade is computed from the base (it LIGHTENS a dark one), and
   hover-text is the pc1 variant that re-runs the contrast pick against that
   computed shade rather than reusing the resting text colour. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-submit:hover:not(:disabled) {
	background: var(--mbpos-color-primary-hover, #000);
	color: var(--mbpos-color-primary-hover-text, #fff);
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-submit:focus-visible { outline: 2px solid var(--mbpos-color-primary, #2271b1); outline-offset: 2px; }
[data-mbb] .mbb-hire-submit:disabled { opacity: .45; cursor: not-allowed; }
[data-mbb] .mbb-hire-msg { grid-column: 1 / -1; min-height: 1px; }

@media (max-width: 420px) {
	[data-mbb] .mbb-hire-form { grid-template-columns: 1fr; }
}

/**
 * [p3a3] Native Woo suppression on injected product pages. This pair lived
 * ONLY in mbb-widget.css, so a hire product — which loads this island
 * instead — kept Woo's quantity box and Add to cart button sitting under
 * the hire widget, offering a second, unbooked way to buy. Each island
 * owns its own copy; there is no shared stylesheet to put it in, and a
 * shared one would load on every covers page for no reason.
 */
form.cart.mbb-native-suppress .quantity,
form.cart.mbb-native-suppress .single_add_to_cart_button { display: none !important; }
form.cart.mbb-native-suppress [data-mbb].mbb-hire-widget { margin: 12px 0; }

/* [p3pos1s6] POS modal gutters.
   The hire island's root carries no horizontal padding — covers pads its own
   root (14px), hire only sets `margin: 0 auto` — so in the POS product modal
   the calendar sat flush against the panel edge while every sibling block was
   inset, and the widget read as escaping the modal rather than belonging to
   it.

   Deliberately NOT padding added to the hire root: that would change the
   product page too, where the theme's container already provides the gutter
   and nobody reported a problem.

   Same token as the EPO block solving this in the same slot (mbpos-epo.css),
   but NOT its selector shape. EPO has to reach for `.mbpos-lightbox__panel
   .mbpos-products-detail__addons >` because it has no variant class of its
   own; the booking mount already carries `mbb-widget--pos`, set by the modal
   renderer and by nothing else. Keying on that is both narrower and
   [data-mbb]-first, so M26's isolation rule holds without widening its
   allowlist — which its own comment says must not grow by reflex.

   Override per template with --mbb-pos-gutter.

   Not applied to the covers mount: it already pads its own root, and adding
   this would double it. */
[data-mbb][data-mbb].mbb-hire-widget.mbb-widget--pos {
	padding-left: var(--mbb-pos-gutter, var(--mbpos-space-2xs, 12px));
	padding-right: var(--mbb-pos-gutter, var(--mbpos-space-2xs, 12px));
}

/* [p3a5] Empty state — why nothing is bookable. */
[data-mbb] .mbb-hire-empty {
	margin: 10px 0 0; padding: 12px 14px; border-radius: 10px;
	background: var(--mbpos-color-warning-subtle, #fcf3e6); border-left: 4px solid var(--mbpos-color-warning-hover, #b25e09); color: var(--mbpos-color-heading, #1d2327);
}
[data-mbb] .mbb-hire-empty p { margin: 0; }
[data-mbb] .mbb-hire-empty-fix {
	margin-top: 8px !important; padding-top: 8px; border-top: 1px solid var(--mbpos-color-border, #e6d5bd);
	font-size: 13px; color: var(--mbpos-color-text-soft, #50575e);
}

/* [p3a7] Month paging + range highlight. */
[data-mbb] .mbb-hire-cal-nav {
	display: flex; align-items: center; justify-content: space-between;
	gap: 8px; margin-bottom: 8px;
}
[data-mbb] .mbb-hire-cal-title { font-weight: 600; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-nav {
	appearance: none; width: 32px; height: 32px; border-radius: 8px;
	border: 1px solid var(--mbpos-color-primary, #c3c4c7); background: var(--mbpos-color-primary, #fff); color: var(--mbpos-color-primary-text, #1d2327);
	font-size: 18px; line-height: 1; cursor: pointer;
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-nav:hover:not(:disabled) { background: var(--mbpos-color-primary-hover, #8c8f94); color: var(--mbpos-color-primary-hover-text, #fff); border-color: var(--mbpos-color-primary-hover, #8c8f94); }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-nav:focus-visible { outline: 2px solid var(--mbpos-color-primary, #2271b1); outline-offset: 2px; }
[data-mbb] .mbb-hire-nav:disabled { opacity: .35; cursor: not-allowed; }
/* [p3a35] The days BETWEEN pickup and return are a selection state, so they
   derive from `selected` — p3a31 skipped these two tints as "no matching
   token", which was wrong and left a hardcoded pale blue that no theme could
   move. `subtle` is the light variant of the same colour, so the range reads
   as a weaker version of its endpoints rather than an unrelated colour.
   The text colour must be set here too: the cell's own --mbb-cell-text is the
   contrast pick for the PRIMARY fill, and would be unreadable on this one. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-in-range {
	background: var(--mbb-range-bg);
	border-color: var(--mbpos-color-selected, #b8cbdd);
	color: var(--mbb-range-text);
}
[data-mbb] .mbb-hire-cal-hint {
	margin: 8px 0 0; font-size: 12px; color: var(--mbpos-color-text-muted, #787c82); text-align: center;
}

/* [p3a8] Per-day rate labels on calendar cells. */
/* [p3a31] The rate label sits at 10px, and 9px in the narrow container tier.
   Small text needs MORE contrast than the ratio alone suggests, so this uses
   the body text token rather than the softer one it had — `text-soft` is for
   secondary prose at normal size, not for a price the customer is reading to
   make a decision. Weight does some of the work too. */
[data-mbb] .mbb-hire-day-r {
	display: block; font-size: 10px; line-height: 1.2;
	/* [p3a34] currentColor, so the price follows whatever contrast pick the
	   cell made. A fixed token here was legible on a near-white cell and
	   invisible on a saturated one. */
	color: currentColor; opacity: .85; font-weight: 600;
	font-variant-numeric: tabular-nums; margin-top: 1px;
}
/* [p3a34] Weekend rates were amber — `warning`, documented as "caution
   notices", which a higher price is not, and unreadable on a coloured cell.
   Weight and full opacity carry the signal instead. */
[data-mbb] .mbb-hire-day.is-wknd .mbb-hire-day-r { opacity: 1; font-weight: 700; }
/* [hp5] The running total for a hire ending on this cell. Sits under the day
   number, muted, tabular so a column of prices lines up. Deliberately NOT
   truncated: a truncated price is a wrong price, so if it does not fit the
   cell it is better to show nothing and let the quote line carry it. */
/* [hp5/D53] A PILL, not loose text. Loose 10px numerals under a 15px day
   number read as part of the same word — the eye has nothing telling it where
   the date stops and the money starts. A tinted chip gives the price its own
   edge, and costs one background and one radius. */
[data-mbb] .mbb-hire-day-t {
	display: inline-block;
	margin-top: 2px;
	padding: 1px 5px;
	border-radius: 999px;
	/* [hp5/D54] The pill is the SAME chip everywhere — on a plain cell, on the
	   selected run, on a hovered cell. A price that changes appearance
	   depending on whether the day is picked is two visual languages for one
	   piece of information, and the customer has to learn both.
	   `surface` + `text` is white-on-dark-ink in the default skin and stays
	   legible in a dark one, which a literal `#fff` would not.
	   The BORDER is load-bearing: a surface-coloured pill on a
	   surface-coloured cell is invisible without it. */
	background: var(--mbpos-color-surface, #fff);
	border: 1px solid var(--mbpos-color-border, #dcdcde);
	font-size: 10px;
	line-height: 1.35;
	font-variant-numeric: tabular-nums;
	color: var(--mbpos-color-text, #1d2327);
	white-space: nowrap;
	/* NOT overflow:hidden. A clipped price is a WRONG price, and a customer
	   who reads $1,05 and is charged $1,050 has been misled by a stylesheet.
	   If it cannot fit, the length label is dropped first (below) and the
	   number is never touched. */
}
/* The length, inside the pill: "3d $800". Dropped rather than shrunk when the
   cell narrows — see the container rules. */
[data-mbb] .mbb-hire-day-t__d {
	opacity: .65;
	margin-right: 3px;
	font-weight: 600;
}
/* [hp5/D54] NO selected-state override. The pill deliberately does NOT invert
   with the cell — see the background note above. Kept as a comment rather than
   deleted silently, because reversing it out is the obvious thing to reach for
   the next time someone looks at a selected run and thinks the chip looks
   detached. It is meant to. */
/* [p3a31] Was a fixed #dcdcde — a light grey picked for one specific selected
   fill, which becomes unreadable the moment that fill changes. primary-text
   is auto-picked for contrast against the fill actually in use. */
[data-mbb] .mbb-hire-day.is-sel .mbb-hire-day-r,
[data-mbb] .mbb-hire-day.is-sel.is-wknd .mbb-hire-day-r { color: var(--mbpos-color-selected-text, #dcdcde); opacity: .9; }

/* [p3a9] Calendar arrows centred (default button padding pushed the glyph
   off-centre), selection ticks, clear control, day length chip. */
[data-mbb] .mbb-hire-nav {
	display: inline-flex; align-items: center; justify-content: center;
	padding: 0; line-height: 1;
}
[data-mbb] .mbb-hire-day { position: relative; }
[data-mbb] .mbb-hire-tick {
	position: absolute; top: 3px; right: 4px; width: 11px; height: 11px;
}
[data-mbb] .mbb-hire-tick::after {
	content: ""; position: absolute; left: 3px; top: 0; width: 4px; height: 8px;
	border: solid var(--mbpos-color-heading, #1d2327); border-width: 0 2px 2px 0; transform: rotate(45deg);
}
[data-mbb] .mbb-hire-day.is-sel .mbb-hire-tick::after { border-color: var(--mbpos-color-surface, #fff); }
[data-mbb] .mbb-hire-cal-clear { margin: 6px 0 0; text-align: center; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-clear {
	appearance: none; background: none; border: 0; padding: 4px 8px;
	font: inherit; font-size: 12px; color: var(--mbpos-color-primary, #2271b1); cursor: pointer; text-decoration: underline;
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-clear:focus-visible { outline: 2px solid var(--mbpos-color-primary, #2271b1); outline-offset: 2px; }
[data-mbb] .mbb-hire-len {
	display: inline-block; margin-right: 8px; padding: 2px 8px; border-radius: 999px;
	background: var(--mbpos-color-primary, #1d2327); color: var(--mbpos-color-primary-text, #fff); font-size: 12px; font-weight: 600;
}

/**
 * [p3a13] Containment. The island was authored against a full-width
 * column; auto-mount (p3a12) put it inside the product summary, which on
 * most themes is roughly half that. Two things then broke the calendar out
 * of its own border:
 *
 *   1. Grid children default to `min-width: auto`, which means a cell
 *      REFUSES to shrink below its content — seven cells plus gaps simply
 *      overflowed rather than compressing.
 *   2. The calendar carried padding without `box-sizing: border-box`, so
 *      its 100% width became 100% + 20px.
 *
 * Fixed by sizing rather than by clipping: nothing is hidden, the cells
 * just compress properly. `overflow-wrap` on the shell is a backstop for
 * long add-on labels in a narrow column.
 */
[data-mbb].mbb-hire-widget,
[data-mbb].mbb-hire-widget *,
[data-mbb].mbb-hire-widget *::before,
[data-mbb].mbb-hire-widget *::after { box-sizing: border-box; }

[data-mbb].mbb-hire-widget {
	/* [p3a33] The island's own vocabulary, defaulting to POS tokens. Day
	   cells and text inputs both sat on `surface`, so changing it moved
	   both and there is no POS token that separates them. Naming the two
	   concepts makes them independently retargetable in one line instead
	   of across forty rules. See MBPOS-COLOUR-TOKENS.md. */
	/* [p3a34] Day cells carry the CTA colour. Text on them therefore comes
	   from --mbb-cell-text, the contrast pick for whatever fill is in use —
	   a fixed dark colour would be unreadable the moment the fill is
	   saturated. Selection stays on `selected`, which is what keeps the
	   chosen dates distinguishable from the other thirty. */
	--mbb-cell-bg: var(--mbpos-color-primary, #f6f7f7);
	--mbb-cell-hover: var(--mbpos-color-primary-hover, #fff);
	--mbb-cell-text: var(--mbpos-color-primary-text, #1d2327);
	/* [p3a37] The days between pickup and return. Solid `selected`, same as
	   the two ends: a tinted interior is the usual range-picker convention,
	   but it read as "some of my chosen days are less chosen than others".
	   The ends stay distinguishable by their ring, not by weight. Kept as a
	   variable so switching back to `selected-subtle` is one line. */
	--mbb-range-bg: var(--mbpos-color-selected, #1d2327);
	--mbb-range-text: var(--mbpos-color-selected-text, #fff);
	--mbb-field-bg: var(--mbpos-color-surface, #fff);
	width: 100%;
	max-width: 900px;       /* [p3a16] ceiling only — see D12 */
	overflow-wrap: break-word;
}

[data-mbb] .mbb-hire-cal { max-width: 100%; padding: 8px; }

/* The load-bearing line: let grid cells actually shrink. */
[data-mbb] .mbb-hire-cal-grid,
[data-mbb] .mbb-hire-cal-head { min-width: 0; }
[data-mbb] .mbb-hire-cal-grid > *,
[data-mbb] .mbb-hire-cal-head > * { min-width: 0; }

[data-mbb] .mbb-hire-day-n { line-height: 1.15; }
[data-mbb] .mbb-hire-day-r { white-space: nowrap; }

/* Narrow columns: tighten inside the CALENDAR's own width, not the
   viewport's — the widget can sit in a 320px sidebar on a 1600px screen,
   so a viewport media query would measure the wrong box. */
[data-mbb] .mbb-hire-cal { container-type: inline-size; }

/* Injected into form.cart the theme may impose its own flex/grid; keep the
   island a plain block that fills the row it lands in. */
[data-mbb].mbb-hire-widget.mbb-widget--inject { display: block; flex: 1 1 100%; }

/**
 * [p3a14] Two faults from the p3a13 measurements. The container tier fix
 * (a 430px tier for the width a product-summary column actually is) was
 * correct and still stands. The "hard reset against theme button rules"
 * was not: see [p3a15] below for why it changed nothing.
 *
 * `overflow: hidden` on the cell CLIPPED the price instead of fitting it.
 * Clipping is never the right answer for a number the customer is being
 * asked to agree to: a truncated price is worse than no price.
 */
[data-mbb] .mbb-hire-day-n,
[data-mbb] .mbb-hire-day-r {
	display: block;
	width: 100%;
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;   /* if it truly cannot fit, say so visibly */
	white-space: nowrap;
}

/**
 * [p3a15] THE CONTAINMENT CHAIN — one writer for the day cell's box and flow.
 *
 * p3a13 and p3a14 each "hardened" this cell and each changed nothing on the
 * live site. Measured cause, from a rule-level cascade probe in Peter's
 * browser (11,822 rules scanned): the theme's product template carries, in an
 * inline <style>,
 *
 *     .fr-single-product-alpha__cart form.cart button:not(.added_to_cart)
 *         { min-width: var(--btn-width) }              (0,3,2)
 *
 * while every rule this sheet owned was (0,2,0) — [data-mbb] plus one class.
 * It lost on class count, before source order was ever consulted.
 *
 * The sting: `--btn-width` is UNDEFINED on that element. The declaration is
 * invalid at computed-value time, but it has already won the cascade, so it
 * does not fall through to our `min-width: 0` — it falls back to the
 * property's initial value, `min-width: auto`. We were not being beaten by a
 * competing value; we were being beaten by nothing, which resolves to exactly
 * the value we were trying to remove. `min-width: auto` on a grid item floors
 * each track at min-content: seven cells wanted 791px inside a 374px grid.
 *
 * The 20px rate label was the same fault one level down, not a second bug.
 * Nothing else in the document declares `width` on the label; while the cell
 * was min-content-sized, the child's percentage width had no definite basis
 * to resolve against and contributed as `auto`, so the label sized to its
 * text and the cell sized to the label.
 *
 * (0,4,0) clears (0,3,2) on class count regardless of element count. Two
 * near-misses look sufficient and are not: `[data-mbb][data-mbb] .mbb-hire-day`
 * is (0,3,0) and `[data-mbb] .mbb-hire-cal-grid > .mbb-hire-day` is (0,3,1).
 * Fence M29.1 pins the floor rather than the rule's contents, because M26 and
 * M28 both passed for the whole life of this defect.
 *
 * No `!important` and no dependency on the theme's private `--btn-*` names:
 * the first is a ceiling we may want later and cannot climb past, the second
 * couples this island to one theme's internals.
 *
 * LESSON FOR THE STANDARD: CSS isolation and cascade authority are different
 * properties. Scoping every selector to [data-mbb] makes this sheet unable to
 * leak OUT. It does nothing to stop a theme leaking IN.
 */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day {
	min-width: 0;
	width: 100%;
	max-width: 100%;
	margin: 0;
	padding: 5px 1px;
	overflow: visible;          /* never clip a price */
	display: flex;
	flex-direction: column;
	align-items: stretch;       /* children get the cell's width, not their own */
	text-align: center;
}

/* Tiers run WIDEST-FIRST. Both are max-width, both are (0,4,0): below 330px
   they both match and the later one wins, so an ascending order silently
   makes the tighter tier dead code — which is what p3a14 shipped by
   appending the 430 tier after the 330 one. M29.3 pins the ordering. */
@container (max-width: 430px) {
	[data-mbb] .mbb-hire-cal-grid,
	[data-mbb] .mbb-hire-cal-head { gap: 3px; }
	[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day { padding: 4px 0; }
	[data-mbb] .mbb-hire-day { border-radius: 6px; }
	[data-mbb] .mbb-hire-day-n { font-size: 13px; }
	[data-mbb] .mbb-hire-day-r { font-size: 9px; letter-spacing: -0.2px; }
	[data-mbb] .mbb-hire-cal-head span { font-size: 10px; }
	[data-mbb] .mbb-hire-tick { top: 2px; right: 2px; width: 9px; height: 9px; }
	[data-mbb] .mbb-hire-tick::after { left: 2px; width: 3px; height: 6px; }
	/* [hp5/D53] Seven columns in 430px is a ~57px cell. "3d $1050" does not
	   fit; "$1050" does. The LABEL goes, never the number.
	   [hp5/D62] A marginal annotation briefly shared this breakpoint and was
	   reverted — see mbb-hire.js. Only the day label is droppable. */
	[data-mbb] .mbb-hire-day-t__d { display: none; }
	[data-mbb] .mbb-hire-day-t { padding: 1px 4px; font-size: 9px; }
}

@container (max-width: 330px) {
	[data-mbb] .mbb-hire-cal-grid,
	[data-mbb] .mbb-hire-cal-head { gap: 2px; }
	[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day { padding: 4px 0; }
	[data-mbb] .mbb-hire-day { border-radius: 6px; }
	[data-mbb] .mbb-hire-day-n { font-size: 13px; }
	[data-mbb] .mbb-hire-day-r { font-size: 8px; }
	[data-mbb] .mbb-hire-tick { top: 2px; right: 2px; width: 8px; height: 8px; }
	[data-mbb] .mbb-hire-tick::after { left: 2px; width: 3px; height: 6px; border-width: 0 2px 2px 0; }
	[data-mbb] .mbb-hire-cal-head span { font-size: 9px; }
}

/* [p3a20, revised p3cal1] Base held treatment, now only ever seen through
   .is-locked or .is-mine below. p3a20's "it is bookable" is no longer true
   of a foreign hold and never was — the server refused it the whole time
   while the calendar said "whoever pays first gets the machine". */
/* [hp1d] The length-discount promo.
   -subtle fill with its -strong pair, NOT -text: `success-text` is auto-picked
   for contrast against the saturated base and resolves to white on a light
   theme, which is how the hold notice ended up white-on-pink (p3cal1b). The
   pair travels together or it does not travel.
   Success rather than warning: this is good news, and the amber block already
   means "you cannot have these dates". */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal {
	margin: 10px 0;
	padding: 8px 10px;
	border-radius: 8px;
	border: 1px solid var(--mbpos-color-success, #16a34a);
	background: var(--mbpos-color-success-subtle, #f0fdf4);
	color: var(--mbpos-color-success-strong, #14532d);
	font-size: 13px;
}
/* One unit short: the same fact, weighted. Not a different colour — a nudge
   that shouts reads as pressure, and this one is true either way. */
/* [hp2e] The ladder. Tight leading and a modest marker — it is an offer list,
   not a feature grid, and three rungs should read in one glance. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal-list {
	margin: 0;
	/* [hp4/D50] NO list-style and NO padding-left. The marker is a real
	   element now (.mbb-hire-deal-mark) rendered on every row, because the
	   old arrangement — CSS bullets, plus a tick span only when on, plus
	   `li.is-on { list-style:none; margin-left:-18px }` to make room for it —
	   shifted the applying row sideways every time the selection moved. A
	   price list whose rows jump as you scan it is hard to read. */
	padding-left: 0;
	list-style: none;
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal-list li {
	margin: 2px 0;
	/* The row is marker + text on one baseline; the marker slot is a fixed
	   width so tick and bullet occupy exactly the same space. */
	display: flex;
	align-items: baseline;
	gap: 6px;
	padding: 2px 6px;
	border-radius: 4px;
	/* [hp4/D52] Rows are normal weight; `is-on` supplies the emphasis and is
	   the only thing that should. `.mbb-hire-deal.is-live` bolds the whole
	   container, which was right when a picked list held two lines and is
	   wrong for a price list. Set here rather than by overriding .is-live so
	   this stays BELOW li.is-on in specificity — a rule carrying .is-live
	   would outrank it and un-bold the very row being highlighted. */
	font-weight: 400;
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal-mark {
	flex: 0 0 1em;
	text-align: center;
	font-weight: 700;
}
/* [hp4] The rung that APPLIES. Exactly one can be on — highest qualifying
   wins, and a Saturday start hands it to the weekend line instead (D50).
   [hp4/D50] Reversed out rather than merely bolded: at a glance the customer
   should find their price without reading, and weight alone does not survive
   a list of seven similar rows. currentColor keeps it correct in a dark
   theme without a second declaration. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal-list li.is-on {
	font-weight: 700;
	/* primary + primary-text is the existing "this one is chosen" pair used
	   throughout the plugin, and it is a REAL token pair — an earlier draft
	   of this rule invented --mbpos-color-fg/-bg, which tok1 §E3 caught
	   because nothing emits them. */
	background: var(--mbpos-color-primary, #1d2327);
	color: var(--mbpos-color-primary-text, #fff);
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal-tick { font-weight: 700; }
/* Reached but superseded: muted, and deliberately NOT ticked — the customer
   is not getting this one. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal-list li.is-passed { opacity: .55; }
/* The next rung up carries its own "add N more", so it stays at full weight. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal-list li.is-next { opacity: 1; }
/* [hp30b/D224b] THE FEE IS ALWAYS IN FORCE, SO IT IS WEIGHTED — NEVER TICKED.
   Peter, 2026-09-08: *"i only want one choice to be ticked … the setup fee
   should always be highlighted eg bold … but the check should only be the 1,
   EG the price it matches"*.

   The rungs are ALTERNATIVES and exactly one of them applies, which is what
   the tick says (D50). The fee is not an alternative — it is charged whichever
   rung wins — so it needs emphasis that does NOT read as a selection. Weight
   is exactly that: it says "this one counts" without claiming "this one is
   your choice".

   ⚠ IT CANNOT COMPETE WITH THE APPLYING ROW, AND THAT IS BY CONSTRUCTION
   RATHER THAN BY LUCK. `li.is-on` above is REVERSED OUT — primary background,
   primary text — precisely because D50 found that weight alone does not
   survive a list of seven similar rows. The customer's own price is a filled
   block; the fee is bold text on the page background. Two different signals,
   so raising the fee's weight takes nothing away from the tick.

   Set AFTER li.is-on rather than with a heavier selector: same specificity,
   later wins, and a rule that outranked li.is-on is exactly what the note
   beside `li` at font-weight 400 warns about. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal-list li.is-note { font-weight: 700; }

/* [hp2f] Inside a picked-state list the FIRST line is the news and the second
   is the aside, so the trailing rung is lightened by position rather than by a
   class the markup no longer needs. */
/* [hp4/D52] The `li + li` rule is GONE, not merely lightened.
   It existed to revert `.is-live`'s container bold on every row after the
   first — which quietly made row one bold, because it was the "news" line of
   a two-line list. D49 turned this into a price list of nine rows, so the
   1-day rung was arriving bold for no reason a customer could read, and it
   was the odd one out in exactly the way Peter spotted. Weight is now set
   once on `li` above, and `is-on` is the only thing that raises it. */

/* [hp3] Price breakdown — the hire twin of the checkout's, and deliberately
   quiet: it is a way to check the arithmetic, not a feature to advertise. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd { margin-top: 6px; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__toggle {
	display: inline-flex; align-items: center; gap: 5px;
	background: none; border: 0; padding: 2px 0; cursor: pointer;
	font-size: 12px; font-family: inherit;
	color: var(--mbpos-color-text-muted, #6b7280);
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__chevron { transition: transform .15s ease; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__table {
	width: 100%; border-collapse: collapse; margin-top: 4px; font-size: 13px;
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__table td { padding: 3px 0; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__table td + td { text-align: right; }
/* [hp6] Ledger conventions: a single rule ABOVE a subtotal, a double rule
   under the final total. Structure carries the meaning — the colours below are
   reinforcement, never the only signal, because a customer who cannot separate
   green from grey still has the minus sign and the rules. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__is-sub td {
	border-top: 1px solid var(--mbpos-color-border, #E4E1DC);
	padding-top: 5px;
	font-weight: 600;
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__total td {
	border-top: 1px solid var(--mbpos-color-border, #E4E1DC);
	border-bottom: 3px double var(--mbpos-color-border, #E4E1DC);
	padding-top: 5px; padding-bottom: 4px;
	font-weight: 700;
	color: var(--mbpos-color-heading, #1C1917);
}
/* A saving is good news, and it is already signed — the colour agrees with the
   minus rather than replacing it. -strong on the panel's own surface, NOT
   -text: success-text is picked for contrast against the SATURATED base and
   resolves to white on a light theme, which is how the hold notice ended up
   white-on-pink (Addendum 43). */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__is-off td {
	color: var(--mbpos-color-success-strong, #14532d);
}
/* Labels recede so the money reads first. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__table td:first-child {
	color: var(--mbpos-color-text-muted, #6b7280);
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__is-sub td:first-child,
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__total td:first-child {
	color: var(--mbpos-color-heading, #1C1917);
}

[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal.is-nudge { font-weight: 700; }
/* [hp1e] Applied: the same green, weighted like the nudge — it is the payoff
   the nudge promised, and switching colour at the moment it lands would read
   as a different kind of message rather than the same one resolving. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal.is-live { font-weight: 700; }

[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-deal-tag {
	color: var(--mbpos-color-success-strong, #14532d);
	font-style: normal;
	font-weight: 700;
}

[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-held {
	border-color: var(--mbpos-color-warning, #d97706);
	border-style: dashed;
	background: var(--mbpos-color-warning-subtle, #fffbeb);
	/* [p3cal1b] The pair, restated. Every .is-held cell also carries
	   .is-locked or .is-mine today, both of which set a colour, so this is
	   currently unreachable — but a fill without its colour is a bug waiting
	   for the first cell that carries neither, and the whole point of the
	   fix2 invariant is that the pair travels with the fill. */
	color: var(--mbpos-color-warning-strong, #78350f);
}
/* [p3cal1] LOCKED — someone else's live hold. create_hold WILL refuse this
   span, so the calendar must not offer it. Deliberately NOT the .is-off
   treatment (opacity .35 + line-through): that says "the yard never does
   this", when in fact it is available and will be again shortly. Amber and
   solid-edged, cursor forbidden, full opacity — a wait, not a closure. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-held.is-locked {
	border-style: solid;
	border-color: var(--mbpos-color-warning-hover, #b45309);
	background: var(--mbpos-color-warning-subtle, #fffbeb);
	/* [p3cal1b] The pair MUST be restated, exactly as p3a35 says four rules
	   up: --mbb-cell-text is the contrast pick for the PRIMARY fill and is
	   unreadable on this one. Shipped without it, the day number and rate
	   were near-white on a pale tint.
	   -strong, not -text: `warning-text` is auto-picked against the BASE
	   warning colour (saturated), so on a light theme it resolves to white
	   and lands white-on-near-white here. Same defect pc1/pc2 fixed for
	   -hover and -strong elsewhere. The rate follows via currentColor,
	   which is what p3a34 built it for. */
	color: var(--mbpos-color-warning-strong, #78350f);
	cursor: not-allowed;
	opacity: 1;
	text-decoration: none;
}

/* [p3cal1] MINE — this visitor's own cart. p3sb1 makes the server accept
   these, so they stay selectable and get a statement of fact rather than a
   caution: no warning colour, no dashed edge. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-held.is-mine {
	border-style: solid;
	border-color: var(--mbpos-color-border, #E4E1DC);
	/* [p3cal1b] Hand the cell back to its OWN pair rather than inventing a
	   second one. The first draft painted `surface` here and left the colour
	   alone, which is the same mismatch as the locked cell: --mbb-cell-text
	   is picked against --mbb-cell-bg, so overriding one and not the other
	   guarantees the two disagree under some theme. A date in your own cart
	   is an ORDINARY available date wearing a badge; it should look like
	   one. */
	background: var(--mbb-cell-bg);
	color: var(--mbb-cell-text);
}

/* [p3cal1] The p3a25 selection ring is RETIRED. It existed so the held cue
   survived selection — but a foreign hold can no longer BE selected, so the
   rule is unreachable. Its raw #fbbf24 goes with it, which is a token
   standard improvement as a side effect rather than as a goal. Only the
   .is-mine case can now be both held and selected, and it is styled as an
   ordinary selection because that is exactly what it is. */

/**
 * [p3a16] D12 — the island's width is host-derived, not content-derived.
 *
 * MEASURED on SNH: the right column of the product grid is a stable 748px,
 * but the theme's add-to-cart wrapper caps itself with `max-width: max-content`.
 * A max-content cap measures OUR contribution, so the column reported 390px at
 * rest and 560px once the quote line ("Pick up … → return …") appeared — the
 * widget was sizing its own container, and the container was sizing the widget.
 * That is the width oscillation, and also what the p3a13 handover recorded as
 * the puzzling "523/539 after a click".
 *
 * The cap is on the theme's wrapper — our PARENT's parent — and CSS cannot
 * reach upward, so no [data-mbb]-scoped rule can undo it. The suppression
 * script tags that one element `data-mbb-host` (it already walks this DOM to
 * find form.cart), and we clear the cap on exactly that element.
 *
 * DELIBERATE EXCEPTION TO CSS-ISOLATION-STANDARD, the first this module has
 * taken beyond native suppression. The justification is narrow and should stay
 * narrow: the tag is only applied to a form that CONTAINS the island, and by
 * then native suppression has hidden everything else that form held, so the
 * wrapper contains nothing but us. Minimum intervention — ONE property. If a
 * future theme needs more than this to lay the island out, that is a case for
 * mounting outside the summary column (§8), not for growing this rule. M30
 * pins both the exception and its size.
 *
 * `max-width: 900px` on the island is a ceiling, not a target: on a
 * single-column theme the host can be the full page, and a 1300px-wide booking
 * form is not better than a 900px one.
 */
/* [p3a17] Doubled attribute = (0,2,0). MEASURED: the cap is
   `.fr-single-product-alpha__cart` at (0,1,0) in an inline <style>, so the
   single-attribute form tied it and lost on source order — p3a16 pinned this
   exception's SIZE but never that it could WIN, which is the exact gap M29
   closes one level down. Not an ID selector, so no !important is needed.
   M30 now pins the floor. */
[data-mbb-host][data-mbb-host] { max-width: none; }

/* The form is a flex item in that wrapper; on a row-flex host it would size to
   its content even once the cap is gone. Its native controls are already
   display:none by the rule above, so it holds nothing but the island. */
form.cart.mbb-native-suppress { width: 100%; }

/* [p3a25] The same warning in words, for touch users and anyone who does not
   hover. Deliberately calm: a statement of fact, not a countdown. */
[data-mbb] .mbb-hire-warn {
	margin: 0 0 6px;
	padding: 6px 8px;
	border-left: 3px solid var(--mbpos-color-warning, #d97706);
	background: var(--mbpos-color-warning-subtle, #fffbeb);
	/* [p3cal1b] Was warning-TEXT, which is auto-picked for contrast against
	   the BASE warning colour — on a light theme that resolves to white, and
	   this fill is near-white, so the notice rendered white-on-pink. Reported
	   from SNH. -strong is the dark shade of the same hue and is the pairing
	   the gifts modal (pc2) and pickup modal already use on a -subtle fill. */
	color: var(--mbpos-color-warning-strong, #78350f);
	font-size: 12px;
	line-height: 1.35;
}

/* [p3a26] The busy marker on a held date. STATIC once shown: a single
   fade-in draws the eye when the cell first renders and then stops. A looping
   animation would keep the compositor awake for as long as the page is open,
   on a phone, possibly scrolled far past the calendar — the sort of small
   always-on cost that adds up on a shared host. It would also make a true
   statement look like the fake-urgency widgets this deliberately is not. */
/* [p3a27] A filled badge, not punctuation. The dots were too quiet to read
   as a status at 9px inside an already-busy cell. Solid amber against the
   cell's pale fill carries at a glance without moving. */
/* [p3a28] The hidden twin reserves the row height, so a cell is the same
   size whether or not it is held and the grid never resizes when the
   selection changes. */
[data-mbb] .mbb-hire-busy.is-off { visibility: hidden; }
[data-mbb] .mbb-hire-busy {
	display: block;
	margin: 2px -1px -1px;
	padding: 1px 0;
	border-radius: 0 0 5px 5px;
	background: var(--mbpos-color-warning, #d97706);
	color: var(--mbpos-color-surface, #fff);
	font-size: 7px;
	font-weight: 700;
	line-height: 1.4;
	letter-spacing: 0.4px;
	animation: mbb-hire-fade 240ms ease-out 1;
}
@keyframes mbb-hire-fade { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
	[data-mbb] .mbb-hire-busy { animation: none; }
}

/* [p3a27] The notice sits BELOW the calendar (Peter's preferred position),
   present whether or not a date is selected. */
[data-mbb] .mbb-hire-warn { margin: 8px 0 0; }

/* [p3a29] A held date that is currently un-pickable keeps its badge — it is
   still being booked by someone else, and hiding that just because the date
   cannot be clicked right now is how the cue disappeared the moment a pickup
   date was chosen. Muted, not removed. */
/* [p3cal1b] The muted badge repainted its background and kept `surface` as
   its colour — but `surface` was picked to sit on the AMBER base, so under a
   dark theme it is dark-on-grey and under a light one it is white on #a8a29e,
   about 2.3:1. Both fixed, because the grey itself is fixed by design (see
   the p3a31 note below): a token colour on a hardcoded fill can only ever be
   right by luck. */
[data-mbb] .mbb-hire-day.is-off .mbb-hire-busy { background: #a8a29e; color: #1d2327; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-off.is-held { border-color: #a8a29e; }

/* [p3a31] Deliberately NOT tokenised, each for a reason:
   #000 on the submit hover is replaced by primary-hover above — darkening a
   dark button on hover reads as "less available", and the token already
   computes the right direction for a light OR dark base.
   #a8a29e is the muted busy badge on a closed day, and #1d2327 is the text
   that sits on it: both fixed by design, because they must stay legible
   against whatever the theme sets — and a fill fixed by design needs its
   colour fixed by design too, or the pair breaks the moment the theme moves
   (p3cal1b).
   (p3cal1: #fbbf24, the held ring, was listed here too and is GONE — the ring
   existed so the held cue survived selection, and a foreign hold can no
   longer BE selected. An exemption outliving the thing it exempted is worse
   than no exemption: it reads as permission for a colour nobody can find.)
   (p3a35: all three of the tints previously listed here WERE mappable after
   all — the in-range pair derives from `selected`, the divider from `border`.
   "No matching token" was a failure to look, and it left a pale blue range
   that no theme could move.) */

/* [p3a32] THE PAINT FLOOR — why every interactive element above is prefixed
   `[data-mbb][data-mbb].mbb-hire-widget`.
   MEASURED on SNH: the theme's product template carries, in an inline <style>,
     .fr-single-product-alpha__cart form.cart button:not(.added_to_cart)
        { background-color: var(--button-color); color: var(--button-text) }
   at (0,3,2). It matches EVERY button in this island on the add-to-cart mount,
   so the day cells were painted in the theme's button colours and changing the
   MBPOS Appearance theme did nothing visible.
   p3a15 fixed exactly this for the cell's BOX (min-width, padding, display).
   The PAINT stayed at (0,2,0) and kept losing. Doubling the attribute gives
   (0,4,0), which clears (0,3,2) on class count without !important.
   The child spans (-n, -r, -m) are deliberately NOT raised: no theme rule
   targets them, and raising uncontested selectors spends specificity we may
   need later. */

/* [p3a36] The two ends read as one bar rather than two unrelated chips: the
   pickup keeps its left corners, the return its right, and the days between
   square off. Purely visual — the range is still three separate states. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-sel:not(.is-end) { border-radius: 8px 2px 2px 8px; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-end { border-radius: 2px 8px 8px 2px; }
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-in-range { border-radius: 2px; }

/* [hp3] The saving line and the combo nudge.

   Two different jobs, deliberately styled differently. The saving CONFIRMS a
   decision already made — quiet, success-toned, sitting under the price it
   explains. The nudge PROPOSES another one, so it gets a box and a border:
   it is the only element in the quote panel asking the customer to do
   something they have not thought of, and reading as a footnote to the price
   would waste it.

   Both stay inside the [data-mbb] scope like everything else in this island
   (CSS-ISOLATION-STANDARD), and both use the shared tokens with literal
   fallbacks so a theme without them still renders. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-saving {
	margin: 6px 0 0;
	color: var(--mbpos-color-success-strong, #14532d);
	font-size: 0.92em;
	line-height: 1.4;
}

[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-combo-nudge {
	margin: 10px 0 0;
	padding: 9px 11px;
	/* primary-subtle / border-soft, NOT invented accent-bg + accent-subtle.
	   The first cut used those two: they read plausibly and they are not in
	   the emitted set, so every site would have silently taken the hardcoded
	   fallback and the nudge would have ignored the skin entirely. tok1's E3
	   caught it. Tokens here must come from build_skin_css()'s :root. */
	border: 1px solid var(--mbpos-color-border-soft, #d6d3d1);
	border-radius: var(--mbpos-radius-sm, 6px);
	background: var(--mbpos-color-primary-subtle, #f5f5f4);
	font-size: 0.92em;
	line-height: 1.45;
}

[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-combo-nudge a {
	font-weight: 700;
	text-decoration: underline;
}

/* [hp16/D98b] The APPLIED state, same box and same position as the offer it
   replaces — one slot, two states. Distinguished by the accent border alone
   rather than a different colour block: a customer glancing back at the panel
   should see the same element having changed, not a new one having appeared.

   Tokens from build_skin_css()'s :root only. tok1's E3 caught an earlier cut
   inventing accent-bg / accent-subtle, which are not in the emitted set, so
   every site would silently have taken the hardcoded fallback and ignored the
   skin. */
/* [hp16/D99] The per-day figure with the combo already in it. Marked, not
   duplicated: D61 put a second money figure in the cell and D62 reverted it
   because two numbers in a 57px cell read as one confusing number. This is
   still ONE number — it just tells the truth about what the day costs while
   the other machine is in the cart.

   WEIGHT AND AN UNDERLINE, NEVER A COLOUR. p3a's M44.2 forbids a day-cell
   child pinning its own colour, and it is right: the child cannot know what
   fill it is sitting on. The first cut set --mbpos-color-primary here, which
   would have kept the discounted rate teal on a SELECTED cell — a dark fill
   the cell's own children are recoloured against — and quietly made the one
   number this feature exists to show unreadable at the moment the customer
   picks the date.

   Single-scoped, matching the sibling rate rules, for the reason M42.1 gives:
   no theme rule targets these child spans, so doubling the scope attribute
   spends specificity nothing is contesting, and spent specificity is how
   there is none left when something does.

   (Written without repeating the doubled selector, because M42.1 scans the
   stylesheet as text and matched this very paragraph when it did — "a grep
   can match its own explanation", the house rule, arriving in a comment for
   the second time in one session.)

   No badge, no icon, no extra box either: the cell already carries an
   availability state, hp9's Booked pill, hp5's total pill and this rate line,
   and hp5/D53 exists because that content was already reflowing. */
[data-mbb] .mbb-hire-day-r--combo {
	font-weight: 700;
	text-decoration: underline dotted;
	text-underline-offset: 2px;
}

/* [hp17/D101] THE QUALIFYING SPAN, RINGED.

   AN INSET box-shadow, and the reasoning that first rejected it was WRONG.
   The first cut used `outline` on the grounds that inset box-shadow was
   "taken by is-sel". It is taken on a SELECTED cell — and D101.3 means the
   ghost is never on one: the real selection wins the cell outright, which
   6t6 pins and M53 mutates. So the channel was free here all along, and the
   ghost can speak the same visual language as a real selection, which is
   what it is: the shape the selection should be.

   SUCCESS, NOT PRIMARY — and the first two attempts failed on this. Measured
   on the live site, primary, warning, warning-hover and selected all resolved
   to the same hue at four lightnesses. Combo, hold and selected were not
   neighbouring colours; they were ONE colour, so the ring could not read as a
   distinction however it was drawn. (The measured values are recorded in
   HANDOVER-hp17.md — they stay out of this file, because M45.3 cannot tell a
   hex in a comment from a hex in a declaration, and it is right not to try.)

   The cause is in the appearance system, not here: only eight base tokens are
   settable (primary, primary-text, surface, border, text, text-muted, success,
   danger) and warning and selected are DERIVED, so an orange brand makes every
   state orange. success is one of the eight, so it survives that derivation —
   and it is the honest semantic anyway. A combo is a saving. A saving is a
   positive, not a caution, and it should never have been wearing the warning
   family's hue.

   ENDPOINTS SOLID, MIDDLE LIGHTER. The two ends are the cells the customer
   has to tap; the days between are connective tissue and must not compete
   with them. That is also what makes two spans readable as two spans with no
   colour per machine — a contiguous run reads as one block, and pairing
   (which end goes with which start) is answered by adjacency. See D104.

   NO COLOUR ON THE RATE ITSELF. M44.2 forbids a day-cell child pinning its
   own colour and is protecting exactly this change: under D100 the discounted
   figure now appears on SELECTED cells, where a fixed token would have gone
   unreadable against the dark fill at the moment the customer picks the date.
   The rate keeps currentColor; the cell carries the cue. */
/* [cx2] THE RING NOW MATCHES THE OFFER LINE — Peter's direction: the outer
   border of a combo span is the same colour as the "$155 combo" text inside
   it. That text is currentColor (D109, revised), so the ring is too.

   This retires the success-green choice reasoned about immediately above, and
   the reasoning is worth keeping rather than deleting: green was picked as the
   honest semantic (a combo is a saving, not a caution) AND because `success`
   is one of the eight settable base tokens, so it survives the derivation that
   makes warning and selected follow an orange brand.

   What it could not survive is the D109 problem, which is the same defect the
   text hit and the same one the ring was always exposed to: a venue token
   cannot be checked for contrast against a venue surface from inside this
   file. Measured live, success green came out at 1.11:1 on the venue's
   surface — invisible, and no amount of ring-drawing fixes a colour that is
   not there. (The measured values stay in HANDOVER-hp17.md, not here, for the
   reason given at the top of this block: M45.3 cannot tell a hex in a comment
   from a hex in a declaration, and it is right not to try. Writing one here
   turned it red, which is the rule working.)
   currentColor cannot have that problem, because it is by definition the
   colour already proven readable on whatever this cell is.

   So the cue is now carried by SHAPE and WEIGHT rather than hue — 2px solid
   ends, 1px middle, exactly as D104 set out — plus the word "combo" in the
   offer line, which was the point of moving to words in the first place. The
   endpoints-solid/middle-lighter distinction is unchanged and still does the
   work of making two spans read as two spans.

   The ring is full-strength currentColor; the offer text sits at .85 opacity.
   Same colour, and the ring deliberately reads a touch stronger — it is the
   tap target. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-combo-start,
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-combo-end,
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-combo-both {
	box-shadow: inset 0 0 0 2px currentColor;
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day.is-combo-span {
	box-shadow: inset 0 0 0 1px currentColor;
	opacity: .9;
}

/* The legend that makes the above readable on touch (hp9/D80 — a title needs
   a pointing device). Quiet: it explains, it does not sell. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-cal-legend {
	margin: 8px 0 0;
	color: var(--mbpos-color-primary, #0f766e);
	font-size: 0.85em;
	line-height: 1.4;
}

/* [hp17/D103] One line per qualifying span. A list rather than a sentence
   because there can be more than one, and the failure it replaces was exactly
   a single sentence quoting the first span's length at all of them. */
/* [hp17/D107] The offer line. currentColor is NOT used here, deliberately and
   as the ONE exception M44.2 allows for: the offer is a different claim from
   the rate above it (a conditional price, not this cell's price) and must not
   read as a second helping of the same number. It is scoped so it never lands
   on the selected fill — an offer retires the moment the selection earns it,
   so this rule cannot be the white-on-near-white failure pc1/pc2 fixed. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day-c {
	display: block;
	font-size: .78em;
	line-height: 1.2;
	font-weight: 600;
	/* [hp17/D109, revised] currentColor — the SAME colour as the rate above
	   it, at Peter's direction after two colour attempts failed.
	   
	   Both failures had one cause: a venue token cannot be checked for
	   contrast against a venue surface from inside this file. Measured live,
	   the success green came out at 1.11:1 on #C75134 — a different hue at
	   almost the same luminance. currentColor cannot have that problem,
	   because it is by definition the colour already proven readable on
	   whatever this cell is. It is also what M44.2 asks for.
	   
	   The word "combo" carries the meaning, which was the point of moving to
	   words in the first place; smaller and lighter keeps it subordinate to
	   the rate without needing a hue to say so. */
	color: currentColor;
	opacity: .85;
	white-space: nowrap;
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-day-c.is-off {
	visibility: hidden;
}

[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-cal-legend__lead {
	margin: 0;
	font-size: inherit;
	color: inherit;
}
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-cal-legend__spans {
	margin: 2px 0 0;
	padding-left: 1.2em;
	color: var(--mbpos-color-primary, #0f766e);
	font-size: 0.85em;
	line-height: 1.5;
}

[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-combo-nudge--on {
	border-color: var(--mbpos-color-primary, #0f766e);
}

/* [hp16/D98b] The combo rows in the breakdown. The deduction reads like the
   other negative lines (the flat-price adjustment above it), and "You pay"
   carries the weight of the Total it follows — the Total is still the locked
   machine price, so the eye needs to land on the row below it. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__combo td {
	color: var(--mbpos-color-primary, #0f766e);
}

[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-bd__pay td {
	font-weight: 700;
}

/* The condition, not the offer. Same size would make it compete with the
   money; hiding it would make the offer look unconditional, and a customer
   who books two machines on different dates and gets no discount has been
   misled by this box. */
[data-mbb][data-mbb].mbb-hire-widget .mbb-hire-combo-nudge__note {
	display: block;
	margin-top: 3px;
	opacity: 0.75;
	font-size: 0.9em;
}

/* [hp9b/D80] THE REASON, as a PILL.
   Same chip as the price (.mbb-hire-day-t): inline-block, 999px radius,
   surface fill, real border. Peter asked for this shape after seeing the bare
   text version, and he is right that it reads better — a chip has an edge, and
   an edge survives the 35% dimming that .is-off puts on the whole cell. Bare
   10px text at 35% of a muted grey did not, which was the original complaint.
   The known trade, recorded rather than argued: the price chip means "you can
   have this", so a refusal wearing the same shape asks the customer to read
   the WORD rather than the form. The word is short and the cell is struck
   through, so there is little room to misread it.
   Opts out of the strike-through only — the dimming stays, because the cell
   as a whole is meant to look unavailable. */
[data-mbb] .mbb-hire-day-x {
	display: inline-block;
	margin-top: 2px;
	padding: 1px 5px;
	border-radius: 999px;
	background: var(--mbpos-color-surface, #fff);
	border: 1px solid var(--mbpos-color-border, #dcdcde);
	color: var(--mbpos-color-text, #1d2327);
	font-size: 10px;
	line-height: 1.35;
	letter-spacing: -0.1px;
	text-decoration: none;
	white-space: nowrap;
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* [hp9/D79] The next month's first days, borrowed to finish the last week.
   Dimmed so the grid does not contradict the month title above it — but
   lighter than .is-off, which means "unavailable" and must stay the stronger
   signal of the two. A borrowed day that is ALSO unavailable gets both. */
[data-mbb] .mbb-hire-day.is-adjacent { opacity: .72; }
[data-mbb] .mbb-hire-day.is-adjacent.is-off { opacity: .3; }

/* ── [avt2/D294] Opt-in two-column layout ────────────────────────────────
 *
 * Selected on the ATTRIBUTE, not on a class, so nothing here can apply to a
 * storefront island by accident — a customer page never sets it.
 *
 * 2fr / 1fr, not 3fr / 1fr. "7 days hire: $1,680, additional days at $240"
 * wraps to three lines at a quarter width, and once every rung wraps the
 * falling per-day column stops reading as a column — which is the whole
 * argument for a longer hire (hp4/D57: the rate is there so the customer does
 * not have to divide).
 *
 * align-items:start so the ladder does not stretch to the calendar's height.
 */
[data-mbb][data-mbb-layout="split"] {
	display: grid;
	grid-template-columns: 2fr 1fr;
	gap: 20px;
	align-items: start;
}
[data-mbb][data-mbb-layout="split"] > .mbb-hire-main,
[data-mbb][data-mbb-layout="split"] > .mbb-hire-side { min-width: 0; }

/* ⚠ STACKS ON NARROW SCREENS. The yard reads this on a phone; a hard two
 * column grid would undo the mobile work av1 shipped. */
@media (max-width: 820px) {
	[data-mbb][data-mbb-layout="split"] {
		grid-template-columns: 1fr;
		gap: 14px;
	}
}
