/* =========================================================
   chat.css — Single source of truth for chat UI styles
   Used by: style.css (@import), embed.html (<link>)
   DO NOT duplicate these styles anywhere else.
   ========================================================= */

/* =========================================================
   CHAT LAUNCHER — bottom right bubble
   ========================================================= */
#chat-launcher-wrapper {
  position: fixed;
  bottom: 28px;
  right: 28px;
  z-index: 300;
}
#chat-launcher-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  background: var(--primary);
  color: #fff;
  border: none;
  border-radius: 50px;
  font-size: 14px;
  font-weight: 600;
  font-family: 'Barlow', sans-serif;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(13,148,136,0.3), 0 0 0 1px rgba(255,255,255,0.06);
  transition: all 0.3s;
}
#chat-launcher-btn:hover {
  background: var(--primary-dark);
  transform: translateY(-2px);
  box-shadow: 0 12px 30px rgba(13,148,136,0.4);
}
#chat-launcher-btn i { font-size: 16px; color: #fff; }


/* =========================================================
   CHAT WINDOW — bottom right messenger style
   ========================================================= */
#chat-window-container {
  position: fixed;
  top: calc(var(--header-h) + 12px);
  bottom: 12px;
  right: 28px;
  width: min(480px, calc(100vw - 56px));
  background: #fff;
  border-radius: 20px;
  box-shadow: var(--shadow-xl);
  border: 2px solid rgba(255,255,255,0.22);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 600;
}
.chat-toolbar {
  background: var(--bg-off);
  padding: 12px 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
  border-bottom: 1px solid rgba(29,31,32,0.1);
}
.bot-identity { display: flex; align-items: center; gap: 10px; }
.avatar {
  width: 32px; height: 32px;
  background: rgba(65,97,128,0.15);
  color: var(--primary);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  border: 1px solid rgba(65,97,128,0.3);
  flex-shrink: 0;
}
.bot-name h3 { font-size: 13px; font-weight: 700; color: var(--text-main); margin: 0; }
.status {
  font-size: 11px;
  color: #64748b;
  display: flex;
  align-items: center;
  gap: 5px;
}
.status-dot {
  width: 6px; height: 6px;
  background: #22c55e;
  border-radius: 50%;
}
.chat-controls { display: flex; gap: 10px; align-items: center; }
#chat-close-btn, #chat-clear-btn {
  background: none;
  border: none;
  color: #64748b;
  font-size: 14px;
  cursor: pointer;
  padding: 4px;
  transition: color 0.2s;
  line-height: 1;
}
#chat-close-btn:hover { color: #ef4444; }
#chat-clear-btn:hover { color: #fff; }

.demo-banner {
  background: #fffbeb;
  color: #92400e;
  padding: 8px 14px;
  font-size: 12px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 6px;
  border-bottom: 1px solid #fde68a;
  flex-shrink: 0;
}
.demo-banner.hidden { display: none; }

#chat-messages {
  flex: 1;
  padding: 16px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: #e5ddd5;
}
#chat-messages::-webkit-scrollbar { width: 4px; }
#chat-messages::-webkit-scrollbar-track { background: transparent; }
#chat-messages::-webkit-scrollbar-thumb { background: #e2e8f0; border-radius: 2px; }

.msg {
  max-width: 88%;
  padding: 10px 13px;
  border-radius: 14px;
  font-size: 13.5px;
  line-height: 1.5;
}
.bot {
  align-self: flex-start;
  background: #fff;
  color: var(--text-main);
  border-bottom-left-radius: 4px;
  border: 1px solid rgba(29,31,32,0.08);
}
.user {
  align-self: flex-end;
  background: #dcf8c6;
  color: #111b21;
  border-bottom-right-radius: 4px;
}

/* Matches the site-wide convention (see main style.css / pricing section):
   DM Sans lacks a proper ₹ glyph -- Lora renders it correctly. chat.js
   already wraps every ₹ in this span; this rule was simply never added
   here, which is why the symbol has been rendering broken in the widget
   and the embedded demo iframe alike (both share this one CSS file). */
.rupee-fix {
  font-family: 'Lora', serif;
}

.chat-lang-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px 2px;
  background: #fff;
}
.lang-btn {
  padding: 3px 10px;
  border-radius: 20px;
  border: 1.5px solid var(--border);
  background: #f8fafc;
  color: #64748b;
  font-size: 12px;
  font-family: 'Barlow', sans-serif;
  cursor: pointer;
  transition: all 0.2s;
}
.lang-btn:hover { border-color: var(--primary); color: var(--primary); }
.lang-btn.active { background: var(--primary); color: #fff; border-color: var(--primary); }
.lang-bar-powered {
  margin-left: auto;
  font-size: 11px;
  color: #000000;
}

.chat-input-area {
  padding: 10px 12px;
  background: #fff;
  border-top: 1px solid var(--border);
  display: flex;
  gap: 8px;
  align-items: center;
  flex-shrink: 0;
}
#user-input {
  flex: 1;
  padding: 9px 14px;
  border: 1.5px solid var(--border);
  border-radius: 50px;
  font-size: 13.5px;
  font-family: 'Barlow', sans-serif;
  outline: none;
  color: var(--text-main);
  background: #f8fafc;
  transition: border-color 0.2s;
}
#user-input:focus { border-color: var(--primary); background: #fff; }
#mic-btn {
  width: 34px; height: 34px;
  background: #f1f5f9;
  border: none;
  border-radius: 50%;
  color: #94a3b8;
  font-size: 14px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
  flex-shrink: 0;
}
#mic-btn:hover { background: #e2e8f0; color: var(--text-main); }
#mic-btn.listening { color: #ef4444; animation: pulse 1.5s infinite; background: #fef2f2; }
#send-btn {
  width: 34px; height: 34px;
  background: var(--text-main);
  border: none;
  border-radius: 50%;
  color: #fff;
  font-size: 13px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
  flex-shrink: 0;
}
#send-btn:hover { background: var(--primary); transform: scale(1.05); }


/* =========================================================
   PROPERTY CARDS
   ========================================================= */
.property-list {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  width: 100%;
  margin-top: 8px;
  justify-content: center;
}
.prop-card {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: #fff;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  transition: transform 0.2s, box-shadow 0.2s;
}
.group-separator {
  width: 100%;
  display: flex;
  align-items: center;
  margin: 12px 0 8px 0;
  gap: 10px;
  color: #64748b;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.group-separator::before,
.group-separator::after {
  content: '';
  flex: 1;
  height: 1px;
  background: #e2e8f0;
}
@media (min-width: 400px) {
  .prop-card { width: calc(50% - 8px); }
}
.prop-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.prop-card img { width: 100%; height: 160px; object-fit: cover; }
.prop-badges { display: flex; gap: 5px; padding: 8px 12px 0; flex-wrap: wrap; }
.listing-badge, .legal-badge { font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 4px; text-transform: uppercase; letter-spacing: 0.05em; }
.listing-badge.listing-sale  { background: #dcfce7; color: #15803d; }
.listing-badge.listing-rent  { background: #fef3c7; color: #b45309; }
.listing-badge.listing-lease { background: #ede9fe; color: #6d28d9; }
.legal-badge { background: #f0fdf4; color: #166534; border: 1px solid #bbf7d0; }
.distance-badge { background: #eff6ff; color: #1d4ed8; border: 1px solid #bfdbfe; font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 4px; display: inline-flex; align-items: center; gap: 4px; }
.distance-badge i { font-size: 9px; }
.prop-info { padding: 12px; display: flex; flex-direction: column; gap: 5px; }
.prop-title { font-weight: 700; font-size: 14px; color: var(--text-main); line-height: 1.3; }
.prop-meta { font-size: 12px; color: var(--text-muted); display: flex; align-items: center; gap: 6px; }
.prop-meta i { color: #cbd5e1; width: 14px; text-align: center; }
.prop-price { color: #059669; font-weight: 700; font-size: 15px; margin-top: 3px; }
.detail-btn {
  margin: 8px 12px 12px;
  padding: 8px;
  background: var(--text-main);
  color: #fff;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  font-family: 'Barlow', sans-serif;
  transition: background 0.2s;
}
.detail-btn:hover { background: var(--primary); }
.map-link {
  color: var(--text-muted);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  transition: color 0.2s;
}
.map-link:hover { color: var(--primary); }
.map-link i.fa-map-marker-alt { color: #ef4444; }
.load-more-btn {
  background: var(--bg-off);
  color: var(--primary-dark);
  border: 1px solid var(--primary-light);
  padding: 8px 20px;
  border-radius: 50px;
  font-size: 13px;
  font-weight: 600;
  font-family: 'Barlow', sans-serif;
  cursor: pointer;
  display: block;
  margin: 12px auto 0;
  transition: all 0.2s;
}
.load-more-btn:hover { background: var(--primary-light); transform: translateY(-1px); }


/* =========================================================
   PROPERTY DETAILS MODAL
   ========================================================= */
#property-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(0,0,0,0.7);
  backdrop-filter: blur(4px);
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
}
.modal-content {
  background: #fff;
  width: 90%;
  max-width: 560px;
  border-radius: 16px;
  padding: 24px;
  position: relative;
  max-height: 88vh;
  overflow-y: auto;
  color: var(--text-main);
  box-shadow: var(--shadow-xl);
}
#modal-close-btn {
  position: absolute;
  top: 14px; right: 14px;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: #f1f5f9;
  border: none;
  color: #64748b;
  font-size: 13px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s, color 0.2s;
  z-index: 1;
}
#modal-close-btn:hover { background: #e2e8f0; color: #1e293b; }
.modal-img { width: 100%; height: 200px; object-fit: cover; border-radius: var(--radius-md); margin-bottom: 16px; }
.modal-title { font-family: 'Barlow Condensed', serif; font-size: 20px; font-weight: 700; margin-bottom: 4px; }
.modal-price { color: #059669; font-weight: 700; font-size: 18px; margin-bottom: 16px; }
.modal-section { margin-bottom: 16px; }
.modal-section h4 { font-size: 11px; font-weight: 700; color: var(--text-muted); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.08em; }
.modal-text { font-size: 14px; line-height: 1.7; color: #334155; }
.modal-badges { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.overview-item { background: var(--bg-off); padding: 8px; border-radius: 6px; font-size: 13px; }
.tag-empty, .spec-empty { opacity: 0.5; font-style: italic; }
.tag-container { display: flex; flex-wrap: wrap; gap: 6px; }
.tag { background: var(--bg-off); color: var(--text-muted); padding: 4px 10px; border-radius: 4px; font-size: 12px; border: 1px solid var(--border); }
.spec-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.spec-item { background: var(--bg-off); padding: 8px; border-radius: 6px; font-size: 13px; }
.spec-label { color: var(--text-muted); font-size: 10px; display: block; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 2px; }


/* =========================================================
   POI MAP MODAL — interactive nearby-places explorer (Sep 2026)
   Nested INSIDE #chat-window-container (NOT a page-level overlay like
   #property-modal) so it is physically confined to the widget:
   position:absolute resolves against the nearest positioned ancestor, and
   #chat-window-container is position:fixed in the floating widget and
   fills the whole iframe viewport in embed mode -- either way this can
   never render outside the widget, on any host page.
   ========================================================= */
#poi-map-modal {
  position: absolute;
  inset: 0;
  z-index: 900;
  background: #fff;
  border-radius: 16px;
  box-shadow: var(--shadow-xl);
  border: 1px solid var(--border);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.poi-map-header {
  background: var(--text-main);
  padding: 10px 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}
.poi-map-title {
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: 8px;
}
.poi-map-title i { color: var(--primary); }
#poi-map-close-btn {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: rgba(239,68,68,0.25); /* Sep 9 2026 -- close is now visually
    distinct (red-tinted) from the neutral fullscreen-toggle right next to
    it, after confirmed live confusion between the two: clicking
    fullscreen-toggle instead of close shrinks the widget but never hides
    the modal, leaving it open and squeezed inside a small widget with no
    obvious way out. */
  border: none;
  color: #fff;
  font-size: 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.2s;
}
#poi-map-close-btn:hover { background: rgba(239,68,68,0.5); }
#poi-map-canvas {
  flex: 1;
  position: relative;
  background: #e5ddd5;
}
.poi-map-loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-muted);
  font-family: 'Barlow', sans-serif;
}
#poi-map-legend {
  flex-shrink: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 10px;
  max-height: 76px;
  overflow-y: auto;
  border-top: 1px solid var(--border);
  background: #f8fafc;
}
.poi-legend-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 20px;
  border: 1.5px solid var(--border);
  background: #fff;
  color: var(--text-main); /* Sep 8 2026, Ram's fix -- text stays dark
                               regardless of selected/unselected state,
                               never fades. */
  font-size: 11px;
  font-weight: 600;
  font-family: 'Barlow', sans-serif;
  cursor: pointer;
  transition: all 0.2s;
}
.poi-legend-chip .poi-legend-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--chip-color);
  border: 2px solid var(--chip-color);
  transition: background 0.2s;
}
/* Unselected state (Sep 8 2026) -- ONLY the dot changes: ring stays the
   category color, fill goes near-white. The chip itself no longer fades
   at all -- that's what was dimming the text before. */
.poi-legend-chip.inactive .poi-legend-dot {
  background: #ffffff;
}
.poi-marker-label {
  text-shadow: 0 1px 2px rgba(255,255,255,0.9), 0 -1px 2px rgba(255,255,255,0.9);
}
.poi-venture-label {
  background: linear-gradient(135deg, #ffffff, #f0fdfa);
  padding: 4px 12px;
  border-radius: 20px;
  border: 1.5px solid var(--primary);
  box-shadow: 0 3px 10px rgba(13,148,136,0.35), 0 1px 3px rgba(0,0,0,0.15);
  white-space: nowrap;
  letter-spacing: 0.02em;
}


/* =========================================================
   UTILS — shared by chat
   ========================================================= */
.hidden { display: none !important; }

@keyframes pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.15); }
  100% { transform: scale(1); }
}


/* =========================================================
   RESPONSIVE — chat-specific rules only
   ========================================================= */
@media (max-width: 768px) {
  #chat-window-container {
    top: calc(var(--header-h) + 5vh);
    bottom: 5vh;
    right: 5vw;
    left: 5vw;
    width: 90vw;
    border-radius: 16px;
  }
  /* Aug 2026: was collapsing to an icon-only circle on mobile (span display:none +
     circular padding) -- this is the primary CTA for the whole site on both desktop
     and mobile now, so the "Try Now" label stays visible everywhere. Padding/font-size
     trimmed slightly from desktop's, just to keep it comfortably sized on a narrow
     screen without ever hiding the text. */
  #chat-launcher-wrapper { bottom: 20px; right: 20px; }
  #chat-launcher-btn { padding: 12px 18px; gap: 8px; font-size: 13px; }
  #chat-launcher-btn i { font-size: 14px; }
}

/* embed.html full-screen mode — when loaded inside widget iframe */
body.embed-mode {
  margin: 0;
  padding: 0;
  overflow: hidden;
}
body.embed-mode #chat-window-container {
  position: static;
  width: 100%;
  height: 100vh;
  border-radius: 0;
  box-shadow: none;
  border: none;
}

.chat-lang-bar { position: relative; }
.script-subselect {
  position: absolute;
  bottom: 100%;
  left: 0;
  margin-bottom: 6px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  z-index: 5;
}
.script-subselect.hidden { display: none; }
.script-pill {
  padding: 3px 10px;
  border-radius: 20px;
  border: 1.5px solid var(--border);
  background: #f8fafc;
  color: #64748b;
  font-size: 11px;
  font-family: 'Barlow', sans-serif;
  cursor: pointer;
  transition: all 0.2s;
}
.script-pill:hover { border-color: var(--primary); color: var(--primary); }
.script-pill.active { background: var(--primary); color: #fff; border-color: var(--primary); }

#plan-image-modal {
  position: absolute;
  inset: 0;
  z-index: 900;
  background: #fff;
  border-radius: 16px;
  box-shadow: var(--shadow-xl);
  border: 1px solid var(--border);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.plan-modal-header {
  background: var(--text-main);
  padding: 10px 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}
.plan-modal-title { color: #fff; font-size: 13px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.plan-modal-title i { color: var(--primary); }
#plan-modal-close-btn {
  width: 28px; height: 28px; border-radius: 50%; background: rgba(239,68,68,0.25);
  border: none; color: #fff; font-size: 12px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  transition: background 0.2s;
}
#plan-modal-close-btn:hover { background: rgba(239,68,68,0.5); }
#plan-modal-body { flex: 1; display: flex; overflow: hidden; position: relative; }
#plan-modal-image-wrap {
  flex: 1; overflow: auto; background: #f1f5f9;
  display: flex; align-items: flex-start; justify-content: flex-start; padding: 12px;
}
#plan-modal-image-wrap::-webkit-scrollbar { width: 6px; height: 6px; }
#plan-modal-image-wrap::-webkit-scrollbar-track { background: transparent; }
#plan-modal-image-wrap::-webkit-scrollbar-thumb { background: rgba(15,23,42,0.18); border-radius: 3px; }
#plan-modal-image-wrap::-webkit-scrollbar-thumb:hover { background: rgba(15,23,42,0.3); }
/* Sep 2026 fix, confirmed live -- align-items/justify-content:center on
   an overflow:auto flex container makes the "before center" overflow
   region (here, the top of the image once zoomed in) genuinely
   unreachable via scroll in most browsers. margin:auto centers this
   element ONLY when it's smaller than the wrap (small image case) and
   collapses to normal top-left positioning once it's zoomed larger,
   keeping every part of the image reachable by scroll either way. */
#plan-modal-image-inner { position: relative; display: block; flex-shrink: 0; margin: auto; }
#plan-modal-image { max-width: none; width: 100%; height: auto; display: block; transition: width 0.12s ease-out; }
#plan-modal-hotspots { position: absolute; inset: 0; width: 100%; height: 100%; }
.plan-hotspot {
  position: absolute;
  border: 2px solid rgba(13,148,136,0.55);
  background: rgba(13,148,136,0.07);
  cursor: pointer;
  border-radius: 4px;
  transition: background 0.15s, border-color 0.15s;
}
.plan-hotspot:hover { background: rgba(13,148,136,0.22); border-color: var(--primary); }
/* Sep 9 2026 -- real unit-shaped hotspots (SVG polygons), replacing the
   rectangle approximation where traced polygon data exists. Rolling out
   image by image, starting with Tower 02 & 03 Typical -- images without
   polygon data yet keep using the .plan-hotspot rectangles above. */
/* Sep 2026, Ram's explicit ask -- always-visible, bold boundaries +
   flat-number labels, so tracing inaccuracies are obvious in a plain
   screenshot with no click needed. */
.plan-hotspot-polygon {
  fill: rgba(239,68,68,0.12);
  stroke: rgba(220,38,38,0.9);
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
  cursor: pointer;
  transition: fill 0.15s, stroke 0.15s;
}
.plan-hotspot-polygon:hover { fill: rgba(13,148,136,0.3); stroke: var(--primary); }
.plan-hotspot-label {
  fill: #dc2626; font-size: 3px; font-weight: 700; font-family: 'Barlow', sans-serif;
  text-anchor: middle; dominant-baseline: middle;
  paint-order: stroke; stroke: #fff; stroke-width: 0.6px;
}
.plan-hotspot-callout {
  position: absolute;
  background: #0f172a;
  color: #fff;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 11px;
  font-family: 'Barlow', sans-serif;
  line-height: 1.5;
  white-space: nowrap;
  box-shadow: 0 4px 14px rgba(0,0,0,0.3);
  z-index: 20;
  pointer-events: none;
}
.plan-hotspot-callout strong { color: var(--primary-light); }
/* Sep 9 2026 -- revived as a TOGGLEABLE overlay (not a permanent flex
   sibling squeezing the image width, which was the original mobile
   problem). Floats on top of the image, opened only via the Amenities/
   Details button, closed by default. */
#plan-modal-side-panel {
  display: none;
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 260px;
  max-width: 80vw;
  background: #fff;
  border-left: 1px solid var(--border);
  padding: 12px;
  overflow-y: auto;
  z-index: 15;
  box-shadow: -4px 0 12px rgba(0,0,0,0.12);
}
#plan-modal-side-panel.open { display: block; }
#plan-amenity-toggle-btn {
  padding: 4px 10px; border-radius: 20px; border: 1.5px solid var(--border); background: #fff;
  color: var(--text-main); font-size: 11px; font-family: 'Barlow', sans-serif; cursor: pointer;
}
#plan-amenity-toggle-btn.active { background: var(--primary); color: #fff; border-color: var(--primary); }
.plan-legend-search {
  width: 100%; padding: 7px 10px; border: 1.5px solid var(--border); border-radius: 8px;
  font-size: 12px; font-family: 'Barlow', sans-serif; margin-bottom: 8px;
}
/* Sep 9 2026 -- new on-image floating controls, site plan only. Replaces
   the footer "Amenities" button (Ram's explicit call: "right on top of
   the image, not in the bottom nav bar"). Positioned absolute against
   #plan-modal-body (already position:relative), so it stays fixed on
   screen regardless of scroll/zoom/pan underneath. */
#plan-amenity-controls {
  position: absolute; top: 12px; right: 12px; z-index: 30;
  display: none; flex-direction: column; align-items: flex-end; gap: 6px;
}
#plan-amenity-controls.visible { display: flex; }
.plan-amenity-row { display: flex; gap: 6px; }
#plan-amenity-toggle-btn-onimage, #plan-amenity-list-all-btn {
  padding: 6px 12px; border-radius: 20px; border: none; background: rgba(15,23,42,0.85);
  color: #fff; font-size: 11px; font-family: 'Barlow', sans-serif; cursor: pointer;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2); display: flex; align-items: center; gap: 5px;
  transition: background 0.2s; white-space: nowrap;
}
#plan-amenity-toggle-btn-onimage:hover, #plan-amenity-list-all-btn:hover { background: rgba(15,23,42,1); }
#plan-amenity-toggle-btn-onimage.active { background: var(--primary); }
#plan-amenity-search {
  padding: 6px 10px; border-radius: 20px; border: none; background: rgba(15,23,42,0.85);
  color: #fff; font-size: 11px; font-family: 'Barlow', sans-serif; width: 160px; display: none;
}
#plan-amenity-search.visible { display: block; }
#plan-amenity-search::placeholder { color: rgba(255,255,255,0.6); }
#plan-amenity-search:focus { outline: none; background: rgba(15,23,42,1); }

/* Sep 2026 full redesign, Ram's explicit ask -- three problems fixed
   at once: (1) only amenities with real photos/videos pulse now --
   every other genuine location gets a small, quiet, STATIC dot with
   zero animation, so the site plan doesn't read as "Diwali lights"
   with 53 things blinking at once; (2) glossy teal/gold treatment on
   the clickable ones so they read as premium and obviously
   interactive, distinct from the plain blue tower labels; (3) label
   pulled tight against its dot (see chat.js offset change) instead of
   floating with a visible gap underneath it. */
.plan-amenity-marker {
  position: absolute; width: 8px; height: 8px; margin-left: -4px; margin-top: -4px;
  border-radius: 50%; background: rgba(255,255,255,0.6); border: 1.5px solid rgba(15,23,42,0.35);
  box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  z-index: 20; pointer-events: none;
}
.plan-amenity-marker.clickable {
  width: 17px; height: 17px; margin-left: -8.5px; margin-top: -8.5px;
  background: linear-gradient(135deg, #2dd4bf 0%, #0d9488 100%);
  border: 2px solid #fff;
  box-shadow: 0 2px 10px rgba(13,148,136,0.55), inset 0 1px 2px rgba(255,255,255,0.6);
  animation: aivAmenityGlossyPulse 1.8s ease-in-out infinite;
  pointer-events: auto; cursor: pointer;
  transition: transform 0.15s ease;
}
.plan-amenity-marker.clickable:hover {
  background: #fff; border-color: #0d9488;
  transform: scale(1.3);
  box-shadow: 0 4px 16px rgba(13,148,136,0.75), inset 0 1px 3px rgba(255,255,255,0.75);
}
@keyframes aivAmenityGlossyPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(13,148,136,0.5), inset 0 1px 2px rgba(255,255,255,0.6); }
  50%      { box-shadow: 0 0 0 9px rgba(13,148,136,0), inset 0 1px 2px rgba(255,255,255,0.6); }
}
.plan-amenity-marker-label {
  position: absolute; transform: translateX(-50%);
  background: linear-gradient(135deg, rgba(15,118,110,0.95) 0%, rgba(13,148,136,0.95) 100%);
  color: #fff; font-size: 9px; font-weight: 600; font-family: 'Barlow', sans-serif;
  padding: 3px 10px 3px 7px; border-radius: 12px; white-space: nowrap; z-index: 21;
  pointer-events: auto; cursor: pointer;
  border: 1px solid rgba(255,255,255,0.35);
  box-shadow: 0 3px 10px rgba(0,0,0,0.28), inset 0 1px 1px rgba(255,255,255,0.3);
  display: flex; align-items: center; gap: 4px;
  transition: transform 0.15s ease;
}
.plan-amenity-marker-label:hover { background: #fff; color: #0d9488; transform: translateX(-50%) scale(1.08); }
.plan-amenity-marker-label::before {
  content: '\f030'; font-family: 'Font Awesome 6 Free'; font-weight: 900; font-size: 7px; opacity: 0.85;
}

/* Drag-to-pan (Sep 9 2026, Ram's explicit ask) */
#plan-modal-image-wrap.pannable { cursor: grab; }
#plan-modal-image-wrap.dragging { cursor: grabbing !important; user-select: none; }

/* "List All" grid modal -- static reference view, replaces the old
   single-column textbook-style list entirely for the site plan. */
#plan-amenity-list-modal {
  display: none; position: absolute; inset: 0; z-index: 40; background: #fff; flex-direction: column;
}
#plan-amenity-list-modal.open { display: flex; }
.plan-amenity-list-header {
  background: var(--text-main); color: #fff; padding: 12px 16px; display: flex;
  justify-content: space-between; align-items: center; font-size: 13px; font-weight: 700; flex-shrink: 0;
}
#plan-amenity-list-close-btn {
  width: 28px; height: 28px; border-radius: 50%; background: rgba(239,68,68,0.25);
  border: none; color: #fff; cursor: pointer;
}
#plan-amenity-list-grid {
  flex: 1; overflow-y: auto; padding: 16px; display: grid;
  grid-template-columns: repeat(3, 1fr); gap: 6px 16px; font-size: 12px; color: var(--text-main);
}
@media (max-width: 480px) { #plan-amenity-list-grid { grid-template-columns: repeat(2, 1fr); } }

#plan-modal-side-panel::-webkit-scrollbar { width: 5px; }
#plan-modal-side-panel::-webkit-scrollbar-track { background: transparent; }
#plan-modal-side-panel::-webkit-scrollbar-thumb { background: rgba(15,23,42,0.15); border-radius: 3px; }
.plan-legend-list { list-style: none; padding: 0; margin: 0; font-size: 12px; color: var(--text-main); }
.plan-legend-list li {
  padding: 6px 8px; border-bottom: 1px solid #f1f5f9; border-radius: 5px; cursor: pointer; transition: background 0.15s;
}
.plan-legend-list li:hover { background: var(--bg-off); }
.plan-legend-list li.active { background: var(--primary-light); color: var(--primary-dark); font-weight: 600; }
.plan-legend-hint {
  font-size: 11px; color: var(--text-muted); padding: 6px 8px; border-top: 1px solid var(--border);
  margin-top: 4px; font-style: italic;
}
.plan-area-table { width: 100%; border-collapse: collapse; font-size: 11px; }
.plan-area-table th { background: var(--primary); color: #fff; padding: 6px 4px; text-align: left; }
.plan-area-table td { padding: 5px 4px; border-bottom: 1px solid #f1f5f9; }
/* Sep 9 2026 -- restyled to match the dark header theme (Ram's ask), so
   the mostly-white plan image is visually framed by two dark bars. */
.plan-modal-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; border-top: 1px solid rgba(255,255,255,0.1); background: var(--text-main); flex-shrink: 0; flex-wrap: wrap; }
#plan-modal-switcher { display: flex; flex-wrap: wrap; gap: 6px; }
.plan-switch-btn {
  padding: 4px 10px; border-radius: 20px; border: 1.5px solid rgba(255,255,255,0.25); background: transparent;
  color: #fff; font-size: 11px; font-family: 'Barlow', sans-serif; cursor: pointer;
}
.plan-switch-btn.active { background: var(--primary); color: #fff; border-color: var(--primary); }
.plan-zoom-controls { display: flex; gap: 4px; flex-shrink: 0; }
.plan-zoom-controls button {
  width: 28px; height: 28px; border-radius: 6px; border: 1px solid rgba(255,255,255,0.25); background: transparent;
  cursor: pointer; font-size: 13px; color: #fff;
}
@media (max-width: 480px) {
  .plan-modal-footer { flex-wrap: nowrap; }
  #plan-modal-switcher {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 60%;
  }
  #plan-modal-switcher::-webkit-scrollbar { height: 4px; }
  .plan-switch-btn { flex-shrink: 0; font-size: 10px; padding: 3px 8px; white-space: nowrap; }
  .plan-zoom-controls { flex-shrink: 0; }
}

#poi-map-fullscreen-btn, #plan-modal-fullscreen-btn {
  width: 28px; height: 28px; border-radius: 50%; background: rgba(255,255,255,0.1);
  border: none; color: #fff; font-size: 12px; cursor: pointer; margin-right: 6px;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
#poi-map-modal.modal-fullscreen, #plan-image-modal.modal-fullscreen,
#poi-map-modal:fullscreen, #plan-image-modal:fullscreen {
  position: fixed !important;
  inset: 0 !important;
  width: 100vw !important;
  height: 100vh !important;
  border-radius: 0 !important;
  z-index: 99999;
  background: #fff;
}

.plan-zoom-cap-hint {
  font-size: 10px; color: rgba(255,255,255,0.7); opacity: 0; transition: opacity 0.2s;
  margin-right: 4px; white-space: nowrap;
}
.plan-zoom-cap-hint.visible { opacity: 1; }

#chat-window-container.widget-maximized {
  position: fixed !important;
  top: 0.005% !important; left: 0.005% !important; right: 0.005% !important; bottom: 0.005% !important;
  width: 99.99vw !important; height: 99.99vh !important;
  border-radius: 0 !important;
  z-index: 999999 !important;
}

.poi-legend-chip.poi-legend-nav {
  background: var(--primary-light);
  color: var(--primary-dark);
  font-weight: 700;
  border-color: var(--primary);
}

/* Sep 2026 -- Unit Spotlight: cinematic full-screen zoom onto a single
   clicked unit, dims every other unit, slides in a real-facts panel. */
#plan-unit-spotlight-panel {
  position: absolute; bottom: 16px; left: 16px; right: 16px;
  background: rgba(15,23,42,0.92); color: #fff; border-radius: 12px;
  padding: 16px 20px; display: none; align-items: center; justify-content: flex-start;
  z-index: 35; opacity: 0; transform: translateY(20px);
  transition: opacity 0.4s ease, transform 0.4s ease;
}
#plan-unit-spotlight-panel.visible { display: flex; opacity: 1; transform: translateY(0); }
#plan-unit-spotlight-back-btn {
  background: rgba(255,255,255,0.15); border: none; color: #fff; padding: 8px 14px;
  border-radius: 20px; font-size: 12px; cursor: pointer; flex-shrink: 0; margin-right: 16px;
  white-space: nowrap;
}
#plan-unit-spotlight-info { flex: 1; }
#plan-unit-spotlight-info .unit-title { font-size: 17px; font-weight: 700; font-family: 'Barlow Condensed', serif; margin-bottom: 4px; }
#plan-unit-spotlight-info .unit-facts { display: flex; gap: 18px; font-size: 12px; flex-wrap: wrap; color: rgba(255,255,255,0.85); }
#plan-unit-spotlight-info .unit-facts strong { color: var(--primary-light); }

/* Sep 2026 fix -- polygons are transparent click-overlays at rest, so
   lowering opacity on an already-invisible shape did nothing. The dim
   effect needs a real, opaque dark fill to actually darken that part
   of the image underneath. */
/* Sep 2026 -- dim/spotlight polygon states retired along with the old
   live-zoom approach; replaced by the real crop modal below. */
/* Sep 2026 rewrite #2 -- replaces the separate full-viewport modal
   entirely (confirmed live: mis-rendered as a side panel, likely the
   same position:fixed containing-block quirk this project has hit
   before). Now a plain absolute-positioned crop layer living directly
   inside #plan-modal-image-wrap -- no separate modal, no
   document.body append, no position:fixed anywhere in this feature. */
/* Sep 2026 redesign -- fixes: (1) phantom scrollbar/blank space (the
   hidden main plan no longer reserves stale zoomed layout space, see
   JS), (2) info panel now hugs the unit vertically on the right instead
   of a bottom bar, (3) zoom reuses the exact same mechanism as the main
   plan (see _applyPlanZoom). */
/* Sep 2026 redesign #2 -- image + info panel now move and center
   together as one floating pair, not the panel pinned to the far
   screen edge. Outer wrap's overflow:auto (from main plan zoom/pan) is
   switched off via .unit-view-active while a unit is showing, since
   #plan-unit-crop-scroll now handles its own scroll independently --
   fixes the phantom scrollbar with nothing meaningful behind it. */
#plan-modal-image-wrap.unit-view-active { overflow: hidden; }
#plan-unit-view {
  display: none; position: absolute; inset: 0; z-index: 15;
  align-items: center; justify-content: center; background: #f1f5f9;
}
#plan-unit-view.visible { display: flex; }
/* Sep 2026 fix -- gap between image and panel (was one shared
   overflow:hidden shape, no gap); panel now has its own fully-rounded
   corners and auto-fits its content instead of a fixed 190px width
   leaving empty space. */
#plan-unit-content {
  display: flex; flex-direction: row; align-items: stretch; gap: 12px;
  max-width: 92%; max-height: 92%;
}
#plan-unit-crop-scroll {
  overflow: auto; display: flex; align-items: center; justify-content: center;
  max-width: 68vw; max-height: 80vh;
  border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,0.18);
}
#plan-unit-crop-img { display: block; border-radius: 12px; }
#plan-unit-info-bar {
  width: auto; max-width: 220px; flex-shrink: 0;
  background: rgba(15,23,42,0.95); color: #fff;
  border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,0.18);
  padding: 18px 16px; overflow-y: auto; display: flex; flex-direction: column; justify-content: center;
}
#plan-unit-info-bar .unit-title { font-size: 16px; font-weight: 700; font-family: 'Barlow Condensed', serif; margin-bottom: 18px; }
#plan-unit-info-bar .unit-facts { display: flex; flex-direction: column; gap: 12px; font-size: 12px; }
#plan-unit-info-bar .unit-facts strong { display: block; color: var(--primary-light); font-size: 10px; text-transform: uppercase; letter-spacing: 0.03em; opacity: 0.75; margin-bottom: 2px; }
@media (max-width: 640px) {
  #plan-unit-content { flex-direction: column; max-width: 96%; }
  #plan-unit-crop-scroll { max-width: 90vw; }
  #plan-unit-info-bar { width: 100%; max-height: 30vh; }
}
/* position:relative merged in here (was a separate, later duplicate
   block for this same selector -- consolidated per the project's own
   "duplicate selector blocks are a hard-to-spot bug class" lesson) so
   the crop layer's inset:0 binds to this wrap's own bounds. */
#plan-modal-image-wrap { scroll-behavior: smooth; position: relative; }

.plan-unit-expand-btn {
  display: block; margin-top: 6px; background: var(--primary); color: #fff; border: none;
  border-radius: 14px; padding: 5px 12px; font-size: 10px; cursor: pointer; font-family: 'Barlow', sans-serif;
}
.plan-unit-expand-btn:hover { background: var(--primary-dark); }

/* Sep 2026 -- inline amenity photo card, shown after the text response */
.amenity-photo-msg { padding: 0 !important; overflow: hidden; max-width: 260px; }
.amenity-photo-img { width: 100%; display: block; border-radius: var(--radius-md) var(--radius-md) 0 0; }
.amenity-photo-caption {
  padding: 8px 12px; font-size: 11px; color: var(--text-muted); background: var(--bg-off);
  border-radius: 0 0 var(--radius-md) var(--radius-md); font-family: 'Barlow', sans-serif;
}

/* Sep 2026 -- tower footprints on the site plan (distinct color from
   unit polygons) and the elevation view's floor ladder. */
/* Sep 2026 redesign, Ram's explicit ask -- glossy hover, cleaner
   premium look. White stroke-outline behind the blue text makes it
   pop against the busy photo background instead of sitting flat. */
.plan-tower-polygon {
  stroke: rgba(37,99,235,0.9); stroke-width: 1.5; fill: rgba(37,99,235,0.10);
  cursor: pointer; transition: fill 0.2s ease, stroke-width 0.2s ease;
}
/* Sep 2026, Ram's explicit ask -- invert-color hover, more obviously
   interactive than a subtle fill-opacity change. */
.plan-tower-polygon:hover { fill: rgba(37,99,235,0.92); stroke: #1e3a8a; stroke-width: 2.5; }
.plan-tower-label {
  fill: #1d4ed8; font-weight: 800;
  paint-order: stroke; stroke: #fff; stroke-width: 0.8px; stroke-linejoin: round;
}

/* Sep 2026 -- floor numbers drawn directly on the tower, hand-placed
   via the Plan Editor, same visual treatment as tower footprint labels
   plus a small pill background for legibility against the photo. */
.plan-floor-marker-label {
  fill: #fff; font-size: 2.6px; font-weight: 700; font-family: 'Barlow', sans-serif;
  text-anchor: middle; dominant-baseline: middle; cursor: pointer;
  paint-order: stroke; stroke: rgba(13,148,136,0.92); stroke-width: 2.4px; stroke-linejoin: round;
}
.plan-floor-marker-label.refuge { stroke: rgba(220,38,38,0.9); font-size: 2.1px; }

#plan-refuge-notice {
  display: none; position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%);
  background: rgba(15,23,42,0.92); color: #fff; padding: 10px 18px; border-radius: 20px;
  font-size: 12px; z-index: 40; white-space: nowrap;
}
#plan-refuge-notice.visible { display: block; }

.plan-breadcrumb-sep { color: rgba(255,255,255,0.4); font-size: 13px; align-self: center; }
.plan-switch-btn:disabled { opacity: 1; cursor: default; }

/* Sep 2026 -- dedicated amenity video modal. z-index must clear
   #chat-window-container.widget-maximized's 999999 !important (the
   exact stacking bug this project already hit once tonight with the
   unit-crop modal) -- same fix applied preemptively here.
   Sep 2026 update, Ram's explicit ask -- occupies 99.99% of the real
   viewport, matching the same fullscreen pattern the maps/plan views
   already use, instead of a modest 90vw/75vh box floating inside
   whatever size the widget already happened to be. */
/* Sep 2026 restructure, Ram's explicit ask -- follows the exact same
   header/body/footer pattern as .plan-modal-header/#plan-modal-body/
   .plan-modal-footer (same colors, same close-button treatment) instead
   of a raw fullscreen black void. This also structurally fixes the
   close-button collision with the widget's own chrome -- it now lives
   in a predictable header strip, same as every other modal. */
/* Sep 2026 rewrite -- confirmed root cause: was position:fixed on
   document.body, fighting #chat-window-container's global z-index
   across its static/fixed embed-mode transitions. Now nested INSIDE
   #chat-window-container instead (matches #poi-map-modal's own
   already-working pattern) -- position:absolute against that
   container naturally fills the SAME box the container itself
   occupies (99.99% of viewport once .widget-maximized is applied),
   no global z-index competition needed at all. */
#amenity-video-modal {
  /* Sep 2026 fix, confirmed root cause -- #plan-image-modal.modal-
     fullscreen jumps to z-index:99999 with position:fixed !important.
     950 never had a chance against that once triggered from a site
     plan/floor plan already open in fullscreen -- every earlier test
     tonight happened from plain chat with nothing else open, so this
     exact collision never surfaced until now. Matches the same
     1000000 ceiling already proven to clear every other modal in this
     widget (the unit-crop modal hit this identical class of bug
     earlier tonight too). */
  display: none; position: absolute; inset: 0; z-index: 1000000;
  background: rgba(10,15,25,0.6); align-items: center; justify-content: center;
}
#amenity-video-modal.visible { display: flex; }
#amenity-video-modal-inner {
  width: 100%; height: 100%; background: #000;
  display: flex; flex-direction: column;
}
#amenity-video-modal-header {
  background: var(--text-main); padding: 10px 14px;
  display: flex; justify-content: space-between; align-items: center; flex-shrink: 0;
}
#amenity-video-modal-title {
  color: #fff; font-size: 13px; font-weight: 700; display: flex; align-items: center; gap: 8px;
}
#amenity-video-modal-title i { color: var(--primary); }
#amenity-video-modal-close {
  width: 28px; height: 28px; border-radius: 50%; background: rgba(239,68,68,0.25);
  border: none; color: #fff; font-size: 12px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  transition: background 0.2s;
}
#amenity-video-modal-close:hover { background: rgba(239,68,68,0.5); }
#amenity-video-modal-body {
  flex: 1; display: flex; align-items: center; justify-content: center;
  overflow: hidden; position: relative;
}
/* Sep 2026 fix -- max-width/max-height only cap a size, they don't make
   an element GROW. The source file is a small 640x360 compressed clip,
   so it was rendering near its native pixel size with black filling
   everything else. width/height:100% + object-fit:contain makes it
   actually scale up to fill the available body space, letterboxing
   only where the real aspect ratio doesn't match -- not because the
   source file itself is small. */
#amenity-video-modal-player { display: block; width: 100%; height: 100%; object-fit: contain; }
#amenity-video-modal-error {
  display: none; padding: 24px 20px; color: #fca5a5; font-size: 13px; line-height: 1.5;
  max-width: 400px; text-align: center;
}
#amenity-video-modal-error.visible { display: block; }
#amenity-video-modal-spinner {
  display: none; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  color: #fff; font-size: 36px; z-index: 1;
}
#amenity-video-modal-spinner.visible { display: block; }
#amenity-video-modal-footer {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 8px 12px; border-top: 1px solid rgba(255,255,255,0.1);
  background: var(--text-main); flex-shrink: 0; min-height: 20px;
}

/* Sep 2026 fix -- this whole block was a stale duplicate of
   .plan-amenity-marker.clickable/.clickable:hover from an earlier
   round, left in place instead of removed when the glossy redesign
   was added above. Its static box-shadow was overriding the pulse
   animation's own box-shadow, since it came later in the file -- the
   exact "duplicate selector" bug class this project has hit before.
   Consolidated into the single correct block above; only the genuinely
   new rules (image sizing, tower hover) stay here. */
/* Sep 2026 fix -- same bug the video player already hit once tonight:
   max-width/max-height only CAPS a size, never makes a small source
   image grow to fill the available space. width/height:100% +
   object-fit:contain actually scales it up, letterboxing only where
   the real aspect ratio doesn't match -- not because the source file
   itself happens to be small. */
#amenity-video-modal-image { display: block; width: 100%; height: 100%; object-fit: contain; }