:root {
  /* Matches the production build's own default easing, read from
     mirror/assets/index-Cth6RUGg.css (--default-transition-timing-function). */
  --ease-out: cubic-bezier(0.4, 0, 0.2, 1);
  /* Colors below are sampled directly from the original deployed build (computed
     styles + Tailwind arbitrary-value classes) — keep these exact if resyncing. */
  --teal-500: #12b0bd;
  --teal-600: #0aabb8;
  --teal-700: #0a7cb8;
  --green-600: #22a45d;
  --bg: #ffffff;
  --bg-subtle: #ffffff;
  --surface: #ffffff;
  --surface-2: #f1f3f5;
  --text: #1c1c1c;
  --text-muted: #9aa3af;
  --text-faint: #9aa3af;
  --text-muted-2: #5a6272;
  --border: #eaecef;
  --accent: var(--teal-600);
  --accent-contrast: #ffffff;
  --danger: #e0524c;
  --ai-banner-from: #eaf6f8;
  --ai-banner-to: #f0f7fb;
  --ai-banner-border: #cdeaee;
  --ai-banner-title: #0a5a78;
  --ai-banner-sub: #4a8aa0;
  --active-tint: #eef8fa;
  --shadow: 0 1px 3px rgba(16, 24, 32, 0.06), 0 1px 2px rgba(16, 24, 32, 0.08);
  --shadow-lg: 0 8px 24px rgba(16, 24, 32, 0.12);
  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 20px;
  --font-en: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
  --font-ar: "Noto Sans Arabic", ui-sans-serif, system-ui, sans-serif;
}

[data-theme="dark"] {
  --bg: #10181b;
  --bg-subtle: #0c1315;
  --surface: #172226;
  --surface-2: #1e2b30;
  --text: #eef2f3;
  --text-muted: #9fb0b6;
  --text-faint: #6d7d83;
  --border: #263338;
  --shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 8px 28px rgba(0, 0, 0, 0.5);
  /* The AI banner was left on its light-mode palette, so it rendered as a pale
     box with near-black text on the dark detail page. */
  --ai-banner-from: #13323a;
  --ai-banner-to: #16262f;
  --ai-banner-border: #22505c;
  --ai-banner-title: #8fe1ec;
  --ai-banner-sub: #7ba9b6;
}

* { box-sizing: border-box; }
html, body {
  height: 100%;
  margin: 0;
  background: var(--bg-subtle);
  -webkit-tap-highlight-color: transparent;
}
/* Lock the underlying page while the chat modal is open, so scroll/touch
   gestures on the overlay can never bleed through to the page behind it. */
body.chat-open {
  overflow: hidden;
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  /* Belt to the overlay's braces: anything that manages to show past the
     overlay — keyboard accessory strip, rubber-band overscroll, the sliver
     below a shrunk visual viewport — lands on the chat's own base colour
     rather than the white page. */
  background: #07191f;
}
body {
  font-family: var(--font-en);
  color: var(--text);
}
body[dir="rtl"] { font-family: var(--font-ar); }
button { font-family: inherit; }
img { -webkit-user-drag: none; user-select: none; }

#app { height: 100%; }

.phone {
  max-width: 600px;
  margin: 0 auto;
  min-height: 100vh;
  background: var(--bg);
  position: relative;
  overflow-x: hidden;
}

/* ---------- generic bits ---------- */
.icon-btn {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}
.icon-btn:active { transform: scale(0.94); }
.icon-btn svg { width: 18px; height: 18px; }
.pill-btn {
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  white-space: nowrap;
}
.pill-btn svg { width: 15px; height: 15px; }
.pill-btn.active { background: var(--accent); color: var(--accent-contrast); border-color: var(--accent); }
.btn-primary {
  background: var(--accent);
  color: var(--accent-contrast);
  border: none;
  border-radius: 999px;
  padding: 14px 24px;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
}
.btn-primary:active { opacity: 0.85; }
.btn-primary:disabled { opacity: 0.5; cursor: default; }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.currency { display: inline-flex; align-items: center; gap: 3px; }
.currency .sar { display: inline-flex; align-items: center; opacity: 0.85; }
.currency .sar-icon { width: 0.7em; height: 0.78em; display: block; }

/* ---------- splash ---------- */
.splash {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 64px 24px 40px;
  text-align: center;
}
.splash-logo {
  width: 100px; height: 100px;
  border-radius: 24px;
  background: linear-gradient(160deg, var(--teal-500), var(--teal-700));
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 40px rgba(74, 155, 168, 0.45);
  margin-bottom: 20px;
}
.splash-logo svg { width: 48px; height: 48px; color: #fff; }
.splash h1 { font-size: 30px; margin: 0 0 10px; letter-spacing: -0.02em; }
.splash .tagline { color: var(--text-muted); margin: 2px 0; font-size: 15px; }
.splash-section { width: 100%; max-width: 420px; margin-top: 40px; }
.splash-section-label {
  font-size: 13px; color: var(--text-faint); margin-bottom: 12px;
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.seg-toggle {
  display: flex; border: 1px solid var(--border); border-radius: 999px;
  padding: 4px; background: var(--surface-2); gap: 4px;
}
.seg-toggle button {
  flex: 1; border: none; background: transparent; border-radius: 999px;
  padding: 12px 10px; font-weight: 700; font-size: 15px; color: var(--text-muted);
  cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 8px;
}
.seg-toggle button.active { background: var(--surface); color: var(--text); box-shadow: var(--shadow); }
.lang-row {
  display: flex; align-items: center; justify-content: space-between;
  border: 2px solid var(--border); border-radius: var(--radius-lg);
  padding: 16px 20px; margin-top: 14px; cursor: pointer; background: var(--surface);
  text-align: start; transition: border-color 0.15s, background-color 0.15s;
}
.lang-row:active, .lang-row:hover { border-color: var(--accent); background: var(--active-tint); }
.lang-row .flag { font-size: 26px; margin-inline-end: 14px; }
.lang-row .lang-main { flex: 1; }
.lang-row .lang-name { font-weight: 700; font-size: 16px; }
.lang-row .lang-sub { color: var(--text-muted); font-size: 13px; margin-top: 2px; }
.radio {
  width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--border);
  flex-shrink: 0;
}

/* ---------- top bars ---------- */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px; gap: 12px; position: sticky; top: 0; background: var(--bg);
  z-index: 5;
}
.topbar .title-block { text-align: center; flex: 1; }
.topbar h2 { margin: 0; font-size: 17px; }
.topbar .sub { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

/* ---------- filter bar ---------- */
.filter-bar {
  display: flex; gap: 10px; padding: 0 16px 16px; overflow-x: auto;
  border-bottom: 1px solid var(--border);
}

/* ---------- hotel list ---------- */
.hotel-list { padding: 16px; display: flex; flex-direction: column; gap: 20px; }
.hotel-card {
  border: 1px solid var(--border); border-radius: 16px;
  overflow: hidden; cursor: pointer; background: var(--surface);
}
.hotel-card:active { transform: scale(0.99); }
.hotel-card img { width: 100%; height: 220px; object-fit: cover; display: block; }
.hotel-card-body { padding: 14px 16px 16px; }
.hotel-card-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.hotel-card-name {
  font-size: 17px; font-weight: 700; margin: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; max-width: 100%;
}
.hotel-card-meta { color: var(--text-muted); font-size: 13px; margin-top: 4px; }
.hotel-card-price { text-align: end; flex-shrink: 0; }
.hotel-card-price .amount { font-size: 17px; font-weight: 700; }
.hotel-card-price .per { font-size: 12px; color: var(--text-muted); }
.hotel-card-rating { display: flex; align-items: center; gap: 6px; margin-top: 10px; font-size: 14px; }
.hotel-card-rating svg { width: 15px; height: 15px; flex-shrink: 0; }
.hotel-card-rating .score-star { color: var(--green-600); display: inline-flex; }
.hotel-card-rating .score-star svg { width: 14px; height: 14px; }
.score-badge { color: var(--green-600); font-weight: 700; font-size: 14px; }
.score-word { font-weight: 500; font-size: 13px; }
.score-count { color: var(--text-muted); font-size: 13px; }

/* ---------- detail hero ---------- */
.detail-hero { position: relative; }
.detail-hero-main { width: 100%; height: 300px; object-fit: cover; display: block; cursor: pointer; }
.detail-hero-thumbs { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; height: 150px; overflow: hidden; }
.detail-hero-thumbs img { width: 100%; height: 100%; min-width: 0; object-fit: cover; display: block; cursor: pointer; }
.detail-hero-thumbs .thumb-wrap { position: relative; cursor: pointer; height: 100%; }
.thumb-overlay {
  position: absolute; inset: 0; background: rgba(10, 16, 18, 0.35);
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 18px;
}
.hero-back-btn { position: absolute; top: 16px; inset-inline-start: 16px; z-index: 2; }
/* Horizontal chevrons encode reading direction, so they must mirror in RTL:
   "back" points right and a forward chip chevron points left in Arabic.
   Vertical chevrons (accordion carets) are direction-neutral and must NOT
   be flipped, hence the narrow selectors. */
[dir="rtl"] [data-action="back"] svg,
[dir="rtl"] .followup-chip svg,
[dir="rtl"] .chat-revrail-cap svg,
[dir="rtl"] .ai-banner .chev svg { transform: scaleX(-1); }
.hero-actions { position: absolute; top: 16px; inset-inline-end: 16px; z-index: 2; display: flex; gap: 8px; }

.detail-body { padding: 20px 16px 120px; }
.detail-title-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.detail-title-row h1 { font-size: 24px; margin: 0; }
.detail-actions { display: flex; gap: 8px; flex-shrink: 0; }
.detail-meta { color: var(--text-muted); font-size: 14px; margin-top: 6px; }

/* ---------- animated gradient stroke (AI banner + chat FAB) ----------
   A soft drop shadow to lift the element, plus a thin animated stroke: a
   linear gradient sweeping along a MASKED ring just outside the box.
   The mask is what keeps this a stroke and not a fill — mask-composite:exclude
   knocks the middle out, so the gradient only ever paints the ring.
   (A negative z-index would not work: negative-z children still paint above
   their host's own background, which blanked out the banner.) */
@keyframes ai-stroke-sweep {
  0%   { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}

.ai-glow { position: relative; box-shadow: 0 4px 16px rgba(10, 171, 184, 0.18); }
.ai-glow::before {
  content: "";
  position: absolute;
  inset: -1.5px;
  padding: 1.5px;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    transparent 20%,
    var(--teal-500) 42%,
    #9ceaf3 50%,
    var(--teal-500) 58%,
    transparent 80%
  );
  background-size: 200% 100%;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: ai-stroke-sweep 3s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .ai-glow::before { animation: none; }
}

.ai-banner {
  display: flex; align-items: center; gap: 12px; margin-top: 20px;
  background: linear-gradient(to right, var(--ai-banner-from), var(--ai-banner-to));
  border: 1px solid var(--ai-banner-border);
  border-radius: 16px; padding: 12px 16px; cursor: pointer;
}
.ai-banner .ai-icon {
  width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0;
  background: linear-gradient(135deg, var(--teal-600), var(--teal-700));
  display: flex; align-items: center; justify-content: center; color: #fff;
}
.ai-banner .ai-icon svg { width: 20px; height: 20px; }
.ai-banner .chev svg { width: 18px; height: 18px; display: block; }
.ai-banner .ai-text { flex: 1; }
.ai-banner .ai-title { font-weight: 700; color: var(--ai-banner-title); font-size: 14px; }
.ai-banner .ai-sub { font-size: 12px; color: var(--ai-banner-sub); margin-top: 2px; }
.ai-banner .chev { color: var(--accent); }

.rating-row { display: flex; gap: 12px; margin-top: 20px; align-items: stretch; }
.rating-summary-card {
  background: var(--surface-2); border-radius: var(--radius-md); padding: 16px; flex: 1;
  display: flex; flex-direction: column;
}
.rating-breakdown-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-md); padding: 16px; flex: 1;
}
.rating-summary-card .big-score { font-size: 30px; font-weight: 800; display: flex; align-items: center; gap: 8px; }
.rating-summary-card .big-score svg { color: var(--green-600); width: 20px; height: 20px; }
.rating-summary-card .based-on { color: var(--text-muted); font-size: 13px; margin-top: 4px; }
.rating-summary-card .quote { font-weight: 700; font-size: 12px; margin-top: 12px; line-height: 1.4; }
.rating-summary-card .see-all {
  color: var(--accent); font-weight: 700; font-size: 13px; margin-top: 10px; cursor: pointer;
  background: none; border: none; padding: 0; font-family: inherit; text-align: center;
}
.breakdown-item { margin-bottom: 12px; }
.breakdown-item:last-child { margin-bottom: 0; }
.breakdown-item .b-row { display: flex; align-items: center; gap: 6px; font-size: 12px; margin-bottom: 6px; }
.breakdown-item .b-row .b-icon svg { width: 15px; height: 15px; color: var(--text-muted); display: block; }
.breakdown-item .b-row .b-score { margin-inline-start: auto; font-weight: 700; }
.bar-track { height: 6px; border-radius: 4px; background: var(--border); overflow: hidden; }
.bar-fill { height: 100%; background: var(--accent); border-radius: 4px; }

.section-heading { font-size: 19px; font-weight: 800; margin: 28px 0 14px; }
.review-scroll { display: flex; gap: 12px; overflow-x: auto; margin: 0 -16px; padding: 0 16px 4px; }
.review-card {
  flex: 0 0 auto; width: 78%; max-width: 300px; border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 14px; background: var(--surface);
}
.review-score {
  display: flex; align-items: center; gap: 5px; color: var(--green-600); font-weight: 800; font-size: 14px;
  margin-bottom: 10px;
}
.review-score svg { width: 15px; height: 15px; }
.review-text {
  font-size: 14px; line-height: 1.5; margin: 0 0 10px; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.review-author { font-size: 13px; color: var(--text-muted); }

.location-address { color: var(--text-muted); font-size: 14px; margin-bottom: 12px; }

/* ---------- real interactive maps (Leaflet + OpenStreetMap) ---------- */
/* z-index:0 here (not just position:relative) is load-bearing: it establishes
   a new stacking context so the expand button's z-index below is contained
   within this component and can never bleed through an unrelated ancestor's
   stacking context (e.g. the chat modal overlay sitting on top of a detail
   page that's still rendered behind it). */
.real-map-wrap { position: relative; z-index: 0; }
.real-map {
  height: 220px; width: 100%; border-radius: var(--radius-md); overflow: hidden;
  position: relative; z-index: 0; background: var(--surface-2);
}
/* The in-chat map. Shorter than the detail-page map — inside a reply it is
   orientation, not the main event, and 200px pushed the landmark cards and the
   review rail below the fold on a phone. */
.real-map-sm { height: 140px; }
.map-expand-btn {
  position: absolute; top: 10px; inset-inline-end: 10px; z-index: 5; width: 34px; height: 34px;
  background: var(--surface); box-shadow: var(--shadow);
}
.map-expand-btn svg { width: 15px; height: 15px; }

/* Minimal CARTO Positron/Dark Matter basemap (light/dark theme respectively):
   keep it quiet so custom pins/cards read as the focal layer, not the map
   chrome underneath them. */
.real-map .leaflet-control-attribution {
  background: var(--surface); opacity: 0.85; font-size: 9px; color: var(--text-faint);
}

/* Dark theme: brighten + tint the (quite black) dark_all tiles toward the
   app's navy palette instead of using them at full strength. */
.map-theme-dark .leaflet-tile-pane {
  filter: brightness(1.4) sepia(0.65) hue-rotate(175deg) saturate(2.2) contrast(0.95);
}

/* Teardrop pins built from a rotated square (classic CSS trick): the head is
   a circle-cornered square rotated -45deg, the icon inside is counter-rotated
   back to upright so it never reads sideways. */
.map-pin-wrap { background: none; border: none; }
.map-pin {
  width: 100%; height: 100%; border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 8px rgba(16,24,32,0.28); border: 2px solid var(--surface);
}
.map-pin-icon { transform: rotate(45deg); display: flex; }
.map-pin-icon svg { width: 15px; height: 15px; }
.map-pin-stay { background: var(--accent); color: #fff; }
.map-pin-stay .map-pin-icon svg { width: 17px; height: 17px; }
.map-pin-landmark { background: var(--surface); color: var(--accent); border-color: var(--accent); }

/* Branded card overlay, positioned by JS (not Leaflet's L.Popup — see
   openPinPopup/positionPinCard) so it can flip above/below the pin. */
.pin-card {
  position: absolute; z-index: 650; transform: translate(-50%, calc(-100% - 14px));
  background: var(--surface); border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
  overflow: hidden; pointer-events: auto;
}
.pin-card-below { transform: translate(-50%, 14px); }
.map-card { display: flex; align-items: center; gap: 10px; padding: 8px; min-width: 160px; }
.map-card-plain { padding: 8px; min-width: 210px; align-items: flex-start; }
.map-card-plain .map-card-title { white-space: nowrap; }
.map-card-thumb { width: 44px; height: 44px; border-radius: var(--radius-sm); object-fit: cover; flex-shrink: 0; }
.map-card-body { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.map-card-title { font-size: 13px; font-weight: 700; color: var(--text); font-family: var(--font-en); line-height: 1.25; }
.map-card-sub { font-size: 12px; color: var(--text-muted); font-family: var(--font-en); white-space: nowrap; }
.map-card-title-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.map-card-icon {
  width: 32px; height: 32px; border-radius: var(--radius-sm); flex-shrink: 0; background: rgba(10,171,184,0.12); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
}
.map-card-icon svg { width: 17px; height: 17px; }
.map-card-plain .tag {
  align-self: flex-start; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--accent); background: rgba(10,171,184,0.12); padding: 2px 7px; border-radius: 999px; margin-bottom: 2px;
}

.landmarks-heading { font-size: 15px; font-weight: 700; margin: 16px 0 12px; }
.landmark-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px 16px; }
.landmark-cell { cursor: pointer; border-radius: var(--radius-sm); margin: -6px; padding: 6px; transition: background 0.15s ease; }
.landmark-cell:active { background: var(--surface-2); }
.lm-tag-row { display: flex; align-items: center; gap: 6px; color: var(--accent); margin-bottom: 6px; }
.lm-tag-row svg { width: 15px; height: 15px; }
.lm-tag { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.03em; }
.lm-name-row { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.lm-name-row .lm-name { font-weight: 600; font-size: 14px; }
.lm-name-row .lm-dist { color: var(--text-muted); font-size: 13px; flex-shrink: 0; }

.rooms-tabs { display: flex; gap: 24px; border-bottom: 1px solid var(--border); margin: 28px 0 0; }
.rooms-tab {
  background: none; border: none; font-family: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
  color: var(--text-muted); padding: 0 0 10px; position: relative;
}
.rooms-tab.active { color: var(--accent); }
.rooms-tab.active::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--accent); border-radius: 2px; }

.rooms-toolbar { display: flex; align-items: center; justify-content: space-between; margin-top: 16px; }
.rooms-dates, .rooms-guests { display: flex; align-items: center; gap: 6px; }
.rooms-dates { font-weight: 700; font-size: 14px; }
.rooms-guests { color: var(--text-muted-2); font-size: 13px; }
.rooms-dates svg, .rooms-guests svg { width: 15px; height: 15px; color: var(--text-muted-2); flex-shrink: 0; }
.explore-dates-heading { display: flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 600; color: var(--text); margin-top: 16px; }
.explore-dates-heading svg { width: 15px; height: 15px; color: var(--accent); flex-shrink: 0; }
.date-strip { display: flex; gap: 10px; padding: 14px 0 6px; }
.date-chip {
  flex: 1; min-width: 0; border: 2px solid var(--border); border-radius: var(--radius-lg);
  padding: 12px; cursor: pointer; text-align: center; background: var(--surface);
}
.date-chip.selected { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
/* Shared between the detail page's .date-chip and the chat's .chat-datecard
   so both surfaces present cheaper/higher/selected dates identically. */
.dc-toplabel { font-size: 11px; font-weight: 600; line-height: 1.3; min-height: 26px; display: flex; align-items: center; justify-content: center; }
.dc-toplabel.higher { color: #e15241; }
.dc-toplabel.selected { color: var(--accent); }
.dc-toplabel.best { color: var(--green-600); }
.date-chip .dc-price { font-weight: 800; font-size: 15px; margin-top: 4px; }
.date-note { font-size: 11px; color: var(--text-muted); margin: 4px 0 4px; }

.chip-row { display: flex; gap: 8px; overflow-x: auto; margin: 14px 0; scrollbar-width: none; }
.chip-row::-webkit-scrollbar { display: none; }
.filter-chip {
  border: 1px solid var(--border); border-radius: 999px; background: var(--surface);
  color: var(--text-muted); font-size: 13px; font-weight: 600; padding: 8px 14px; cursor: pointer;
  white-space: nowrap;
}
.filter-chip.active { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, var(--bg)); }

.room-card { border: 1px solid var(--border); border-radius: var(--radius-md); margin-bottom: 16px; overflow: hidden; }
.room-card-top { display: flex; gap: 12px; padding: 14px; }
.room-card-top img { width: 92px; height: 92px; border-radius: var(--radius-sm); object-fit: cover; flex-shrink: 0; }
.room-card-top .rc-name { font-weight: 700; font-size: 15px; }
.room-card-top .rc-view { color: var(--text-muted); font-size: 13px; }
.room-card-top .rc-meta { color: var(--text-muted); font-size: 13px; margin-top: 6px; }
.room-card-actions { display: flex; justify-content: space-between; align-items: center; padding: 0 14px 14px; }
.room-card-actions button {
  background: none; border: none; color: var(--accent); font-weight: 700; font-size: 13px;
  cursor: pointer; padding: 0; font-family: inherit;
}
.room-options { border-top: 1px solid var(--border); }
.rate-row { padding: 14px; border-top: 1px solid var(--border); }
.rate-row:first-child { border-top: none; }
.rate-row .rate-name { font-weight: 700; font-size: 14px; }
.rate-row .rate-tags { font-size: 12px; color: var(--text-muted); margin-top: 4px; line-height: 1.6; }
.rate-row .rate-bottom { display: flex; justify-content: space-between; align-items: flex-end; margin-top: 10px; }
.rate-row .rate-price .amount { font-size: 17px; font-weight: 800; }
.rate-row .rate-price .per { font-size: 12px; color: var(--text-muted); display: block; }
.select-btn {
  background: var(--accent); color: var(--accent-contrast); border: none; border-radius: 999px;
  padding: 8px 18px; font-weight: 700; font-size: 13px; cursor: pointer;
}
.select-btn.selected { background: var(--green-600); }

.sticky-footer {
  position: sticky; bottom: 0; background: var(--bg); border-top: 1px solid var(--border);
  padding: 14px 16px; display: flex; align-items: center; justify-content: space-between;
  box-shadow: 0 -4px 16px rgba(0,0,0,0.06);
}
.sticky-footer .sf-label { font-size: 12px; color: var(--text-muted); }
.sticky-footer .sf-price { font-size: 20px; font-weight: 800; }

.fab-ai {
  position: fixed; bottom: 24px; inset-inline-end: max(24px, calc((100vw - 600px) / 2 + 24px));
  width: 56px; height: 56px; border-radius: 50%; border: none;
  background: linear-gradient(160deg, var(--teal-500), var(--teal-700));
  color: #fff; box-shadow: var(--shadow-lg); cursor: pointer; z-index: 20;
  display: flex; align-items: center; justify-content: center;
}
.fab-ai svg { width: 26px; height: 26px; }
/* The shared .ai-glow stroke inherits border-radius, which is already 50% here,
   so the FAB only needs its own shadow blend (its base shadow is neutral). */
.fab-ai.ai-glow { box-shadow: var(--shadow-lg), 0 4px 18px rgba(10, 171, 184, 0.35); }

/* Tooltip shown once the AI banner scrolls out of view (see syncFabTooltip). */
.fab-tip {
  position: fixed; z-index: 21;
  bottom: 38px; inset-inline-end: max(90px, calc((100vw - 600px) / 2 + 90px));
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 9px 14px; font-size: 13px; font-weight: 600; white-space: nowrap;
  box-shadow: var(--shadow-lg); pointer-events: none;
  animation: fab-tip-in 0.45s cubic-bezier(0.16, 1, 0.3, 1) both, fab-tip-bob 2.6s ease-in-out 0.45s infinite;
}
/* Little arrow pointing at the FAB. */
.fab-tip::after {
  content: ""; position: absolute; top: 50%; inset-inline-end: -5px;
  width: 10px; height: 10px; transform: translateY(-50%) rotate(45deg);
  background: var(--surface);
  border-top: 1px solid var(--border); border-inline-end: 1px solid var(--border);
}
[dir="rtl"] .fab-tip::after { transform: translateY(-50%) rotate(-135deg); }
@keyframes fab-tip-in {
  from { opacity: 0; transform: translateX(8px) scale(0.94); }
  to { opacity: 1; transform: none; }
}
[dir="rtl"] .fab-tip { animation-name: fab-tip-in-rtl, fab-tip-bob-rtl; }
@keyframes fab-tip-in-rtl {
  from { opacity: 0; transform: translateX(-8px) scale(0.94); }
  to { opacity: 1; transform: none; }
}
/* Bob toward the FAB, so the direction flips with the layout. `translate`
   (not transform) so it composes with the entrance animation's transform. */
@keyframes fab-tip-bob { 0%, 100% { translate: 0 0; } 50% { translate: -3px 0; } }
@keyframes fab-tip-bob-rtl { 0%, 100% { translate: 0 0; } 50% { translate: 3px 0; } }
@media (prefers-reduced-motion: reduce) {
  .fab-tip { animation: fab-tip-in 0.2s ease both; }
}
/* Phone-width: keep the bubble from crowding the screen edge. */
@media (max-width: 420px) {
  .fab-tip { font-size: 12px; padding: 8px 12px; bottom: 36px; }
}

/* ---------- end-of-prototype screen ---------- */
.end-screen {
  min-height: 100vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  padding: 48px 28px; gap: 4px;
}
.end-icon {
  width: 76px; height: 76px; border-radius: 50%; margin-bottom: 22px;
  background: linear-gradient(160deg, var(--teal-500), var(--teal-700));
  color: #fff; display: flex; align-items: center; justify-content: center;
  animation: end-icon-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.end-icon svg { width: 38px; height: 38px; }
@keyframes end-icon-in { from { opacity: 0; transform: scale(0.8); } to { opacity: 1; transform: none; } }
.end-title { font-size: 24px; font-weight: 800; margin: 0 0 10px; line-height: 1.25; }
.end-body { font-size: 15px; color: var(--text-muted); margin: 0; max-width: 34ch; line-height: 1.55; }
.end-context {
  margin-top: 18px; font-size: 13px; font-weight: 600; color: var(--accent);
  background: var(--active-tint); border-radius: 999px; padding: 7px 14px;
}
[data-theme="dark"] .end-context { background: rgba(18, 176, 189, 0.14); }
.end-actions { display: flex; flex-direction: column; gap: 12px; width: 100%; max-width: 320px; margin-top: 32px; }
.end-actions .btn-primary { width: 100%; }
.end-restart { justify-content: center; width: 100%; }
.end-restart svg { width: 16px; height: 16px; }

/* ---------- gallery ---------- */
.gallery-tabs { display: flex; gap: 8px; padding: 0 16px 14px; overflow-x: auto; border-bottom: 1px solid var(--border); }
.gallery-grid { padding: 16px; display: flex; flex-direction: column; gap: 8px; }
.gallery-grid .g-hero { width: 100%; height: 220px; object-fit: cover; border-radius: var(--radius-md); }
.gallery-grid .g-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.gallery-grid .g-row img { width: 100%; height: 160px; min-width: 0; object-fit: cover; border-radius: var(--radius-md); }
.gallery-cat-heading { font-weight: 800; font-size: 18px; margin: 4px 0 4px; }

/* ---------- AI chat overlay ---------- */
.chat-overlay {
  position: fixed; inset: 0; z-index: 50; color: #fff;
  background: linear-gradient(to bottom, #103038, #0b252c, #07191f);
  display: flex; flex-direction: column;
  /* dvh already handles collapsing browser chrome. It does NOT account for the
     keyboard, which on iOS leaves the composer behind it — see
     trackKeyboardViewport in app.js, which swaps in --vvh only while a keyboard
     is actually up. */
  height: 100dvh;
}
/* The overlay itself always stays full height so its dark gradient covers the
   whole screen. Only the CONTENT is constrained to the keyboard-safe area.
   Shrinking the overlay instead exposed the page underneath it, which is white
   in light mode — a white band appeared under the composer whenever the
   keyboard opened. */
:root[data-kb="1"] .chat-scroll-wrap { height: var(--vvh, 100%); }
.chat-scroll-wrap {
  max-width: 600px; margin: 0 auto; width: 100%; height: 100%;
  display: flex; flex-direction: column; overflow: hidden;
}
.chat-header {
  display: flex; align-items: center; justify-content: space-between; padding: 16px;
  flex-shrink: 0;
}
.chat-header .chat-title { font-weight: 700; font-size: 16px; }
.chat-header .icon-btn { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.12); color: #fff; position: relative; }
.chat-header .badge {
  position: absolute; top: -4px; inset-inline-end: -4px; background: var(--teal-500); color: #fff;
  font-size: 10px; font-weight: 800; width: 16px; height: 16px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
}
.chat-scroll {
  flex: 1; overflow-y: auto; padding: 0 16px 16px; overscroll-behavior: contain;
}
.chat-heading { font-size: 26px; font-weight: 800; line-height: 1.25; margin: 6px 0 20px; }
.chat-hero-imgs {
  display: flex; gap: 12px; overflow-x: auto; margin: 0 -16px 20px; padding: 0 16px;
  scrollbar-width: none;
}
.chat-hero-imgs::-webkit-scrollbar { display: none; }
/* Height is viewport-relative so the strip never dominates a short screen —
   at 208px fixed it was 31% of an iPhone SE before any content. */
.chat-hero-imgs img {
  width: clamp(200px, 60vw, 248px); height: clamp(116px, 17vh, 150px);
  flex-shrink: 0; border-radius: 16px; object-fit: cover; display: block;
}

/* Starter cards and follow-up chips both live INSIDE .chat-scroll. As pinned
   footers they claimed their full height before the conversation got any, which
   left 163px of 667 for the chat on an iPhone SE. Only the composer is pinned. */

.suggestion-row,
.followup-row {
  display: flex; flex-wrap: nowrap; gap: 8px; overflow-x: auto;
  /* Must be explicit. Setting overflow-x alone makes overflow-y compute to
     `auto`, not `visible`, so the row picked up a 3px vertical scroll from the
     chips' touch-target bleed and dragged up and down as well as sideways. */
  overflow-y: hidden;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
  /* Fade the trailing edge so a cut-off card reads as scrollable, not clipped. */
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
}
[dir="rtl"] .suggestion-row,
[dir="rtl"] .followup-row {
  -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 28px), transparent);
  mask-image: linear-gradient(to left, #000 calc(100% - 28px), transparent);
}
.suggestion-row::-webkit-scrollbar,
.followup-row::-webkit-scrollbar { display: none; }

/* Sibling of .suggestion-row, not a child — the row is a scroller, so a heading
   inside it would scroll away with the pills. */
.suggestion-heading {
  flex-shrink: 0; padding: 0 16px 6px;
  font-size: 12px; font-weight: 600; color: rgba(255,255,255,0.5);
}

/* Pinned above the composer, so it carries its own 16px gutter — and
   scroll-padding must match it, or `scroll-snap-align: start` aligns the first
   card to the scrollport edge and eats the gutter, leaving it flush against the
   screen while the heading above starts at 16. */
.suggestion-row {
  flex-shrink: 0; padding: 2px 16px 10px;
  scroll-snap-type: x proximity; scroll-padding-inline-start: 16px;
}

/* The pinned action band sits at the end of the scroll. Without a fade the
   conversation is cut mid-word at that edge and reads as overlapped content
   rather than as something you can scroll. The fade belongs on .chat-scroll
   itself — a pseudo-element on the band is clipped by its own overflow-x, and
   a mask on a scroll container tracks the scrollport, which is what we want. */
.chat-scroll {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent);
}

/* Pinned above the composer, outside .chat-scroll, so it needs its own gutter.
   Two stacked lines: topic chips scroll across the full width, advance CTA on
   its own row below. Sharing one line clipped the topic chip behind the CTA. */
.followup-bar {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  min-width: 0; flex-shrink: 0; padding: 2px 16px 0;
}
/* Symmetric vertical padding so the chips' -4px touch-target bleed sits inside
   the padding box instead of overflowing it (and getting clipped by the
   overflow-y: hidden above). 4px + 36px pill + 4px = the full 44px target. */
.followup-row { align-self: stretch; min-width: 0; padding: 4px 0; }
/* The advance CTA is the same pill as the topic chips, just on its own line —
   a full-width filled button read as a third competing bar above the composer. */
.followup-advance-row { display: flex; }

.suggestion-tile {
  flex: 0 0 auto; width: 132px; min-height: 94px; scroll-snap-align: start;
  display: flex; flex-direction: column; justify-content: space-between;
  background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.1); border-radius: 14px;
  padding: 11px; cursor: pointer; text-align: start; font-family: inherit;
}
.suggestion-tile .s-icon {
  width: 28px; height: 28px; border-radius: 50%; background: var(--teal-500); color: #fff;
  display: flex; align-items: center; justify-content: center; margin-bottom: 14px;
}
.suggestion-tile .s-icon svg { width: 16px; height: 16px; }
.suggestion-tile .s-title { font-weight: 600; font-size: 13px; line-height: 1.3; color: #fff; }
.suggestion-tile:disabled, .suggestion-tile[data-disabled="true"] { opacity: 0.4; cursor: default; }

.chat-divider { display: flex; align-items: center; gap: 10px; margin: 24px 0 20px; color: rgba(255,255,255,0.4); font-size: 12px; }
.chat-divider .line { flex: 1; height: 1px; background: rgba(255,255,255,0.15); border-top: 1px dashed rgba(255,255,255,0.25); }
.chat-divider .cd-text { text-align: center; }
.chat-divider .cd-sub { color: rgba(255,255,255,0.4); font-weight: 500; font-size: 11px; display: block; }
.chat-divider .cd-strong { color: #fff; font-weight: 700; font-size: 14px; display: block; margin-top: 1px; }
.chat-divider .cd-dates { color: rgba(255,255,255,0.4); font-size: 11px; display: block; margin-top: 2px; }

.chat-msg { display: flex; margin-bottom: 14px; }
.chat-msg.user { justify-content: flex-end; }
.chat-msg .bubble {
  max-width: 80%; padding: 12px 16px; border-radius: 16px 8px 16px 16px; font-size: 14px; line-height: 1.5;
}
.chat-msg.user .bubble { background: rgba(18,176,189,0.25); color: #e8f7f9; }
[dir="rtl"] .chat-msg.user .bubble { border-radius: 8px 16px 16px 16px; }
.chat-msg.ai-block, .chat-msg.user { animation: chat-msg-in 0.4s cubic-bezier(0.16, 1, 0.3, 1) both; }
@keyframes chat-msg-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.chat-msg.ai-block { display: block; margin-bottom: 24px; }
.chat-msg.ai-block .ai-text { font-size: 14px; line-height: 1.6; color: #f2f5f6; margin-bottom: 4px; }

/* Fast "typing" reveal: each word fades/lifts in with a tiny stagger (delay
   set per-word inline via wrapWords()) instead of the whole line popping in
   at once. Kept short so long replies still finish revealing quickly. */
@keyframes word-in { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
.ai-text .w { display: inline-block; opacity: 0; animation: word-in 0.24s cubic-bezier(0.4, 0, 0.2, 1) forwards; }

/* ---- sequential reveal ----------------------------------------------------
   The reply arrives one section at a time: the text writes out, then the first
   widget section, then the next, and the follow-up chips close the turn.

   The delays cannot be hardcoded, because the text's duration depends on its
   word count (45ms per word — see WORD_STEP_MS in app.js). render() measures
   the latest reply and publishes the finish time as --reveal-base on the chat
   overlay; everything below is expressed relative to it.

   Sections are the ai-block's own top-level children, so this works for every
   widget kind without naming any of them — a new widget inherits the cadence
   for free. Each section publishes its own --sec, which its cards inherit. */
.chat-overlay { --reveal-base: 0ms; --sec-step: 150ms; }

.chat-msg.ai-block > *:nth-child(2) { --sec: var(--reveal-base); }
.chat-msg.ai-block > *:nth-child(3) { --sec: calc(var(--reveal-base) + var(--sec-step)); }
.chat-msg.ai-block > *:nth-child(4) { --sec: calc(var(--reveal-base) + var(--sec-step) * 2); }
.chat-msg.ai-block > *:nth-child(5) { --sec: calc(var(--reveal-base) + var(--sec-step) * 3); }
.chat-msg.ai-block > *:nth-child(6) { --sec: calc(var(--reveal-base) + var(--sec-step) * 4); }
/* Anything past the sixth section lands with the sixth rather than trailing
   off — a reply that long should not still be assembling itself. */
.chat-msg.ai-block > *:nth-child(n+7) { --sec: calc(var(--reveal-base) + var(--sec-step) * 4); }

@keyframes chat-card-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.chat-msg.ai-block .chat-card,
.chat-msg.ai-block .chat-amcard,
.chat-msg.ai-block .chat-landmark-card,
.chat-msg.ai-block .real-map-wrap,
.chat-msg.ai-block .chat-datestrip,
.chat-msg.ai-block .chat-faithfit-cols,
/* Every top-level piece of a reply is a section and must take its turn. These
   are the ones that are not cards: without them they rendered instantly and
   appeared *before* the text had finished writing, breaking the sequence they
   sit inside. Adding a new widget means adding its container here. */
.chat-msg.ai-block .chat-amsec,
.chat-msg.ai-block .chat-amrow,
.chat-msg.ai-block .chat-roomcount,
.chat-msg.ai-block .chat-roomlist,
.chat-msg.ai-block .chat-revrail-cap,
/* The rail's title and chevrons are part of the carousel and must arrive with
   it. Left out, they painted at t=0 — the heading and arrows appeared before
   the reply had written its first word, which read as the widget rendering
   twice. */
.chat-msg.ai-block .chat-revrail-head,
/* Direct child only. A single amenity with no photo (gym) renders a bare
   .chat-amitem as its whole section, but .chat-amitem is also what fills
   .chat-amrow — animating both would fade the same pixels twice. */
.chat-msg.ai-block > .chat-amitem {
  opacity: 0; animation: chat-card-in 0.26s var(--ease-out) forwards;
  animation-delay: var(--sec, 0ms);
}

/* Within a section, a light sweep in reading order — across the row, then down.
   Small enough that the section still reads as one arrival. */
.chat-msg.ai-block .chat-scorerow > .chat-card:nth-of-type(2) { animation-delay: calc(var(--sec) + 55ms); }
.chat-msg.ai-block .chat-revrail > .chat-card:nth-of-type(2) { animation-delay: calc(var(--sec) + 55ms); }
.chat-msg.ai-block .chat-revrail > .chat-card:nth-of-type(n+3) { animation-delay: calc(var(--sec) + 110ms); }
.chat-msg.ai-block .chat-amcard-grid > .chat-amcard:nth-of-type(2) { animation-delay: calc(var(--sec) + 55ms); }
.chat-msg.ai-block .chat-amcard-grid > .chat-amcard:nth-of-type(3) { animation-delay: calc(var(--sec) + 110ms); }
.chat-msg.ai-block .chat-amcard-grid > .chat-amcard:nth-of-type(4) { animation-delay: calc(var(--sec) + 165ms); }
/* .chat-landmark-grid flows in columns over 2 rows, so odd nth is the top row
   and even is the bottom — delays go by visual position, not source order. */
.chat-msg.ai-block .chat-landmark-grid > .chat-landmark-card:nth-of-type(2n) { animation-delay: calc(var(--sec) + 55ms); }

/* Nothing already on screen may move. render() replaces #app.innerHTML, so
   every element is new on every tap and every keyframe restarts — measured at
   56 animations re-firing on one tap in an 8-message conversation.
   The gate is the `revealing` class, set by render() only for the turn that was
   just pushed. Keying off :last-child was not enough: closing the photo viewer,
   or leaving the chat and coming back, re-renders the same transcript and
   replayed the newest reply every time. */
.chat-scroll .chat-msg:not(.revealing),
.chat-scroll .chat-msg:not(.revealing) * {
  animation: none !important;
  opacity: 1 !important;
}

/* Chips close the turn, after the last section. */
/* Chips wait for the LAST section, not a fixed number of steps — a one-section
   reply should not sit through four empty beats. render() counts the sections
   and publishes --reveal-chips. Only animates for a new turn; on any other
   re-render the bar is simply already there. */
.followup-bar.revealing {
  opacity: 0; animation: chat-card-in 0.26s var(--ease-out) forwards;
  animation-delay: var(--reveal-chips, 0ms);
}
.chat-msg.ai.typing .bubble { background: rgba(255,255,255,0.06); display: flex; gap: 5px; align-items: center; padding: 14px 18px; }
.typing-dot {
  width: 6px; height: 6px; border-radius: 50%; background: rgba(255,255,255,0.65);
  animation: typing-bounce 1.1s infinite ease-in-out;
}
.typing-dot:nth-child(2) { animation-delay: 0.15s; }
.typing-dot:nth-child(3) { animation-delay: 0.3s; }
@keyframes typing-bounce { 0%, 60%, 100% { transform: translateY(0); opacity: 0.5; } 30% { transform: translateY(-5px); opacity: 1; } }

/* ---------- AI chat rich cards ---------- */
.chat-card {
  background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.08); border-radius: var(--radius-md);
  padding: 16px; color: #f2f5f6;
}
.chat-card .breakdown-item .b-row { color: #f2f5f6; }
.chat-card .bar-track { background: rgba(255,255,255,0.12); }
.chat-card-title { font-weight: 800; font-size: 15px; margin-bottom: 8px; }
.chat-review-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 14px; }
.chat-review-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.chat-avatar {
  width: 28px; height: 28px; border-radius: 50%; background: var(--teal-600); color: #fff; font-size: 11px;
  font-weight: 800; display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
/* Name and date stack as one attribution block, so the date no longer costs a
   separate line under the quote. */
.chat-review-who { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.chat-review-name { font-weight: 700; font-size: 13px; }
.chat-review-score { display: flex; align-items: center; gap: 3px; font-size: 13px; font-weight: 700; color: #fff; }
.chat-review-score svg { width: 13px; height: 13px; color: var(--teal-500); }
/* Clamped to 3 lines so every card in the rail is the same height and the
   rail stops being the tallest thing in the reply. renderMiniReviewCard already
   truncates at 130 characters, but that lands anywhere between 2 and 5 lines
   depending on word lengths — the clamp is what actually squares them up. */
.chat-review-text {
  font-size: 13px; line-height: 1.5; color: rgba(255,255,255,0.85); margin: 0 0 6px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden;
}
.read-more-btn { background: none; border: none; color: var(--teal-500); font-weight: 700; font-size: 12px; padding: 0; cursor: pointer; font-family: inherit; }
.chat-review-date { font-size: 11px; color: rgba(255,255,255,0.4); }

/* ---- review rail: title + swipe affordance ---- */
.chat-revrail-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: 14px 0 8px;
}
.chat-revrail-title { font-size: 12px; font-weight: 600; color: rgba(255,255,255,0.55); }
/* The location rail's heading carries the score, so it reads as a sentence and
   matches the answer prose above the map rather than a small section label. */
.chat-revrail-title.as-body { font-size: 14px; font-weight: 400; color: #f2f5f6; }
.chat-revrail-nav { display: flex; gap: 4px; flex-shrink: 0; }
.chat-revrail-arrow {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.12);
  color: rgba(255,255,255,0.75); display: flex; align-items: center; justify-content: center;
  cursor: pointer; font-family: inherit; padding: 0;
  /* 26px visually, 44px to the finger — same invisible-bleed trick as the
     follow-up chips, so the pair stays discreet without being a tiny target. */
  position: relative;
}
.chat-revrail-arrow::after { content: ""; position: absolute; inset: -9px; border-radius: 50%; }
.chat-revrail-arrow svg { width: 13px; height: 13px; }
/* No chevronLeft in the icon set — mirror chevronRight. In RTL the whole pair
   mirrors, so `flip` un-mirrors to keep "back" pointing back. */
.chat-revrail-arrow.flip svg { transform: scaleX(-1); }
[dir="rtl"] .chat-revrail-arrow svg { transform: scaleX(-1); }
[dir="rtl"] .chat-revrail-arrow.flip svg { transform: none; }
.chat-revrail-arrow:active { transform: scale(0.94); }
.chat-overlay .filter-chip { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.14); color: #f2f5f6; }
.chat-overlay .followup-chip {
  background: rgba(19,72,81,0.7); border-color: rgba(255,255,255,0.1); color: #cde9ed;
  flex: 0 0 auto; font-size: 12px; padding: 5px 11px;
  display: inline-flex; align-items: center; gap: 3px; min-height: 36px;
  position: relative;
}
/* The pill is 36px but the touch target is 44px. Extending it invisibly keeps
   the chips visually small without dropping under the minimum tap size. The
   4px bleed matches half the 8px row gap, so the two lines' targets meet
   exactly rather than overlapping. */
.chat-overlay .followup-chip::after {
  content: ""; position: absolute; inset: -4px 0; border-radius: inherit;
}
.followup-chip svg { width: 11px; height: 11px; }
.chat-overlay .followup-chip.go { background: rgba(18,176,189,0.28); border-color: var(--teal-500); color: #e8f7f9; font-weight: 700; }

/* ---------- AI chat: smart response-engine widgets ---------- */
.chat-context-line { font-size: 13px; color: rgba(255,255,255,0.6); margin: -12px 0 18px; line-height: 1.5; }

.chat-score-card { min-width: 148px; flex-shrink: 0; }
.chat-score-big { font-size: 34px; font-weight: 800; line-height: 1; display: flex; align-items: center; gap: 7px; }
.chat-score-big svg { width: 20px; height: 20px; color: var(--green-600); flex-shrink: 0; }
.chat-score-word { font-size: 12px; color: rgba(255,255,255,0.55); margin: 4px 0 10px; }
.chat-score-hero { padding: 14px; }
.chat-score-hero .chat-score-word { margin-bottom: 8px; }
.chat-score-quote { font-size: 12.5px; font-weight: 700; color: #f2f5f6; line-height: 1.4; }

/* Main score + category breakdown side by side; review carousel spans the
   full card width beneath (see renderReviewsWidget's "overall" branch). */
.chat-scorerow { display: flex; gap: 10px; align-items: stretch; }
.chat-scorerow > .chat-card { flex: 1; min-width: 0; }
.chat-revrail-wrap { margin-top: 2px; }

/* Emphasis hierarchy inside the reviews answer. The headline score is the thing
   the user came for, so it gets a teal-tinted surface and a real border; the
   category breakdown and the review cards step back to supporting evidence.
   Previously all three sat on the same rgba(255,255,255,0.05) and the eye had
   nowhere to land. */
.chat-card.chat-score-hero,
.chat-revrail .chat-card.chat-score-card {
  background: linear-gradient(160deg, rgba(18,176,189,0.16), rgba(18,176,189,0.07));
  border-color: rgba(18,176,189,0.42);
}
/* Supporting evidence steps back. Listed after the score rules but with equal
   or lower specificity on the score selectors' side, so the ordering here
   matters — .chat-revrail .chat-card would otherwise flatten the score card. */
.chat-card.chat-score-breakdown,
.chat-revrail .chat-card:not(.chat-score-card) {
  background: rgba(255,255,255,0.032);
  border-color: rgba(255,255,255,0.06);
}

/* Full-bleed rail: the negative margin cancels .chat-scroll's 16px gutter so the
   strip spans the whole screen and the next card is cut off at the bezel rather
   than stopping politely short of it. padding-inline keeps the first card on the
   gutter and gives a resting gutter at the far end; scroll-padding must match
   the leading value or scroll-snap aligns the first card to the scrollport edge
   and eats it (same trap as the starter row).
   align-items: stretch is what makes the score card and the review cards share
   one height now that they live in the same scroller. */
.chat-revrail {
  display: flex; align-items: stretch; gap: 10px; overflow-x: auto;
  flex: 1; min-width: 0; padding-bottom: 6px;
  margin-inline: -16px; padding-inline: 16px;
  scroll-snap-type: x mandatory; scroll-padding-inline-start: 16px;
}
.chat-revrail::-webkit-scrollbar { display: none; }
.chat-revrail .chat-card { width: 68%; min-width: 200px; max-width: 260px; flex-shrink: 0; scroll-snap-align: start; padding: 12px; }
/* Narrower than a review card, and the overall pill is pushed to the bottom so
   the card still reads as composed once stretched to the rail's height. */
.chat-revrail .chat-score-card {
  width: 44%; min-width: 150px; max-width: 180px;
  display: flex; flex-direction: column;
}
.chat-revrail .chat-score-card .chat-overall-pill { margin-top: auto; align-self: flex-start; }
.chat-revrail .chat-score-card .chat-score-word { margin-bottom: 10px; }
.chat-revrail-cap { font-size: 11px; color: rgba(255,255,255,0.4); margin-top: 6px; display: flex; align-items: center; gap: 4px; }
.chat-revrail-cap svg { width: 12px; height: 12px; flex-shrink: 0; }
.chat-overall-pill {
  display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 700;
  background: rgba(255,255,255,0.1); color: #fff; padding: 4px 10px; border-radius: 999px; margin-bottom: 10px;
}
.chat-overall-pill svg { width: 12px; height: 12px; flex-shrink: 0; }

.chat-amsec { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: rgba(255,255,255,0.45); margin: 0 0 8px; font-weight: 700; }
.chat-amsec.prem { color: var(--teal-500); }
.chat-amgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 14px; margin-bottom: 14px; }
.chat-amitem { display: flex; align-items: center; gap: 8px; font-size: 13px; color: #f2f5f6; }
.chat-am-icon {
  width: 32px; height: 32px; border-radius: 9px; background: rgba(255,255,255,0.08); color: var(--teal-500);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.chat-am-icon svg { width: 17px; height: 17px; }

/* Standard amenities scroll horizontally instead of wrapping, so the full list
   stays reachable without pushing the card taller — but over two rows, not one.
   The list grew to 17 items, and a single line meant a long sideways swipe to
   reach the end.
   `grid-auto-flow: column` over two fixed rows, NOT flex-wrap: wrap — wrapping
   would give an unpredictable number of lines depending on label length and
   language. Same pattern as .chat-landmark-grid.
   Full-bleed so the cut-off column lands on the screen edge and reads as
   scrollable; scroll-padding must match the padding or scroll-snap eats the
   leading gutter. */
.chat-amrow {
  display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, auto);
  grid-auto-columns: max-content; justify-content: start; align-items: center;
  gap: 12px 18px;
  overflow-x: auto; overflow-y: hidden;
  margin-inline: -16px; padding: 2px 16px 4px;
  scroll-snap-type: x proximity; scroll-padding-inline-start: 16px;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);
}
[dir="rtl"] .chat-amrow {
  -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 28px), transparent);
  mask-image: linear-gradient(to left, #000 calc(100% - 28px), transparent);
}
.chat-amrow::-webkit-scrollbar { display: none; }
.chat-amrow .chat-amitem { scroll-snap-align: start; white-space: nowrap; }

/* Premium reads as the showcase tier: photo cards, not icon rows. */
.chat-amcard-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 16px; }
.chat-amcard {
  border-radius: var(--radius-md); overflow: hidden; background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.08);
}
.chat-amcard img { width: 100%; aspect-ratio: 4 / 3; height: auto; object-fit: cover; display: block; }
/* The photo is a button, so it needs the button reset — otherwise it inherits
   UA padding/border and the image stops filling the card. */
.chat-amcard-photo {
  display: block; position: relative; width: 100%; padding: 0; border: none;
  background: none; cursor: pointer; font-family: inherit;
  transition: opacity var(--dur-press, 0.16s) ease;
}
.chat-amcard-photo:active { opacity: 0.82; }
/* Only rendered when there is more than one photo, so it doubles as the hint
   that tapping opens a set rather than a single image. */
.chat-amcard-count {
  position: absolute; bottom: 8px; inset-inline-end: 8px;
  background: rgba(7,25,31,0.72); color: #fff; font-size: 11px; font-weight: 700;
  padding: 3px 8px; border-radius: 999px; line-height: 1.4;
  backdrop-filter: blur(4px);
}

/* ---------- amenity photo viewer ---------- */
.photo-viewer {
  position: fixed; inset: 0; z-index: 60; background: #05141a;
  display: flex; flex-direction: column;
}
.photo-viewer-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: calc(14px + env(safe-area-inset-top)) 16px 14px;
  color: #fff; flex-shrink: 0;
}
.photo-viewer-title { font-size: 14px; font-weight: 700; min-width: 0; }
.photo-viewer-close {
  background: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.16); color: #fff;
  flex-shrink: 0; width: 44px; height: 44px;
}
/* One snapping strip: native swipe works with no JS and the dots just follow
   scroll — same approach as the booking carousel. */
.photo-viewer-strip {
  flex: 1; min-height: 0; display: flex; overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.photo-viewer-strip::-webkit-scrollbar { display: none; }
.photo-viewer-strip img {
  width: 100%; height: 100%; flex: 0 0 100%; object-fit: contain;
  scroll-snap-align: center; display: block;
}
.photo-viewer-dots { padding-bottom: calc(18px + env(safe-area-inset-bottom)); margin: 14px 0 0; gap: 12px; }
/* Swipe is the real interaction here; the dots are indicators that happen to be
   tappable. 8px visually, ~32px to the finger — the 12px gap above keeps
   adjacent targets from overlapping. */
.photo-viewer-dots .carousel-dot {
  background: rgba(255,255,255,0.28); width: 8px; height: 8px; position: relative;
}
.photo-viewer-dots .carousel-dot::after { content: ""; position: absolute; inset: -12px; }
.photo-viewer-dots .carousel-dot.active { background: #fff; width: 20px; }
.chat-amcard-label {
  display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; color: #f2f5f6;
  padding: 9px 10px;
}
.chat-amcard-label .chat-am-icon { background: rgba(18,176,189,0.14); }

.chat-faithfit-cols { display: flex; gap: 18px; margin-top: 14px; }
.chat-faithfit-col { flex: 1; min-width: 0; }
.chat-faithfit-item { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; color: rgba(255,255,255,0.85); margin-bottom: 8px; line-height: 1.4; }
.chat-faithfit-item .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--teal-500); flex-shrink: 0; margin-top: 6px; }
.chat-faithfit-item.worth .dot { background: #caa356; }

.chat-datestrip { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 4px; scroll-snap-type: x mandatory; }
.chat-datestrip::-webkit-scrollbar { display: none; }
.chat-datecard {
  flex-shrink: 0; min-width: 108px; border: 2px solid rgba(255,255,255,0.1); border-radius: 14px; padding: 10px;
  text-align: center; background: rgba(255,255,255,0.05); scroll-snap-align: center; cursor: pointer;
}
.chat-datecard.active { border-color: var(--teal-500); background: rgba(18,176,189,0.1); }
.chat-datecard .pr { font-weight: 800; font-size: 15px; color: #f2f5f6; margin-top: 4px; }
.chat-datecard .dr { font-size: 11.5px; color: rgba(255,255,255,0.5); margin-top: 6px; }

.chat-cost-row { display: flex; justify-content: space-between; font-size: 13px; color: rgba(255,255,255,0.75); padding: 7px 0; border-bottom: 1px solid rgba(255,255,255,0.08); }
.chat-cost-row.total { color: #fff; font-weight: 800; font-size: 15px; border-bottom: none; padding-top: 10px; }
.chat-card-photo { width: 100%; aspect-ratio: 4 / 3; height: auto; object-fit: cover; display: block; }

.chat-empty-note { font-size: 13px; color: rgba(255,255,255,0.55); }

/* kind:"kv" — reusable key/value card (check-in, policies, children, dining) */
.chat-kv { padding: 12px 14px; }
.chat-kv-title { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: rgba(255,255,255,0.45); font-weight: 700; margin-bottom: 8px; }
.chat-kv-row {
  display: flex; justify-content: space-between; gap: 12px; font-size: 13px; padding: 6px 0;
  border-bottom: 1px solid rgba(255,255,255,0.07); color: rgba(255,255,255,0.6);
}
.chat-kv-row:last-child { border-bottom: none; }
.chat-kv-row b { color: #f2f5f6; font-weight: 700; text-align: end; }
.chat-kv-li { font-size: 13px; color: rgba(255,255,255,0.75); padding: 4px 0 4px 14px; position: relative; }
.chat-kv-li::before { content: "•"; position: absolute; inset-inline-start: 0; color: var(--teal-500); }

/* kind:"roomlist" — collapsed room cards via native <details>, so expand
   survives a re-render and needs no JS. */
.chat-roomcount { font-size: 11.5px; color: rgba(255,255,255,0.45); margin-bottom: 8px; }
.chat-roomlist { display: flex; flex-direction: column; gap: 8px; }
.chat-roomcard {
  background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.08);
  border-radius: 14px; overflow: hidden;
}
.chat-roomcard > summary {
  list-style: none; cursor: pointer; padding: 9px 10px; display: flex; align-items: center; gap: 10px;
}
.chat-roomcard > summary::-webkit-details-marker { display: none; }
.chat-roomcard-thumb { width: 44px; height: 44px; border-radius: 10px; object-fit: cover; flex-shrink: 0; display: block; }
.chat-roomcard-main { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.chat-roomcard-name {
  font-weight: 700; font-size: 13px; color: #f2f5f6; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-roomcard-sub { font-size: 11px; color: rgba(255,255,255,0.5); margin-top: 1px; }
.chat-roomcard-right { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.chat-roomcard-price { font-weight: 800; font-size: 13.5px; color: var(--teal-500); white-space: nowrap; }
.chat-roomcard-chev { color: rgba(255,255,255,0.45); display: flex; transition: transform 0.18s ease; }
.chat-roomcard-chev svg { width: 15px; height: 15px; }
.chat-roomcard[open] .chat-roomcard-chev { transform: rotate(180deg); }
.chat-roomcard-body { padding: 4px 12px 12px; border-top: 1px solid rgba(255,255,255,0.08); }
.chat-roomcard-cta { margin-top: 10px; }
.chat-roomcard-cta .booking-book-btn { width: 100%; }
/* Fixed 2 rows, scrolling sideways in 2x2 pages: the full Booking.com
   surroundings list is too tall to stack, so only the first four are in view
   and the rest are a horizontal swipe away. */
.chat-landmark-grid {
  display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, auto);
  grid-auto-columns: calc(50% - 4px); gap: 8px; margin: 12px 0;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.chat-landmark-grid::-webkit-scrollbar { display: none; }
.chat-landmark-grid > .chat-landmark-card { scroll-snap-align: start; }
.chat-landmark-card {
  display: flex; align-items: center; gap: 9px; background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.08); border-radius: 12px; padding: 8px 9px; min-width: 0;
}
.chat-landmark-avatar {
  width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0; overflow: hidden;
  display: flex; align-items: center; justify-content: center; background: rgba(255,255,255,0.08); color: var(--teal-500);
}
.chat-landmark-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.chat-landmark-avatar svg { width: 15px; height: 15px; }
.chat-landmark-body { flex: 1; min-width: 0; }
.chat-landmark-tag {
  display: inline-block; font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--teal-500); background: rgba(18,176,189,0.14); padding: 1px 6px; border-radius: 999px; margin-bottom: 2px;
}
.chat-landmark-name {
  font-weight: 700; font-size: 12px; color: #f2f5f6; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-landmark-meta { font-size: 10.5px; color: rgba(255,255,255,0.5); margin-top: 1px; white-space: nowrap; }

.chat-overlay .real-map-wrap { margin-top: 4px; }
.chat-overlay .map-expand-btn { background: rgba(255,255,255,0.1); border-color: rgba(255,255,255,0.15); color: #fff; }

/* Image leads the card, so the media block is flush to the top corners and the
   card's own padding starts below it. */
.booking-card { padding: 0 16px 14px; overflow: hidden; }
.booking-media { position: relative; margin: 0 -16px 12px; }
.booking-media + .booking-room-name,
.booking-media + .booking-eyebrow { margin-top: 0; }
.booking-media .booking-carousel { border-radius: 0; }
/* Dots sit ON the image, not under it — one less stacked band, and the photo
   keeps the full height it was given. The scrim is what keeps them legible over
   a bright frame; white-on-white is otherwise invisible. */
.booking-media .carousel-dots {
  position: absolute; inset-inline: 0; bottom: 0; top: auto; margin: 0; padding: 22px 0 10px;
  background: linear-gradient(to top, rgba(7,25,31,0.55), transparent);
  pointer-events: none;
}
.booking-media .carousel-dot { pointer-events: auto; background: rgba(255,255,255,0.45); }
.booking-media .carousel-dot.active { background: #fff; }
.booking-eyebrow { font-size: 11px; font-weight: 800; letter-spacing: 0.04em; color: var(--teal-500); }
.booking-room-name { font-size: 19px; font-weight: 800; margin-top: 2px; }
.booking-room-view { font-size: 13px; color: rgba(255,255,255,0.6); }
/* The four facts line: view · size · fits N · connecting. */
.booking-room-spec { font-size: 12.5px; color: rgba(255,255,255,0.55); margin-top: 3px; }
.booking-pick { display: flex; align-items: center; gap: 6px; color: var(--teal-500); font-size: 13px; font-weight: 700; margin-top: 8px; }
.booking-pick svg { width: 14px; height: 14px; }
/* Native horizontal swipe carousel: all images live in one snapping strip so
   touch/trackpad swipe works without JS, and the dots just follow scroll. */
.booking-carousel {
  border-radius: var(--radius-sm); overflow-x: auto; overflow-y: hidden; display: flex;
  scroll-snap-type: x mandatory; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.booking-carousel::-webkit-scrollbar { display: none; }
.booking-carousel img {
  width: 100%; flex: 0 0 100%; height: 178px; object-fit: cover; display: block; scroll-snap-align: center;
}
.carousel-dots { display: flex; justify-content: center; gap: 6px; margin: 10px 0 4px; }
.carousel-dot { width: 6px; height: 6px; border-radius: 50%; background: rgba(255,255,255,0.25); border: none; padding: 0; cursor: pointer; }
.carousel-dot.active { background: var(--teal-500); width: 16px; border-radius: 3px; }
/* Rate tags bleed to the card edge, so a cut-off tag reads as scrollable rather
   than as a tag that happens to end early. Vertical margin lives here, not as
   an inline style on the element — an inline margin shorthand beat the
   margin-inline rule and the bleed silently did nothing. */
.booking-card .booking-tags { margin: 10px -16px; padding-inline: 16px; }
.booking-amenity-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 16px; margin: 12px 0; }
.booking-amenity { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: rgba(255,255,255,0.8); }
.booking-amenity svg { width: 16px; height: 16px; color: var(--teal-500); flex-shrink: 0; }
.booking-bottom { display: flex; justify-content: space-between; align-items: center; margin-top: 6px; }
.booking-price { font-size: 19px; font-weight: 800; }
.booking-cancel { font-size: 12px; color: #7fd6a8; margin-top: 2px; }
.booking-book-btn { background: #e0524c; padding: 12px 22px; }
.see-more-rooms-btn {
  width: 100%; text-align: center; background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1);
  color: #f2f5f6; border-radius: 999px; padding: 12px; font-weight: 700; font-size: 13px; margin-top: 10px;
  cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 6px; font-family: inherit;
}
.see-more-rooms-btn svg { width: 14px; height: 14px; }

.chat-input-bar { padding: 12px 16px 18px; flex-shrink: 0; }
.chat-input-row {
  display: flex; align-items: center; gap: 10px; background: #fff; border-radius: 999px;
  padding: 6px 6px 6px 18px;
}
[dir="rtl"] .chat-input-row { padding: 6px 18px 6px 6px; }
.chat-input-row input {
  flex: 1; border: none; outline: none; font-size: 14px; background: transparent; color: #0d1417;
  font-family: inherit; padding: 8px 0;
}
.chat-input-row input::placeholder { color: #97a0a4; }
.chat-send {
  width: 38px; height: 38px; border-radius: 50%; border: none; background: var(--teal-600); color: #fff;
  display: flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0;
}
.chat-send svg { width: 18px; height: 18px; }
.chat-send:disabled { opacity: 0.4; cursor: default; }

/* ---------- toast ---------- */
.toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  background: var(--text); color: var(--bg); padding: 12px 20px; border-radius: 999px;
  font-size: 13px; font-weight: 600; z-index: 100; box-shadow: var(--shadow-lg);
  max-width: 90vw; text-align: center;
}

/* ---------- bottom sheet (filters/sort/etc stubs) ---------- */
.sheet-backdrop {
  position: fixed; inset: 0; background: rgba(10, 16, 18, 0.5); z-index: 40;
  display: flex; align-items: flex-end; justify-content: center;
}
.sheet {
  background: var(--bg); width: 100%; max-width: 600px; border-radius: 20px 20px 0 0;
  padding: 20px; max-height: 70vh; overflow-y: auto;
}
.sheet-handle { width: 40px; height: 4px; background: var(--border); border-radius: 4px; margin: 0 auto 16px; }
.sheet h3 { margin: 0 0 16px; font-size: 18px; }
.sheet-option {
  display: flex; align-items: center; justify-content: space-between; padding: 14px 0;
  border-bottom: 1px solid var(--border); cursor: pointer; font-size: 15px;
}
.sheet-option:last-child { border-bottom: none; }
.sheet-option.selected { color: var(--accent); font-weight: 700; }
.sheet-option svg { width: 18px; height: 18px; flex-shrink: 0; }

@media (max-width: 400px) {
  .detail-hero-main { height: 220px; }
  .suggestion-grid { gap: 8px; }
}
