/*
 * Integrated date/time panel (spec §6.2).
 *
 * The expansion is a CSS grid column going 0fr → 1fr. That's deliberate: it
 * means the calendar column keeps its exact width and position while the time
 * panel grows out beside it, rather than the whole card re-laying out. On mobile
 * the same idea runs on rows instead, so the panel drops beneath the calendar
 * with one extra rule rather than a separate mobile component.
 *
 * Brand values come from the theme's tokens.css via custom properties, with
 * fallbacks so the plugin still renders sanely under any other theme.
 */

.rsdf-bw {
	--bw-green-dark: var(--rsdf-green-dark, #333B30);
	--bw-green-mid:  var(--rsdf-green-mid, #8A9A5B);
	--bw-cream:      var(--rsdf-cream, #F1F0EB);
	--bw-orange:     var(--rsdf-orange, #DD5A28);
	--bw-grey:       var(--rsdf-grey, #D9D9D6);
	--bw-white:      var(--rsdf-white, #FFFFFF);
	--bw-ease:       var(--rsdf-ease, cubic-bezier(0.2, 0, 0, 1));
	--bw-duration:   var(--rsdf-duration, 280ms);
	--bw-font-ui:    var(--rsdf-font-ui, Georgia, serif);

	--bw-calendar-width: 400px;

	position: relative;
	width: 100%;
	max-width: var(--bw-calendar-width);

	/*
	 * The widget sets its own ink colour rather than inheriting.
	 *
	 * On the homepage it renders inside .rsdf-home-hero, which sets
	 * color: white for the hero copy — every element in here that used
	 * `color: inherit` or relied on the body default (the hint line, the
	 * advisory paragraphs, the consent labels, the Back link, the field
	 * hints, the empty-state) was therefore painting white text onto a cream
	 * card and disappearing. Setting it once at the root fixes all of them at
	 * every breakpoint; the two places that genuinely are white — the dark
	 * heads and the alert bar — set it explicitly themselves.
	 */
	color: var(--rsdf-ink, #1C1C1A);

	display: grid;
	/*
	 * The collapsed side column is minmax(0, 0fr), not a bare 0fr.
	 *
	 * A bare `0fr` track is `minmax(auto, 0fr)` — an automatic *minimum*. The
	 * footer spans both columns, and when a spanning item's minimum size is
	 * distributed across its tracks, anything the first track can't absorb
	 * (its minimum is a hard 0) lands on the second. The collapsed column was
	 * therefore sizing itself to the footer's padding rather than to nothing:
	 * 48px of empty cream down the right-hand edge, which also left the dark
	 * green header 48px short of the card's own width. Pinning the minimum to
	 * 0 gives the calendar the full 400px and leaves nothing to see.
	 */
	grid-template-columns: minmax(0, var(--bw-calendar-width)) minmax(0, 0fr);
	grid-template-rows: auto auto;

	background: var(--bw-cream);
	border-radius: 22px;
	overflow: hidden;
	box-shadow: 0 20px 40px rgba(0, 0, 0, 0.25);

	transition:
		max-width var(--bw-duration) var(--bw-ease),
		grid-template-columns var(--bw-duration) var(--bw-ease);
}

.rsdf-bw.is-expanded {
	max-width: 900px;
	grid-template-columns: minmax(0, var(--bw-calendar-width)) minmax(0, 1fr);
}

/* On /booking/ the widget is a page-level component, not a floating card —
   flat on the page, sitting in the normal content flow. */
.rsdf-bw--page {
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
	margin-inline: auto;
}

/* Urgent notice repeated inside the widget (§5.5.2). Spans both columns and
   sits above everything, because it may be the only place someone sees it. */
.rsdf-bw__alert {
	grid-column: 1 / -1;
	grid-row: 1;
	display: flex;
	gap: 10px;
	align-items: baseline;
	flex-wrap: wrap;
	background: var(--rsdf-ink, #1C1C1A);
	color: var(--bw-white);
	padding: 12px 20px;
	font-size: 0.85rem;
	border-bottom: 3px solid var(--bw-orange);
}

.rsdf-bw__alert strong {
	text-transform: uppercase;
	letter-spacing: 0.05em;
	font-size: 0.72rem;
	flex-shrink: 0;
}

/* The alert takes row 1, so everything else shifts down a row. */
.rsdf-bw:has(.rsdf-bw__alert) .rsdf-bw__panel--calendar,
.rsdf-bw:has(.rsdf-bw__alert) .rsdf-bw__panel--side { grid-row: 2; }
.rsdf-bw:has(.rsdf-bw__alert) .rsdf-bw__foot { grid-row: 3; }

@media (max-width: 767px) {
	/* The expanding row is the times panel, which is one further down when an
	   alert is present — so the row template needs the extra row too, or the
	   panel expands the wrong one and nothing appears to happen. */
	.rsdf-bw:has(.rsdf-bw__alert),
	.rsdf-bw:has(.rsdf-bw__alert).is-expanded {
		grid-template-rows: auto auto 0fr auto;
	}
	.rsdf-bw:has(.rsdf-bw__alert).is-expanded { grid-template-rows: auto auto 1fr auto; }

	.rsdf-bw:has(.rsdf-bw__alert) .rsdf-bw__panel--calendar { grid-row: 2; }
	.rsdf-bw:has(.rsdf-bw__alert) .rsdf-bw__panel--side { grid-row: 3; }
	.rsdf-bw:has(.rsdf-bw__alert) .rsdf-bw__foot { grid-row: 4; }
}

/* ── Panels ──────────────────────────────────────────────────────────────── */

.rsdf-bw__panel {
	min-width: 0;
	display: flex;
	flex-direction: column;
}

.rsdf-bw__panel--calendar {
	grid-column: 1;
	grid-row: 1;
}

/*
 * The divider between the two columns is an inset shadow, NOT a border.
 *
 * A border occupies space, and a grid track sized 0fr still has to be wide
 * enough for its item's non-shrinkable parts — so a 1px border on the collapsed
 * side panel forced the whole column to 1px. That 1px was the cause of two
 * separate complaints: the thin grey line down the right-hand edge of the card
 * on first load, and the dark green header being 399px wide inside a 400px card,
 * which read as the header "shrinking" away from the edge.
 *
 * An inset shadow paints inside the element and contributes nothing to layout,
 * so at zero width there is simply nothing to see.
 */
.rsdf-bw__panel--side {
	grid-column: 2;
	grid-row: 1;
	overflow: hidden;
	box-shadow: inset 1px 0 0 rgba(51, 59, 48, 0.12);
	/* Both step views stack in the same cell so swapping between them cannot
	   change the widget's size. */
	display: grid;
	grid-template-areas: 'view';
}

.rsdf-bw__view {
	grid-area: view;
	min-width: 0;
	min-height: 0;
	display: flex;
	flex-direction: column;
}

.rsdf-bw__view[hidden] { display: none; }

/*
 * Desktop: the side column's contents are taken out of flow so they contribute
 * nothing to the grid row's intrinsic height. The row is therefore sized purely
 * by the calendar (which is always six weeks tall), and the side panel stretches
 * to match it. That's what fixes the depth — without this the time list grows
 * the whole widget on a long summer day and shrinks it on a short winter one.
 */
/*
 * Choosing a date, a time and confirming all keep the same footprint — that's
 * what stops the card resizing as you click around, and it's the whole reason
 * the views are taken out of flow here.
 *
 * Payment is the one deliberate exception. Stripe's Payment Element renders at
 * around 512px on its own, which is taller than the entire card; holding the
 * footprint there means the form scrolls, and a payment form with the card
 * field below the fold is a form people abandon. So on this step, and only this
 * step, the box grows to fit and nothing is hidden. It costs one resize of the
 * hero at the last step, which is a fair trade for the checkout being fully
 * visible.
 */
@media (min-width: 768px) {
	.rsdf-bw__panel--side { position: relative; }

	.rsdf-bw__view {
		position: absolute;
		inset: 0;
	}

	.rsdf-bw.is-paying .rsdf-bw__panel--side { position: static; }
	.rsdf-bw.is-paying .rsdf-bw__view { position: static; }
}

.rsdf-bw.is-paying .rsdf-bw__scroll {
	overflow: visible;
	max-height: none;
}

/* Calendar stays put but is no longer the thing setting the height. */
.rsdf-bw.is-paying .rsdf-bw__panel--calendar { align-self: start; }

/* Contents fade in slightly after the container starts opening, so the two
   movements read as one gesture rather than two separate animations. */
.rsdf-bw__panel--side > .rsdf-bw__view {
	min-width: 440px;
	opacity: 0;
	transform: translateY(8px);
	transition:
		opacity var(--bw-duration) var(--bw-ease) 60ms,
		transform var(--bw-duration) var(--bw-ease) 60ms;
}

.rsdf-bw.is-expanded .rsdf-bw__panel--side > .rsdf-bw__view {
	opacity: 1;
	transform: none;
}

/* ── Heads ───────────────────────────────────────────────────────────────── */

/*
 * Both heads are laid out identically and pinned to one fixed height.
 *
 * They were previously sized by their own contents: the calendar's head holds a
 * 30px round nav button, the side panel's holds a line of text, and the two came
 * out about a pixel apart — which is visible as a step in the green band running
 * across the top of the card, and moves as you page through the steps. A shared
 * height and a shared centring rule make the band one continuous block whatever
 * is inside either side.
 */
.rsdf-bw__head {
	background: var(--bw-green-dark);
	color: var(--bw-white);
	padding: 14px 20px;
	height: 84px;
	/* The head is a flex item in a column, so `height` alone is only a starting
	   size — it will still shrink when the panel below it wants more room, which
	   is exactly what squashed the right-hand head to 46px against the
	   calendar's 84px. It must never shrink; the body scrolls instead. */
	flex: 0 0 auto;
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 3px;
	overflow: hidden;
}

/* Mobile stacks the two panels, so there's no band to keep continuous and a
   hard height would clip a wrapped guidance line. */
@media (max-width: 767px) {
	.rsdf-bw__head {
		height: auto;
		min-height: 78px;
	}
}

.rsdf-bw__eyebrow {
	margin: 0;
	font-family: var(--bw-font-ui);
	font-size: 0.75rem;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	opacity: 0.8;
}

/* The side panel's eyebrow doubles as the place the "what's still missing"
   message is shown. As a sentence rather than a label it drops the uppercase
   treatment, so it reads as guidance instead of a heading. */
/*
 * Every eyebrow is one style — the same uppercase label whether it's saying
 * "Select a date" or telling you what to do next. Guidance that changes its
 * typeface to speak up reads as an error message; keeping it in the label's own
 * voice keeps the card calm.
 *
 * Single line on desktop, where the head's height is fixed. The JS mirrors the
 * text into a title attribute so a clipped message is still readable.
 */
@media (min-width: 768px) {
	.rsdf-bw__eyebrow {
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}
}

/* Margins are zero throughout the head — spacing comes from its flex gap, so
   both sides space out identically. */
.rsdf-bw__month {
	display: block;
	font-size: 1.1rem;
	font-weight: 500;
	margin: 0;
	line-height: 1.25;
	/* One line only. A long date wrapping would push the head off its fixed
	   height and reintroduce the step. */
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.rsdf-bw__monthnav {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	margin: 0;
}

.rsdf-bw__monthnav .rsdf-bw__month {
	margin-top: 0;
	text-align: center;
	flex: 1 1 auto;
}

.rsdf-bw__navbtn {
	flex: 0 0 auto;
	width: 30px;
	height: 30px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: 1px solid rgba(255, 255, 255, 0.35);
	border-radius: 50%;
	background: transparent;
	color: inherit;
	font-size: 1.1rem;
	line-height: 1;
	transition: background-color 160ms var(--bw-ease);
}

.rsdf-bw__navbtn:hover:not(:disabled) { background: rgba(255, 255, 255, 0.15); }

.rsdf-bw__navbtn:disabled {
	opacity: 0.3;
	cursor: not-allowed;
}

/* ── Calendar grid ───────────────────────────────────────────────────────── */

.rsdf-bw__body { padding: 20px 24px 8px; }

/* Fills the panel and lets its own children handle the scrolling, so the box
   is a constant height whatever is inside it. */
.rsdf-bw__body--fill {
	flex: 1 1 auto;
	min-height: 0;
	display: flex;
	flex-direction: column;
	padding-bottom: 20px;
}

/* The calendar always renders six week rows (JS pads the trailing cells), so a
   five-row month doesn't make the whole widget shorter. Combined with the panels
   sharing a grid row, this is what keeps the depth fixed as you click around. */
.rsdf-bw__grid {
	display: grid;
	grid-template-columns: repeat(7, 1fr);
	grid-auto-rows: 38px;
	gap: 6px;
	font-family: var(--bw-font-ui);
	font-size: 0.85rem;
	text-align: center;
	color: var(--bw-green-dark);
}

.rsdf-bw__daylabel {
	font-weight: 700;
	opacity: 0.6;
	font-size: 0.7rem;
	padding: 4px 0;
}

.rsdf-bw__day {
	appearance: none;
	border: none;
	background: transparent;
	color: inherit;
	font: inherit;
	padding: 8px 0;
	border-radius: 8px;
	transition: background-color 160ms var(--bw-ease), color 160ms var(--bw-ease);
}

.rsdf-bw__day--empty { visibility: hidden; }

.rsdf-bw__day[aria-disabled="true"] {
	opacity: 0.32;
	cursor: not-allowed;
	text-decoration: line-through;
	text-decoration-thickness: 1px;
}

/* Hover is gated behind (hover: hover) so it never sticks on a touch device
   after a tap — and it explicitly excludes the selected day. Both rules are the
   same specificity, so without the :not() the later one silently wins and the
   chosen date renders white-on-10%-grey. Mobile is the primary surface here,
   which is exactly where that failure would have shipped. */
@media (hover: hover) {
	.rsdf-bw__day:not([aria-disabled="true"]):not([aria-selected="true"]):hover {
		background: rgba(51, 59, 48, 0.1);
	}
}

.rsdf-bw__day[aria-selected="true"] {
	background: var(--bw-green-dark);
	color: var(--bw-white);
	font-weight: 600;
}

/* Today gets a marker that isn't colour alone (§15.3). */
.rsdf-bw__day--today { box-shadow: inset 0 0 0 1px rgba(51, 59, 48, 0.45); }
.rsdf-bw__day--today[aria-selected="true"] { box-shadow: none; }

/* The old .rsdf-bw__hint paragraph below the grid is gone — the calendar's
   eyebrow carries that message now, so there's one line of guidance in one
   place rather than a label and a hint saying much the same thing. */

/* ── Length + dogs, one row ──────────────────────────────────────────────── */

.rsdf-bw__choices {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 16px;
	flex: 0 0 auto;
}

.rsdf-bw__choicegroup {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

/* Separates the two groups without needing visible legends — the pill labels
   ("1 hour", "1–4 dogs") already say what they are. */
.rsdf-bw__choicedivider {
	width: 1px;
	align-self: stretch;
	min-height: 24px;
	background: rgba(51, 59, 48, 0.2);
	margin-inline: 4px;
}

.rsdf-bw__duration {
	appearance: none;
	border: 1px solid rgba(51, 59, 48, 0.25);
	background: transparent;
	color: var(--bw-green-dark);
	font-family: var(--bw-font-ui);
	font-size: 0.8rem;
	padding: 7px 16px;
	border-radius: 999px;
	transition: background-color 160ms var(--bw-ease), border-color 160ms var(--bw-ease), color 160ms var(--bw-ease);
}

.rsdf-bw__duration[aria-checked="true"] {
	background: var(--bw-green-dark);
	border-color: var(--bw-green-dark);
	color: var(--bw-white);
}

/* ── Time list ───────────────────────────────────────────────────────────── */

/* Takes whatever height is left and scrolls internally, rather than growing the
   widget. This is the other half of the fixed-depth behaviour. */
.rsdf-bw__times {
	display: flex;
	flex-direction: column;
	gap: 6px;
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	/*
	 * overflow-y:auto makes overflow-x 'auto' too, so this box clips its own
	 * edges — which was slicing the orange focus ring off the sides and top of
	 * whichever field had focus. The padding gives the ring (3px, offset 2px)
	 * room inside the clip, and the matching negative margin puts the content
	 * back exactly where it was, borrowing from the body's own 24px gutter.
	 */
	padding: 6px;
	margin: -6px;
}

.rsdf-bw__slot {
	appearance: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	width: 100%;
	text-align: left;
	border: 1px solid rgba(51, 59, 48, 0.18);
	background: var(--bw-white);
	color: var(--bw-green-dark);
	font-family: var(--bw-font-ui);
	font-size: 0.9rem;
	padding: 11px 16px;
	border-radius: 10px;
	transition: background-color 160ms var(--bw-ease), border-color 160ms var(--bw-ease), color 160ms var(--bw-ease);
}

@media (hover: hover) {
	.rsdf-bw__slot:not([aria-disabled="true"]):not([aria-selected="true"]):hover { border-color: var(--bw-green-dark); }
	.rsdf-bw__duration:not([aria-checked="true"]):hover { border-color: var(--bw-green-dark); }
}

.rsdf-bw__slot[aria-selected="true"] {
	background: var(--bw-orange);
	border-color: var(--bw-orange);
	color: var(--bw-white);
}

/* Taken slots are shown, not hidden — a visibly busy field reads as a desirable
   one, and it stops the calendar looking broken on a popular Saturday (§6.2). */
.rsdf-bw__slot[aria-disabled="true"] {
	background: var(--bw-grey);
	border-color: transparent;
	color: rgba(28, 28, 26, 0.55);
	cursor: not-allowed;
}

.rsdf-bw__slotstate {
	font-size: 0.72rem;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	opacity: 0.75;
}

.rsdf-bw__empty {
	margin: 0;
	padding: 16px 0;
	font-size: 0.85rem;
	opacity: 0.75;
}

/* ── Confirm view ────────────────────────────────────────────────────────── */

.rsdf-bw__scroll {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	/*
	 * overflow-y:auto makes overflow-x 'auto' too, so this box clips its own
	 * edges — which was slicing the orange focus ring off the sides and top of
	 * whichever field had focus. The padding gives the ring (3px, offset 2px)
	 * room inside the clip, and the matching negative margin puts the content
	 * back exactly where it was, borrowing from the body's own 24px gutter.
	 */
	padding: 6px;
	margin: -6px;
}

.rsdf-bw__subhead {
	margin: 0 0 8px;
	font-size: 0.8rem;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	opacity: 0.7;
}

.rsdf-bw__advisory p {
	margin: 0 0 12px;
	font-size: 0.85rem;
	line-height: 1.5;
}

.rsdf-bw__consent {
	border-top: 1px solid rgba(51, 59, 48, 0.12);
	padding-top: 14px;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.rsdf-bw__check {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	font-size: 0.85rem;
	line-height: 1.4;
	cursor: pointer;
}

.rsdf-bw__check input {
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	margin: 0;
	accent-color: var(--bw-green-dark);
	cursor: pointer;
}

/*
 * "Please tick the box(es) above to continue" belongs directly beneath the
 * boxes it's talking about, not stranded under the CTA in the footer where it
 * reads as a caption for the button.
 */
.rsdf-bw__consenthelp {
	margin: 12px 0 0;
	font-size: 0.78rem;
	line-height: 1.35;
	color: var(--bw-green-dark);
	opacity: 0.8;
}

.rsdf-bw__consenthelp[hidden] { display: none; }

/*
 * Inline link inside a consent label — a button, not an anchor, because it
 * opens a dialog rather than going anywhere. Styled as a link because that's
 * what it reads as, and underlined rather than coloured so it doesn't depend on
 * colour alone to be recognisable (§15.3).
 */
.rsdf-bw__inlinelink {
	appearance: none;
	border: 0;
	background: none;
	padding: 0;
	margin: 0;
	font: inherit;
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
	text-decoration-thickness: 1px;
	cursor: pointer;
}

.rsdf-bw__inlinelink:hover { text-decoration-thickness: 2px; }

/* ── Sign-in panel (pay step) ──────────────────────────────────────────── */

.rsdf-bw__account { margin-bottom: 14px; }

.rsdf-bw__accountprompt {
	font-size: 0.8rem;
	line-height: 1.4;
	margin: 0;
	padding: 10px 12px;
	background: rgba(51, 59, 48, 0.05);
	border-radius: 8px;
}

.rsdf-bw__accountprompt[hidden] { display: none; }

.rsdf-bw__signinform {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: 12px;
	background: rgba(51, 59, 48, 0.05);
	border-radius: 8px;
}

.rsdf-bw__signinform[hidden] { display: none; }

.rsdf-bw__signinactions {
	display: flex;
	align-items: center;
	gap: 14px;
}

.rsdf-bw__signinsubmit {
	appearance: none;
	border: 1px solid var(--bw-green-dark);
	background: transparent;
	color: var(--bw-green-dark);
	border-radius: 8px;
	padding: 8px 14px;
	font: inherit;
	font-size: 0.82rem;
	font-weight: 600;
	cursor: pointer;
}

.rsdf-bw__signinsubmit:hover { background: rgba(51, 59, 48, 0.08); }

.rsdf-bw__signinsubmit:disabled {
	opacity: 0.6;
	cursor: default;
}

.rsdf-bw__signinmsg {
	font-size: 0.76rem;
	line-height: 1.4;
	margin: 0;
	opacity: 0.85;
}

.rsdf-bw__signinmsg[hidden] { display: none; }

.rsdf-bw__back {
	appearance: none;
	border: none;
	background: transparent;
	color: inherit;
	font-family: var(--bw-font-ui);
	font-size: 0.8rem;
	padding: 12px 0 0;
	text-align: left;
	align-self: flex-start;
	text-decoration: underline;
	text-underline-offset: 3px;
	flex: 0 0 auto;
}

/* ── Payment step ────────────────────────────────────────────────────────── */

/*
 * Tightened deliberately. This panel scrolls, and every pixel saved here is a
 * pixel of Stripe's element visible without scrolling — so the spacing is as
 * close as it can get while the tap targets stay a comfortable size.
 */
.rsdf-bw__fields {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin-bottom: 12px;
}

.rsdf-bw__field { display: block; }

.rsdf-bw__field > span {
	display: block;
	font-size: 0.76rem;
	font-weight: 600;
	margin-bottom: 3px;
	color: var(--bw-green-dark);
}

.rsdf-bw__field input {
	width: 100%;
	padding: 9px 12px;
	border: 1px solid rgba(51, 59, 48, 0.25);
	border-radius: 8px;
	font-family: var(--bw-font-ui);
	font-size: 0.9rem;
	background: var(--bw-white);
	color: var(--bw-ink, #1C1C1A);
}

/* iOS Safari zooms the whole page when a field under 16px takes focus, which on
   a booking form mid-checkout is thoroughly disorienting. Mobile is the primary
   surface here, so the fields go full size there. */
@media (max-width: 767px) {
	.rsdf-bw__field input { font-size: 16px; }
}

.rsdf-bw__field small {
	display: block;
	margin-top: 3px;
	font-size: 0.72rem;
	opacity: 0.7;
	line-height: 1.35;
}

.rsdf-bw__card { margin-bottom: 10px; }

.rsdf-bw__paynote {
	margin: 0 0 8px;
	font-size: 0.75rem;
	opacity: 0.75;
	line-height: 1.4;
}

.rsdf-bw__payerror {
	margin: 0;
	padding: 10px 12px;
	border-radius: 8px;
	background: #fdeeea;
	color: #8a2b0d;
	font-size: 0.82rem;
}

.rsdf-bw__payerror[hidden] { display: none; }

/* Reassurance by default, urgency only at the end (and never colour alone —
   the wording changes too). */
.rsdf-bw__hold {
	margin: 10px 0 0;
	font-size: 0.78rem;
	opacity: 0.72;
	display: flex;
	align-items: center;
	gap: 6px;
}

.rsdf-bw__hold:empty { display: none; }

.rsdf-bw__hold::before {
	content: '';
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: currentColor;
	flex-shrink: 0;
	opacity: 0.55;
}

.rsdf-bw__hold.is-urgent {
	opacity: 1;
	color: #8a2b0d;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

/* ── Confirmation ────────────────────────────────────────────────────────── */

.rsdf-bw__doneline {
	margin: 0 0 10px;
	font-size: 0.88rem;
	line-height: 1.5;
}

.rsdf-bw__donebig {
	margin: 0 0 14px;
	font-size: 1.4rem;
	letter-spacing: 0.02em;
}

.rsdf-bw__donelabel {
	display: block;
	font-size: 0.72rem;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	opacity: 0.65;
	margin-bottom: 2px;
}

/* ── Footer ──────────────────────────────────────────────────────────────── */

.rsdf-bw__foot {
	grid-column: 1 / -1;
	grid-row: 2;
	display: flex;
	align-items: center;
	gap: 16px;
	flex-wrap: wrap;
	padding: 16px 24px 22px;
	border-top: 1px solid rgba(51, 59, 48, 0.1);
}

/*
 * Reserved depth. The summary line and price appear only once a date is
 * chosen, and the summary can run to two lines on a long slot label — without
 * a floor here the footer grows the moment you click a date, which on the
 * vertically-centred homepage hero made the whole card jump. Mobile is excluded
 * (full-width CTA on its own row makes a fixed height wrong there).
 */
@media (min-width: 768px) {
	.rsdf-bw__foot { min-height: 96px; }
}

.rsdf-bw__summarywrap {
	flex: 1 1 180px;
	min-width: 0;
	/* Two lines of summary + the price, always — so filling it in doesn't
	   change the footer's height. */
	min-height: 3.1em;
}

.rsdf-bw__summary {
	margin: 0;
	font-size: 0.85rem;
	color: var(--bw-green-dark);
}

.rsdf-bw__price {
	margin: 2px 0 0;
	font-size: 1.15rem;
	font-weight: 600;
	color: var(--bw-green-dark);
}

.rsdf-bw__price:empty { display: none; }

.rsdf-bw__cta {
	appearance: none;
	border: none;
	flex: 0 0 auto;
	background: var(--bw-orange);
	color: var(--bw-white);
	font-family: var(--bw-font-ui);
	text-transform: uppercase;
	font-size: 0.85rem;
	letter-spacing: 0.03em;
	padding: 0.9em 1.8em;
	border-radius: 999px;
	transition: transform var(--bw-duration) var(--bw-ease), background-color var(--bw-duration) var(--bw-ease);
}

.rsdf-bw__cta:hover:not(:disabled) { transform: translateY(-1px); }

/* The disabled state has to be obviously disabled and say why — never silently
   inert (§6.4). The reason is shown in the panel it applies to (the side
   panel's head, under the consent boxes, under the contact fields) rather than
   beside the button; .rsdf-bw__ctahelp carries the same text for assistive
   technology only. */
.rsdf-bw__cta:disabled {
	background: var(--bw-grey);
	color: rgba(28, 28, 26, 0.5);
	cursor: not-allowed;
}

/*
 * The reason the CTA is disabled is now shown in the panel it applies to — in
 * the side panel's own head while choosing a slot, under the consent boxes
 * while confirming, under the contact fields while paying. This element stays
 * in the DOM purely as the CTA's aria-describedby target, so the same reason is
 * still announced to a screen reader on focus; it is never visible.
 */
.rsdf-bw__ctahelp {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* ── Document dialog ─────────────────────────────────────────────────────── */
/* Vaccination policy / terms, read without leaving a half-finished booking. */

.rsdf-bw__modal {
	width: min(560px, calc(100vw - 40px));
	max-height: min(70vh, 620px);
	padding: 0;
	border: 0;
	border-radius: 18px;
	background: var(--bw-cream);
	color: var(--rsdf-ink, #1C1C1A);
	box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
	overflow: hidden;
	/* The dialog is a child of the widget, which is inside a transformed
	   parallax section — so it's laid out against that, not the viewport.
	   Flex on the element itself keeps the head fixed and the body scrolling. */
	flex-direction: column;
}

.rsdf-bw__modal[open] { display: flex; }

.rsdf-bw__modal::backdrop {
	background: rgba(28, 28, 26, 0.55);
}

.rsdf-bw__modalhead {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	flex: 0 0 auto;
	padding: 16px 20px;
	background: var(--bw-green-dark);
	color: var(--bw-white);
}

.rsdf-bw__modaltitle {
	margin: 0;
	font-family: var(--bw-font-ui);
	font-size: 1rem;
	font-weight: 500;
}

.rsdf-bw__modalclose {
	appearance: none;
	flex: 0 0 auto;
	width: 32px;
	height: 32px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: 1px solid rgba(255, 255, 255, 0.35);
	border-radius: 50%;
	background: transparent;
	color: inherit;
	font-size: 1.3rem;
	line-height: 1;
	transition: background-color 160ms var(--bw-ease);
}

.rsdf-bw__modalclose:hover { background: rgba(255, 255, 255, 0.15); }

.rsdf-bw__modalbody {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 20px;
	font-size: 0.88rem;
	line-height: 1.55;
}

.rsdf-bw__modalbody > *:first-child { margin-top: 0; }
.rsdf-bw__modalbody > *:last-child { margin-bottom: 0; }

/* ── Mobile ──────────────────────────────────────────────────────────────── */
/* Same expansion, run on rows instead of columns — the panel drops beneath the
   calendar rather than beside it. Mobile is the primary surface for this flow. */

@media (max-width: 767px) {
	.rsdf-bw,
	.rsdf-bw.is-expanded {
		max-width: none;
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: auto 0fr auto;
		transition: grid-template-rows var(--bw-duration) var(--bw-ease);
	}

	.rsdf-bw.is-expanded { grid-template-rows: auto 1fr auto; }

	.rsdf-bw__panel--calendar { grid-column: 1; grid-row: 1; }

	.rsdf-bw__panel--side {
		grid-column: 1;
		grid-row: 2;
		border-left: none;
		border-top: 1px solid rgba(51, 59, 48, 0.12);
	}

	.rsdf-bw__panel--side > .rsdf-bw__view { min-width: 0; }

	.rsdf-bw__foot { grid-column: 1; grid-row: 3; }

	/* On mobile the panel sits below the calendar rather than beside it, so
	   there's no column height to match — give the scrolling areas an explicit
	   cap instead, still constant between dates. */
	.rsdf-bw__times,
	.rsdf-bw__scroll { max-height: 260px; }

	.rsdf-bw__cta { width: 100%; }
}

/* ── Reduced motion ──────────────────────────────────────────────────────── */
/* Panels appear instantly — no transform, no fade (§5.4). */

@media (prefers-reduced-motion: reduce) {
	.rsdf-bw,
	.rsdf-bw__view,
	.rsdf-bw__cta,
	.rsdf-bw__day,
	.rsdf-bw__slot,
	.rsdf-bw__duration {
		transition: none !important;
	}
	.rsdf-bw__view { transform: none; }
}
