/* ==========================================================================
   Reusable component styles — paired 1:1 with templates/includes/*.html
   ========================================================================== */

[x-cloak] { display: none !important; }

/* Buttons ---------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  font-weight: 600;
  padding: 0.7rem 1.375rem;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.1s ease;
  text-decoration: none;
  line-height: 1.1;
}
.btn:active { transform: translateY(1px); }

.btn-primary { background: var(--color-primary); color: #fff; }
.btn-primary:hover { background: var(--color-primary-light); color: #fff; text-decoration: none; }

.btn-accent { background: var(--color-accent); color: #fff; }
.btn-accent:hover { background: var(--color-accent-dark); color: #fff; text-decoration: none; }

.btn-outline { background: transparent; color: var(--color-ink); border-color: var(--color-border); }
.btn-outline:hover { border-color: var(--color-primary); color: var(--color-primary); text-decoration: none; }

.btn-ghost { background: transparent; color: var(--color-primary); }
.btn-ghost:hover { background: var(--color-sand); text-decoration: none; }

.btn-sm { padding: 0.4rem 0.9rem; font-size: 0.8125rem; }
.btn-block { width: 100%; }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }

/* Icon-only button (nav actions: messages, log in/out) — text moves to
   title/aria-label instead of a visible label, so it stays a single fixed
   width regardless of language. */
.btn-icon { position: relative; padding: 0.5rem; width: 36px; height: 36px; gap: 0; }
.btn-icon svg { width: 18px; height: 18px; }

/* Icon + label together (e.g. nav "Log in") — unlike .btn-icon, keeps the
   text since first-time visitors need the cue that returning ones don't. */
.btn-icon-text svg { width: 16px; height: 16px; }

/* Unread-count badge overlaid on an icon button (nav Messages) — accent
   gold rather than the danger red used for form errors elsewhere, so it
   reads as "something new" rather than "something wrong". */
.nav-icon-badge {
  position: absolute;
  top: -2px;
  right: -2px;
  min-width: 16px;
  height: 16px;
  padding: 0 3px;
  border-radius: var(--radius-pill);
  border: 2px solid var(--color-paper);
  background: var(--color-accent);
  color: #fff;
  font-size: 0.625rem;
  font-weight: 700;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Cards -------------------------------------------------------------------*/
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.card-body { padding: var(--space-5); }

/* Tour card ---------------------------------------------------------------*/
.tour-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.tour-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); text-decoration: none; }
.tour-card-media { position: relative; aspect-ratio: 4 / 3; background: var(--color-sand); overflow: hidden; }
.tour-card-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }

/* Hover photo carousel (multi-photo tours only — see tour_card.html) —
   arrows only appear on hover, dots stay visible whenever there's more
   than one photo so a browsing traveller knows more views exist. */
.card-carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.85);
  color: var(--color-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease, background-color 0.15s ease;
}
.card-carousel-arrow svg { width: 16px; height: 16px; }
.card-carousel-arrow:hover { background: #fff; }
.card-carousel-arrow-prev { left: var(--space-2); }
.card-carousel-arrow-next { right: var(--space-2); }
.tour-card-media:hover .card-carousel-arrow { opacity: 1; }

.card-carousel-dots {
  position: absolute;
  bottom: var(--space-2);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  gap: 4px;
}
.card-carousel-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.6);
  transition: background-color 0.15s ease, transform 0.15s ease;
}
.card-carousel-dot.is-active { background: #fff; transform: scale(1.3); }
.tour-card-body { padding: var(--space-4) var(--space-4) var(--space-5); flex: 1; display: flex; flex-direction: column; }
.tour-card-location { font-size: 0.8125rem; color: var(--color-muted); margin-bottom: var(--space-1); }
.tour-card-title { font-family: var(--font-sans); font-weight: 600; font-size: 1.0625rem; color: var(--color-ink); margin: 0 0 var(--space-2); }
.tour-card-meta { margin-top: auto; display: flex; align-items: baseline; justify-content: space-between; padding-top: var(--space-3); border-top: 1px solid var(--color-border); }
.tour-card-price { font-weight: 700; color: var(--color-ink); }
.tour-card-price small { font-weight: 400; color: var(--color-muted); font-size: 0.8125rem; }

/* Like button (includes/like_button.html) — a private save/bookmark, so
   deliberately no count anywhere near it. Sits over a media container
   that's already position:relative (.tour-card-media). */
.like-button {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  z-index: 2;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.85);
  color: var(--color-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 0.15s ease, background-color 0.15s ease;
}
.like-button svg { width: 17px; height: 17px; transition: fill 0.15s ease, stroke 0.15s ease; }
.like-button:hover { background: #fff; transform: scale(1.08); }
.like-button:active { transform: scale(0.92); }
.like-button.is-liked svg { fill: var(--color-danger); stroke: var(--color-danger); }

/* Tour detail page gallery — one big cover photo, up to 4 smaller ones
   alongside it (Viator-style), "+N" on the last cell when there are more
   than the 5 shown. Flexbox with a wrapping extras column (not a fixed
   4-cell CSS grid) so 1-4 extra photos all lay out cleanly without empty
   gaps when a tour has fewer than 5 photos total. */
.tour-gallery {
  position: relative;
  display: flex;
  gap: var(--space-2);
  aspect-ratio: 16 / 7;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-sand);
}
.tour-gallery-cover { flex: 3; min-width: 0; }
.tour-gallery-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tour-gallery-extras {
  flex: 2;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-content: stretch;
  gap: var(--space-2);
}
.tour-gallery-cell { position: relative; flex: 1 1 calc(50% - var(--space-2) / 2); min-width: 0; min-height: 0; }
.tour-gallery-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tour-gallery-overflow {
  position: absolute;
  inset: 0;
  background: rgba(26, 36, 32, 0.6);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  font-weight: 700;
}

@media (max-width: 700px) {
  .tour-gallery { flex-direction: column; aspect-ratio: auto; }
  .tour-gallery-cover { aspect-ratio: 4 / 3; }
  .tour-gallery-extras { display: none; }
}

/* Badges --------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0.25rem 0.6rem;
  border-radius: var(--radius-pill);
  background: var(--color-sand);
  color: var(--color-body);
}
.badge-verified { background: var(--color-success-bg); color: var(--color-success); }
.badge-instant { background: #eaf1fb; color: #2c568f; }
.badge-accent { background: #f7ecd9; color: var(--color-accent-dark); }
.badge-pending { background: #f7ecd9; color: var(--color-accent-dark); }

/* Avatar ----------------------------------------------------------------- */
.avatar {
  border-radius: 50%;
  object-fit: cover;
  background: var(--color-sand);
  display: inline-block;
  flex: none;
}
.avatar-sm { width: 32px; height: 32px; }
.avatar-md { width: 48px; height: 48px; }
.avatar-lg { width: 80px; height: 80px; }
.avatar-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-weight: 700;
  color: var(--color-primary);
  background: var(--color-sand);
  border-radius: 50%;
}

/* Overlapping avatar stack (e.g. "guides in this city") ------------------ */
.guide-avatar-stack-row { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.guide-avatar-stack { display: flex; }
.guide-avatar-stack .avatar, .guide-avatar-stack .avatar-fallback { border: 2px solid var(--color-paper); }
.guide-avatar-stack > *:not(:first-child) { margin-left: -10px; }
.guide-avatar-stack-overflow {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--color-sand);
  border: 2px solid var(--color-paper);
  margin-left: -10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: 0.6875rem;
  font-weight: 700;
  color: var(--color-primary);
  flex: none;
}
.guide-avatar-stack-caption { font-size: 0.875rem; color: var(--color-muted); }

.profile-avatar-field { margin-bottom: var(--space-2); }
.profile-avatar-wrap { position: relative; width: 80px; }
.profile-avatar-edit-btn {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  border: 2px solid var(--color-paper);
  cursor: pointer;
}
.profile-avatar-edit-btn:hover { background: var(--color-primary-light); }
.profile-avatar-edit-btn svg { width: 14px; height: 14px; }
/* Visually hidden but still focusable/clickable via the <label for=""> —
   the label is the actual click target; this input never needs to be seen. */
.profile-avatar-input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Star rating -------------------------------------------------------------*/
.star-rating { display: inline-flex; gap: 2px; color: var(--color-star); }
.star-rating svg { width: 1em; height: 1em; }
.star-rating .star-empty { color: var(--color-border); }
.rating-summary { display: inline-flex; align-items: center; gap: var(--space-2); font-size: 0.9375rem; }
.rating-summary strong { color: var(--color-ink); }

/* Price breakdown -----------------------------------------------------------
   The transparency component: guide earnings / platform fee / extras.
   Used on tour detail, checkout, booking confirmation and guide dashboard. */
.price-breakdown {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  overflow: hidden;
}
.price-breakdown-header {
  padding: var(--space-4) var(--space-5);
  background: var(--color-sand);
  font-weight: 600;
  color: var(--color-ink);
}
.price-breakdown-rows { padding: var(--space-4) var(--space-5); }
.price-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-4);
  padding: var(--space-2) 0;
  font-size: 0.9375rem;
}
.price-row-label { display: inline-flex; align-items: center; gap: var(--space-1); color: var(--color-body); }
.price-row-sub { color: var(--color-muted); font-size: 0.8125rem; padding-left: var(--space-3); }
.price-row-info { display: flex; flex-direction: column; gap: 2px; }
.price-row-info .price-row-sub { padding-left: 0; }
.price-row.is-guide-earnings .price-row-label { color: var(--color-primary); font-weight: 600; }
.price-row.is-guide-earnings .price-row-value { color: var(--color-primary); font-weight: 600; }
.price-row.is-platform-fee .price-row-label,
.price-row.is-platform-fee .price-row-value { color: var(--color-muted); }
.price-row-divider { border-top: 1px dashed var(--color-border); margin: var(--space-2) 0; }
.price-row-total { display: flex; justify-content: space-between; padding: var(--space-4) var(--space-5); background: var(--color-paper); border-top: 1px solid var(--color-border); font-weight: 700; font-size: 1.0625rem; color: var(--color-ink); }
.price-breakdown-note { padding: 0 var(--space-5) var(--space-4); font-size: 0.8125rem; color: var(--color-muted); }

/* Comparison table (trust page: "most marketplaces" vs GuidesUnited) ------*/
.compare-table {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
}
.compare-table th, .compare-table td {
  padding: var(--space-4) var(--space-5);
  text-align: left;
  vertical-align: top;
  font-size: 0.9375rem;
  border-bottom: 1px solid var(--color-border);
}
.compare-table th { background: var(--color-sand); font-weight: 600; color: var(--color-ink); }
.compare-table td:first-child { color: var(--color-muted); font-weight: 600; width: 34%; }
.compare-table td.is-us { color: var(--color-primary); }
.compare-table tr:last-child th, .compare-table tr:last-child td { border-bottom: none; }

/* Fee info tooltip — a small (i) trigger next to "Platform cost" that
   explains what it covers and links to the full trust-page breakdown,
   without needing a static paragraph of its own. */
.fee-tooltip { position: relative; display: inline-flex; }
.fee-tooltip-trigger { background: none; border: none; padding: 0; margin: 0; line-height: 0; cursor: pointer; color: var(--color-muted); }
.fee-tooltip-trigger svg { width: 14px; height: 14px; }
.fee-tooltip-trigger:hover, .fee-tooltip-trigger:focus-visible { color: var(--color-primary); }
.fee-tooltip-panel {
  position: absolute;
  bottom: calc(100% + var(--space-2));
  left: 50%;
  transform: translateX(-50%);
  width: 220px;
  padding: var(--space-3);
  background: var(--color-ink);
  color: var(--color-paper);
  border-radius: var(--radius-md);
  font-size: 0.8125rem;
  line-height: 1.4;
  box-shadow: var(--shadow-md);
  z-index: 20;
  text-align: left;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.fee-tooltip-panel a { color: var(--color-paper); text-decoration: underline; font-weight: 600; white-space: nowrap; display: block; margin-top: var(--space-1); }
/* Desktop: pure CSS hover/keyboard-focus reveal, no JS involved — avoids
   fighting with the tap-to-toggle Alpine state below (mouseenter + click
   firing together on a real click would otherwise open then immediately
   re-close it). Touch: .is-open is toggled by the click handler instead,
   since touch devices don't dispatch :hover. */
.fee-tooltip:hover .fee-tooltip-panel,
.fee-tooltip:focus-within .fee-tooltip-panel,
.fee-tooltip-panel.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* Forms ---------------------------------------------------------------- */
label { display: block; font-weight: 600; font-size: 0.875rem; margin-bottom: var(--space-1); color: var(--color-ink); }
input, select, textarea {
  font-family: var(--font-sans);
  font-size: 1rem;
  width: 100%;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-ink);
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--color-primary-light); outline-offset: 1px; }
.field { margin-bottom: var(--space-4); }
.field-help { font-size: 0.8125rem; color: var(--color-muted); margin-top: var(--space-1); }
.field-error { font-size: 0.8125rem; color: var(--color-danger); margin-top: var(--space-1); }
.checkbox-field { display: flex; align-items: flex-start; gap: var(--space-2); }
.checkbox-field input { width: auto; margin-top: 0.15rem; }
.checkbox-field label { font-weight: 400; margin: 0; }

/* Two side-by-side fields whose labels must stay row-aligned even if one
   wraps to two lines and the other doesn't (e.g. a longer translation) —
   a flex .cluster can't do this since each field's label+input stack is
   sized independently, but a grid's row height is the tallest cell in it,
   so both inputs line up automatically regardless of label length. Direct
   children in DOM order: label, label, input-wrapper, input-wrapper. */
.field-grid-row {
  display: grid;
  grid-template-columns: 1fr auto;
  column-gap: var(--space-3);
  row-gap: var(--space-1);
  margin-bottom: var(--space-4);
}
/* Labels bottom-align within row 1 — so a short one-line label still sits
   flush against its input below even when a sibling label wraps to two
   lines and grows the row. Inputs top-align within row 2 for the opposite
   reason: one field having help-text under it (making its cell taller)
   must not push a shorter sibling field's input down to "bottom-align"
   too — that's what made the trip-request form's date/budget pairs look
   broken. A blanket `align-items` on the grid can't give each row a
   different answer, so each row gets its own `align-self` instead. */
.field-grid-row > label { align-self: end; margin-bottom: 0; }
.field-grid-row > .field { align-self: start; margin-bottom: 0; }

/* Number inputs — no browser spinner arrows anywhere on the site, even
   outside the dedicated .stepper-input (e.g. price/duration fields, which
   are free-typed rather than stepped). */
input[type="number"] { -moz-appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* Checkboxes — fully custom box + check mark instead of the raw OS widget. */
input[type="checkbox"] {
  appearance: none;
  width: 1.15rem;
  height: 1.15rem;
  padding: 0;
  flex: none;
  border: 1.5px solid var(--color-border);
  border-radius: 4px;
  background: var(--color-surface);
  cursor: pointer;
  display: inline-grid;
  place-content: center;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
input[type="checkbox"]::after {
  content: "";
  width: 0.65rem;
  height: 0.65rem;
  clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
  background: #fff;
  transform: scale(0);
  transition: transform 0.1s ease;
}
input[type="checkbox"]:checked {
  background: var(--color-primary);
  border-color: var(--color-primary);
}
input[type="checkbox"]:checked::after { transform: scale(1); }
input[type="checkbox"]:disabled { opacity: 0.5; cursor: not-allowed; }

/* Selects — native popup stays (that's the right call, not worth a JS
   rebuild), but the closed-state control gets our own chevron instead of
   the OS one. Both prefixes are needed: unprefixed `appearance` alone
   still leaves GTK/Firefox-on-Linux painting its own button chrome under
   our background, which is what "default styling" looked like. */
select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding-right: 2.5rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B7770' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.85rem center;
  background-size: 1rem;
  cursor: pointer;
  transition: border-color 0.15s ease;
}
select:hover { border-color: var(--color-primary-light); }

/* Custom select dropdown (includes/select_dropdown.html) — a native
   <select>'s open option list is OS-rendered and can't be restyled past
   the closed-state treatment above, so this swaps in a fully themed panel
   (matching the language switcher) for the fields where that matters. The
   real <select> stays in the DOM, visually hidden but still rendered (not
   display:none), so name/required/native validation/form submission all
   keep working untouched. */
.select-dropdown { position: relative; }
.select-dropdown-native {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.select-dropdown-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  font-family: var(--font-sans);
  font-size: 1rem;
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-ink);
  cursor: pointer;
  transition: border-color 0.15s ease;
}
.select-dropdown-trigger:hover { border-color: var(--color-primary-light); }
.select-dropdown-trigger svg { width: 1rem; height: 1rem; flex: none; color: var(--color-muted); }
/* A native <select> never wraps its closed-state text, it truncates —
   match that instead of letting a longer translation grow the box taller
   than the other fields in the same row (min-width:0 is required for
   text-overflow to take effect on a flex child at all). */
.select-dropdown-trigger span {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.select-dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: var(--space-2);
  max-height: 280px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--space-2);
  z-index: 110;
}
.select-dropdown-option {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm, 6px);
  font-family: inherit;
  font-size: 0.9375rem;
  color: var(--color-body);
  cursor: pointer;
}
.select-dropdown-option:hover { background: var(--color-sand); color: var(--color-primary); }
.select-dropdown-option.is-active { color: var(--color-primary); font-weight: 600; background: var(--color-sand); }
.select-dropdown-option.is-disabled { color: var(--color-muted); cursor: not-allowed; }

/* Booking date/time picker (includes/availability_calendar.html,
   static/js/availability-calendar.js) — an Airbnb-Experiences-style
   month-jump + date-grouped slot list. Reuses .select-dropdown-trigger/
   -native for the closed state (same hidden-native-select technique), but
   needs its own wider panel since the content is month nav + grouped
   cards, not a flat option list. */
.availability-picker-panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: var(--space-2);
  max-height: 380px;
  overflow-y: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--space-4);
  z-index: 110;
}
.availability-picker-month-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-4);
  font-weight: 600;
  color: var(--color-ink);
}
.availability-picker-month-nav button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--color-border);
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-ink);
  cursor: pointer;
}
.availability-picker-month-nav button:hover { border-color: var(--color-primary); color: var(--color-primary); }
.availability-picker-month-nav svg { width: 16px; height: 16px; }

.availability-picker-group + .availability-picker-group { margin-top: var(--space-4); }
.availability-picker-group-label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-ink);
  margin-bottom: var(--space-2);
}
.availability-picker-empty { color: var(--color-muted); font-size: 0.875rem; padding: var(--space-2) 0; }

.availability-slot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  text-align: left;
  padding: var(--space-3);
  margin-bottom: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  cursor: pointer;
  font-family: inherit;
  color: var(--color-ink);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.availability-slot:last-child { margin-bottom: 0; }
.availability-slot:hover { border-color: var(--color-primary); }
.availability-slot.is-selected { border-color: var(--color-primary); background: var(--color-sand); }
.availability-slot:disabled { cursor: not-allowed; opacity: 0.5; }
.availability-slot-time { font-weight: 600; }
.availability-slot-spots { font-size: 0.8125rem; color: var(--color-muted); }

/* Freeform date picker (includes/date_picker.html,
   static/js/date-picker.js) — shares .availability-picker-panel/
   -month-nav for the trigger/panel shell, just with a day-grid body
   instead of a date-grouped slot list. */
.date-picker-weekdays,
.date-picker-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.date-picker-weekdays {
  margin-bottom: var(--space-1);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-muted);
  text-align: center;
}
.date-picker-day {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: none;
  font-family: inherit;
  font-size: 0.875rem;
  color: var(--color-ink);
  cursor: pointer;
}
.date-picker-day:hover:not(:disabled) { background: var(--color-sand); }
.date-picker-day.is-today { font-weight: 700; color: var(--color-primary); }
.date-picker-day.is-selected { background: var(--color-primary); color: #fff; }
.date-picker-day:disabled { color: var(--color-border); cursor: not-allowed; }
.date-picker-day.is-empty { visibility: hidden; pointer-events: none; }
.date-picker-clear {
  display: block;
  margin: var(--space-3) auto 0;
  background: none;
  border: none;
  color: var(--color-muted);
  font-size: 0.8125rem;
  text-decoration: underline;
  cursor: pointer;
}
.date-picker-clear:hover { color: var(--color-primary); }

/* File inputs — ::file-selector-button is broadly supported now and lets
   us restyle just the native "choose file" button in place, no JS/markup
   needed to fake it. */
input[type="file"] { padding: 0.4rem; }
input[type="file"]::file-selector-button {
  font-family: var(--font-sans);
  font-size: 0.875rem;
  font-weight: 600;
  color: #fff;
  background: var(--color-primary);
  border: none;
  border-radius: var(--radius-pill);
  padding: 0.5rem 1rem;
  margin-right: var(--space-3);
  cursor: pointer;
  transition: background-color 0.15s ease;
}
input[type="file"]::file-selector-button:hover { background: var(--color-primary-light); }

/* Date / time — the native picker UI can't be fully rebuilt without a JS
   calendar widget, but the trigger icon can be tinted to match instead of
   the default black glyph. */
input[type="date"], input[type="time"] { cursor: text; }
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator {
  filter: invert(28%) sepia(17%) saturate(1400%) hue-rotate(122deg) brightness(90%);
  cursor: pointer;
}

/* Star rating picker — a real input (radio group), not just the read-only
   includes/star_rating.html display. Source order is 5..1 so the CSS
   general-sibling selector can light up "this star and everything before
   it" purely from :checked/:hover, no JS. */
.star-picker { display: flex; flex-direction: row-reverse; justify-content: flex-end; gap: 0.2rem; }
.star-picker input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.star-picker label {
  width: 2rem;
  height: 2rem;
  margin: 0;
  color: var(--color-border);
  cursor: pointer;
  transition: color 0.1s ease;
}
.star-picker label svg { width: 100%; height: 100%; }
.star-picker input:checked ~ label,
.star-picker input:hover ~ label,
.star-picker label:hover ~ label,
.star-picker label:hover { color: var(--color-star); }
.star-picker input:focus-visible ~ label { outline: 2px solid var(--color-primary-light); outline-offset: 2px; border-radius: 2px; }

/* Alerts / messages ------------------------------------------------------ */
.alert { padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); margin-bottom: var(--space-4); font-size: 0.9375rem; }
.alert-success { background: var(--color-success-bg); color: var(--color-success); }
.alert-error { background: var(--color-danger-bg); color: var(--color-danger); }
.alert-info { background: var(--color-sand); color: var(--color-body); }
.alert-warning { background: var(--color-warning-bg); color: var(--color-warning); }

/* Empty state -------------------------------------------------------------*/
.empty-state { text-align: center; padding: var(--space-10) var(--space-5); color: var(--color-muted); }
.empty-state h3 { color: var(--color-ink); }

/* Pagination ----------------------------------------------------------- */
.pagination { display: flex; justify-content: center; gap: var(--space-2); margin-top: var(--space-8); }
.pagination a, .pagination span {
  min-width: 2.25rem;
  height: 2.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  font-size: 0.875rem;
  color: var(--color-body);
}
.pagination a:hover { background: var(--color-sand); text-decoration: none; }
.pagination .is-current { background: var(--color-primary); color: #fff; font-weight: 600; }

/* Section spacing ------------------------------------------------------- */
/* Longhand, not the `padding` shorthand — .section is almost always used
   together with .container on the same element ("container section"), and
   the shorthand would win the whole property (all four sides) over
   .container's own padding since this file loads after grid.css, silently
   zeroing out its left/right padding at every viewport width. */
.section { padding-top: var(--space-10); padding-bottom: var(--space-10); }
.section-tight { padding-top: var(--space-8); padding-bottom: var(--space-8); }

/* Chat thread ---------------------------------------------------------- */
/* Fixed-height chat panel: .chat-thread scrolls internally, .chat-composer
   stays pinned at the bottom regardless of how many messages pile up. */
.chat-panel { display: flex; flex-direction: column; height: 70vh; max-height: 640px; }
.chat-thread { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4); overflow-y: auto; }
.chat-bubble { max-width: 70%; padding: var(--space-3) var(--space-4); border-radius: var(--radius-lg); background: var(--color-sand); align-self: flex-start; }
.chat-bubble.is-mine { background: var(--color-primary); color: #fff; align-self: flex-end; }
.chat-bubble-meta { font-size: 0.6875rem; opacity: 0.7; margin-top: var(--space-1); }
.chat-composer-form { flex-shrink: 0; }
.chat-composer { display: flex; gap: var(--space-2); padding: var(--space-4); border-top: 1px solid var(--color-border); }
.chat-composer textarea { resize: none; }
.chat-contact-warning { margin: var(--space-3) var(--space-4) 0; }
.chat-contact-warning p { margin: var(--space-1) 0 0; }

/* Cookie consent banner ---------------------------------------------------*/
.consent-banner {
  position: fixed;
  left: var(--space-4);
  right: var(--space-4);
  bottom: var(--space-4);
  z-index: 200;
  max-width: 640px;
  margin: 0 auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-5);
}
.consent-banner p { font-size: 0.875rem; margin-bottom: var(--space-3); }
.consent-banner-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }

/* Homepage hero -------------------------------------------------------- */
.hero-split {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: center;
}
.hero-search {
  display: flex;
  gap: var(--space-2);
  background: var(--color-surface);
  padding: var(--space-2);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-md);
  max-width: 480px;
}
.hero-search input {
  border: none;
  border-radius: var(--radius-pill);
  padding-left: var(--space-4);
}
.hero-search input:focus { outline: none; box-shadow: none; }
.hero-search .btn { flex: none; }

.hero-collage { position: relative; display: none; }
.collage-main {
  position: absolute;
  top: 0;
  right: 0;
  width: 62%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.collage-small {
  position: absolute;
  width: 36%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  border: 5px solid var(--color-paper);
}
.collage-small-1 { top: -6%; left: 0; }
.collage-small-2 { bottom: -6%; left: 8%; }

/* Below 900px the desktop collage's absolute-positioned overlap doesn't
   have a sane height to anchor to, so it stays hidden (.hero-collage's
   default display:none) and this simpler strip takes over instead — a
   real photo, visible in the first screen on a phone, not the desktop
   layout guessing at a small-screen height. Inspired by withlocals'
   mobile home screen (partial image peeking below the search bar,
   inviting a scroll) but in this site's own rounded-card, shadowed style
   rather than their edge-to-edge treatment. */
.hero-mobile-collage {
  display: flex;
  gap: var(--space-3);
  height: 180px;
  margin-top: var(--space-6);
}
.hero-mobile-collage img {
  border-radius: var(--radius-lg);
  object-fit: cover;
  box-shadow: var(--shadow-md);
  height: 100%;
  min-width: 0;
  width: 100%;
}
.hero-mobile-collage img:first-child { flex: 1.4; }
.hero-mobile-collage img:nth-child(2) { flex: 1; }

@media (min-width: 900px) {
  .hero-split { grid-template-columns: 1fr 1fr; }
  .hero-collage { display: block; height: 460px; }
  .hero-mobile-collage { display: none; }
}

/* Category cards --------------------------------------------------------- */
.category-card {
  position: relative;
  display: block;
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  box-shadow: var(--shadow-sm);
}
.category-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.35s ease;
}
.category-card:hover img { transform: scale(1.05); }
.category-card:hover { text-decoration: none; }
.category-card::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(14, 47, 41, 0.8), rgba(14, 47, 41, 0) 60%);
}
.category-card-label {
  position: absolute;
  left: var(--space-4);
  bottom: var(--space-4);
  z-index: 1;
  color: #fff;
  font-family: var(--font-serif);
  font-size: 1.25rem;
}

/* Editorial image + text split ------------------------------------------- */
.editorial-split {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: center;
}
.editorial-image {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
@media (min-width: 900px) {
  .editorial-split { grid-template-columns: 1fr 1fr; }
  /* Zigzag layout for a run of several editorial-split sections in a row
     (e.g. how_it_works_page.html's steps) — alternates which side the
     photo sits on instead of every section looking identical. */
  .editorial-split.is-reversed .editorial-image { order: 2; }
}

/* Centered copy column (how_it_works_page.html's steps) — the icon,
   "Step N" eyebrow and heading read as a centered unit within their half
   of the split, rather than pinned to the column's inner edge. */
.step-copy { text-align: center; }
.step-copy .icon-badge { margin: 0 auto var(--space-3); }

/* Scroll-reveal (static/js/scroll-reveal.js) — starts every
   [data-scroll-reveal] element lower and transparent, animates up into
   place the first time it scrolls into view. */
[data-scroll-reveal] {
  opacity: 0;
  transform: translateY(32px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
[data-scroll-reveal].is-visible { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  [data-scroll-reveal] { opacity: 1; transform: none; transition: none; }
}

/* CTA band ----------------------------------------------------------------*/
.cta-band {
  position: relative;
  background-size: cover;
  background-position: center;
}
.cta-band-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(14, 47, 41, 0.92) 10%, rgba(14, 47, 41, 0.55) 60%, rgba(14, 47, 41, 0.25) 100%);
}
.cta-band-content {
  position: relative;
  /* Longhand — see the note on .section above; this is paired with
     .container on its element too (templates/cms/home_page.html). */
  padding-top: var(--space-12);
  padding-bottom: var(--space-12);
  max-width: 520px;
}
.cta-band-content p { color: #dde7e2; }

/* Tabbed carousel ---------------------------------------------------------
   Our own lightweight replacement for a common "tabs switch a horizontal
   carousel" pattern — plain CSS scroll-snap + a few lines of Alpine
   (static/js/tabbed-carousel.js), no external carousel library. */
.tabbed-carousel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
.tabs { display: flex; gap: var(--space-5); overflow-x: auto; }
.tab-button {
  background: none;
  border: none;
  padding: var(--space-2) 0;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--color-muted);
  border-bottom: 3px solid transparent;
  cursor: pointer;
  white-space: nowrap;
}
.tab-button.is-active, .tab-button:hover { color: var(--color-primary); border-bottom-color: var(--color-accent); }

.carousel-arrows { display: flex; gap: var(--space-2); flex: none; }
.carousel-arrow {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--color-ink);
}
.carousel-arrow svg { width: 18px; height: 18px; }
.carousel-arrow:hover { border-color: var(--color-primary); color: var(--color-primary); }

.carousel-row {
  display: flex;
  gap: var(--space-5);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--space-2);
  scrollbar-width: none;
}
.carousel-row::-webkit-scrollbar { display: none; }
.carousel-row > * { flex: 0 0 280px; scroll-snap-align: start; }

/* Icon badges + step/point cards ------------------------------------------ */
.icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--color-sand);
  color: var(--color-primary);
  flex: none;
}
.icon-badge svg { width: 26px; height: 26px; }
.icon-badge-accent { background: #f7ecd9; color: var(--color-accent-dark); }

.icon-card {
  position: relative;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
.icon-card .icon-badge { margin-bottom: var(--space-4); }
.icon-card h4 { margin-bottom: var(--space-2); }
.icon-card p { margin-bottom: 0; }
.icon-card-number {
  position: absolute;
  top: var(--space-5);
  right: var(--space-6);
  font-family: var(--font-serif);
  font-size: 1.75rem;
  color: var(--color-border);
}

/* Quantity stepper — our replacement for browser-default number inputs */
.stepper-control {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  padding: var(--space-1);
}
.stepper-btn {
  width: 2.25rem;
  height: 2.25rem;
  flex: none;
  border: none;
  border-radius: 50%;
  background: var(--color-sand);
  color: var(--color-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.stepper-btn svg { width: 16px; height: 16px; }
.stepper-btn:hover:not(:disabled) { background: var(--color-primary); color: #fff; }
.stepper-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.stepper-input {
  flex: 1;
  border: none;
  background: transparent;
  text-align: center;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 1.0625rem;
  color: var(--color-ink);
  padding: 0;
}
.stepper-input:focus { outline: none; box-shadow: none; }

/* Tour creation wizard ----------------------------------------------------
   Two-column layout: form content + a sidebar tracking step progress. */
.wizard-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: var(--space-8);
  align-items: start;
}
.wizard-sidebar { position: sticky; top: var(--space-6); }

/* Must come after the unconditional .wizard-sidebar rule above — same
   specificity, so with this block first (as it originally was), the
   later unconditional rule always won the cascade regardless of whether
   the media query matched, silently overriding position: static below. */
@media (max-width: 900px) {
  .wizard-layout { grid-template-columns: 1fr; }
  /* The sticky position above is only correct in the two-column desktop
     layout, where the sidebar stays put in its own narrow column while
     content scrolls beside it. Collapsed to one column, the sidebar
     becomes a full-width block sitting above the content — sticky there
     just pins the whole 8-step list over the page as you scroll. */
  .wizard-sidebar { order: -1; position: static; }
}

.wizard-progress-track {
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--color-sand);
  overflow: hidden;
  margin-bottom: var(--space-2);
}
.wizard-progress-fill {
  height: 100%;
  background: var(--color-primary);
  border-radius: var(--radius-pill);
  transition: width 0.25s ease;
}
.wizard-progress-label { font-size: 0.8125rem; color: var(--color-muted); margin-bottom: var(--space-5); }

.wizard-steps { list-style: none; margin: 0; padding: 0; }
.wizard-step-item { position: relative; padding-left: var(--space-8); padding-bottom: var(--space-5); }
.wizard-step-item::before {
  /* connecting line down to the next step */
  content: "";
  position: absolute;
  left: 13px;
  top: 28px;
  bottom: 0;
  width: 1px;
  background: var(--color-border);
}
.wizard-step-item:last-child::before { display: none; }
.wizard-step-marker {
  position: absolute;
  left: 0;
  top: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8125rem;
  font-weight: 700;
  background: var(--color-surface);
  border: 1.5px solid var(--color-border);
  color: var(--color-muted);
}
.wizard-step-marker svg { width: 14px; height: 14px; }
.wizard-step-item.is-complete .wizard-step-marker { background: var(--color-success); border-color: var(--color-success); color: #fff; }
.wizard-step-item.is-current .wizard-step-marker { border-color: var(--color-primary); color: var(--color-primary); }
.wizard-step-link { font-weight: 500; color: var(--color-body); text-decoration: none; }
.wizard-step-item.is-current .wizard-step-link { color: var(--color-primary); font-weight: 700; }
.wizard-step-item.is-locked .wizard-step-link { color: var(--color-muted); pointer-events: none; cursor: default; }
.wizard-step-link:hover { color: var(--color-primary); text-decoration: none; }

.wizard-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-border);
}

/* Requirements checklist — shown before a guide starts creating a tour */
.checklist { list-style: none; margin: 0; padding: 0; }
.checklist-item { display: flex; gap: var(--space-4); padding: var(--space-3) 0; }
.checklist-number {
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-sand);
  color: var(--color-primary);
  font-weight: 700;
  font-size: 0.8125rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.checklist-item h5 { margin: 0 0 0.15rem; font-size: 0.9375rem; }
.checklist-item p { margin: 0; font-size: 0.875rem; color: var(--color-muted); }

/* Radio cards — illustrated single-choice picker (category, booking mode,
   cancellation policy). Real radio inputs under the hood, visually hidden;
   the whole card is the label so it's keyboard- and screen-reader-friendly. */
.radio-card-group { display: grid; gap: var(--space-3); }
.radio-card-group.is-columns { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.radio-card { position: relative; }
.radio-card input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}
.radio-card label {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  margin: 0;
  padding: var(--space-4) var(--space-5);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.radio-card label:hover { border-color: var(--color-primary-light); }
.radio-card input:focus-visible + label { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.radio-card input:checked + label { border-color: var(--color-primary); background: var(--color-success-bg); }
.radio-card-icon {
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--color-sand);
  color: var(--color-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.radio-card-icon svg { width: 20px; height: 20px; }
.radio-card-body { flex: 1; }
.radio-card-title { font-weight: 600; color: var(--color-ink); margin-bottom: 0.15rem; }
.radio-card-desc { font-size: 0.8125rem; color: var(--color-muted); }
.radio-card-check {
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1.5px solid var(--color-border);
  margin-top: 2px;
}
.radio-card input:checked + label .radio-card-check {
  border-color: var(--color-primary);
  background: var(--color-primary);
  position: relative;
}
.radio-card input:checked + label .radio-card-check::after {
  content: "";
  position: absolute;
  left: 6px;
  top: 2px;
  width: 5px;
  height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* City/country autocomplete — templates/includes/city_autocomplete.html */
.autocomplete { position: relative; }
.autocomplete-panel {
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  max-height: 280px;
  overflow-y: auto;
}
.autocomplete-list { list-style: none; margin: 0; padding: var(--space-1); }
.autocomplete-option {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  border: none;
  background: transparent;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  color: var(--color-ink);
}
.autocomplete-option:hover, .autocomplete-option:focus-visible { background: var(--color-sand); outline: none; }
.autocomplete-option-secondary { font-size: 0.8125rem; color: var(--color-muted); flex: none; }
.autocomplete-empty { padding: var(--space-3); margin: 0; font-size: 0.8125rem; color: var(--color-muted); }

/* Language pill picker (includes/language_autocomplete.html) — the
   bordered box IS the "field", styled to look like one input even though
   it's a wrapping flex row of pills + a borderless text input. */
.language-pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
.language-pills:focus-within { border-color: var(--color-primary); }
.language-pills input {
  flex: 1 1 120px;
  min-width: 120px;
  border: none;
  outline: none;
  padding: var(--space-1);
  font-family: inherit;
  font-size: 0.9375rem;
  background: transparent;
}
.language-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.3rem 0.4rem 0.3rem 0.75rem;
  border-radius: var(--radius-pill);
  background: var(--color-sand);
  color: var(--color-primary);
  font-size: 0.8125rem;
  font-weight: 600;
  white-space: nowrap;
}
.language-pill button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.language-pill button:hover { background: rgba(22, 68, 60, 0.15); }

/* Theme checkboxes — grouped, optional discovery tags (wizard_basics.html) */
.theme-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
}
.theme-group h5 { margin: 0 0 var(--space-2); font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-muted); }
.theme-checkboxes { display: flex; flex-direction: column; gap: var(--space-2); }

/* Drag-and-drop photo upload (wizard_photos.html) */
.dropzone {
  border: 2px dashed var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-sand);
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.dropzone.is-dragging { border-color: var(--color-primary); background: var(--color-success-bg); }
.dropzone-label {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-8) var(--space-5);
  cursor: pointer;
  text-align: center;
}
.dropzone-input { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; }
.dropzone-icon { color: var(--color-primary); }
.dropzone-icon svg { width: 32px; height: 32px; }
.dropzone-text { font-size: 0.9375rem; color: var(--color-body); }
.dropzone-browse { color: var(--color-primary); font-weight: 600; text-decoration: underline; }
.dropzone-hint { font-size: 0.8125rem; color: var(--color-muted); }

.photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--space-3); }
.photo-thumb { position: relative; aspect-ratio: 1; border-radius: var(--radius-md); overflow: hidden; }
.photo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-thumb-remove { position: absolute; top: var(--space-2); right: var(--space-2); margin: 0; }
.photo-thumb-remove button {
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(26, 36, 32, 0.65);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.photo-thumb-remove button:hover { background: var(--color-danger); }
.photo-thumb-remove svg { width: 14px; height: 14px; }

.photo-thumb-cover-badge {
  position: absolute;
  bottom: var(--space-2);
  left: var(--space-2);
  background: var(--color-primary);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 0.25rem 0.6rem;
  border-radius: var(--radius-pill);
}
.photo-thumb-set-cover { position: absolute; bottom: var(--space-2); left: var(--space-2); margin: 0; }
.photo-thumb-set-cover button {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.25rem 0.6rem;
  border: none;
  border-radius: var(--radius-pill);
  background: rgba(26, 36, 32, 0.65);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  cursor: pointer;
}
.photo-thumb-set-cover button:hover { background: var(--color-primary); }
.photo-thumb-set-cover svg { width: 12px; height: 12px; }

/* Pickup-area map picker (wizard_pickup.html) */
.map-picker {
  height: 320px;
  width: 100%;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--color-border);
}

/* Custom-styled native range input — used for pickup radius */
.range-slider {
  width: 100%;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--color-sand);
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
}
.range-slider::-webkit-slider-runnable-track { height: 6px; border-radius: var(--radius-pill); background: transparent; }
.range-slider::-moz-range-track { height: 6px; border-radius: var(--radius-pill); background: transparent; }
.range-slider::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  margin-top: -7px;
  border-radius: 50%;
  background: var(--color-primary);
  border: 3px solid #fff;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
}
.range-slider::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--color-primary);
  border: 3px solid #fff;
  box-shadow: var(--shadow-sm);
  cursor: pointer;
}
.range-slider:focus { outline: none; }
.range-slider:focus-visible::-webkit-slider-thumb,
.range-slider:focus-visible::-moz-range-thumb { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* Itinerary timeline (wizard_itinerary.html) */
.itinerary-timeline { list-style: none; margin: 0; padding: 0; }
.itinerary-stop { position: relative; padding-left: var(--space-8); padding-bottom: var(--space-4); }
.itinerary-stop::before {
  content: "";
  position: absolute;
  left: 13px;
  top: 28px;
  bottom: 0;
  border-left: 2px dashed var(--color-border);
}
.itinerary-stop:last-child::before { display: none; }
.itinerary-stop-marker {
  position: absolute;
  left: 0;
  top: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8125rem;
  font-weight: 700;
}
.itinerary-stop-body {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.itinerary-stop-title { font-weight: 600; margin: 0 0 0.15rem; }
.itinerary-stop-meta { font-size: 0.8125rem; color: var(--color-muted); }
.itinerary-stop-desc { font-size: 0.875rem; color: var(--color-body); margin: var(--space-2) 0 0; }
.itinerary-stop-actions { display: flex; flex-direction: column; gap: var(--space-1); flex: none; }
.itinerary-stop-actions form { margin: 0; }
.itinerary-stop-actions button {
  background: transparent;
  border: none;
  color: var(--color-muted);
  cursor: pointer;
  padding: var(--space-1);
  border-radius: var(--radius-sm);
  display: inline-flex;
}
.itinerary-stop-actions button:hover:not(:disabled) { background: var(--color-sand); color: var(--color-ink); }
.itinerary-stop-actions button:disabled { opacity: 0.3; cursor: not-allowed; }

/* Weekday picker — availability recurrence rule (wizard_availability.html) */
.weekday-picker { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.weekday-toggle input[type="checkbox"] { position: absolute; opacity: 0; width: 1px; height: 1px; }
.weekday-toggle label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1.5px solid var(--color-border);
  background: var(--color-surface);
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
  color: var(--color-body);
  transition: border-color 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}
.weekday-toggle input:checked + label { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }
.weekday-toggle input:focus-visible + label { outline: 2px solid var(--color-primary); outline-offset: 2px; }

.rule-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-3);
}

/* Event Calendar theming (github.com/vkurko/calendar) — every custom
   property it exposes, mapped to our own tokens. includes/event_calendar.html */
.ec {
  --ec-bg-color: var(--color-surface);
  --ec-text-color: var(--color-ink);
  --ec-border-color: var(--color-border);
  --ec-button-bg-color: var(--color-surface);
  --ec-button-border-color: var(--color-border);
  --ec-button-text-color: var(--color-ink);
  --ec-button-active-bg-color: var(--color-sand);
  --ec-button-active-border-color: var(--color-primary);
  --ec-button-active-text-color: var(--color-primary);
  --ec-today-bg-color: var(--color-sand);
  --ec-highlight-color: var(--color-sand);
  --ec-event-bg-color: var(--color-primary);
  --ec-event-text-color: #fff;
  --ec-bg-event-color: var(--color-sand);
  --ec-now-indicator-color: var(--color-accent);
  --ec-popup-bg-color: var(--color-surface);
  font-family: var(--font-sans);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.ec-day {
  cursor: pointer;
  transition: background-color 0.12s ease, box-shadow 0.12s ease;
}
.ec-day:hover { background-color: var(--color-sand); box-shadow: inset 0 0 0 1px var(--color-border); }
.ec-day.ec-today:hover { box-shadow: inset 0 0 0 1px var(--color-primary-light); }
.ec-day-number { text-align: right; padding: var(--space-1) var(--space-2) 0; font-size: 0.875rem; }
.ec-day-badge {
  display: inline-block;
  margin: var(--space-1) var(--space-2) var(--space-2);
  padding: 0.15rem 0.55rem;
  background: var(--color-primary);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 600;
  border-radius: var(--radius-pill);
}
.event-calendar-day-panel {
  margin-top: var(--space-5);
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}
.event-calendar-day-panel h4 { margin: 0 0 var(--space-3); }

/* Location settings strip (dashboard/requests_inbox.html) — deliberately
   flat and sand-toned with a dashed border, unlike the elevated white
   .card-body request items below it: this is a filter/preference control,
   not a piece of content, and it needs to read that way at a glance. */
.location-settings {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4) var(--space-5);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-6);
  background: var(--color-sand);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
}
.location-settings-header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  flex: 0 0 240px;
}
.location-settings-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-primary);
}
.location-settings-icon svg { width: 16px; height: 16px; }
.location-settings-body {
  flex: 1 1 280px;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}

/* Location subscription chips — white pills read as tags against the
   settings strip's sand background (they'd disappear against the old
   all-white card). */
.location-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.3rem 0.4rem 0.3rem 0.75rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  font-size: 0.8125rem;
  color: var(--color-ink);
}
.location-chip form { margin: 0; }
.location-chip button {
  width: 20px;
  height: 20px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--color-muted);
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.location-chip button:hover { background: var(--color-sand); color: var(--color-ink); }

/* Proposal negotiation thread ------------------------------------------ */
.proposal-thread-timeline { padding-left: var(--space-4); border-left: 2px solid var(--color-border); }
.proposal-round { padding: var(--space-2) 0; }
.proposal-round + .proposal-round { border-top: 1px dashed var(--color-border); }

/* Site-wide dismissible banner (SiteBanner) ------------------------------
   Sits in normal document flow above the nav — not fixed/sticky, so it
   scrolls away like any other content rather than permanently eating
   viewport height on small screens. */
.site-banner { background: var(--color-primary); color: var(--color-paper); }
.site-banner-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-5);
  text-align: center;
}
.site-banner-message { margin: 0; font-size: 0.9375rem; }
.site-banner-cta { color: var(--color-accent); font-weight: 600; text-decoration: underline; margin-left: var(--space-2); }
.site-banner-cta:hover { color: var(--color-paper); }
.site-banner-dismiss {
  flex: none;
  background: none;
  border: none;
  padding: var(--space-1);
  margin: 0;
  color: var(--color-paper);
  opacity: 0.8;
  cursor: pointer;
  line-height: 0;
}
.site-banner-dismiss:hover { opacity: 1; }
.site-banner-dismiss svg { width: 18px; height: 18px; }
@media (max-width: 600px) {
  .site-banner-inner { flex-wrap: wrap; padding: var(--space-3) var(--space-4); }
  .site-banner-message { font-size: 0.875rem; }
}
