/*
 * The dispatch design tokens.
 *
 * COPIED VERBATIM from src/ui/tokens.css on 2026-08-06 — the light :root block,
 * located by its delimiters and never by line numbers (06-UI-SPEC Token Transfer
 * rule 1). Same declarations, same order, same values, same spelling. Nothing is
 * renamed, tidied or dropped for being unused, and tests/booking-isolation.test.ts
 * asserts byte-identity.
 *
 * The dark-theme override block is deliberately NOT copied, and neither are the
 * scrim and halo tokens: no scrim and no primary-pill halo exist on this page.
 * Omitting dark entirely is what makes "the booking page is light" unbreakable
 * rather than a convention someone half-enables later. The isolation test asserts
 * the absence of all three by name, so this comment describes them rather than
 * spelling them — prose that names a forbidden literal fails the guard.
 *
 * This page can neither link nor inline-include tokens.css: that file is served
 * by a Bun server on Michael's own machine, and a public page fetching it would
 * block on a request that never resolves. Fonts load by <link> for the same
 * reason — a stylesheet-level include is render-blocking and serial on a phone.
 */
:root {
  --canvas: #F3F1EC;
  --card: #FDFCFA;
  --card-2: #F7F5F0;
  --ink: #17161B;
  --ink-soft: #57555E;
  --ink-faint: #8B8994;
  --line: #E4E1D9;
  --line-strong: #CFCCC2;
  --lilac: #C9B8FF;
  --lilac-deep: #7A5FD0;
  --lilac-wash: #EFEAFF;
  --orange: #E24400;
  --orange-bright: #FC4C02;
  --orange-wash: #FBEADF;
  --green: #1F7A46;
  --green-wash: #E4F2E9;
  --amber: #9A6A00;
  --amber-wash: #F6EDDA;
  --red: #B4231F;
  --red-wash: #F9E7E5;
  --shadow-card: 0 1px 2px rgba(23,22,27,0.05), 0 8px 24px -12px rgba(23,22,27,0.18);
  --shadow-float: 0 2px 4px rgba(23,22,27,0.06), 0 18px 44px -18px rgba(23,22,27,0.28);
  --radius: 18px;
}

/* ===========================================================================
   Everything below the copied token block is this page's own, and every colour
   in it flows from a token above — the same no-literals rule
   tests/tokens.test.ts applies to every stylesheet under src/ui/, applied here
   because this file sits outside that walk.

   Mobile-first, and that is a design instruction rather than a nicety:
   prospects open this from a text message or an ad on a phone, usually within a
   minute of deciding to. Every dimension is specified small first and the
   desktop layout is the enhancement.

   Class names cross the deployment boundary with their values: .kick, .card,
   .pill, .field, .chip, .linklike, .empty, .skel and .display keep their
   shipped names and shipped declarations. Booking-only classes are prefixed
   .bk- and nothing else is.
   =========================================================================== */

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background: var(--canvas);
  color: var(--ink);
  /* A system stack so the page is readable before the three families land. */
  font-family: "Barlow", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ===== dispatch .display, verbatim ===== */
.display {
  font-family: "Archivo", "Barlow", sans-serif;
  font-variation-settings: "wdth" 115;
  font-weight: 800;
  letter-spacing: -0.015em;
}

/* ===== dispatch .kick, verbatim ===== */
.kick {
  display: block;
  font-family: "Space Grotesk", sans-serif;
  font-weight: 600;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .22em;
  color: var(--ink-soft);
}

/* ===== dispatch .card, verbatim ===== */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 22px 24px;
}

/* ===== dispatch .empty, verbatim ===== */
.empty {
  border: 1.5px dashed var(--line-strong);
  border-radius: var(--radius);
  padding: 44px 30px;
  text-align: center;
  color: var(--ink-faint);
}

/* ===== dispatch button.pill, lifted from contacts.css =====
   One deliberate omission: the primary pill's second shadow layer is the halo,
   and the halo token is not copied to this page (Token Transfer rule 2). The
   lilac-wash ring carries the treatment on its own. */
button.pill {
  border: none;
  cursor: pointer;
  border-radius: 999px;
  font: 700 13px "Barlow", sans-serif;
  letter-spacing: .02em;
  padding: 9px 18px;
  transition: transform .12s ease, box-shadow .12s ease;
}
button.pill:active { transform: scale(.97); }
button.pill.primary {
  background: var(--ink);
  color: var(--canvas);
  box-shadow: 0 0 0 4px var(--lilac-wash);
}
button.pill.primary:hover { box-shadow: 0 0 0 4px var(--lilac); }
button.pill.ghost { background: transparent; color: var(--ink-soft); border: 1px solid var(--line-strong); }
button.pill[disabled] { opacity: .45; cursor: not-allowed; }
button.pill:focus-visible { outline: 2px solid var(--lilac-deep); outline-offset: 2px; }

/* ===== dispatch .linklike, verbatim ===== */
.linklike {
  border: none;
  background: transparent;
  padding: 0;
  cursor: pointer;
  font: inherit;
  font-weight: 700;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--lilac);
  text-underline-offset: 3px;
}
.linklike:hover { text-decoration-color: var(--lilac-deep); }
.linklike:focus-visible { outline: 2px solid var(--lilac-deep); outline-offset: 2px; }

/* ===== dispatch .field, verbatim ===== */
.field { display: flex; flex-direction: column; gap: 6px; }
.field label {
  font: 700 11.5px "Space Grotesk", sans-serif;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.field input, .field select, .field textarea {
  background: var(--canvas);
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  padding: 11px 13px;
  font: 500 14px "Barlow", sans-serif;
  width: 100%;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 2px solid var(--lilac);
  outline-offset: -1px;
}
.field .hint { font: 500 12px "Barlow", sans-serif; color: var(--ink-faint); }

/* ===== dispatch .skel, verbatim ===== */
.skel {
  display: block;
  height: 12px;
  border-radius: 6px;
  background: var(--card-2);
  animation: pulse 1.2s ease-in-out infinite alternate;
}
@keyframes pulse { from { opacity: .55; } to { opacity: 1; } }

/* ===== dispatch .iconbtn, the 38px circular control ===== */
.iconbtn {
  width: 38px;
  height: 38px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
}
.iconbtn:hover { color: var(--ink); border-color: var(--ink-faint); }
.iconbtn:focus-visible { outline: 2px solid var(--lilac-deep); outline-offset: 2px; }

/* ===========================================================================
   Booking-only surfaces
   =========================================================================== */

/* The page's max-width carries the card's measure PLUS its own padding, so the
   card itself lands on 560 and 880 rather than 48px short of each. */
.bk-page {
  max-width: 608px;
  margin: 0 auto;
  padding: 24px;
}

.bk-head { margin-bottom: 16px; }
.bk-head h1 { font-size: 28px; line-height: 1.1; margin-top: 4px; }
.bk-sub { color: var(--ink-soft); margin-top: 4px; }

.bk-card { padding: 20px; }

.bk-foot {
  font: 500 12.5px "Barlow", sans-serif;
  line-height: 1.4;
  color: var(--ink-faint);
  margin-top: 24px;
}

/* A polite region, off-screen but never display:none — a hidden live region
   announces nothing. */
.bk-live {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.bk-panels { display: block; }
.bk-when { margin-bottom: 16px; }

/* ---- the day strip: the mobile day picker ---- */
.bk-strip {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: thin;
}
.bk-day {
  flex: none;
  width: 56px;
  min-height: 48px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  padding: 4px;
}
.bk-day .bk-dow {
  display: block;
  font: 600 11px "Space Grotesk", sans-serif;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--ink-soft);
}
.bk-day .bk-num { display: block; font: 700 15px "Barlow", sans-serif; line-height: 1.35; }
.bk-day[aria-pressed="true"] {
  background: var(--lilac-wash);
  border-color: var(--lilac-deep);
}
.bk-day[aria-pressed="true"] .bk-num,
.bk-day[aria-pressed="true"] .bk-dow { color: var(--lilac-deep); }
.bk-day[disabled] { color: var(--ink-faint); cursor: not-allowed; background: var(--card-2); }
.bk-day[disabled] .bk-dow, .bk-day[disabled] .bk-num { color: var(--ink-faint); }
.bk-day:focus-visible { outline: 2px solid var(--lilac-deep); outline-offset: 2px; }

/* ---- the month panel: the desktop day picker ---- */
.bk-month { display: none; }
.bk-monthbar { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.bk-monthname { flex: 1; text-align: center; font: 700 15px "Barlow", sans-serif; }
.bk-weekdays, .bk-cells { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.bk-weekdays span {
  text-align: center;
  font: 600 11px "Space Grotesk", sans-serif;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--ink-faint);
}
.bk-cell {
  min-width: 0;
  height: 40px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  font: 500 14px "Barlow", sans-serif;
  cursor: pointer;
}
.bk-cell[aria-pressed="true"] {
  background: var(--lilac-wash);
  border-color: var(--lilac-deep);
  color: var(--lilac-deep);
  font-weight: 700;
}
.bk-cell[disabled] { color: var(--ink-faint); cursor: not-allowed; background: var(--canvas); }
.bk-cell.bk-blank { border: none; background: transparent; cursor: default; }
.bk-cell:focus-visible { outline: 2px solid var(--lilac-deep); outline-offset: 2px; }

/* ---- the slots ---- */
.bk-slots {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
.bk-slot {
  min-width: 0;
  min-height: 48px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: var(--card);
  color: var(--ink);
  font: 700 15px "Barlow", sans-serif;
  line-height: 1.35;
  cursor: pointer;
  transition: border-color .12s ease;
}
.bk-slot:hover { border-color: var(--lilac-deep); }
.bk-slot[aria-pressed="true"] {
  background: var(--lilac-wash);
  border-color: var(--lilac-deep);
  color: var(--lilac-deep);
}
.bk-slot:focus-visible { outline: 2px solid var(--lilac-deep); outline-offset: 2px; }

/* Six of these render at full slot height while the request is in flight.
   An empty column for 800ms reads as "he is fully booked" and the prospect
   closes the tab, so there is no state in which this column is blank and
   silent. */
.bk-skel { height: 48px; border-radius: 12px; }

.bk-note {
  font: 500 12.5px "Barlow", sans-serif;
  line-height: 1.4;
  color: var(--ink-soft);
  margin-top: 16px;
}
.bk-note + .bk-note { margin-top: 4px; }

/* "Fully booked" and "broken" look identical to a stranger and only one of them
   is recoverable, so a failure renders this block and never an empty list. */
.bk-fail {
  background: var(--red-wash);
  border: 1px solid var(--red);
  border-radius: var(--radius);
  padding: 16px;
  color: var(--ink);
}
.bk-fail b { display: block; font-family: "Archivo", sans-serif; font-weight: 800; font-size: 17px; margin-bottom: 4px; }
.bk-fail p { font-size: 14px; }

/* ---- state 2 ---- */
.bk-back { margin-bottom: 8px; display: inline-block; }
.bk-chosen { font: 700 15px "Barlow", sans-serif; line-height: 1.35; margin-bottom: 16px; }

.bk-form { display: flex; flex-direction: column; gap: 16px; }
/* Touch target comes before density on a surface a stranger operates on an
   unknown phone. */
.bk-form .field input { min-height: 48px; }
.bk-form .field textarea { min-height: 96px; }

.bk-error { color: var(--red); font-size: 14px; font-weight: 600; }

.bk-submit { min-height: 48px; width: 100%; font-size: 15px; }

/* ---- state 3 ---- */
.bk-done { font-size: 28px; line-height: 1.1; }
.bk-done:focus-visible { outline: 2px solid var(--lilac-deep); outline-offset: 4px; }
.bk-tick { color: var(--green); margin-right: 8px; }
.bk-when-line { font: 700 15px "Barlow", sans-serif; line-height: 1.35; margin-top: 8px; }
.bk-rule { border: none; border-top: 1px solid var(--line); margin: 32px 0 16px; }
.bk-body { font-size: 14px; color: var(--ink); }

/* ===========================================================================
   720px — the one breakpoint, stated once. Below it, a single column and the
   day strip. At and above it, the two-panel month + slots layout.
   =========================================================================== */
@media (min-width: 720px) {
    /* 880 gives a 320px month panel, a 32px gap and a 464px slot panel. */
  .bk-page { max-width: 928px; padding: 48px 24px; }
  .bk-card { padding: 32px; }
  .bk-panels { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 32px; }
  .bk-when { margin-bottom: 0; }
  .bk-strip { display: none; }
  .bk-month { display: block; }
  .bk-submit { width: auto; align-self: flex-start; padding-left: 24px; padding-right: 24px; }
}

/* States change without gliding; nothing becomes unreachable. */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
