/**
 * TOF Boulevard Booking
 *
 * Palette is straight from The Only Facial Brand Guide 2023:
 *   #CD1D57 Rose Red · #F49CB1 Peony · #FCDFE3 Pink Marshmallow
 *   #FEEEF0 pale · #F4F4F4 Snow White · #414042 Black Oyster
 *
 * The guide lists "most shades of blue" under Avoid, so every interactive
 * element sets an explicit color. Unstyled <button> text renders as system
 * blue on iOS, which is where blue was leaking in before.
 */

.tof-blvd {
	--tof-brand: #cd1d57;
	--tof-brand-dark: #a81746;
	--tof-peony: #f49cb1;
	--tof-marshmallow: #fcdfe3;
	--tof-pale: #feeef0;
	--tof-snow: #f4f4f4;
	--tof-ink: #414042;
	--tof-muted: #6f686b;
	--tof-line: #f3d5dd;
	--tof-white: #fff;
	--tof-radius: 10px;

	max-width: 760px;
	margin: 0 auto;
	color: var(--tof-ink);
	font-size: 16px;
	line-height: 1.5;
	text-align: left;

	/* iOS: stop auto-linking of addresses, dates and times into blue text */
	-webkit-text-size-adjust: 100%;
}

.tof-blvd *,
.tof-blvd *::before,
.tof-blvd *::after {
	box-sizing: border-box;
}

/*
 * Every button gets an explicit color — never inherit the UA's blue.
 * :where() keeps this at zero specificity so the variant classes below
 * (.tof-btn--primary in particular) still win. Without that, the white
 * button text was being overridden back to ink.
 */
.tof-blvd :where(button) {
	color: var(--tof-ink);
	font: inherit;
	-webkit-tap-highlight-color: rgba(205, 29, 87, 0.15);
	accent-color: var(--tof-brand);
}

/*
 * :where() for the same reason as the button rule above — at plain specificity
 * this beat .tof-btn--primary, so an <a class="tof-btn tof-btn--primary">
 * rendered brand-pink text on a brand-pink fill. Invisible buttons.
 */
.tof-blvd :where(a) {
	color: var(--tof-brand);
}

.tof-blvd ::selection {
	background: var(--tof-marshmallow);
	color: var(--tof-brand-dark);
}

/* Chrome autofill forces a pale blue field background; this repaints it. */
.tof-blvd input:-webkit-autofill,
.tof-blvd input:-webkit-autofill:hover,
.tof-blvd input:-webkit-autofill:focus {
	-webkit-text-fill-color: var(--tof-ink);
	-webkit-box-shadow: 0 0 0 1000px var(--tof-pale) inset;
	box-shadow: 0 0 0 1000px var(--tof-pale) inset;
	caret-color: var(--tof-ink);
}

.tof-blvd.is-busy {
	opacity: 0.65;
	pointer-events: none;
}

.tof-blvd__boot,
.tof-spinner {
	padding: 32px 0;
	color: var(--tof-muted);
	text-align: center;
}

/* ---------- hero (replaces the theme's page header) ---------- */

.tof-above {
	margin: 0 0 30px;
}

.tof-above[hidden] {
	display: none;
}

/*
 * Full-bleed video hero. Breaks out of the theme's 760px column with the
 * standard 100vw / negative-margin technique — safe here because no ancestor
 * of the widget sets overflow:hidden (checked on the live page).
 *
 * The ground is a deeper rose than the brand pink so the hero reads as its own
 * band rather than merging into the site header directly above it.
 */
.tof-hero {
	--tof-hero-bg: #8b1339;

	position: relative;
	width: 100vw;
	margin-right: calc(50% - 50vw);
	margin-left: calc(50% - 50vw);
	overflow: hidden;
	padding: 64px 24px;
	background: var(--tof-hero-bg);
	color: #fff;
	text-align: center;
}

.tof-hero__video {
	position: absolute;
	z-index: 0;
	top: 50%;
	left: 50%;
	min-width: 100%;
	min-height: 100%;
	transform: translate(-50%, -50%);
	object-fit: cover;
	opacity: 0;
	transition: opacity 0.6s ease;
	pointer-events: none;
}

.tof-hero__video.is-ready {
	opacity: 0.32;
}

.tof-hero__body {
	position: relative;
	z-index: 1;
	max-width: 720px;
	margin: 0 auto;
}

.tof-hero__title {
	margin: 0 0 12px;
	color: #fff;
	font-size: 2.2em;
	line-height: 1.15;
	text-shadow: 0 1px 12px rgba(50, 4, 20, 0.4);
}

.tof-hero__blurb {
	max-width: 34em;
	margin: 0 auto 18px;
	color: #fff;
	font-size: 1.05em;
	opacity: 0.95;
	text-shadow: 0 1px 10px rgba(50, 4, 20, 0.4);
}

.tof-hero__addr {
	margin: 0 0 10px;
	color: #fff;
	font-size: 0.98em;
	line-height: 1.5;
	text-shadow: 0 1px 10px rgba(50, 4, 20, 0.4);
}

.tof-hero__addr a {
	color: #fff;
	text-decoration: none;
	border-bottom: 1px solid rgba(255, 255, 255, 0.5);
}

.tof-hero__addr a:hover {
	border-bottom-color: #fff;
}

/*
 * The call option, kept deliberately quieter than Book now: smaller, lighter,
 * and never styled as a button. It is there for the people who will only ever
 * ring, without pulling anyone out of a flow that works.
 */
.tof-hero__tel {
	margin: 0 0 22px;
	color: rgba(255, 255, 255, 0.85);
	font-size: 0.9em;
	text-shadow: 0 1px 10px rgba(50, 4, 20, 0.4);
}

.tof-blvd .tof-hero__tel :where(a) {
	color: #fff;
	font-weight: 600;
	text-decoration: none;
	border-bottom: 1px solid rgba(255, 255, 255, 0.5);
}

.tof-blvd .tof-hero__tel :where(a):hover {
	border-bottom-color: #fff;
}

.tof-hero .tof-btn--onbrand {
	border-color: #fff;
	background: #fff;
	color: var(--tof-brand);
}

.tof-hero .tof-btn--onbrand:hover {
	border-color: #fff;
	background: var(--tof-pale);
	color: var(--tof-brand-dark);
}

/*
 * Mobile never loads the video, so a still stands in. The overlay keeps the
 * white type legible whatever the photo underneath is doing.
 */
@media (max-width: 767px) {
	.tof-hero[data-has-photo] {
		background-image: var(--tof-hero-img);
		background-position: center;
		background-size: cover;
	}
	.tof-hero[data-has-photo]::before {
		position: absolute;
		z-index: 0;
		background: rgba(139, 19, 57, 0.74);
		content: '';
		inset: 0;
	}
}

@media (max-width: 600px) {
	.tof-hero {
		padding: 44px 20px;
	}
	.tof-hero__title {
		font-size: 1.6em;
	}
}

@media (prefers-reduced-motion: reduce) {
	.tof-hero__video {
		display: none;
	}
}

/*
 * No hero means nothing fills the band the theme's padding used to occupy, so
 * the JS measures where this lands and publishes the correction as --tof-shift.
 * The old rule added the header height unconditionally, on top of the space the
 * theme ALREADY reserves for its fixed header — which is what produced the big
 * empty band. This measures the real landing position instead, so the result is
 * a fixed clearance below the header whatever the theme is doing above it.
 */
.tof-blvd--nohero {
	padding-top: var(--tof-shift, 0px);
}

/*
 * Simple layout: heading, address, widget. Reached from a location page, so the
 * visitor already has the pitch — this exists to get out of their way. Slightly
 * tighter than the landing page, and never full-bleed.
 */
.tof-blvd--simple {
	max-width: 720px;
	padding-bottom: 8px;
}

/* Nothing above the heading to breathe against — keep it tight. */
.tof-blvd--simple .tof-blvd__heading {
	margin-top: 0;
}

.tof-blvd--simple .tof-blvd__heading {
	font-size: 1.45em;
}

.tof-blvd--simple .tof-blvd__loc {
	margin-bottom: 20px;
}

/* ---------- headings & steps ---------- */

.tof-blvd__heading {
	margin: 0 0 4px;
	color: var(--tof-brand);
	font-size: 1.6em;
	line-height: 1.2;
}

.tof-blvd__loc {
	margin: 0 0 18px;
	color: var(--tof-muted);
	font-size: 0.95em;
}

.tof-blvd__sub {
	margin: 0 0 14px;
	color: var(--tof-muted);
}

.tof-link {
	padding: 0 0 0 4px;
	border: 0;
	background: none;
	color: var(--tof-brand);
	font-size: 0.95em;
	text-decoration: underline;
	cursor: pointer;
}

.tof-steps {
	display: flex;
	gap: 6px;
	margin: 0 0 22px;
	padding: 0;
	list-style: none;
}

.tof-step {
	display: flex;
	flex: 1;
	align-items: center;
	gap: 7px;
	min-width: 0;
	color: var(--tof-muted);
	font-size: 0.8em;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

.tof-step__dot {
	display: flex;
	width: 22px;
	height: 22px;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	border: 1px solid var(--tof-line);
	border-radius: 50%;
	background: var(--tof-white);
	color: var(--tof-muted);
	font-size: 11px;
}

.tof-step__label {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.tof-step.is-current {
	color: var(--tof-brand);
	font-weight: 700;
}

.tof-step.is-current .tof-step__dot {
	border-color: var(--tof-brand);
	background: var(--tof-brand);
	color: #fff;
}

.tof-step.is-done .tof-step__dot {
	border-color: var(--tof-peony);
	color: var(--tof-brand);
}

@media (max-width: 520px) {
	.tof-step__label {
		display: none;
	}
	.tof-step {
		flex: 0 0 auto;
	}
}

/* ---------- alerts ---------- */

.tof-alert {
	margin: 0 0 16px;
	padding: 11px 14px;
	border: 1px solid var(--tof-peony);
	border-left: 4px solid var(--tof-brand);
	border-radius: 6px;
	background: var(--tof-pale);
	color: var(--tof-brand-dark);
	font-size: 0.95em;
}

.tof-blvd__inner .tof-hold {
	margin: 0 0 16px;
	color: var(--tof-muted);
	font-size: 0.88em;
}

.tof-hold.is-expired {
	color: var(--tof-brand);
	font-weight: 700;
}

/* ---------- locations ---------- */

.tof-locgroup h3 {
	margin: 18px 0 8px;
	color: var(--tof-brand);
	font-size: 0.85em;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.tof-loclist {
	display: grid;
	margin: 0;
	padding: 0;
	gap: 8px;
	list-style: none;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

.tof-loc {
	display: flex;
	width: 100%;
	flex-direction: column;
	padding: 12px 14px;
	border: 1px solid var(--tof-line);
	border-radius: var(--tof-radius);
	background: var(--tof-white);
	color: var(--tof-ink);
	text-align: left;
	cursor: pointer;
	transition: border-color 0.15s, box-shadow 0.15s;
}

.tof-loc:hover,
.tof-loc:focus-visible {
	border-color: var(--tof-brand);
	box-shadow: 0 2px 10px rgba(205, 29, 87, 0.12);
	outline: none;
}

.tof-loc__name {
	color: var(--tof-brand);
	font-weight: 700;
}

.tof-loc__addr {
	color: var(--tof-muted);
	font-size: 0.85em;
}

/* ---------- services ---------- */

/*
 * Two up on desktop, stacked on phones. auto-fit rather than a fixed 2 means a
 * third service later needs no change here, and a location with only one
 * doesn't leave a lonely half-width card.
 */
.tof-services {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	align-items: stretch;
	margin: 0 0 18px;
	padding: 0;
	gap: 12px;
	list-style: none;
}

.tof-service {
	display: flex;
	width: 100%;
	flex-direction: column;
	align-items: stretch;
	padding: 0;
	overflow: hidden;
	border: 1px solid var(--tof-line);
	border-radius: var(--tof-radius);
	background: var(--tof-white);
	color: var(--tof-ink);
	text-align: left;
	cursor: pointer;
	transition: border-color 0.15s, box-shadow 0.15s;
}

.tof-service:hover,
.tof-service:focus-visible {
	border-color: var(--tof-brand);
	box-shadow: 0 2px 12px rgba(205, 29, 87, 0.14);
	outline: none;
}

.tof-service.is-disabled {
	opacity: 0.55;
	cursor: not-allowed;
}

/*
 * The card is a flex column and the text block grows, which pushes the pink
 * Book Now stripe to the bottom edge. With uneven description lengths — the
 * Teen Facial runs about three lines to the Signature's one — that keeps both
 * buttons on the same line instead of stair-stepping.
 */
.tof-service__main {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	padding: 18px 20px 16px;
}

.tof-service__name {
	color: var(--tof-ink);
	font-size: 1.15em;
	font-weight: 700;
	line-height: 1.25;
}

.tof-service__desc {
	margin-top: 6px;
	color: var(--tof-muted);
	font-size: 0.9em;
	line-height: 1.5;
}

/* the stripe */
/*
 * Brand ground with white and marshmallow accents. A pale strip on a pale page
 * had almost no separation; this makes the booking action the loudest thing
 * on the card.
 */
.tof-service__bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 14px;
	padding: 13px 20px;
	background: var(--tof-brand);
}

.tof-service__facts {
	display: flex;
	align-items: baseline;
	gap: 10px;
	min-width: 0;
}

.tof-service__price {
	color: #fff;
	font-size: 1.3em;
	font-weight: 700;
	line-height: 1;
}

.tof-service__dur {
	color: var(--tof-marshmallow);
	font-size: 0.85em;
	white-space: nowrap;
}

.tof-service__cta {
	display: inline-block;
	flex: 0 0 auto;
	padding: 10px 22px;
	border-radius: 999px;
	background: #fff;
	color: var(--tof-brand);
	font-size: 0.78em;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	white-space: nowrap;
	transition: background 0.15s, color 0.15s;
}

.tof-service:hover .tof-service__cta,
.tof-service:focus-visible .tof-service__cta {
	background: var(--tof-marshmallow);
	color: var(--tof-brand-dark);
}

.tof-service.is-disabled .tof-service__bar {
	background: var(--tof-muted);
}

.tof-service.is-disabled .tof-service__cta {
	background: var(--tof-snow);
	color: var(--tof-muted);
}

/* ---------- estheticians ---------- */

/*
 * Some locations run a dozen estheticians, so this is deliberately dense:
 * tighter rows, smaller avatars, and multiple columns once there's width for
 * them. The whole list should be scannable without a long scroll.
 */
.tof-staff {
	display: grid;
	margin: 0 0 16px;
	padding: 0;
	gap: 8px;
	list-style: none;
	grid-template-columns: repeat(auto-fill, minmax(238px, 1fr));
}

.tof-staff__card {
	display: flex;
	width: 100%;
	height: 100%;
	align-items: center;
	gap: 11px;
	padding: 9px 13px;
	border: 1px solid var(--tof-line);
	border-radius: var(--tof-radius);
	background: var(--tof-white);
	color: var(--tof-ink);
	text-align: left;
	cursor: pointer;
	transition: border-color 0.15s, box-shadow 0.15s;
}

.tof-staff__card:hover,
.tof-staff__card:focus-visible {
	border-color: var(--tof-brand);
	box-shadow: 0 2px 10px rgba(205, 29, 87, 0.12);
	outline: none;
}

.tof-staff__card.is-selected {
	border-color: var(--tof-brand);
	background: var(--tof-pale);
	box-shadow: inset 0 0 0 1px var(--tof-brand);
}

/* "First available" leads and spans the full width on multi-column layouts. */
.tof-staff__card.is-any {
	grid-column: 1 / -1;
	padding: 12px 14px;
}

.tof-staff li:first-child {
	grid-column: 1 / -1;
}

.tof-staff__avatar {
	display: flex;
	width: 38px;
	height: 38px;
	flex: 0 0 38px;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: var(--tof-marshmallow);
	color: var(--tof-brand-dark);
	font-size: 0.95em;
	font-weight: 700;
	object-fit: cover;
}

.tof-staff__avatar--any {
	background: var(--tof-brand);
	color: #fff;
}

.tof-staff__body {
	display: flex;
	min-width: 0;
	flex-direction: column;
}

.tof-staff__name {
	overflow: hidden;
	color: var(--tof-ink);
	font-size: 0.98em;
	font-weight: 700;
	line-height: 1.25;
	text-overflow: ellipsis;
}

.tof-staff__meta {
	color: var(--tof-muted);
	font-size: 0.82em;
	line-height: 1.3;
}

/*
 * Next, riding along with the selection.
 *
 * The action bars above and below the list are both off-screen on a phone once
 * a location has a dozen estheticians, and the middle of the list is exactly
 * where people tap. Only the chosen row becomes a flex row, so every other row
 * is the plain grid cell it always was.
 */
.tof-staff li.is-selected {
	display: flex;
	align-items: stretch;
	gap: 8px;
}

.tof-staff li.is-selected .tof-staff__card {
	min-width: 0;
	flex: 1 1 auto;
}

/*
 * align-self: stretch is what matches the row height, rather than a number
 * that would need revisiting every time the card's padding or the avatar
 * changes size. The pill keeps its own horizontal padding.
 */
.tof-staff__next {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	align-self: stretch;
	padding-top: 0;
	padding-bottom: 0;
	white-space: nowrap;
}

/* Actions above the list, so Next is reachable without scrolling past everyone. */
.tof-actions--top {
	margin: 0 0 14px;
}

/* ---------- returning-client match ---------- */

.tof-welcome {
	margin: 0 0 14px;
	padding: 12px 16px;
	border-left: 4px solid var(--tof-brand);
	border-radius: 6px;
	background: var(--tof-pale);
	color: var(--tof-brand-dark);
	font-weight: 600;
}

.tof-altline {
	margin: 2px 0 0;
	text-align: center;
}

/* ---------- verified details, shown back rather than asked for ---------- */

.tof-review {
	margin: 0 0 16px;
	padding: 14px 16px;
	border: 1px solid var(--tof-line);
	border-radius: 10px;
	background: #fff;
}

.tof-review__label {
	margin: 0 0 6px;
	color: var(--tof-muted);
	font-size: 0.85em;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.tof-review__body {
	margin: 0 0 8px;
	line-height: 1.5;
	/* A long address must not push the card wider than the phone. */
	overflow-wrap: anywhere;
}

/* ---------- group bookings ---------- */

.tof-services--lead {
	margin-bottom: 12px;
}

.tof-services--pair {
	display: grid;
	gap: 12px;
	grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
	/* Equal height regardless of description length, so the two CTAs line up. */
	align-items: stretch;
}

.tof-services--pair > li {
	display: flex;
}

.tof-blvd :where(button).tof-service--lead {
	border-width: 2px;
	border-color: var(--tof-brand);
}

/*
 * The Signature Facial is the booking almost everyone wants, so it keeps the
 * solid brand stripe and the secondary pair give it room: no filled stripe,
 * just a brand rule separating the description from the action, with the
 * price and button in brand text. Still obviously clickable, visibly the
 * second choice.
 */
.tof-services--pair .tof-service .tof-service__bar {
	border-top: 2px solid var(--tof-brand);
	background: transparent;
}

.tof-services--pair .tof-service .tof-service__price {
	color: var(--tof-brand-dark);
}

.tof-services--pair .tof-service .tof-service__dur {
	color: var(--tof-muted);
}

.tof-services--pair .tof-service .tof-service__cta {
	padding: 8px 18px;
	border: 1px solid var(--tof-brand);
	background: transparent;
	color: var(--tof-brand);
}

.tof-services--pair .tof-service:hover .tof-service__cta,
.tof-services--pair .tof-service:focus-visible .tof-service__cta {
	background: var(--tof-brand);
	color: #fff;
}

/* An empty facts slot still has to hold the CTA to the right. */
.tof-service__facts:empty {
	flex: 1 1 auto;
}

.tof-partysizes {
	display: grid;
	margin: 0 0 16px;
	gap: 10px;
	grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
}

.tof-blvd :where(button).tof-partysize {
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 18px 10px;
	border: 2px solid var(--tof-line);
	border-radius: 12px;
	background: #fff;
	color: inherit;
	font: inherit;
	cursor: pointer;
	gap: 2px;
}

.tof-blvd :where(button).tof-partysize:hover,
.tof-blvd :where(button).tof-partysize:focus-visible {
	border-color: var(--tof-brand);
	background: var(--tof-pale);
}

.tof-partysize__n {
	color: var(--tof-brand);
	font-size: 1.7em;
	font-weight: 700;
	line-height: 1;
}

.tof-partysize__l {
	color: var(--tof-muted);
	font-size: 0.8em;
}

.tof-members {
	margin: 0 0 14px;
	padding: 0;
	list-style: none;
}

/*
 * One person per row, three columns: who, what, with whom. They line up down
 * the page so a party of six scans as a list rather than six separate forms.
 */
.tof-member {
	display: grid;
	margin: 0 0 10px;
	padding: 14px 16px;
	align-items: end;
	gap: 10px 20px;
	grid-template-columns: 1fr 1fr auto;
	border: 1px solid var(--tof-line);
	border-radius: 10px;
	background: #fff;
}

.tof-member__cell {
	min-width: 0;
}

.tof-member__field {
	display: block;
}

.tof-member__label {
	display: block;
	margin-bottom: 4px;
	color: var(--tof-muted);
	font-size: 0.75em;
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

/*
 * The name input and the service select share one class so they are the same
 * height and the same width in their column. Mismatched control widths were
 * the thing that read as unfinished, particularly stacked on a phone.
 */
.tof-blvd .tof-member__input {
	display: block;
	width: 100%;
	max-width: 100%;
	height: 40px;
	margin: 0;
	padding: 8px 10px;
	border: 1px solid var(--tof-line);
	border-radius: 8px;
	background: #fff;
	color: var(--tof-ink);
	font: inherit;
	line-height: 1.2;
}

.tof-member__who {
	padding-bottom: 9px;
	color: var(--tof-muted);
	font-size: 0.95em;
	white-space: nowrap;
}

.tof-partytotal {
	display: flex;
	justify-content: space-between;
	margin: 0 0 14px;
	padding: 12px 16px;
	border-radius: 10px;
	background: var(--tof-pale);
	font-size: 1.05em;
}

.tof-partytotal strong {
	color: var(--tof-brand-dark);
}

/* Three columns need real width; below that they stack full-bleed. */
@media (max-width: 720px) {
	.tof-member {
		grid-template-columns: 1fr;
		gap: 12px;
	}

	.tof-member__who {
		padding-bottom: 0;
		white-space: normal;
	}
}

@media (max-width: 480px) {
	/* Three columns of numbers is plenty on a phone; five is a scroll. */
	.tof-partysizes {
		grid-template-columns: repeat(3, 1fr);
	}
}

/* ---------- profile picker ---------- */

.tof-profiles {
	display: grid;
	margin: 0 0 14px;
	gap: 10px;
}

.tof-blvd :where(button).tof-profile {
	display: block;
	width: 100%;
	margin: 0;
	padding: 14px 16px;
	border: 2px solid var(--tof-line);
	border-radius: 10px;
	background: #fff;
	color: inherit;
	font: inherit;
	text-align: left;
	cursor: pointer;
	transition: border-color 0.15s ease, background 0.15s ease;
}

.tof-blvd :where(button).tof-profile:hover,
.tof-blvd :where(button).tof-profile:focus-visible {
	border-color: var(--tof-brand);
	background: var(--tof-pale);
}

/* Selection has to read at a glance, since Continue acts on it. */
.tof-blvd :where(button).tof-profile.is-selected {
	border-color: var(--tof-brand);
	background: var(--tof-pale);
	box-shadow: inset 0 0 0 1px var(--tof-brand);
}

.tof-profile__name {
	display: block;
	color: var(--tof-brand-dark);
	font-weight: 700;
}

.tof-profile__meta {
	display: block;
	margin-top: 3px;
	color: var(--tof-muted);
	font-size: 0.9em;
	/* Long emails must not widen the card on a phone. */
	overflow-wrap: anywhere;
}

.tof-altline .tof-link {
	font-size: 0.9em;
}

/* ---------- dates & times ---------- */

.tof-dates {
	display: flex;
	margin: 0 0 18px;
	padding-bottom: 6px;
	gap: 8px;
	overflow-x: auto;
	scrollbar-width: thin;
	-webkit-overflow-scrolling: touch;
}

.tof-date {
	display: flex;
	width: 62px;
	flex: 0 0 auto;
	flex-direction: column;
	align-items: center;
	padding: 9px 0;
	border: 1px solid var(--tof-line);
	border-radius: var(--tof-radius);
	background: var(--tof-white);
	color: var(--tof-ink);
	line-height: 1.15;
	cursor: pointer;
}

.tof-date:focus-visible {
	border-color: var(--tof-brand);
	outline: none;
}

/*
 * Hover, only where something actually hovers.
 *
 * A touch screen leaves :hover on whatever sits under the finger after a tap,
 * and this strip moves under the finger — it scrolls to centre the date just
 * chosen, which slides the next date along into that spot. The result was a
 * brand-pink outline on the day after the selected one, reading as a second,
 * competing selection. The query means a phone never applies it at all.
 */
@media (hover: hover) {
	.tof-date:hover {
		border-color: var(--tof-brand);
		outline: none;
	}
}

.tof-date.is-active {
	border-color: var(--tof-brand);
	background: var(--tof-brand);
	color: #fff;
}

.tof-date__dow {
	font-size: 0.72em;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	opacity: 0.75;
}

.tof-date__day {
	font-size: 1.25em;
	font-weight: 700;
}

.tof-date__mon {
	font-size: 0.72em;
	text-transform: uppercase;
	opacity: 0.75;
}

.tof-times {
	display: grid;
	margin: 0 0 20px;
	gap: 8px;
	grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
}

.tof-time {
	padding: 12px 6px;
	border: 1px solid var(--tof-line);
	border-radius: var(--tof-radius);
	background: var(--tof-white);
	color: var(--tof-ink);
	font-weight: 600;
	cursor: pointer;
	transition: border-color 0.15s, background 0.15s, color 0.15s;
}

.tof-time:hover,
.tof-time:focus-visible {
	border-color: var(--tof-brand);
	background: var(--tof-brand);
	color: #fff;
	outline: none;
}

/* ---------- summary & form ---------- */

.tof-summary {
	margin: 0 0 14px;
	padding: 14px 16px;
	border-radius: var(--tof-radius);
	background: var(--tof-pale);
	line-height: 1.6;
}

.tof-form {
	display: grid;
	gap: 13px;
}

.tof-field-row {
	display: grid;
	gap: 13px;
	grid-template-columns: 1fr 1fr;
}

@media (max-width: 480px) {
	.tof-field-row {
		grid-template-columns: 1fr;
	}
}

.tof-field {
	display: flex;
	flex-direction: column;
	gap: 5px;
	font-size: 0.9em;
}

.tof-field > span {
	color: var(--tof-muted);
	font-weight: 600;
}

.tof-field input,
.tof-field textarea {
	width: 100%;
	padding: 11px 13px;
	border: 1px solid var(--tof-line);
	border-radius: 8px;
	background: var(--tof-white);
	color: var(--tof-ink);
	font: inherit;
	font-size: 16px; /* stops iOS zoom-on-focus */
}

.tof-field input:focus,
.tof-field textarea:focus {
	border-color: var(--tof-brand);
	box-shadow: 0 0 0 3px rgba(244, 156, 177, 0.4);
	outline: none;
}

.tof-actions {
	display: flex;
	align-items: center;
	margin-top: 4px;
	gap: 10px;
}

.tof-btn {
	display: inline-block;
	padding: 13px 26px;
	border: 1px solid var(--tof-brand);
	border-radius: 999px;
	font: inherit;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-decoration: none;
	text-transform: uppercase;
	cursor: pointer;
	transition: background 0.15s, color 0.15s;
}

.tof-btn--primary {
	background: var(--tof-brand);
	color: #fff;
}

.tof-btn--primary:hover:not(:disabled) {
	border-color: var(--tof-brand-dark);
	background: var(--tof-brand-dark);
	color: #fff;
}

.tof-btn--ghost {
	background: transparent;
	color: var(--tof-brand);
}

.tof-btn--ghost:hover {
	background: var(--tof-pale);
}

.tof-btn:disabled {
	opacity: 0.6;
	cursor: default;
}

.tof-fineprint {
	margin: 0;
	color: var(--tof-muted);
	font-size: 0.78em;
}

/* ---------- confirmation ---------- */

.tof-done {
	padding: 26px 20px;
	border: 1px solid var(--tof-line);
	border-radius: var(--tof-radius);
	background: var(--tof-pale);
	text-align: center;
}

.tof-done__check {
	display: flex;
	width: 52px;
	height: 52px;
	align-items: center;
	justify-content: center;
	margin: 0 auto 12px;
	border-radius: 50%;
	background: var(--tof-brand);
	color: #fff;
	font-size: 27px;
	line-height: 1;
}

.tof-done h3 {
	margin: 0 0 6px;
	color: var(--tof-brand);
	font-size: 1.4em;
}

.tof-done__when {
	margin: 0 0 4px;
	font-size: 1.1em;
	font-weight: 700;
}

.tof-done__what {
	margin: 0 0 16px;
	color: var(--tof-muted);
}

.tof-done__where {
	margin: 0 0 14px;
	line-height: 1.5;
}

.tof-done__note {
	margin: 0;
	color: var(--tof-muted);
	font-size: 0.88em;
}

/* ---------- below-widget content ---------- */

.tof-below {
	margin: 40px 0 0;
}

.tof-below[hidden] {
	display: none;
}

/*
 * Each section is its own full-bleed band, so the page reads as a stack of
 * alternating white and pale stripes rather than one long wash of pink. Same
 * 100vw / negative-margin break-out as the hero, with the inline padding
 * putting the content back on the 800px column.
 *
 * The carousel and the reviews slider break out AGAIN from inside here. That
 * still works: 50% is now half the band's content box, so calc(50% - 50vw)
 * resolves to exactly minus this padding, and they land where they always did.
 */
.tof-sec {
	width: 100vw;
	margin: 0;
	margin-right: calc(50% - 50vw);
	margin-left: calc(50% - 50vw);
	padding: 44px max(20px, calc(50vw - 400px));
}

.tof-sec--white {
	background: var(--tof-white);
}

/*
 * Transparent rather than a pink of our own. The page ground is #ffebee and
 * our pale token is #feeef0 — near-identical on a swatch, visibly a seam on
 * screen. Letting the page show through means the alternate band matches the
 * page exactly, on this theme and any other, with no colour to keep in sync.
 */
.tof-sec--pale {
	background: transparent;
}

/*
 * The reviews widget stays in the content column.
 *
 * It was full-bleed for a while, and the plugin's own summary — "Excellent /
 * spa name / 5.0 / Based on 59 reviews" — went with it, pinned to the far left
 * of the screen while our heading sat in the column. That summary sets
 * text-align:start on each of its own elements, so centring it means naming
 * .rpi-scale, .rpi-name, .rpi-stars and .rpi-based and overriding each: four
 * third-party class names to pin, in a plugin that updates itself.
 *
 * The widget is built for a normal column and looks right in one, which is how
 * it renders on the location pages. The band around it is still full width, so
 * the alternating stripes are unaffected — only the cards stop running to the
 * edges.
 */

.tof-sec__title {
	margin: 0 0 6px;
	color: var(--tof-brand);
	font-size: 1.35em;
	line-height: 1.25;
}

.tof-sec__lede {
	margin: 0 0 18px;
	color: var(--tof-ink);
	font-size: 1.02em;
}

/* differentiator */

/*
 * The page background is already pale pink, so a pale-pink card was invisible.
 * Solid brand fill gives this block the emphasis it's meant to carry.
 */
.tof-diff {
	padding: 34px 28px;
	border-radius: var(--tof-radius);
	background: var(--tof-brand);
	color: #fff;
	text-align: center;
}

.tof-diff__title {
	margin: 0 0 10px;
	color: #fff;
	font-size: 1.5em;
	line-height: 1.2;
}

.tof-diff__body {
	max-width: 44em;
	margin: 0 auto;
	color: #fff;
	opacity: 0.95;
}

.tof-diff__points {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	margin: 18px 0 0;
	padding: 0;
	gap: 10px;
	list-style: none;
}

.tof-diff__points li {
	padding: 8px 18px;
	border: 1px solid transparent;
	border-radius: 999px;
	background: var(--tof-white);
	color: var(--tof-brand-dark);
	font-size: 0.9em;
	font-weight: 700;
}

.tof-sec__media {
	overflow: hidden;
	margin: 0 0 18px;
	border-radius: var(--tof-radius);
	background: var(--tof-marshmallow);
	line-height: 0;
}

.tof-sec__media img {
	display: block;
	width: 100%;
	height: 300px;
	object-fit: cover;
	object-position: center 35%;
}

@media (max-width: 600px) {
	.tof-sec__media img {
		height: 200px;
	}
}

/* facial steps — horizontal carousel */

/*
 * Full-bleed carousel. Breaks out to the viewport like the hero, but pads its
 * inline edges so the first card still lines up with the 760px content column
 * — the track runs edge to edge, the content stays on the grid.
 */
.tof-carousel {
	position: relative;
	width: calc(100vw - 40px);
	margin-right: calc(50% - 50vw + 20px);
	margin-left: calc(50% - 50vw + 20px);
}

.tof-facial,
.tof-carousel__nav {
	padding-right: max(4px, calc(50vw - 400px));
	padding-left: max(4px, calc(50vw - 400px));
}

.tof-facial {
	display: flex;
	margin: 0;
	padding-bottom: 8px;
	gap: 12px;
	list-style: none;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	scrollbar-width: thin;
	scrollbar-color: var(--tof-peony) transparent;
	-webkit-overflow-scrolling: touch;
	counter-reset: tofstep;
}

.tof-facial::-webkit-scrollbar {
	height: 6px;
}

.tof-facial::-webkit-scrollbar-thumb {
	border-radius: 999px;
	background: var(--tof-peony);
}

.tof-facial li {
	position: relative;
	display: flex;
	flex: 0 0 clamp(230px, 66vw, 300px);
	flex-direction: column;
	padding: 44px 18px 18px;
	border: 1px solid var(--tof-line);
	border-radius: var(--tof-radius);
	background: var(--tof-white);
	scroll-snap-align: start;
	counter-increment: tofstep;
}

.tof-facial li::before {
	position: absolute;
	top: 16px;
	left: 18px;
	display: flex;
	width: 26px;
	height: 26px;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	background: var(--tof-brand);
	color: #fff;
	content: counter(tofstep);
	font-size: 0.8em;
	font-weight: 700;
}

.tof-facial__name {
	display: block;
	margin-bottom: 6px;
	color: var(--tof-ink);
	font-weight: 700;
}

.tof-facial__desc {
	color: var(--tof-muted);
	font-size: 0.9em;
	line-height: 1.5;
}

.tof-carousel__nav {
	display: flex;
	justify-content: flex-end;
	margin-top: 12px;
	gap: 8px;
}

.tof-carousel__btn {
	display: flex;
	width: 40px;
	height: 40px;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 1px solid var(--tof-brand);
	border-radius: 50%;
	background: var(--tof-white);
	color: var(--tof-brand);
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
	transition: background 0.15s, color 0.15s, opacity 0.15s;
}

.tof-carousel__btn:hover:not(:disabled) {
	background: var(--tof-brand);
	color: #fff;
}

.tof-carousel__btn:disabled {
	opacity: 0.3;
	cursor: default;
}

/* mid-page CTA */

.tof-midcta {
	margin: 26px 0 0;
	text-align: center;
}

/* map */

.tof-map {
	overflow: hidden;
	border: 1px solid var(--tof-line);
	border-radius: var(--tof-radius);
}

.tof-map iframe {
	display: block;
	width: 100%;
	height: 320px;
	border: 0;
}

.tof-map__foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	padding: 12px 16px;
	gap: 10px;
	background: var(--tof-pale);
	font-size: 0.92em;
}

.tof-map__addr {
	color: var(--tof-ink);
}

/* ---------- plan your visit: hours and phone, live from Boulevard ---------- */

.tof-visit {
	display: grid;
	margin-top: 18px;
	gap: 18px 32px;
	grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}

.tof-visit__label {
	margin: 0 0 6px;
	color: var(--tof-muted);
	font-size: 0.78em;
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.tof-visit__body {
	margin: 0;
	font-size: 1.05em;
}

.tof-blvd .tof-visit__body :where(a) {
	color: var(--tof-brand);
	font-weight: 700;
	text-decoration: none;
	border-bottom: 1px solid var(--tof-line);
}

.tof-blvd .tof-visit__body :where(a):hover {
	border-bottom-color: var(--tof-brand);
}

/*
 * The theme stripes table rows and gives cells no padding of its own, which
 * left the hours looking like a spreadsheet export bleeding into its edges.
 * Everything below is stated explicitly — background included — so the block
 * reads as one card whatever the theme does to tables elsewhere.
 */
.tof-blvd .tof-hours {
	width: 100%;
	max-width: 340px;
	margin: 0;
	padding: 6px 4px;
	border: 1px solid var(--tof-line);
	border-collapse: collapse;
	border-radius: 10px;
	background: #fff;
	font-size: 0.95em;
	overflow: hidden;
}

.tof-blvd .tof-hours tr,
.tof-blvd .tof-hours tbody {
	border: 0;
	background: transparent;
}

.tof-blvd .tof-hours th,
.tof-blvd .tof-hours td {
	padding: 11px 18px;
	border: 0;
	background: transparent;
	text-align: left;
	vertical-align: top;
}

.tof-blvd .tof-hours tr + tr th,
.tof-blvd .tof-hours tr + tr td {
	border-top: 1px solid var(--tof-line);
}

.tof-blvd .tof-hours th {
	padding-right: 10px;
	color: var(--tof-muted);
	font-weight: 600;
	/* Day ranges are short; stop "Mon–Fri" wrapping mid-range on a phone. */
	white-space: nowrap;
}

.tof-blvd .tof-hours td {
	color: var(--tof-ink);
	font-variant-numeric: tabular-nums;
}

/* reviews slot — the reviews plugin renders its own markup inside */

.tof-reviews:empty {
	display: none;
}

/*
 * Stars, in the summary and on every card.
 *
 * The plugin's default star is orange (#fb8e28) and each collection can
 * override it in its own settings — 30 collections, set by hand, so some are
 * brand pink, some are grey and some were never touched. That is not something
 * to fix 30 times in a third-party admin screen and re-check every time a
 * location is added.
 *
 * Both names are needed: the summary and badge read --head-star-color, falling
 * back to --star-color, while the cards read --star-color alone. The empty
 * half of a partial star goes marshmallow rather than the plugin's grey, so a
 * 4.8 still reads as our palette — pale enough to still be clearly "not
 * filled".
 *
 * These are set inline on .rpi by the collection, and an author rule with
 * !important is what beats an inline style.
 */
.tof-blvd .tof-reviews .rpi {
	--head-star-color: var(--tof-brand) !important;
	--star-color: var(--tof-brand) !important;
	--rpi-star-empty-color: var(--tof-marshmallow) !important;
}

/*
 * Carousel progress dots.
 *
 * The plugin paints the inactive dots with --slider-dot-color, which the
 * client's collection settings set to #ffffff — invisible on our white band,
 * and a dot you cannot see is a control nobody knows is there. Colouring them
 * pale pink would fix this band and break again the moment the band behind
 * them alternates to pink, so they are drawn as rings instead: an outline
 * reads against any of our backgrounds, and the filled dot is unambiguously
 * the current page.
 *
 * Every declaration the plugin makes here is !important, so every override has
 * to be too — specificity between two !important rules is what decides it, and
 * the .tof-blvd .tof-reviews scope keeps that fight inside our widget rather
 * than restyling the dots on the location pages, which are on a white card
 * where the plugin's own colours are fine.
 *
 * box-shadow was the first attempt at the ring and computed to none: something
 * in the theme zeroes shadows on <button>. A real border draws it, with
 * box-sizing pinned because the plugin fixes width and height and a
 * content-box border would grow the dot past them.
 *
 * The size bump is what makes the ring legible. Dots are .5em (8px) by
 * default and the plugin scales the off-centre ones down to 0.55, so a 2px
 * ring on the smallest would close up into a blob; at .75em they stay rings.
 */
.tof-blvd .tof-reviews .rpi {
	--slider-dot-size: 0.75em !important;
}

.tof-blvd .tof-reviews .rpi-dots .rpi-dot {
	box-sizing: border-box !important;
	border: 2px solid var(--tof-brand) !important;
	background-color: transparent !important;
	opacity: 1 !important;
}

.tof-blvd .tof-reviews .rpi-dots .rpi-dot.active {
	background-color: var(--tof-brand) !important;
}

/* back-to-booking CTA */

.tof-jump {
	padding: 26px 20px;
	border: 1px solid var(--tof-line);
	border-radius: var(--tof-radius);
	background: var(--tof-white);
	text-align: center;
}

.tof-jump__title {
	margin: 0 0 12px;
	color: var(--tof-brand);
	font-size: 1.25em;
}

/* ---------- admin-only warning ---------- */

.tof-blvd-fatal {
	padding: 14px 16px;
	border: 2px dashed #cd1d57;
	border-radius: 8px;
	background: #feeef0;
	color: #a81746;
}

/* ---------- add to calendar ---------- */

/*
 * Boulevard sends a confirmation email, which is read once. A calendar entry
 * with reminders is what gets someone through the door, so this sits with the
 * booking details rather than being buried under them.
 */
.tof-cal {
	margin: 20px 0 4px;
	padding: 16px 0 0;
	border-top: 1px solid var(--tof-line);
}

.tof-cal__label {
	margin: 0 0 10px;
	color: var(--tof-muted);
	font-size: 0.85em;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

.tof-cal__actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	margin: 0;
}

.tof-cal__actions .tof-btn {
	padding: 10px 20px;
	font-size: 0.85em;
}
