/* 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;
}

/* 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;
	--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: 6px; }

/* 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); }

/* 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.6rem, 3vw, 2.4rem);
}
.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 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%; }

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

.button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	padding: 0.8rem 1.5rem;
	border: 1.5px solid var(--text);
	border-radius: var(--radius-sm);
	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; }

/* 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: 6px;
	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;
}

.form button[type="submit"] {
	justify-self: start;
	margin-top: 0.9rem;
	padding: 0.5rem 1.1rem;
	border: 1px solid var(--accent);
	border-radius: 6px;
	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"]:hover { transform: translateY(-1px); box-shadow: var(--shadow); }
.form button[type="submit"][disabled] { opacity: 0.55; transform: none; cursor: default; }

/* A field with a control living inside it — the password eye. */
.field-affix { position: relative; }
.field-affix input { padding-right: 3rem; }
.field-affix .affix {
	position: absolute;
	right: 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); }

/* 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); }

/* 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: 999px;
	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: 1rem 1.25rem;
	border-bottom: 1px solid var(--line);
	background: color-mix(in srgb, var(--text) 3%, var(--surface));
}

.daynav {
	flex: none;
	width: 2.4rem;
	height: 2.4rem;
	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.15rem;
	padding: 0.55rem 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.15rem; 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.66rem; }
}

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

.time {
	padding: 0.75rem 0.5rem;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--surface);
	color: var(--text);
	font: 600 1rem/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); }

/* 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: 1.25rem; }
.areas:has(> :only-child) { display: none; }
.areas .tab img { width: 1.6rem; height: 1.6rem; border-radius: 50%; object-fit: cover; }

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

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

.booking-body {
	display: grid;
	grid-template-columns: minmax(15rem, 20rem) 1fr;
}
.services { padding: 1.5rem 1.5rem 1.75rem; border-right: 1px solid var(--line); }
.times { padding: 1.5rem 1.5rem 1.75rem; }

.service {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	width: 100%;
	padding: 0.85rem 1rem;
	margin-bottom: 0.4rem;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--surface);
	color: var(--text);
	font: inherit;
	text-align: left;
	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-left: 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-right: 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); }
.paymethod input { width: 1.05rem; height: 1.05rem; accent-color: var(--accent); }

/* 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 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); }

.account-pop {
	position: absolute;
	top: calc(100% + 0.5rem);
	right: 0;
	z-index: 20;
	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: left;
	text-decoration: none;
	cursor: pointer;
}
.account-pop a:hover, .account-pop button:hover { background: var(--bg); }
