/* Booking page — Swiss-minimal, mobile-first. Scoped under .bk so the
   admin and manage pages keep using style.css untouched. */

/* Aliases onto the shared palette in theme.css — values live there, not here,
   so the customer pages and the admin cannot drift apart. */
.bk {
  --bk-ink: var(--u-ink);
  --bk-ink-2: var(--u-ink-2);
  --bk-muted: var(--u-muted);
  --bk-line: var(--u-line);
  --bk-line-2: var(--u-line-2);
  --bk-surface: var(--u-surface);
  --bk-page: var(--u-page);
  --bk-accent: var(--u-accent);
  --bk-accent-ink: var(--u-accent-ink);
  --bk-accent-tint: var(--u-accent-tint);
  --bk-ok: var(--u-ok);
  --bk-ok-tint: var(--u-ok-tint);
  --bk-danger: var(--u-danger);
  --bk-danger-tint: var(--u-danger-tint);

  --bk-r-sm: var(--u-r-sm);
  --bk-r: var(--u-r);
  --bk-r-lg: var(--u-r-lg);

  --bk-ease: var(--u-ease);
  --bk-shadow: var(--u-shadow);
}

/* The `hidden` attribute is the page's on/off switch — the JS toggles it on the
   verify row, the verified line and every field error. The browser implements
   it as `[hidden] { display: none }`, which any of our own class rules with a
   `display` silently outranks; that is how "Email verified" came to show on a
   page where nothing had been verified. Stated once here so no future rule can
   do it again. */
[hidden] { display: none !important; }

/* Reset what style.css does to the page shell. book.css is only linked from the
   booking page, so this needs no :has() guard — and works in every browser. */
body {
  max-width: none;
  padding: 0;
  /* Not var(--bk-page): those aliases are scoped to .bk, and this is <body>. */
  background: var(--u-page);
}

.bk {
  font-family: var(--u-font);
  color: var(--bk-ink);
  -webkit-font-smoothing: antialiased;
  padding: 0 0 7rem;
  min-height: 100dvh;
}

.bk * { box-sizing: border-box; }

.bk-shell {
  max-width: 1060px;
  margin-inline: auto;
}

/* The booking page is one column at every width — the calendar and the times
   sit side by side inside it, but nothing sits beside the card. Wider than this
   and the form fields stretch past a comfortable line length. */
.bk-shell-single { max-width: 40rem; }

/* ---------- Page header (booking page) ----------
   Was an aside inside the card, which on a phone pushed the calendar below the
   fold. Out here it is three lines of context the customer reads once, and the
   card underneath opens straight onto the choice they came to make. */

.bk-head { padding: 1.5rem 1.25rem .875rem; }

.bk-chips {
  list-style: none;
  margin: .875rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .375rem .5rem;
}

.bk-chip {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  padding: .3125rem .625rem;
  border: 1px solid var(--bk-line);
  border-radius: 999px;
  background: var(--bk-surface);
  font-size: .8125rem;
  font-weight: 500;
  color: var(--bk-ink-2);
  line-height: 1.3;
}

.bk-chip svg { width: 15px; height: 15px; flex: 0 0 auto; color: var(--bk-muted); }

.bk-card {
  background: var(--bk-surface);
  border: 1px solid var(--bk-line);
  border-radius: var(--bk-r-lg);
  box-shadow: var(--bk-shadow);
  overflow: hidden;
}

/* ---------- Brand / summary panel ---------- */

.bk-side {
  padding: 1.5rem 1.25rem;
  border-bottom: 1px solid var(--bk-line);
}

.bk-brand {
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bk-muted);
  margin: 0 0 .875rem;
}

.bk-title {
  font-size: 1.5rem;
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -.02em;
  margin: 0 0 1rem;
}

.bk-meta { list-style: none; margin: 0; padding: 0; display: grid; gap: .625rem; }

.bk-meta li {
  display: flex;
  gap: .625rem;
  align-items: flex-start;
  font-size: .9375rem;
  color: var(--bk-ink-2);
  line-height: 1.45;
}

.bk-meta svg {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--bk-muted);
}

.bk-order {
  margin: 1rem 0 0;
  padding: .625rem .75rem;
  background: var(--bk-accent-tint);
  border-radius: var(--bk-r-sm);
  font-size: .875rem;
  color: var(--bk-accent-ink);
  font-weight: 500;
}

/* ---------- Sections ---------- */

.bk-main { padding: 0; }

.bk-section { padding: 1.5rem 1.25rem; border-bottom: 1px solid var(--bk-line); }
.bk-section:last-child { border-bottom: 0; }

.bk-step {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--bk-muted);
  margin: 0 0 .25rem;
}

.bk-h2 {
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -.01em;
  margin: 0 0 1rem;
}

.bk-hint { font-size: .875rem; color: var(--bk-muted); margin: .75rem 0 0; }

/* ---------- Appointment type ----------
   Segmented control rather than a stack of full-width radio cards: the choice
   is between two short labels, so it fits on one row and stops reading like a
   question that has to be worked through before the calendar. Each half still
   clears the 44px touch minimum. */

.bk-seg {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 4px;
  padding: 4px;
  background: var(--bk-page);
  border: 1px solid var(--bk-line);
  border-radius: var(--bk-r);
}

.bk-seg-item { display: block; min-width: 0; }

.bk-seg input { position: absolute; opacity: 0; pointer-events: none; }

.bk-seg label {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .0625rem;
  min-height: 46px;
  padding: .4375rem .5rem;
  margin: 0;
  border-radius: calc(var(--bk-r) - 5px);
  background: transparent;
  cursor: pointer;
  text-align: center;
  transition: background-color 160ms var(--bk-ease), box-shadow 160ms var(--bk-ease),
              color 160ms var(--bk-ease);
}

.bk-seg-name {
  font-weight: 600;
  font-size: .9375rem;
  line-height: 1.2;
  /* Two long type names must not blow the row out sideways. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.bk-seg .bk-dur { font-weight: 500; font-size: .75rem; color: var(--bk-muted); }

.bk-seg input:checked + label {
  background: var(--bk-surface);
  box-shadow: 0 1px 2px rgba(16, 19, 24, .08);
  color: var(--bk-accent-ink);
}

.bk-seg input:checked + label .bk-dur { color: var(--bk-accent-ink); }
.bk-seg input:focus-visible + label { outline: 2px solid var(--bk-accent); outline-offset: 2px; }

/* Kept for the reschedule page, which still renders the stacked variant. */
.bk-types { display: grid; gap: .5rem; }

.bk-type input { position: absolute; opacity: 0; pointer-events: none; }

.bk-type label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  min-height: 52px;
  padding: .75rem .875rem;
  margin: 0;
  border: 1px solid var(--bk-line-2);
  border-radius: var(--bk-r);
  background: var(--bk-surface);
  font-weight: 600;
  font-size: .9375rem;
  cursor: pointer;
  transition: border-color 160ms var(--bk-ease), background-color 160ms var(--bk-ease),
              transform 160ms var(--bk-ease);
}

.bk-type label:active { transform: scale(.985); }

.bk-type .bk-dur { font-weight: 500; font-size: .8125rem; color: var(--bk-muted); }

.bk-type input:checked + label {
  border-color: var(--bk-accent);
  background: var(--bk-accent-tint);
  box-shadow: inset 0 0 0 1px var(--bk-accent);
}

.bk-type input:checked + label .bk-dur { color: var(--bk-accent-ink); }
.bk-type input:focus-visible + label { outline: 2px solid var(--bk-accent); outline-offset: 2px; }

/* ---------- Calendar ---------- */

.bk-cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: .75rem;
}

.bk-month { font-size: 1rem; font-weight: 700; letter-spacing: -.01em; }

.bk-nav { display: flex; gap: .25rem; }

.bk-nav button {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--bk-line-2);
  border-radius: 10px;
  background: var(--bk-surface);
  color: var(--bk-ink);
  cursor: pointer;
  transition: background-color 160ms var(--bk-ease), transform 160ms var(--bk-ease);
}

.bk-nav button:active:not(:disabled) { transform: scale(.94); }
.bk-nav button:disabled { color: #BFC5CE; cursor: not-allowed; }
.bk-nav svg { width: 18px; height: 18px; }

.bk-dow, .bk-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

.bk-dow span {
  text-align: center;
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--bk-muted);
  padding-bottom: .5rem;
}

.bk-day {
  position: relative;
  aspect-ratio: 1 / 1;
  min-height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font: inherit;
  font-size: .9375rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: #B4BAC3;
  cursor: default;
}

.bk-day.is-free {
  color: var(--bk-accent-ink);
  font-weight: 700;
  background: var(--bk-accent-tint);
  cursor: pointer;
  transition: background-color 160ms var(--bk-ease), color 160ms var(--bk-ease),
              transform 160ms var(--bk-ease);
}

.bk-day.is-free:active { transform: scale(.9); }

@media (hover: hover) and (pointer: fine) {
  .bk-day.is-free:hover { background: #D6EDFA; }
  .bk-nav button:hover:not(:disabled) { background: #F2F4F7; }
  .bk-type label:hover { border-color: var(--bk-line-2); background: #FAFBFC; }
}

/* Filled states use the darker accent so white text clears 4.5:1. */
.bk-day.is-selected,
.bk-day.is-selected:hover {
  background: var(--bk-accent-ink);
  color: #fff;
}

.bk-day:focus-visible { outline: 2px solid var(--bk-accent); outline-offset: 2px; }

.bk-day.is-today::after {
  content: '';
  position: absolute;
  bottom: 6px;
  width: 4px;
  height: 4px;
  border-radius: 999px;
  background: currentColor;
  opacity: .5;
}

.bk-tz {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin: 1rem 0 0;
  font-size: .8125rem;
  color: var(--bk-muted);
}

.bk-tz svg { width: 16px; height: 16px; }

/* ---------- Times ---------- */

.bk-times-wrap { margin-top: 1.5rem; }

.bk-times-head {
  font-size: .9375rem;
  font-weight: 700;
  margin: 0 0 .75rem;
}

.bk-times {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: .5rem;
}

.bk-slot input { position: absolute; opacity: 0; pointer-events: none; }

.bk-slot label {
  display: grid;
  place-items: center;
  min-height: 48px;
  margin: 0;
  padding: .5rem;
  border: 1px solid var(--bk-accent);
  border-radius: var(--bk-r);
  background: var(--bk-surface);
  color: var(--bk-accent-ink);
  font-weight: 600;
  font-size: .9375rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background-color 150ms var(--bk-ease), color 150ms var(--bk-ease),
              transform 150ms var(--bk-ease);
}

.bk-slot label:active { transform: scale(.97); }

.bk-slot input:checked + label {
  background: var(--bk-accent-ink);
  border-color: var(--bk-accent-ink);
  color: #fff;
}

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

/* Staggered entrance for a freshly opened day. */
.bk-times.is-entering .bk-slot {
  animation: bk-rise 260ms var(--bk-ease) both;
}

@keyframes bk-rise {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

.bk-empty {
  padding: 1.25rem;
  border: 1px dashed var(--bk-line-2);
  border-radius: var(--bk-r);
  text-align: center;
  color: var(--bk-muted);
  font-size: .9375rem;
}

.bk-empty a { color: var(--bk-accent-ink); font-weight: 600; }

/* ---------- Fields ---------- */

.bk-fields { display: grid; gap: 1rem; }

.bk-field label {
  display: block;
  margin: 0 0 .375rem;
  font-size: .8125rem;
  font-weight: 600;
  color: var(--bk-ink-2);
}

.bk-req { color: var(--bk-accent-ink); }

.bk-field input,
.bk-field textarea {
  width: 100%;
  min-height: 48px;
  padding: .75rem .875rem;
  border: 1px solid var(--bk-line-2);
  border-radius: var(--bk-r);
  background: var(--bk-surface);
  font: inherit;
  font-size: 1rem;
  color: var(--bk-ink);
  transition: border-color 150ms var(--bk-ease), box-shadow 150ms var(--bk-ease);
}

.bk-field textarea { resize: vertical; line-height: 1.5; }

.bk-field input:focus,
.bk-field textarea:focus {
  outline: none;
  border-color: var(--bk-accent);
  box-shadow: 0 0 0 3px rgba(2, 132, 199, .16);
}

.bk-field input::placeholder,
.bk-field textarea::placeholder { color: #A6ADB8; }

.bk-field-hint {
  margin: .375rem 0 0;
  font-size: .8125rem;
  color: var(--bk-muted);
}

/* ---------- Email verification ---------- */

/* Input and its button on one line. The button is sized to the input rather
   than the text so the two stay level as the field grows on a wide card. */
.bk-with-action { display: flex; gap: .5rem; align-items: stretch; }
.bk-with-action input { flex: 1 1 auto; min-width: 0; }

.bk-mini {
  flex: 0 0 auto;
  min-height: 48px;
  padding: 0 1rem;
  border: 1px solid var(--bk-line-2);
  border-radius: var(--bk-r);
  background: var(--bk-surface);
  font: inherit;
  font-size: .9375rem;
  font-weight: 600;
  color: var(--bk-ink-2);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 150ms var(--bk-ease), color 150ms var(--bk-ease),
              background 150ms var(--bk-ease);
}

.bk-mini:hover:not(:disabled) { border-color: var(--bk-accent); color: var(--bk-accent-ink); }

.bk-mini:disabled { opacity: .55; cursor: default; }

.bk-code { margin: .75rem 0 0; }

.bk-code label {
  display: block;
  margin: 0 0 .375rem;
  font-size: .8125rem;
  font-weight: 600;
  color: var(--bk-ink-2);
}

/* Wide-set digits, so a code read off a phone is retyped once. */
.bk-code input {
  max-width: 11rem;
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: .22em;
}

.bk-code-status {
  margin: .375rem 0 0;
  font-size: .8125rem;
  line-height: 1.5;
  color: var(--bk-muted);
}

.bk-code-status.is-bad { color: var(--bk-danger); font-weight: 500; }

.bk-verified {
  display: flex;
  gap: .375rem;
  align-items: center;
  margin: .5rem 0 0;
  font-size: .875rem;
  font-weight: 600;
  color: var(--bk-ok);
}

.bk-verified svg { width: 16px; height: 16px; flex: 0 0 auto; }

/* ---------- Errors ---------- */

.bk-error {
  display: flex;
  gap: .625rem;
  align-items: flex-start;
  margin: 0 1.25rem 1rem;
  padding: .75rem .875rem;
  border: 1px solid #F0C4BF;
  border-radius: var(--bk-r);
  background: var(--bk-danger-tint);
  color: var(--bk-danger);
  font-size: .9375rem;
  font-weight: 500;
}

.bk-error svg { flex: 0 0 auto; width: 18px; height: 18px; margin-top: 1px; }

.bk-inline-error {
  margin: .75rem 0 0;
  font-size: .875rem;
  font-weight: 600;
  color: var(--bk-danger);
}

.bk-field-error {
  margin: .375rem 0 0;
  font-size: .8125rem;
  font-weight: 500;
  color: var(--bk-danger);
}

.bk-field input[aria-invalid="true"],
.bk-field textarea[aria-invalid="true"] { border-color: var(--bk-danger); }

.bk-field input[aria-invalid="true"]:focus,
.bk-field textarea[aria-invalid="true"]:focus {
  border-color: var(--bk-danger);
  box-shadow: 0 0 0 3px var(--bk-danger-tint);
}

/* The Turnstile iframe is a fixed-height block; give it room without letting a
   slow load collapse the layout underneath it. */
.bk-turnstile { min-height: 65px; margin: 1.25rem 0 0; }

/* ---------- Sticky confirm bar ---------- */

.bk-bar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 40;
  background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--bk-line);
  padding: .75rem 1.25rem calc(.75rem + env(safe-area-inset-bottom));
}

.bk-bar-inner {
  max-width: 1060px;
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* The bar is fixed to the viewport but lives inside the form, so it can still
   be matched to whichever shell it belongs to. Without this the booking page's
   40rem card sits under a 1060px bar and the Confirm button drifts off to the
   right of everything it belongs to. */
.bk-shell-single .bk-bar-inner { max-width: 40rem; }

.bk-summary {
  flex: 1;
  min-width: 0;
  font-size: .8125rem;
  line-height: 1.35;
  color: var(--bk-muted);
}

.bk-summary strong {
  display: block;
  font-size: .9375rem;
  color: var(--bk-ink);
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.bk-submit {
  flex: 0 0 auto;
  min-height: 52px;
  padding: 0 1.5rem;
  border: 0;
  border-radius: var(--bk-r);
  background: var(--bk-ink);
  color: #fff;
  font: inherit;
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  transition: transform 160ms var(--bk-ease), background-color 160ms var(--bk-ease);
}

.bk-submit:active { transform: scale(.97); }
.bk-submit:focus-visible { outline: 2px solid var(--bk-accent); outline-offset: 2px; }
.bk-submit[aria-disabled="true"] { background: #C2C7CF; cursor: not-allowed; }
.bk-submit[aria-disabled="true"]:active { transform: none; }

.bk-submit.is-busy { background: #2A3038; cursor: progress; }

/* Small phones: stack the bar so neither half gets squeezed, and give the page
   back the extra height that stacking costs so the bar never covers content. */
@media (max-width: 359px) {
  .bk { padding-bottom: 9.5rem; }
  .bk-bar-inner { flex-direction: column; align-items: stretch; gap: .5rem; }
  .bk-submit { width: 100%; }
  .bk-section, .bk-side, .bk-head,
  .bk-done, .bk-actions { padding-left: 1rem; padding-right: 1rem; }
  .bk-error { margin-inline: 1rem; }
  .bk-day { min-height: 38px; }   /* keeps the day circle round at 320px */
}

/* ---------- No-JS fallback ---------- */

.bk-daylist-head {
  margin: 1.25rem 0 .5rem;
  font-size: .9375rem;
  font-weight: 700;
}

/* ---------- Tablet / desktop ---------- */

@media (min-width: 700px) {
  .bk { padding: 2.5rem 1.5rem 7rem; }
  .bk-side, .bk-section { padding: 1.75rem; }
  .bk-head { padding: 0 .25rem 1.25rem; }
  .bk-error { margin: 0 1.75rem 1rem; }
  .bk-times { grid-template-columns: repeat(3, 1fr); }
  .bk-fields { grid-template-columns: 1fr 1fr; }
  .bk-field.is-wide { grid-column: 1 / -1; }
}

@media (min-width: 960px) {
  /* Opt-in, via .bk-split — see the note in manage.html. The booking page has
     no .bk-side any more, so assuming the split here would leave it with a
     320px empty column. */
  .bk-card.bk-split { display: grid; grid-template-columns: 320px 1fr; align-items: start; }
  /* That two-pane split is for the booking and reschedule cards, which have a
     .bk-side. The single-column pages (confirmation, cancelled, message) sit in
     a 34rem shell, so splitting them 320px + 1fr leaves ~220px for the actions
     column and wraps the WhatsApp button onto four lines. */
  .bk-plain .bk-card { display: block; }
  .bk-side {
    border-bottom: 0;
    border-right: 1px solid var(--bk-line);
    height: 100%;
    position: sticky;
    top: 0;
  }
  .bk-title { font-size: 1.625rem; }
  .bk-cal-times { display: grid; grid-template-columns: 1fr 200px; gap: 1.75rem; align-items: start; }
  .bk-times-wrap { margin-top: 0; }
  .bk-times { grid-template-columns: 1fr; max-height: 340px; overflow-y: auto; padding-right: 4px; }
}

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

@media (prefers-reduced-motion: reduce) {
  .bk *, .bk *::before, .bk *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    transition-duration: 1ms !important;
  }
}

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

.bk-shell-narrow { max-width: 34rem; }

.bk-done {
  padding: 2rem 1.25rem 1.5rem;
  border-bottom: 1px solid var(--bk-line);
}

.bk-tick {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: 1.25rem;
  border-radius: 999px;
  background: var(--bk-ok-tint);
  color: var(--bk-ok);
  animation: bk-tick-in 420ms var(--bk-ease) both;
}

.bk-tick svg { width: 22px; height: 22px; }

@keyframes bk-tick-in {
  from { transform: scale(.7); opacity: 0; }
  to   { transform: scale(1);  opacity: 1; }
}

.bk-done .bk-title { margin-bottom: 1.5rem; }

/* Label above value: the values here (a full date, a street address) are long
   enough that a two-column term/description list wraps badly at 320px. */
.bk-recap { margin: 0; display: grid; gap: .875rem; }

.bk-recap dt {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--bk-muted);
  margin-bottom: .125rem;
}

.bk-recap dd {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--bk-ink);
}

.bk-actions { padding: 1.5rem 1.25rem; }

.bk-wa {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .625rem;
  width: 100%;
  min-height: 54px;
  padding: .75rem 1.25rem;
  border-radius: var(--bk-r);
  background: var(--u-wa);
  color: #fff;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  transition: transform 160ms var(--bk-ease), background-color 160ms var(--bk-ease);
}

.bk-wa svg { flex: 0 0 auto; width: 22px; height: 22px; }
.bk-wa:hover { background: var(--u-wa-hover); }
.bk-wa:active { transform: scale(.97); }
.bk-wa:focus-visible { outline: 2px solid var(--bk-ink); outline-offset: 2px; }

.bk-wa-hint {
  margin: .75rem 0 0;
  font-size: .875rem;
  line-height: 1.5;
  color: var(--bk-muted);
  text-align: center;
}

.bk-after {
  margin: 1.5rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--bk-line);
  font-size: .9375rem;
  line-height: 1.55;
  color: var(--bk-ink-2);
}

.bk-after a { color: var(--bk-accent-ink); font-weight: 600; }

@media (min-width: 700px) {
  .bk-done { padding: 2.25rem 1.75rem 1.75rem; }
  .bk-actions { padding: 1.75rem; }
}

/* ---------- Manage / message pages ---------- */

.bk-lead {
  margin: 0;
  font-size: 1rem;
  line-height: 1.55;
  color: var(--bk-ink-2);
}

/* Secondary full-width action: same footprint as .bk-wa, quieter colours. */
.bk-alt {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  width: 100%;
  min-height: 52px;
  padding: .75rem 1.25rem;
  border: 1px solid var(--bk-line-2);
  border-radius: var(--bk-r);
  background: var(--bk-surface);
  color: var(--bk-ink);
  font: inherit;
  font-size: 1rem;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 160ms var(--bk-ease), border-color 160ms var(--bk-ease),
              transform 160ms var(--bk-ease);
}

.bk-alt:active { transform: scale(.97); }
.bk-alt:focus-visible { outline: 2px solid var(--bk-accent); outline-offset: 2px; }

.bk-alt-danger { color: var(--bk-danger); border-color: #F0C4BF; }

@media (hover: hover) and (pointer: fine) {
  .bk-alt:hover { background: #FAFBFC; }
  .bk-alt-danger:hover { background: var(--bk-danger-tint); border-color: var(--bk-danger); }
}

.bk-side-note {
  margin: 1.25rem 0 0;
  font-size: .875rem;
  line-height: 1.5;
  color: var(--bk-muted);
}

.bk-cancel-row { display: grid; gap: .75rem; }

.bk-cancel-lead {
  margin: 0;
  font-size: .9375rem;
  font-weight: 600;
  color: var(--bk-ink-2);
}

/* The .bk-error default gutters assume a full-bleed section; inside a padded
   block it needs none. */
.bk-error-flush { margin: 0 0 1rem; }

.bk-actions .bk-after a { text-decoration: none; }

/* The booking page reserves 7rem at the foot for its sticky submit bar. The
   confirmation page has no such bar, so it reclaims that space. Declared last
   so it also beats the small-phone override above. */
.bk-plain { padding: 1.25rem 1rem 3rem; }

@media (min-width: 700px) {
  .bk-plain { padding: 2.5rem 1.5rem 4rem; }
}

/* ==========================================================================
   Premium layer
   --------------------------------------------------------------------------
   Appended last so it overrides the base rules above at equal specificity
   without editing them, which keeps the diff readable and makes the whole
   treatment revertible by deleting one block.

   Scoped to .bk throughout: theme.css is shared with the admin, so the palette
   is re-pointed here rather than at :root. The admin keeps its own look.

   Two deliberate departures from the base:

   1. Selected states are ink, not blue. A saturated blue fill on every chosen
      day and time is the default SaaS signature; near-black reads as considered
      and lets the one accent do a single job. Blue is now only links, focus
      rings and the required-field marker.
   2. The ground is warm (#F6F5F3), not cool grey. Against a warm ground white
      cards actually read as white and lift off the page, which cool grey
      flattens.
   ========================================================================== */

.bk {
  --bk-ink: #0A0C0F;
  --bk-ink-2: #3D4450;
  --bk-muted: #6E7581;
  --bk-line: #EAE8E4;
  --bk-line-2: #D9D6D1;
  --bk-page: #F6F5F3;

  /* Selected / filled states. Named separately from the accent so the two
     cannot drift back into each other. */
  --bk-sel: #12151A;
  --bk-sel-hover: #23282F;

  --bk-r-sm: 10px;
  --bk-r: 14px;
  --bk-r-lg: 20px;

  /* Three layers rather than two: a hairline to seat the edge, a close shadow
     for the lift, and a wide soft one for the ambient. */
  --bk-shadow:
    0 1px 1px rgba(10, 12, 15, .04),
    0 4px 12px rgba(10, 12, 15, .05),
    0 16px 40px -12px rgba(10, 12, 15, .10);

  font-feature-settings: 'ss01' 1, 'cv01' 1;
  letter-spacing: -.005em;
}

body { background: #F6F5F3; }

/* ---------- Type ---------- */

.bk-brand {
  font-size: .6875rem;
  letter-spacing: .18em;
  color: var(--bk-muted);
  margin-bottom: .625rem;
}

.bk-title {
  font-size: 1.75rem;
  line-height: 1.12;
  letter-spacing: -.035em;
}

.bk-h2 {
  font-size: 1.0625rem;
  letter-spacing: -.02em;
  margin-bottom: 1.125rem;
}

.bk-month { letter-spacing: -.02em; }

/* ---------- Surfaces ---------- */

.bk-card { border-color: var(--bk-line); }

.bk-chip {
  background: rgba(255, 255, 255, .7);
  border-color: var(--bk-line);
  backdrop-filter: blur(6px);
}

/* ---------- Segmented control ---------- */

.bk-seg { background: #EEECE8; border-color: transparent; }

.bk-seg input:checked + label {
  background: var(--bk-surface);
  color: var(--bk-ink);
  box-shadow: 0 1px 1px rgba(10, 12, 15, .05), 0 2px 6px rgba(10, 12, 15, .07);
}

.bk-seg input:checked + label .bk-dur { color: var(--bk-muted); }

/* ---------- Calendar ---------- */

/* Available days: a warm neutral cushion with ink numerals. The blue tint made
   the grid read as fourteen competing buttons; this lets the selected day be
   the only thing with weight. */
.bk-day.is-free {
  background: #EDEAE5;
  color: var(--bk-ink);
  font-weight: 600;
}

.bk-day.is-selected,
.bk-day.is-selected:hover {
  background: var(--bk-sel);
  color: #fff;
  font-weight: 600;
}

.bk-nav button { border-color: var(--bk-line); border-radius: 12px; }

@media (hover: hover) and (pointer: fine) {
  .bk-day.is-free:hover { background: #E2DED7; }
  .bk-nav button:hover:not(:disabled) { background: #F2F0EC; }
}

/* ---------- Times ---------- */

.bk-slot label {
  border-color: var(--bk-line-2);
  color: var(--bk-ink);
  letter-spacing: -.01em;
}

.bk-slot input:checked + label {
  background: var(--bk-sel);
  border-color: var(--bk-sel);
  color: #fff;
}

@media (hover: hover) and (pointer: fine) {
  .bk-slot label:hover { border-color: var(--bk-ink-2); }
  .bk-slot input:checked + label:hover { background: var(--bk-sel-hover); }
}

/* ---------- Fields ---------- */

.bk-field input,
.bk-field textarea {
  border-radius: var(--bk-r-sm);
  border-color: var(--bk-line-2);
  background: var(--bk-surface);
  transition: border-color 160ms var(--bk-ease), box-shadow 160ms var(--bk-ease);
}

.bk-field input:focus,
.bk-field textarea:focus {
  border-color: var(--bk-ink);
  box-shadow: 0 0 0 3px rgba(10, 12, 15, .07);
  outline: none;
}

/* ---------- Sticky bar ---------- */

.bk-bar {
  background: rgba(246, 245, 243, .82);
  backdrop-filter: blur(16px) saturate(1.4);
  border-top-color: var(--bk-line);
}

.bk-submit {
  background: var(--bk-sel);
  border-radius: 999px;
  letter-spacing: -.01em;
  box-shadow: 0 1px 2px rgba(10, 12, 15, .12), 0 6px 16px -4px rgba(10, 12, 15, .25);
  transition: background-color 180ms var(--bk-ease), transform 180ms var(--bk-ease),
              box-shadow 180ms var(--bk-ease);
}

.bk-submit:active { transform: translateY(1px); }

@media (hover: hover) and (pointer: fine) {
  .bk-submit:hover { background: var(--bk-sel-hover); }
}

/* The bar is the one surface that sits over content, so it earns a real edge
   rather than a hairline. */
.bk-bar-inner { align-items: center; }

/* ---------- Confirmation / message pages ---------- */

.bk-tick { background: var(--bk-sel); color: #fff; }
.bk-wa { border-radius: 999px; }

/* ==========================================================================
   App-card layer
   --------------------------------------------------------------------------
   The soft, rounded, app-like treatment: a tinted ground, white cards with
   generous radii, a horizontal day rail, tinted time pills and one dark
   full-width action. Appended after the premium layer, so it wins where the
   two disagree and the whole treatment is still one deletable block.

   Colours stay on the warm neutral palette of the layer above — this layer
   changes shape, not hue. An earlier revision made them sage; owner's call on
   2026-08-28 was to keep the warm neutrals, so the two layers now agree and
   the values are simply restated here rather than overridden.
   ========================================================================== */

.bk {
  --bk-page: #F6F5F3;
  --bk-line: #EAE8E4;
  --bk-line-2: #D9D6D1;

  /* Availability tint. Reserved for "you can have this", so a tinted pill
     always means bookable and never decoration. */
  --bk-tint: #EDEAE5;
  --bk-tint-hi: #E2DED7;

  --bk-r-sm: 12px;
  --bk-r: 16px;
  --bk-r-lg: 26px;

  --bk-shadow:
    0 1px 2px rgba(10, 12, 15, .04),
    0 6px 16px -4px rgba(10, 12, 15, .06),
    0 24px 48px -20px rgba(10, 12, 15, .14);
}

body { background: #F6F5F3; }

/* Cards float on the ground rather than sitting in a bordered box. */
.bk-card {
  border: 0;
  border-radius: var(--bk-r-lg);
  overflow: visible;
}

.bk-section { border-bottom-color: #EEF2F0; }

.bk-chip {
  background: rgba(255, 255, 255, .75);
  border-color: transparent;
  box-shadow: 0 1px 2px rgba(10, 12, 15, .05);
}

/* ---------- Day rail ----------
   Replaces the month grid. Horizontal, snapping, and only ever showing days
   that have times. */

.bk-dow { display: none; }

.bk-grid {
  display: flex;
  gap: .5rem;
  grid-template-columns: none;      /* undo the 7-column grid above */
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding: .125rem .125rem .5rem;
  margin-inline: -.125rem;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.bk-grid::-webkit-scrollbar { display: none; }

.bk-day {
  flex: 0 0 auto;
  aspect-ratio: auto;
  scroll-snap-align: center;
  width: 58px;
  min-height: 68px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .1875rem;
  border-radius: var(--bk-r);
  background: var(--bk-surface);
  color: var(--bk-ink);
  box-shadow: 0 1px 2px rgba(10, 12, 15, .05);
}

.bk-day-dow {
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--bk-muted);
  transition: color 160ms var(--bk-ease);
}

.bk-day-num {
  font-size: 1.0625rem;
  font-weight: 700;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

.bk-day.is-free { background: var(--bk-surface); font-weight: 600; }

.bk-day.is-selected,
.bk-day.is-selected:hover {
  background: var(--bk-sel);
  color: #fff;
  box-shadow: 0 2px 6px rgba(10, 12, 15, .16), 0 10px 22px -8px rgba(10, 12, 15, .34);
}

.bk-day.is-selected .bk-day-dow { color: rgba(255, 255, 255, .72); }

/* The today dot sat at the bottom of a square cell; centre it under the number
   now that the cell is a tall pill. */
.bk-day.is-today::after { bottom: 8px; }

@media (hover: hover) and (pointer: fine) {
  .bk-day.is-free:hover { background: var(--bk-tint); }
  .bk-day.is-selected:hover { background: var(--bk-sel-hover); }
}

.bk-strip-empty {
  margin: .5rem 0;
  font-size: .875rem;
  color: var(--bk-muted);
}

/* ---------- Time pills ---------- */

.bk-times { gap: .5rem; grid-template-columns: repeat(2, 1fr); }

.bk-slot label {
  min-height: 46px;
  border: 0;
  border-radius: 999px;
  background: var(--bk-tint);
  color: var(--bk-ink);
  font-weight: 600;
  box-shadow: none;
}

.bk-slot input:checked + label {
  background: var(--bk-sel);
  color: #fff;
  box-shadow: 0 2px 6px rgba(10, 12, 15, .16), 0 10px 22px -8px rgba(10, 12, 15, .34);
}

@media (hover: hover) and (pointer: fine) {
  .bk-slot label:hover { background: var(--bk-tint-hi); }
  .bk-slot input:checked + label:hover { background: var(--bk-sel-hover); }
}

/* ---------- Segmented control ---------- */

.bk-seg { background: #EEECE8; }
.bk-seg label { border-radius: 999px; }

/* ---------- Action ---------- */

.bk-bar { background: rgba(246, 245, 243, .82); border-top-color: transparent; }

.bk-submit {
  min-height: 54px;
  border-radius: 999px;
  font-size: 1rem;
  box-shadow: 0 2px 6px rgba(10, 12, 15, .16), 0 12px 28px -10px rgba(10, 12, 15, .4);
}

/* ---------- Fields ---------- */

.bk-field input,
.bk-field textarea { border-radius: var(--bk-r-sm); background: #FAF9F7; border-color: transparent; }

.bk-field input:focus,
.bk-field textarea:focus {
  background: var(--bk-surface);
  border-color: var(--bk-ink);
  box-shadow: 0 0 0 3px rgba(10, 12, 15, .08);
}

/* ---------- Tablet and desktop ----------
   The rail stays horizontal at every width — it is the same gesture with a
   mouse wheel or a trackpad swipe, and switching back to a grid on desktop
   would mean two calendars to keep in step. Desktop simply gets more of the
   rail on screen and more time pills per row. */

@media (min-width: 700px) {
  .bk-times { grid-template-columns: repeat(4, 1fr); }
  .bk-day { width: 62px; min-height: 72px; }
}

@media (min-width: 960px) {
  /* Undo the base rule that put the times in a narrow 200px column beside the
     calendar: the rail is full-width now, so the pills sit under it. */
  .bk-cal-times { display: block; }
  .bk-times-wrap { margin-top: 1.5rem; }
  .bk-times { grid-template-columns: repeat(4, 1fr); max-height: none; overflow: visible; }
}

/* ---------- Visually hidden inputs ----------
   The radio behind each type, slot and segment label. `position: absolute` with
   no offsets and no positioned ancestor resolves against the initial containing
   block and stretches the input to the full viewport width, which pushed the
   whole page sideways on a phone. Clip them properly instead — and never with
   `display: none`, which would take them out of the tab order and kill the
   `:focus-visible + label` ring that is the only focus cue these controls have. */

.bk-seg input,
.bk-slot input,
.bk-type input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- Accessibility corrections ----------
   Both of these were measured in a real browser, not eyeballed.

   1. The "no time selected" Confirm button was white on #C2C7CF — a contrast
      ratio of 1.70, so the label was barely there. It is a hint, not a true
      disabled control (the button still submits and raises an inline error),
      so it should read as muted-but-legible rather than invisible.
   2. The month arrows were 40x40, under the 44px minimum touch target. */

.bk-submit[aria-disabled="true"] {
  background: #D5D1CA;
  color: #332F2A;
  box-shadow: none;
}

.bk-nav button { width: 44px; height: 44px; }

/* Sits under the time pills — the answer to "why does nothing start before
   7pm". Muted so it reads as a footnote to the grid, not another choice. */
.bk-note {
  margin: 1rem 0 0;
  font-size: .8125rem;
  line-height: 1.5;
  color: var(--bk-muted);
}

/* ---------- "Ship it instead" escape hatch ----------
   For the customer who opened the booking page and then realised they would
   rather not come at all. Deliberately after the form and visually quieter
   than Confirm: it is an alternative, not a competing call to action. */

.bk-switch {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-top: 1rem;
  padding: 1.25rem;
  border-radius: var(--bk-r-lg);
  background: var(--bk-surface);
  box-shadow: var(--bk-shadow);
}

.bk-switch-title {
  margin: 0 0 .25rem;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -.015em;
}

.bk-switch-sub {
  margin: 0;
  font-size: .875rem;
  line-height: 1.5;
  color: var(--bk-muted);
}

.bk-switch-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  flex: 0 0 auto;
  min-height: 48px;
  padding: .75rem 1.25rem;
  border-radius: 999px;
  background: var(--u-wa);
  color: #fff;
  font-size: .9375rem;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  box-shadow: 0 2px 6px rgba(10, 12, 15, .12), 0 10px 22px -10px rgba(37, 211, 102, .7);
  transition: background-color 180ms var(--bk-ease), transform 180ms var(--bk-ease);
}

.bk-switch-cta svg { width: 20px; height: 20px; flex: 0 0 auto; }
.bk-switch-cta:active { transform: scale(.97); }
.bk-switch-cta:focus-visible { outline: 2px solid var(--bk-ink); outline-offset: 3px; }

@media (hover: hover) and (pointer: fine) {
  .bk-switch-cta:hover { background: var(--u-wa-hover); }
}

/* Side by side once there is room for the copy to sit left of the button. */
@media (min-width: 560px) {
  .bk-switch { flex-direction: row; align-items: center; justify-content: space-between; }
  .bk-switch-copy { min-width: 0; }
}

/* The nudge. Added by JS the first time the card scrolls into view, and removed
   when it ends, so it plays exactly once — a looping animation on a page the
   customer is trying to fill in is an irritation, not a prompt. */
.bk-switch.is-nudging { animation: bk-switch-in 620ms var(--bk-ease) both; }
.bk-switch.is-nudging .bk-switch-cta { animation: bk-pulse 1400ms var(--bk-ease) 300ms 2; }

@keyframes bk-switch-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

@keyframes bk-pulse {
  0%, 100% { box-shadow: 0 2px 6px rgba(10, 12, 15, .12), 0 10px 22px -10px rgba(37, 211, 102, .7); }
  50% {
    box-shadow: 0 2px 6px rgba(10, 12, 15, .12), 0 10px 26px -8px rgba(37, 211, 102, .9),
                0 0 0 8px rgba(37, 211, 102, .14);
  }
}

/* The global reduced-motion block above already flattens these to 1ms, so the
   card simply appears. Nothing here needs to opt out separately. */

/* ---------- "Ship it instead", repositioned above the card ----------
   Moved from the foot of the page on 2026-08-28. Everything here is about
   making it read as the secondary option now that it sits over the calendar
   rather than below the form: a tinted bar instead of a white card, no lifted
   shadow, a smaller button, and a single fade rather than a repeating pulse. */

.bk-switch {
  margin-top: 0;
  margin-bottom: .875rem;
  padding: .875rem 1rem;
  border-radius: var(--bk-r);
  background: rgba(255, 255, 255, .66);
  border: 1px solid var(--bk-line);
  box-shadow: none;
  gap: .75rem;
}

.bk-switch-title { font-size: .9375rem; margin-bottom: .125rem; }
.bk-switch-sub { font-size: .8125rem; }

.bk-switch-cta {
  min-height: 44px;
  padding: .5rem 1rem;
  font-size: .875rem;
  box-shadow: 0 1px 2px rgba(10, 12, 15, .1);
}

.bk-switch-cta svg { width: 18px; height: 18px; }

/* One fade, no pulse. The card is on screen at load now, so a green ring
   throbbing beside the date rail would pull attention off the booking. */
.bk-switch.is-nudging { animation: bk-switch-in 480ms var(--bk-ease) both; }
.bk-switch.is-nudging .bk-switch-cta { animation: none; }

/* On a phone the copy and the button stack; keep the button full width there so
   it does not end up a lonely pill under two lines of text. */
@media (max-width: 559px) {
  .bk-switch-cta { width: 100%; }
}

/* A full-width green button above the calendar is louder than the Confirm
   button it is an alternative to, which is backwards. Auto width, aligned
   left, so it stays an offer rather than the headline. */
@media (max-width: 559px) {
  .bk-switch-cta { width: auto; align-self: flex-start; }
}

/* "Book an appointment with us" broke with "us" alone on the second line.
   Unsupported browsers just get the normal greedy wrap. */
.bk-title { text-wrap: balance; }

.bk-note a { color: var(--bk-accent-ink); font-weight: 600; }

/* ==========================================================================
   Phone: fit the page down instead of splitting it
   --------------------------------------------------------------------------
   An earlier revision made this a two-step wizard, swapping the picker out for
   the form once a time was chosen. Owner's call on 2026-08-28: it is one page,
   and it should stay one page. So the height comes out of the furniture and out
   of the times list, not out of splitting the flow.

   Measured at 390x844 before this block: the page ran 1128px. The costs were a
   146px "changed your mind" card, 112px of bottom padding reserving space for
   an 80px bar, a two-line note, and a two-column time grid.
   ========================================================================== */

@media (max-width: 699px) {
  /* One row: the heading and the button, with the explanatory line dropped.
     "Changed your mind?" beside a WhatsApp button already carries the offer,
     and the sentence under it was costing two lines to restate that. It stays
     on wider screens, where the height is free. */
  .bk-switch {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: .625rem;
    padding: .5rem .5rem .5rem .875rem;
    margin-bottom: .625rem;
  }

  .bk-switch-sub { display: none; }
  .bk-switch-title { margin-bottom: 0; font-size: .875rem; }

  .bk-switch-cta {
    width: auto;
    align-self: auto;
    min-height: 40px;
    padding: .4375rem .875rem;
    font-size: .8125rem;
  }

  .bk-switch-cta svg { width: 16px; height: 16px; }

  /* General tightening. Nothing here changes what is on the page. */
  .bk-head { padding-top: 1rem; padding-bottom: .625rem; }
  .bk-title { font-size: 1.375rem; margin-bottom: .75rem; }
  .bk-brand { margin-bottom: .5rem; }
  .bk-section { padding-top: 1.125rem; padding-bottom: 1.125rem; }
  .bk-h2 { margin-bottom: .875rem; }
  .bk-fields { gap: .75rem; }
  .bk-note { margin-top: .75rem; }

  /* Three time columns rather than two. "7:00 PM" needs about 60px and each
     column gets ~114px at 390px wide, so the extra column costs nothing in
     legibility and removes a row. */
  .bk-times { grid-template-columns: repeat(3, 1fr); gap: .4375rem; }
  .bk-slot label { min-height: 44px; font-size: .875rem; }

  /* Deliberately NOT capped with its own scrollbar. Capping the list shortens
     the page, but it buys that with a scroll region inside a scrolling page,
     and a nested scroller on a phone is the "scrolling here and there" this
     was meant to remove: the list eats the swipe, then hands it back to the
     page halfway through. One page, one scroll. */
}

/* The bar is 80px tall here; 112px of padding left 32px of dead air under the
   last section. The 360px floor keeps the taller allowance where the bar stacks
   into two rows. */
@media (min-width: 360px) and (max-width: 699px) {
  .bk { padding-bottom: 88px; }
}

/* ---------- Sticky bar: its own surface ----------
   It was the page tint at 82%, so it read as the page rather than as a layer
   over it - with nothing but a hairline saying where the content stopped.
   White separates it from the warm ground, and a shadow thrown upward makes it
   sit above the page instead of being cut out of it. The dark Confirm button
   gains contrast from the lighter ground too. */

.bk-bar {
  background: rgba(255, 255, 255, .88);
  backdrop-filter: blur(18px) saturate(1.6);
  -webkit-backdrop-filter: blur(18px) saturate(1.6);
  border-top: 1px solid rgba(10, 12, 15, .07);
  box-shadow: 0 -1px 2px rgba(10, 12, 15, .03), 0 -10px 30px -12px rgba(10, 12, 15, .16);
}

/* Backdrop-filter is widely supported but not universal, and a bar at 88%
   opacity over scrolling text is unreadable without the blur. Anywhere it is
   missing, go fully opaque instead. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .bk-bar { background: #FFFFFF; }
}

/* ---------- Summary: never truncate the time ----------
   `white-space: nowrap` with an ellipsis cut "Fri 28 Aug 2026, 7:00 PM" to
   "Fri 28 Aug 2026, 7:0..." on a 390px screen - clipping the one piece of
   information the line exists to carry, and always at the same place, because
   the time is last. Let it wrap onto a second line instead; the bar has the
   room and "Singapore time" underneath is the expendable part. */

.bk-summary strong {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  text-wrap: balance;
}

/* Two lines of date plus the timezone line is a tall bar on a small screen, so
   the timezone gives way once the date needs the space. It is also the least
   surprising thing to lose: every time on the page is Singapore time, and the
   header already says so. */
@media (max-width: 430px) {
  .bk-summary span { display: none; }
}

/* ---------- "How to get to us" ----------
   A native <details>. Closed it is one row; open it adds the map buttons and
   the travel notes. No JS, so it works with scripting off and comes with
   keyboard and screen-reader behaviour already correct. */

.bk-getting { padding-top: 1.125rem; padding-bottom: 1.125rem; }

.bk-details { border-radius: var(--bk-r); }

.bk-summary-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  min-height: 44px;
  cursor: pointer;
  list-style: none;          /* kill the default disclosure triangle */
  border-radius: var(--bk-r-sm);
}

.bk-summary-row::-webkit-details-marker { display: none; }
.bk-summary-row:focus-visible { outline: 2px solid var(--bk-accent); outline-offset: 3px; }

.bk-getting-head { display: flex; align-items: center; gap: .625rem; min-width: 0; }

.bk-getting-head > svg {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  color: var(--bk-muted);
}

.bk-getting-head strong {
  display: block;
  font-size: .9375rem;
  font-weight: 700;
  letter-spacing: -.01em;
}

.bk-getting-addr {
  display: block;
  font-size: .8125rem;
  color: var(--bk-muted);
  line-height: 1.35;
}

.bk-chevron {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  color: var(--bk-muted);
  transition: transform 200ms var(--bk-ease);
}

.bk-details[open] .bk-chevron { transform: rotate(180deg); }

.bk-getting-body { padding-top: 1rem; }

.bk-maps { display: flex; flex-wrap: wrap; gap: .5rem; }

.bk-map-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: .5rem 1rem;
  border: 1px solid var(--bk-line-2);
  border-radius: 999px;
  background: var(--bk-surface);
  color: var(--bk-ink);
  font-size: .875rem;
  font-weight: 600;
  text-decoration: none;
  transition: border-color 160ms var(--bk-ease), background-color 160ms var(--bk-ease);
}

@media (hover: hover) and (pointer: fine) {
  .bk-map-btn:hover { border-color: var(--bk-ink); background: var(--bk-page); }
}

.bk-map-btn:focus-visible { outline: 2px solid var(--bk-accent); outline-offset: 2px; }

.bk-ways {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  gap: .75rem;
}

.bk-ways li {
  font-size: .875rem;
  line-height: 1.5;
  color: var(--bk-ink-2);
}

.bk-ways strong {
  display: block;
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--bk-muted);
  margin-bottom: .125rem;
}

.bk-getting-note {
  margin: 1rem 0 0;
  font-size: .8125rem;
  line-height: 1.5;
  color: var(--bk-muted);
}

.bk-getting-note a { color: var(--bk-accent-ink); font-weight: 600; }

/* The disclosure opening is a change of state, so it moves rather than snaps.
   The global reduced-motion rule flattens this to nothing. */
.bk-details[open] .bk-getting-body { animation: bk-step-open 220ms var(--bk-ease) both; }

@keyframes bk-step-open {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: none; }
}
