/* ==========================================================================
   Easton — "Book a Free Class" booking module (Reimagined direction)
   Faithful port of the Claude Design handoff into the theme. Self-contained:
   all custom properties are scoped to .eb-bk so the module renders identically
   regardless of the page's global cascade (incl. the clean-room /b-version).
   Cream / ink / red · Anton (display) / Oswald (labels) / Barlow (body).
   Bold language: Anton at scale, 0-radius on bold surfaces, red as accent only.
   ========================================================================== */

.eb-bk {
	--ebk-ink: #0d0d0c;
	/* THE TWO REDS (2026-09-18, v0.2.95 — the design file's colour sheet).
	   #f04137 is the brand red and it is KEPT, but only where it carries no
	   text: the eyebrow and header squares, every summary/panel icon, the
	   selected-chip box, the slot clock, the note bullets, the rail's
	   current-step square. It measures 3.02:1 against white, so anything that
	   prints WORDS on it or in it moved:

	     --ebk-red-btn     #d13a31  button GROUND, white label      4.82:1
	     --ebk-red-btn-hv  #bb3028  hover ground, white label       5.89:1
	     --ebk-red-text    #bb3028  red AS TEXT on cream            5.22:1
	                                (errors, link rules, the success eyebrow)
	     --ebk-red-ink     #961e18  the 3px bottom edge, unchanged  8.42:1 */
	--ebk-red: #f04137;
	--ebk-red-btn: #d13a31;
	--ebk-red-btn-hv: #bb3028;
	--ebk-red-text: #bb3028;
	--ebk-red-ink: #961e18;
	/* Rail + disabled, also from the colour sheet. --ebk-rail-idle is a solid
	   #65645f rather than an alpha: it is exactly what rgba(13,13,12,0.62)
	   already composites to over the cream canvas, so it is the same ink the
	   module's muted text has always been — stated once, and correct on white
	   too. It took the rail in v0.2.98 and the last of the faint text in
	   v0.2.99, so it is now the module's ONE secondary-text ink, which is
	   exactly what the design's accessible layer does with it. */
	--ebk-rail-idle: #65645f;
	/* #8A8880 is the design file's ONE border-grade neutral. Its measured colour
	   sheet states it exactly once -- `railMark: '#8a8880', // idle rail markers /
	   borders . 3.15:1` -- so the rail markers and every field border in this
	   module are the same ink by design, and this is the single place it is
	   written. --ebk-line-st below is that same source, not a second value. */
	--ebk-rail-mark: #8a8880;
	--ebk-dis-bg: #e3dfd6;
	--ebk-dis-fg: #4a4845;
	--ebk-canvas: #f4f1ea;
	--ebk-paper: #fff;
	--ebk-mut: rgba(13, 13, 12, 0.62);
	/* --ebk-faint: rgba(13,13,12,0.32) WAS HERE AND IS DELETED (2026-09-19,
	   v0.2.99). It composited to 2.11:1 on cream and 2.12:1 on white, and every
	   one of its five uses was TEXT — .eb-bk-hint, the `(optional)` marker in a
	   field label, .eb-bk-chip__note, .eb-bk-finding and the no-JS label's
	   span. All five are small text, so the bar is the full 4.5:1 and this was
	   less than half of it: a straight AA failure inside the booking flow.

	   All five now take --ebk-rail-idle (5.93:1 on white, 5.26:1 on cream,
	   4.89:1 on a --ebk-sunken panel). The token is DELETED rather than
	   re-pointed because the design's own accessible layer abandoned the tier:
	   in merged-details.jsx — the file v0.2.95 was built to — `BK.faint` has
	   ZERO uses and `BK.mut` has zero too, while `MD.railIdle` has sixteen, at
	   every size from 10.5px to 14.5px. There is no faint grade left to name,
	   and leaving the name behind invites a future rule to reach for a lighter
	   ink that no longer exists. (--ebk-mut2 was deleted the same way in
	   v0.2.98.) The de-emphasis those five carried is still carried — by size
	   and weight, which is where it was doing the work anyway.

	   --ebk-line below is NOT following it, and the difference is the whole
	   point: see its own note. */
	/* --ebk-line: KEPT, deliberately, at 1.30:1 (2026-09-19, v0.2.99). It was
	   audited in the same pass as --ebk-faint and it is the louder-looking
	   number, so the reason it does not move needs to be on the record.

	   v0.2.98 changed --ebk-line-st at the TOKEN because all nine of its call
	   sites were non-text boundaries at the same 3:1 bar. The rule that came
	   out of that override was: a token-wide change is right only when every
	   call site sits at the same bar. --ebk-line does not.

	   Of its eleven uses, exactly ONE bounded a control — .eb-bk-chip, a
	   <button>, whose white fill is 1.09:1 against the cream behind it, so its
	   border is the only thing drawing the control at all. That one is fixed
	   where it is used, below, and takes --ebk-line-st like every other control
	   edge in the module. The other ten are dividers and panel edges: the embed
	   frame, the sticky CTA hairline, the cityrow panel, the what/note/minorbox
	   panels, the summary card and its row rules. WCAG 1.4.11 asks 3:1 of user
	   interface components and of graphics that carry meaning; a rule between
	   two summary rows is neither, and darkening all ten to #8A8880 would be a
	   visible redesign of the module bought with no accessibility gain.

	   A TWELFTH USE LANDED 2026-09-20 and it is a control edge, so this
	   paragraph would otherwise now be false: .eb-bk-chip:disabled. It is the
	   ONE case where the exemption in 1.4.11's own text applies — "inactive user
	   interface components" are excluded by name — and it is load-bearing rather
	   than incidental. That rule replaced an `opacity: 0.4` which faded the
	   border to 1.50:1 anyway, so the disabled edge is not getting weaker; and
	   the disabled chip is now drawn by its GROUND (#E3DFD6 against white) the
	   way the disabled CTA is, which is what a hairline border leaves room to
	   read. An enabled chip still takes --ebk-line-st at 3.55:1. The inventory,
	   restated: one control edge at the bar, one inactive control edge below it
	   by exemption, ten dividers.

	   The design's accessible layer independently agrees. In merged-details.jsx
	   `BK.line` SURVIVES — six uses, and all six are dividers or panel edges
	   (sunken box, note box, summary row rule, expander rule, and the sticky
	   bar's top border twice). The same file replaces every faint text with
	   MD.railIdle and states MD.railMark as the one border ink. So the design
	   kept this hairline for exactly the job it still does here. */
	--ebk-line: rgba(13, 13, 12, 0.12);
	/* THE FIELD-BORDER INK (2026-09-19, v0.2.98). This was rgba(13,13,12,0.20),
	   which composites to #CFCFCE over the white a field sits on and measures
	   1.56:1 -- and it is the resting border on EVERY text input, select and
	   textarea in the module, in both lanes. A form field's border is a non-text
	   UI boundary: the bar is 3:1, and 1.56 is less than half of it.

	   The design handoff carries the failure twice over, which is why it survived
	   the port: its OLD kit (booking-kit.jsx, `BK`) defines `lineSt:
	   'rgba(13,13,12,0.20)'`, and its swatch sheet annotates that exact value
	   "Border rgba(13,13,12,0.20) vs #FFFFFF . 3.4:1". That annotation is
	   arithmetically false -- the value is 1.56:1 -- and it is superseded inside
	   the same handoff by the MEASURED colour sheet, which states the border ink
	   as #8A8880. So this takes the design's own value; it is not a new colour,
	   and --ebk-rail-mark above is the one place it is written.

	     before  rgba(13,13,12,0.20) -> #CFCFCE on #FFFFFF   1.56:1  FAIL
	     after   #8A8880             on #FFFFFF              3.55:1  PASS
	                                 on #F4F1EA              3.15:1  PASS

	   Hover and focus (--ebk-ink, 19.44:1) and error (--ebk-red-text, 5.89:1)
	   already cleared the bar and are untouched, so the resting -> hover step is
	   now a smaller jump than it was, not a larger one. Only the colour moves:
	   every width stays 1px / 1.5px / 2px as it was, so no box changes size. */
	--ebk-line-st: var(--ebk-rail-mark);
	--ebk-sunken: rgba(13, 13, 12, 0.035);
	/* The one selected-state pair, used by every control that can be chosen: ink
	   ground, cream ink. 17.16:1 — see the guard block at the foot of this file
	   for why the selected state is stated three times per control. */
	--ebk-on-ink: var(--ebk-canvas);
	--ebk-on-ink-mut: rgba(244, 241, 234, 0.72);
	--ebk-anton: "Anton", sans-serif;
	--ebk-oswald: "Oswald", sans-serif;
	--ebk-barlow: "Barlow", sans-serif;
	/* The design file's edge: a flat 3px riser, no red glow. The glow was drawn
	   from #f04137 and read as a halo around a button that is no longer that
	   colour. Hover lifts to 4px, active presses to 1px. */
	--ebk-cta-shadow: 0 3px 0 var(--ebk-red-ink);
	font-family: var(--ebk-barlow);
	color: var(--ebk-ink);
	-webkit-font-smoothing: antialiased;
}
.eb-bk *, .eb-bk *::before, .eb-bk *::after { box-sizing: border-box; }

/* --- Overlay + sheet/card chrome ---------------------------------------- */
.eb-bk-scrim {
	position: fixed; inset: 0; z-index: 99998;
	background: radial-gradient(120% 90% at 50% 0%, rgba(13, 13, 12, 0.62), rgba(13, 13, 12, 0.80));
	display: flex; justify-content: center; align-items: flex-end;
	opacity: 0; transition: opacity 0.2s ease;
}
.eb-bk-scrim[data-open] { opacity: 1; }
body.eb-bk-locked { overflow: hidden; }

.eb-bk-modal {
	width: 100%; max-width: 100%; max-height: 94vh;
	background: var(--ebk-canvas);
	border-radius: 18px 18px 0 0;
	display: flex; flex-direction: column; overflow: hidden;
	transform: translateY(14px); transition: transform 0.22s cubic-bezier(.4, 0, .2, 1);
	box-shadow: 0 -1px 0 rgba(255, 255, 255, 0.05);
}
.eb-bk-scrim[data-open] .eb-bk-modal { transform: none; }

.eb-bk-grab { display: flex; justify-content: center; padding: 9px 0 0; flex: 0 0 auto; }
.eb-bk-grab span { width: 38px; height: 4px; border-radius: 999px; background: rgba(13, 13, 12, 0.16); }

.eb-bk-head { display: flex; align-items: center; gap: 10px; padding: 12px 18px 0; flex: 0 0 auto; }
.eb-bk-head__title {
	flex: 1 1 auto; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
	font-family: var(--ebk-oswald); font-weight: 600; font-size: 12px; letter-spacing: 0.18em;
	text-transform: uppercase; color: var(--ebk-ink);
}
.eb-bk-head__title::before { content: ""; width: 7px; height: 7px; background: var(--ebk-red); flex: 0 0 auto; }
.eb-bk-iconbtn {
	display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px;
	border: none; background: transparent; cursor: pointer; color: var(--ebk-mut); flex: 0 0 auto;
	border-radius: 999px; transition: background 0.14s ease, color 0.14s ease; padding: 0;
}
.eb-bk-iconbtn:hover { background: var(--ebk-sunken); color: var(--ebk-ink); }
.eb-bk-iconbtn[hidden] { visibility: hidden; }
.eb-bk-back { color: var(--ebk-ink); }

.eb-bk-rail { padding: 16px 22px 4px; flex: 0 0 auto; }
/* The body's own padding is published as two custom properties because the
   docked action bar below has to cancel the horizontal one (to reach the modal's
   edges) and re-serve the vertical one (to keep its gap above the bottom edge).
   Two places, one source — change the padding here and the bar follows. */
.eb-bk-body { --ebk-bx: 18px; --ebk-bb: 24px; padding: 14px var(--ebk-bx) var(--ebk-bb); flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; }

/* Desktop: centered card over a dim. */
@media (min-width: 720px) {
	.eb-bk-scrim { align-items: center; padding: 40px; }
	.eb-bk-modal {
		max-width: 600px; border-radius: 10px; max-height: 88vh;
		box-shadow: 0 1px 0 rgba(13, 13, 12, 0.06), 0 50px 90px -40px rgba(0, 0, 0, 0.7);
		transform: translateY(20px) scale(0.98);
	}
	.eb-bk-scrim[data-open] .eb-bk-modal { transform: none; }
	.eb-bk-modal[data-wide] { max-width: 880px; }
	.eb-bk-grab { display: none; }
	.eb-bk-head { padding: 22px 26px 0; }
	.eb-bk-rail { padding: 16px 26px 2px; }
	.eb-bk-body { --ebk-bx: 26px; --ebk-bb: 28px; padding: 20px var(--ebk-bx) var(--ebk-bb); }
}

/* Embedded (inline on /free-class/) — no scrim, in flow. */
.eb-bk-embed {
	background: var(--ebk-canvas); border: 1px solid var(--ebk-line); border-radius: 8px; overflow: hidden;
	box-shadow: 0 1px 0 rgba(13, 13, 12, 0.04), 0 30px 60px -45px rgba(13, 13, 12, 0.45);
	transform: none; max-height: none; max-width: 100%;
}
.eb-bk-embed .eb-bk-grab, .eb-bk-embed .eb-bk-close { display: none; }
.eb-bk-embed .eb-bk-head { padding-top: 20px; }
.eb-bk-embed .eb-bk-body { overflow: visible; }

/* Step fade. */
@media (prefers-reduced-motion: no-preference) {
	.eb-bk-fade { animation: ebkFade 0.2s cubic-bezier(.4, 0, .2, 1); }
	@keyframes ebkFade { from { transform: translateY(6px); opacity: 0.4; } to { transform: none; opacity: 1; } }
}

/* --- Typography atoms --------------------------------------------------- */
.eb-bk-eyebrow {
	display: inline-flex; align-items: center; gap: 10px; margin-bottom: 14px;
	font-family: var(--ebk-oswald); font-weight: 600; font-size: 12px; letter-spacing: 0.22em;
	text-transform: uppercase; color: var(--ebk-red-text);
}
.eb-bk-eyebrow::before { content: ""; width: 9px; height: 9px; background: var(--ebk-red); flex: 0 0 auto; }
.eb-bk-h {
	margin: 0 0 14px; font-family: var(--ebk-anton); font-weight: 400; font-size: 46px; line-height: 0.92;
	letter-spacing: 0.005em; text-transform: uppercase; color: var(--ebk-ink); text-wrap: balance;
}
.eb-bk-h--sm { font-size: 40px; }
.eb-bk-sub { margin: 0 0 22px; font-family: var(--ebk-barlow); font-weight: 500; font-size: 15px; line-height: 1.5; color: var(--ebk-mut); text-wrap: pretty; }
.eb-bk-label { font-family: var(--ebk-oswald); font-weight: 700; font-size: 11.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ebk-ink); }
.eb-bk-hint { font-family: var(--ebk-barlow); font-size: 12.5px; color: var(--ebk-rail-idle); }

/* --- Buttons ------------------------------------------------------------ */
.eb-bk-btn {
	display: inline-flex; align-items: center; justify-content: center; gap: 11px; width: 100%;
	padding: 18px 28px; cursor: pointer; font-family: var(--ebk-oswald); font-weight: 700; font-size: 16px;
	letter-spacing: 0.11em; text-transform: uppercase; border: none; border-radius: 0; white-space: nowrap;
	transition: filter 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.eb-bk-btn svg { flex: 0 0 auto; }
.eb-bk-btn--primary { background: var(--ebk-red-btn); color: #fff; box-shadow: var(--ebk-cta-shadow); }
/* A darker GROUND, not a filter: `brightness(1.05)` on #d13a31 lands back on a
   ratio that fails, and it is the label on this button that has to stay read. */
.eb-bk-btn--primary:not(:disabled):hover { background: var(--ebk-red-btn-hv); transform: translateY(-1px); box-shadow: 0 4px 0 var(--ebk-red-ink); }
.eb-bk-btn--primary:not(:disabled):active { transform: translateY(2px); box-shadow: 0 1px 0 var(--ebk-red-ink); }
/* Disabled is a real pair, not 42% of an enabled one: opacity dragged the white
   label to 1.9:1 on the faded red and made "Pick a time to continue" — a line
   whose whole job is to tell you what to do — the least readable text on the
   step. #4A4845 on #E3DFD6 is 6.85:1. */
.eb-bk-btn--primary:disabled { background: var(--ebk-dis-bg); color: var(--ebk-dis-fg); cursor: not-allowed; box-shadow: none; }
.eb-bk-btn--primary:disabled svg { display: none; }
.eb-bk-btn--ghost { background: transparent; color: var(--ebk-ink); border: 2px solid var(--ebk-ink); border-radius: 0; font-size: 14px; padding: 15px 24px; }
.eb-bk-btn--quiet { background: transparent; color: var(--ebk-mut); border: none; font-size: 14px; letter-spacing: 0.12em; padding: 13px 20px; }

/* --- The docked action bar (2026-09-18, v0.2.94) ------------------------
   The way forward must never be off-screen. It was: the CTA is the last thing
   in `.eb-bk-body`, which is the modal's scroll container, so on any step whose
   content outran the modal the button sat below the fold with nothing saying to
   scroll. Measured before this change, at scroll position 0: the button's bottom
   was 253px past the modal's bottom edge on Pick-a-time at 1440, 66px on the
   experienced form at 390, 51px on the entry step at 390 — five of the ten
   steps-with-a-bar that exist across the two widths.

   `position: sticky` docks it to the bottom of that scrollport and content
   scrolls underneath, WITHOUT moving the button out of `.eb-bk-body` in the
   markup — which the brief's stop condition rules out and which would also cost
   the bar its place in the flow. Because it keeps that place, the bar still
   reserves its own height at the end of the content: when you scroll to the
   bottom, the last field ends ABOVE it, never under it (that is 1.3, and it is
   why no "bar height + a step" of dead padding is needed under the content —
   padding that would re-create the empty region 1.2 is about).

   The two negatives-and-a-padding dance is what makes an element inside a padded
   scroll container reach that container's edges: cancel the body's horizontal
   padding with a negative margin, then re-serve it as the bar's own padding so
   the button still lines up with the fields above it. The body's bottom padding
   moves into the bar for the same reason — `:has()` so a step WITHOUT a bar (the
   fork is the only one) keeps its own breathing room at the bottom. */
.eb-bk-cta-wrap {
	position: sticky; bottom: 0; z-index: 3;
	margin: 22px calc(var(--ebk-bx) * -1) 0;
	padding: 16px var(--ebk-bx) var(--ebk-bb);
	background: var(--ebk-canvas);
	box-shadow: 0 -1px 0 var(--ebk-line);
}
.eb-bk-body:has(> * > .eb-bk-cta-wrap) { padding-bottom: 0; }
/* Embedded (/free-class/) has no scrollport of its own — `.eb-bk-embed
   .eb-bk-body` is `overflow: visible`, so a sticky bar there would dock to the
   PAGE and float over the article. In flow, exactly as it has always been. */
.eb-bk-embed .eb-bk-cta-wrap { position: static; margin-inline: 0; padding: 0; background: none; box-shadow: none; }
.eb-bk-embed .eb-bk-body { padding-bottom: var(--ebk-bb); }

/* --- Academy row / city chip ------------------------------------------- */
.eb-bk-cityrow {
	display: flex; align-items: center; gap: 12px; padding: 14px 16px; margin-bottom: 20px;
	background: var(--ebk-paper); border: 2px solid var(--ebk-line);
}
.eb-bk-cityrow__pin { display: inline-flex; color: var(--ebk-red); flex: 0 0 auto; }
.eb-bk-cityrow__body { display: flex; flex-direction: column; gap: 1px; flex: 1 1 auto; min-width: 0; }
/* --ebk-rail-idle, not --ebk-mut2 (2026-09-19, v0.2.98). This is the "Your
   academy" eyebrow on the entry step, and it sits on the cityrow's WHITE fill,
   not on the cream card: rgba(13,13,12,0.45) composites to #929292 there and
   measured 3.11:1. It is 9.5px/600 Oswald -- small text, so the bar is the full
   4.5:1, not the large-text 3:1. #65645F is the same solid ink §6.2 moved the
   summary-row labels to, and the same one the step rail's idle labels use.
     before  rgba(13,13,12,0.45) -> #929292 on #FFFFFF  3.11:1  FAIL
     after   #65645F                       on #FFFFFF   5.93:1  PASS
   This was --ebk-mut2's last call site, so the token is gone with it rather than
   left lying around at 3.11:1 for the next label that reaches for it. */
.eb-bk-cityrow__kick { font-family: var(--ebk-oswald); font-weight: 600; font-size: 9.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ebk-rail-idle); }
.eb-bk-cityrow__name { font-family: var(--ebk-oswald); font-weight: 600; font-size: 16px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ebk-ink); }
.eb-bk-change {
	display: inline-flex; align-items: center; gap: 6px; padding: 0 0 2px; background: none; border: none;
	border-bottom: 2px solid var(--ebk-red-text); cursor: pointer; font-family: var(--ebk-oswald); font-weight: 600;
	font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ebk-ink);
}

/* --- Fields ------------------------------------------------------------- */
.eb-bk-field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.eb-bk-field > span { display: flex; align-items: baseline; gap: 7px; font-family: var(--ebk-oswald); font-weight: 600; font-size: 11px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ebk-mut); }
.eb-bk-field > span em { color: var(--ebk-rail-idle); font-style: normal; letter-spacing: 0.1em; }
/* ONE rule set for all three field types — <input>, <select> and <textarea> — and
   it is SCOPED to the module root .eb-bk so it wins on SPECIFICITY, never on load
   order. That scoping is the whole fix (2026-09-18, v0.2.93).

   The defect it closes: GeneratePress dresses form controls with a selector LIST —
   `input[type="text"], …, input[type="url"], select, textarea { … }` — and CSS
   computes specificity PER SELECTOR in a list, not for the list as a whole. So one
   declaration block arrived at two different weights: (0,1,1) for each
   input[type=…], but only (0,0,1) for the bare `select` and `textarea`. Unscoped
   `.eb-bk-input` at (0,1,0) lost to the first and beat the other two — which is
   why this module's text inputs rendered in GeneratePress's grey while the selects
   and the notes textarea beside them kept the module's own tokens. One rule set,
   split apart by element type.

   `.eb-bk .eb-bk-input` at (0,2,0) outranks every arm of that list, so the split
   cannot reopen the next time a stylesheet ships those selectors. No !important is
   needed and none is used: .eb-bk is on the module root in all three variants (the
   modal scrim, the inline embed, and the no-JS /free-class/ form), so the scope is
   always there to be had. Load order is deliberately NOT the mechanism — that is
   what fails silently when another stylesheet moves.

   The VALUES below are unchanged and are the design file's, property for property
   (strategy/design-system/design_handoff_booking_module/booking-kit.jsx, `Field`).
   Only who wins changed. */
.eb-bk .eb-bk-input, .eb-bk .eb-bk-select {
	width: 100%; background: var(--ebk-paper); border: 1px solid var(--ebk-line-st); border-radius: 3px;
	padding: 14px; font-family: var(--ebk-barlow); font-weight: 500; font-size: 16px; color: var(--ebk-ink);
	margin: 0; transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.eb-bk .eb-bk-select {
	font-family: var(--ebk-oswald); font-weight: 600; font-size: 15px; letter-spacing: 0.05em;
	text-transform: uppercase; padding: 15px 40px 15px 14px; cursor: pointer;
	appearance: none; -webkit-appearance: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23f04137' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat; background-position: right 16px center;
}
/* Focus/error are scoped for the same reason: GeneratePress ships a matching
   `input[type=…]:focus, …, textarea:focus, select:focus` list, so an unscoped
   `.eb-bk-input:focus` at (0,1,1) only tied it and won on file order. */
/* `background` and `color` joined this rule on 2026-09-18 (v0.2.94). 99abaf4
   contested the RESTING fill and won it back, but GeneratePress ships a second,
   matching list for the focused one --
   `input[type=…]:focus, …, textarea:focus, select:focus { color: var(--contrast);
   background-color: var(--base-2); … }` -- and this rule declared only
   border-color and box-shadow against it. An undeclared property is not a
   contest: every field in the module took GP's #f7f8f9 fill and #222 ink the
   moment it was focused, which is every field a person actually types in. The
   values below are the design file's, the same two this rule's resting twin
   already serves. */
/* Hover was never declared: an input the pointer is over looked identical to
   one it is not, on the one step that is nothing but inputs. */
.eb-bk .eb-bk-input:hover:not(:focus), .eb-bk .eb-bk-select:hover:not(:focus) { border-color: var(--ebk-ink); }
.eb-bk .eb-bk-input:focus, .eb-bk .eb-bk-select:focus { background: var(--ebk-paper); color: var(--ebk-ink); border-color: var(--ebk-ink); box-shadow: 0 0 0 3px rgba(13, 13, 12, 0.18); outline: none; }
.eb-bk .eb-bk-input.is-err, .eb-bk .eb-bk-select.is-err { border-color: var(--ebk-red-text); }
.eb-bk .eb-bk-input.is-err:focus { box-shadow: 0 0 0 3px rgba(187, 48, 40, 0.24); }
/* The one multi-line field — the SAME input, not a new one. It carries
   .eb-bk-input for every colour, border, radius, padding and focus ring above and
   adds only what a <textarea> needs that an <input> does not, so it renders
   identically to the text inputs and the selects beside it. It always did; what
   changed in v0.2.93 is that they now render like IT, rather than in
   GeneratePress's colours. */
.eb-bk .eb-bk-textarea { display: block; resize: vertical; line-height: 1.45; }
/* SCOPED, and that is the fix, not the colour (2026-09-18, v0.2.95). field()
   puts <span class="eb-bk-err"> inside <label class="eb-bk-field">, which makes
   it a direct child — and `.eb-bk-field > span` is (0,1,1) against this rule's
   (0,1,0). So every validation message in this module has been rendering as a
   FIELD LABEL: Oswald, 11px, uppercase, letterspaced, in muted grey. Measured
   #656460 where it should have been red. `.eb-bk .eb-bk-err` is (0,2,0) and
   wins; the properties below are the ones it always declared. */
.eb-bk .eb-bk-err { font-family: var(--ebk-barlow); font-weight: 600; font-size: 12.5px; letter-spacing: normal; text-transform: none; color: var(--ebk-red-text); }
.eb-bk-fieldrow { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }
.eb-bk-stack { display: flex; flex-direction: column; gap: 16px; }
.eb-bk-hp { position: absolute !important; left: -9999px !important; width: 1px; height: 1px; opacity: 0; }

/* --- SMS consent (2026-09-18, v0.2.96) ----------------------------------
   One checkbox, unchecked, optional, on the Details step of both lanes. The
   `.eb-bk-consent` rules deleted from this file earlier today are NOT coming
   back and this is not them: that class dressed a SENTENCE bound to the primary
   action ("by tapping Confirm…"), which is implied consent and unevidencable.
   This is a separable control with its own label and its own record.

   Not a `.eb-bk-field`: that wrapper's `> span` is Oswald, 11px, uppercase and
   letterspaced — correct for a field label, wrong for a sentence somebody has to
   read and agree to. Two spans instead: the thing being agreed to, and the
   carrier-required disclosure under it.

   SCOPED to .eb-bk and declaring every property it owns, for the reason the
   whole file is: GeneratePress ships `input[type="checkbox"] { box-sizing;
   padding }` at (0,1,1), and `a, button, input { transition }` besides. Only
   the first is declared here; `.eb-bk .eb-bk-sms__box` is (0,2,1) and takes it.
   There is no !important and load order is not the mechanism.

   CONTRAST, measured against the cream card (#f4f1ea) the control sits on and
   the white (#fff) inside its own box:
     head  #0d0d0c on #f4f1ea                       17.24:1
     fine  rgba(13,13,12,.62) -> #656460 on #f4f1ea  5.25:1
     box border #65645f on #fff 5.93:1 / on cream    5.26:1   (bar is 3:1)
     checked: cream tick on ink ground              17.24:1
   The box was given --ebk-rail-idle rather than --ebk-line-st because, in
   v0.2.96, --ebk-line-st still composited to 1.56:1 and would have failed the
   border bar. That token was fixed in v0.2.98 (it is now #8A8880, 3.55:1), so the
   sidestep is no longer load-bearing -- but the box KEEPS --ebk-rail-idle: at
   22x22 it is the smallest control in the module and the stronger 5.93:1 edge is
   the one that was reviewed and signed off. */
.eb-bk-sms { display: flex; gap: 12px; align-items: flex-start; cursor: pointer; }
.eb-bk .eb-bk-sms__box {
	appearance: none; -webkit-appearance: none; box-sizing: border-box;
	flex: 0 0 auto; width: 22px; height: 22px; margin: 1px 0 0; padding: 0;
	background: var(--ebk-paper); border: 1.5px solid var(--ebk-rail-idle); border-radius: 3px;
	background-repeat: no-repeat; background-position: center; cursor: pointer;
	transition: background-color 0.15s ease, border-color 0.15s ease;
}
.eb-bk .eb-bk-sms__box:hover { border-color: var(--ebk-ink); }
/* The module's own check glyph (SVG.check in booking.js), drawn in --ebk-on-ink
   on the ink ground — the same "this one is chosen" pair as every selected
   control in the flow. Stated on :hover and :focus too, because GeneratePress
   contests grounds on both and an undeclared property is not a contest. */
.eb-bk .eb-bk-sms__box:checked,
.eb-bk .eb-bk-sms__box:checked:hover,
.eb-bk .eb-bk-sms__box:checked:focus {
	background-color: var(--ebk-ink); border-color: var(--ebk-ink);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23f4f1ea' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5 5L20 6'/%3E%3C/svg%3E");
}
.eb-bk-sms__copy { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.eb-bk-sms__head { font-family: var(--ebk-barlow); font-weight: 700; font-size: 14.5px; line-height: 1.35; color: var(--ebk-ink); }
.eb-bk-sms__fine { font-family: var(--ebk-barlow); font-weight: 500; font-size: 12.5px; line-height: 1.5; color: var(--ebk-mut); text-wrap: pretty; }
/* The privacy-policy link inside the fine print (wording v2, 2026-09-19).
   --ebk-red-text is the module's one red-as-text and is already measured at
   5.22:1 on this cream card, over the 4.5:1 bar. The underline and the extra
   weight are not decoration: they are the second and third channels, so the
   link is never colour alone against 12.5px muted ink at 5.25:1.

   It sits INSIDE the <label>, and that is safe rather than lucky: an <a href> is
   interactive content, so a click on it is not forwarded to the labelled
   checkbox. Reading the policy cannot tick the box.

   Scoped and declaring its own colour because GeneratePress ships `a { color }`
   from the customizer, inline in the head. (0,2,0) takes it; no !important. */
.eb-bk .eb-bk-sms__link {
	color: var(--ebk-red-text); font-weight: 600;
	text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px;
}
.eb-bk .eb-bk-sms__link:hover { color: var(--ebk-red-ink); }

/* --- Program chips (squared, bold) ------------------------------------- */
.eb-bk-chips { display: grid; grid-template-columns: 1fr; gap: 10px; margin-top: 10px; }
@media (min-width: 720px) { .eb-bk-chips { grid-template-columns: 1fr 1fr; } }
.eb-bk-chip {
	display: flex; flex-direction: column; align-items: flex-start; gap: 3px; text-align: left; width: 100%;
	/* --ebk-line-st, not --ebk-line (2026-09-19, v0.2.99). This is the program
	   chip: a <button>, and the first control anybody meets in the flow. Its
	   fill is --ebk-paper on the body's --ebk-canvas — 1.09:1 — so the fill
	   does not draw it and the border is the entire visual boundary of the
	   control. At rgba(13,13,12,0.12) that border measured 1.30:1 against its
	   own white and 1.29:1 against the cream, well under the 3:1 WCAG 1.4.11
	   asks of a control's boundary, and lower than the field borders v0.2.98
	   had just raised. It is now the same ink as every other control edge in
	   the module: 3.55:1 on white, 3.15:1 on cream. Only the colour moves —
	   the border stays 2px, so no chip changes size. */
	padding: 16px 17px; cursor: pointer; background: var(--ebk-paper); border: 2px solid var(--ebk-line-st);
	border-radius: 0; transition: border-color 0.14s ease, background 0.14s ease, color 0.14s ease;
	/* `color` is declared even though every text child below sets its own. An
	   UNDECLARED property is not a contest — leave it out and GeneratePress's
	   `button { color: #fff }` owns this element's currentColor, which is what
	   `outline-color` and any future inheriting child would resolve against. The
	   hostile-stylesheet probe caught exactly this on .eb-bk-chip and .eb-bk-tap,
	   the only two controls in the module that had left it open. */
	color: var(--ebk-ink);
}
/* HOVER HAD TO MOVE WITH IT. Hover was --ebk-line-st, which the resting state
   has now taken, and a hover that resolves to the colour already on the element
   is not a hover at all — raising the resting border would have silently cost
   the chip its pointer affordance. --ebk-ink is the step .eb-bk-tap:hover and
   .eb-bk-input:hover already use, and it is what the design's own `.md-in:hover`
   does, so the chip now climbs the same resting -> ink -> ink-filled ladder as
   every other control here rather than a private one. Selected stays distinct:
   it fills the ground and flips the text to cream, which hover never does. */
.eb-bk-chip:hover:not([data-on="1"]):not(:disabled) { border-color: var(--ebk-ink); }
.eb-bk-chip[data-on="1"] { background: var(--ebk-ink); border-color: var(--ebk-ink); color: var(--ebk-on-ink); }
/* THE DISABLED CHIP NO LONGER DIMS ITSELF (2026-09-20, v0.2.100). It was
   `opacity: 0.4`, and opacity composites the WHOLE subtree — including
   .eb-bk-chip__note, the "Not at this academy" line that is the only answer a
   person gets to "why can't I click this?". Measured on 968ffcc, with the chip's
   white fill and the note's --ebk-rail-idle both composited at 0.4 over the
   cream canvas:

       ground  #FFFFFF -> #F8F7F2      note ink  #65645F -> #BBB9B2    1.83:1
       (the note's DECLARED colour is 5.93:1 on white — the declared number was
        a fiction; nothing on screen was ever that colour)

   WCAG exempts inactive components, so this was never a violation. It was a
   design failure: the sentence that explains the state was the least legible
   thing in the module.

   RULED (2026-09-20): do NOT raise the opacity — a brighter chip reads ENABLED
   and reintroduces the confusion the dimming exists to prevent. So the opacity
   is gone entirely and the disabled state is stated the way this module already
   states one: --ebk-dis-bg / --ebk-dis-fg, the design's own disabled pair, which
   .eb-bk-btn--primary:disabled has used since the port. A ground swap, not a
   fade — the same move the CTA makes, so the module has ONE disabled mechanism
   rather than two.

   Why the note was not simply moved OUT of the <button> instead: it sits inside
   the control on purpose. It is part of the chip's accessible name, so a screen
   reader announces "Kids Jiu Jitsu, Not at this academy, dimmed". Lifting it to
   a sibling would fix the contrast for people who can see it and take the
   explanation away from everyone who cannot — an accessibility regression
   wearing an accessibility fix. The dimming is what had to leave, not the note.

       note  --ebk-dis-fg #4A4845 on --ebk-dis-bg #E3DFD6   6.85:1   (was 1.83)
       name  --ebk-dis-fg #4A4845 on --ebk-dis-bg #E3DFD6   6.85:1   (was 2.75)

   Name and note share an ink and the hierarchy still reads, because it was
   never the colour doing that work: 15px uppercase Oswald 600 against 10.5px
   Barlow. That is the same argument v0.2.99 made when it deleted --ebk-faint.

   --ebk-rail-idle, the module's one secondary-text ink, is NOT used here: on
   #E3DFD6 it measures 4.46:1 and misses the 4.5 bar for small text by 0.04.
   The disabled pair is the one that clears it, and it is already the pair this
   ground belongs to.

   GEOMETRY IS UNTOUCHED. No padding, border width, font size or gap moves, so a
   chip occupies exactly the pixels it did — only its ground and its inks change. */
.eb-bk-chip:disabled { background: var(--ebk-dis-bg); border-color: var(--ebk-line); cursor: not-allowed; }
.eb-bk-chip:disabled .eb-bk-chip__name,
.eb-bk-chip:disabled .eb-bk-chip__note { color: var(--ebk-dis-fg); }
.eb-bk-chip:disabled .eb-bk-chip__box { border-color: var(--ebk-rail-mark); }
.eb-bk-chip__row { display: flex; align-items: center; gap: 11px; width: 100%; }
.eb-bk-chip__box {
	width: 15px; height: 15px; flex: 0 0 auto; border-radius: 0; border: 2px solid var(--ebk-line-st);
	background: transparent; display: inline-flex; align-items: center; justify-content: center;
}
.eb-bk-chip[data-on="1"] .eb-bk-chip__box { border-color: var(--ebk-red); background: var(--ebk-red); }
.eb-bk-chip__name { font-family: var(--ebk-oswald); font-weight: 600; font-size: 15px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ebk-ink); }
.eb-bk-chip[data-on="1"] .eb-bk-chip__name { color: var(--ebk-on-ink); }
.eb-bk-chip__note { font-family: var(--ebk-barlow); font-weight: 600; font-size: 10.5px; letter-spacing: 0.08em; color: var(--ebk-rail-idle); padding-left: 26px; }

/* --- Tap targets (fork) + age toggle ----------------------------------- */
.eb-bk-taps { display: flex; flex-direction: column; gap: 12px; }
.eb-bk-tap {
	display: flex; flex-direction: column; align-items: flex-start; gap: 5px; text-align: left; width: 100%;
	padding: 20px; cursor: pointer; background: var(--ebk-paper); border: 1.5px solid var(--ebk-line-st);
	border-radius: 4px; transition: border-color 0.15s ease, background 0.15s ease, transform 0.12s ease;
	color: var(--ebk-ink);   /* see .eb-bk-chip — an undeclared colour is GP's to take */
}
.eb-bk-tap:hover { border-color: var(--ebk-ink); }
.eb-bk-tap:active { transform: translateY(1px); }
/* THE THREE .eb-bk-tap[data-on="1"] RULES THAT WERE HERE ARE DELETED
   (2026-09-19, v0.2.99) — and so is a FOURTH, in the selected-state guard at
   the foot of this file, which the audit that raised this had not counted.
   They styled a selected state that has never existed:
   forkHTML() emits both cards with data-exp and never data-on, nothing writes
   the attribute afterwards, and no other script on the site touches data-on.
   Three rules matched nothing.

   They are not a missing feature. The fork ADVANCES on tap — choosing a card
   leaves the step — so there is no moment at which a selected card could be
   seen, and walking back re-renders both cards unselected. Building the state
   would be building a frame nobody can ever be shown.

   Worth knowing because the corpse did damage: during 557abe9 these rules were
   read as evidence that a selected state existed, and the grey a card actually
   showed was blamed on them. It was GeneratePress's inline customizer CSS. A
   rule that matches nothing still gets quoted as if it described the product,
   which is the argument for deleting it rather than commenting it out.

   --ebk-on-ink-mut is NOT orphaned by this; .eb-bk-daytab[data-on="1"]
   .eb-bk-daytab__sub still uses it, on a control that really does select. */
.eb-bk-tap__title { font-family: var(--ebk-anton); font-size: 22px; line-height: 1.04; letter-spacing: 0.01em; text-transform: uppercase; color: var(--ebk-ink); }
.eb-bk-tap__sub { font-family: var(--ebk-barlow); font-weight: 500; font-size: 13.5px; line-height: 1.4; color: var(--ebk-mut); }
.eb-bk-agetoggle { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.eb-bk-agebtn {
	display: flex; align-items: center; justify-content: center; gap: 8px; padding: 15px 12px; cursor: pointer;
	background: var(--ebk-paper); border: 1.5px solid var(--ebk-line-st); border-radius: 3px;
	font-family: var(--ebk-oswald); font-weight: 600; font-size: 13px; letter-spacing: 0.06em;
	text-transform: uppercase; color: var(--ebk-ink); text-align: center;
}
.eb-bk-agebtn[data-on="1"] { border-color: var(--ebk-ink); background: var(--ebk-ink); color: var(--ebk-on-ink); }
.eb-bk-agebtn svg { color: var(--ebk-red); }
.eb-bk-agebtn[data-on="1"] svg { color: var(--ebk-red); }

/* --- Step rail (redesigned 2026-09-18, v0.2.95) --------------------------
   Not a recolour. The current step was a 13px red dot beside a label in
   rgba(ink,0.32) — the label measured 2.11:1 on cream, the least readable text
   in the module, and the dot was the same red as six decorative squares
   elsewhere on the screen. It is now an INK-FILLED TAB with a cream label:
   17.24:1, and the only filled element in the rail, so "you are here" reads
   louder than it did, not quieter. Idle and completed labels take the solid
   #65645F (5.25:1); the hollow marker and the not-yet connector take #8A8880
   (3.15:1, the non-text border minimum). Red survives inside the tab as a 7px
   square that carries nothing. */
.eb-bk-steprail { display: flex; align-items: center; gap: 6px; width: 100%; }
.eb-bk-steprail__seg { flex: 1 1 auto; height: 2px; background: var(--ebk-rail-mark); min-width: 8px; }
.eb-bk-steprail__seg.is-done { background: var(--ebk-ink); }
.eb-bk-steprail__node { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; padding: 6px 0; }
/* `color` is declared even though the label child sets its own — an undeclared
   property is not a contest, and the hostile-stylesheet probe caught this tab
   (and only this tab) taking a `span { color }` rule. Same reason .eb-bk-chip
   and .eb-bk-tap declare theirs. */
.eb-bk-steprail__node.is-cur { gap: 7px; background: var(--ebk-ink); padding: 6px 9px; color: var(--ebk-canvas); }
.eb-bk-steprail__box {
	width: 13px; height: 13px; border-radius: 0; flex: 0 0 auto; border: 2px solid var(--ebk-rail-mark);
	background: transparent; display: inline-flex; align-items: center; justify-content: center;
}
.eb-bk-steprail__node.is-done .eb-bk-steprail__box { border-color: var(--ebk-ink); background: var(--ebk-ink); color: var(--ebk-canvas); }
.eb-bk-steprail__mark { width: 7px; height: 7px; flex: 0 0 auto; background: var(--ebk-red); }
.eb-bk-steprail__lab { font-family: var(--ebk-oswald); font-weight: 600; font-size: 10.5px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ebk-rail-idle); white-space: nowrap; }
.eb-bk-steprail__node.is-cur .eb-bk-steprail__lab { color: var(--ebk-canvas); }
@media (min-width: 720px) {
	.eb-bk-steprail { gap: 10px; }
	.eb-bk-steprail__node { padding: 7px 2px; }
	.eb-bk-steprail__node.is-cur { padding: 7px 12px; }
	.eb-bk-steprail__lab { font-size: 11.5px; }
	/* The rail is the modal's width at 600px, and 920px of card would stretch
	   four labels across the whole header. The design file caps it and centres. */
	.eb-bk-modal[data-wide] .eb-bk-rail { max-width: 560px; margin-inline: auto; }
}

/* --- Slots: day tabs (Layout B) + chips --------------------------------- */
.eb-bk-slots-layout { display: block; }
@media (min-width: 720px) {
	.eb-bk-modal[data-wide] .eb-bk-slots-layout { display: grid; grid-template-columns: 1.2fr 1fr; gap: 30px; align-items: start; }
	/* `min-width: 0` is the whole of the empty region on Pick-a-time (v0.2.94).
	   A grid item's automatic minimum size is its MIN-CONTENT width, and column
	   one holds the day rail — fourteen day tabs, which do not wrap. So the
	   1.2fr column was floored at the rail's full 997px inside an 880px modal:
	   the "1.2fr 1fr" resolved to `997.469px 166.188px`, the what-happens column
	   was crushed to 166px and pushed to x=1333 (the modal ends at x=1160, and
	   `overflow: hidden` clipped it away — the "tall empty region" is that column
	   being off-screen), and at 166px wide its text stacked 854px tall, which is
	   what dragged the CTA 253px below the fold. Releasing the floor: columns
	   435/363, the day rail scrolls as it was always meant to (scrollWidth 997,
	   clientWidth 435), the panel is 363x344, and the body's scroll height falls
	   from 984px to 474px — shorter than the viewport, so nothing scrolls at all. */
	.eb-bk-modal[data-wide] .eb-bk-slots-layout > * { min-width: 0; }
}
.eb-bk-daytabs { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 6px; margin-bottom: 16px; }
.eb-bk-daytab {
	flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 62px;
	padding: 10px 12px; border-radius: 3px; cursor: pointer; background: var(--ebk-paper);
	border: 1.5px solid var(--ebk-line-st); color: var(--ebk-ink);
}
.eb-bk-daytab[data-on="1"] { background: var(--ebk-ink); border-color: var(--ebk-ink); color: var(--ebk-on-ink); }
.eb-bk-daytab__head { font-family: var(--ebk-oswald); font-weight: 700; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; }
/* --ebk-mut, not the old --ebk-faint (deleted in v0.2.99, see the token
   block): this is the DATE under the weekday ("Sep 20"),
   which is how a person tells one Monday from the next, and at 0.32 alpha on
   white it measured 2.12:1. The same token the selected tab's date already uses
   at its own weight; 5.50:1 (2026-09-18). */
.eb-bk-daytab__sub { font-family: var(--ebk-barlow); font-weight: 600; font-size: 11px; color: var(--ebk-mut); }
.eb-bk-daytab[data-on="1"] .eb-bk-daytab__sub { color: var(--ebk-on-ink-mut); }
.eb-bk-slotgrid { display: flex; flex-wrap: wrap; gap: 9px; }
.eb-bk-slot {
	display: inline-flex; align-items: center; gap: 8px; padding: 13px 17px; border-radius: 0; cursor: pointer;
	background: var(--ebk-paper); border: 2px solid var(--ebk-line-st); min-height: 48px;
	font-family: var(--ebk-oswald); font-weight: 600; font-size: 14.5px; letter-spacing: 0.04em;
	text-transform: uppercase; color: var(--ebk-ink); white-space: nowrap;
	transition: border-color 0.14s ease, background 0.14s ease, transform 0.1s ease;
}
.eb-bk-slot:hover:not([data-on="1"]) { border-color: var(--ebk-ink); }
.eb-bk-slot:active { transform: translateY(1px); }
.eb-bk-slot__clock { display: inline-flex; color: var(--ebk-red); }
.eb-bk-slot[data-on="1"] { background: var(--ebk-ink); border-color: var(--ebk-ink); color: var(--ebk-on-ink); }
.eb-bk-slot[data-on="1"] .eb-bk-slot__clock { color: var(--ebk-red); }

/* Skeleton + empty states. */
.eb-bk-skel-group { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
.eb-bk-skel { display: block; background: var(--ebk-sunken); border-radius: 3px; }
@media (prefers-reduced-motion: no-preference) { .eb-bk-skel { animation: ebkPulse 1.1s ease-in-out infinite; } }
@keyframes ebkPulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 0.85; } }
.eb-bk-finding { font-family: var(--ebk-oswald); font-weight: 600; font-size: 11px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ebk-rail-idle); }
.eb-bk-empty {
	padding: 24px 18px; text-align: center; background: var(--ebk-sunken);
	border: 1px dashed var(--ebk-line-st); border-radius: 5px;
}
.eb-bk-empty--all { padding: 30px 20px; }
.eb-bk-empty__t { font-family: var(--ebk-oswald); font-weight: 600; font-size: 13px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ebk-ink); margin-bottom: 6px; }
.eb-bk-empty__p { font-family: var(--ebk-barlow); font-weight: 500; font-size: 13.5px; line-height: 1.5; color: var(--ebk-mut); max-width: 320px; margin: 0 auto; }

/* --- What-happens (light palette, photo + steps) ------------------------ */
.eb-bk-what { margin-top: 24px; }
@media (min-width: 720px) { .eb-bk-modal[data-wide] .eb-bk-what { margin-top: 0; } }
.eb-bk-what__photo {
	width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; border-radius: 6px;
	margin-bottom: 14px; background: var(--ebk-sunken);
}
@media (min-width: 720px) { .eb-bk-modal[data-wide] .eb-bk-what__photo { aspect-ratio: 4 / 3; } }
.eb-bk-what__panel { background: var(--ebk-sunken); border-radius: 5px; padding: 20px 20px 22px; border: 1px solid var(--ebk-line); }
.eb-bk-what__head { display: flex; align-items: center; gap: 9px; margin-bottom: 16px; font-family: var(--ebk-oswald); font-weight: 600; font-size: 12px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ebk-ink); }
.eb-bk-what__head svg { color: var(--ebk-red); }
.eb-bk-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.eb-bk-steps li { display: flex; gap: 13px; align-items: flex-start; }
/* INK GROUND, CREAM NUMERAL (2026-09-19, v0.2.98). These are the numbered discs
   in "What happens at your first class", and they carry DIGITS -- so they are
   text and the bar is 4.5:1, not the 3:1 a bare decorative disc would get. They
   were a white numeral on #F04137: 3.81:1, a fail. The design's colour sheet does
   list #F04137 for "step numbers", but the same sheet's rule is that #F04137
   carries NO TEXT, and a numeral is text; the sheet's own resolution of that
   collision is the current-step tab, which stopped being red and became an ink
   tab with a cream label. These discs now take that identical pair -- the module's
   one selected-state pair, --ebk-ink / --ebk-on-ink, which every control that can
   be chosen already uses.
     before  #FFFFFF on #F04137  3.81:1  FAIL
     after   #F4F1EA on #0D0D0C 17.24:1  PASS
   Geometry is untouched: 25x25, radius 999px, Oswald 700/13px as drawn. Red is
   not removed from the panel -- .eb-bk-what__head svg is still #F04137, and it
   carries nothing. */
.eb-bk-steps__n {
	flex: 0 0 auto; width: 25px; height: 25px; border-radius: 999px; background: var(--ebk-ink); color: var(--ebk-on-ink);
	display: inline-flex; align-items: center; justify-content: center; font-family: var(--ebk-oswald);
	font-weight: 700; font-size: 13px; margin-top: 1px;
}
.eb-bk-steps__t { font-family: var(--ebk-barlow); font-weight: 500; font-size: 14px; line-height: 1.5; color: var(--ebk-mut); text-wrap: pretty; }
.eb-bk-reassure { display: flex; gap: 10px; align-items: center; margin-top: 16px; padding-top: 15px; border-top: 1px solid var(--ebk-line); }
.eb-bk-reassure svg { color: var(--ebk-red); flex: 0 0 auto; }
.eb-bk-reassure span { font-family: var(--ebk-barlow); font-weight: 600; font-size: 13.5px; line-height: 1.4; color: var(--ebk-ink); text-wrap: pretty; }

/* --- Summary card (2px ink-bordered, squared) -------------------------- */
.eb-bk-summary { background: var(--ebk-paper); border: 2px solid var(--ebk-ink); padding: 2px 18px; }
.eb-bk-summary--soft { border: 1px solid var(--ebk-line); border-radius: 5px; padding: 4px 18px; box-shadow: 0 1px 0 rgba(13, 13, 12, 0.04), 0 20px 40px -34px rgba(13, 13, 12, 0.5); }
.eb-bk-srow { display: flex; gap: 14px; align-items: flex-start; padding: 16px 0; border-top: 1px solid var(--ebk-line); }
.eb-bk-srow:first-child { border-top: none; }
.eb-bk-srow__icon { display: inline-flex; color: var(--ebk-red); flex: 0 0 auto; margin-top: 1px; }
/* --ebk-rail-idle, not the old --ebk-mut2 (deleted in v0.2.98, see the eyebrow
   above): these labels sit on the summary card's WHITE
   ground, where rgba(13,13,12,0.45) composites to #929292 and measures 3.11:1 —
   the only text on the merged screen that failed. 5.74:1, and the design file's
   own value for this row (2026-09-18). */
.eb-bk-srow__lab { font-family: var(--ebk-oswald); font-weight: 600; font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ebk-rail-idle); }
/* `overflow-wrap` is for the Email row (2026-09-17): an address is one unbreakable
   token and a long one would push the summary past the modal on a 320px phone. No
   other value in this list lacks a space, so nothing else can change. */
.eb-bk-srow__val { font-family: var(--ebk-barlow); font-weight: 700; font-size: 16.5px; line-height: 1.3; color: var(--ebk-ink); overflow-wrap: anywhere; }
.eb-bk-srow__sub { font-family: var(--ebk-barlow); font-weight: 500; font-size: 13.5px; line-height: 1.4; color: var(--ebk-mut); }
.eb-bk-srow__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.eb-bk-srow__dir { align-self: flex-start; margin-top: 4px; font-family: var(--ebk-barlow); font-weight: 700; font-size: 12.5px; line-height: 1.4; color: var(--ebk-red-text); text-decoration: underline; white-space: nowrap; }

/* --- The merged DETAILS screen (2026-09-18, v0.2.95) ---------------------
   Review & Confirm folded into Details, so what you chose and what you type now
   share one surface. Two densities of the same summary ship in the markup and
   CSS picks exactly one — `display: none` keeps the other out of the
   accessibility tree, so no screen reader is read the booking twice.

     <=719px   `__lead`, the condensed three-line block, ~96px tall. The first
               field is on screen without scrolling. `__rows` opens under it on
               the "All details" disclosure.
     >=720px   `__lead` is gone, `__rows` is always open, and the whole aside
               moves into its own 300px column beside the fields, where it stays
               put while the form scrolls.

   The Class row is `--wide`: at 390 the lead already prints the program, and
   the row would be the same sentence twice, 30px apart. */
.eb-bk-merged { display: block; }
.eb-bk-merged__aside { display: flex; flex-direction: column; gap: 16px; margin-bottom: 18px; }
.eb-bk-merged__head .eb-bk-h { margin-bottom: 10px; }
.eb-bk-merged__head .eb-bk-sub { margin-bottom: 0; max-width: 440px; }

.eb-bk-sum { background: var(--ebk-paper); border: 2px solid var(--ebk-ink); }
.eb-bk-sum__lead { display: flex; gap: 11px; align-items: flex-start; padding: 13px 14px; }
.eb-bk-sum__icon { display: inline-flex; color: var(--ebk-red); flex: 0 0 auto; margin-top: 2px; }
.eb-bk-sum__body { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
.eb-bk-sum__kick { font-family: var(--ebk-oswald); font-weight: 600; font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ebk-mut); }
.eb-bk-sum__prog { font-family: var(--ebk-barlow); font-weight: 700; font-size: 15.5px; line-height: 1.25; color: var(--ebk-ink); }
.eb-bk-sum__when { font-family: var(--ebk-barlow); font-weight: 600; font-size: 13.5px; line-height: 1.35; color: var(--ebk-ink); }
.eb-bk-sum__where { font-family: var(--ebk-barlow); font-weight: 500; font-size: 13px; line-height: 1.35; color: var(--ebk-mut); }
.eb-bk-sum__free { font-family: var(--ebk-barlow); font-weight: 500; font-size: 12.5px; line-height: 1.35; color: var(--ebk-mut); }
/* 44px of height on a control whose label is 10.5px — the tap target is the
   reason, not the type. */
.eb-bk-sum__toggle {
	flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px; min-height: 44px; padding: 0 2px;
	background: none; border: none; cursor: pointer; font-family: var(--ebk-oswald); font-weight: 600;
	font-size: 10.5px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ebk-ink);
}
.eb-bk-sum__togglab { border-bottom: 2px solid var(--ebk-red-text); padding-bottom: 1px; }
.eb-bk-sum__caret { color: var(--ebk-red-text); font-size: 9px; }
.eb-bk-sum__rows { display: none; padding: 2px 14px; border-top: 1px solid var(--ebk-line); }
.eb-bk-sum[data-open] .eb-bk-sum__rows { display: block; }
.eb-bk-sum .eb-bk-srow--wide { display: none; }

/* The two-column form is the WIDE CARD's layout, not a viewport's.
   `:not(.eb-bk-embed)` because the inline mount on /free-class/ carries
   .eb-bk-modal and takes data-wide with it, but it lives in the page's article
   column — measured 666px at a 1440 viewport, where a fixed 300px summary left
   the fields 332px and squeezed every two-up row to its 150px minimum. A media
   query cannot tell those two 1440s apart; the card can. The embed keeps the
   condensed summary and the stacked fields, which is what 666px wants. */
@media (min-width: 720px) {
	.eb-bk-modal[data-wide]:not(.eb-bk-embed) .eb-bk-merged { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 34px; align-items: start; }
	/* Same floor release as the Pick-a-time grid (v0.2.94): a grid item's
	   automatic minimum size is its min-content width, and a field row that
	   cannot wrap would push this column past the card. */
	.eb-bk-modal[data-wide]:not(.eb-bk-embed) .eb-bk-merged > * { min-width: 0; }
	.eb-bk-modal[data-wide]:not(.eb-bk-embed) .eb-bk-merged__aside { margin-bottom: 0; position: sticky; top: 0; }
	.eb-bk-modal[data-wide]:not(.eb-bk-embed) .eb-bk-sum__lead { display: none; }
	.eb-bk-modal[data-wide]:not(.eb-bk-embed) .eb-bk-sum__rows { display: block; border-top: none; padding: 2px 16px; }
	.eb-bk-modal[data-wide]:not(.eb-bk-embed) .eb-bk-sum .eb-bk-srow--wide { display: flex; }
}

/* --- Notes / alerts -----------------------------------------------------
   `.eb-bk-consent` and `.eb-bk-fb-consent` were deleted here (2026-09-18).
   They were the containers for the SMS consent sentence that f4aed35 removed
   from all three renderers on 2026-09-07 — dead rules whose only remaining
   function was to make it cheap to put that sentence back. It does not go back:
   10DLC is not approved, "by tapping" is implied consent bound to the primary
   action, and the design file draws it on the KIDS artboards, where consent is
   never collected at all. */
.eb-bk-note { display: flex; gap: 10px; align-items: flex-start; background: var(--ebk-sunken); border: 1px solid var(--ebk-line); border-radius: 4px; padding: 12px 14px; }
.eb-bk-note::before { content: ""; width: 6px; height: 6px; border-radius: 999px; background: var(--ebk-red); flex: 0 0 auto; margin-top: 7px; }
.eb-bk-note span { font-family: var(--ebk-barlow); font-weight: 500; font-size: 13px; line-height: 1.5; color: var(--ebk-mut); text-wrap: pretty; }
/* A failure the prospect can't fix in a field: token, rate limit, dead request,
   server error. Louder than .eb-bk-note (which is reassurance) because this one
   is the only thing standing between them and a lost booking (2026-09-16). */
.eb-bk-alert { display: flex; flex-direction: column; gap: 8px; margin: 0 0 20px; background: rgba(240, 65, 55, 0.06); border: 1px solid rgba(240, 65, 55, 0.3); border-left: 3px solid var(--ebk-red); border-radius: 4px; padding: 12px 14px; }
.eb-bk-alert span { font-family: var(--ebk-barlow); font-weight: 500; font-size: 13.5px; line-height: 1.5; color: var(--ebk-ink); text-wrap: pretty; }
.eb-bk-alert a { color: var(--ebk-red-text); font-weight: 700; text-decoration: underline; white-space: nowrap; }
.eb-bk-minorbox { display: flex; flex-direction: column; gap: 16px; padding: 16px; background: var(--ebk-sunken); border: 1px solid var(--ebk-line); border-radius: 5px; }

/* --- Success ------------------------------------------------------------ */
.eb-bk-success { text-align: center; padding-top: 8px; }
.eb-bk-success__check {
	display: inline-flex; align-items: center; justify-content: center; width: 64px; height: 64px;
	border-radius: 0; background: var(--ebk-red-btn); color: #fff; margin-bottom: 18px;
	box-shadow: 0 3px 0 var(--ebk-red-ink);
}
.eb-bk-success__kick { font-family: var(--ebk-oswald); font-weight: 600; font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ebk-red-text); margin-bottom: 8px; }
.eb-bk-success__title { margin: 0; font-family: var(--ebk-anton); font-weight: 400; font-size: 42px; line-height: 1; letter-spacing: 0.01em; text-transform: uppercase; color: var(--ebk-ink); }
.eb-bk-success__cal { display: flex; align-items: center; justify-content: center; gap: 9px; margin: 16px 0 22px; }
.eb-bk-success__cal svg { color: var(--ebk-red); }
.eb-bk-success__cal span { font-family: var(--ebk-barlow); font-weight: 600; font-size: 14px; color: var(--ebk-mut); }
.eb-bk-success__cal b { color: var(--ebk-ink); font-weight: 700; }
.eb-bk-success__cal--noinvite { margin-inline: auto; max-width: 380px; }
.eb-bk-success__cal--noinvite span { text-align: center; }
.eb-bk-success__after { display: flex; gap: 11px; align-items: flex-start; padding: 0 2px; }
.eb-bk-success__after svg { color: var(--ebk-red); flex: 0 0 auto; margin-top: 1px; }
.eb-bk-success__after span { font-family: var(--ebk-barlow); font-weight: 500; font-size: 13.5px; line-height: 1.5; color: var(--ebk-mut); text-wrap: pretty; }
.eb-bk-success__exp-p { margin: 18px auto 0; max-width: 380px; text-align: center; font-family: var(--ebk-barlow); font-weight: 500; font-size: 15px; line-height: 1.55; color: var(--ebk-mut); text-wrap: pretty; }

/* --- No-JS fallback form ------------------------------------------------ */
.eb-bk-fallback { display: flex; flex-direction: column; gap: 14px; max-width: 460px; }
.eb-bk-fb-field { display: flex; flex-direction: column; gap: 6px; margin: 0; }
.eb-bk-fb-field label { font-family: var(--ebk-oswald); font-weight: 600; font-size: 11px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ebk-mut); }
.eb-bk-fb-field label span { color: var(--ebk-rail-idle); }
/* Scoped to .eb-bk for the same reason as the modal's fields, and it matters just
   as much here even though nothing moves: unscoped, `.eb-bk-fallback input` is
   (0,1,1) — an exact TIE with GeneratePress's `input[type="text"]`, resolved only
   by booking.css loading later. It renders correctly today by load order alone.
   (0,2,1) makes that a win on specificity. `textarea` is in the list so a
   multi-line field added here can never be the odd one out the way the modal's
   notes field was; it matches nothing in the form as it stands. */
.eb-bk .eb-bk-fallback input, .eb-bk .eb-bk-fallback select, .eb-bk .eb-bk-fallback textarea { width: 100%; padding: 13px 14px; font-family: var(--ebk-barlow); font-size: 16px; border: 1px solid var(--ebk-line-st); border-radius: 3px; background: var(--ebk-paper); color: var(--ebk-ink); }
/* The notes textarea joined this form on 2026-09-20 and the rule above already
   dressed it — `textarea` was listed there from the start, against the day one
   arrived. These two are what the modal's .eb-bk-textarea adds on top, restated
   for this lane so a multi-line field reads the same in both: drag it taller if
   you have more to say, and lines that are not crammed together. */
.eb-bk .eb-bk-fallback textarea { resize: vertical; line-height: 1.45; }

/* --- Notices (success/error banners on /free-class/) -------------------- */
.eb-bk-notice { padding: 14px 18px; border-radius: 4px; font-family: var(--ebk-barlow); font-weight: 600; font-size: 15px; margin-bottom: 20px; }
.eb-bk-notice--ok { background: rgba(31, 122, 77, 0.10); border: 1px solid rgba(31, 122, 77, 0.35); color: #1f7a4d; }
.eb-bk-notice--err { background: rgba(240, 65, 55, 0.08); border: 1px solid rgba(240, 65, 55, 0.30); color: var(--ebk-red-ink); }
/* The notice carries its own links (the stale-token reload + the front-desk
   number). Inherit the notice's ink so they read on its tinted ground rather
   than taking GeneratePress's global link colour. */
.eb-bk-notice a { color: inherit; font-weight: 700; text-decoration: underline; }

/* ==========================================================================
   THE HOVER/FOCUS GUARD — and the selected state restated inside it
   2026-09-18, v0.2.94
   ==========================================================================

   v0.2.93 scoped this module's FIELD rules to `.eb-bk` because GeneratePress
   outranked them. The same thing was happening, unnoticed, to every BUTTON in
   the module — and it is what Ignacio saw as "the selected card is black text on
   dark grey" on the first-time / trained-before fork.

   GeneratePress emits, inline in the head (inc/css-output.php, from the
   customizer's form-button colours, so it is NOT in main.min.css and a grep of
   the stylesheet misses it):

       button:hover, …, button:focus, … { color:#ffffff; background-color:#3f4047 }

   That is (0,1,1). Every control here is a real <button> whose own ground is
   declared at (0,1,0) — `.eb-bk-tap`, `.eb-bk-chip`, `.eb-bk-slot`,
   `.eb-bk-daytab`, `.eb-bk-agebtn`, `.eb-bk-btn--primary`, `.eb-bk-change`,
   `.eb-bk-iconbtn`. GP wins all eight. The module's own hover rules did not save
   them: they set `border-color` only, so the BACKGROUND declaration was never
   contested and #3f4047 went straight through.

   Why it read as "selected": `render()` focuses the first focusable control on
   every step, so on the fork the first card arrives already `:focus` — grey
   before the visitor has done anything. And `:focus`, unlike `:focus-visible`,
   does not care that the visitor used a mouse. Measured end states before this
   block (Chrome, forced pseudo-state, read after the transition settles):

       .eb-bk-tap:focus     #3f4047 ground, .eb-bk-tap__title stays #0d0d0c  1.45:1
       .eb-bk-chip:hover    #3f4047 ground, .eb-bk-chip__name stays #0d0d0c  1.45:1
       .eb-bk-daytab:hover  #3f4047 ground, __sub stays rgba(13,13,12,.32)   1.11:1
       .eb-bk-agebtn[data-on="1"]:hover  ink TEXT turned #fff on its own
                            near-white selected ground                       1.07:1
       .eb-bk-btn--primary:hover/:focus  the red CTA turns #3f4047

   The fix is 99abaf4's, applied to buttons: scope to the module root. `.eb-bk
   .eb-bk-tap:hover` is (0,2,1) and beats (0,1,1) on specificity, so it cannot
   reopen the next time a stylesheet ships `button:hover`. No !important, and
   load order is deliberately not the mechanism.

   Each control states its ground AND its ink in hover and focus, because GP sets
   both. The values are the control's own resting values — nothing here is a new
   colour, and a control that genuinely changes on hover (the icon button's
   sunken wash, and the border moves that live with each control above) keeps
   doing so. */
.eb-bk .eb-bk-btn--primary:hover, .eb-bk .eb-bk-btn--primary:focus { background: var(--ebk-red-btn-hv); color: #fff; }
.eb-bk .eb-bk-btn--primary:disabled:hover, .eb-bk .eb-bk-btn--primary:disabled:focus { background: var(--ebk-dis-bg); color: var(--ebk-dis-fg); }
.eb-bk .eb-bk-btn--ghost:hover, .eb-bk .eb-bk-btn--ghost:focus { background: transparent; color: var(--ebk-ink); }
.eb-bk .eb-bk-btn--quiet:hover, .eb-bk .eb-bk-btn--quiet:focus { background: transparent; color: var(--ebk-mut); }
.eb-bk .eb-bk-iconbtn:hover, .eb-bk .eb-bk-iconbtn:focus { background: var(--ebk-sunken); color: var(--ebk-ink); }
.eb-bk .eb-bk-change:hover, .eb-bk .eb-bk-change:focus { background: transparent; color: var(--ebk-ink); }
.eb-bk .eb-bk-chip:hover, .eb-bk .eb-bk-chip:focus { background: var(--ebk-paper); color: var(--ebk-ink); }
/* The chip's disabled ground needs the same guard line the CTA has had since
   the port. `:hover` MATCHES a disabled button — the pseudo-class is about the
   pointer, not about whether the control can be activated — so without this,
   .eb-bk .eb-bk-chip:hover (0,2,1) would hand an unavailable chip the white
   ground of an available one the moment the pointer crossed it, which is
   precisely the "reads as enabled" failure the ruling was about. (0,3,1). */
.eb-bk .eb-bk-chip:disabled:hover, .eb-bk .eb-bk-chip:disabled:focus { background: var(--ebk-dis-bg); color: var(--ebk-dis-fg); }
.eb-bk .eb-bk-tap:hover, .eb-bk .eb-bk-tap:focus { background: var(--ebk-paper); color: var(--ebk-ink); }
.eb-bk .eb-bk-agebtn:hover, .eb-bk .eb-bk-agebtn:focus { background: var(--ebk-paper); color: var(--ebk-ink); }
.eb-bk .eb-bk-daytab:hover, .eb-bk .eb-bk-daytab:focus { background: var(--ebk-paper); color: var(--ebk-ink); }
.eb-bk .eb-bk-slot:hover, .eb-bk .eb-bk-slot:focus { background: var(--ebk-paper); color: var(--ebk-ink); }
/* The summary disclosure joined the module on 2026-09-18 and is the NINTH real
   <button> here, so it needs the same guard as the other eight: measured, it
   took GeneratePress's #3f4047 ground and #fff ink the moment it was hovered or
   focused — a dark-grey block where a text link had been. */
.eb-bk .eb-bk-sum__toggle:hover, .eb-bk .eb-bk-sum__toggle:focus { background: none; color: var(--ebk-ink); }

/* The four selected states, restated at (0,3,0)/(0,4,0) so they outrank the
   guard above in every combination — a chosen card must stay chosen while the
   pointer is on it. Same ink ground and cream ink for all four, so "this is the
   one you picked" reads identically wherever the flow asks a question:

       ground #0d0d0c · ink #f4f1ea = 17.16:1   (label text)
       ground #0d0d0c · ink rgba(244,241,234,0.72) = 9.20:1   (sub-labels)

   The time chip moved OFF red to get here. Red ground with white text measures
   3.02:1 and fails 4.5:1 — it was the only selected state in the module that was
   unreadable by the numbers rather than by GeneratePress's doing. The clock
   glyph keeps the red (4.87:1 on ink), so red stays the accent it is everywhere
   else in this design. */
.eb-bk .eb-bk-chip[data-on="1"], .eb-bk .eb-bk-chip[data-on="1"]:hover, .eb-bk .eb-bk-chip[data-on="1"]:focus { background: var(--ebk-ink); color: var(--ebk-on-ink); }
/* .eb-bk-tap WAS the fifth line here and is deleted with the other three (see
   the fork block above): it is the only one of the five whose markup never
   carries data-on, so it guarded a state that cannot occur. It was also the
   most misleading of the four, because a list captioned "the selected states"
   is read as an inventory — it asserted the fork HAS one. The tap's :hover and
   :focus guard higher up is real and stays; it is the selected line that goes. */
.eb-bk .eb-bk-agebtn[data-on="1"], .eb-bk .eb-bk-agebtn[data-on="1"]:hover, .eb-bk .eb-bk-agebtn[data-on="1"]:focus { background: var(--ebk-ink); color: var(--ebk-on-ink); }
.eb-bk .eb-bk-daytab[data-on="1"], .eb-bk .eb-bk-daytab[data-on="1"]:hover, .eb-bk .eb-bk-daytab[data-on="1"]:focus { background: var(--ebk-ink); color: var(--ebk-on-ink); }
.eb-bk .eb-bk-slot[data-on="1"], .eb-bk .eb-bk-slot[data-on="1"]:hover, .eb-bk .eb-bk-slot[data-on="1"]:focus { background: var(--ebk-ink); color: var(--ebk-on-ink); }

/* Keyboard focus, stated rather than inherited. The browser default was a 1px
   `outline: auto` in Chrome's blue — it survives, but it is the one piece of
   this flow that was never designed, and on a selected ink card it is the only
   thing distinguishing focus from selection, so it has to be unmistakable.

   `outline-offset: 2px` puts the ring OUTSIDE the control, which means it always
   lands on the modal's cream ground — never on the control's own. So one colour
   serves every state: ink on cream is 17.16:1, whether the control underneath is
   white, ink or red. Hover, focus and selected stay three visibly different
   things: hover moves the border, focus adds this ring, selected inverts the
   whole card. */
.eb-bk button:focus-visible, .eb-bk a.eb-bk-btn:focus-visible,
.eb-bk .eb-bk-input:focus-visible, .eb-bk .eb-bk-select:focus-visible,
.eb-bk .eb-bk-sms__box:focus-visible,
.eb-bk a.eb-bk-sms__link:focus-visible,
.eb-bk .eb-bk-fallback input:focus-visible, .eb-bk .eb-bk-fallback select:focus-visible,
.eb-bk .eb-bk-fallback textarea:focus-visible {
	outline: 3px solid var(--ebk-ink); outline-offset: 2px;
}
/* The day rail is a horizontal scroller, so a ring drawn 2px outside a tab would
   be clipped at the rail's own edges. Drawn just inside instead, in whichever of
   the pair contrasts with the tab's own ground. */
.eb-bk .eb-bk-btn--primary:focus-visible { outline-offset: 3px; }
.eb-bk .eb-bk-daytab:focus-visible { outline-offset: -4px; }
.eb-bk .eb-bk-daytab[data-on="1"]:focus-visible { outline-color: var(--ebk-on-ink); }
