/*
 * Booking Suite — public-facing form styles.
 *
 * Mobile-first. CSS Grid for layout. Container queries adapt the layout to
 * whichever element actually hosts the form (so two shortcodes side-by-side
 * each get their own ideal layout).
 *
 * Design tokens are declared on :root so admin + frontend share the same
 * palette. This file is self-bootstrapping when loaded standalone (public-only
 * contexts); when loaded inside an admin page, admin.css overrides take
 * precedence in cascade order.
 *
 * 1.6.0: dropped the .bs-cal* month-view calendar + .bs-slots grid (1.4.6 era)
 * and replaced them with a CTA button + <dialog> modal containing iOS-style
 * vertical scroll wheels (.bs-wheel) for date + time selection. The inline
 * fallback form for no-JS / modal-blocked visitors reuses the .bs-form shell.
 *
 * @package Booking_Suite
 */

:root {
	--bs-radius:        10px;
	--bs-pad:           16px;
	--bs-gap:           14px;
	--bs-accent:        #3b4cf6;
	--bs-accent-contrast: #ffffff;
	--bs-muted:         #5a6470;
	--bs-border:        rgba(0, 0, 0, 0.10);
	--bs-bg:            #ffffff;
	--bs-input-bg:      #f5f7fb;
	--bs-text:          #1f2530;
	--bs-text-muted:    #5a6470;
	--bs-surface:       #ffffff;
	--bs-surface-2:     #f8f9fb;
	--bs-success-bg:    #e6f4ea;
	--bs-success-fg:    #1a6b34;
	--bs-error-bg:      #fdecec;
	--bs-error-fg:      #842323;
	--bs-error-text:    #d23547;
	--bs-info-bg:       #eef2ff;
	--bs-info-fg:       #20306c;
	--bs-shadow:        0 1px 2px rgba(0,0,0,0.04), 0 4px 12px rgba(0,0,0,0.04);
	--bs-shadow-lift:   0 4px 12px rgba(0,0,0,0.06), 0 18px 40px rgba(0,0,0,0.08);
	--bs-font:          ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	--bs-font-wheel:    var(--bs-font);
	/* 1.6.8: removed — the v1.6.5-1.6.7 iOS white-on-slate scroller has been
	   replaced wholesale by the teal-vibe picker. The wheel now ships its
	   own colours (teal gradient bg + cyan #00ffd1 glow + per-column
	   overlays, 200px / 40px) — there are no `--bs-wheel-*` vars anymore.

	   1.6.5-1.6.7 had `--bs-wheel-row-h` (280px) + `--bs-wheel-option-h`
	   (56px) for sizing and `--bs-wheel-bg-edge/mid/text-default/selected/
	   band-bg/band-border` for colouring. The new picker hard-codes the
	   dimensions in the `.bs-wheel` rule below and renders its own colours
	   via `.bs-wheel[data-bs-wheel="…"]` + `.bs-wheel__option.active` etc.
	   Operators who want a different look can override those selectors
	   directly. */
}

@media (prefers-color-scheme: dark) {
	:root {
		--bs-bg:         #15171c;
		--bs-surface:    #15171c;
		--bs-surface-2:  #1d2129;
		--bs-input-bg:   #1d2129;
		--bs-text:       #e4e8ef;
		--bs-muted:      #a4adba;
		--bs-text-muted: #a4adba;
		--bs-border:     rgba(255, 255, 255, 0.08);
		--bs-shadow:     0 1px 2px rgba(0,0,0,0.4), 0 4px 12px rgba(0,0,0,0.4);
		--bs-shadow-lift:0 4px 12px rgba(0,0,0,0.5), 0 18px 48px rgba(0,0,0,0.55);
		--bs-success-bg: #142a1d;
		--bs-success-fg: #6ddb94;
		--bs-error-bg:   #2a1416;
		--bs-error-fg:   #ff8a96;
		--bs-error-text: #ff6675;
		--bs-info-bg:    #1c2233;
		--bs-info-fg:    #c8d2ec;
	}
}

/* 1.8.0: cyan #00ffd1 / dark-teal aesthetic for both booking forms (modal +
   fallback). Scoped via :is(.bs-form--modal, .bs-form--fallback) (specificity
   0,1,0) so the token cascade wins over the operator's `:where(.bs-form){...}`
   default that Settings → Styling emits inline in the page head (specificity
   0,0,0 + later cascade position). Both forms now share the same palette —
   JS-enabled visitors see the modal dialog with the iOS picker in step 1,
   JS-disabled visitors see the inline form with native `<input type="date">`
   in step 1, but step 2 (prospect fields + submit) looks identical. Operator
   custom values still cascade via the same `:where(.bs-form)` block (both
   forms carry `.bs-form`). */
:is(.bs-form--modal, .bs-form--fallback) {
	--bs-accent:          var(--bs-picker-accent,    #00ffd1);
	--bs-accent-contrast: var(--bs-picker-contrast, #0f2027);
	--bs-bg:              var(--bs-picker-contrast, #0f2027);
	--bs-surface:         var(--bs-picker-contrast, #0f2027);
	--bs-surface-2:       #143040;
	--bs-input-bg:        #143040;
	--bs-text:            #e6f7f5;
	--bs-text-muted:      #8da4b0;
	--bs-muted:           #8da4b0;
	--bs-border:          color-mix(in oklab, var(--bs-picker-accent, #00ffd1) 18%, transparent);
	--bs-info-bg:         color-mix(in oklab, var(--bs-picker-accent, #00ffd1)  8%, transparent);
	--bs-info-fg:         var(--bs-picker-accent, #00ffd1);
	--bs-error-bg:        rgba(255, 75, 75, 0.12);
	--bs-error-fg:        #ff8080;
	--bs-error-text:      #ff8080;
	--bs-success-bg:      color-mix(in oklab, var(--bs-picker-accent, #00ffd1) 12%, transparent);
	--bs-success-fg:      var(--bs-picker-accent, #00ffd1);
	--bs-shadow:          0 4px 16px rgba(0, 0, 0, 0.45), 0 1px 0 color-mix(in oklab, var(--bs-picker-accent, #00ffd1) 15%, transparent) inset;
	--bs-shadow-lift:     0 8px 24px rgba(0, 0, 0, 0.55), 0 18px 48px color-mix(in oklab, var(--bs-picker-accent, #00ffd1) 12%, transparent);
}

/* 1.8.0.4 + 1.8.0.6: explicit input + label rules for both forms. `.bs-input`
   alone has specificity (0,1,0) and loses to Divi theme's `input[type="text"]`
   (specificity (0,1,1) — `input` + `[type="text"]`), which painted text
   fields white with a gray border. `.bs-label` had no color set so it
   inherited the dark `--bs-text` (#1f2530) once the operator's
   `:where(.bs-form)` inline style reset it. The rules below use
   `:is(.bs-form--modal, .bs-form--fallback) .bs-input` (specificity (0,2,0))
   to win the cascade for fields in BOTH forms — step 2 of the modal AND
   the entire fallback form. */
/* `body ` prefix bumps specificity to (0,3,0) so Divi's input[type="text"]
   (0,1,1) and any later cascade override lose the colour battle even when
   the operator's `--bs-input-bg` and `--bs-text` happen to be similar. */
body :is(.bs-form--modal, .bs-form--fallback) .bs-input,
body :is(.bs-form--modal, .bs-form--fallback) textarea.bs-input {
	background-color: var(--bs-input-bg);
	color:            var(--bs-text);
	border:           1.5px solid transparent;
	caret-color:      var(--bs-text);
}
body :is(.bs-form--modal, .bs-form--fallback) .bs-input::placeholder,
body :is(.bs-form--modal, .bs-form--fallback) textarea.bs-input::placeholder {
	color: var(--bs-text-muted);
	opacity: 1;
}
body :is(.bs-form--modal, .bs-form--fallback) .bs-input:focus {
	border-color: var(--bs-accent);
}
:is(.bs-form--modal, .bs-form--fallback) .bs-label {
	color: var(--bs-text);
}
:is(.bs-form--modal, .bs-form--fallback) .bs-form__title {
	color: var(--bs-text);
}
:is(.bs-form--modal) .bs-modal__title,
:is(.bs-form--modal) .bs-step__title {
	color: var(--bs-text);
}
:is(.bs-form--modal) .bs-modal__close {
	color: var(--bs-text-muted);
}

:is(.bs-form--modal, .bs-form--fallback) .bs-radio input[type="radio"] { accent-color: var(--bs-picker-accent, #00ffd1); }
:is(.bs-form--modal) .bs-modal { border: 1px solid color-mix(in oklab, var(--bs-picker-accent, #00ffd1) 25%, transparent); }

.bs-form {
	font-family: var(--bs-font);
	color: var(--bs-text);
	background: var(--bs-bg);
	border: 1px solid var(--bs-border);
	border-radius: var(--bs-radius);
	box-shadow: var(--bs-shadow);
	padding: var(--bs-pad);
	max-width: 720px;
	margin: 0 auto;
	box-sizing: border-box;
}

.bs-form *,
.bs-form *::before,
.bs-form *::after {
	box-sizing: inherit;
}

.bs-form__title {
	margin: 0 0 0.4em;
	font-size: clamp(1.4rem, 1.1rem + 1.6vw, 1.95rem);
	font-weight: 600;
	line-height: 1.2;
}

.bs-form__intro {
	color: var(--bs-muted);
	margin: 0 0 var(--bs-gap);
	font-size: 1rem;
}

.bs-form__steps {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--bs-gap);
}

.bs-step__title {
	margin: 0 0 calc(var(--bs-gap) * 0.75);
	font-size: 1.1rem;
	font-weight: 600;
}

/* 1.10.0.27: defensive kill for any stray leading digit. The hardcoded
   '1.' / '2.' was already stripped in v1.10.0.23 (commit 35cf913), but
   a theme or future refactor could re-introduce one via `::before`. */
.bs-step__title::before {
	content: none;
}

.bs-step__title--success {
	color: var(--bs-accent);
}

/* 1.6.3: Cloudflare Turnstile widget. The iframe sizes itself once rendered
   (~300×65px); the explicit min-height prevents layout jump while the
   challenges.cloudflare.com script loads. */
.bs-turnstile {
	margin: 12px 0 4px;
	min-height: 65px;
}

.bs-form__notice,
.bs-fallback__notice {
	background: var(--bs-info-bg);
	color: var(--bs-info-fg);
	border: 1px solid color-mix(in oklab, var(--bs-accent) 32%, transparent);
	border-radius: var(--bs-radius);
	padding: 10px 14px;
	margin: 0 0 var(--bs-gap);
	font-size: 0.9rem;
}

/* Inputs ------------------------------------------------------------- */

.bs-label {
	display: block;
	font-weight: 500;
	margin: var(--bs-gap) 0 4px;
	font-size: 0.94rem;
}

.bs-label--inline {
	display: inline-block;
	margin-right: 8px;
}

.bs-req {
	color: var(--bs-error-text);
	margin-left: 2px;
}

.bs-input {
	display: block;
	width: 100%;
	font: inherit;
	padding: 11px 14px;
	background: var(--bs-input-bg);
	border: 1.5px solid transparent;
	border-radius: var(--bs-radius);
	color: inherit;
	transition: border-color 0.15s ease, background 0.15s ease;
}

.bs-input:focus {
	outline: 3px solid color-mix(in oklab, var(--bs-accent) 30%, transparent);
	outline-offset: 1px;
	border-color: var(--bs-accent);
	background: var(--bs-bg);
}

.bs-input[aria-invalid="true"] {
	border-color: var(--bs-error-text);
	background: var(--bs-error-bg);
}

textarea.bs-input {
	resize: vertical;
	min-height: 96px;
}

/* CTA button (modal trigger) ---------------------------------------- */

.bs-cta {
	appearance: none;
	font: inherit;
	font-weight: 600;
	font-size: 1.05rem;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 14px 24px;
	margin: 0 auto var(--bs-gap);
	background: var(--bs-accent);
	color: var(--bs-accent-contrast);
	border: none;
	border-radius: 999px;
	cursor: pointer;
	box-shadow: var(--bs-shadow);
	transition: transform 0.12s ease, box-shadow 0.15s ease, background 0.15s ease;
	text-align: left;
	max-width: 720px;
	width: 100%;
	justify-content: center;
}

.bs-cta:hover,
.bs-cta:focus-visible {
	background: color-mix(in oklab, var(--bs-accent) 88%, black);
	transform: translateY(-1px);
	box-shadow: var(--bs-shadow-lift);
	outline: none;
}

.bs-cta:focus-visible {
	outline: 3px solid color-mix(in oklab, var(--bs-accent) 30%, transparent);
	outline-offset: 2px;
}

.bs-cta__icon {
	font-size: 1.2rem;
	line-height: 1;
}

/* Modal dialog ------------------------------------------------------ */

body.bs-modal-open {
	overflow: hidden;
}

.bs-modal {
	padding: 0;
	border: 1px solid var(--bs-border);
	border-radius: var(--bs-radius);
	background: var(--bs-surface);
	color: var(--bs-text);
	box-shadow: var(--bs-shadow-lift);
	max-width: min(560px, 96vw);
	max-height: 92vh;
	width: 100%;
	margin: auto;
	overflow: hidden;
}

.bs-modal::backdrop {
	background: rgba(0, 0, 0, 0.55);
	-webkit-backdrop-filter: blur(4px);
	backdrop-filter: blur(4px);
}

.bs-modal[open] {
	display: flex;
	flex-direction: column;
	animation: bs-modal-in 180ms ease-out;
}

@keyframes bs-modal-in {
	from { opacity: 0; transform: translateY(8px) scale(0.98); }
	to   { opacity: 1; transform: none; }
}

.bs-modal__title {
	margin: 0;
	padding: 18px 20px 8px;
	font-size: 1.15rem;
	font-weight: 600;
}

.bs-modal__close {
	position: absolute;
	top: 10px;
	right: 12px;
	appearance: none;
	background: transparent;
	border: 1.5px solid transparent;
	color: var(--bs-text-muted);
	width: 36px;
	height: 36px;
	border-radius: 999px;
	font-size: 1.4rem;
	line-height: 1;
	cursor: pointer;
	transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.bs-modal__close:hover,
.bs-modal__close:focus-visible {
	background: color-mix(in oklab, var(--bs-accent) 8%, transparent);
	color: var(--bs-text);
	border-color: var(--bs-border);
	outline: none;
}

.bs-modal__close:focus-visible {
	outline: 3px solid color-mix(in oklab, var(--bs-accent) 30%, transparent);
	outline-offset: 2px;
}

.bs-modal .bs-form__steps {
	padding: 8px 20px 20px;
	overflow-y: auto;
	flex: 1;
}

/* 1.8.0: the v1.6.8 teal-vibe scroller (.bs-wheels / .bs-wheel /
   .bs-wheel__option / per-column tints / band / colon separator / container
   queries / @supports fallback) is gone — step 1 of the modal now embeds
   the iOS picker widget (assets/css/ios-picker.css), which ships its own
   styles. The .bs-summary pill below remains: it's used by both step 2 of
   the modal (showing the picked date+time with a back link) and the
   fallback form's success notice. */

/* Inline ghost link (Back to date / Book another) ----------------- */

.bs-link {
	appearance: none;
	background: none;
	border: none;
	padding: 0;
	margin: 8px 0 0;
	color: var(--bs-accent);
	font: inherit;
	font-weight: 500;
	cursor: pointer;
	text-decoration: none;
}

.bs-link:hover {
	text-decoration: underline;
}

/* Contact-step summary (picked day + time + back link) -------------- */

.bs-summary {
	display: flex;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
	background: var(--bs-info-bg);
	color: var(--bs-info-fg);
	border: 1px solid color-mix(in oklab, var(--bs-accent) 32%, transparent);
	border-radius: var(--bs-radius);
	padding: 10px 14px;
	margin: 0 0 var(--bs-gap);
	font-size: 0.95rem;
}

.bs-summary .bs-link {
	color: var(--bs-info-fg);
	margin: 0;
}

/* Fieldset (contact methods) ---------------------------------------- */

.bs-fieldset {
	border: 1px solid var(--bs-border);
	border-radius: var(--bs-radius);
	padding: 12px 16px;
	margin: var(--bs-gap) 0;
}

.bs-fieldset > legend {
	padding: 0 6px;
	font-weight: 600;
}

.bs-radio {
	display: inline-flex;
	gap: 8px;
	align-items: center;
	margin-right: 18px;
	margin-block: 6px;
}

/* Buttons ----------------------------------------------------------- */

.bs-button {
	appearance: none;
	border: 1.5px solid transparent;
	border-radius: var(--bs-radius);
	font: inherit;
	font-weight: 600;
	padding: 12px 18px;
	margin-top: 12px;
	cursor: pointer;
	transition: background 0.15s ease, border-color 0.15s ease;
}

.bs-button--primary {
	background: var(--bs-accent);
	color: var(--bs-accent-contrast);
}

.bs-button--primary:hover {
	background: color-mix(in oklab, var(--bs-accent) 88%, black);
}

.bs-button--ghost {
	background: transparent;
	color: var(--bs-accent);
	border-color: var(--bs-accent);
}

/* Continue button in the modal step 1 — slightly rounded + a little smaller
   than the default .bs-button (12px 18px / radius 10px). */
[data-bs-modal-continue] {
	border-radius: 6px;
	padding: 8px 14px;
	margin-top: 8px;
	font-weight: 600;
}

/* Help + instructional text ------------------------------------------- */

.bs-help {
	color: var(--bs-muted);
	margin: 4px 0 0;
	font-size: 0.9rem;
}

.bs-instructions {
	background: var(--bs-info-bg);
	border: 1px solid color-mix(in oklab, var(--bs-accent) 32%, transparent);
	border-radius: var(--bs-radius);
	padding: 14px 16px;
	margin-top: var(--bs-gap);
	color: var(--bs-info-fg);
	font-size: 0.95rem;
}

/* Error banner ----------------------------------------------------- */

.bs-form__error {
	background: var(--bs-error-bg);
	border: 1px solid color-mix(in oklab, var(--bs-error-text) 32%, transparent);
	color: var(--bs-error-fg);
	padding: 12px 14px;
	border-radius: var(--bs-radius);
	margin-top: var(--bs-gap);
}

/* 1.10.0.28: loud payment-failure banner. Shown when the server returns
   5xx (Stripe start failed, meeting platform not configured, internal
   errors) so the user cannot miss the error while the Turnstile widget
   is also re-firing on the page. */
.bs-form__error--payment {
	background: #fdecea;
	border: 2px solid #c0392b;
	color: #922b21;
	font-weight: 600;
	font-size: 1.05rem;
	padding: 14px 16px;
}

/* Fallback form (no-JS / modal-blocked) --------------------------- */

.bs-form--fallback {
	margin-top: var(--bs-gap);
}

/* Success summary */

.bs-success-body {
	font-size: 1rem;
	color: var(--bs-text);
	margin: 8px 0 16px;
}

.bs-success-body a {
	color: var(--bs-accent);
	text-decoration: underline;
}

/* 1.8.0: keep container-name `bs-form` on both form variants so the
   iOS picker widget's CSS (which still uses `@container bs-form`) keeps
   working — the container is set on each form root, not on the now-gone
   wheel layout. */
.bs-form--modal {
	container-type: inline-size;
	container-name: bs-form;
}

.bs-form--fallback {
	container-type: inline-size;
	container-name: bs-form;
}

/* Reduced-motion respect: zero animation, instant swap. */
@media (prefers-reduced-motion: reduce) {
	.bs-form *,
	.bs-form *::before,
	.bs-form *::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
	.bs-modal[open] {
		animation: none !important;
	}
}

/* Responsive -------------------------------------------------------- */
/* The booking form is already mostly responsive (modal adapts 360→560px,
   fallback inputs are full-width with `width:100%`, radios wrap, submit
   stretches). What changes at ≤ 480px:

   - Modal goes nearly edge-to-edge with hairline gutters + uses `100dvh`
     so it fills the visible viewport on mobile (handles browser chrome
     show/hide correctly — `100vh` would leave a gap when the URL bar
     collapses).
   - Title padding shrinks, font-size steps down to 1.05rem.
   - Form padding steps from 16px to 12px to recover horizontal room.
   - Inputs / buttons get a 44px min-height for iOS HIG touch targets.
   - The submit button becomes full-width so thumbs can hit it without
     precise aim.
   - Fieldset legend font shrinks + radios are allowed to wrap.

   Below 360px (Galaxy Fold cover / older iPhone SE 1st gen) we tighten
   further: 4px gutters on the modal, 10px form padding.

   Container queries are not used here because the dialog / form is the
   whole page on small screens — viewport media queries are simpler and
   work correctly when the dialog is rendered into a third-party theme
   that may itself have a non-responsive wrapper. */

@media (max-width: 480px) {
	.bs-modal {
		max-width: calc(100vw - 8px);
		max-height: calc(100dvh - 8px);
		border-radius: 8px;
	}
	.bs-modal__title {
		padding: 14px 16px 6px;
		font-size: 1.05rem;
	}
	.bs-modal__close {
		top: 8px;
		right: 8px;
		width: 32px;
		height: 32px;
		font-size: 1.25rem;
	}
	.bs-modal .bs-form__steps {
		padding: 6px 16px 16px;
	}
	.bs-form {
		padding: 12px;
	}
	:is(.bs-form--modal, .bs-form--fallback) .bs-input,
	:is(.bs-form--modal, .bs-form--fallback) textarea.bs-input {
		min-height: 44px;
	}
	:is(.bs-form--modal, .bs-form--fallback) .bs-button--primary,
	:is(.bs-form--modal, .bs-form--fallback) .bs-button--ghost {
		width: 100%;
		min-height: 44px;
	}
	.bs-fieldset {
		padding: 10px 14px;
	}
	.bs-fieldset > legend {
		font-size: 0.95rem;
		padding: 0 4px;
	}
	.bs-radio {
		margin-right: 12px;
	}
}

@media (max-width: 360px) {
	.bs-modal {
		max-width: calc(100vw - 4px);
		max-height: calc(100dvh - 4px);
		border-radius: 6px;
	}
	.bs-modal__title {
		padding: 12px 12px 6px;
	}
	.bs-modal .bs-form__steps {
		padding: 6px 12px 14px;
	}
	.bs-modal__close {
		top: 6px;
		right: 6px;
	}
	.bs-form {
		padding: 10px;
	}
}
