/* ============================================
   /book-v2 — the booking redesign

   One screen for the whole "what am I buying" decision, staged as the route it
   actually is: the style, then the room, then the times, then a bar that reads
   the three back before the customer commits.

   Loaded AFTER book.css. Since the 2026-08-24 prune, book.css carries only the
   shared details / success / error structure (form, guests, code box, recap,
   voucher badges) — this file owns the whole choose flow and the theme, and no
   longer has to out-rank a dead desktop layout.

   Three previews collapsed into this one on 2026-08-23. What each contributed:
     v4  the staged route, and the honest empty state
     v3  the day strip — the week grid renders every hour of seven days at once,
         2377px tall at 375px wide, measured
     v5  the room repaints the page, via :has() and a token swap, with no JS
   ============================================ */

/* ── the theme ───────────────────────────────────────────────────────────────
   Every colour below resolves through these five tokens, which is the whole
   mechanism: the room choice reassigns them and the page follows. Anything that
   hardcodes a colour instead will be the one thing that stays white on black. */

/* Registering the theme tokens as real colours is what lets the room change fade
   instead of snap. The alternative — a transition on every element that reads
   them — would also slow down each control's own selection feedback, because the
   properties are the same ones: tapping the style toggle would take as long as
   repainting the page. Animating the token means the page crossfades while the
   controls stay instant.

   Unregistered custom properties cannot animate, so a browser without @property
   support simply gets today's instant swap. That is the same bet as :has() below:
   a complete page, just a plainer one. */
@property --bk-bg {
  syntax: '<color>';
  inherits: true;
  initial-value: #ffffff;
}
@property --bk-fg {
  syntax: '<color>';
  inherits: true;
  initial-value: #000000;
}
@property --bk-dim {
  syntax: '<color>';
  inherits: true;
  initial-value: #8a8078;
}
@property --bk-line {
  syntax: '<color>';
  inherits: true;
  initial-value: rgba(0, 0, 0, 0.12);
}
@property --bk-block {
  syntax: '<color>';
  inherits: true;
  initial-value: rgba(0, 0, 0, 0.04);
}

.book-v2 {
  /* long enough to read as the room arriving rather than a repaint, short enough
     not to sit between the tap and the times underneath it */
  --bk-fade: 900ms ease;

  --bk-bg: var(--light);
  --bk-fg: var(--ink);
  /* The brand token, unmodified — owner decision 2026-08-23. Measured at 3.86:1
     on white, which is under the 4.5:1 AA bar for normal text; that is a property
     of --selenium itself and therefore of every customer page, not of this one,
     so it is not this page's business to fork it. The dark theme is a different
     matter and does override, below: --selenium on black is 1.9:1, which is not
     a house style, it is unreadable. */
  --bk-dim: var(--selenium);
  --bk-line: rgba(0, 0, 0, 0.12);
  --bk-block: rgba(0, 0, 0, 0.04);

  /* instant twins of --bk-fg/--bk-bg: not @property-registered and not in the
     transition list, so they flip in one frame. The selected style chip reads
     these — riding the 900ms fade put its colors through matching luminance
     mid-flip and the selected label vanished for a second (measured live
     2026-08-24). Page-surface text stays on the animated pair on purpose. */
  --bk-fg-instant: var(--ink);
  --bk-bg-instant: var(--light);

  background: var(--bk-bg);
  color: var(--bk-fg);
  transition:
    --bk-bg var(--bk-fade),
    --bk-fg var(--bk-fade),
    --bk-dim var(--bk-fade),
    --bk-line var(--bk-fade),
    --bk-block var(--bk-fade);
}

/* The room choice repaints the page. :has() means book.js needs no new code — it
   already sets .is-selected on the chosen card. A browser without :has() simply
   stays on the light theme, which is a complete page, not a broken one. */
.book-v2:has(#room-options .room-card.is-selected[data-room='black']) {
  --bk-bg: var(--ink);
  --bk-fg: var(--light);
  /* NOT --dark-text-secondary: that token is #8a8078, the same selenium used on
     white, which lands at 1.9:1 against black — measured on /book-v3, where it
     shipped. A lightened selenium keeps the warm hue the brand specifies and
     clears AA on this surface. */
  --bk-dim: #b3aca6;
  --bk-line: rgba(255, 255, 255, 0.18);
  --bk-block: rgba(255, 255, 255, 0.06);
  --bk-fg-instant: var(--light);
  --bk-bg-instant: var(--ink);
}

@media (prefers-reduced-motion: reduce) {
  .book-v2,
  .book-v2 * {
    transition: none;
  }
}

/* ── header ──────────────────────────────────────────────────────────────────
   The full-bleed black slab the other surfaces carry cannot survive a page that
   inverts: on the black room it becomes a black block on black. One quiet line
   that follows the theme instead. */

.book-v2 .page-header {
  padding: var(--space-md) var(--space-md) var(--space-sm);
  background: transparent;
  color: var(--bk-fg);
  text-align: left;
}

/* the mark was invisible until 2026-08-24: brand.css paints .brand-mark
   fill: var(--dark-text-primary) — white, for the black header it was designed
   in — and this header is transparent, so the logo rendered white-on-white.
   currentColor follows --bk-fg, so it also survives the black-room inversion.
   Owner's call on placement: small, top-left, balancing the switcher top-right
   — the corner read as reserved-but-empty because it was. */
.book-v2 .page-header {
  position: relative;
}

.book-v2 .page-header .brand-mark {
  position: absolute;
  top: calc(var(--space-md) + 10px);
  left: var(--space-md);
  width: 34px;
  height: 25px;
  margin: 0;
  color: var(--bk-fg);
  fill: currentColor;
}

.book-v2 .page-header h1 {
  margin: 0;
  font-size: var(--text-h2);
  font-weight: var(--weight-semi);
  letter-spacing: var(--tracking-heading);
  color: var(--bk-fg);
}

.book-v2 .page-header .tagline {
  margin: 6px 0 0;
  font-size: var(--text-body-sm);
  color: var(--bk-dim);
}

.book-v2 .booking-content {
  padding: 0 0 var(--space-md);
  background: transparent;
}

/* ── the stages ──────────────────────────────────────────────────────────── */

.book-v2 .bk-stage {
  padding: 0 var(--space-md);
  /* section rhythm is one token, opened ABOVE each section (below), never
     closed underneath — the measured boundaries drifted 16/31/43 down the page
     and the first was inverted, binding "choose your style" to the header
     instead of to its own control */
  margin-bottom: 0;
}

.book-v2 .bk-stage-style {
  margin-top: var(--space-sm); /* + the header's 16px padding-bottom = 32 */
}

.book-v2 .bk-stage-room {
  margin-top: var(--space-md);
}

/* outside the pop-up the style stage is display:none and the room stage opens
   the page — display:none keeps sibling combinators alive, so the first-section
   rhythm (header 16 + 24 = 40) holds there too */
.book-v2 .bk-stage-style:has(#look-options[hidden]) + .bk-stage-room {
  margin-top: var(--space-sm); /* header 16 + 16 = 32, the first-section open */
}

.book-v2 .bk-heading {
  /* nikolai 2026-08-24: all three choose-flow headings speak the same small
     label voice, lowercase — the room, the style and the calendar are steps of
     one flow, not competing landmarks. matches his mockup. */
  margin: 0 0 var(--space-sm);
  font-size: var(--text-ui-label);
  font-weight: var(--weight-semi);
  letter-spacing: var(--tracking-ui);
  line-height: 1;
  color: var(--bk-dim);
}

/* "your details" / success / error join the one h2 rank — they fell through to
   book.css's max-440 24px and the UA default (with UA margins) above 440,
   outranking the choose-step headings and tying with the price */
.book-v2 #step-details h2,
.book-v2 #step-success h2,
.book-v2 #step-error h2 {
  font-size: var(--text-body-lg);
  line-height: 1.15;
  margin: 0 0 var(--space-sm);
}

/* Outside a pop-up the server sends one style, book.js hides the picker, and
   this collapses the whole stage — heading included. Without it the page keeps a
   heading over nothing, which is worse than the control it is hiding. */
.book-v2 .bk-stage-style:has(#look-options[hidden]) {
  display: none;
}

/* ── the style toggle ────────────────────────────────────────────────────────
   Two halves of one control rather than two loose pills: with exactly two
   options a segmented control says "one of these" in a way a pair of chips does
   not. It still renders correctly with more than two — the row just divides
   further — because the server decides how many there are, not this file. */

.book-v2 .look-options {
  display: block;
}

.book-v2 .look-options[hidden] {
  display: none;
}

.book-v2 .look-chips {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  border: 1px solid var(--bk-fg);
  border-radius: var(--radius-pill);
  overflow: hidden;
  transition: border-color var(--transition);
}

.book-v2 .look-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  /* the floor, not a coincidence: scripts/customer-device-audit.js fails the
     build under 44px, and the unstyled version of this control on /book-v5
     measured 26px */
  min-height: var(--touch-min);
  padding: 6px var(--space-sm);
  border: none;
  background: transparent;
  font-family: inherit;
  font-size: var(--text-body-sm);
  color: var(--bk-fg);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--transition),
    color var(--transition);
}

.book-v2 .look-chip.is-selected {
  background: var(--bk-fg-instant);
  color: var(--bk-bg-instant);
}

.book-v2 .look-name {
  font-weight: var(--weight-semi);
  letter-spacing: -0.01em;
}

/* The window the mockup leaves off. Without it, choosing retro greys most of the
   calendar with nothing on screen saying why — and an empty state has to name
   its cause (docs/brand/interaction-reference.md §3). */
.book-v2 .look-window {
  font-size: var(--text-micro);
  color: var(--bk-dim);
}

.book-v2 .look-chip.is-selected .look-window {
  color: var(--bk-bg-instant);
  opacity: 0.72;
}

/* ── the rooms ───────────────────────────────────────────────────────────── */

.book-v2 .room-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-xs);
}

.book-v2 .room-card {
  position: relative;
  /* the card sizes ITSELF; the photograph is an absolute fill layer below.
     With any in-flow child, a two-rule interaction in book.css inflated the
     card ~40px past its photograph and the scrim painted boards over bare
     card — the owner caught it against the CDN originals. No in-flow
     children means no strip, whatever the old sheet does. */
  display: block;
  aspect-ratio: 3 / 4;
  padding: 0;
  border: 1px solid var(--bk-line);
  border-radius: 0;
  background: transparent;
  overflow: hidden;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition:
    border-color var(--transition),
    opacity var(--transition);
}

.book-v2 .room-card .room-shot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focal, 50% 50%);
  transition: filter var(--transition);
}

/* The label sits ON the photograph behind a scrim rather than in a bar beneath
   it. A bar has to be painted in the theme's colours, and on the white room card
   that puts a white bar under a white-backdrop photograph. The scrim is
   photograph-independent: it works on both rooms and on both styles, which
   matters because the retro pop-up swaps both photographs. */
.book-v2 .room-meta {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: block;
  /* the taller top padding is gradient runway, not text spacing: the ramp needs
     room to reach zero without a visible start line. two stops made a smog band
     with a hard edge on the light photographs — reported by the owner on the
     switch day; the eased stops approximate a smooth curve instead */
  padding: calc(var(--space-lg) * 2.6) 10px 10px;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.82) 0%,
    rgba(0, 0, 0, 0.72) 20%,
    rgba(0, 0, 0, 0.52) 42%,
    rgba(0, 0, 0, 0.3) 62%,
    rgba(0, 0, 0, 0.13) 80%,
    rgba(0, 0, 0, 0.04) 92%,
    rgba(0, 0, 0, 0) 100%
  );
  text-align: left;
  pointer-events: none;
}

.book-v2 .room-name {
  display: block;
  /* the 2px under the name came from the old sheet's label rule; kept on its
     own feet when that rule was pruned (2026-08-24) */
  margin-bottom: 2px;
  font-size: var(--text-body);
  font-weight: var(--weight-semi);
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: #ffffff;
}

/* Hardcoded white with the scrim above it, deliberately — this text is over a
   photograph, not over the page, so it must not follow the theme. The 86% is
   measured against the scrim, not guessed: plain selenium here is what fell to
   2.06:1 on /book-v3. */
.book-v2 .room-desc {
  display: block;
  margin-top: 2px;
  max-width: 18ch;
  font-size: var(--text-micro);
  line-height: 1.3;
  color: rgba(255, 255, 255, 0.86);
}

.book-v2 .room-card.is-selected .bk-check {
  border-color: #ffffff;
  background: #ffffff;
  color: #000000;
}

/* press + pointer feedback, inherited behavior from the old sheet's rules and
   re-homed here when they were pruned (2026-08-24). Same guard as the original:
   hover only on real pointers, :active outside so touch keeps its feedback. */
.book-v2 .room-card:active {
  opacity: 0.5;
}

@media (hover: hover) and (pointer: fine) {
  .book-v2 .room-card:hover {
    opacity: 0.6;
  }
}

.book-v2 .room-card.is-selected {
  /* selection is the frame alone — the checks and the folder-tab drawer lines
     were both tried and taken off (owner, 2026-08-24): the pictures carry the
     page; their frames do the talking */
  border-color: var(--bk-fg);
  box-shadow: 0 0 0 1px var(--bk-fg);
}


/* The unchosen room recedes once a choice exists — but stays legible and stays a
   control, because switching rooms is the normal move on this layout. */
.book-v2 .room-options.is-chosen .room-card:not(.is-selected) .room-shot {
  /* darken, never whiten: the old opacity dim faded the photograph toward the
     page color, which turned the black room milky on the light page — the
     owner's first live report after the switch. Shadow dims both photographs
     toward themselves. Filter on the img, not a pseudo-element veil: see the
     .bk-check comment for why pseudos on these buttons paint nothing. The
     label scrim and check stay full-strength — the photograph recedes, the
     control stays. */
  filter: brightness(0.62);
}

/* ── the times ───────────────────────────────────────────────────────────── */

.book-v2 .bk-sheet {
  /* the same 24 that opens "choose a room" under the style pill — the owner
     measured the two boundaries against each other on the phone (2026-08-24),
     so they share one value on purpose. Change both or neither. */
  margin-top: var(--space-md);
  padding-top: 0;
}

.book-v2 .bk-sheet .bk-heading {
  padding: 0 var(--space-md);
}

/* Nothing to navigate before a room is chosen: the week label is empty and the
   two arrows float above an empty calendar looking like a broken control. */
.book-v2 .bk-sheet:has(.bk-invite) .calendar-nav {
  display: none;
}

.book-v2 .calendar-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  padding: 0 var(--space-md) var(--space-sm);
  /* calendar.css leaks an un-tokenized 14px margin-bottom onto the bare
     selector; the 16px padding above is the whole intended gap */
  margin-bottom: 0;
}

.book-v2 .calendar-nav .nav-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: var(--touch-min);
  min-height: var(--touch-min);
  border: 1px solid var(--bk-line);
  border-radius: 50%;
  background: transparent;
  font-family: inherit;
  font-size: var(--text-body);
  color: var(--bk-fg);
  cursor: pointer;
  transition:
    border-color var(--transition),
    color var(--transition);
}

.book-v2 .calendar-nav .nav-btn:disabled {
  /* nikolai: both rings the same color — dim the glyph, keep the outline */
  opacity: 1;
  color: var(--bk-dim);
  cursor: default;
}

.book-v2 #week-label {
  font-size: var(--text-body-sm);
  color: var(--bk-dim);
}

.book-v2 .pricing-info {
  padding: 0 var(--space-md);
}

/* No room chosen means nothing is loading and nothing will. "loading available
   times…" sat here permanently and was simply untrue. */
.book-v2 .bk-invite {
  margin: 0;
  padding: var(--space-lg) var(--space-md);
  text-align: center;
  font-size: var(--text-body-sm);
  color: var(--bk-dim);
}

/* calendar.css leaks margin-bottom: 16px onto the bare selector — the sheet's
   tail spacing belongs to the content padding, not a legacy margin */
.book-v2 .calendar {
  margin-bottom: 0;
}

.book-v2 .calendar .loading {
  padding: var(--space-lg) var(--space-md);
  text-align: center;
  font-size: var(--text-body-sm);
  color: var(--bk-dim);
}

.book-v2 .days {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 2px;
  /* the group boundary out of the meta block and into the calendar */
  padding: var(--space-sm) var(--space-md) 0;
}

.book-v2 .day {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 56px;
  padding: 6px 0;
  border: none;
  border-bottom: 2px solid transparent;
  background: transparent;
  font-family: inherit;
  color: var(--bk-dim);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    color var(--transition),
    border-color var(--transition);
}

.book-v2 .day-name {
  font-size: var(--text-micro);
  letter-spacing: 0.06em;
}

.book-v2 .day-num {
  font-size: var(--text-body-lg);
  font-weight: var(--weight-semi);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--bk-fg);
}

.book-v2 .day.is-empty {
  cursor: default;
}

.book-v2 .day.is-empty .day-num,
.book-v2 .day.is-empty .day-name {
  color: var(--bk-dim);
  opacity: 0.4;
}

.book-v2 .day.is-selected {
  border-bottom-color: var(--bk-fg);
  color: var(--bk-fg);
}

.book-v2 .times {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  padding: var(--space-sm) var(--space-md) 0;
}

.book-v2 .slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  min-height: 56px;
  padding: 8px 4px;
  border: 1px solid var(--bk-line);
  border-radius: 0;
  background: transparent;
  font-family: inherit;
  color: var(--bk-fg);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--transition),
    border-color var(--transition),
    color var(--transition);
}

.book-v2 .slot .time {
  font-size: var(--text-body);
  font-weight: var(--weight-semi);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.book-v2 .slot .price {
  font-size: var(--text-micro);
  color: var(--bk-dim);
}

.book-v2 .slot.selected {
  background: var(--bk-fg);
  border-color: var(--bk-fg);
  color: var(--bk-bg);
}

.book-v2 .slot.selected .price {
  color: var(--bk-bg);
  opacity: 0.72;
}

.book-v2 .discount-strike {
  text-decoration: line-through;
  opacity: 0.5;
}

.book-v2 .times-empty {
  grid-column: 1 / -1;
  padding: var(--space-md) 0;
  text-align: center;
  font-size: var(--text-body-sm);
  color: var(--bk-dim);
}

/* ── the jump shortcut ───────────────────────────────────────────────────────
   A quiet underlined line, not an outlined pill. It is a shortcut past the
   calendar, not a second primary action competing with continue. */

.book-v2 .bk-jump {
  display: flex;
  align-items: center;
  min-height: var(--touch-min);
  /* facts and this jump are one meta block — the 44px touch box's centered
     text already gives ~10px optical air, so added margin inverted the
     grouping (this gap read larger than the one into the calendar) */
  margin-top: 0;
  padding: 0;
  border: none;
  background: transparent;
  font-family: inherit;
  font-size: var(--text-body-sm);
  color: var(--bk-fg);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* `hidden` is only a user-agent rule, and the display above beats it at equal
   specificity — without this companion the control renders as an empty line
   whenever there is no slot to jump to. */
.book-v2 .bk-jump[hidden] {
  display: none;
}

/* ── the commit bar ──────────────────────────────────────────────────────── */

.book-v2 .bk-commit {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-xs);
  margin: var(--space-md) var(--space-md) 0;
  padding: var(--space-sm) 0 0;
  border-top: 1px solid var(--bk-line);
}

.book-v2 .bk-commit[hidden] {
  display: none;
}

.book-v2 .bk-commit-lines {
  display: block;
  min-width: 0;
}

.book-v2 .bk-commit-what,
.book-v2 .bk-commit-when {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.book-v2 .bk-commit-what {
  font-size: var(--text-body-sm);
  font-weight: var(--weight-semi);
  letter-spacing: -0.01em;
  color: var(--bk-fg);
}

.book-v2 .bk-commit-when {
  font-size: var(--text-body-sm);
  color: var(--bk-dim);
}

.book-v2 .bk-commit-price {
  font-size: var(--text-body);
  font-weight: var(--weight-semi);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--bk-fg);
}

.book-v2 .bk-commit-btn {
  grid-column: 1 / -1;
  min-height: var(--touch-min);
  margin-top: var(--space-sm);
  padding: 0 var(--space-md);
  border: 1px solid var(--bk-fg);
  border-radius: var(--radius-pill);
  background: var(--bk-fg);
  font-family: inherit;
  font-size: var(--text-body);
  font-weight: var(--weight-semi);
  letter-spacing: -0.01em;
  color: var(--bk-bg);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color var(--transition),
    color var(--transition),
    border-color var(--transition);
}

/* ── the details step's change controls ──────────────────────────────────────
   Two outlined pills here read as a decision to make, sitting directly under the
   booking the customer just confirmed — they invite a second guess rather than
   offering an escape hatch. Quiet underlined links instead: findable when wanted,
   silent when not. Team feedback 2026-08-23.

   Still real buttons at the full touch size — quieter, not smaller. */
.book-v2 .selected-slot-actions {
  display: flex;
  gap: var(--space-sm);
  /* no margin of its own: the links live in 44px touch boxes whose dead zone
     already reads as ~12px of air, and .selected-slot-main adds its 14px gap —
     a margin on top of both is what the owner flagged as excessive (2026-08-24) */
  margin-top: 0;
}

.book-v2 .selected-slot-actions .btn-pill {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  padding: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  font-size: var(--text-body-sm);
  font-weight: var(--weight-regular);
  letter-spacing: normal;
  text-transform: none;
  color: var(--bk-dim);
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (hover: hover) {
  .book-v2 .selected-slot-actions .btn-pill:hover {
    color: var(--bk-fg);
    background: transparent;
  }
}

/* ── lowercase, including the labels ─────────────────────────────────────────
   `.input-label` (brand.css) and `.guests-label` (book.css) render NAME, EMAIL,
   PHONE NUMBER and HOW MANY OF YOU in caps. The words in the markup are already
   lowercase; the caps are a CSS treatment, and monomo copy is lowercase.

   The letter-spacing goes with it. --tracking-ui is 0.08em, which is there to
   keep uppercase legible; on lowercase it just looks loose.

   Scoped to this surface on purpose. Both rules are shared with /gift, /redeem,
   /manage, /visits and live /book, and changing them site-wide is a brand call
   rather than a side effect of shipping a booking preview. */
.book-v2 .input-label,
.book-v2 .guests-label {
  text-transform: none;
  letter-spacing: normal;
  font-size: var(--text-body-sm);
}

/* ── focus ───────────────────────────────────────────────────────────────────
   One rule for every control this file introduces. :focus-visible only, so a
   pointer tap never paints a ring the customer did not ask for. */

.book-v2 .look-chip:focus-visible,
.book-v2 .room-card:focus-visible,
.book-v2 .day:focus-visible,
.book-v2 .slot:focus-visible,
.book-v2 .bk-jump:focus-visible,
.book-v2 .bk-commit-btn:focus-visible,
.book-v2 .calendar-nav .nav-btn:focus-visible {
  outline: 2px solid var(--bk-fg);
  outline-offset: 2px;
}

.book-v2 .room-card:focus-visible {
  outline-offset: -3px;
}

/* ── hover ───────────────────────────────────────────────────────────────────
   Guarded, because on a touch device a hover state sticks after the tap and
   leaves a control looking pressed that is not. Every rule below stays inside
   the media query — test/customer-css-hover-guard.test.js fails the suite
   otherwise, having caught nine drifted rules on 2026-08-22. */

@media (hover: hover) {
  .book-v2 .slot:hover:not(.selected) {
    border-color: var(--bk-fg);
  }

  .book-v2 .look-chip:hover:not(.is-selected) {
    background: var(--bk-block);
  }

  .book-v2 .day:hover:not(.is-empty):not(.is-selected) {
    color: var(--bk-fg);
  }

  .book-v2 .room-options.is-chosen .room-card:not(.is-selected):hover .room-shot {
    filter: brightness(0.8);
  }

  .book-v2 .bk-commit-btn:hover {
    opacity: 0.85;
  }

  /* brand.css inverts outline pills to ink-on-white on hover — themed here so
     the inversion survives the black room */
  .book-v2 .btn-pill-outline:hover {
    background: var(--bk-fg);
    color: var(--bk-bg);
    border-color: var(--bk-fg);
  }
}

/* ── the rest of the flow ────────────────────────────────────────────────────
   The details, success and error steps are shared with every other booking
   surface and keep book.css's structure. Two things they do need from here.

   First, their gutter back. The first screen gives each stage its own horizontal
   padding so the day strip and the room cards can run full-bleed, which meant
   taking it off .booking-content — and these steps were relying on it. Without
   this they sit flush against the left edge of the phone.

   Second, the theme. book.css was written for a page that is always white, so a
   set of controls hardcode ink and vanish on the black room. These are not
   guessed: they are what a sweep of the rendered details step reported painting
   near-black on a near-black page. */

.book-v2 #step-details,
.book-v2 #step-success,
.book-v2 #step-error {
  padding-inline: var(--space-md);
  background: transparent;
  color: var(--bk-fg);
}

.book-v2 #step-details h2,
.book-v2 #step-success h2,
.book-v2 #step-error h2 {
  color: var(--bk-fg);
}

/* ── details-step rhythm ─────────────────────────────────────────────────────
   Owner, on the phone, 2026-08-24: the recap, its change links, and the form
   sat too far apart. Most of the perceived air is not margin at all — the back
   link and the change links are 44px touch boxes with centered text, so every
   real margin lands on top of ~12px of built-in dead zone. These rules take
   the margins down to where box + margin reads like the 16/24 the rest of the
   page keeps. Touch sizes untouched. */

.book-v2 #step-details h2 {
  margin-bottom: var(--space-xs); /* + the back link's dead zone ≈ 20 optical */
}

.book-v2 #step-details .back-link {
  margin-bottom: 0; /* book.css adds 12 under a box that already carries 12 */
}

.book-v2 .selected-slot {
  /* top: 4 + the back link's dead zone ≈ 16 down to "white room";
     bottom: 4 + the links' dead zone ≈ 16 to the rule (owner round two,
     2026-08-24: the recap itself still read loose) */
  padding: 4px 0;
  border-bottom-color: var(--bk-line);
}

/* main's two children are the room/date/price block and the change links —
   book.css opens 14px between them, on top of the links' ~12px dead zone */
.book-v2 .selected-slot-main {
  gap: 4px;
}

/* the chosen slot's date line — explicitly ink in book.css, so black on black */
.book-v2 .selected-slot .datetime {
  color: var(--bk-fg);
}

.book-v2 .selected-slot .room,
.book-v2 .selected-slot .price,
.book-v2 .selected-slot .guests-included {
  color: var(--bk-fg);
}

/* group-size chips: an ink border and an ink fill, both invisible on black */
.book-v2 .guest-chip {
  border-color: var(--bk-line);
  color: var(--bk-fg);
  background: transparent;
}

.book-v2 .guest-chip.selected {
  border-color: var(--bk-fg);
  background: var(--bk-fg);
  color: var(--bk-bg);
}

/* the form: labels, help text, dividers and inline links */
.book-v2 .input-label,
.book-v2 .field-note,
.book-v2 .guests-label,
.book-v2 .guests-help,
.book-v2 .guests-more-note,
.book-v2 .transparency,
.book-v2 .transparency p,
.book-v2 .code-toggle,
.book-v2 .back-link a {
  color: var(--bk-dim);
}

.book-v2 .transparency a,
.book-v2 .source-chip span {
  color: var(--bk-fg);
}

/* reassurance copy files at the help tier — unsized it rendered at the UA's
   16px, louder than the labels of the form it sits in, and glued 18px above
   the phone field as if the privacy text belonged to it */
.book-v2 .transparency,
.book-v2 .transparency p {
  font-size: var(--text-body-sm);
}

.book-v2 .form-group.transparency {
  margin: var(--space-sm) 0; /* the form's own 16 — 24 read as excessive on the phone */
}

.book-v2 .source-chip span {
  border-color: var(--bk-line);
}

/* Inputs keep a light field on purpose — a black field on a black page loses its
   edge entirely, and a customer typing needs to see where the box is. Only the
   border has to stop being ink so the field reads as a field rather than a
   floating white slab. */
.book-v2 .input-brand {
  border-color: var(--bk-line);
}

/* the "have a code?" box hardcodes a translucent white fill — on the black room
   that painted a grey slab with grey text in it (owner, on the phone,
   2026-08-24). On white, transparent-with-a-line is what it already looked
   like; on black it finally reads. The id is load-bearing: book.css styles this
   box as `#booking-form > .form-group.code-section` (1,2,0), which outranks any
   class-only override this file could write. */
.book-v2 #booking-form > .form-group.code-section {
  background: transparent;
  border-color: var(--bk-line);
}

/* outline pills (code apply, the 8+ contact links) hardcode ink on ink */
.book-v2 .btn-pill-outline {
  color: var(--bk-fg);
  border-color: var(--bk-fg);
}

/* validation + code status lines hardcode ink/selenium */
.book-v2 .field-error,
.book-v2 .code-valid {
  color: var(--bk-fg);
}

.book-v2 .code-invalid {
  color: var(--bk-dim);
}

.book-v2 .voucher-badge,
.book-v2 .discount-badge {
  color: var(--bk-dim);
  border-bottom-color: var(--bk-line);
}

/* the pay button inverts with the page: ink-on-white becomes white-on-ink */
.book-v2 .submit-btn {
  border-color: var(--bk-fg);
  background: var(--bk-fg);
  color: var(--bk-bg);
}

/* book.css fades the page out behind the sticky pay button with a hardcoded
   white gradient — correct on a page that is always white, a glowing square
   around the button on the black room (owner, on the phone, 2026-08-24). Same
   fade, in the page's own color; --bk-bg is a registered @property, so it
   rides the 900ms room fade like every other surface. The 6px margin on top
   of the 16px fade zone goes with it. */
.book-v2 .submit-sticky {
  margin-top: 0;
  background: linear-gradient(180deg, transparent 0%, var(--bk-bg) 65%);
}

/* ── desktop ─────────────────────────────────────────────────────────────────
   Mobile-first: everything above is the 375px layout. From 600px the page gets a
   measure so the day strip does not stretch a seven-column grid across a
   desktop window. */

@media (min-width: 600px) {
  .book-v2 .booking-content,
  .book-v2 .page-header {
    /* body.booking-page is a column flexbox, and auto inline margins on a flex
       item beat align-stretch — without an explicit width the header shrinks to
       its own h1 (measured 285px inside an 880 cap) and the mark drifts inland */
    width: 100%;
    max-width: 560px;
    margin-inline: auto;
  }

  .book-v2 .bk-commit {
    grid-template-columns: 1fr auto auto;
  }

  .book-v2 .bk-commit-btn {
    grid-column: auto;
    margin-top: 0;
    margin-left: var(--space-sm);
  }
}

@media (min-width: 960px) {
  /* the page was a 560px mobile column floating on the desktop canvas, with
     the photographs — the product — rendered small. The column widens for the
     stages so the cards get real size; reading surfaces keep their measure. */
  .book-v2 .page-header,
  .book-v2 .booking-content {
    max-width: 880px;
  }

  .book-v2 .look-options {
    max-width: 460px;
  }

  .book-v2 .bk-sheet {
    max-width: 640px;
    margin-inline: auto;
  }

  .book-v2 #step-details,
  .book-v2 #step-success,
  .book-v2 #step-error {
    max-width: 560px;
    margin-inline: auto;
  }

}
