/* Slotti booking widget.
 *
 * Mobile-first and single column, because most of these bookings are made on
 * a phone, standing in a shop or on a bus.
 *
 * Colours, radii and shadows come from the host theme's custom properties
 * with fallbacks, so the widget looks like it belongs on a themed site and
 * still looks deliberate on a stock one. What it must never do is reference a
 * theme's class names or import its stylesheet: that is a dependency in the
 * wrong direction, and it would break the moment somebody changed a theme.
 *
 * Two rules run through the whole file. Availability is never signalled by
 * colour alone — a free day carries a dot, a chosen one carries a filled
 * shape, and both are named in the accessible label. And every focus ring is
 * an outline, not a colour swap, so it survives a high-contrast mode and a
 * customer who cannot pick blue out of grey. Some of these customers are
 * booking precisely because they cannot see well.
 */

.slotti-booking,
.slotti-modal {
	--slotti-accent: var(--accent, #2f6fe0);
	--slotti-accent-ink: var(--accent-ink, #2458b3);

	/* The very light accent fill the cards and the chosen day wear. The
	   fallback is a literal rather than a color-mix() of its own: the theme
	   this was drawn against computes one, and a plugin that shipped the
	   computation would inherit whatever accent a stock theme happened to
	   have and mix an unreadable wash out of it. */
	--slotti-accent-wash: var(--accent-wash, #eef3fd);
	--slotti-on-accent: var(--accent-contrast, #ffffff);
	--slotti-ink: var(--ink, #1a1a1a);
	--slotti-ink-soft: var(--ink-soft, #41464d);
	--slotti-ink-muted: var(--ink-muted, #6b7280);
	--slotti-bg: var(--bg, #ffffff);
	--slotti-tint: var(--tint, #f4f8fc);
	--slotti-line: var(--line, #e7ecf3);
	--slotti-radius: var(--r-md, var(--radius, 12px));
	--slotti-radius-sm: var(--r-sm, 10px);
	--slotti-shadow: var(--shadow-md, 0 4px 14px rgba(20, 40, 80, .07), 0 18px 40px rgba(20, 40, 80, .07));
	--slotti-danger: #b3261e;
	--slotti-danger-wash: #fdf1f0;
	--slotti-tap: 44px;

	box-sizing: border-box;
	color: var(--slotti-ink);
	font-family: inherit;
	line-height: 1.5;
	text-align: left;
}

.slotti-booking *,
.slotti-modal * {
	box-sizing: border-box;
}

.slotti-booking {
	max-width: 40rem;
}

/* The fallback is visible until the script says otherwise — the same way
   round as the reveal-on-scroll pattern, and for the same reason: content
   that something has to hide survives every failure, content that something
   has to reveal survives none of them. */
.slotti-booking.slotti-has-js > .slotti-fallback {
	display: none;
}

.slotti-fallback {
	background: var(--slotti-tint);
	border-radius: var(--slotti-radius);
	padding: 20px;
}

.slotti-fallback > :first-child {
	margin-top: 0;
}

.slotti-fallback > :last-child {
	margin-bottom: 0;
}

/* ---- steps ---- */

.slotti-step {
	margin: 0;
}

.slotti-step__title {
	font-size: 1.25rem;
	font-weight: 600;
	line-height: 1.25;
	margin: 0 0 4px;
}

/* Focus lands here when a step opens, and a heading is not normally
   focusable, so the ring has to be asked for explicitly. */
.slotti-step__title:focus {
	outline: none;
}

.slotti-step__title:focus-visible {
	outline: 2px solid var(--slotti-accent);
	outline-offset: 4px;
}

.slotti-step__hint,
.slotti-chosen {
	color: var(--slotti-ink-muted);
	font-size: .9375rem;
	margin: 0 0 16px;
}

.slotti-chosen strong {
	color: var(--slotti-ink);
}

.slotti-actions {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin-top: 24px;
}

/* ---- buttons ---- */

.slotti-btn {
	background: var(--slotti-tint);
	border: 1px solid var(--slotti-line);
	border-radius: 999px;
	color: var(--slotti-ink);
	cursor: pointer;
	font: inherit;
	font-weight: 600;
	line-height: 1.2;
	min-height: var(--slotti-tap);
	padding: 12px 22px;
}

.slotti-btn:hover {
	border-color: var(--slotti-ink-muted);
}

.slotti-btn--primary {
	background: var(--slotti-accent);
	border-color: var(--slotti-accent);
	color: var(--slotti-on-accent);
}

.slotti-btn--primary:hover {
	background: var(--slotti-accent-ink);
	border-color: var(--slotti-accent-ink);
}

.slotti-btn[disabled] {
	cursor: default;
	opacity: .55;
}

.slotti-link {
	background: none;
	border: 0;
	color: var(--slotti-accent);
	cursor: pointer;
	font: inherit;
	padding: 6px 2px;
	text-decoration: underline;
}

.slotti-booking :focus-visible,
.slotti-modal :focus-visible {
	outline: 2px solid var(--slotti-accent);
	outline-offset: 2px;
}

/* ---- option lists: services, prescription, practitioners ---- */

.slotti-options {
	display: grid;
	gap: 10px;
	list-style: none;
	margin: 0;
	padding: 0;
}

.slotti-option {
	background: var(--slotti-bg);
	border: 1px solid var(--slotti-line);
	border-radius: var(--slotti-radius);
	color: inherit;
	cursor: pointer;
	display: block;
	font: inherit;
	min-height: var(--slotti-tap);
	padding: 16px 18px;
	text-align: left;
	width: 100%;
}

.slotti-option:hover {
	border-color: var(--slotti-accent);
}

.slotti-option__name {
	display: block;
	font-weight: 600;
}

.slotti-option__meta {
	color: var(--slotti-ink-muted);
	display: block;
	font-size: .9375rem;
	margin-top: 2px;
}

.slotti-option__price {
	float: right;
	font-weight: 600;
	margin-left: 12px;
}

.slotti-option__body {
	color: var(--slotti-ink-soft);
	font-size: .9375rem;
	margin: 8px 0 0;
}

.slotti-option__body p {
	margin: 0 0 6px;
}

/* ---- month grid ---- */

.slotti-cal__head {
	align-items: center;
	display: flex;
	gap: 8px;
	justify-content: space-between;
	margin-bottom: 8px;
}

.slotti-cal__title {
	font-size: 1.0625rem;
	font-weight: 600;
	margin: 0;
	text-align: center;
}

.slotti-cal__nav {
	background: none;
	border: 1px solid var(--slotti-line);
	border-radius: 50%;
	color: inherit;
	cursor: pointer;
	flex: none;
	font: inherit;
	height: var(--slotti-tap);
	line-height: 0;
	width: var(--slotti-tap);
}

.slotti-cal__nav[disabled] {
	cursor: default;
	opacity: .4;
}

.slotti-cal__nav svg {
	height: 18px;
	width: 18px;
}

.slotti-cal {
	border-collapse: collapse;
	table-layout: fixed;
	width: 100%;
}

.slotti-cal th {
	color: var(--slotti-ink-muted);
	font-size: .8125rem;
	font-weight: 600;
	padding: 6px 0;
	text-align: center;
}

/* No horizontal padding: at 360px the seven columns have 308px between them,
   and a cell that spent 4px on padding left a 40px button — under the 44px a
   fingertip needs. The vertical padding still separates the rows. */
.slotti-cal td {
	padding: 2px 0;
	text-align: center;
}

.slotti-day {
	background: none;
	border: 1px solid transparent;
	border-radius: var(--slotti-radius-sm);
	color: inherit;
	cursor: pointer;
	font: inherit;
	line-height: 1;
	min-height: var(--slotti-tap);
	padding: 6px 0 4px;
	width: 100%;
}

.slotti-day:hover {
	border-color: var(--slotti-accent);
}

/* The dot is the point: a day with times has one, a day without has none, so
   availability reads without relying on the colour of the number. */
.slotti-day__dot {
	background: var(--slotti-accent);
	border-radius: 50%;
	display: block;
	height: 5px;
	margin: 5px auto 0;
	width: 5px;
}

.slotti-day__dot--empty {
	background: none;
}

.slotti-day[aria-disabled="true"] {
	color: var(--slotti-ink-muted);
	cursor: default;
	opacity: .5;
}

.slotti-day[aria-disabled="true"]:hover {
	border-color: transparent;
}

.slotti-cal td[aria-selected="true"] .slotti-day {
	background: var(--slotti-accent);
	border-color: var(--slotti-accent);
	color: var(--slotti-on-accent);
	font-weight: 700;
}

.slotti-cal td[aria-selected="true"] .slotti-day__dot {
	background: var(--slotti-on-accent);
}

.slotti-today {
	box-shadow: inset 0 0 0 1px var(--slotti-line);
}

/* ---- times ---- */

.slotti-slots {
	border: 0;
	margin: 0;
	min-width: 0;
	padding: 0;
}

.slotti-slots__group {
	margin-top: 16px;
}

.slotti-slots__label {
	color: var(--slotti-ink-muted);
	font-size: .875rem;
	font-weight: 600;
	margin: 0 0 8px;
	text-transform: uppercase;
}

.slotti-slots__grid {
	display: grid;
	gap: 8px;
	grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
}

.slotti-slot {
	display: block;
	position: relative;
}

.slotti-slot input {
	height: 1px;
	opacity: 0;
	position: absolute;
	width: 1px;
}

.slotti-slot span {
	align-items: center;
	border: 1px solid var(--slotti-line);
	border-radius: var(--slotti-radius-sm);
	cursor: pointer;
	display: flex;
	justify-content: center;
	min-height: var(--slotti-tap);
	padding: 10px 6px;
}

.slotti-slot input:checked + span {
	background: var(--slotti-accent);
	border-color: var(--slotti-accent);
	color: var(--slotti-on-accent);
	font-weight: 700;
}

.slotti-slot input:focus-visible + span {
	outline: 2px solid var(--slotti-accent);
	outline-offset: 2px;
}

/* ---- details form ---- */

.slotti-field {
	margin-bottom: 18px;
}

/* :not(.slotti-check) matters. The consent row is a label inside a field too,
   and this rule (0,1,1) outranks .slotti-check (0,1,0) — which quietly made it
   display:block, so its flex gap did nothing and the box sat against its own
   first word. */
.slotti-field > label:not(.slotti-check),
.slotti-fieldset > legend {
	display: block;
	font-size: .9375rem;
	font-weight: 600;
	line-height: 1.4;
	margin-bottom: 6px;
	padding: 0;
}

.slotti-field input[type="text"],
.slotti-field input[type="tel"],
.slotti-field input[type="email"],
.slotti-field textarea {
	background: var(--slotti-bg);
	border: 1px solid var(--slotti-line);
	border-radius: var(--slotti-radius-sm);
	color: inherit;
	font: inherit;
	min-height: var(--slotti-tap);
	padding: 11px 14px;
	width: 100%;
}

.slotti-field textarea {
	min-height: 90px;
	resize: vertical;
}

.slotti-field input[type="text"]:focus-visible,
.slotti-field input[type="tel"]:focus-visible,
.slotti-field input[type="email"]:focus-visible,
.slotti-field textarea:focus-visible {
	border-color: var(--slotti-accent);
	box-shadow: 0 0 0 3px var(--slotti-accent-wash);
	outline: none;
}

.slotti-hint {
	color: var(--slotti-ink-muted);
	font-size: .875rem;
	margin: 4px 0 0;
}

.slotti-error {
	color: var(--slotti-danger);
	font-size: .875rem;
	font-weight: 600;
	margin: 4px 0 0;
}

.slotti-field--invalid input,
.slotti-field--invalid textarea {
	border-color: var(--slotti-danger);
	border-width: 2px;
}

.slotti-fieldset {
	border: 0;
	margin: 0 0 16px;
	min-width: 0;
	padding: 0;
}

.slotti-choices {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.slotti-check {
	align-items: flex-start;
	cursor: pointer;
	display: flex;
	font-weight: 400;
	gap: 10px;
	min-height: var(--slotti-tap);
	padding: 10px 0;
}

/* Drawn, not native. Slotti runs inside somebody else's theme, and a native
   control inherits whatever that theme did to it — which is how the consent
   box came to sit flush against its own label, gap or no gap. Drawing it is
   also the only way the tick matches the accent the rest of the widget uses. */
.slotti-check input {
	-webkit-appearance: none;
	appearance: none;
	background: var(--slotti-bg);
	border: 1px solid var(--slotti-line);
	border-radius: 6px;
	cursor: pointer;
	flex: none;
	height: 20px;
	margin: 2px 0 0;
	position: relative;
	width: 20px;
}

.slotti-check input[type="radio"] {
	border-radius: 50%;
}

.slotti-check input:checked {
	background: var(--slotti-accent);
	border-color: var(--slotti-accent);
}

.slotti-check input[type="checkbox"]:checked::after {
	border: solid var(--slotti-on-accent);
	border-width: 0 2px 2px 0;
	content: "";
	height: 10px;
	left: 6px;
	position: absolute;
	top: 2px;
	transform: rotate(45deg);
	width: 5px;
}

.slotti-check input[type="radio"]:checked::after {
	background: var(--slotti-on-accent);
	border-radius: 50%;
	content: "";
	inset: 4px;
	position: absolute;
}

.slotti-check input:focus-visible {
	outline: 2px solid var(--slotti-accent);
	outline-offset: 2px;
}

.slotti-check > span {
	line-height: 1.5;
}

.slotti-check a {
	color: var(--slotti-accent);
}

/* The honeypot. Off-screen rather than display:none, because plenty of bots
   skip anything that is not rendered, and named so a password manager has
   nothing to recognise — this form has a real company field, and a hidden one
   called "company" would get filled in for a real customer. */
.slotti-trap {
	height: 1px;
	left: -9999px;
	overflow: hidden;
	position: absolute;
	top: auto;
	width: 1px;
}

/* ---- review ---- */

.slotti-review {
	border-top: 1px solid var(--slotti-line);

	/* The review step has no hint line under its title, so without this the
	   table starts immediately under the heading. */
	margin: 18px 0 8px;
}

.slotti-review__row {
	align-items: baseline;
	border-bottom: 1px solid var(--slotti-line);
	display: flex;
	flex-wrap: wrap;
	gap: 6px 16px;
	padding: 15px 0;
}

.slotti-review__key {
	color: var(--slotti-ink-muted);
	flex: none;
	font-size: .875rem;
	line-height: 1.5;
	padding-top: 1px;
	width: 7.5rem;
}

.slotti-review__value {
	flex: 1 1 8rem;
	font-weight: 600;
	line-height: 1.5;
	margin: 0;
	overflow-wrap: anywhere;
}

/* ---- notices, loading ---- */

.slotti-notice {
	background: var(--slotti-tint);
	border-left: 4px solid var(--slotti-accent);
	border-radius: var(--slotti-radius-sm);
	margin: 0 0 16px;
	padding: 14px 16px;
}

.slotti-notice--bad {
	background: var(--slotti-danger-wash);
	border-left-color: var(--slotti-danger);
}

.slotti-notice p {
	margin: 0 0 8px;
}

.slotti-notice > :last-child {
	margin-bottom: 0;
}

.slotti-empty {
	color: var(--slotti-ink-muted);
	margin: 0 0 16px;
}

/* Reserves the height a step is about to need, so the page does not jump when
   the answer arrives. */
.slotti-loading {
	align-items: center;
	color: var(--slotti-ink-muted);
	display: flex;
	justify-content: center;
	min-height: 220px;
}

.slotti-vh {
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	overflow: hidden;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

/* ---- modal ---- */

.slotti-locked {
	overflow: hidden;
}

.slotti-modal {
	bottom: 0;
	display: flex;
	left: 0;
	position: fixed;
	right: 0;
	top: 0;
	z-index: 100000;
}

.slotti-modal__scrim {
	background: rgba(16, 24, 40, .55);
	bottom: 0;
	left: 0;
	position: absolute;
	right: 0;
	top: 0;
}

.slotti-modal__panel {
	background: var(--slotti-bg);
	display: flex;
	flex-direction: column;
	margin: auto;
	max-height: 100%;
	overflow: hidden;
	position: relative;
	width: 100%;
}

/* Only the close button lives here now. The bar used to be a titled,
   bordered strip, which meant the dialog announced itself twice over —
   once here and again in the widget's own "BRONEERI AEG · SAMM n/m" line
   directly beneath it. The design has one. */
.slotti-modal__bar {
	position: absolute;
	right: 10px;
	top: 10px;
	z-index: 2;
}

/* Kept in the DOM: it is the dialog's accessible name and the element that
   takes focus when the modal opens. It just has nothing to say visually. */
.slotti-modal__title {
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	margin: 0;
	overflow: hidden;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

.slotti-modal__close {
	background: var(--slotti-bg);
	border: 1px solid var(--slotti-line);
	border-radius: 50%;
	color: inherit;
	cursor: pointer;
	flex: none;
	height: var(--slotti-tap);
	line-height: 0;
	width: var(--slotti-tap);
}

.slotti-modal__close svg {
	height: 18px;
	width: 18px;
}

/* The close button is absolutely placed over the body's top-right corner, so
   the step line stops short of it and the progress bar starts below it.
   Nothing here applies to the widget rendered on a page: it has no button. */
.slotti-modal__body .slotti-progress__label {
	margin-bottom: 18px;
	padding-right: 52px;
}

.slotti-modal__body {
	-webkit-overflow-scrolling: touch;
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	padding: 24px 16px 28px;

	/* Firefox. The thumb only, no track, so nothing draws a line down the
	   panel's edge. */
	scrollbar-color: rgba(16, 24, 40, .2) transparent;
	scrollbar-width: thin;
}

/* WebKit and Blink. The transparent border plus background-clip is what
   makes the thumb read as a floating pill rather than a bar wedged against
   the panel wall. */
.slotti-modal__body::-webkit-scrollbar {
	width: 10px;
}

.slotti-modal__body::-webkit-scrollbar-track {
	background: transparent;
}

.slotti-modal__body::-webkit-scrollbar-thumb {
	background: rgba(16, 24, 40, .2);
	background-clip: padding-box;
	border: 3px solid transparent;
	border-radius: 999px;
}

.slotti-modal__body::-webkit-scrollbar-thumb:hover {
	background: rgba(16, 24, 40, .34);
	background-clip: padding-box;
	border: 3px solid transparent;
}

@media (min-width: 40em) {
	.slotti-modal {
		padding: 24px;
	}

	.slotti-modal__panel {
		border-radius: var(--slotti-radius);
		box-shadow: var(--slotti-shadow);
		max-height: calc(100% - 48px);
		max-width: 34rem;
	}

	.slotti-modal__bar {
		right: 14px;
		top: 14px;
	}

	.slotti-modal__body {
		padding: 26px 24px 32px;
	}
}

@media (prefers-reduced-motion: no-preference) {
	.slotti-modal__panel {
		animation: slotti-rise .18s ease-out;
	}

	@keyframes slotti-rise {
		from {
			opacity: 0;
			transform: translateY(12px);
		}
	}
}

@media (prefers-contrast: more) {
	.slotti-option,
	.slotti-slot span,
	.slotti-day {
		border-color: currentColor;
	}
}

/* ---- manage view ---- */

/* Server-rendered, so these are the only classes on the page that have to
   look right before any JavaScript has run at all. */

/* The primary and the secondary action on one row. The filled button does
   the likely thing; cancelling is a link beside it, in the danger colour so
   it is not taken for a second way forward, but not filled, so it does not
   compete with the button it sits next to. */
.slotti-manage__actions {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 8px 20px;
	margin: 20px 0 0;
}

/* Where the reschedule picker mounts, under the actions. Empty until the
   button is pressed, and an empty element must take no room: it is the last
   thing on the page, and its margin would be a blank band under the row. */
.slotti-manage__move {
	margin: 20px 0 0;
}

.slotti-manage__move:empty {
	display: none;
}

.slotti-manage__again {
	margin: 24px 0 0;
}

/* The two ways into the customer's own calendar, under the details. A note
   above the buttons rather than beside them: it is one sentence about why
   they are here, and it must not read as a third button. */
.slotti-manage__calendar {
	margin: 0;
}

.slotti-manage__calendar-note {
	color: var(--slotti-ink-muted);
	font-size: .9375rem;
	margin: 0 0 8px;
}

.slotti-manage__calendar-links {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0;
}

/* Larger than the 18px the widget's own buttons carry: these two are the
   only thing on their row, and the mark is half of what tells them apart. */
.slotti-manage__calendar-links .slotti-btn__icon svg {
	height: 24px;
	width: 24px;
}

/* Soft: the accent's wash rather than its fill, for an action that helps
   rather than commits — adding the booking to a calendar changes nothing
   here. The text is the accent's ink and not the accent: on the wash the
   accent itself reads at about 4:1, under the 4.5:1 text needs. */
.slotti-btn--soft {
	background: var(--slotti-accent-wash);
	border-color: var(--slotti-accent-wash);
	color: var(--slotti-accent-ink);
}

.slotti-btn--soft:hover {
	border-color: var(--slotti-accent);
}

/* Quiet: the lesser of two choices, for "No, keep it" and "Book another
   time". The muted ink reads at 4.8:1 on white and 4.5:1 on the tint. Hover
   darkens it; it used to turn red, from the days this was the cancel link. */
.slotti-btn--quiet {
	background: none;
	border-color: var(--slotti-line);
	color: var(--slotti-ink-muted);
	font-weight: 500;
}

.slotti-btn--quiet:hover {
	border-color: var(--slotti-ink-muted);
	color: var(--slotti-ink);
}

/* Link-styled, in the danger colour — 6.5:1 on white — and underlined only
   on hover, which is how the rest of the page's links behave. At rest it is
   the quieter of the two actions on its row; it is never the filled red of
   .slotti-btn--danger, which is kept for the button that actually cancels. */
.slotti-btn--link-danger {
	background: none;
	border-color: transparent;
	color: var(--slotti-danger);
	padding-left: 4px;
	padding-right: 4px;
}

.slotti-btn--link-danger:hover {
	border-color: transparent;
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* The confirmation step before a cancellation. Boxed rather than inline,
   because the question has to read as a stop rather than as one more thing on
   the page — the customer arrived here from a link that looked harmless. */
.slotti-manage__confirm {
	border: 1px solid var(--slotti-line);
	border-radius: var(--slotti-radius);
	margin: 24px 0 0;
	padding: 16px;
}

.slotti-manage__confirm-title {
	font-size: 1.0625rem;
	margin: 0 0 8px;
}

.slotti-manage__confirm p {
	color: var(--slotti-ink-muted);
	margin: 0 0 16px;
}

.slotti-manage__confirm form {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}

.slotti-btn--danger {
	background: var(--slotti-danger);
	border-color: var(--slotti-danger);
	color: #fff;
}

.slotti-btn--danger:hover {
	filter: brightness(.92);
}

.slotti-summary {
	border-top: 1px solid var(--slotti-line);
	margin: 0 0 16px;
}

.slotti-summary__row {
	align-items: baseline;
	border-bottom: 1px solid var(--slotti-line);
	display: flex;
	flex-wrap: wrap;
	gap: 4px 12px;
	padding: 12px 0;
}

.slotti-summary dt {
	color: var(--slotti-ink-muted);
	flex: none;
	font-size: .9375rem;
	width: 8.5rem;
}

.slotti-summary dd {
	flex: 1 1 8rem;
	font-weight: 600;
	margin: 0;
	overflow-wrap: anywhere;
}

/* The launcher sets this on a theme's own booking button while the widget is
   being fetched. It is defined here for completeness, but deliberately not
   relied on: on a page carrying only the launcher this stylesheet is one of
   the two files still on their way, so the launcher sets an inline style too. */
.slotti-is-loading {
	opacity: .7;
}

/* ---- the step header ---- */

/* An eyebrow saying which of the four steps this is, and a bar per step. The
   bar is decorative — role="img" with a label carries the same fact to a
   screen reader — so nothing here is the only way to know where you are. */
.slotti-progress {
	margin: 0 0 20px;
}

.slotti-progress__label {
	color: var(--slotti-accent);
	font-size: .8125rem;
	font-weight: 600;
	letter-spacing: .1em;
	margin: 0 0 12px;
	text-transform: uppercase;
}

.slotti-progress__bar {
	display: flex;
	gap: 8px;
}

.slotti-progress__step {
	background: var(--slotti-line);
	border-radius: 3px;
	flex: 1;
	height: 5px;
}

.slotti-progress__step.is-done {
	background: var(--slotti-accent);
}

/* ---- the practitioner selector ---- */

.slotti-who {
	border: 0;
	margin: 0 0 16px;
	min-width: 0;
	padding: 0;
}

.slotti-who__legend {
	color: var(--slotti-ink-muted);
	font-size: .875rem;
	font-weight: 600;
	margin-bottom: 8px;
	padding: 0;
}

.slotti-who__row {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.slotti-who__pill {
	cursor: pointer;
	display: block;
	position: relative;
}

.slotti-who__pill input {
	height: 1px;
	opacity: 0;
	position: absolute;
	width: 1px;
}

.slotti-who__pill span {
	border: 1px solid var(--slotti-line);
	border-radius: 999px;
	display: block;
	padding: 9px 16px;
}

.slotti-who__pill input:checked + span {
	background: var(--slotti-accent-wash);
	border-color: var(--slotti-accent);
	color: var(--slotti-accent-ink);
	font-weight: 600;
}

.slotti-who__pill input:focus-visible + span {
	outline: 2px solid var(--slotti-accent);
	outline-offset: 2px;
}

/* ---- the day strip ---- */

/* Five columns whatever the screen, because the cells are small and a strip
   that wrapped to two rows would read as a grid rather than as a shortlist. */
.slotti-strip {
	display: grid;
	gap: 8px;
	grid-template-columns: repeat(5, 1fr);
}

.slotti-strip__day {
	cursor: pointer;
	display: block;
	position: relative;
}

.slotti-strip__day input {
	height: 1px;
	opacity: 0;
	position: absolute;
	width: 1px;
}

.slotti-strip__box {
	border: 1px solid var(--slotti-line);
	border-radius: var(--slotti-radius);
	display: block;
	line-height: 1.2;
	min-height: var(--slotti-tap);
	padding: 10px 2px;
	text-align: center;
}

.slotti-strip__dow {
	color: var(--slotti-ink-muted);
	display: block;
	font-size: .75rem;
}

.slotti-strip__num {
	display: block;
	font-size: 1.25rem;
	font-weight: 600;
	margin-top: 2px;
}

.slotti-strip__mon {
	color: var(--slotti-ink-muted);
	display: block;
	font-size: .6875rem;
}

.slotti-strip__day input:checked + .slotti-strip__box {
	background: var(--slotti-accent-wash);
	border-color: var(--slotti-accent);
	color: var(--slotti-accent-ink);
}

.slotti-strip__day input:checked + .slotti-strip__box .slotti-strip__dow,
.slotti-strip__day input:checked + .slotti-strip__box .slotti-strip__mon {
	color: inherit;
}

.slotti-strip__day input:focus-visible + .slotti-strip__box {
	outline: 2px solid var(--slotti-accent);
	outline-offset: 2px;
}

.slotti-more {
	margin: 12px 0 0;
}

.slotti-cal__wrap {
	margin: 0;
}

.slotti-slots__day {
	color: var(--slotti-ink-muted);
	font-size: .9375rem;
	margin: 20px 0 0;
}

/* The time being moved from, above the manage flow's list of times. */
.slotti-move__current {
	color: var(--slotti-ink-muted);
	font-size: .9375rem;
	margin: 0;
}

/* ---- service cards ---- */

.slotti-cards {
	display: grid;
	gap: 10px;
	list-style: none;
	margin: 0 0 16px;
	padding: 0;
}

.slotti-card {
	align-items: center;
	background: var(--slotti-bg);
	border: 1px solid var(--slotti-line);
	border-radius: var(--slotti-radius);
	cursor: pointer;
	display: flex;
	gap: 14px;
	padding: 14px 16px;
	position: relative;
}

.slotti-card:hover {
	border-color: var(--slotti-accent);
}

/* The checkbox is what a keyboard and a screen reader operate; the tick on
   the right is a picture of its state. Hiding it with display:none would take
   it out of the tab order and out of the accessibility tree with it. */
.slotti-card input {
	height: 1px;
	opacity: 0;
	position: absolute;
	width: 1px;
}

.slotti-card__icon {
	align-items: center;
	background: var(--slotti-accent-wash);
	border-radius: 12px;
	color: var(--slotti-accent-ink);
	display: flex;
	flex: none;
	height: 44px;
	justify-content: center;
	width: 44px;
}

.slotti-card__icon svg {
	height: 22px;
	width: 22px;
}

.slotti-card__text {
	flex: 1;
	min-width: 0;
}

.slotti-card__name {
	display: block;
	font-weight: 600;
}

.slotti-card__meta {
	color: var(--slotti-ink-muted);
	display: block;
	font-size: .9375rem;
	margin-top: 2px;
}

.slotti-card__body {
	color: var(--slotti-ink-soft);
	display: block;
	font-size: .875rem;
	margin-top: 6px;
}

.slotti-card__body p {
	margin: 0 0 4px;
}

/* Why, not just that. A service that vanishes reads as a bug; one that says
   it will not fit the time chosen tells the customer what to do about it. */
.slotti-card__why {
	color: var(--slotti-danger);
	display: block;
	font-size: .875rem;
	font-weight: 600;
	margin-top: 6px;
}

.slotti-card__tick {
	align-items: center;
	border: 1px solid var(--slotti-line);
	border-radius: 50%;
	color: transparent;
	display: flex;
	flex: none;
	height: 24px;
	justify-content: center;
	width: 24px;
}

.slotti-card__tick svg {
	height: 14px;
	width: 14px;
}

.slotti-card input:checked ~ .slotti-card__tick {
	background: var(--slotti-accent);
	border-color: var(--slotti-accent);
	color: var(--slotti-on-accent);
}

.slotti-card:has( input:checked ) {
	background: var(--slotti-accent-wash);
	border-color: var(--slotti-accent);
}

.slotti-card input:focus-visible ~ .slotti-card__tick {
	outline: 2px solid var(--slotti-accent);
	outline-offset: 2px;
}

/* Dimmed and not clickable, but still there and still readable — including
   the sentence saying why, which is the whole point of not hiding it. */
.slotti-card--blocked {
	cursor: default;
	opacity: .6;
}

.slotti-card--blocked:hover {
	border-color: var(--slotti-line);
}

/* ---- the running total ---- */

.slotti-total {
	background: var(--slotti-tint);
	border-radius: var(--slotti-radius);
	margin: 0 0 16px;
	padding: 14px 16px;
}

.slotti-total__sum {
	font-weight: 600;
	margin: 0;
}

.slotti-total__left {
	color: var(--slotti-ink-muted);
	font-size: .9375rem;
	margin: 4px 0 0;
}

/* ---- the prescription question, inline ---- */

.slotti-rx {
	background: var(--slotti-tint);
	border: 0;
	border-radius: var(--slotti-radius);
	margin: 0 0 16px;
	min-width: 0;
	padding: 14px 16px;
}

.slotti-rx__legend {
	font-weight: 600;
	padding: 0;
}

.slotti-rx__cost {
	color: var(--slotti-ink-muted);
	font-size: .9375rem;
	margin: 4px 0 10px;
}

.slotti-rx__options {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.slotti-rx__option {
	cursor: pointer;
	display: block;
	flex: 1 1 12rem;
	position: relative;
}

.slotti-rx__option input {
	height: 1px;
	opacity: 0;
	position: absolute;
	width: 1px;
}

.slotti-rx__option span {
	background: var(--slotti-bg);
	border: 1px solid var(--slotti-line);
	border-radius: var(--slotti-radius-sm);
	display: block;
	min-height: var(--slotti-tap);
	padding: 11px 14px;
}

.slotti-rx__option input:checked + span {
	background: var(--slotti-accent-wash);
	border-color: var(--slotti-accent);
	box-shadow: inset 0 0 0 1px var(--slotti-accent);
	color: var(--slotti-accent-ink);
	font-weight: 600;
}

.slotti-rx__option input:focus-visible + span {
	outline: 2px solid var(--slotti-accent);
	outline-offset: 2px;
}

/* ---- the shop's own note ---- */

/* Dashed rather than filled, so it reads as an aside rather than as one more
   thing to choose. Empty on a fresh install and never rendered then. */
.slotti-note {
	border: 1px dashed var(--slotti-line);
	border-radius: var(--slotti-radius);
	color: var(--slotti-ink-muted);
	font-size: .9375rem;
	margin: 0 0 16px;
	padding: 14px 16px;
}

.slotti-note > :first-child {
	margin-top: 0;
}

.slotti-note > :last-child {
	margin-bottom: 0;
}

/* ---- buttons with an icon ---- */

.slotti-btn {
	align-items: center;
	display: inline-flex;
	gap: 8px;
	justify-content: center;
}

.slotti-btn__icon {
	display: inline-flex;
	line-height: 0;
}

.slotti-btn__icon svg {
	height: 18px;
	width: 18px;
}

/* The primary action sits on the right, where the design puts it, and Back
   stays on the left of it. */
.slotti-actions {
	flex-direction: row-reverse;
	justify-content: flex-start;
}

.slotti-btn--back {
	background: none;
	border-color: transparent;
	color: var(--slotti-ink-soft);
}

.slotti-btn--back:hover {
	border-color: transparent;
	color: var(--slotti-ink);
}

/* ---- the review list ---- */

.slotti-review__list {
	flex: 1 1 8rem;
	font-weight: 600;
	list-style: none;
	margin: 0;
	padding: 0;
}

.slotti-review__list li {
	line-height: 1.5;
	overflow-wrap: anywhere;
}

.slotti-review__list li + li {
	margin-top: 4px;
}

@media (prefers-contrast: more) {
	.slotti-card,
	.slotti-strip__box,
	.slotti-rx__option span,
	.slotti-who__pill span {
		border-color: currentColor;
	}
}

/* A set that no longer fits reads as a warning rather than as a tally. It is
   the one state the running total has to argue with rather than report. */
.slotti-total--over {
	background: var(--slotti-danger-wash);
}

.slotti-total--over .slotti-total__left {
	color: var(--slotti-danger);
	font-weight: 600;
}
