/* ==========================================================================
   Zippydot scheduling — booking picker.

   Consumes the theme's design tokens, every one with a fallback, so the panel
   degrades to something sane rather than something unreadable if the plugin
   ever runs under a different theme. See docs/design-system.md.

   The panel is a full-width band, not a card: booking is the action the contact
   page exists for, and a bordered box floating in a column reads as an
   afterthought. Structure instead of a container — a rule under the header, a
   rule under the timezone bar, and the slots laid out on a grid.

   One accent: the selected slot is the single lit thing on the panel, the
   confirmation is yellow rather than green, and errors are stated in text and
   border weight rather than in red.

   Secondary text here is --color-text-muted, not --color-text-faint. When this was
   written faint was #71717a, 4.1:1 on the page background and under 4.5:1 at any
   size we use it — so it was kept to the eyebrow label only, matching the theme's
   own .zd-label. The token has since been fixed at the root (#83838c, 4.54:1 at
   worst), so this is no longer a workaround, just a choice: muted is the right
   weight for text a visitor has to read to book. See docs/scheduling-notes.md.
   ========================================================================== */

.zd-sched {
	color: var(--color-text, #fff);
	position: relative;
	/* ::before below bleeds -80px past this box on two edges by design (see its
	   own comment) — contain that bleed here so it can never contribute to the
	   page's own scrollable area. A <dialog> child renders in the top layer
	   regardless of ancestor overflow (see `.zd-sched > *:not(dialog)` below),
	   so this doesn't touch the modal. */
	overflow: hidden;
}

/* Engineering-diagram backing behind the header. The mask has to fade on both
   axes — a one-axis mask over a fixed-height block ends on a visible straight
   edge, which reads as a rendering artefact rather than a texture. */
.zd-sched::before {
	background-image: radial-gradient(
		circle at 1px 1px,
		var(--dot-color, rgba(255, 255, 255, 0.05)) 1px,
		transparent 0
	);
	background-size: var(--dot-pitch, 32px) var(--dot-pitch, 32px);
	content: "";
	height: 320px;
	inset: -80px auto auto -80px;
	-webkit-mask-image: radial-gradient(ellipse at 30% 30%, #000 0%, transparent 65%);
	mask-image: radial-gradient(ellipse at 30% 30%, #000 0%, transparent 65%);
	opacity: 0.7;
	pointer-events: none;
	position: absolute;
	/* Was a flat 520px — on any viewport narrower than ~600px that's most of
	   the box hanging off the edge, which is exactly what was defeating the
	   dvh fix: an uncontained descendant's ink overflow still counts toward
	   the page's scrollable area even though it's out of flow. Capped at the
	   viewport width now, and `overflow: hidden` above means it's fully
	   contained either way regardless of this value. */
	width: min(520px, 100vw);
	z-index: 0;
}

/* Everything except the dialog. A modal <dialog> is `position: fixed` by UA
   rule, and an author rule beats the UA origin — catching it here pinned it to
   its place in the document instead of the viewport, so it scrolled with the
   page and its top ran off the screen where nothing could reach it. */
.zd-sched > *:not(dialog) {
	position: relative;
	z-index: 1;
}

/* --- Header ---------------------------------------------------------------- */

.zd-sched__head {
	margin-bottom: var(--space-5, 40px);
	max-width: var(--measure, 760px);
}

.zd-sched__label {
	align-items: center;
	color: var(--color-text-faint, #83838c);
	display: flex;
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	font-weight: 500;
	gap: var(--space-1, 8px);
	letter-spacing: var(--tracking-label, 0.12em);
	margin: 0 0 var(--space-2, 16px);
	text-transform: uppercase;
}

.zd-sched__title {
	font-family: var(--font-heading, sans-serif);
	font-size: var(--fs-h2, 2.25rem);
	font-weight: 800;
	letter-spacing: var(--tracking-heading, -0.02em);
	line-height: var(--lh-heading, 1.15);
	margin: 0 0 var(--space-2, 16px);
}

.zd-sched__lead,
.zd-sched__fallback {
	color: var(--color-text-muted, #a1a1aa);
	font-size: var(--fs-lg, 1.125rem);
	line-height: var(--lh-body, 1.65);
	margin: 0;
}

/* --- Timezone bar ---------------------------------------------------------- */

.zd-sched__bar {
	border-top: 1px solid var(--color-border, rgba(255, 255, 255, 0.08));
	padding-top: var(--space-2, 16px);
}

.zd-sched__tz-line {
	align-items: center;
	color: var(--color-text-muted, #a1a1aa);
	display: flex;
	flex-wrap: wrap;
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	gap: var(--space-1, 8px);
	letter-spacing: var(--tracking-label, 0.12em);
	margin: 0;
	text-transform: uppercase;
}

/* Reads as a value you can edit, not a button someone dropped in the sentence:
   the dotted underline is the only affordance until you hover it. */
.zd-sched__tz-toggle {
	align-items: center;
	background: none;
	border: 0;
	border-bottom: 1px dashed var(--color-border-strong, rgba(255, 255, 255, 0.14));
	color: var(--color-text, #fff);
	cursor: pointer;
	display: inline-flex;
	font: inherit;
	gap: var(--space-1, 8px);
	letter-spacing: inherit;
	padding: var(--space-half, 4px) 0;
	transition: color var(--dur-fast, 160ms) var(--ease, ease),
		border-color var(--dur-fast, 160ms) var(--ease, ease);
}

.zd-sched__tz-toggle:hover {
	border-bottom-color: var(--color-brand, #ffd500);
	color: var(--color-brand, #ffd500);
}

.zd-sched__tz-caret {
	border-left: 4px solid transparent;
	border-right: 4px solid transparent;
	border-top: 4px solid currentColor;
	display: inline-block;
	height: 0;
	width: 0;
}

.zd-sched__tz-toggle[aria-expanded="true"] .zd-sched__tz-caret {
	transform: rotate(180deg);
}

/* --- Timezone picker ------------------------------------------------------- */

/* Opens inline rather than floating. An absolutely positioned dropdown inside a
   scrolling modal body is clipped by it — the list was cut off after two rows
   with no way to reach the rest. Pushing the content down costs a reflow and is
   always fully visible. */
.zd-sched__tz-panel {
	background: var(--color-bg, #0a0a0a);
	border: 1px solid var(--color-border-strong, rgba(255, 255, 255, 0.14));
	border-radius: var(--radius-card, 16px);
	margin-top: var(--space-2, 16px);
	padding: var(--space-2, 16px);
	width: 100%;
}

.zd-sched__tz-search-label {
	color: var(--color-text-muted, #a1a1aa);
	display: block;
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	letter-spacing: var(--tracking-label, 0.12em);
	margin-bottom: var(--space-1, 8px);
	text-transform: uppercase;
}

.zd-sched__tz-search {
	appearance: none;
	background: var(--color-bg, #0a0a0a);
	border: 1px solid var(--color-border, rgba(255, 255, 255, 0.08));
	border-radius: var(--radius-btn, 12px);
	color: var(--color-text, #fff);
	font: inherit;
	height: var(--control-h, 48px);
	padding-inline: var(--space-2, 16px);
	width: 100%;
}

.zd-sched__tz-list {
	list-style: none;
	margin: var(--space-1, 8px) 0 0;
	/* Tall enough to read as a list rather than a peephole. The modal itself is
	   allowed to grow to 90vh, so this can take a real share of it. */
	max-height: min(46vh, 380px);
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 0;
}

.zd-sched__tz-option {
	align-items: baseline;
	border-radius: var(--radius-sm, 8px);
	cursor: pointer;
	display: grid;
	gap: var(--space-1, 8px);
	/* City, region, clock — the clock is what tells two same-offset zones apart. */
	grid-template-columns: 1fr auto;
	padding: var(--space-1, 8px) var(--space-2, 16px);
}

.zd-sched__tz-option:hover,
.zd-sched__tz-option.is-active {
	background: var(--color-surface-2, #1c1c1c);
}

.zd-sched__tz-city {
	font-size: var(--fs-sm, 0.875rem);
	font-weight: 500;
}

.zd-sched__tz-region {
	color: var(--color-text-muted, #a1a1aa);
	font-size: var(--fs-label, 0.75rem);
	grid-column: 1;
	grid-row: 2;
}

.zd-sched__tz-clock {
	color: var(--color-text-muted, #a1a1aa);
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	grid-column: 2;
	grid-row: 1 / span 2;
}

.zd-sched__tz-option.is-current .zd-sched__tz-city {
	color: var(--color-brand, #ffd500);
}

.zd-sched__tz-empty {
	color: var(--color-text-muted, #a1a1aa);
	font-size: var(--fs-sm, 0.875rem);
	margin: var(--space-2, 16px) 0 0;
}

/* --- The page band: days only ----------------------------------------------
   Times moved into the modal. A grid of every slot grew with the configuration
   until it was a wall; a row of days is the same size whether each holds four
   openings or forty. */

.zd-sched__zone-note {
	color: var(--color-text-muted, #a1a1aa);
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	letter-spacing: var(--tracking-label, 0.12em);
	margin: 0 0 var(--space-2, 16px);
	text-transform: uppercase;
}

.zd-sched__days {
	display: grid;
	gap: var(--space-2, 16px);
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.zd-sched__status {
	color: var(--color-text-muted, #a1a1aa);
	font-size: var(--fs-sm, 0.875rem);
	grid-column: 1 / -1;
	margin: 0;
}

.zd-sched__daycard {
	align-items: flex-start;
	background: var(--color-surface, #141414);
	border: 1px solid var(--color-border, rgba(255, 255, 255, 0.08));
	border-radius: var(--radius-card, 16px);
	color: var(--color-text, #fff);
	cursor: pointer;
	display: flex;
	flex-direction: column;
	font: inherit;
	gap: var(--space-half, 4px);
	padding: var(--space-3, 24px) var(--space-2, 16px);
	text-align: left;
	transition: background-color var(--dur-fast, 160ms) var(--ease, ease),
		border-color var(--dur-fast, 160ms) var(--ease, ease),
		box-shadow var(--dur-fast, 160ms) var(--ease, ease),
		transform var(--dur-fast, 160ms) var(--ease, ease);
}

.zd-sched__daycard:hover {
	background: var(--color-surface-2, #1c1c1c);
	border-color: var(--color-border-brand, rgba(255, 213, 0, 0.32));
	box-shadow: var(--glow-sm, 0 0 12px rgba(255, 213, 0, 0.35));
	transform: translateY(-2px);
}

.zd-sched__daycard-dow {
	color: var(--color-text-muted, #a1a1aa);
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	letter-spacing: var(--tracking-label, 0.12em);
	text-transform: uppercase;
}

.zd-sched__daycard-date {
	font-family: var(--font-heading, sans-serif);
	font-size: var(--fs-h3, 1.5rem);
	font-weight: 800;
	letter-spacing: var(--tracking-heading, -0.02em);
}

/* The count is the only yellow on the card — it is the number that decides
   whether the day is worth opening. */
.zd-sched__daycard-count {
	color: var(--color-brand, #ffd500);
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	letter-spacing: var(--tracking-label, 0.12em);
	text-transform: uppercase;
}

/* --- Modal ------------------------------------------------------------------
   A native <dialog>: showModal() brings the focus trap, the Escape key and an
   inert background with it. */

.zd-sched__modal {
	/* One gutter for the whole dialog: the head, the body, and the negative
	   margin the day strip uses to bleed to the edges all read it, so the
	   small-screen override below is a single line rather than four. */
	--zd-sched-gutter: var(--space-3, 24px);

	background: var(--color-surface, #141414);
	/* The UA centres a modal dialog with `margin: auto`, which the theme's
	   `* { margin: 0 }` reset wipes out — without this it opens pinned to the
	   top-left corner. Restated rather than assumed. */
	margin: auto;
	border: 1px solid var(--color-border-strong, rgba(255, 255, 255, 0.14));
	border-radius: var(--radius-card, 16px);
	box-shadow: var(--shadow-hover, 0 8px 32px rgba(0, 0, 0, 0.5));
	color: var(--color-text, #fff);
	flex-direction: column;
	/* dvh, not vh: on mobile `vh` is measured against the largest viewport,
	   toolbars included, so 90vh can be taller than what is actually on screen —
	   and a centred box that overflows is unreachable at the top, because there
	   is nothing to scroll. */
	max-height: min(90dvh, 860px);
	max-width: 560px;
	overflow: hidden;
	padding: 0;
	width: calc(100% - var(--space-4, 32px));
}

/*
 * A closed <dialog> is display:none by UA rule, and `display: flex` on the
 * element flatly overrides that — which rendered the whole modal inline under
 * the day cards. The layout only applies while it is open, and the closed state
 * is restated rather than left to a rule this file has already broken once.
 *
 * A flex column: header fixed, body scrolling.
 */
.zd-sched__modal[open] {
	display: flex;
}

/* Restated rather than inherited from the UA, since this file has already
   overridden it once by accident. */
.zd-sched__modal:modal {
	inset: 0;
	margin: auto;
	position: fixed;
}

.zd-sched__modal:not([open]) {
	display: none;
}

.zd-sched__modal::backdrop {
	backdrop-filter: blur(2px);
	background: rgba(10, 10, 10, 0.72);
}

/* Without showModal the dialog opens in place rather than over the page, so it
   must not try to behave like an overlay. */
.zd-sched__modal[open]:not(:modal) {
	margin: var(--space-4, 32px) 0 0;
	max-height: none;
	width: 100%;
}

.zd-sched__modal-head {
	align-items: flex-start;
	border-bottom: 1px solid var(--color-border, rgba(255, 255, 255, 0.08));
	display: flex;
	flex: none;
	gap: var(--space-2, 16px);
	justify-content: space-between;
	padding: var(--zd-sched-gutter, var(--space-3, 24px));
}

.zd-sched__modal-step {
	color: var(--color-text-muted, #a1a1aa);
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	letter-spacing: var(--tracking-label, 0.12em);
	margin: 0 0 var(--space-1, 8px);
	text-transform: uppercase;
}

.zd-sched__modal-step:empty {
	display: none;
}

.zd-sched__modal-title {
	font-family: var(--font-heading, sans-serif);
	font-size: var(--fs-h3, 1.5rem);
	font-weight: 800;
	letter-spacing: var(--tracking-heading, -0.02em);
	margin: 0;
}

.zd-sched__modal-close {
	background: none;
	border: 1px solid var(--color-border, rgba(255, 255, 255, 0.08));
	border-radius: var(--radius-btn, 12px);
	color: var(--color-text-muted, #a1a1aa);
	cursor: pointer;
	flex: none;
	height: var(--space-5, 40px);
	position: relative;
	width: var(--space-5, 40px);
}

.zd-sched__modal-close:hover {
	border-color: var(--color-border-brand, rgba(255, 213, 0, 0.32));
	color: var(--color-brand, #ffd500);
}

/* Two rules crossed, so the glyph is never a font's idea of an X. */
.zd-sched__modal-close-x::before,
.zd-sched__modal-close-x::after {
	background: currentColor;
	content: "";
	height: 1px;
	left: 50%;
	position: absolute;
	top: 50%;
	width: 14px;
}

.zd-sched__modal-close-x::before {
	transform: translate(-50%, -50%) rotate(45deg);
}

.zd-sched__modal-close-x::after {
	transform: translate(-50%, -50%) rotate(-45deg);
}

.zd-sched__modal-body {
	flex: 1;
	/* Without min-height a flex child refuses to shrink below its content, and
	   the body never scrolls — it just pushes the dialog past the viewport. */
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: var(--zd-sched-gutter, var(--space-3, 24px));
}

.zd-sched__modal[open]:not(:modal) .zd-sched__modal-body {
	overflow-y: visible;
}

/* --- Step 1: day strip and times ------------------------------------------- */

/* Scrolls sideways, and bleeds out to the dialog's edges to do it. Inset, the
   last chip was sliced off short of the border and read as a broken column
   rather than as a row that continues. Running to the edge is what says
   "there is more this way". */
.zd-sched__daystrip {
	display: flex;
	gap: var(--space-1, 8px);
	margin-bottom: var(--space-3, 24px);
	margin-inline: calc(var(--zd-sched-gutter, var(--space-3, 24px)) * -1);
	overflow-x: auto;
	padding-bottom: var(--space-1, 8px);
	padding-inline: var(--zd-sched-gutter, var(--space-3, 24px));
	/* Chips land on the gutter rather than half-under it when the strip is
	   flicked or arrowed. */
	scroll-padding-inline: var(--zd-sched-gutter, var(--space-3, 24px));
	scroll-snap-type: x proximity;
	scrollbar-width: thin;
}

/* With no days left to show, the strip is an empty box holding a gap open above
   the timezone line. */
.zd-sched__daystrip:empty {
	display: none;
}

.zd-sched__chip {
	background: var(--color-bg, #0a0a0a);
	border: 1px solid var(--color-border, rgba(255, 255, 255, 0.08));
	border-radius: var(--radius-btn, 12px);
	color: var(--color-text, #fff);
	cursor: pointer;
	display: flex;
	flex: none;
	flex-direction: column;
	font: inherit;
	gap: 2px;
	min-height: var(--control-h, 48px);
	padding: var(--space-1, 8px) var(--space-2, 16px);
	scroll-snap-align: start;
	text-align: center;
	transition: background-color var(--dur-fast, 160ms) var(--ease, ease),
		border-color var(--dur-fast, 160ms) var(--ease, ease);
}

.zd-sched__chip:hover {
	border-color: var(--color-border-brand, rgba(255, 213, 0, 0.32));
}

.zd-sched__chip.is-selected {
	background: var(--color-surface-2, #1c1c1c);
	border-color: var(--color-brand, #ffd500);
}

.zd-sched__chip-dow {
	color: var(--color-text-muted, #a1a1aa);
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	letter-spacing: var(--tracking-label, 0.12em);
	text-transform: uppercase;
}

.zd-sched__chip.is-selected .zd-sched__chip-dow {
	color: var(--color-brand, #ffd500);
}

.zd-sched__chip-date {
	font-size: var(--fs-sm, 0.875rem);
	font-weight: 700;
	white-space: nowrap;
}

.zd-sched__slots {
	margin-top: var(--space-3, 24px);
}

/* The track is sized for the widest thing a slot can hold. That is now the time
   itself — a button holds one line and it is the visitor's own clock. It was
   140px while a second line rode underneath; sized for that line and then not
   sized for it is how the times ended up printed across each other. */
.zd-sched__list {
	display: grid;
	gap: var(--space-1, 8px);
	grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
	list-style: none;
	margin: 0;
	padding: 0;
}

/* A grid item's min-width is auto, which lets its content push the track wider
   than the track was told to be — the <li> is the item, so this is where the
   floor has to be lifted. Kept as a guard now that the long line is gone: it
   costs nothing and it is the rule that was missing when it wasn't. */
.zd-sched__list > li {
	min-width: 0;
}

.zd-sched__slot {
	align-items: center;
	background: var(--color-bg, #0a0a0a);
	border: 1px solid var(--color-border, rgba(255, 255, 255, 0.08));
	border-radius: var(--radius-btn, 12px);
	color: var(--color-text, #fff);
	cursor: pointer;
	display: flex;
	flex-direction: column;
	font: inherit;
	gap: 2px;
	justify-content: center;
	min-height: var(--control-h, 48px);
	overflow: hidden;
	padding: var(--space-1, 8px);
	transition: background-color var(--dur-fast, 160ms) var(--ease, ease),
		border-color var(--dur-fast, 160ms) var(--ease, ease),
		box-shadow var(--dur-fast, 160ms) var(--ease, ease);
	width: 100%;
}

.zd-sched__slot:hover {
	background: var(--color-surface-2, #1c1c1c);
	border-color: var(--color-brand, #ffd500);
	box-shadow: var(--glow-sm, 0 0 12px rgba(255, 213, 0, 0.35));
}

.zd-sched__slot-time {
	font-size: var(--fs-base, 1rem);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}


.zd-sched__more {
	align-items: center;
	background: none;
	border: 1px solid var(--color-border, rgba(255, 255, 255, 0.08));
	border-radius: var(--radius-btn, 12px);
	color: var(--color-text-muted, #a1a1aa);
	cursor: pointer;
	display: inline-flex;
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	gap: var(--space-1, 8px);
	height: var(--control-h, 48px);
	letter-spacing: var(--tracking-label, 0.12em);
	margin-top: var(--space-3, 24px);
	padding-inline: var(--space-3, 24px);
	text-transform: uppercase;
	transition: border-color var(--dur-fast, 160ms) var(--ease, ease),
		color var(--dur-fast, 160ms) var(--ease, ease);
}

.zd-sched__more:hover {
	border-color: var(--color-border-brand, rgba(255, 213, 0, 0.32));
	color: var(--color-brand, #ffd500);
}

/* The third time this stylesheet has taken a UA rule away by setting `display`.
   `[hidden] { display: none }` is a UA rule, and any author display wins over
   it — so `moreEl.hidden = true` did nothing and "More days" sat under the
   day list whether there were more days or not, dead-end states included. */
.zd-sched__more[hidden] {
	display: none;
}

/* --- Form -------------------------------------------------------------------
   A modal step now, so it carries no divider and no width of its own — the
   dialog is already the frame. */

.zd-sched__form {
	margin: 0;
}

.zd-sched__chosen {
	border-left: 2px solid var(--color-brand, #ffd500);
	margin-bottom: var(--space-3, 24px);
	padding-left: var(--space-2, 16px);
}

.zd-sched__chosen-main {
	font-family: var(--font-heading, sans-serif);
	font-size: var(--fs-h3, 1.5rem);
	font-weight: 700;
	letter-spacing: var(--tracking-heading, -0.02em);
	margin: 0;
}


.zd-sched__field {
	margin-bottom: var(--space-3, 24px);
}

.zd-sched__field label {
	display: block;
	font-size: var(--fs-sm, 0.875rem);
	font-weight: 500;
	margin-bottom: var(--space-1, 8px);
}

.zd-sched__optional {
	color: var(--color-text-muted, #a1a1aa);
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	font-weight: 400;
	letter-spacing: var(--tracking-label, 0.12em);
	margin-left: var(--space-1, 8px);
	text-transform: uppercase;
}

.zd-sched__field input,
.zd-sched__field textarea {
	background: var(--color-surface, #141414);
	border: 1px solid var(--color-border, rgba(255, 255, 255, 0.08));
	border-radius: var(--radius-btn, 12px);
	color: var(--color-text, #fff);
	font: inherit;
	padding-inline: var(--space-2, 16px);
	transition: border-color var(--dur-fast, 160ms) var(--ease, ease);
	width: 100%;
}

.zd-sched__field input {
	appearance: none;
	height: var(--control-h, 48px);
}

.zd-sched__field textarea {
	padding-block: var(--space-2, 16px);
	resize: vertical;
}

.zd-sched__field input:focus,
.zd-sched__field textarea:focus,
.zd-sched__tz-search:focus {
	border-color: var(--color-border-strong, rgba(255, 255, 255, 0.14));
}

/* Errors carry weight, not colour. A red state would be a second accent. */
.zd-sched__errors,
.zd-sched__error {
	color: var(--color-text, #fff);
	font-size: var(--fs-sm, 0.875rem);
	margin: 0 0 var(--space-3, 24px);
}

.zd-sched__errors {
	border-left: 2px solid var(--color-brand, #ffd500);
	padding-left: var(--space-2, 16px);
}

.zd-sched__error {
	margin: var(--space-1, 8px) 0 0;
}

.zd-sched__field:has(.zd-sched__error:not([hidden])) input {
	border-color: var(--color-border-strong, rgba(255, 255, 255, 0.14));
	border-width: 2px;
}

/* The mailto shares the submit's shape rather than copying it: on a band with
   no times left it is the only action on the panel, so it gets the lit button,
   not a quiet link. `.zd-sched__status` above it carries the reason. */
.zd-sched__submit,
.zd-sched__mailto {
	align-items: center;
	background: var(--color-brand, #ffd500);
	border: 1px solid transparent;
	border-radius: var(--radius-btn, 12px);
	box-shadow: var(--glow-md, 0 0 16px rgba(255, 213, 0, 0.45), 0 0 40px rgba(255, 213, 0, 0.18));
	color: var(--color-brand-ink, #0a0a0a);
	cursor: pointer;
	display: inline-flex;
	font-family: inherit;
	font-size: var(--fs-sm, 0.875rem);
	font-weight: 700;
	height: var(--control-h, 48px);
	justify-content: center;
	padding-inline: var(--space-3, 24px);
	transition: background-color var(--dur-fast, 160ms) var(--ease, ease),
		box-shadow var(--dur-fast, 160ms) var(--ease, ease),
		transform var(--dur-fast, 160ms) var(--ease, ease);
}

/* `color` is restated because one of these is an <a>, and a theme that styles
   its own links — ours sets `a:hover { color: var(--color-brand) }` — otherwise
   wins here and paints the label brand-yellow on a brand-yellow button, lit from
   behind by the button's own bloom. The <button> next to it never had the
   problem, which is exactly why it survived review. */
.zd-sched__submit:hover:not(:disabled),
.zd-sched__mailto:hover,
.zd-sched__mailto:active {
	background: var(--color-brand-bright, #ffde33);
	box-shadow: var(--glow-lg, 0 0 24px rgba(255, 213, 0, 0.55), 0 0 64px rgba(255, 213, 0, 0.22));
	color: var(--color-brand-ink, #0a0a0a);
	transform: translateY(-2px);
}

/* The dead-end state is a sentence and this button. It sits in the day grid,
   which is a two-column track at most sizes — the button should be its own
   width, not a column's. */
.zd-sched__mailto {
	grid-column: 1 / -1;
	justify-self: start;
	text-decoration: none;
}

/* Inside the modal there is no grid to space it — .zd-sched__status carries no
   bottom margin, and the button would sit against the sentence. */
.zd-sched__slots .zd-sched__mailto {
	margin-top: var(--space-2, 16px);
}

.zd-sched__submit:disabled {
	cursor: progress;
	opacity: 0.6;
}

.zd-sched__modal-actions {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-2, 16px);
	margin-top: var(--space-3, 24px);
}

/* Back is a way out, not a second call to action — it stays quiet next to the
   one lit button. */
.zd-sched__back {
	background: none;
	border: 1px solid var(--color-border, rgba(255, 255, 255, 0.08));
	border-radius: var(--radius-btn, 12px);
	color: var(--color-text-muted, #a1a1aa);
	cursor: pointer;
	font-family: inherit;
	font-size: var(--fs-sm, 0.875rem);
	font-weight: 500;
	height: var(--control-h, 48px);
	padding-inline: var(--space-3, 24px);
	transition: border-color var(--dur-fast, 160ms) var(--ease, ease),
		color var(--dur-fast, 160ms) var(--ease, ease);
}

.zd-sched__back:hover {
	border-color: var(--color-border-strong, rgba(255, 255, 255, 0.14));
	color: var(--color-text, #fff);
}

.zd-sched__consent {
	color: var(--color-text-muted, #a1a1aa);
	font-size: var(--fs-label, 0.75rem);
	line-height: var(--lh-body, 1.65);
	margin: var(--space-2, 16px) 0 0;
	max-width: 52ch;
}

/* Honeypot. Off-screen rather than display:none or type=hidden — both of those
   are signals a bot reads to decide the field isn't worth filling. */
.zd-sched__hp {
	height: 1px;
	left: -9999px;
	overflow: hidden;
	position: absolute;
	width: 1px;
}

/* --- Confirmation ---------------------------------------------------------- */

.zd-sched__done {
	border-left: 2px solid var(--color-brand, #ffd500);
	padding-left: var(--space-3, 24px);
}

.zd-sched__done-label {
	color: var(--color-brand, #ffd500);
	font-family: var(--font-mono, ui-monospace, monospace);
	font-size: var(--fs-label, 0.75rem);
	letter-spacing: var(--tracking-label, 0.12em);
	margin: 0 0 var(--space-1, 8px);
	text-shadow: var(--glow-text, 0 0 18px rgba(255, 213, 0, 0.45));
	text-transform: uppercase;
}

.zd-sched__done-title {
	font-family: var(--font-heading, sans-serif);
	font-size: var(--fs-h3, 1.5rem);
	font-weight: 800;
	letter-spacing: var(--tracking-heading, -0.02em);
	margin: 0;
}


.zd-sched__done-note {
	color: var(--color-text-muted, #a1a1aa);
	font-size: var(--fs-sm, 0.875rem);
	margin: var(--space-2, 16px) 0 0;
}

.zd-sched__cancel-link {
	color: var(--color-text-muted, #a1a1aa);
	display: inline-block;
	font-size: var(--fs-sm, 0.875rem);
	margin-top: var(--space-2, 16px);
	/* Underlined, because next to two lines of body copy an unadorned link is
	   just more body copy. */
	text-decoration: underline;
	text-underline-offset: 3px;
}

.zd-sched__cancel-link:hover {
	color: var(--color-brand, #ffd500);
}

/* The page behind a modal must not scroll. A modal <dialog> makes the background
   inert to clicks and tab, but the wheel still moves it. */
.zd-sched-modal-open,
.zd-sched-modal-open body {
	overflow: hidden;
}

/* --- Focus ----------------------------------------------------------------- */

.zd-sched :focus-visible {
	outline: 2px solid var(--color-brand, #ffd500);
	outline-offset: 2px;
}

/* The error summary and the confirmation take focus programmatically; a ring on
   a region the user never tabbed to is noise. */
.zd-sched__errors:focus,
.zd-sched__done:focus {
	outline: none;
}

/* --- Motion ---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.zd-sched *,
	.zd-sched *::before,
	.zd-sched *::after {
		transition-duration: 0.01ms !important;
	}

	.zd-sched__slot:hover,
	.zd-sched__submit:hover:not(:disabled),
	.zd-sched__mailto:hover {
		transform: none;
	}
}

/* --- Small screens --------------------------------------------------------- */

@media (max-width: 600px) {
	/* 24px of padding on each side of a 320px screen is a tenth of the dialog
	   spent on air, and it came out of the times. One step down the scale. */
	.zd-sched__modal {
		--zd-sched-gutter: var(--space-2, 16px);
	}

	/* Three times across on a normal phone, two at 320px. A single stacked
	   column of 48px buttons would be most of a screen for one morning. */
	.zd-sched__list {
		grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
	}

	.zd-sched__tz-panel {
		max-width: none;
	}
}
