/*
  BusyCal Bookings: public page styles, ported from design/tokens.css and design/bookings.css.

  Every interaction is a link, a form or a <details> disclosure, so pages work with scripts
  turned off. The Content Security Policy blocks images, data: URIs and inline styles, so
  all icons are inline SVG in the markup and every style lives in this file.

  Breakpoints: phones below 640 px (single column, full-bleed card, 16 px gutters), tablets
  from 640 px (inset card), two-pane picker from 720 px, two-pane form from 880 px, desktop
  from 1024 px.
*/

/* ---------- Tokens ---------- */

/*
  The host's accent is one property, --accent; the default is BusyCal blue, #4480db, as on
  busymac.com, and the organizer's appearance.css replaces it. Pages never use it directly
  for text or fills; they use tones derived from it in OKLCH with the lightness clamped, so
  text and controls keep WCAG AA contrast in both appearances. White text on the blue itself
  is only 3.9:1, so fills take the rule's deeper step of the same hue; tints use the blue
  itself. Browsers without relative color syntax (Safari before 18, older Firefox) use fixed
  tones instead: the default blue's derived tones, resolved once, so they keep the same
  contrast (ink 6.66:1 on the light card, white on the fill 5.59:1; 9.14:1 and 5.36:1 in
  dark appearance).
*/
:root {
  --accent: #4480db;

  /* Type */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI",
    system-ui, Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji",
    "Segoe UI Emoji";
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-md: 1.125rem;
  --text-lg: 1.375rem;
  --text-xl: 1.75rem;
  --leading-tight: 1.25;
  --leading: 1.5;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  /* Spacing, on a 4 px grid */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* Shape */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 22px;
  --radius-full: 999px;
  --target: 44px;
  --gutter: 16px;

  /* Light appearance */
  color-scheme: light;
  --bg: #f3f4f7;
  --surface: #ffffff;
  --surface-2: #f6f7f9;
  --surface-3: #eceef2;
  --surface-raised: #ffffff;
  --seg-active: #ffffff;
  --line: #e1e4e9;
  --line-strong: #878e99;
  --text: #16181d;
  --text-2: #4b515a;
  --text-3: #626873;
  --text-disabled: #8b919a;
  --field-bg: #ffffff;

  --success-ink: #13743f;
  --success-soft: #e5f5ec;
  --warn-ink: #7f5200;
  --warn-soft: #fcf1d8;
  --danger-ink: #b3261e;
  --danger-soft: #fceceb;
  --danger-fill: #c42b22;
  --success-fill: #1c8a4f;
  --warn-fill: #b87200;
  --on-fill: #ffffff;

  /* macOS system colors, for drawings that mirror BusyCal on the Mac: free and busy time as
     its Availability Viewer draws them. The green itself is 2.1:1 on white, too faint for a
     line, so a line drawn in it uses the darker --system-green-line (4.4:1). */
  --system-green: #28cd41;
  --system-green-line: #248a3d;
  --system-gray: #8e8e93;

  --shadow-card: 0 1px 2px rgb(16 24 40 / 0.05), 0 12px 32px -12px rgb(16 24 40 / 0.14);
  --shadow-pop: 0 2px 6px rgb(16 24 40 / 0.08), 0 18px 40px -12px rgb(16 24 40 / 0.22);

  /* Accent tones: fixed fallbacks first, derived tones in the @supports block below */
  --accent-fill: #2b66bf;
  --accent-fill-hover: #1754ab;
  --accent-ink: #1e5ab1;
  --accent-soft: #e9f0fa;
  --accent-soft-hover: #dae5f6;
  --accent-line: #a9c2e8;
  --accent-band: #f0f5fd;
  --accent-wash: rgb(68 128 219 / 0.16);
  --focus: var(--accent-ink);
}

/*
  Light: fills that carry white text are capped at OKLCH lightness 0.52 and accent text at
  0.48. Chroma is capped at 0.16 so neon accents stay inside the sRGB gamut; browsers clip
  out-of-gamut colors, which shifts their luminance and breaks contrast.
*/
@supports (color: oklch(from red min(l, 0.5) c h)) {
  :root {
    --accent-fill: oklch(from var(--accent) min(l, 0.52) min(c, 0.16) h);
    --accent-fill-hover: oklch(from var(--accent) min(calc(l - 0.06), 0.46) min(c, 0.16) h);
    --accent-ink: oklch(from var(--accent) min(l, 0.48) min(c, 0.16) h);
    --accent-soft: color-mix(in oklab, var(--accent-fill) 10%, var(--surface));
    --accent-soft-hover: color-mix(in oklab, var(--accent-fill) 17%, var(--surface));
    --accent-line: color-mix(in oklab, var(--accent-fill) 40%, var(--surface));
    --accent-band: color-mix(in oklab, var(--accent) 8%, var(--surface));
    --accent-wash: color-mix(in srgb, var(--accent) 16%, transparent);
  }
}

/* Dark appearance follows the visitor's system setting. */
/* ---------- Base ---------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: var(--space-4);
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading);
  color: var(--text);
  background:
    radial-gradient(110% 420px at 50% -180px, var(--accent-wash), transparent 72%) no-repeat,
    var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6, p, ul, ol, dl, dd, figure, blockquote, form {
  margin: 0;
}

ul[role="list"],
ol[role="list"] {
  list-style: none;
  padding: 0;
}

svg {
  display: block;
  max-width: 100%;
}

.icon {
  width: 20px;
  height: 20px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

a {
  color: var(--accent-ink);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

time {
  font-variant-numeric: tabular-nums;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  z-index: 100;
  left: var(--space-3);
  top: -200px;
  display: inline-flex;
  align-items: center;
  min-height: var(--target);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--surface-raised);
  color: var(--text);
  font-weight: var(--weight-semibold);
  box-shadow: var(--shadow-pop);
}

.skip-link:focus {
  top: var(--space-3);
}

/* ---------- Page frame and footer ---------- */

.page {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

.shell {
  flex: 1;
  width: 100%;
  max-width: calc(var(--shell, 1040px) + 2 * var(--gutter));
  margin: 0 auto;
  padding: var(--space-6) var(--gutter) var(--space-8);
}

.shell--narrow {
  --shell: 800px;
}

.shell--status {
  --shell: 640px;
}

.shell--center {
  --shell: 520px;
  display: flex;
  align-items: center;
}

/* The organizer's logo sits above the card and lines up with the page's own width. */
.brandbar {
  width: 100%;
  max-width: calc(var(--shell, 1040px) + 2 * var(--gutter));
  margin: 0 auto;
  padding: var(--space-6) var(--gutter) 0;
}

.page:has(> .shell--narrow) > .brandbar {
  --shell: 800px;
}

.page:has(> .shell--status) > .brandbar {
  --shell: 640px;
}

.page:has(> .shell--center) > .brandbar {
  --shell: 520px;
}

/* Logos fill an 8:1 area. In dark appearance a light plate keeps dark logos visible. */
.brand-logo {
  display: inline-block;
  border-radius: var(--radius-sm);
}

.brand-logo img {
  display: block;
  height: 28px;
  width: auto;
  max-width: 224px;
  object-fit: contain;
}

/* The preview notice sits above the card, inside the page gutters on every width. */
.preview-banner {
  margin-bottom: var(--space-4);
}

.site-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-1) var(--space-3);
  padding: var(--space-4) var(--gutter) var(--space-8);
  font-size: var(--text-sm);
  color: var(--text-3);
}

.site-foot a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 32px;
  color: var(--text-3);
  text-decoration: none;
}

.site-foot a:hover {
  color: var(--text);
}

.made-with .mark {
  width: 18px;
  height: 18px;
}

/* ---------- Cards ---------- */

.booker,
.status-card,
.error-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-card);
}

/*
  Host band: a light wash of the accent across the top of the card, like the colored header
  of a paper calendar page. It carries the host, the page title and the page facts.
*/
.booker-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--space-5);
  row-gap: var(--space-4);
  padding: var(--space-8) var(--space-8) var(--space-6);
  background: linear-gradient(180deg, var(--accent-band) 0%, var(--surface) 100%);
  border-bottom: 1px solid var(--line);
  border-radius: calc(var(--radius-xl) - 1px) calc(var(--radius-xl) - 1px) 0 0;
}

.booker-id {
  grid-row: 1;
  grid-column: 1;
  align-self: center;
  min-width: 0;
}

.booker-head > .settings {
  grid-row: 1;
  grid-column: 2;
  align-self: start;
}

.booker-head > .meta,
.booker-head > .description,
.booker-head > .band-note {
  grid-column: 1 / -1;
}

/*
  A host with a photo gets a leading column for it. The notices and page facts then line up
  under the name rather than under the photo. Without a photo the band keeps two columns.
*/
.booker-head:has(> .avatar) {
  grid-template-columns: auto minmax(0, 1fr) auto;
}

.booker-head > .avatar {
  grid-row: 1;
  grid-column: 1;
}

.booker-head:has(> .avatar) > .booker-id {
  grid-column: 2;
}

.booker-head:has(> .avatar) > .settings {
  grid-column: 3;
}

.booker-head:has(> .avatar) > .notice,
.booker-head:has(> .avatar) > .meta,
.booker-head:has(> .avatar) > .description,
.booker-head:has(> .avatar) > .band-note {
  grid-column: 2 / -1;
}

.booker-head--compact {
  padding-bottom: var(--space-5);
}

.booker-head--compact .page-title {
  font-size: var(--text-lg);
}

/* The host's photo, re-encoded as a square by the service and cropped to a circle here. */
.avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--surface-3);
  box-shadow: 0 0 0 3px var(--surface), 0 0 0 4px var(--line);
}

.host-name {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-2);
  overflow-wrap: anywhere;
}

/*
  Where the host's profile lists a page, the name leads back to that profile. It stays the
  quiet eyebrow, in the eyebrow's colour, size and weight; an underline on hover and the
  shared focus ring, rounded as on the other quiet links, show that it is a link.
*/
.host-name a {
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius-sm);
}

.host-name a:hover {
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
}

/* A touch screen has no hover, so there the name keeps the same 1 px underline at rest, in
   the eyebrow's own tone, and a visitor can see that it leads back to the profile. */
@media (hover: none) {
  .host-name a {
    text-decoration-line: underline;
    text-decoration-thickness: 1px;
  }
}

.page-title {
  margin-top: 2px;
  font-size: var(--text-xl);
  line-height: 1.2;
  font-weight: var(--weight-bold);
  letter-spacing: -0.015em;
  overflow-wrap: anywhere;
  text-wrap: balance;
}

/* Page facts: duration, location kinds and approval. */
.meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-5);
  list-style: none;
  padding: 0;
  font-size: var(--text-sm);
  color: var(--text-2);
}

.meta > li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 32px;
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.meta .icon {
  width: 18px;
  height: 18px;
  color: var(--text-3);
}

.description {
  max-width: 68ch;
  color: var(--text-2);
}

/* ---------- Host-authored Markdown ---------- */

.prose {
  overflow-wrap: anywhere;
}

.prose > * + * {
  margin-top: 0.7em;
}

.prose h1,
.prose h2,
.prose h3,
.prose h4,
.prose h5,
.prose h6 {
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  color: var(--text);
}

.prose ul,
.prose ol {
  padding-left: 1.3em;
}

.prose li + li {
  margin-top: 0.25em;
}

.prose strong {
  font-weight: var(--weight-semibold);
  color: var(--text);
}

.prose del {
  color: var(--text-3);
}

/* A long description shows its first paragraph; the rest opens below it. */
.more > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 32px;
  margin-top: var(--space-1);
  list-style: none;
  cursor: pointer;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--accent-ink);
}

.more > summary::-webkit-details-marker {
  display: none;
}

.more > summary .icon {
  width: 16px;
  height: 16px;
  transition: transform 0.15s ease;
}

.more .more-less,
.more[open] .more-more {
  display: none;
}

.more[open] .more-less {
  display: inline;
}

.more[open] > summary .icon {
  transform: rotate(180deg);
}

.more > summary + * {
  margin-top: 0.7em;
}

/* ---------- Disclosure menus: settings and time zone ---------- */

.menu,
.tz {
  position: relative;
}

.menu > summary,
.tz > summary,
.reveal > summary {
  list-style: none;
  cursor: pointer;
}

.menu > summary::-webkit-details-marker,
.tz > summary::-webkit-details-marker,
.reveal > summary::-webkit-details-marker {
  display: none;
}

.control {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 36px;
  padding: 0 var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}

.control:hover,
details[open] > .control {
  background: var(--surface-2);
  color: var(--text);
}

.control .chev {
  width: 16px;
  height: 16px;
  color: var(--text-3);
  transition: transform 0.15s ease;
}

details[open] > .control .chev {
  transform: rotate(180deg);
}

.popover {
  position: absolute;
  z-index: 20;
  top: calc(100% + var(--space-2));
  right: 0;
  width: 336px;
  max-width: calc(100vw - 2 * var(--gutter));
  padding: var(--space-4);
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop);
}

/* The time zone button sits at the right of the times column, so its menu opens leftward. */
.tz .popover {
  padding: var(--space-3);
}

.menu-section + .menu-section {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.menu-heading,
.eyebrow {
  margin-bottom: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-3);
}

.choice-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px var(--space-1);
  list-style: none;
  padding: 0;
}

.choice-list button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  min-height: 36px;
  padding: 0 var(--space-2) 0 var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text);
  font: inherit;
  font-size: var(--text-sm);
  text-align: start;
  cursor: pointer;
}

.choice-list button:hover {
  background: var(--surface-2);
}

.choice-list button[aria-current] {
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-weight: var(--weight-semibold);
}

.choice-list .icon {
  width: 16px;
  height: 16px;
}

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

/*
  Each segment submits its GET form; the current one carries aria-current. A page may offer
  up to eight durations, so segments wrap onto more rows instead of running off a phone.
*/
.seg {
  display: inline-flex;
  flex-wrap: wrap;
  min-width: 0;
  max-width: 100%;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-2);
}

.seg button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 28px;
  padding: 0 var(--space-3);
  border: 0;
  border-radius: 9px;
  background: none;
  color: var(--text-2);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  cursor: pointer;
}

.seg button:hover {
  color: var(--text);
  background: var(--surface-3);
}

.seg button[aria-current] {
  background: var(--seg-active);
  color: var(--text);
  font-weight: var(--weight-semibold);
  box-shadow: 0 1px 2px rgb(16 24 40 / 0.12), 0 0 0 1px var(--line);
}

.seg--block {
  display: flex;
}

.seg--block button {
  flex: 1;
}

/* ---------- Picker body: month ---------- */

.booker-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.pane {
  padding: var(--space-6) var(--space-8) var(--space-8);
  min-width: 0;
}

.pane-title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  letter-spacing: -0.01em;
}

.cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin: var(--space-4) 0 var(--space-2);
}

.cal-month {
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
}

.cal-nav {
  display: flex;
  gap: var(--space-1);
}

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-2);
}

.icon-btn:hover {
  background: var(--surface-2);
  color: var(--text);
}

.month {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}

.month th {
  padding: 0 0 var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-3);
}

.month abbr {
  text-decoration: none;
}

.month td {
  padding: 2px;
  text-align: center;
}

/*
  Day tiles echo the rounded tiles of the BusyCal icon. Open days are tinted and bold;
  closed days are plain and faint. The dots under an open day hint at how many times it
  has: one for a few, two for several, three for many.
*/
.day {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  max-width: 48px;
  aspect-ratio: 1;
  margin: 0 auto;
  border-radius: var(--radius-md);
  color: var(--text-disabled);
  font-size: 0.9375rem;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
}

.day--open {
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-weight: var(--weight-bold);
}

a.day--open:hover {
  background: var(--accent-soft-hover);
}

.day[aria-current] {
  background: var(--accent-fill);
  color: var(--on-fill);
}

.day-num {
  position: relative;
}

.day-dots {
  position: absolute;
  left: 50%;
  bottom: 5px;
  display: flex;
  gap: 3px;
  translate: -50% 0;
}

.day-dots i {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.55;
}

.day[aria-current] .day-dots i {
  opacity: 0.9;
}

.cal-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  margin-top: var(--space-4);
  font-size: var(--text-xs);
  color: var(--text-3);
}

.cal-legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.cal-legend i {
  width: 12px;
  height: 12px;
  border-radius: 4px;
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}

.cal-legend i.is-closed {
  background: none;
  box-shadow: inset 0 0 0 1px var(--line);
}

/* ---------- Picker body: times ---------- */

.times-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--line);
}

.times-day {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  letter-spacing: -0.01em;
}

.times-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.slot-group {
  margin-top: var(--space-5);
}

/* The part of the day, followed by a hairline that runs to the pane's edge. */
.slot-group-title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-3);
}

.slot-group-title::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

/* Each slot shows only its clock time, so columns are 104 px wide, three on phones. */
.slots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: var(--space-2);
  list-style: none;
  padding: 0;
}

/* A time that wraps in a narrow column stays centered and keeps its row's height. */
.slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: var(--target);
  height: 100%;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--accent-ink);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

a.slot:hover {
  background: var(--accent-fill);
  border-color: var(--accent-fill);
  color: var(--on-fill);
}

/* While rescheduling, the booking's own time keeps its place as a quiet dashed chip with
   a note beneath the time. It is not a link, so it has no hover. */
.slot[data-current] {
  border-style: dashed;
  border-color: var(--line-strong);
  background: var(--surface-2);
  color: var(--text-2);
}

.slot-note {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--text-3);
}

/* ---------- Time zone menu ---------- */

.tz-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text);
}

.tz-search {
  display: flex;
  gap: var(--space-2);
}

.tz-search .input {
  flex: 1;
  min-width: 0;
}

.tz-group {
  margin: var(--space-3) var(--space-1) var(--space-1);
}

.tz-list {
  max-height: 272px;
  overflow: auto;
  list-style: none;
  padding: 0;
  overscroll-behavior: contain;
}

.tz-list button {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0 var(--space-2);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text);
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.tz-list button:hover {
  background: var(--surface-2);
}

.tz-list button[aria-current] {
  background: var(--accent-soft);
}

.tz-city {
  font-weight: var(--weight-medium);
  overflow-wrap: anywhere;
}

.tz-meta {
  grid-column: 1 / -1;
  font-size: var(--text-xs);
  color: var(--text-3);
}

.tz-locked {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 36px;
  font-size: var(--text-sm);
  color: var(--text-2);
  overflow-wrap: anywhere;
}

.tz-locked .icon {
  width: 18px;
  height: 18px;
  color: var(--text-3);
}

/* ---------- Notices and empty states ---------- */

.notice {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 2px var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  background: var(--accent-soft);
  color: var(--text);
  font-size: var(--text-sm);
}

.notice > .icon {
  grid-row: 1 / span 2;
  margin-top: 1px;
  color: var(--accent-ink);
}

.notice-title {
  font-weight: var(--weight-semibold);
}

.notice-body {
  color: var(--text-2);
}

.notice--warn {
  background: var(--warn-soft);
}

.notice--warn > .icon {
  color: var(--warn-ink);
}

.notice--neutral {
  background: var(--surface-2);
}

.notice--neutral > .icon {
  color: var(--text-3);
}

.notice--neutral > .notice-title {
  align-self: center;
  font-weight: var(--weight-regular);
}

.state {
  display: grid;
  justify-items: center;
  gap: var(--space-3);
  padding: var(--space-10) var(--space-4);
  text-align: center;
}

.state-title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  text-wrap: balance;
}

/* A closed or paused page on its own names the state as the page heading. */
.state--page .state-title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  line-height: 1.25;
  letter-spacing: -0.01em;
}

.state-body {
  max-width: 40ch;
  color: var(--text-2);
  text-wrap: pretty;
}

.state-icon {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 16px;
  background: var(--surface-2);
  color: var(--text-3);
}

.state-icon .icon {
  width: 24px;
  height: 24px;
}

/* Tones for a status icon: the accent for the booking's own steps, the status colors for a
   result or a warning, and the plain tile for closed and neutral states. */
.state-icon--accent {
  background: var(--accent-soft);
  color: var(--accent-ink);
}

.state-icon--success {
  background: var(--success-soft);
  color: var(--success-ink);
}

.state-icon--warn {
  background: var(--warn-soft);
  color: var(--warn-ink);
}

.state-icon--danger {
  background: var(--danger-soft);
  color: var(--danger-ink);
}

/* ---------- Buttons and links ---------- */

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--target);
  padding: var(--space-2) var(--space-5);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font: inherit;
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.btn-primary {
  background: var(--accent-fill);
  color: var(--on-fill);
  box-shadow: 0 1px 2px rgb(16 24 40 / 0.14);
}

.btn-primary:hover {
  background: var(--accent-fill-hover);
}

.btn-secondary {
  background: var(--surface);
  border-color: var(--line-strong);
  color: var(--text);
}

.btn-secondary:hover {
  background: var(--surface-2);
}

/* A destructive answer, such as Cancel Booking or Decline. The dashboard uses the same
   three variants, with the same values, from its own sheet. */
.btn-danger {
  background: var(--danger-fill);
  color: var(--on-fill);
  box-shadow: 0 1px 2px rgb(16 24 40 / 0.14);
}

.btn-danger:hover {
  background: color-mix(in oklab, var(--danger-fill) 88%, black);
}

/* A quiet way out beside the main answers, such as Keep Current Time. */
.btn-quiet {
  background: transparent;
  color: var(--accent-ink);
}

.btn-quiet:hover {
  background: var(--accent-soft);
}

/* A quiet destructive link that only opens its confirmation step. */
.btn-danger-quiet {
  background: transparent;
  border-color: color-mix(in oklab, var(--danger-ink) 45%, transparent);
  color: var(--danger-ink);
}

.btn-danger-quiet:hover {
  background: var(--danger-soft);
}

.btn-sm {
  min-height: 36px;
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
}

.link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  text-decoration: none;
  border-radius: var(--radius-sm);
}

.link:hover {
  text-decoration: underline;
}

.link .icon {
  width: 16px;
  height: 16px;
}

/* ---------- Calendar page badge ---------- */

/*
  A small tear-off calendar page: the colored strip with two binder holes is taken from the
  BusyCal icon. It marks the meeting on the form, the confirmation and every error page.
*/
.datebadge {
  --badge-w: 64px;
  position: relative;
  display: grid;
  width: var(--badge-w);
  flex: none;
  border-radius: 14px;
  background: var(--surface-raised);
  box-shadow: 0 0 0 1px var(--line), 0 8px 18px -10px rgb(16 24 40 / 0.35);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.datebadge-month {
  position: relative;
  padding: 10px 0 3px;
  border-radius: 14px 14px 0 0;
  background: var(--accent-fill);
  color: var(--on-fill);
  font-size: 0.6875rem;
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.2;
}

.datebadge-month::before,
.datebadge-month::after {
  content: "";
  position: absolute;
  top: 4px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: color-mix(in oklab, var(--accent-fill) 55%, black);
}

.datebadge-month::before {
  left: 28%;
}

.datebadge-month::after {
  right: 28%;
}

.datebadge-day {
  padding-top: 6px;
  font-size: 1.75rem;
  font-weight: var(--weight-bold);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--text);
}

.datebadge-weekday {
  padding: 4px 0 9px;
  font-size: 0.6875rem;
  font-weight: var(--weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-3);
}

.datebadge--lg {
  --badge-w: 104px;
  border-radius: 20px;
}

.datebadge--lg .datebadge-month {
  padding: 14px 0 5px;
  border-radius: 20px 20px 0 0;
  font-size: 0.8125rem;
}

.datebadge--lg .datebadge-month::before,
.datebadge--lg .datebadge-month::after {
  top: 5px;
  width: 7px;
  height: 7px;
}

.datebadge--lg .datebadge-day {
  padding-top: 10px;
  font-size: 2.75rem;
}

.datebadge--lg .datebadge-weekday {
  padding: 6px 0 14px;
  font-size: 0.8125rem;
}

.datebadge--muted .datebadge-month {
  background: var(--text-3);
}

.datebadge--muted .datebadge-month::before,
.datebadge--muted .datebadge-month::after {
  background: color-mix(in oklab, var(--text-3) 50%, black);
}

.datebadge--icon .datebadge-body {
  display: grid;
  place-items: center;
  height: 64px;
  color: var(--text-2);
}

.datebadge--icon .datebadge-body .icon {
  width: 30px;
  height: 30px;
}

.datebadge--lg.datebadge--icon .datebadge-body {
  height: 88px;
}

.datebadge--lg.datebadge--icon .datebadge-body .icon {
  width: 40px;
  height: 40px;
}

.seal {
  position: absolute;
  right: -12px;
  bottom: -12px;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  color: #ffffff;
  background: var(--success-fill);
  box-shadow: 0 0 0 4px var(--surface);
}

.seal .icon {
  width: 20px;
  height: 20px;
  stroke-width: 2.4;
}

.seal--warn {
  background: var(--warn-fill);
}

/* ---------- Booking summary ("ticket") ---------- */

.ticket {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-5);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
}

/* The time names its full date and zone, so it uses body size to keep the zone on one line. */
.ticket-time {
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}

.ticket-date {
  font-size: var(--text-sm);
  color: var(--text-2);
  overflow-wrap: anywhere;
}

.ticket-facts {
  grid-column: 1 / -1;
  display: grid;
  gap: var(--space-2);
  padding-top: var(--space-4);
  border-top: 1px dashed var(--line-strong);
  list-style: none;
  font-size: var(--text-sm);
  color: var(--text-2);
}

.ticket-facts li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  min-width: 0;
  overflow-wrap: anywhere;
}

.ticket-facts .icon {
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--text-3);
}

.old-time {
  color: var(--text-3);
  text-decoration: line-through;
}

/* ---------- Facts and people (confirmation) ---------- */

.facts {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  gap: var(--space-4);
}

.facts dt {
  padding-top: 1px;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-3);
}

.facts dd {
  min-width: 0;
  color: var(--text);
  overflow-wrap: anywhere;
}

/* Answers to the host's own questions can have long labels, so they stack above the value. */
.facts--stacked {
  grid-template-columns: minmax(0, 1fr);
  gap: 2px;
}

.facts--stacked dd + dt {
  margin-top: var(--space-4);
}

.sub {
  display: block;
  font-size: var(--text-sm);
  color: var(--text-2);
}

.sub--quiet {
  color: var(--text-3);
}

/* A call link or meeting address opens from the facts, so it keeps the link color. */
.sub--link {
  color: var(--accent-ink);
  overflow-wrap: anywhere;
}

/* The proposed time in a reschedule review, under the struck-through current one. */
.new-time {
  font-weight: var(--weight-semibold);
}

.plain-list {
  display: grid;
  gap: 2px;
  list-style: none;
  padding: 0;
}

/* A message someone wrote: the host's reason or the invitee's notes. */
.quote {
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid var(--line-strong);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--surface-2);
  color: var(--text);
  overflow-wrap: anywhere;
}

.people {
  display: grid;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
}

.person {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  min-width: 0;
}

.person-name {
  min-width: 0;
  overflow-wrap: anywhere;
}

.tag {
  display: inline-flex;
  align-items: center;
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--surface-3);
  color: var(--text-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  white-space: nowrap;
}

/* ---------- Status pages ---------- */

/*
  Every status card has the same parts: a hero with the date badge or a status icon, the
  title and one lead line; then sections for the facts, a message, a form or the way
  forward. A card that is only its hero, such as an error, keeps the card's own corners.
*/
.status-hero {
  display: grid;
  justify-items: center;
  gap: var(--space-3);
  padding: var(--space-10) var(--space-8) var(--space-8);
  text-align: center;
  background: linear-gradient(180deg, var(--accent-band) 0%, var(--surface) 100%);
  border-bottom: 1px solid var(--line);
  border-radius: calc(var(--radius-xl) - 1px) calc(var(--radius-xl) - 1px) 0 0;
}

.status-hero:last-child {
  border-bottom: 0;
  border-radius: calc(var(--radius-xl) - 1px);
}

.status-hero .datebadge {
  margin-bottom: var(--space-4);
}

/* The status icon on public steps and states is a little larger than in empty states. */
.shell--status .status-hero .state-icon {
  width: 56px;
  height: 56px;
  margin-bottom: var(--space-2);
  border-radius: 18px;
}

.shell--status .status-hero .state-icon .icon {
  width: 28px;
  height: 28px;
}

.status-title {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  line-height: 1.2;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

.lead {
  max-width: 46ch;
  color: var(--text-2);
  text-wrap: pretty;
  overflow-wrap: anywhere;
}

/* A second fact under the lead, such as the invitee's details having been deleted: smaller
   and quieter than the outcome above it, with its icon before the first line. */
.status-aside {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  max-width: 46ch;
  font-size: var(--text-sm);
  color: var(--text-2);
  text-align: start;
  text-wrap: pretty;
  overflow-wrap: anywhere;
}

.status-aside .icon {
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 0.15em;
  color: var(--text-3);
}

.status-section {
  padding: var(--space-6) var(--space-8);
}

.status-section + .status-section {
  border-top: 1px solid var(--line);
}

/* A notice above the facts, such as the host's deadline, keeps its distance from them. A
   notice that is one sentence reads as text rather than as a heading. */
.shell--status .status-section > .notice > .notice-title:last-child {
  font-weight: var(--weight-regular);
}

.shell--status .status-section > .notice + .notice {
  margin-top: var(--space-2);
}

.shell--status .status-section > .notice + .facts {
  margin-top: var(--space-5);
}

/* Confirm, cancel and approval forms: the optional reason sits above the buttons. */
form.status-section {
  display: grid;
  gap: var(--space-4);
}

form.status-section > .btn {
  justify-self: start;
}

/* A state's one way forward closes the card, centered under its message. */
.status-section--end {
  display: flex;
  justify-content: center;
}

.section-title {
  margin-bottom: var(--space-3);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
}

/* Calendar links share one row of equal buttons; the file link says what it does with its
   download icon. */
.cal-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
}

.cal-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--target);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  line-height: 1.3;
  text-decoration: none;
}

.cal-link:hover {
  border-color: var(--accent-line);
  background: var(--accent-soft);
}

.cal-link .icon {
  width: 18px;
  height: 18px;
  color: var(--text-3);
}

/* The confirmation's seal settles in once, so a new booking reads as done. */
@keyframes seal-in {
  from {
    opacity: 0;
    transform: scale(0.6);
  }
}

.shell--status .seal {
  animation: seal-in 0.3s cubic-bezier(0.2, 0.9, 0.3, 1.25) 0.1s both;
}

/* ---------- Forms ---------- */

.form-intro {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-1) var(--space-3);
  margin-bottom: var(--space-5);
}

.form {
  display: grid;
  gap: var(--space-5);
}

.field {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.label,
.legend {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text);
  overflow-wrap: anywhere;
}

.req {
  margin-left: 2px;
  color: var(--danger-ink);
}

.optional {
  font-weight: var(--weight-regular);
  color: var(--text-3);
}

.hint {
  font-size: var(--text-sm);
  color: var(--text-3);
}

fieldset {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.legend {
  padding: 0;
  margin-bottom: 6px;
}

.legend + .hint {
  margin: -2px 0 var(--space-2);
}

/* Inputs never go below 16 px, so iOS does not zoom into them. */
.input,
.textarea,
.select select {
  width: 100%;
  min-height: var(--target);
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--field-bg);
  color: var(--text);
  font: inherit;
  font-size: 1rem;
  line-height: 1.4;
}

.input::placeholder,
.textarea::placeholder {
  color: var(--text-3);
  opacity: 1;
}

.input:hover,
.textarea:hover,
.select select:hover {
  border-color: var(--text-3);
}

.input:focus-visible,
.textarea:focus-visible,
.select select:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
  border-color: var(--focus);
}

.textarea {
  min-height: 112px;
  resize: vertical;
  line-height: var(--leading);
}

.select {
  position: relative;
}

.select select {
  appearance: none;
  padding-right: 40px;
}

.select .icon {
  position: absolute;
  right: 12px;
  top: 50%;
  width: 18px;
  height: 18px;
  color: var(--text-3);
  translate: 0 -50%;
  pointer-events: none;
}

.field--error .input,
.field--error .textarea,
.field--error .select select,
.field--error .option,
.field--error .check {
  border-color: var(--danger-ink);
}

.error-text {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--danger-ink);
  overflow-wrap: anywhere;
}

.error-text .icon {
  width: 16px;
  height: 16px;
  margin-top: 2px;
}

.check {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  cursor: pointer;
}

.check input,
.option input {
  width: 20px;
  height: 20px;
  margin: 2px 0 0;
  accent-color: var(--accent-fill);
  cursor: pointer;
}

.check-label {
  font-size: var(--text-sm);
  color: var(--text);
  overflow-wrap: anywhere;
}

.options {
  display: grid;
  gap: var(--space-2);
}

/* Location choices: the whole card is the radio's label and draws its focus ring. */
.option {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-3);
  min-height: 60px;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--field-bg);
  cursor: pointer;
}

.option input {
  margin: 0;
}

.option:hover {
  border-color: var(--text-3);
}

.option:has(input:checked) {
  border-color: var(--accent-fill);
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent-fill);
}

.option:has(input:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.option-icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--surface-3);
  color: var(--text-2);
}

.option-title {
  display: block;
  font-weight: var(--weight-semibold);
  overflow-wrap: anywhere;
}

.option-sub {
  display: block;
  font-size: var(--text-sm);
  color: var(--text-3);
}

/* "Add guests" opens the guest field in place. */
.reveal > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--target);
  padding: 0 var(--space-3) 0 var(--space-2);
  margin-left: calc(-1 * var(--space-2));
  border-radius: var(--radius-md);
  color: var(--accent-ink);
  font-weight: var(--weight-semibold);
  font-size: var(--text-sm);
}

.reveal > summary:hover {
  background: var(--accent-soft);
}

.reveal[open] > summary {
  margin-bottom: var(--space-2);
}

.honeypot {
  display: none;
}

.form-notes {
  display: grid;
  gap: var(--space-2);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line);
  font-size: var(--text-sm);
  color: var(--text-2);
}

.form-note {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
}

.form-note .icon {
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--text-3);
}

.form-note .dot {
  color: var(--text-3);
}

.error-summary {
  padding: var(--space-4) var(--space-5);
  border: 1px solid color-mix(in oklab, var(--danger-ink) 35%, transparent);
  border-radius: var(--radius-lg);
  background: var(--danger-soft);
}

.error-summary-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  color: var(--danger-ink);
}

.error-summary ul {
  margin-top: var(--space-2);
  padding-left: calc(20px + var(--space-2));
  font-size: var(--text-sm);
  color: var(--danger-ink);
}

.error-summary a {
  color: var(--danger-ink);
  font-weight: var(--weight-medium);
}

/* The label that names which question a generic message belongs to. */
.error-summary-field {
  font-weight: var(--weight-bold);
}

/* The time was taken between the picker and the form. */
.alert {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-5);
  border: 1px solid color-mix(in oklab, var(--warn-ink) 30%, transparent);
  border-radius: var(--radius-lg);
  background: var(--warn-soft);
}

.alert-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
}

.alert-title .icon {
  color: var(--warn-ink);
}

.alert-body {
  color: var(--text-2);
  overflow-wrap: anywhere;
}

.alert .link {
  justify-self: start;
}

/* Other free times after the chosen one was taken. They are the form's own start choices,
   so the details typed so far go with whichever time is booked. */
.pick-field {
  margin: var(--space-1) 0 0;
  padding: 0;
  border: 0;
}

.pick-slots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: var(--space-2);
}

.pick-slot {
  position: relative;
}

.pick-slot input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

.pick-slot span {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--target);
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--accent-ink);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

.pick-slot input:checked + span {
  background: var(--accent-fill);
  border-color: var(--accent-fill);
  color: var(--on-fill);
}

.pick-slot input:focus-visible + span {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* ---------- Details step layout ---------- */

.summary-pane-inner {
  display: grid;
  gap: var(--space-3);
}

.summary-pane-inner > .link {
  justify-self: start;
}

.form-pane {
  max-width: 680px;
}

/* ---------- Profile ---------- */

.profile-head {
  display: grid;
  justify-items: center;
  gap: var(--space-3);
  padding: var(--space-6) 0 var(--space-8);
  text-align: center;
}

.profile-head .avatar {
  width: 96px;
  height: 96px;
  margin-bottom: var(--space-1);
}

.profile-name {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  line-height: 1.2;
  letter-spacing: -0.015em;
  overflow-wrap: anywhere;
  text-wrap: balance;
}

.page-cards {
  display: grid;
  gap: var(--space-4);
  list-style: none;
  padding: 0;
}

.page-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-6);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  transition: border-color 0.15s ease;
}

.page-card:hover {
  border-color: var(--accent-line);
}

.page-card:has(.page-card-action:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.page-card-head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}

.page-card-title {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: -0.01em;
  overflow-wrap: anywhere;
}

.page-card .meta {
  gap: var(--space-1) var(--space-4);
}

.page-card .meta > li {
  min-height: 24px;
}

/* The description is shortened to three lines; the page itself shows it in full. */
.page-card-desc {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  font-size: var(--text-sm);
  color: var(--text-2);
}

.page-card-desc > * + * {
  margin-top: 0.35em;
}

/* Links in the description stay above the card-wide action link, so they still open. */
.page-card-desc a {
  position: relative;
  z-index: 1;
}

/* The card ends on its one action, so cards in a row line up at the bottom. */
.page-card-foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-top: auto;
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
}

/* The weekly days and booking window read as one more page fact, under the others. */
.page-card-when {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  min-width: 0;
  font-size: var(--text-sm);
  color: var(--text-2);
  overflow-wrap: anywhere;
}

.page-card-when .icon {
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--text-3);
}

.page-card-action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  font-weight: var(--weight-semibold);
  text-decoration: none;
  white-space: nowrap;
}

.page-card-action:focus-visible {
  outline: none;
}

/* The action link covers the whole card, so the card is one click target. */
.page-card-action::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.page-card-action .icon {
  width: 16px;
  height: 16px;
  transition: transform 0.15s ease;
}

.page-card:hover .page-card-action .icon {
  transform: translateX(2px);
}

/* ---------- Error pages ---------- */

.error-card {
  display: grid;
  justify-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-10) var(--space-8);
  text-align: center;
}

.error-card .datebadge {
  margin-bottom: var(--space-3);
}

.error-title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  line-height: 1.25;
  letter-spacing: -0.01em;
  text-wrap: balance;
  overflow-wrap: anywhere;
}

/* ---------- Tablet and up ---------- */

@media (min-width: 640px) {
  :root {
    --gutter: 24px;
  }

  .profile-head {
    padding-top: var(--space-10);
  }
}

@media (min-width: 720px) {
  .booker-body--picker {
    grid-template-columns: minmax(300px, 392px) minmax(0, 1fr);
  }

  .booker-body--picker > .cal-pane {
    border-right: 1px solid var(--line);
  }

  /* The month stays in view while the times scroll. */
  .cal-pane-inner {
    position: sticky;
    top: var(--space-6);
  }

  .page-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .page-cards--single {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (min-width: 880px) {
  .booker-body--details {
    grid-template-columns: minmax(280px, 340px) minmax(0, 1fr);
  }

  .booker-body--details > .summary-pane {
    padding-left: var(--space-6);
    padding-right: var(--space-6);
    border-right: 1px solid var(--line);
  }

  .summary-pane-inner {
    position: sticky;
    top: var(--space-6);
  }
}

@media (min-width: 1024px) {
  :root {
    --gutter: 32px;
  }

  .shell {
    padding-top: var(--space-8);
  }
}

@media (min-width: 640px) and (max-width: 1023px) {
  .pane,
  .booker-head {
    padding-left: var(--space-6);
    padding-right: var(--space-6);
  }
}

/* ---------- Phones ---------- */

@media (max-width: 639px) {
  .shell--flush {
    padding: 0;
  }

  .shell--flush > .preview-banner {
    margin: var(--space-4) var(--gutter);
  }

  .booker,
  .status-card {
    border-left: 0;
    border-right: 0;
    border-radius: 0;
    box-shadow: none;
  }

  .booker-head,
  .status-hero,
  .status-hero:last-child {
    border-radius: 0;
  }

  .booker-head {
    column-gap: var(--space-3);
    padding: var(--space-5) var(--gutter);
  }

  /* On phones the notices and page facts use the full width, below the photo too. */
  .booker-head:has(> .avatar) > .notice,
  .booker-head:has(> .avatar) > .meta,
  .booker-head:has(> .avatar) > .description,
  .booker-head:has(> .avatar) > .band-note {
    grid-column: 1 / -1;
  }

  /* The band's photo shrinks; the profile's photo keeps its size through its own rule. */
  .avatar {
    width: 48px;
    height: 48px;
  }

  .page-title {
    font-size: var(--text-lg);
  }

  .pane {
    padding: var(--space-5) var(--gutter) var(--space-6);
  }

  .pane + .pane {
    border-top: 1px solid var(--line);
  }

  .status-hero {
    padding: var(--space-8) var(--gutter) var(--space-6);
  }

  .status-section {
    padding: var(--space-5) var(--gutter);
  }

  .error-card {
    padding: var(--space-8) var(--space-5);
  }

  .status-title {
    font-size: var(--text-lg);
  }

  /* Touch targets are at least 44 px on phones. */
  .control,
  .icon-btn,
  .btn-sm,
  .seg button,
  .choice-list button,
  .tz-list button,
  .link,
  .page-card-action,
  .site-foot a {
    min-height: var(--target);
  }

  .icon-btn {
    width: var(--target);
    height: var(--target);
  }

  /* A link's words sit in one element, so they wrap as one line of text in this box. */
  .error-summary a {
    display: inline-flex;
    align-items: center;
    min-height: var(--target);
  }

  /* The settings button shows only its icon; its text stays as the accessible name. */
  .menu-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .settings > .control {
    width: var(--target);
    justify-content: center;
    padding: 0;
  }

  .settings > .control .chev {
    display: none;
  }

  .times-tools {
    width: 100%;
  }

  .tz {
    flex: 1;
    min-width: 0;
  }

  .tz > .control {
    width: 100%;
  }

  .tz > .control .chev {
    margin-left: auto;
  }

  /* On phones the time zone list opens in place instead of floating. */
  .tz .popover {
    position: static;
    width: auto;
    max-width: none;
    margin-top: var(--space-2);
    box-shadow: none;
  }

  .slots,
  .pick-slots {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .actions > .btn,
  .status-section--end > .btn {
    flex: 1 1 100%;
  }

  /* On phones each calendar link takes its own full-width row. */
  .cal-links > li {
    flex: 1 1 100%;
  }

  .cal-link {
    width: 100%;
  }

  .facts {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
  }

  .facts dd + dt {
    margin-top: var(--space-4);
  }

  .page-card {
    padding: var(--space-5);
  }
}

/* ---------- Refinements: template hooks ---------- */

/*
  The hooks the picker and the booking form carry for the refined look (design/2a/): the
  duration pane, the form's field groups and the summary's label. These rules come after the
  components and breakpoints above, so they win where both set a property; preferences,
  forced colors and print still come last.
*/
.day-count { display: none; }
.booker-body--picker > .duration-pane { grid-column: 1 / -1; }
.duration-pane { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); padding-bottom: 0; }
.duration-pane .pane-title { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--text-2); letter-spacing: 0; }
.seg--durations button { min-height: 34px; padding: 0 var(--space-4); }
.summary-title { margin-bottom: var(--space-1); font-size: var(--text-xs); font-weight: var(--weight-semibold); text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-3); }
.form-group { display: grid; gap: var(--space-5); min-width: 0; }
.form > .form-group + .form-group { padding-top: var(--space-6); box-shadow: inset 0 1px 0 var(--line); }
fieldset.form-group { display: block; }
fieldset.form-group > .legend { float: left; width: 100%; }
fieldset.form-group > .legend + * { clear: both; }
fieldset.form-group > .hint { margin: 0 0 var(--space-3); }
.times-tools > .seg { flex: none; flex-wrap: nowrap; }
.prose > .more { margin-top: 0.25em; }
/* The list reset ul[role="list"] outranks .ticket-facts, so its padding is restated here to
   keep the perforation clear of the first fact. */
.ticket .ticket-facts { padding-top: var(--space-4); }
/* A soft halo joins the focus ring on fields; the 2 px ring stays for contrast. */
.input:focus-visible, .textarea:focus-visible, .select select:focus-visible { box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent-fill) 18%, transparent); }
@media (max-width: 639px) {
  /* Even padding above and below, so the switch never sits on the rule under it. */
  .duration-pane { padding-block: var(--space-5); }
  .seg--durations { display: flex; width: 100%; }
  .seg--durations button { flex: 1; min-height: var(--target); }
}
/* Beside the pane's heading the switch keeps its own width; it keeps the segmented control's
   wrapping, so lengths that don't fit one row go onto more rows inside the card. */
@media (min-width: 640px) {
  .seg--durations { flex: none; }
}

/* ---------- Refinements: polish ---------- */

/*
  The pages' look, refined (design/2a/, "Polished"): page facts as soft chips, the duration as
  a pill switch on its own row, round days without shadows and a small dot for today, times as
  pills three across, a tinted ticket, the date on a square calendar leaf, and on the
  confirmation each label sitting right on its answer. The default accent, BusyCal blue, is
  set with the tokens at the top of this file.
*/
:root { --radius-day: 999px; }
body { background: radial-gradient(120% 360px at 50% -160px, var(--accent-wash), transparent 70%) no-repeat, var(--bg); }

/* Header: lighter band, facts as soft chips */
.booker-head { background: linear-gradient(180deg, var(--accent-band) 0%, var(--surface) 72%); row-gap: var(--space-3); }
.page-title { letter-spacing: -0.02em; }
.meta { gap: var(--space-2); }
.meta > li { min-height: 30px; padding: 0 var(--space-3) 0 10px; border-radius: var(--radius-full); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); color: var(--text-2); font-weight: var(--weight-medium); }
.meta .icon { width: 16px; height: 16px; }
.description { margin-top: var(--space-1); }

/* Duration: a pill switch on its own row. A page may offer eight lengths, and some languages
   name them at length, so the switch wraps onto more rows when they don't fit one. Its
   corners are concentric with the pills inside (half a pill's height plus the track's 4 px
   inset), so one row reads as a pill and several rows as a rounded tray, never an oval. */
.seg--durations { border-radius: calc(34px / 2 + 4px); }
.seg--durations button { border-radius: var(--radius-full); }

/* Month: round days, the chosen one without a shadow; counts give way to a calmer grid */
.cal-head { margin-top: var(--space-3); }
.month th { font-weight: var(--weight-medium); letter-spacing: 0.04em; }
.month td { padding: 3px 2px; }
.day { max-width: 44px; border-radius: var(--radius-day); font-size: 0.9375rem; transition: background-color 0.12s ease, transform 0.12s ease; }
.day-dots { display: none; }
.day--open { font-weight: var(--weight-semibold); }
.day[data-today="true"]::after { content: ""; position: absolute; left: 50%; bottom: 5px; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: currentColor; }
/* The legend's keys stand for days, so they are round too. */
.cal-legend i { border-radius: 50%; }

/* Times: pills, three across */
.times-head { border-bottom: 0; padding-bottom: 0; }
.slot-group { margin-top: var(--space-6); }
.slot-group-title { font-weight: var(--weight-medium); letter-spacing: 0.05em; }
.slot-group-title::after { display: none; }
.slots { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.slot { min-height: 46px; border-radius: var(--radius-full); font-weight: var(--weight-semibold); }
/* The other times offered after a time was taken are pills like the times they stand in for. */
.pick-slot span { border-radius: var(--radius-full); }

/* Details: a tinted ticket, roomier groups, one clear primary action */
.ticket { background: var(--accent-band); border-color: color-mix(in oklab, var(--accent-line) 60%, var(--line)); }
.form-intro .pane-title { font-size: var(--text-lg); letter-spacing: -0.015em; }
.option { border-radius: var(--radius-lg); }
.option-icon { border-radius: 12px; background: var(--accent-soft); color: var(--accent-ink); }
.check { border-radius: var(--radius-lg); }
.form-notes { border-top: 0; padding-top: 0; }
/* Only the booking form's own button widens; other action rows keep their buttons' widths. */
.booker--details .actions .btn-primary { min-width: min(100%, 240px); }

/* Date badge: a square calendar leaf. The weekday is already in the date beside it. */
.datebadge { --badge-w: 56px; border-radius: 12px; }
.datebadge-month { padding: 8px 0 2px; border-radius: 12px 12px 0 0; font-size: 0.625rem; letter-spacing: 0.1em; }
.datebadge-month::before, .datebadge-month::after { top: 3px; width: 4px; height: 4px; }
.datebadge-day { padding: 5px 0 9px; font-size: 1.5rem; }
.datebadge-weekday { display: none; }
.datebadge--lg { --badge-w: 84px; border-radius: 18px; }
.datebadge--lg .datebadge-month { padding: 11px 0 4px; border-radius: 18px 18px 0 0; font-size: 0.75rem; }
.datebadge--lg .datebadge-month::before, .datebadge--lg .datebadge-month::after { top: 4px; width: 5px; height: 5px; }
.datebadge--lg .datebadge-day { padding: 8px 0 14px; font-size: 2.25rem; }
.datebadge--lg .seal { right: -10px; bottom: -10px; width: 32px; height: 32px; }
.datebadge--lg .seal .icon { width: 18px; height: 18px; }
/* An icon in the day's place keeps the leaf the day's size, so it stays square. */
.datebadge--icon .datebadge-body { height: 38px; }
.datebadge--icon .datebadge-body .icon { width: 24px; height: 24px; }
.datebadge--lg.datebadge--icon .datebadge-body { height: 58px; }
.datebadge--lg.datebadge--icon .datebadge-body .icon { width: 32px; height: 32px; }

/* Confirmation */
.status-hero .datebadge { margin-bottom: var(--space-4); }
.cal-links { display: grid; grid-template-columns: repeat(auto-fit, minmax(172px, 1fr)); }
.cal-link { justify-content: flex-start; border-color: var(--line); background: var(--surface-2); }
/* Facts: a bold label sits right on its answer; groups are spaced and ruled apart.
   Three levels: the answer in semibold ink, its details in secondary text, asides quieter. */
.facts { grid-template-columns: minmax(0, 1fr); gap: 0; }
.facts dt { padding-top: 0; font-size: 0.75rem; font-weight: var(--weight-semibold); letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-2); }
.facts dd { margin-top: 4px; font-size: 1.0625rem; font-weight: var(--weight-semibold); line-height: 1.4; color: var(--text); }
.facts dd + dt { margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--line); }
.facts .sub { margin-top: 2px; font-size: var(--text-sm); font-weight: var(--weight-regular); color: var(--text-2); }
.facts .sub--quiet { font-size: 0.8125rem; color: var(--text-3); }
/* A call link or meeting address opens from the facts, so it keeps the link color. */
.facts .sub--link { color: var(--accent-ink); }
.facts .people { gap: var(--space-1); margin-top: 2px; }
.facts .person-name { font-size: var(--text-base); font-weight: var(--weight-medium); }

/* Profile */
.page-card { border-radius: var(--radius-xl); }
.page-card-title { font-size: 1.1875rem; }
.page-card-foot { border-top: 0; padding-top: 0; }
.page-card-action { padding: 0 var(--space-4); border-radius: var(--radius-full); background: var(--accent-soft); }
.page-card:hover .page-card-action { background: var(--accent-fill); color: var(--on-fill); }

@media (min-width: 720px) {
  .duration-pane { padding-top: var(--space-5); }
}
@media (max-width: 639px) {
  .slots { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Phone pills are a touch target high, so the track's corners follow them. */
  .seg--durations { border-radius: calc(var(--target) / 2 + 4px); }
}
@media (max-width: 359px) {
  .slots { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------- Preferences ---------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none !important;
    animation: none !important;
  }
}

/* Windows high contrast: outlines on tiles, times and choices; system highlight on the day. */
@media (forced-colors: active) {
  .day--open,
  .slot,
  .pick-slot span,
  .option,
  .check,
  .cal-link,
  .seg button[aria-current],
  .choice-list button[aria-current] {
    border: 1px solid CanvasText;
  }

  .day[aria-current],
  .pick-slot input:checked + span {
    forced-color-adjust: none;
    background: Highlight;
    color: HighlightText;
  }
}

@media print {
  body {
    background: none;
  }

  .site-foot,
  .skip-link,
  .settings,
  .actions,
  .cal-links {
    display: none;
  }

  .status-card,
  .booker {
    border: 0;
    box-shadow: none;
  }
}
