:root {
  color-scheme: dark;
  --bg-app: #0b0d10;
  --bg-panel: #13161b;
  --bg-panel-hi: #181c22;
  --border: rgba(255, 255, 255, 0.06);
  --border-strong: rgba(255, 255, 255, 0.12);
  --text: #e6e9ef;
  --text-dim: #8a93a3;
  --text-muted: #5b6371;
  --accent: #4ea1ff;
  --accent-dim: #2a3340;
  --accent-2: #9b6bff;
  --accent-glow: rgba(78, 161, 255, 0.30);
  --accent-haze: rgba(78, 161, 255, 0.16);
  --pos: #22c55e;
  --pos-bg: rgba(34, 197, 94, 0.10);
  --popular: #f59e0b;
  --popular-bg: rgba(245, 158, 11, 0.16);
  --shadow-overlay: 0 10px 40px rgba(0, 0, 0, 0.6);

  --font-sans: 'Inter', -apple-system, 'Segoe UI', system-ui, sans-serif;
}

:root[data-theme="light"] {
  color-scheme: light;
  --bg-app: #f4f5f8;
  --bg-panel: #ffffff;
  --bg-panel-hi: #f7f8fb;
  --border: rgba(0, 0, 0, 0.08);
  --border-strong: rgba(0, 0, 0, 0.14);
  --text: #1a1d23;
  --text-dim: #5b6371;
  --text-muted: #9aa3b2;
  --accent: #2563eb;
  --accent-dim: #dbeafe;
  --accent-2: #7c3aed;
  --accent-glow: rgba(37, 99, 235, 0.22);
  --accent-haze: rgba(37, 99, 235, 0.12);
  --pos: #16a34a;
  --pos-bg: rgba(22, 163, 74, 0.10);
  --popular: #d97706;
  --popular-bg: rgba(217, 119, 6, 0.14);
  --shadow-overlay: 0 10px 40px rgba(15, 23, 42, 0.18);
}

* { box-sizing: border-box; }

/* iOS Safari auto-zooms the page on focusing any input/textarea/select whose
   computed font-size is under 16px. Keep this at 16px+ regardless of what
   individual components set, so new form fields can't reintroduce the zoom-in bug. */
input, textarea, select { font-size: 16px; }

/* Autofilled values were invisible until the field was focused: with no
   color-scheme declared the browser assumed a light page and painted its
   autofill overlay in near-black on our dark inputs. color-scheme (in :root
   above) fixes the assumption; these rules keep the site's own colors even
   when the UA forces its autofill background — the inset shadow covers the
   forced background and the huge transition delay stops it ever painting. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--text);
  -webkit-box-shadow: 0 0 0 1000px var(--bg-panel-hi) inset;
  caret-color: var(--text);
  transition: background-color 9999999s ease-in-out 0s;
}
input:autofill {
  -webkit-text-fill-color: var(--text);
  box-shadow: 0 0 0 1000px var(--bg-panel-hi) inset;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg-app);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

.app {
  display: grid;
  gap: 16px;
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

/* ═══════════════ App shell: left nav (sidebar.tpl.php) ═══════════════
   Modeled on chores.vertwo.com's left-nav shell. Only rendered when
   $showSidebar is set (organiser-facing pages) — public respondent pages
   and guest routes get none of this.
   Three independent pieces rather than one responsive component:
     .sidebar     — fixed left column, desktop only (≥ 960px)
     .mobile-nav  — horizontal link strip, mobile only (< 960px)
     .utility-bar — theme-toggle + sign-out, a small fixed corner control
                    shown at every size, so neither of the two above needs
                    its own copy (avoids duplicate #theme-toggle/#logout-btn
                    ids on the same page). */
.sidebar {
  display: none;
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: 220px;
  background: var(--bg-panel);
  border-right: 1px solid var(--border);
  flex-direction: column;
  z-index: 50;
}
.sidebar-logo {
  padding: 18px 20px;
  border-bottom: 1px solid var(--border);
}
.sidebar-logo .logo-label {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
}
.sidebar-nav {
  flex: 1;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
}
.sidebar-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-radius: 8px;
  color: var(--text-dim);
  font-size: 13.5px;
  font-weight: 500;
  text-decoration: none;
  transition: background-color 0.12s ease, color 0.12s ease;
}
.sidebar-item svg { width: 17px; height: 17px; flex-shrink: 0; }
.sidebar-item:hover { background: var(--bg-panel-hi); color: var(--text); }
.sidebar-item.active { background: var(--accent-haze); color: var(--accent); }

.mobile-nav {
  display: flex;
  overflow-x: auto;
  gap: 4px;
  padding: 8px 10px;
  background: var(--bg-panel);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 90;
}
.mobile-nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 6px 12px;
  border-radius: 8px;
  color: var(--text-dim);
  font-size: 10.5px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  flex-shrink: 0;
}
.mobile-nav-item svg { width: 18px; height: 18px; }
.mobile-nav-item.active { color: var(--accent); background: var(--accent-haze); }

.utility-bar {
  position: fixed;
  bottom: 16px;
  right: 16px;
  z-index: 200;
  display: flex;
  gap: 8px;
}
.utility-bar .icon-btn {
  background: var(--bg-panel);
  box-shadow: var(--shadow-overlay);
}

@media (min-width: 960px) {
  .sidebar { display: flex; }
  .mobile-nav { display: none; }
  .app-main { margin-left: 220px; }
}

/* ─────────── header ─────────── */
.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.brand {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.brand h1 {
  font-size: 18px;
  font-weight: 700;
  margin: 0;
  letter-spacing: -0.01em;
}
.brand .dot { color: var(--text-muted); }
.brand .sub { color: var(--text-dim); font-size: 14px; }

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg-panel);
  color: var(--text-dim);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.icon-btn[hidden] { display: none; }
.icon-btn svg { width: 17px; height: 17px; }
.icon-btn:hover {
  color: var(--text);
  background: var(--bg-panel-hi);
  border-color: var(--border-strong);
  transform: translateY(-1px);
}

/* ─────────── shared panel ─────────── */
.panel {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 20px;
}
.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.panel-header h2 {
  font-size: 15px;
  font-weight: 600;
  margin: 0;
}

/* ─────────── event card ─────────── */
.event-card {
  display: flex;
  gap: 24px;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
}
.event-card[hidden] { display: none; }
.event-main { max-width: 640px; }
.event-eyebrow {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin-bottom: 6px;
}
.event-title {
  font-size: 22px;
  font-weight: 700;
  margin: 0 0 8px;
  letter-spacing: -0.01em;
}
.event-desc {
  color: var(--text-dim);
  margin: 0 0 14px;
  font-size: 14px;
}
.event-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.meta-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text-dim);
  background: var(--bg-panel-hi);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 10px;
}
.meta-chip svg { width: 13px; height: 13px; opacity: 0.8; }

.event-name-input {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 220px;
}
.form-field-compact {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.event-name-input label {
  font-size: 12px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.event-name-input input {
  background: var(--bg-panel-hi);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  padding: 9px 12px;
  color: var(--text);
  font-size: 16px;
  font-family: var(--font-sans);
}
.event-name-input input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-haze);
}

/* ─────────── layout ─────────── */
.layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 16px;
  align-items: start;
}
.layout[hidden] { display: none; } /* .layout sets display:grid unconditionally — see the recurring [hidden]-vs-author-display gotcha noted elsewhere in this project */
@media (max-width: 860px) {
  .layout { grid-template-columns: 1fr; }
}

/* Jump link from the bottom of the dashboard's calendar down to the
 * appointments panel — only useful once .layout above has stacked them,
 * so hidden by default and shown at the same breakpoint. */
.mobile-scroll-hint {
  display: none;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  text-decoration: none;
  padding: 12px 0 2px;
}
.mobile-scroll-hint:hover { color: var(--accent-2); }
@media (max-width: 860px) {
  .mobile-scroll-hint { display: block; }
}

/* ─────────── legend ─────────── */
.legend {
  display: flex;
  gap: 14px;
  font-size: 12.5px;
  color: var(--text-dim);
}
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.swatch {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  display: inline-block;
}
.swatch-selected { background: var(--accent); }
.swatch-popular { background: var(--popular-bg); border: 1px solid var(--popular); }
.swatch-confirmed { background: var(--accent-haze); border: 1px solid var(--accent); }
.swatch-pending { background: rgba(245, 158, 11, 0.14); border: 1px dashed rgba(245, 158, 11, 0.6); }

/* ─────────── calendar toolbar ─────────── */
.calendar-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
  flex-wrap: wrap;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 10px;
}
.cal-nav {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--bg-panel-hi);
  color: var(--text);
  font-size: 16px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.cal-nav:hover {
  background: var(--accent-haze);
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-1px);
}
.cal-range {
  flex: 1 1 auto;
  text-align: center;
  font-weight: 600;
  font-size: 14px;
  min-width: 140px;
}
.cal-actions {
  display: flex;
  gap: 8px;
}
.btn-ghost {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 8px;
  padding: 7px 12px;
  font-size: 12.5px;
  cursor: pointer;
  font-family: var(--font-sans);
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.btn-ghost:hover {
  color: var(--text);
  background: var(--bg-panel-hi);
  border-color: var(--border-strong);
  transform: translateY(-1px);
}

/* ─────────── calendar grid ─────────── */
.calendar-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}
@media (max-width: 640px) {
  .calendar-grid { grid-template-columns: 1fr; }
}

/* booking-appointment page shows one month at a time (unlike the poll
   pages' two-month .calendar-grid, left as-is) — scoped by ancestor rather
   than a shared class so this doesn't affect event.tpl.php/home.tpl.php's
   drag-select calendars. */
#booking-app .calendar-grid {
  grid-template-columns: 1fr;
  max-width: 380px;
  margin: 0 auto;
}

/* booking-appointment page shows the calendar OR the times for the picked
   date, never both — so #booking-layout is a single centered column
   rather than the shared .layout's calendar+sidebar side-by-side grid. */
#booking-layout {
  grid-template-columns: 1fr;
  max-width: 460px;
  margin: 0 auto;
}

/* The two caps above were fixed at a phone-sized width unconditionally, so
   picking a slot felt like the mobile layout even on a full desktop screen.
   Past the same 640px breakpoint the rest of the app uses for mobile/desktop,
   drop the cap on #booking-layout so it matches #booking-content's own width
   — that element sets no width of its own, so it (and the event-card panels
   above the calendar) simply fill #booking-app's natural width; the times
   panel now does the same instead of being narrower than everything else on
   the page.
   The calendar itself keeps a real cap (640px, matching the size it renders
   at in booking-form-v2.html) rather than also stretching full-width —
   .day-cell's aspect-ratio:1 means an unbounded-width grid makes every cell
   much *taller* too (a previous fix fought this with aspect-ratio:unset +
   a fixed height, but that made cells short rectangles instead of the
   squares the static concept has — reverted in favour of just bounding the
   grid's width, which keeps real squares at a sensible size). The calendar
   panel around it stays full-width regardless — the grid just doesn't fill
   every last pixel of it, same as the mockup's own layout. */
@media (min-width: 641px) {
  #booking-app .calendar-grid { max-width: 640px; }
  #booking-layout { max-width: none; }
}

/* recurring-booking request fields */
.recurring-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  margin-top: 4px;
}
.recurring-toggle input { width: 15px; height: 15px; accent-color: var(--accent); }
.recurring-fields-row {
  display: flex;
  gap: 10px;
  margin-top: 8px;
}
.recurring-fields-row[hidden] { display: none; }

.month {
  user-select: none;
}
.month-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-dim);
  margin-bottom: 8px;
  text-align: center;
}
.weekday-row {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  margin-bottom: 4px;
}
.weekday-row span {
  text-align: center;
  font-size: 11px;
  color: var(--text-muted);
  padding: 4px 0;
}
.days-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 3px;
}
.day-cell {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  font-size: 13px;
  cursor: pointer;
  position: relative;
  color: var(--text);
  border: 1px solid transparent;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.1s ease;
}
.day-cell.outside {
  visibility: hidden;
  cursor: default;
}
.day-cell.past,
.day-cell.unavailable {
  color: var(--text-muted);
  cursor: not-allowed;
  opacity: 0.5;
}
.day-cell:not(.outside):not(.past):not(.unavailable):not(.selected):hover {
  background: var(--bg-panel-hi);
  border-color: var(--border-strong);
  transform: scale(1.08);
}
.day-cell.popular:not(.selected) {
  background: var(--popular-bg);
  border-color: var(--popular);
}
.day-cell.selected {
  background: var(--accent);
  color: #fff;
  font-weight: 600;
}
.day-cell.selected:hover {
  background: var(--bg-panel);
  color: var(--accent);
  border-color: var(--accent);
  transform: scale(1.08);
}
.day-cell.today:not(.selected) {
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}
.day-cell .dot-count {
  position: absolute;
  bottom: 3px;
  font-size: 8px;
  font-weight: 700;
  color: var(--popular);
}
.day-cell.selected .dot-count { color: rgba(255,255,255,0.85); }
.day-cell.selected:hover .dot-count { color: var(--popular); }

.cal-hint {
  margin: 14px 0 0;
  font-size: 12px;
  color: var(--text-muted);
}

/* ─────────── sidebar ─────────── */
.sidebar-panel { position: sticky; top: 20px; }
.count-badge {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-haze);
  border-radius: 999px;
  padding: 3px 10px;
}
.selected-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 32px;
}
.empty-hint {
  font-size: 13px;
  color: var(--text-muted);
  margin: 0;
}
.date-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--accent-haze);
  color: var(--accent);
  border: 1px solid var(--accent-glow);
  border-radius: 999px;
  padding: 5px 6px 5px 12px;
  font-size: 12.5px;
  font-weight: 500;
}
.date-chip button {
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0.7;
  transition: opacity 0.15s ease, background-color 0.15s ease, transform 0.15s ease;
}
.date-chip button:hover {
  opacity: 1;
  background: rgba(255,255,255,0.22);
  transform: scale(1.15);
}

.divider {
  height: 1px;
  background: var(--border);
  margin: 20px 0;
}

.respondent-list {
  list-style: none;
  margin: 0 0 20px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.respondent-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13.5px;
  color: var(--text);
}
.respondent-list li.pending { color: var(--text-muted); }
.avatar {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  flex-shrink: 0;
}
.avatar-pending {
  background: var(--bg-panel-hi);
  border: 1px dashed var(--border-strong);
  color: var(--text-muted);
}

.btn-primary {
  width: 100%;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 12px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: var(--font-sans);
  transition: filter 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.btn-primary:hover {
  filter: brightness(1.1);
  transform: translateY(-1px);
  box-shadow: 0 6px 18px var(--accent-glow);
}
.submit-hint {
  text-align: center;
  font-size: 11.5px;
  color: var(--text-muted);
  margin: 8px 0 0;
}

/* ─────────── auth pages (login / register / reset / etc.) ─────────── */
.auth-wrap {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 20px;
  position: relative;
}
.auth-theme-toggle {
  position: absolute;
  top: 20px;
  right: 20px;
}
.auth-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 32px;
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  box-shadow: var(--shadow-overlay);
}
.auth-card[hidden] {
  display: none;
}
.auth-brand {
  display: flex;
  justify-content: center;
  margin-bottom: 4px;
}
.auth-brand .brand-title {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.auth-card h1 {
  font-size: 19px;
  font-weight: 700;
  margin: 0;
  text-align: center;
  letter-spacing: -0.01em;
}
.auth-sub {
  color: var(--text-dim);
  font-size: 13.5px;
  text-align: center;
  margin: -4px 0 4px;
}
.auth-card label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text-dim);
  font-weight: 500;
}
.auth-card label .hint {
  color: var(--text-muted);
  font-weight: 400;
}
.auth-card input[type="text"],
.auth-card input[type="email"],
.auth-card input[type="password"],
.auth-card textarea {
  background: var(--bg-panel-hi);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  padding: 9px 12px;
  color: var(--text);
  font-size: 16px;
  font-family: var(--font-sans);
}
.auth-card input:focus,
.auth-card textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-haze);
}
.auth-remember {
  flex-direction: row !important;
  align-items: center;
  gap: 8px !important;
}
.auth-remember input {
  width: 15px;
  height: 15px;
  accent-color: var(--accent);
}
.auth-error {
  color: #ef4444;
  font-size: 12.5px;
  text-align: center;
  margin: 0;
}
.auth-note {
  color: var(--pos);
  font-size: 12.5px;
  text-align: center;
  margin: 0;
}
.auth-alt {
  text-align: center;
  font-size: 12.5px;
  color: var(--text-dim);
  margin: 0;
}
.auth-alt a {
  color: var(--accent);
  text-decoration: none;
}
.auth-alt a:hover { text-decoration: underline; }
.auth-alt .dot { color: var(--text-muted); margin: 0 6px; }

/* ─────────── generic form field (dashboard forms) ─────────── */
.form-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text-dim);
  font-weight: 500;
}
/* .form-field sets display unconditionally — first time it's been paired
   with a hidden attribute (#ce-emoji-field), same recurring gotcha this
   project has hit with .auth-card/.modal-backdrop/.layout/.event-card/
   .icon-btn/#business-rename-form before: [hidden]'s default display:none
   silently loses to any author rule that sets display, regardless of
   specificity. Caught proactively this time. */
.form-field[hidden] { display: none; }
.form-field .hint { color: var(--text-muted); font-weight: 400; }

/* Booking event colour-scheme accent emoji picker (create/edit modals) */
.emoji-picker { display: flex; flex-wrap: wrap; gap: 4px; }
.emoji-picker button {
  appearance: none; border: 1px solid var(--border); background: var(--bg-panel-hi);
  font-size: 16px; line-height: 1; padding: 6px 9px; border-radius: 999px; cursor: pointer;
  transition: border-color 0.12s ease, background-color 0.12s ease;
}
.emoji-picker button:hover { border-color: var(--accent); }
.emoji-picker button.active { border-color: var(--accent); background: var(--accent-dim); }
.field-input {
  background: var(--bg-panel-hi);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  padding: 9px 12px;
  color: var(--text);
  font-size: 16px;
  font-family: var(--font-sans);
}
.field-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-haze);
}

/* ─────────── event list (dashboard) ─────────── */
.event-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.event-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--bg-panel-hi);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
}
.event-item-info { min-width: 0; }
.event-item-title {
  font-size: 13.5px;
  font-weight: 600;
  margin: 0 0 2px;
}
.event-item-link {
  font-size: 12px;
  color: var(--text-dim);
  word-break: break-all;
  text-decoration: none;
  transition: color 0.15s ease;
}
a.event-item-link:hover {
  color: var(--accent);
  text-decoration: underline;
}
.event-copy-btn {
  display: inline-block;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 12px;
  cursor: pointer;
  font-family: var(--font-sans);
  text-decoration: none;
  flex-shrink: 0;
  white-space: nowrap;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
.event-copy-btn:hover {
  color: var(--text);
  background: var(--bg-panel-hi);
  border-color: var(--border-strong);
  transform: translateY(-1px);
}

/* ─────────── results calendar (organiser view — avatars per date) ─────────── */
.results-calendar .day-cell {
  aspect-ratio: auto;
  min-height: 84px;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 4px;
  padding: 6px;
  cursor: default;
}
.results-calendar .day-cell:not(.outside):hover {
  /* !important on all three: the general drag-select calendar's hover rule
     (.day-cell:not(.outside):not(.past):not(.unavailable):not(.selected):hover)
     has higher specificity (6 class-equivalents vs. 4 here) and would otherwise
     win and apply its bg/border/scale here too — this results-calendar view is
     read-only and must not react to hover. */
  background: transparent !important;
  border-color: transparent !important;
  transform: none !important;
}
.results-calendar .day-cell.has-avatars {
  background: var(--bg-panel-hi);
  border-color: var(--border);
}
.results-calendar .day-cell.not-offered {
  opacity: 0.35;
}
.results-calendar .day-cell.not-offered .day-num {
  color: var(--text-muted);
}
.results-calendar .day-num {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-dim);
}
.results-calendar .day-cell.today .day-num {
  color: var(--accent);
}
.results-calendar .day-avatars {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  width: 100%;
}
.day-avatar {
  width: 19px;
  height: 19px;
  border-radius: 50%;
  font-size: 8px;
  font-weight: 700;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: transform 0.15s ease;
}
.day-avatar:hover {
  transform: scale(1.35);
  z-index: 1;
  position: relative;
}
.day-avatar-more {
  background: var(--bg-panel);
  border: 1px solid var(--border-strong);
  color: var(--text-dim);
}
@media (max-width: 640px) {
  .results-calendar .day-cell { min-height: 64px; }
  .day-avatar { width: 16px; height: 16px; font-size: 7px; }
}

/* ─────────── dashboard: events header + grid ─────────── */
.events-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 4px;
}
.events-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
}
.event-tile {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.event-tile:hover {
  border-color: var(--border-strong);
  transform: translateY(-3px);
  box-shadow: var(--shadow-overlay);
}
.event-tile-disabled {
  opacity: 0.6;
}
.event-tile-disabled:hover {
  opacity: 0.85;
}
.event-tile-title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}
.event-tile-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  text-decoration: none;
  letter-spacing: -0.01em;
  transition: color 0.15s ease;
}
.event-tile-title:hover { color: var(--accent); text-decoration: underline; }
.icon-btn.event-tile-delete-btn {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  color: var(--text-muted);
}
.event-tile-delete-btn svg { width: 14px; height: 14px; }
.icon-btn.event-tile-delete-btn:hover {
  color: #ef4444;
  background: rgba(239, 68, 68, 0.12);
  border-color: rgba(239, 68, 68, 0.4);
}
.event-tile-disabled-badge {
  display: inline-block;
  width: fit-content;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  background: var(--bg-panel-hi);
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 3px 10px;
}
.event-tile-meta {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: -8px;
}
.event-tile-insight {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: auto;
  padding-top: 4px;
}
.event-tile-avatars {
  display: flex;
}
.event-tile-avatars .avatar {
  margin-left: -8px;
  border: 2px solid var(--bg-panel);
  transition: transform 0.15s ease;
}
.event-tile-avatars .avatar:first-child { margin-left: 0; }
.event-tile-avatars .avatar:hover {
  transform: translateY(-3px) scale(1.12);
  z-index: 1;
}
.event-tile-insight-text {
  font-size: 12.5px;
  color: var(--text-dim);
}
.event-tile-frontrunner {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-haze);
  border: 1px solid var(--accent-glow);
  border-radius: 999px;
  padding: 4px 10px;
  width: fit-content;
}
.event-tile-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
/* display:flex above beats the UA's [hidden] rule — the recurring gotcha
   (7th instance); needed since the booking-detail modal hides this row for
   non-pending bookings. */
.event-tile-actions[hidden] { display: none; }
.booking-detail-actions { margin-top: 16px; }
/* 8th instance (display:inline-block below) — the detail modal hides
   individual buttons per booking status, not just the whole row. */
.event-copy-btn[hidden] { display: none; }
.event-tile-actions .event-copy-btn { flex: 1 1 auto; min-width: 72px; text-align: center; }

/* ─────────── create-event modal ─────────── */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 100;
}
.modal-backdrop[hidden] {
  display: none;
}
.modal-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 28px;
  width: 100%;
  max-width: 540px;
  max-height: 90vh;
  overflow-y: auto;
  position: relative;
  box-shadow: var(--shadow-overlay);
}
.modal-close {
  position: absolute;
  top: 16px;
  right: 16px;
}

/* ─────────── custom tooltip ─────────── */
/* The native [title] attribute doesn't show on tap on touch devices (no hover
   state) — this shows on hover *and* on tap/keyboard-focus via the
   .tooltip-active class toggled in JS, so avatar names are reachable on mobile. */
.has-tooltip {
  position: relative;
}
.has-tooltip::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg-panel);
  color: var(--text);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  padding: 4px 9px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  box-shadow: var(--shadow-overlay);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.12s ease;
  z-index: 20;
}
.has-tooltip:hover::after,
.has-tooltip:focus::after,
.has-tooltip.tooltip-active::after {
  opacity: 1;
  visibility: visible;
}

/* ─────────── booking events: type toggle, weekly hours, overrides, slots ─────────── */

.segmented {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.segmented-btn {
  background: var(--bg-panel-hi);
  border: 1px solid var(--border-strong);
  color: var(--text-dim);
  border-radius: 8px;
  padding: 9px 14px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  font-family: var(--font-sans);
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.segmented-btn:hover {
  border-color: var(--border-strong);
  color: var(--text);
}
.segmented-btn.active {
  background: var(--accent-haze);
  border-color: var(--accent);
  color: var(--accent);
}

.weekly-hours-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
}
.weekly-hours-row:last-child { border-bottom: none; }
.weekly-hours-day {
  width: 38px;
  flex-shrink: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-dim);
  padding-top: 8px;
}
.weekly-hours-windows {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 1 auto;
}

.time-window-row {
  display: flex;
  align-items: center;
  gap: 6px;
}
.time-window-row input[type="time"] {
  background: var(--bg-panel-hi);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  padding: 6px 8px;
  color: var(--text);
  font-size: 13px;
  font-family: var(--font-sans);
}
.time-window-row span { color: var(--text-muted); font-size: 12.5px; }
.icon-btn.time-window-remove {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  font-size: 16px;
  line-height: 1;
  color: var(--text-muted);
}
.icon-btn.time-window-remove:hover {
  color: #ef4444;
  background: rgba(239, 68, 68, 0.12);
  border-color: rgba(239, 68, 68, 0.4);
}

.override-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 12.5px;
  color: var(--text-dim);
  margin-bottom: 8px;
}
.override-add-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border: 1px dashed var(--border-strong);
  border-radius: 8px;
  margin-top: 4px;
}
.override-add-row input[type="date"] {
  background: var(--bg-panel-hi);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  padding: 8px 10px;
  color: var(--text);
  font-size: 13px;
  font-family: var(--font-sans);
}

/* respondent-facing slot picker (booking.tpl.php) */
.slot-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 8px;
}
.slot-btn {
  background: var(--bg-panel-hi);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  padding: 9px 6px;
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  font-family: var(--font-sans);
  transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.slot-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-1px);
}
.slot-btn.selected {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  border-radius: 999px;
  padding: 4px 12px;
  width: fit-content;
}
.status-badge[hidden] { display: none; }
.status-badge.status-pending {
  color: #b45309;
  background: rgba(245, 158, 11, 0.14);
  border: 1px solid rgba(245, 158, 11, 0.35);
}
.status-badge.status-confirmed {
  color: var(--pos);
  background: var(--pos-bg);
  border: 1px solid rgba(34, 197, 94, 0.35);
}
.status-badge.status-rejected,
.status-badge.status-cancelled {
  color: var(--text-muted);
  background: var(--bg-panel-hi);
  border: 1px solid var(--border-strong);
}

/* profile switcher (home.tpl.php dashboard) */
.profile-switcher-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
#business-rename-form {
  display: flex;
  align-items: center;
  gap: 8px;
}
#business-rename-form[hidden] { display: none; }
#business-rename-input {
  width: auto;
  min-width: 180px;
}

/* organiser request list (booking-results.tpl.php) */
.request-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 8px;
  font-size: 13px;
}
.request-row-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  font-weight: 600;
}
.request-row-meta { color: var(--text-dim); font-size: 12.5px; }

/* Divides the Upcoming-confirmed list (booking-results.js) into months when
 * it isn't filtered down to just one — sits between .request-row cards, not
 * inside one, so no border-radius/background of its own is needed. */
.month-separator {
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  padding: 4px 2px;
  margin-bottom: 4px;
}
.month-separator:not(:first-child) { margin-top: 10px; }

/* dashboard: confirmed-bookings schedule — time-of-day gutter on the left,
   each visible day as its own column (7 on desktop, 2 on mobile — column
   count and hour-row height come in as --week-days/--hour-px custom
   properties set by dashboard.js, since both are responsive/data-driven). */
.week-schedule {
  display: grid;
  grid-template-columns: 52px 1fr;
  grid-template-rows: auto 1fr;
  max-height: 520px;
  overflow-y: auto;
}
/* Desktop (same breakpoint where .layout goes side-by-side): the fixed
   520px cap only ever shows ~6 of the schedule's 14 hours, so let the
   scroll window grow with the viewport instead — 200px ≈ the panel/toolbar
   chrome above the grid once the panel is scrolled into view. max() keeps
   short windows from getting *less* than the old cap. */
@media (min-width: 861px) {
  .week-schedule { max-height: max(520px, calc(100vh - 200px)); }
}
.week-schedule-corner {
  grid-column: 1;
  grid-row: 1;
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bg-panel);
}
.week-day-headers {
  grid-column: 2;
  grid-row: 1;
  display: grid;
  grid-template-columns: repeat(var(--week-days, 7), 1fr);
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bg-panel);
}
.week-day-header {
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-dim);
  padding: 4px 2px 8px;
  border-bottom: 1px solid var(--border);
}
.week-day-header.today { color: var(--accent); }
.week-time-gutter {
  grid-column: 1;
  grid-row: 2;
  position: relative;
}
.week-time-label {
  position: absolute;
  right: 8px;
  transform: translateY(-50%);
  font-size: 10.5px;
  color: var(--text-muted);
  white-space: nowrap;
}
.week-days-grid {
  grid-column: 2;
  grid-row: 2;
  display: grid;
  grid-template-columns: repeat(var(--week-days, 7), 1fr);
  position: relative;
}
.week-day-col {
  position: relative;
  border-left: 1px solid var(--border);
  background-image: repeating-linear-gradient(to bottom,
    var(--border) 0, var(--border) 1px, transparent 1px, transparent var(--hour-px, 48px));
}
.week-booking-item {
  position: absolute;
  left: 2px;
  right: 2px;
  background: var(--accent-haze);
  border: 1px solid var(--accent);
  border-radius: 6px;
  padding: 4px 7px;
  font-size: 11.5px;
  line-height: 1.35;
  overflow: hidden;
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.1s ease;
}
.week-booking-item:hover,
.week-booking-item:focus-visible {
  background: var(--accent);
  color: #fff;
  transform: scale(1.02);
  outline: none;
}
.week-booking-item:hover .week-booking-title,
.week-booking-item:focus-visible .week-booking-title { color: rgba(255,255,255,0.85); }
.week-booking-time { font-weight: 600; display: block; }
.week-booking-title { color: var(--text-dim); display: block; }
.week-booking-note {
  color: var(--text-muted);
  display: block;
  font-style: italic;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.week-booking-item:hover .week-booking-note,
.week-booking-item:focus-visible .week-booking-note { color: rgba(255,255,255,0.75); }

/* past bookings (end time already gone by) — same opacity/muted treatment
   as .day-cell.past elsewhere in this app */
.week-booking-item.past {
  opacity: 0.5;
  background: var(--bg-panel-hi);
  border-color: var(--border);
}
.week-booking-item.past:hover,
.week-booking-item.past:focus-visible {
  background: var(--bg-panel-hi);
  color: inherit;
  transform: none;
}
.week-booking-item.past:hover .week-booking-title,
.week-booking-item.past:focus-visible .week-booking-title { color: var(--text-dim); }
.week-booking-item.past:hover .week-booking-note,
.week-booking-item.past:focus-visible .week-booking-note { color: var(--text-muted); }

/* pending requests shown alongside confirmed bookings on the same weekly
   calendar (dashboard.js's getWeeklyBookings now returns both) — dashed
   amber instead of a solid accent fill, so "still awaiting a decision"
   reads differently from "booked". Hover fills solid amber with dark navy
   text, same convention as the professional booking-scheme's amber
   selected state elsewhere in this file. */
.week-booking-item.pending {
  background: rgba(245, 158, 11, 0.14);
  border: 1px dashed rgba(245, 158, 11, 0.6);
}
.week-booking-item.pending:hover,
.week-booking-item.pending:focus-visible {
  background: #f59e0b;
  border-style: solid;
  border-color: #f59e0b;
  color: #1e293b;
  transform: scale(1.02);
  outline: none;
}
.week-booking-item.pending:hover .week-booking-title,
.week-booking-item.pending:focus-visible .week-booking-title,
.week-booking-item.pending:hover .week-booking-note,
.week-booking-item.pending:focus-visible .week-booking-note { color: rgba(30, 41, 59, 0.75); }

/* A pending request whose slot has already passed without ever being
   confirmed/declined — .past's muted treatment should win outright over
   the amber pending look, not blend with it. 3-class selector so this
   doesn't depend on which of .past/.pending happens to come later in the
   file (both are otherwise equally specific). */
.week-booking-item.pending.past {
  background: var(--bg-panel-hi);
  border: 1px solid var(--border);
  opacity: 0.5;
}
.week-booking-item.pending.past:hover,
.week-booking-item.pending.past:focus-visible {
  background: var(--bg-panel-hi);
  color: inherit;
  transform: none;
}

/* current-time indicator — deliberately loud (red, not in the app's normal
   accent/pos/popular palette) so "now" is unmistakable against booking
   blocks in the accent color */
.week-now-line {
  position: absolute;
  left: 0;
  right: 0;
  border-top: 2px solid #ef4444;
  z-index: 3;
  pointer-events: none;
}
.week-now-line::before {
  content: '';
  position: absolute;
  left: -4px;
  top: -4px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #ef4444;
  box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.28);
}
.week-now-label {
  position: absolute;
  left: 6px;
  top: -8px;
  background: #ef4444;
  color: #fff;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 1px 5px;
  border-radius: 4px;
  white-space: nowrap;
}

/* ─────────── booking detail overlay ─────────── */
.booking-detail-card { max-width: 380px; }
.booking-detail-title { margin: 0 0 2px; font-size: 18px; }
.booking-detail-when { margin: 0 0 16px; }
.booking-detail-field {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 13.5px;
  margin-bottom: 12px;
}
.booking-detail-field[hidden] { display: none; }
.booking-detail-label {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
#booking-detail-email { color: var(--accent); text-decoration: none; }
#booking-detail-email:hover { text-decoration: underline; }
#booking-detail-note { white-space: pre-wrap; color: var(--text-dim); }

/* ═══════════════ Booking page spacing/layout (all schemes) ═══════════════
   Matches booking-form-v2.html's proportions — roomier padding/radius/gaps
   than the shared defaults elsewhere. Scoped to #booking-app (same element
   as .app, so the ID alone outranks the class) so poll/results/dashboard
   pages sharing these same classes are untouched. Colour is handled
   separately below; this section is scheme-independent on purpose. */
#booking-app { gap: 18px; }

#booking-app .event-hero { border-radius: 18px; padding: 26px 28px; }
#booking-app .event-hero .event-title { font-size: 28px; }
#booking-app .event-hero .event-desc { max-width: 60ch; }

#booking-app #calendar-panel,
#booking-app #times-panel,
#booking-app #request-form-wrap { border-radius: 16px; padding: 20px 22px; }
/* Doesn't affect the "Weekly availability"/"Exceptions" sub-headers inside
   #times-panel — those already carry their own inline font-size:14px, which
   (being an inline style) outranks this class-level rule regardless. */
#booking-app .panel-header h2 { font-size: 16px; font-weight: 800; }
#booking-app .section-icon,
#booking-app .deco-emoji { margin-right: 4px; }

/* "Pick a date"/"Available times" markers stay visible in every colour
   scheme (an explicit request — these read as functional section labels,
   not decoration); .deco-emoji (day-dot, recurring-toggle, submit button,
   "Your details" heading) is the purely decorative set, ported from
   booking-form-v2.html's .v2-emoji/.v2-emoji-always split, and hidden for
   classic/professional below. */
#booking-app[data-scheme="classic"] .deco-emoji,
#booking-app[data-scheme="professional"] .deco-emoji { display: none; }

#booking-app .weekday-row { margin-bottom: 6px; }
#booking-app .days-grid { gap: 6px; }
#booking-app .day-cell { border-radius: 10px; }
#booking-app .day-cell .day-dot { position: absolute; bottom: 3px; font-size: 7px; }
#booking-app .day-cell.selected .day-dot { display: none; }
#booking-app .cal-hint { text-align: center; }

/* Calendar toolbar/nav sized to match booking-form-v2.html exactly — the
   shared .calendar-toolbar/.cal-nav (used by event.tpl.php/home.tpl.php's
   weekly-hours editor too) are a bordered box with square-ish nav buttons;
   the static concept's are borderless and fully circular. Scoped to
   #booking-app so those other callers are untouched. */
#booking-app .calendar-toolbar { border: none; padding: 0; justify-content: center; gap: 14px; }
#booking-app .cal-nav { border-radius: 999px; }
#booking-app .cal-range { font-weight: 700; min-width: 120px; }

#booking-app .slot-grid { grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); gap: 10px; }
#booking-app .slot-btn { border-radius: 10px; padding: 10px 6px; }

/* Recurring-booking toggle as a tinted pill box (matching .v2-recurring),
   not the plain unboxed label the shared .recurring-toggle rule (further
   up this file) renders elsewhere — safe to restyle directly since this
   class has no other consumer than booking.tpl.php. Classic keeps the
   neutral panel tint (its "no special colour" look); colourful/professional
   layer their own tint below. */
.recurring-toggle {
  background: var(--bg-panel-hi);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 12px;
  margin-top: 0;
  margin-bottom: 14px;
  font-weight: 600;
  transition: filter 0.12s ease;
}
.recurring-toggle:hover { filter: brightness(1.1); }

#booking-app .event-name-input input,
#booking-app .field-input { border-radius: 10px; padding: 10px 12px; }

#booking-app #request-btn { border-radius: 12px; padding: 14px; font-size: 15px; font-weight: 800; }

/* ═══════════════ Booking page colour schemes (Classic/Colourful/Professional) ═══════════════
   Organiser-selected per booking event (booking_settings.theme/emoji), applied via
   #booking-app[data-scheme]. "Classic" is today's existing look above — deliberately zero
   rules here, since it IS the base/default styling every other page already uses.
   Ported from the booking-form-v2.html static concept (same reasoning/comments preserved
   where relevant) onto the real classes, scoped so it only ever touches booking.tpl.php:
     .event-hero      → the event-title/organiser hero card (own class, NOT plain .event-card,
                         so #respondent-gate/#request-status-banner — which reuse .event-card/
                         .event-eyebrow/.event-title/.meta-chip for unrelated content — are untouched)
     .day-cell.has-slots → days with open times (booking.js only adds this class there)
     #request-btn      → the actual submit button id, not the shared .btn-primary class (which
                         the business-account login/register forms on this same page also use)
   ══════════════════════════════════════════════════════════════════════════════════════ */

/* ── Colourful ───────────────────────────────────────────────────────── */
#booking-app[data-scheme="colourful"] .event-hero {
  background: linear-gradient(135deg, #4f46e5 0%, #9333ea 45%, #ec4899 100%);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 12px 32px rgba(147, 51, 234, 0.35);
  position: relative;
  overflow: hidden;
}
#booking-app[data-scheme="colourful"] .event-hero .event-eyebrow,
#booking-app[data-scheme="colourful"] .event-hero .event-desc { color: #fff; opacity: 0.9; }
#booking-app[data-scheme="colourful"] .event-hero .meta-chip {
  background: rgba(255, 255, 255, 0.18);
  border-color: rgba(255, 255, 255, 0.3);
  color: #fff;
  padding: 6px 14px;
  font-size: 13px;
  backdrop-filter: blur(2px);
}
#booking-app[data-scheme="colourful"] .hero-emoji {
  position: absolute; right: 20px; top: 16px; font-size: 26px; opacity: 0.75;
}
#booking-app[data-scheme="colourful"] #calendar-panel     { border-top: 4px solid #3b82f6; }
#booking-app[data-scheme="colourful"] #times-panel        { border-top: 4px solid #a855f7; }
#booking-app[data-scheme="colourful"] #request-form-wrap  { border-top: 4px solid #ec4899; }
#booking-app[data-scheme="colourful"] #times-panel .count-badge {
  background: rgba(168, 85, 247, 0.14); border: 1px solid rgba(168, 85, 247, 0.35); color: #d8b4fe;
}

#booking-app[data-scheme="colourful"] .day-cell.has-slots {
  background: rgba(59, 130, 246, 0.12); border-color: rgba(59, 130, 246, 0.3); color: #93c5fd;
}
#booking-app[data-scheme="colourful"] .day-cell.selected {
  background: linear-gradient(135deg, #6366f1, #ec4899); border-color: transparent;
  box-shadow: 0 4px 14px rgba(236, 72, 153, 0.45);
}
#booking-app[data-scheme="colourful"] .day-cell.selected:hover { background: linear-gradient(135deg, #6366f1, #ec4899); color: #fff; }

#booking-app[data-scheme="colourful"] .slot-btn {
  background: rgba(168, 85, 247, 0.10); border-color: rgba(168, 85, 247, 0.35); color: #d8b4fe;
}
#booking-app[data-scheme="colourful"] .slot-btn:hover { border-color: #d8b4fe; color: #d8b4fe; filter: brightness(1.15); }
#booking-app[data-scheme="colourful"] .slot-btn.selected {
  background: linear-gradient(135deg, #a855f7, #ec4899); border-color: transparent; color: #fff;
  box-shadow: 0 4px 14px rgba(168, 85, 247, 0.4);
}

#booking-app[data-scheme="colourful"] .recurring-toggle {
  background: rgba(245, 158, 11, 0.10); border-color: rgba(245, 158, 11, 0.3);
}
#booking-app[data-scheme="colourful"] .recurring-toggle input { accent-color: #f59e0b; }

#booking-app[data-scheme="colourful"] #request-btn {
  background: linear-gradient(135deg, #6366f1, #a855f7 55%, #ec4899); border: none;
  box-shadow: 0 8px 22px rgba(168, 85, 247, 0.4);
}
#booking-app[data-scheme="colourful"] #request-btn:hover { filter: brightness(1.08); box-shadow: 0 10px 26px rgba(168, 85, 247, 0.55); }

/* Light mode: the pale text colours above (meant to sit on a dark tinted
   chip/day) lose contrast on a light page's much-lighter version of the same
   low-opacity tint — darker equivalents here, same fix as the static concept.
   data-theme lives on <html> (the site-wide toggle, header.tpl.php), NOT on
   #booking-app (which only ever gets data-scheme, set server-side per
   event) — these were originally written as #booking-app[data-theme=...],
   an attribute that element never has, so the whole light-mode fix silently
   never matched and colourful/professional kept their dark-mode colours
   even in light mode. Fixed to check <html> and #booking-app separately. */
html[data-theme="light"] #booking-app[data-scheme="colourful"] .day-cell.has-slots {
  background: rgba(59, 130, 246, 0.10); border-color: rgba(59, 130, 246, 0.35); color: #1d4ed8;
}
html[data-theme="light"] #booking-app[data-scheme="colourful"] .slot-btn {
  background: rgba(168, 85, 247, 0.08); border-color: rgba(168, 85, 247, 0.4); color: #7c3aed;
}
html[data-theme="light"] #booking-app[data-scheme="colourful"] .event-hero {
  box-shadow: 0 12px 32px rgba(147, 51, 234, 0.22);
}
html[data-theme="light"] #booking-app[data-scheme="colourful"] .recurring-toggle {
  background: rgba(245, 158, 11, 0.08); border-color: rgba(245, 158, 11, 0.4); color: #92400e;
}

/* ── Professional ────────────────────────────────────────────────────── */
#booking-app[data-scheme="professional"] {
  /* Dark mode (default) — deliberately more pronounced than a first pass
     would be: a dark navy fill on an already near-black page barely shows
     up, so the "selected" state needs a lighter accent than the light-mode
     value below, not the same or darker. */
  --prof-accent: #64748b;
  --prof-tint: rgba(100, 116, 139, 0.24);
  --prof-border: rgba(148, 163, 184, 0.55);
  --prof-green-tint: rgba(34, 197, 94, 0.22);
  --prof-green-border: rgba(34, 197, 94, 0.6);
}
html[data-theme="light"] #booking-app[data-scheme="professional"] {
  /* Light mode keeps subdued values — a dark navy reads fine on a white page.
     Same <html>-vs-#booking-app attribute mix-up as the colourful fix above —
     this block never applied either, so professional stayed at its
     dark-mode-pronounced accent/tint values even on a light page. */
  --prof-accent: #334155;
  --prof-tint: rgba(30, 41, 59, 0.08);
  --prof-border: rgba(30, 41, 59, 0.35);
  --prof-green-tint: rgba(21, 128, 61, 0.10);
  --prof-green-border: rgba(21, 128, 61, 0.4);
}
#booking-app[data-scheme="professional"] .event-hero {
  border-left: 4px solid var(--prof-accent);
}
#booking-app[data-scheme="professional"] .event-hero .meta-chip {
  background: var(--prof-tint); border-color: var(--prof-border); color: var(--text);
}
#booking-app[data-scheme="professional"] #calendar-panel,
#booking-app[data-scheme="professional"] #times-panel,
#booking-app[data-scheme="professional"] #request-form-wrap { border-top: 4px solid var(--prof-accent); }
#booking-app[data-scheme="professional"] #times-panel .count-badge {
  background: var(--prof-tint); border: 1px solid var(--prof-border); color: var(--text);
}

#booking-app[data-scheme="professional"] .day-cell.has-slots {
  background: var(--prof-green-tint); border-color: var(--prof-green-border); color: var(--text);
}
/* Active/selected uses today's marker colour (the amber accent ring) as its
   fill, with what used to be the selected fill (--prof-accent) as its border
   instead — text switches to a fixed dark navy since white doesn't read
   well against amber. Applied to both the calendar day and the matching
   time slot, for consistency between the two. Hovering an unselected but
   available day/slot previews the same amber look, so hover reads as "this
   is what selecting it looks like" rather than an unrelated grey highlight. */
#booking-app[data-scheme="professional"] .day-cell.selected,
#booking-app[data-scheme="professional"] .slot-btn.selected,
#booking-app[data-scheme="professional"] .day-cell.has-slots:hover,
#booking-app[data-scheme="professional"] .slot-btn:hover {
  background: #f59e0b; border-color: var(--prof-accent); color: #1e293b;
}

#booking-app[data-scheme="professional"] .slot-btn {
  background: var(--prof-tint); border-color: var(--prof-border); color: var(--text);
}

#booking-app[data-scheme="professional"] .recurring-toggle {
  background: var(--prof-tint); border-color: var(--prof-border); color: var(--text);
}
#booking-app[data-scheme="professional"] .recurring-toggle input { accent-color: var(--prof-accent); }

#booking-app[data-scheme="professional"] #request-btn { background: var(--prof-accent); border: none; }
#booking-app[data-scheme="professional"] #request-btn:hover { box-shadow: 0 6px 16px rgba(30, 41, 59, 0.35); }

/* ════════════════════════════════════════════════════════════════════════
   Dashboard "interface style" (2026-07-07) — a personal per-user setting
   (account-settings.tpl.php → updateUiScheme) offering the same three names
   (classic/colourful/professional) as the booking-page theme above, but for
   the organiser's own dashboard/management pages instead of one event's
   respondent-facing page. header.tpl.php only ever prints data-scheme onto
   <html> when $showSidebar is set, i.e. only on logged-in organiser pages —
   so this can never reach the public /e/<slug> pages (which keep their own
   independent #booking-app[data-scheme] untouched, scoped to that element
   rather than <html>, and set from the event's own booking_settings.theme).

   Rather than re-declaring every component (panels, tiles, buttons...), this
   overrides the shared accent custom properties every one of those already
   reads (--accent, --accent-2, --accent-glow, --accent-haze) so the whole
   interface recolors from a handful of variable swaps, then layers a few
   extra touches to match the booking page's visual language: gradients for
   colourful, a flatter muted-slate accent + left-border for professional. */
html[data-scheme="colourful"] {
  --accent: #9333ea;
  --accent-2: #ec4899;
  --accent-dim: #3b1264;
  --accent-glow: rgba(236, 72, 153, 0.35);
  --accent-haze: rgba(147, 51, 234, 0.16);
}
html[data-theme="light"][data-scheme="colourful"] {
  --accent: #9333ea;
  --accent-2: #db2777;
  --accent-dim: #f3e8ff;
  --accent-glow: rgba(219, 39, 119, 0.22);
  --accent-haze: rgba(147, 51, 234, 0.10);
}
html[data-scheme="colourful"] .btn-primary,
html[data-scheme="colourful"] .segmented-btn.active,
html[data-scheme="colourful"] .day-cell.selected {
  background: linear-gradient(135deg, #6366f1, #9333ea 55%, #ec4899);
  color: #fff;
  border-color: transparent;
}
/* Base .day-cell.selected:hover inverts to an outline look (bg-panel/accent
   border) — kept solid here instead, same "gradient stays gradient on
   hover" precedent as the booking page's colourful day-cell.selected:hover. */
html[data-scheme="colourful"] .day-cell.selected:hover {
  background: linear-gradient(135deg, #6366f1, #9333ea 55%, #ec4899);
  color: #fff;
}
html[data-scheme="colourful"] .panel,
html[data-scheme="colourful"] .event-tile {
  border-top: 3px solid var(--accent-2);
}

html[data-scheme="professional"] {
  --accent: #64748b;
  --accent-2: #475569;
  --accent-dim: #334155;
  --accent-glow: rgba(100, 116, 139, 0.28);
  --accent-haze: rgba(100, 116, 139, 0.20);
}
html[data-theme="light"][data-scheme="professional"] {
  --accent: #334155;
  --accent-2: #1e293b;
  --accent-dim: #e2e8f0;
  --accent-glow: rgba(51, 65, 85, 0.20);
  --accent-haze: rgba(51, 65, 85, 0.08);
}
html[data-scheme="professional"] .btn-primary { box-shadow: none; }
html[data-scheme="professional"] .btn-primary:hover { box-shadow: 0 6px 16px rgba(30, 41, 59, 0.3); }
html[data-scheme="professional"] .panel,
html[data-scheme="professional"] .event-tile {
  border-left: 3px solid var(--accent);
}
html[data-scheme="professional"] .segmented-btn.active { font-weight: 700; }

/* ────────────────────────── My bookings (/bookings) ──────────────────────
   Respondent-side month calendar: read-only day cells, days with bookings
   carry per-business dots (hollow = pending, dimmed = past) and click
   through to a detail list. */
.mybookings-cal { max-width: 480px; margin: 0 auto; }
.mybookings-cal .day-cell { cursor: default; }
.mybookings-cal .day-cell.has-bookings { cursor: pointer; border-color: var(--border-strong); }
/* Cancel the shared interactive-calendar hover on cells with nothing to
   click — the general rule (.day-cell:not(...):hover, 6 class-equivalents)
   beats any sane scoped selector on specificity, so !important, same as the
   .results-calendar precedent (see that rule's comment). */
.mybookings-cal .day-cell:not(.has-bookings):hover {
  background: transparent !important;
  border-color: transparent !important;
  transform: none !important;
}
.mybookings-cal .day-cell.sched-selected {
  background: var(--accent-haze);
  border-color: var(--accent);
  color: var(--accent);
}

.booking-dots {
  position: absolute;
  bottom: 3px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 3px;
}
.booking-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 999px;
  flex-shrink: 0;
}
.booking-dot.past { opacity: 0.35; }
/* square = an appointment your own business RECEIVED, round = one you made —
   the My bookings calendar plots both, this is how they're told apart */
.booking-dot.biz { border-radius: 2px; }
/* the same dot keys a list row / legend entry back to its calendar colour —
   larger than the in-cell dots so it reads at row scale */
.request-row .booking-dot,
.event-tile .booking-dot {
  width: 10px;
  height: 10px;
  margin-right: 8px;
  vertical-align: -1px;
}
.legend .booking-dot { width: 8px; height: 8px; }

/* ─────────── landing page (templates/landing.tpl.php, guests at "/") ─────────── */
.landing {
  max-width: 1020px;
  margin: 0 auto;
  padding: 0 24px 40px;
}
.landing-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 0;
}
.landing-nav .brand-title {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.landing-nav-actions {
  display: flex;
  align-items: center;
  gap: 14px;
}
.landing-signin {
  color: var(--text);
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 600;
  padding: 8px 16px;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.landing-signin:hover {
  border-color: var(--accent);
  background: var(--accent-haze);
}

.landing-hero {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: 40px;
  align-items: center;
  padding: 48px 0 56px;
}
.landing-hero-copy h1 {
  font-size: 40px;
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin: 0 0 16px;
}
.landing-grad {
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.landing-lede {
  color: var(--text-dim);
  font-size: 15.5px;
  line-height: 1.55;
  margin: 0 0 24px;
  max-width: 48ch;
}
.landing-cta-row {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}
.landing-cta {
  width: auto;
  display: inline-block;
  padding: 12px 22px;
  text-decoration: none;
  text-align: center;
}
.landing-cta-alt {
  color: var(--text-dim);
  font-size: 13.5px;
  font-weight: 500;
  text-decoration: none;
}
.landing-cta-alt:hover { color: var(--accent); }

/* hero mock — a fake date-poll result card, pure decoration */
.landing-hero-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 22px;
  box-shadow: var(--shadow-overlay);
  display: grid;
  gap: 12px;
}
.landing-mock-title {
  font-weight: 600;
  font-size: 14px;
  margin-bottom: 2px;
}
.landing-mock-row {
  display: grid;
  grid-template-columns: 84px 1fr 40px;
  align-items: center;
  gap: 12px;
  font-size: 12.5px;
  color: var(--text-dim);
  background: var(--bg-panel-hi);
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 9px 12px;
}
.landing-mock-row.is-popular {
  border-color: var(--popular);
  background: var(--popular-bg);
  color: var(--text);
}
.landing-mock-votes {
  height: 7px;
  border-radius: 4px;
  background: var(--accent-dim);
  overflow: hidden;
}
.landing-mock-votes i {
  display: block;
  height: 100%;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
}
.landing-mock-count {
  text-align: right;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.landing-mock-row.is-popular .landing-mock-count { color: var(--popular); }
.landing-mock-foot {
  font-size: 11.5px;
  color: var(--text-muted);
}

.landing-section {
  padding: 26px 0;
}
.landing-section h2 {
  font-size: 24px;
  letter-spacing: -0.015em;
  margin: 0 0 20px;
}
.landing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}
.landing-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 20px;
}
.landing-card h3 {
  font-size: 14.5px;
  margin: 0 0 8px;
}
.landing-card p {
  color: var(--text-dim);
  font-size: 13px;
  line-height: 1.55;
  margin: 0;
}
.landing-steps {
  margin: 0;
  padding-left: 22px;
  display: grid;
  gap: 12px;
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1.55;
  max-width: 70ch;
}
.landing-steps strong { color: var(--text); }

.landing-final {
  text-align: center;
  padding: 48px 20px 56px;
  border-top: 1px solid var(--border);
  margin-top: 24px;
}
.landing-final h2 {
  font-size: 26px;
  letter-spacing: -0.015em;
  margin: 0 0 8px;
}
.landing-final p {
  color: var(--text-dim);
  margin: 0 0 20px;
}
.landing-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid var(--border);
  padding-top: 20px;
  font-size: 12.5px;
  color: var(--text-muted);
}
.landing-foot a { color: var(--text-dim); }

@media (max-width: 860px) {
  .landing-hero {
    grid-template-columns: 1fr;
    gap: 32px;
    padding: 28px 0 40px;
  }
  .landing-hero-copy h1 { font-size: 31px; }
  .landing-grid { grid-template-columns: 1fr; }
}

/* ─────────── admin dashboard (templates/admin.tpl.php, /admin) ─────────── */
.admin-title {
  font-size: 22px;
  letter-spacing: -0.015em;
  margin: 0;
}
.admin-count {
  font-size: 12px;
  font-weight: 600;
  color: var(--popular);
  background: var(--popular-bg);
  border-radius: 999px;
  padding: 3px 10px;
}
.admin-list {
  display: grid;
  gap: 8px;
}
.admin-empty {
  color: var(--text-muted);
  font-size: 13px;
  margin: 4px 0;
}
.admin-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  background: var(--bg-panel-hi);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
}
.admin-row.is-decided { opacity: 0.65; }
.admin-row-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.admin-row-name { font-weight: 600; font-size: 13.5px; }
.admin-row-email { color: var(--text-dim); font-size: 12.5px; overflow-wrap: anywhere; }
.admin-row-msg {
  color: var(--text-dim);
  font-size: 12.5px;
  font-style: italic;
  margin-top: 2px;
  overflow-wrap: anywhere;
}
.admin-row-meta { color: var(--text-muted); font-size: 11.5px; }
.admin-row-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.admin-badge {
  font-size: 11px;
  font-weight: 600;
  text-transform: capitalize;
  border-radius: 999px;
  padding: 3px 10px;
  background: var(--bg-panel);
  border: 1px solid var(--border-strong);
  color: var(--text-dim);
}
.admin-badge-live     { color: var(--pos); background: var(--pos-bg); border-color: transparent; }
.admin-badge-approved { color: var(--pos); background: var(--pos-bg); border-color: transparent; }
.admin-badge-used     { color: var(--accent); background: var(--accent-haze); border-color: transparent; }
.admin-badge-denied,
.admin-badge-revoked,
.admin-badge-expired  { color: var(--text-muted); }
.admin-invite-form {
  display: flex;
  gap: 10px;
  margin-bottom: 14px;
}
.admin-invite-form .field-input { flex: 1; }
.admin-invite-btn { width: auto; padding: 10px 18px; }
.admin-note { color: var(--text-dim); font-size: 12.5px; margin: 0 0 12px; }
.admin-history summary {
  cursor: pointer;
  color: var(--text-dim);
  font-size: 12.5px;
  margin: 12px 0 8px;
}
@media (max-width: 640px) {
  .admin-row { flex-direction: column; align-items: flex-start; }
  .admin-invite-form { flex-direction: column; }
}

/* admin: users panel */
.admin-count-plain { color: var(--text-dim); background: var(--bg-panel-hi); }
.admin-seen-now { color: var(--pos); font-weight: 600; }
.admin-row-name .admin-badge { margin-left: 6px; font-size: 10px; padding: 2px 8px; vertical-align: 1px; }
