/* base.css — the platform's base sheet: the primitives every module's pages are built from
   (a page head, a button, a card, a form, a badge, the date field, the day strip and the
   time grid a booking is picked from, the ways-to-pay list), drawn ONLY in the site's
   tokens. A page links it BEFORE the site's /styles.css, so the site's tokens and rules win.

   The contract a site fulfils is four tokens — --bg, --text, --accent, --font — declared in
   its styles.css; everything else below has a default derived from those four, and a site
   overrides any of them by declaring it. See docs/WEBSITE.md, "The contract". */

/* Tokens: neutral defaults for the required four, so a module's page on a tenant with no
   site of its own still reads as a page (system type, white ground, one plain accent); a
   site's styles.css, linked after this sheet, overrides them --------------------------- */

:root {
	--bg: #FFFFFF;
	--text: #1B1F24;
	--accent: #1F6FEB;
	--font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* A PARAGRAPH READS IN ITS OWN LANGUAGE. A page carries the business's direction, but the
   words on it are whatever somebody wrote — a Hebrew club whose racket is called "Babolat
   Pure Drive", an English sentence left in a template. `plaintext` lets each block take its
   direction from its own first strong character, so a Latin sentence on a right-to-left page
   keeps its full stop at the end instead of having it dragged to the front. It changes
   nothing on a page whose text matches its direction, which is every page today. */
h1, h2, h3, h4, h5, h6, p, li, dd, dt, blockquote, figcaption, td, th, label, legend,
button, .button, .status {
	unicode-bidi: plaintext;
}

/* Tokens: the optional half, derived from the required four ------------------------ */

:root {
	--surface: color-mix(in srgb, var(--bg) 88%, white);
	--line: color-mix(in srgb, var(--text) 14%, var(--bg));
	--muted: color-mix(in srgb, var(--text) 64%, var(--bg));
	--accent-contrast: #FFFFFF;
	--accent-text: var(--accent);
	--font-display: var(--font);
	--radius: 14px;
	--radius-sm: 10px;
	--radius-control: 6px;
	--wrap: 72rem;
	--shadow: 0 1px 2px color-mix(in srgb, var(--text) 6%, transparent),
		0 10px 28px color-mix(in srgb, var(--text) 8%, transparent);
	--ring: 0 0 0 4px color-mix(in srgb, var(--accent) 24%, transparent);
	--ok: #1E7F3C;
	--warn: #B8791A;
	--bad: #B4311B;
}

/* Ground --------------------------------------------------------------------------- */

* { box-sizing: border-box; }

/* The hidden attribute wins over any display a class sets — a card a script hides is hidden. */
[hidden] { display: none !important; }

body {
	margin: 0;
	min-height: 100vh;
	display: flex;
	flex-direction: column;
	font-family: var(--font);
	font-size: 1.0625rem;
	line-height: 1.6;
	color: var(--text);
	background: var(--bg);
	-webkit-font-smoothing: antialiased;
}

/* The page's main content grows, so a short page still puts its footer at the bottom. */
main { flex: 1 0 auto; }

h1, h2, h3 { margin: 0 0 0.5em; font-family: var(--font-display); line-height: 1.1; }
p { margin: 0 0 1em; }
a { color: inherit; }

:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--radius-control); }

/* Layout --------------------------------------------------------------------------- */

.wrap {
	max-width: var(--wrap);
	margin-inline: auto;
	padding-inline: clamp(1.25rem, 4vw, 2.5rem);
}
.narrow { max-width: 44rem; }

.band { padding-block: clamp(2.5rem, 6vw, 4.5rem); }

/* A module page (one that opens with a page-head) is a working page, not a landing: it
   starts close under the header, whatever rhythm the site's template gives its bands. */
.band:has(> .wrap > .page-head) { padding-top: clamp(1.5rem, 3vw, 2.25rem); }

/* The chrome of a page that is TAKING MONEY: the business's mark, and nothing to click away
   with. It is what partials/brand.html draws when the site ships no brand of its own. */

.brandbar {
	padding-block: 1rem;
	border-bottom: 1px solid var(--line);
	background: var(--surface);
}
.brandbar-name {
	font-family: var(--font-display);
	font-size: 1.3rem;
	font-weight: 700;
	text-decoration: none;
}

/* The head of a module page: its title and the one or two actions that belong beside it.
   Sized here so the site's display h1 (a hero size) never lands on a booking page. */

.page-head {
	display: flex;
	flex-wrap: wrap;
	align-items: end;
	justify-content: space-between;
	gap: 1rem 2rem;
	margin-bottom: clamp(1.1rem, 2vw, 1.5rem);
}
.page-head h1 { margin: 0; font-size: clamp(1.7rem, 2.8vw, 2.2rem); font-weight: 600; letter-spacing: -0.01em; }
.page-head .actions { margin: 0; }

.lede { max-width: 40rem; margin: -0.5rem 0 1.75rem; font-size: 1.1rem; color: var(--muted); }

.eyebrow {
	margin: 0 0 0.6rem;
	font: 600 0.74rem/1.5 var(--font);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--accent-text);
}

.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem; margin: 1.5rem 0 0; }
/* One decision, full width, with a line under it — the shape a confirmation page ends on. */
.actions--stack { flex-direction: column; align-items: stretch; text-align: center; }
.button--wide { width: 100%; }

/* Prose: what the markdown filter prints — an article, a post — set to be READ -------- */

.prose { font-size: 1.05rem; line-height: 1.7; overflow-wrap: break-word; }
.prose h1 { font-size: clamp(1.7rem, 2.8vw, 2.2rem); font-weight: 600; letter-spacing: -0.01em; }
.prose h2 { margin: 2.25rem 0 0.6em; font-size: 1.35rem; font-weight: 600; letter-spacing: 0; }
.prose h3 { margin: 1.75rem 0 0.5em; font-size: 1.1rem; font-weight: 600; letter-spacing: 0; }
.prose p { margin: 0 0 1.1em; }
.prose ul, .prose ol { margin: 0 0 1.1em; padding-inline-start: 1.4rem; }
.prose li { margin-bottom: 0.4em; }
/* A BUTTON inside prose is a button, not a link: prose's link colour is more specific than
   the button's own, so it would paint the label over the button's background and leave it
   unreadable. */
.prose a:not(.button) { color: var(--accent-text); text-underline-offset: 0.15em; }
.prose hr { margin: 2.25rem 0; border: 0; border-top: 1px solid var(--line); }
.prose blockquote {
	margin: 1.5rem 0;
	padding: 0.1rem 1.25rem;
	border-inline-start: 3px solid var(--accent);
	color: var(--muted);
}

/* A screenshot gets the width of the column and a frame, so a picture of a screen does not
   read as part of the page it is shown on. */
.prose img {
	display: block;
	max-width: 100%;
	height: auto;
	margin: 1.5rem 0;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
}

.prose code {
	padding: 0.15em 0.4em;
	border-radius: 0.35rem;
	background: color-mix(in srgb, var(--text) 7%, var(--bg));
	font-size: 0.9em;
}
.prose pre {
	overflow-x: auto;
	margin: 1.5rem 0;
	padding: 1rem 1.15rem;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: color-mix(in srgb, var(--text) 4%, var(--bg));
	line-height: 1.5;
}
.prose pre code { padding: 0; background: none; }

.prose table {
	display: block;
	overflow-x: auto;
	width: 100%;
	margin: 1.5rem 0;
	border-collapse: collapse;
	font-size: 0.95rem;
}
.prose th, .prose td { padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--line); text-align: start; }
.prose th { font-weight: 600; }

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

.button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 0.7rem 1.4rem;
	border: 1.5px solid var(--text);
	border-radius: var(--radius-control);
	font: 600 0.95rem/1.2 var(--font);
	text-decoration: none;
	cursor: pointer;
	background: var(--text);
	color: var(--bg);
	transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
}
.button:hover { transform: translateY(-1px); box-shadow: var(--shadow); }
.button:active { transform: translateY(0); }
.button[disabled] { opacity: 0.55; cursor: default; transform: none; box-shadow: none; }

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

.button--ghost {
	background: transparent;
	border-color: var(--line);
	color: var(--text);
}
.button--ghost:hover { border-color: var(--text); }

.button--ghost-danger {
	background: transparent;
	border-color: color-mix(in srgb, var(--bad) 40%, var(--bg));
	color: var(--bad);
}
.button--ghost-danger:hover { border-color: var(--bad); }

.linklike {
	padding: 0;
	border: 0;
	background: none;
	font: inherit;
	font-weight: 600;
	color: var(--accent-text);
	cursor: pointer;
	text-decoration: underline;
}

/* Cards ---------------------------------------------------------------------------- */

.card {
	padding: clamp(1.4rem, 3vw, 2.2rem);
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
}

/* A title INSIDE a card is a content title, never the site's display size: the site's own
   h2 is a band headline (a hero scale), and a module's page must not inherit it for "your
   booking is confirmed". Sized above the site's bare selectors by specificity. */
.card h2 { font-size: 1.3rem; font-weight: 600; letter-spacing: 0; margin: 0 0 0.35em; }
.card h3 { font-size: 1.05rem; font-weight: 600; letter-spacing: 0; margin: 0 0 0.35em; }
.card p:last-child { margin-bottom: 0; }
/* The card's padding is the space above its first line: a status or a row of actions that
   opens a card keeps the gap it takes after other content to itself. */
.card > :first-child { margin-top: 0; }

/* Forms ---------------------------------------------------------------------------- */

/* A form is a column of ordinary-sized fields, never a wall of them: a field is as tall as
   its text needs, and fills its container — the PAGE bounds the container (a card, a
   narrow wrap, a max-width on its own form) so fields never sit ragged inside a wider box. */
.form { display: grid; gap: 0.15rem; align-content: start; }
.form label { font-weight: 600; font-size: 0.85rem; margin-top: 0.7rem; }
.form label:first-child { margin-top: 0; }

.form input,
.form textarea,
.form select {
	width: 100%;
	padding: 0.5rem 0.7rem;
	border: 1px solid var(--line);
	border-radius: var(--radius-control);
	font: inherit;
	font-size: 0.95rem;
	line-height: 1.3;
	color: inherit;
	background: var(--surface);
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.form input::placeholder, .form textarea::placeholder { color: var(--muted); opacity: 0.7; }
.form input:hover, .form textarea:hover, .form select:hover { border-color: var(--muted); }
.form input:focus-visible, .form textarea:focus-visible, .form select:focus-visible {
	border-color: var(--accent);
	box-shadow: var(--ring);
	outline: none;
}

/* A yes/no choice is the box and its words on one line, the words part of the click: a label
   wrapping its checkbox ("Keep me signed in"). */
.form .check {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	font-weight: 400;
	font-size: 0.9rem;
	cursor: pointer;
}
.form .check input {
	width: auto;
	padding: 0;
	margin: 0;
	accent-color: var(--accent);
	box-shadow: none;
}

/* A form's own submit, when the page did not dress it as one of the buttons above: the
   same shape as .button--accent (padding, radius, type), so a submit and a .button beside
   it — the sign-in card's two ways in — read as one family. */
.form button[type="submit"]:not(.button) {
	justify-self: start;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	margin-top: 0.9rem;
	padding: 0.7rem 1.4rem;
	border: 1.5px solid var(--accent);
	border-radius: var(--radius-control);
	background: var(--accent);
	color: var(--accent-contrast);
	font: 600 0.95rem/1.2 var(--font);
	cursor: pointer;
	transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.form button[type="submit"]:not(.button):hover { transform: translateY(-1px); box-shadow: var(--shadow); }
.form button[type="submit"]:not(.button)[disabled] { opacity: 0.55; transform: none; cursor: default; }
/* A submit the page already dressed as one of the buttons: it is still the form's last row,
   and the grid's own gap is the space between a label and its field, never between a field
   and the button that sends it. */
.form button[type="submit"].button { margin-top: 0.9rem; }

/* Where a payment gateway draws its own card field, and what it draws around it. The box
   is the gateway's — its iframe, its validation — so the page cannot style what is inside
   it; what the page owes it is an input's shape and room to breathe. */
.paygate { display: grid; gap: 0.75rem; }
.cardfield {
	padding: 0.65rem 0.7rem;
	border: 1px solid var(--line);
	border-radius: var(--radius-control);
	background: var(--surface);
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.cardfield.is-focus { border-color: var(--accent); box-shadow: var(--ring); }

/* A field with a control living inside it — the password eye. */
.field-affix { position: relative; }
.field-affix input { padding-inline-end: 3rem; }
.field-affix .affix {
	position: absolute;
	inset-inline-end: 0.6rem;
	top: 50%;
	transform: translateY(-50%);
	display: inline-flex;
	padding: 0.4rem;
	border: 0;
	border-radius: 8px;
	background: none;
	color: var(--muted);
	cursor: pointer;
}
.field-affix .affix:hover { color: var(--text); background: var(--bg); }
.field-affix .affix svg { width: 1.15rem; height: 1.15rem; }

.status { min-height: 1.6em; margin: 0.9rem 0 0; color: var(--muted); font-size: 0.95rem; }
.status.error { color: var(--bad); }

/* The answer a form gives when it lands: the fields give way to the confirmation, in the
   same box the person was looking at. A line of grey text under a form that has just
   emptied itself does not tell anybody whether they sent something. */

.form-done {
	display: grid;
	justify-items: center;
	text-align: center;
	gap: 0.45rem;
	padding: 0.6rem 0 0.2rem;
}

.form-done-mark {
	display: grid;
	place-items: center;
	width: 3rem;
	height: 3rem;
	margin-bottom: 0.35rem;
	border-radius: 50%;
	background: color-mix(in srgb, var(--ok) 14%, var(--surface));
	color: var(--ok);
	font-size: 1.45rem;
	line-height: 1;
}

.form-done h2 { margin: 0; font-size: 1.25rem; font-weight: 600; letter-spacing: 0; }
.form-done p { margin: 0; max-width: 26rem; color: var(--muted); }
.form-done .linklike { margin-top: 0.7rem; }

/* A button that is waiting says so where the person pressed, not in a line below it. */
.is-busy::before {
	content: "";
	flex: none;
	width: 0.9em;
	height: 0.9em;
	border: 2px solid currentColor;
	border-top-color: transparent;
	border-radius: 50%;
	animation: spin 0.7s linear infinite;
}

@keyframes spin {
	to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
	.is-busy::before { animation: none; }
}

/* Badges and notices: a state, coloured by what it means --------------------------- */

.badge {
	display: inline-block;
	padding: 0.3rem 0.75rem;
	border-radius: 999px;
	font-size: 0.8rem;
	font-weight: 600;
	white-space: nowrap;
	background: color-mix(in srgb, var(--text) 8%, var(--surface));
	color: var(--muted);
}
.badge.is-ok { background: color-mix(in srgb, var(--ok) 14%, var(--surface)); color: var(--ok); }
.badge.is-pending { background: color-mix(in srgb, var(--warn) 16%, var(--surface)); color: var(--warn); }
.badge.is-cancelled { background: color-mix(in srgb, var(--bad) 12%, var(--surface)); color: var(--bad); }

.notice {
	margin: 0;
	padding: 0.95rem 1.2rem;
	border-radius: var(--radius-sm);
	font-weight: 600;
	background: color-mix(in srgb, var(--text) 8%, var(--surface));
}
.notice.is-ok { background: color-mix(in srgb, var(--ok) 14%, var(--surface)); color: var(--ok); }
.notice.is-pending { background: color-mix(in srgb, var(--warn) 16%, var(--surface)); color: var(--warn); }
.notice.is-cancelled { background: color-mix(in srgb, var(--bad) 12%, var(--surface)); color: var(--bad); }
.notice.is-error { background: color-mix(in srgb, var(--bad) 12%, var(--surface)); color: var(--bad); }

/* Modal: the one thing a page interrupts you with — an act it will not undo -------- */

.modal {
	width: min(30rem, calc(100vw - 2rem));
	/* The reset zeroes every margin; a dialog centers itself only through margin: auto. */
	margin: auto;
	padding: 0;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--surface);
	color: var(--text);
	box-shadow: var(--shadow);
}
.modal::backdrop { background: color-mix(in srgb, var(--text) 45%, transparent); }

.modal-body { padding: clamp(1.4rem, 3vw, 2rem) clamp(1.4rem, 3vw, 2rem) 0; }
.modal-body h2 { margin: 0 0 0.6rem; font-size: 1.25rem; font-weight: 600; }
.modal-body p { margin: 0; color: var(--muted); }
.modal-input {
	width: 100%;
	margin-top: 1rem;
	padding: 0.5rem 0.7rem;
	border: 1px solid var(--line);
	border-radius: var(--radius-control);
	font: inherit;
	font-size: 0.95rem;
	color: inherit;
	background: var(--surface);
}

/* The decision lives at the bottom, where a reader finishes and where every OS puts it:
   the primary last, Cancel beside it. */
.modal-actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-end;
	gap: 0.6rem;
	padding: clamp(1.4rem, 3vw, 2rem);
}

/* Tabs and chips: one choice among a few ------------------------------------------- */

.tabs { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.5rem; }

.tab {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.55rem 1.3rem;
	border: 1.5px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--surface);
	font: 600 0.95rem/1.2 var(--font);
	color: var(--text);
	cursor: pointer;
	transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.tab:hover { transform: translateY(-1px); box-shadow: var(--shadow); }
.tab.is-active { background: var(--accent); border-color: var(--accent); color: var(--accent-contrast); }
a.tab { text-decoration: none; }

/* The date field (widgets.js) ------------------------------------------------------ */

.datefield {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.7rem 1.2rem;
	border: 1.5px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--surface);
	font: 600 1rem/1.2 var(--font);
	color: var(--text);
	cursor: pointer;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.datefield:hover { border-color: var(--muted); box-shadow: var(--shadow); }
.datefield svg { width: 1.1rem; height: 1.1rem; color: var(--accent-text); }
.datefield-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

.datepop {
	position: absolute;
	z-index: 20;
	margin-top: 0.5rem;
	padding: 1rem;
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
	animation: pop 0.16s ease;
}

.datepop-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	margin-bottom: 0.7rem;
}

.datepop-nav {
	width: 2.1rem;
	height: 2.1rem;
	border: 0;
	border-radius: 50%;
	background: var(--bg);
	color: var(--text);
	font-size: 1.05rem;
	cursor: pointer;
}
.datepop-nav:hover { background: var(--line); }

.datepop-grid {
	display: grid;
	grid-template-columns: repeat(7, 2.3rem);
	gap: 2px;
	justify-items: stretch;
}

.datepop-dow {
	font: 600 0.7rem/2 var(--font);
	text-transform: uppercase;
	text-align: center;
	color: var(--muted);
}

.datepop-day {
	height: 2.3rem;
	border: 0;
	border-radius: 50%;
	background: none;
	font: 500 0.92rem/1 var(--font);
	color: var(--text);
	cursor: pointer;
}
.datepop-day:hover { background: var(--bg); }
.datepop-day.is-today { box-shadow: inset 0 0 0 1.5px var(--line); }
.datepop-day.is-selected { background: var(--accent); color: var(--accent-contrast); font-weight: 700; }
.datepop-day:disabled { color: var(--line); cursor: default; background: none; }

@keyframes pop {
	from { opacity: 0; transform: translateY(-4px); }
}

/* Picking a moment: a strip of days, then the free times of the chosen one -------------
   The same two pieces wherever something is booked — a court, a class, a meeting — so a
   visitor who has taken one thing on the site already knows how to take the next. The
   strip sits at the top of its card (padding 0), the grid in the card's body. */

.daystrip {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	padding: 0.6rem 0.9rem;
	border-bottom: 1px solid var(--line);
	background: color-mix(in srgb, var(--text) 3%, var(--surface));
}

.daynav {
	flex: none;
	width: 2rem;
	height: 2rem;
	border: 1px solid var(--line);
	border-radius: 50%;
	background: var(--surface);
	color: var(--text);
	font-size: 1.1rem;
	cursor: pointer;
	transition: border-color 0.15s ease;
}
.daynav:hover { border-color: var(--text); }
.daynav[disabled] { opacity: 0.35; cursor: default; }

.days {
	display: grid;
	grid-template-columns: repeat(7, 1fr);
	gap: 0.4rem;
	flex: 1;
	min-width: 0;
}

.day {
	display: grid;
	justify-items: center;
	gap: 0.05rem;
	padding: 0.4rem 0.25rem;
	border: 1px solid transparent;
	border-radius: var(--radius-sm);
	background: transparent;
	color: var(--text);
	font: inherit;
	line-height: 1.2;
	cursor: pointer;
	transition: background 0.15s ease, border-color 0.15s ease;
}
.day:hover { border-color: var(--line); background: var(--surface); }
.day-name { font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.day-num { font-size: 1.05rem; font-weight: 600; }
.day.is-active { background: var(--accent); border-color: var(--accent); color: var(--accent-contrast); }
.day.is-active .day-name { color: var(--accent-contrast); opacity: 0.8; }

@media (max-width: 48rem) {
	.day-name { font-size: 0.7rem; }
}

.timegrid {
	display: grid;
	gap: 0.45rem;
	grid-template-columns: repeat(auto-fill, minmax(5.25rem, 1fr));
}

.time {
	padding: 0.5rem 0.4rem;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--surface);
	color: var(--text);
	font: 600 0.95rem/1.2 var(--font);
	cursor: pointer;
	transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.time:hover { border-color: var(--accent); background: var(--accent); color: var(--accent-contrast); }

/* A chip says its own price only when the day holds more than one, so the clock keeps the
   grid's rhythm on every ordinary day. */
.time-when { display: block; }
.time-price {
	display: block;
	margin-top: 0.1rem;
	font-size: 0.78rem;
	font-weight: 500;
	color: var(--muted);
}
.time:hover .time-price { color: inherit; opacity: 0.85; }

/* The card the two pieces sit in, and the SERVICE column beside them -------------------
   The strip sits flush at the top (padding 0, clipped corners) and the body is what the
   chosen day offers: the things that can be taken on the left, their free times on the
   right. A page with one thing to take (a meeting) writes its own body and uses the label
   alone. */

/* One area is no choice, so the picker above the card is not drawn. */
.areas { margin-bottom: 1rem; }
.areas:has(> :only-child) { display: none; }

.booking { padding: 0; overflow: hidden; }

.booking-label {
	margin: 0 0 0.7rem;
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--muted);
}

.booking-body {
	display: grid;
	grid-template-columns: minmax(14rem, 17rem) 1fr;
}
.services { padding: 1rem 1rem 1.25rem; border-inline-end: 1px solid var(--line); }
.times { padding: 1rem 1rem 1.25rem; }

.service {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	width: 100%;
	padding: 0.6rem 0.85rem;
	margin-bottom: 0.35rem;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--surface);
	color: var(--text);
	font: inherit;
	text-align: start;
	cursor: pointer;
	transition: border-color 0.15s ease, background 0.15s ease;
}
.service:hover { border-color: var(--text); }
.service.is-active { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.service.is-empty { opacity: 0.5; }
.service-name { font-weight: 600; }
.service-meta { display: block; font-size: 0.85rem; color: var(--muted); }
.service-price { margin-inline-start: auto; font-weight: 600; white-space: nowrap; }

.times .status { margin: 0.2rem 0 0; }

@media (max-width: 48rem) {
	.booking-body { grid-template-columns: 1fr; }
	.services { border-inline-end: 0; border-bottom: 1px solid var(--line); }
}

/* A summary and its total: what is being taken, one line each, and the sum under a rule -- */

.summary-line { margin: 0; color: var(--muted); }

.summary-total {
	display: flex;
	justify-content: space-between;
	margin: 0.9rem 0 0;
	padding-top: 0.9rem;
	border-top: 1px solid var(--line);
	font-size: 1.1rem;
}

/* The ways to pay: one radio row per method or kept card ------------------------------- */

.paymethods { display: grid; gap: 0.5rem; }

.paymethod {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 0.9rem 1.1rem;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--surface);
	cursor: pointer;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.paymethod:hover { border-color: var(--muted); }
.paymethod:has(input:checked) { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
/* The tick is INK, so it is the accent's ink token: a palette whose accent is a pale
   yellow draws a checked radio nobody can tell from an empty one. */
.paymethod input { width: 1.05rem; height: 1.05rem; accent-color: var(--accent-text); }

/* The card brands a merchant is required to show: monochrome-neutral, small, in the foot. */
.paybrands { display: inline-flex; align-items: center; gap: 0.75rem; }
.paybrands img { display: block; height: 1rem; width: auto; }
.paybrands img[alt="Mastercard"] { height: 1.25rem; }

/* The header on a narrow screen ----------------------------------------------------
   A template hides its menu links on a phone; the burger and the drawer under the bar are
   what gives them back, and site.js shows them exactly where the links went (a header that
   lays its menu out for a phone itself keeps its own answer and never sees these). The
   drawer sits in the flow under the header, so it pushes the page down instead of
   positioning over it — which is what lets it work inside a sticky header it knows
   nothing about. */

/* And WHERE the two of them sit while the menu is folded away: the burger at the start of
   the bar and the account at the end, which is how a phone's header reads everywhere. The
   template's own order stands at every other width — this applies only while the burger is
   showing, and it moves nothing else. */
.topbar-inner:has(> .nav-burger:not([hidden])) { justify-content: flex-start; }
.topbar-inner:has(> .nav-burger:not([hidden])) > .nav-burger { order: -1; }
.topbar-inner:has(> .nav-burger:not([hidden])) > .brand,
.topbar-inner:has(> .nav-burger:not([hidden])) > .logo { margin-inline-end: auto; }

.nav-burger {
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 4px;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	border: 0;
	border-radius: var(--radius-sm);
	background: none;
	cursor: pointer;
}
.nav-burger:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.nav-burger-bar {
	width: 1.1rem;
	height: 2px;
	border-radius: 2px;
	background: var(--text);
}

.nav-drawer:not([hidden]) {
	display: grid;
	gap: 0.15rem;
	padding-block: 0.5rem 0.9rem;
	border-top: 1px solid var(--line);
}
.nav-drawer a {
	padding: 0.6rem 0.2rem;
	color: var(--text);
	font: 500 1rem/1.3 var(--font);
	text-decoration: none;
}
.nav-drawer a:hover { color: var(--accent-text); }

/* The account corner: who is signed in, and the two things they do about it ---------
   The header carries [data-account]; the platform's site.js fills it with the member's
   avatar (a photo, or the initial of their name) and a small menu — My account, Sign out —
   once it knows somebody is signed in. A stranger keeps the plain Sign in link. */

.account { position: relative; display: inline-flex; align-items: center; }
.account-link { text-decoration: none; color: var(--muted); font-weight: 500; }
.account-link:hover { color: var(--text); }

.avatar {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	border: 1px solid var(--line);
	border-radius: 50%;
	background: color-mix(in srgb, var(--accent) 16%, var(--surface));
	color: var(--accent-text);
	font: 700 0.9rem/1 var(--font);
	cursor: pointer;
	overflow: hidden;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.avatar:hover { border-color: var(--muted); }

/* Fixed and hung off the body (site.js), so no rule the site writes about its own header
   can hide what is in it; the script puts it under the avatar. */
.account-pop {
	position: fixed;
	z-index: 900;
	min-width: 14rem;
	padding: 0.5rem;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--surface);
	box-shadow: var(--shadow);
	animation: pop 0.12s ease;
}
.account-who { display: grid; padding: 0.4rem 0.6rem 0.6rem; border-bottom: 1px solid var(--line); margin-bottom: 0.3rem; }
.account-who strong { font-size: 0.95rem; }
.account-who span { font-size: 0.82rem; color: var(--muted); overflow: hidden; text-overflow: ellipsis; }
.account-pop a, .account-pop button {
	display: block;
	width: 100%;
	padding: 0.45rem 0.6rem;
	border: 0;
	border-radius: 6px;
	background: none;
	color: var(--text);
	font: 500 0.92rem/1.3 var(--font);
	text-align: start;
	text-decoration: none;
	cursor: pointer;
}
.account-pop a:hover, .account-pop button:hover { background: var(--bg); }

/* Language is a visible header control, outside the navigation that folds into a drawer —
   ONE button beside the account, which site.js opens onto the list. The markup ships plain
   links, so a page with no JavaScript still switches language; there they read as a row of
   autonyms, which keep the way out legible even to a visitor who cannot read the page. */
.site-languages {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 0.25rem;
	flex-shrink: 0;
	font-size: 0.8125rem;
	line-height: 1.2;
}
.site-languages a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 0.5rem;
	color: inherit;
	text-decoration: none;
	white-space: nowrap;
	border-radius: var(--radius-control);
}
.site-languages a:hover { text-decoration: underline; text-underline-offset: 0.3em; }
.site-languages a[aria-current] { font-weight: 750; text-decoration: underline; text-underline-offset: 0.3em; }

.lang-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.25rem;
	height: 2.25rem;
	padding: 0;
	border: 0;
	border-radius: var(--radius-control);
	background: none;
	color: inherit;
	cursor: pointer;
}
.lang-button:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.lang-pop { min-width: 11rem; }
.lang-pop a[aria-current] { font-weight: 750; }

/* THE ACCOUNT IS ALWAYS THE LAST THING IN THE BAR — every template, every width
   (docs/WEBSITE.md). Wherever a header writes it, site.js moves it to the end of the bar
   and this keeps it there; the name holds the start — whatever the header calls it, .brand
   or .logo, because both are written and a bar that names it otherwise would silently stop
   holding anything — and the menu, the language and the account travel together at the other
   end. */
.topbar-inner > .account,
.topbar-inner > :has(.account) {
	order: 99;
}
.topbar-inner:has(> .account) { justify-content: flex-start; }
.topbar-inner:has(> .account) > .brand,
.topbar-inner:has(> .account) > .logo { margin-inline-end: auto; }

/* A background slideshow leaves the heading and booking action still. */
.hero-slides { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.hero-slides [data-slide] { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 1.2s ease; }
.hero-slides [data-slide].is-active { opacity: 1; }
.slideshow-controls { display: flex; align-items: center; gap: 0.35rem; color: inherit; }
.slideshow-controls[hidden] { display: none; }
.slideshow-controls [data-slide-dots] { display: flex; align-items: center; }
.slideshow-controls button { display: grid; place-items: center; width: 28px; height: 32px; padding: 0; border: 0; border-radius: 999px; background: transparent; color: inherit; cursor: pointer; }
.slideshow-controls .slideshow-dot::before { content: ""; width: 6px; height: 6px; border-radius: 999px; background: currentColor; opacity: 0.45; transition: width 0.25s, opacity 0.25s; }
.slideshow-controls .slideshow-dot[aria-pressed="true"] { width: 36px; }
.slideshow-controls .slideshow-dot[aria-pressed="true"]::before { width: 22px; opacity: 1; }
.slideshow-controls button:hover { background: #FFFFFF18; }
.slideshow-controls button:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.slideshow-controls [data-slide-pause] { width: 32px; font-size: 0.8rem; opacity: 0.7; }
.slideshow-controls [data-slide-pause]:hover { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .hero-slides [data-slide] { transition: none; } }
