/* ── Fonts ───────────────────────────────────────────────────────────────── */

@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;0,800;0,900;1,400;1,500;1,600;1,700;1,800;1,900&family=Roboto:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,600&display=swap');

/* Locally-cached fallbacks. Only italic weights were available to capture
   from the live site's font CDN links — no upright cut exists locally, so
   the @import above (which does carry upright weights) is the primary
   source and these are a same-family safety net if that request is blocked. */
@font-face { font-family: 'Playfair Display'; src: url('fonts/PlayfairDisplay-400-italic.woff2') format('woff2'); font-weight: 400; font-style: italic; }
@font-face { font-family: 'Playfair Display'; src: url('fonts/PlayfairDisplay-500-italic.woff2') format('woff2'); font-weight: 500; font-style: italic; }
@font-face { font-family: 'Playfair Display'; src: url('fonts/PlayfairDisplay-600-italic.woff2') format('woff2'); font-weight: 600; font-style: italic; }
@font-face { font-family: 'Playfair Display'; src: url('fonts/PlayfairDisplay-700-italic.woff2') format('woff2'); font-weight: 700; font-style: italic; }
@font-face { font-family: 'Roboto'; src: url('fonts/Roboto-400-italic.woff2') format('woff2'); font-weight: 400; font-style: italic; }
@font-face { font-family: 'Roboto'; src: url('fonts/Roboto-500-italic.woff2') format('woff2'); font-weight: 500; font-style: italic; }

/* ── The Trilogy Residences Virtual Tour — Luxury Design System ────────────────── */

:root {
  --tw-navy: #2E3035;      /* dark grey base (Danny 2026-10-19: grey UI, burgundy as the accent) */
  --tw-navy-deep: #17181b; /* dark-glass base */
  --tw-cream: #F4EDE5;
  --tw-ink: #212529;       /* primary on-site body text color, for any future light-ground UI */
  --tw-gold: #8A4262;      /* Trilogy burgundy accent (map hue); fills, borders, pins, rules */
  --tw-accent-text: #F4EDE5; /* burgundy is too dark to read as small text on dark grey: accent TEXT stays cream */
  --tw-serif: 'Playfair Display', serif;
  --tw-sans: 'Roboto', sans-serif;
  --tw-ease: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  /* onboarding hint card: deliberately brand-neutral frosted white (same as the other Devon tours) */
  --hint-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --hint-bg: rgba(255, 255, 255, 0.58);
  --hint-border: rgba(255, 255, 255, 0.5);
  --hint-ink: rgba(22, 22, 26, 0.9);
  --hint-ink-soft: rgba(22, 22, 26, 0.62);
  --hint-ink-faint: rgba(22, 22, 26, 0.48);
}

/* While #viewer is held at opacity 0 (inline tag in index.html) and before #tw-splash exists, the page shows
   html/body: make that the splash's own colour so there is no white flash ahead of the splash. */
html, body { background: var(--tw-navy-deep); }

/* ── SPLASH ──────────────────────────────────────────────────────────────── */

#tw-splash {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Solid-color fallback only (paints instantly) — no static hero image, so
     there's no render-then-crossfade-to-video flash. The video is the splash. */
  background: var(--tw-navy-deep);
  transition: opacity 1.0s var(--tw-ease);
  overflow: hidden;
}

#tw-splash-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  transform: scale(1);
  transition: transform 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.tw-splash-overlay {
  position: absolute;
  inset: 0;
  background: rgba(23, 24, 27, 0.65);
  z-index: 1;
  transition: background 0.5s var(--tw-ease);
}

#tw-splash.tw-hiding {
  opacity: 0;
  pointer-events: none;
}

/* Cinematic exit: video slowly pushes in and overlay seals to black */
#tw-splash.tw-hiding #tw-splash-video {
  transform: scale(1.07);
}

#tw-splash.tw-hiding .tw-splash-overlay {
  background: rgba(23, 24, 27, 0.78);
}

#tw-splash.tw-gone {
  display: none;
}

.tw-splash-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 48px 36px;
  width: 100%;
  max-width: 720px;
  position: relative;
  z-index: 2;
}

.tw-splash-wordmark-img {
  width: clamp(260px, 30vw, 520px);
  height: auto;
  margin-bottom: clamp(16px, 1.6vw, 26px);
  opacity: 0;
  transform: translateY(24px);
  animation: tw-rise 1.5s 0.45s var(--tw-ease) forwards;
  user-select: none;
  pointer-events: none;
}

.tw-splash-sub {
  font-family: var(--tw-sans);
  font-size: clamp(16.5px, 1.6vw, 24px);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(244, 237, 229, 0.78);
  margin-top: 15px;
  opacity: 0;
  animation: tw-fade 0.8s 0.45s var(--tw-ease) forwards;
}

.tw-splash-rule {
  width: clamp(72px, 7vw, 108px);
  height: 1.5px;
  background: linear-gradient(90deg, transparent, var(--tw-gold), transparent);
  margin: clamp(18px, 1.8vw, 28px) auto;
  opacity: 0;
  animation: tw-fade 1.1s 0.9s var(--tw-ease) forwards;
}

/* ── FLOATING MAP PILL ───────────────────────────────────────────────────── */
/* No inline preview map anymore (dropped 2026-07-09) — this is a single
   button, styled like the other floating pills, that opens the fullscreen
   map modal directly. */

#tw-map-card {
  position: fixed;
  bottom: 42px;
  right: 36px;
  z-index: 100;
  border-radius: 999px;
  overflow: hidden;
  border: 1px solid rgba(138, 66, 98, 0.18);
  box-shadow: 0 12px 60px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(138, 66, 98, 0.06) inset;
  background: rgba(23, 24, 27, 0.84);
  backdrop-filter: blur(24px) saturate(170%);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  transition-delay: 0.3s;
}

.tw-map-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16.5px 24px;
  background: transparent;
  border: none;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.18s;
}

.tw-map-header:hover { background: rgba(255, 255, 255, 0.04); }
.tw-map-header:focus-visible { outline: 2px solid var(--tw-gold); outline-offset: -2px; }

.tw-map-header-icon {
  color: var(--tw-accent-text);
  flex-shrink: 0;
  display: flex;
  align-items: center;
}

.tw-map-header-text {
  font-family: var(--tw-sans);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.20em;
  text-transform: uppercase;
  color: rgba(244, 237, 229, 0.72);
  text-align: left;
  white-space: nowrap;
}

.tw-splash-location {
  font-family: var(--tw-sans);
  font-size: clamp(15px, 1.4vw, 21px);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(244, 237, 229, 0.78);
  margin-top: 14px;
  opacity: 0;
  animation: tw-fade 1.0s 1.15s var(--tw-ease) forwards;
}

.tw-splash-enter {
  margin-top: clamp(24px, 2.4vw, 42px);
  font-family: var(--tw-sans);
  font-size: clamp(15px, 1.2vw, 18px);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--tw-cream);
  background: var(--tw-gold);
  border: none;
  border-radius: 150px;
  padding: clamp(18px, 1.8vw, 24px) clamp(42px, 4vw, 66px);
  min-height: 72px;
  min-width: 66px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 18px;
  touch-action: manipulation;
  box-shadow: 0 4px 24px rgba(138, 66, 98, 0.40);
  transition: background 0.22s, box-shadow 0.22s, transform 0.18s var(--tw-ease);
  opacity: 0;
  animation: tw-rise 1.1s 1.4s var(--tw-ease) forwards;
}

.tw-splash-enter:hover {
  background: #A04F72;   /* hover: a step lighter than the burgundy fill (was Ellis olive) */
  box-shadow: 0 6px 32px rgba(138, 66, 98, 0.55);
  transform: translateY(-1.5px);
}

.tw-splash-enter:focus-visible {
  outline: 2px solid var(--tw-gold);
  outline-offset: 4px;
}

.tw-splash-arrow {
  width: 21px;
  height: 21px;
  transition: transform 0.18s var(--tw-ease);
}

.tw-splash-enter:hover .tw-splash-arrow {
  transform: translateX(4.5px);
}

/* Devon Properties — pinned to bottom of splash, with label */
.tw-splash-devon-wrap {
  position: absolute;
  bottom: 40px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 11px;
  opacity: 0;
  animation: tw-fade 1.0s 1.65s var(--tw-ease) forwards;
  white-space: nowrap;
}

.tw-splash-devon-label {
  font-family: var(--tw-sans);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(244, 237, 229, 0.42);
}

.tw-splash-devon-img {
  width: clamp(100px, 8vw, 138px);
  height: auto;
  filter: drop-shadow(0 1px 10px rgba(0,0,0,0.45));
  user-select: none;
  pointer-events: none;
}

/* ── ANIMATIONS ──────────────────────────────────────────────────────────── */

@keyframes tw-rise {
  from { opacity: 0; transform: translateY(21px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes tw-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ── VIGNETTES ───────────────────────────────────────────────────────────── */

/* All four vignettes below use a raised-cosine ease (alpha(t) = peak * 0.5 *
   (1 + cos(pi*t))) instead of hand-picked linear steps. A linear ramp that
   snaps to a flat 0 at its last stop has a slope DISCONTINUITY right at that
   last stop — the eye's contrast sensitivity picks up exactly that kind of
   "knee" as a visible seam (a Mach band) even though the color values
   themselves are technically continuous, especially over a large flat bright
   surface (a ceiling, a wall) with nothing else to break it up (reported by
   Danny looking straight up at Ellis's rooftop, 2026-07-09). The cosine curve
   has ZERO slope at both t=0 and t=1, so it eases out and touches zero
   tangentially — no knee anywhere along the curve. */
#tw-vignette-top {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 195px;
  background: linear-gradient(to bottom,
    rgba(14, 15, 17, 0.45) 0%,
    rgba(14, 15, 17, 0.44) 15%,
    rgba(14, 15, 17, 0.36) 30%,
    rgba(14, 15, 17, 0.26) 45%,
    rgba(14, 15, 17, 0.16) 60%,
    rgba(14, 15, 17, 0.07) 75%,
    rgba(14, 15, 17, 0.01) 90%,
    rgba(14, 15, 17, 0) 100%
  );
  z-index: 98;
  pointer-events: none;
}

#tw-vignette-bottom {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 270px;
  background: linear-gradient(to top,
    rgba(14, 15, 17, 0.40) 0%,
    rgba(14, 15, 17, 0.38) 15%,
    rgba(14, 15, 17, 0.32) 30%,
    rgba(14, 15, 17, 0.23) 45%,
    rgba(14, 15, 17, 0.14) 60%,
    rgba(14, 15, 17, 0.06) 75%,
    rgba(14, 15, 17, 0.01) 90%,
    rgba(14, 15, 17, 0) 100%
  );
  z-index: 98;
  pointer-events: none;
}

/* Top-left vignette — kept very subtle so top darkness is consistent across
   the full width (the top linear vignette handles the primary coverage).
   Cosine-eased all the way to 100% (missed in the first pass, which cut the
   curve short at 90%→0 — same hard-knee bug as the others, reported again by
   Danny 2026-07-09 looking at the Devon logo corner). Explicit `farthest-side`
   sizing (2026-07-09, later still) — the default `farthest-corner` sizes the
   ellipse to reach the box's diagonal corner, which makes it ~41% larger than
   the box along the straight top/left edges, so alpha never actually reached
   0 before the 480×280 div ran out — a real rectangular edge was visible at
   the div's own boundary, independent of the cosine-ease fix above (that fix
   only smooths the curve *within* whatever the ellipse's true edge is; it
   can't fix the box being undersized relative to that edge). `farthest-side`
   sizes the ellipse to exactly the box's own width/height, so alpha reaches
   true 0 right at the div boundary. */
#tw-vignette-tl {
  position: fixed;
  top: 0;
  left: 0;
  width: 480px;
  height: 280px;
  background: radial-gradient(ellipse farthest-side at 0% 0%,
    rgba(14, 15, 17, 0.18) 0%,
    rgba(14, 15, 17, 0.17) 15%,
    rgba(14, 15, 17, 0.14) 30%,
    rgba(14, 15, 17, 0.10) 45%,
    rgba(14, 15, 17, 0.06) 60%,
    rgba(14, 15, 17, 0.03) 75%,
    rgba(14, 15, 17, 0.005) 90%,
    rgba(14, 15, 17, 0) 100%
  );
  z-index: 98;
  pointer-events: none;
}

/* Bottom-left vignette — behind the "Now Viewing" toast. Strengthened over
   the base Thera values (2026-07-09) — bright interior panos were washing
   out the unit text/meta row otherwise. Re-eased (same day, later) after a
   ceiling-pointed test still showed a visible seam — see the comment above
   #tw-vignette-top for why a cosine ease fixes it where a linear one didn't.
   Also given explicit `farthest-side` sizing (2026-07-09, later still) — see
   the comment on #tw-vignette-tl for why the default `farthest-corner`
   leaves a visible rectangular edge at the box's own boundary. */
#tw-vignette-toast {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 850px;
  height: 680px;
  background: radial-gradient(ellipse farthest-side at 0% 100%,
    rgba(14, 15, 17, 0.95) 0%,
    rgba(14, 15, 17, 0.90) 15%,
    rgba(14, 15, 17, 0.75) 30%,
    rgba(14, 15, 17, 0.55) 45%,
    rgba(14, 15, 17, 0.33) 60%,
    rgba(14, 15, 17, 0.14) 75%,
    rgba(14, 15, 17, 0.02) 90%,
    rgba(14, 15, 17, 0) 100%
  );
  z-index: 98;
  pointer-events: none;
}

/* ── UI FLOAT VISIBILITY ─────────────────────────────────────────────────── */

.tw-ui-el {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.55s var(--tw-ease);
}

.tw-ui-el.tw-show {
  opacity: 1;
  pointer-events: all;
}

#tw-devon-logo-float { transition-delay: 0.04s; }
#tw-logo-float       { transition-delay: 0.08s; }
#tw-cta-btn          { transition-delay: 0.12s; }
#tw-menu-bar         { transition-delay: 0.22s; }

/* ── FLOATING LOGOS ────────────────────────────────────────────────────────── */

/* Devon Properties — top left (developer / brokerage mark) */
#tw-devon-logo-float {
  position: fixed;
  top: 30px;
  left: 36px;
  z-index: 100;
}

.tw-devon-logo-img {
  display: block;
  height: 52px;
  width: auto;
  filter: drop-shadow(0 2px 14px rgba(0,0,0,0.55));
}

/* Trilogy — horizontally centred at top, shifted slightly below the top edge */
#tw-logo-float {
  position: fixed;
  top: 38px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
}

.tw-logo-svg {
  display: block;
  height: 90px;
  width: auto;
  filter: drop-shadow(0 2px 18px rgba(0,0,0,0.55));
}

/* ── FLOATING CTA ─────────────────────────────────────────────────────────── */

#tw-cta-btn {
  position: fixed;
  top: 27px;
  right: 30px;
  z-index: 100;
  font-family: var(--tw-sans);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--tw-cream);
  background: var(--tw-gold);
  border-radius: 150px;
  padding: 0 33px;
  height: 66px;
  min-width: 66px;
  display: flex;
  align-items: center;
  white-space: nowrap;
  transition: opacity 0.55s var(--tw-ease), filter 0.2s;
  transition-delay: 0.12s, 0s;
}

#tw-cta-btn:hover  { filter: brightness(1.1); }
#tw-cta-btn:focus-visible { outline: 2px solid var(--tw-cream); outline-offset: 3px; }

/* ── BOTTOM MENU BAR ─────────────────────────────────────────────────────── */

#tw-menu-bar {
  position: fixed;
  bottom: 42px;
  left: 50%;
  transform: translateX(-50%);
  /* Higher than #tw-map-card's z-index:100 so the whole menu bar (dropdowns
     included) reliably paints above the map pill — .tw-dropdown's own
     z-index:200 doesn't help here since it's nested inside this element's
     own stacking context. Fixed 2026-08-06 (found live on the deployed
     tour: open suites dropdown got its bottom-right corner covered by the
     map FAB). Full mechanism in MetaTours/CLAUDE.md. */
  z-index: 150;
}

.tw-menu-pill {
  display: flex;
  align-items: center;
  background: rgba(23, 24, 27, 0.84);
  backdrop-filter: blur(24px) saturate(170%);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  border: 1px solid rgba(138, 66, 98, 0.18);
  border-radius: 150px;
  padding: 0 9px;
  height: 78px;
  gap: 0;
  box-shadow: 0 12px 54px rgba(0, 0, 0, 0.4), 0 1.5px 0 rgba(138, 66, 98, 0.06) inset;
}

/* ── MENU TRIGGER BUTTONS ─────────────────────────────────────────────────── */

.tw-menu-group {
  position: relative;
}

.tw-menu-btn {
  display: flex;
  align-items: center;
  gap: 10.5px;
  font-family: var(--tw-sans);
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: rgba(244, 237, 229, 0.52);
  background: transparent;
  border: none;
  padding: 0 25.5px;
  height: 60px;
  border-radius: 150px;
  cursor: pointer;
  white-space: nowrap;
  touch-action: manipulation;
  transition: color 0.18s, background 0.18s;
}

.tw-menu-btn:hover {
  color: rgba(244, 237, 229, 0.88);
  background: rgba(255, 255, 255, 0.05);
}

.tw-menu-btn[aria-expanded="true"] {
  color: var(--tw-cream);
  background: rgba(255, 255, 255, 0.07);
}

.tw-menu-btn.tw-active {
  color: var(--tw-accent-text);
}

.tw-menu-btn:focus-visible {
  outline: 2px solid var(--tw-gold);
  outline-offset: -2px;
  border-radius: 150px;
}

.tw-menu-chevron {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  opacity: 0.4;
  transition: transform 0.22s var(--tw-ease), opacity 0.18s;
}

.tw-menu-btn:hover .tw-menu-chevron { opacity: 0.65; }
.tw-menu-btn.tw-active .tw-menu-chevron { opacity: 0.65; }
.tw-menu-btn[aria-expanded="true"] .tw-menu-chevron {
  transform: rotate(180deg);
  opacity: 0.9;
}

/* ── SEPARATOR ───────────────────────────────────────────────────────────── */

.tw-menu-sep {
  width: 1.5px;
  height: 27px;
  background: rgba(244, 237, 229, 0.1);
  flex-shrink: 0;
  margin: 0 3px;
}

/* ── DRONE / AERIAL BUTTON ───────────────────────────────────────────────── */

#tw-aerial {
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  width: 66px;
  height: 60px;
  border-radius: 150px;
  cursor: pointer;
  color: rgba(244, 237, 229, 0.52);
  touch-action: manipulation;
  transition: color 0.18s, background 0.18s;
  margin: 0 3px;
}

#tw-aerial:hover {
  color: rgba(244, 237, 229, 0.88);
  background: rgba(255, 255, 255, 0.05);
}

#tw-aerial.tw-active { color: var(--tw-accent-text); }

#tw-aerial svg {
  width: 24px;
  height: 24px;
}

#tw-aerial:focus-visible {
  outline: 2px solid var(--tw-gold);
  outline-offset: -2px;
  border-radius: 150px;
}

/* ── DROPDOWN CARDS ──────────────────────────────────────────────────────── */

.tw-dropdown {
  position: absolute;
  bottom: calc(100% + 24px);
  left: 50%;
  transform: translateX(-50%) translateY(12px);
  min-width: 277.5px;
  background: rgba(20, 21, 24, 0.96);
  backdrop-filter: blur(28px) saturate(160%);
  -webkit-backdrop-filter: blur(28px) saturate(160%);
  border: 1px solid rgba(138, 66, 98, 0.2);
  border-radius: 24px;
  padding: 9px;
  box-shadow: 0 30px 84px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(138, 66, 98, 0.06);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s var(--tw-ease), transform 0.2s var(--tw-ease);
}

#tw-suites-dd {
  min-width: 290px;
  max-height: 62vh;
  overflow-y: auto;
}

/* Wider than the base 277.5px — rows pair a label with a "Coming Soon" tag
   (e.g. "Bike Repair & Wash" + tag), which clips at the narrower width. */
#tw-amenities-dd {
  min-width: 340px;
}

.tw-dropdown.tw-open {
  opacity: 1;
  pointer-events: all;
  transform: translateX(-50%) translateY(0);
}

/* ── Polished dropdown scroller ──────────────────────────────────────────── */
/* Both dropdowns scroll when content exceeds the card; give them a slim,
   gold-tinted scrollbar (inset via a transparent border) instead of the raw
   default one, plus smooth scrolling and scroll containment. */
.tw-dropdown {
  max-height: 62vh;
  overflow-y: auto;
  scroll-behavior: smooth;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(138, 66, 98, 0.32) transparent;
}
.tw-dropdown::-webkit-scrollbar { width: 10px; }
.tw-dropdown::-webkit-scrollbar-track { background: transparent; }
.tw-dropdown::-webkit-scrollbar-thumb {
  background: rgba(138, 66, 98, 0.3);
  border-radius: 99px;
  border: 3px solid transparent;
  background-clip: padding-box;
}
.tw-dropdown::-webkit-scrollbar-thumb:hover {
  background: rgba(138, 66, 98, 0.55);
  background-clip: padding-box;
}

.tw-dropdown-label {
  font-family: var(--tw-sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(244, 237, 229, 0.25);
  padding: 9px 21px 12px;
  display: block;
  border-bottom: 1px solid rgba(138, 66, 98, 0.1);
  margin-bottom: 6px;
}

/* Group header inside suite dropdown */
/* Empty state — shown in amenities dropdown until panos are added */
.tw-dropdown-empty {
  display: block;
  font-family: var(--tw-sans);
  font-size: 13.5px;
  font-weight: 400;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(244, 237, 229, 0.28);
  padding: 14px 21px 18px;
  text-align: center;
}

/* Per-item "Coming Soon" row — amenities with no pano coverage yet, shown
   alongside real clickable entries rather than replacing the whole list. */
.tw-dropdown-item-soon {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  font-family: var(--tw-sans);
  font-size: 15px;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: rgba(244, 237, 229, 0.32);
  padding: 11px 21px;
  border-radius: 15px;
  cursor: default;
  user-select: none;
}

.tw-dropdown-soon-tag {
  flex-shrink: 0;
  font-family: var(--tw-sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(138, 66, 98, 0.85);
  border: 1px solid rgba(138, 66, 98, 0.35);
  border-radius: 999px;
  padding: 3px 9px;
  white-space: nowrap;
}

.tw-dropdown-group-label {
  display: block;
  font-family: var(--tw-sans);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(138, 66, 98, 0.65);
  padding: 14px 21px 5px;
}

.tw-dropdown-group-label:first-child { padding-top: 6px; }

.tw-dropdown-item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
  width: 100%;
  font-family: var(--tw-sans);
  font-size: 17px;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: rgba(244, 237, 229, 0.55);
  background: transparent;
  border: none;
  padding: 11px 21px 11px 39px;
  border-radius: 15px;
  cursor: pointer;
  text-align: left;
  touch-action: manipulation;
  transition: color 0.15s, background 0.15s;
  position: relative;
}

/* Unit name — primary text in each suite item */
.tw-dd-unit-name {
  font-size: 17px;
  font-weight: 400;
  color: inherit;
  letter-spacing: 0.02em;
}

/* Staged show suites, using Ellis's olive accent. Wrap the badge on small screens. */
.tw-dd-row-top {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 10px;
  width: 100%;
}
.tw-dropdown-show-tag {
  flex-shrink: 0;
  font-family: var(--tw-sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--tw-cream);
  background: rgba(138, 66, 98, 0.7);
  padding: 3px 9px;
  border-radius: 4px;
  white-space: nowrap;
}

/* Metadata row: bed / bath / sqft */
.tw-dd-meta {
  display: flex;
  align-items: center;
  gap: 13px;
  opacity: 0.6;
  transition: opacity 0.15s;
}

.tw-dropdown-item:hover   .tw-dd-meta { opacity: 0.85; }
.tw-dropdown-item.tw-active .tw-dd-meta { opacity: 0.75; }

.tw-dd-meta-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--tw-sans);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(244, 237, 229, 0.75);
}

.tw-dropdown-item::before {
  content: '';
  position: absolute;
  left: 15px;
  top: 50%;
  transform: translateY(-50%);
  width: 4.5px;
  height: 4.5px;
  border-radius: 50%;
  background: var(--tw-gold);
  opacity: 0;
  transition: opacity 0.15s;
}

.tw-dropdown-item:hover {
  color: var(--tw-cream);
  background: rgba(255, 255, 255, 0.05);
}

.tw-dropdown-item.tw-active {
  color: var(--tw-cream);
  font-weight: 500;
}

.tw-dropdown-item.tw-active::before {
  opacity: 1;
}

.tw-dropdown-item:focus-visible {
  outline: 2px solid var(--tw-gold);
  outline-offset: -2px;
  border-radius: 15px;
}

/* ── ROOM NAME TOAST ─────────────────────────────────────────────────────── */

#tw-toast {
  position: fixed;
  bottom: 52px;
  left: 48px;
  z-index: 99;
  pointer-events: none;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.7s var(--tw-ease), transform 0.7s var(--tw-ease);
  max-width: 500px;
}

#tw-toast.tw-show {
  opacity: 1;
  transform: translateY(0);
}

.tw-toast-label {
  display: block;
  font-family: var(--tw-sans);
  font-size: clamp(22px, 1.6vw, 28px);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--tw-gold);
  margin-bottom: 12px;
  text-shadow: 0 1.5px 15px rgba(0,0,0,0.6);
}

.tw-toast-room {
  display: block;
  font-family: var(--tw-serif);
  font-size: clamp(54px, 4.2vw, 86px);
  font-weight: 300;
  color: var(--tw-cream);
  line-height: 1.05;
  text-shadow: 0 3px 30px rgba(0,0,0,0.55);
  letter-spacing: 0.01em;
}

.tw-toast-meta {
  display: flex;
  align-items: center;
  gap: 24px;
  margin-top: 18px;
  font-family: var(--tw-sans);
  font-size: clamp(17px, 1.3vw, 22px);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #fff;   /* bed/bath text white (Danny 2026-10-19); the icons stay burgundy */
  text-shadow: 0 1.5px 12px rgba(0,0,0,0.6);
}

.tw-toast-meta-item {
  display: inline-flex;
  align-items: center;
  gap: 9px;
}

.tw-toast-meta-icon {
  color: var(--tw-gold);
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
}

.tw-toast-meta-icon svg {
  width: 30px;
  height: 30px;
}

/* ── RESPONSIVE ──────────────────────────────────────────────────────────── */

/* Tablet — fires earlier (≤1199px) so mid-size laptops and iPads get
   a properly scaled layout before things start overlapping. */
@media (max-width: 1199px) and (min-width: 769px) {
  #tw-devon-logo-float { top: 22px; left: 26px; }
  .tw-devon-logo-img { height: 42px; }
  #tw-logo-float { top: 28px; }
  .tw-logo-svg { height: 64px; }
  #tw-cta-btn    { top: 22px; right: 22px; height: 56px; padding: 0 24px; font-size: 13.5px; }

  #tw-menu-bar   { bottom: calc(22px + env(safe-area-inset-bottom)); }
  .tw-menu-pill  { height: 64px; padding: 0 6px; }
  .tw-menu-btn   { padding: 0 18px; height: 50px; font-size: 14px; gap: 8px; }
  .tw-menu-sep   { height: 24px; margin: 0 2px; }
  #tw-aerial     { width: 56px; height: 50px; margin: 0 2px; }

  #tw-toast      { bottom: calc(52px + env(safe-area-inset-bottom)); left: 24px; max-width: min(42vw, 420px); }
  .tw-toast-label { font-size: clamp(16px, 2vw, 20px); letter-spacing: 0.16em; margin-bottom: 9px; }
  .tw-toast-room  { font-size: clamp(36px, 5vw, 54px); }
  .tw-toast-meta  { gap: 16px; margin-top: 12px; font-size: clamp(13px, 1.4vw, 17px); }

  #tw-map-card   { bottom: calc(52px + env(safe-area-inset-bottom)); right: 22px; width: 280px; }
  #tw-map        { height: 200px; }
}

/* Mobile — all phones (portrait & landscape) and small tablets ≤768px.
   Radical layout: toast moves to top, map collapses to a circle FAB,
   menu pill goes full-width across the bottom.
   Minimum readable sizes enforced throughout — no text below 15px. */
@media (max-width: 768px) {
  /* One consistent 20px edge gutter for every floating element on mobile —
     the base build mixed 14/16/18px insets across different pieces, which
     read as slightly haphazard/cramped up close on a real device. */

  /* Logos — Ellis top-left, Devon hidden on mobile (shown in splash) */
  #tw-devon-logo-float { display: none; }
  #tw-logo-float { top: 18px; left: 20px; transform: none; }
  .tw-logo-svg { height: 54px; }

  /* CTA */
  #tw-cta-btn {
    top: 18px;
    right: 20px;
    height: 54px;
    min-width: 0;
    padding: 0 26px;
    font-size: 15px;
    letter-spacing: 0.12em;
  }

  /* Menu pill — full-width, generous touch targets, readable text */
  #tw-menu-bar   { bottom: calc(18px + env(safe-area-inset-bottom)); width: calc(100vw - 40px); display: flex; justify-content: center; left: 20px; right: 20px; transform: none; }
  .tw-menu-pill  {
    height: 70px; padding: 0 6px; max-width: 100%;
    /* Blur creates a containing block that traps the fixed dropdowns. */
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: rgba(23, 24, 27, 0.96);
  }
  .tw-menu-btn   { padding: 0 20px; height: 58px; font-size: 16px; gap: 8px; letter-spacing: 0.04em; }
  .tw-menu-sep   { height: 26px; margin: 0 2px; }
  #tw-aerial     { width: 58px; height: 58px; margin: 0 2px; }
  .tw-menu-chevron { width: 13px; height: 13px; }
  .tw-menu-pill::-webkit-scrollbar { display: none; }

  /* Toast — top of screen, below the logo/CTA bar.
     Min sizes: label ≥16px, room name ≥38px, meta ≥16px. */
  #tw-toast       { bottom: auto; top: calc(104px + env(safe-area-inset-top)); left: 20px; right: 20px; max-width: none; transform: translateY(-10px); }
  #tw-toast.tw-show { transform: translateY(0); }
  .tw-toast-label { font-size: 16px; letter-spacing: 0.16em; margin-bottom: 10px; }
  .tw-toast-dot   { display: none; }
  .tw-toast-loc-b { display: block; margin-top: 6px; }
  .tw-toast-room  { font-size: clamp(38px, 10vw, 56px); line-height: 1.0; }
  .tw-toast-meta  { flex-direction: row; align-items: flex-start; gap: 20px; margin-top: 12px; font-size: 16px; letter-spacing: 0.08em; }
  .tw-toast-meta-item { gap: 8px; align-items: center; }
  .tw-toast-meta-icon svg { width: 26px !important; height: 26px !important; }

  /* Map pill → circle FAB — tap opens fullscreen modal.
     Positioned above the menu pill with a clear 16px gap (menu-bar: 18px base
     + 70px pill = 88px to its top edge; +16px gap = 104px). */
  #tw-map-card {
    bottom: calc(104px + env(safe-area-inset-bottom));
    right: 20px;
    left: auto;
    width: 68px;
    height: 68px;
    border-radius: 50%;
  }
  .tw-map-header { width: 100%; height: 100%; padding: 0; gap: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
  .tw-map-header-text { display: none; }
  .tw-map-header-icon { display: flex; align-items: center; justify-content: center; }
  .tw-map-header-icon svg { width: 26px !important; height: 26px !important; stroke-width: 2.2 !important; }

  /* Splash — readable minimums: subtext ≥17px, enter button ≥17px */
  .tw-splash-inner { padding: 36px 30px; }
  .tw-splash-wordmark-img { width: clamp(250px, 76vw, 340px); margin-bottom: 14px; }
  .tw-splash-sub { font-size: 17px; letter-spacing: 0.16em; margin-top: 14px; }
  .tw-splash-location { font-size: 16px; letter-spacing: 0.12em; margin-top: 12px; }
  .tw-splash-enter {
    margin-top: 24px;
    font-size: 17px;
    padding: 20px 44px;
    min-height: 64px;
    gap: 18px;
  }
  .tw-splash-arrow { width: 22px; height: 22px; }
  .tw-splash-rule { margin: 16px auto; }
  .tw-splash-devon-wrap { bottom: 28px; gap: 9px; }
  .tw-splash-devon-img { width: clamp(100px, 28vw, 140px); }

  /* Vignettes — sized to just cover the toast block, not sprawl deep into the
     open pano below it (was 320px — reads as sitting "too high" against
     bright panos). Cosine-eased falloff (see the comment above the base
     #tw-vignette-top rule) — a linear ramp ending in a flat 0 still showed a
     visible seam against a ceiling pano even after fixing the `transparent`-
     keyword hue shift, because the slope itself still snapped to flat right
     at the last stop. The cosine curve has zero slope at both ends. */
  #tw-vignette-top {
    height: 240px;
    background: linear-gradient(to bottom,
      rgba(14, 15, 17, 0.82) 0%,
      rgba(14, 15, 17, 0.78) 15%,
      rgba(14, 15, 17, 0.65) 30%,
      rgba(14, 15, 17, 0.47) 45%,
      rgba(14, 15, 17, 0.28) 60%,
      rgba(14, 15, 17, 0.12) 75%,
      rgba(14, 15, 17, 0.02) 90%,
      rgba(14, 15, 17, 0) 100%
    );
  }
  #tw-vignette-bottom {
    height: 200px;
    background: linear-gradient(to top,
      rgba(14, 15, 17, 0.40) 0%,
      rgba(14, 15, 17, 0.38) 15%,
      rgba(14, 15, 17, 0.32) 30%,
      rgba(14, 15, 17, 0.23) 45%,
      rgba(14, 15, 17, 0.14) 60%,
      rgba(14, 15, 17, 0.06) 75%,
      rgba(14, 15, 17, 0.01) 90%,
      rgba(14, 15, 17, 0) 100%
    );
  }
  /* Toast is at the top on mobile — bottom-left vignette not needed */
  #tw-vignette-toast { display: none; }

  /* With the mobile pill blur and menu transform removed, fixed dropdowns
     use the viewport. The menu bar's z-index keeps them above the map pill.
     Cap the card width as mobile begins; shrink within 20px edge gutters.
     Bottom: 18px base + 70px pill + 16px gap = 104px. */
  .tw-dropdown {
    position: fixed !important;
    box-sizing: border-box;
    left: 50% !important;
    right: auto !important;
    bottom: calc(104px + env(safe-area-inset-bottom)) !important;
    top: auto !important;
    max-width: calc(100vw - 40px) !important;
    min-width: 0 !important;
    width: min(360px, calc(100vw - 40px)) !important;
    z-index: 200 !important;
    transform: translate(-50%, 12px) !important;
    max-height: 46vh !important;
    max-height: 46dvh !important;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: 20px;
  }
  .tw-dropdown.tw-open {
    transform: translate(-50%, 0) !important;
  }
  .tw-dropdown-item { padding: 16px 20px 16px 32px; font-size: 16px; }
  .tw-dropdown-item::before { left: 12px; }
  .tw-dropdown-item-soon { padding: 16px 20px; }
}

/* Compact layout for very short screens (iPhone landscape, small phones) */
@media (max-height: 680px) {
  .tw-splash-wordmark-img { width: clamp(200px, 30vw, 300px); margin-bottom: 16px; }
  .tw-splash-rule  { margin: 18px auto; }
  .tw-splash-enter { margin-top: 24px; font-size: 15px; min-height: 54px; padding: 16px 36px; }
  /* Tighten menu bar on short landscape screens but keep text readable */
  #tw-menu-bar     { bottom: calc(10px + env(safe-area-inset-bottom)); }
  .tw-menu-pill    { height: 58px; }
  .tw-menu-btn     { height: 46px; font-size: 14px; }
  /* Reduce top vignette height in landscape so toast doesn't overlap panorama too much */
  #tw-vignette-top { height: 180px; }
}

/* ── HIDE NATIVE 3DVISTA LOAD BAR & PRELOADER ───────────────────────────── */
#viewer div[style*="height: 3px"][style*="z-index: 2"] { visibility: hidden !important; }
#preloadContainer { display: none !important; }

/* ── BRANDED LOAD INDICATOR ─────────────────────────────────────────────── */

#tw-loader {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 200;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s var(--tw-ease);
}

#tw-loader.tw-loader-active { opacity: 1; }
#tw-loader.tw-loader-done   { opacity: 0; transition: opacity 0.3s var(--tw-ease) 0.15s; }

.tw-loader-fill {
  width: 100%;
  height: 100%;
  transform-origin: left center;
  transform: scaleX(0);
  background: linear-gradient(90deg, rgba(148,129,117,0), var(--tw-gold) 30%, var(--tw-cream) 70%, rgba(244,237,229,0));
  box-shadow: 0 0 12px rgba(138, 66, 98, 0.5);
}

/* ── FULLSCREEN MAP MODAL ────────────────────────────────────────────────── */

#tw-map-modal {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 1;
  transition: opacity 0.2s var(--tw-ease);
}

#tw-map-modal.tw-map-modal-hidden {
  opacity: 0;
  pointer-events: none;
}

.tw-map-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(23, 24, 27, 0.72);
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  cursor: pointer;
}

.tw-map-modal-card {
  position: relative;
  width: 92vw;
  height: 88vh;
  max-width: 2100px;
  background: rgba(23, 24, 27, 0.95);
  border: 1px solid rgba(138, 66, 98, 0.2);
  border-radius: 24px;
  box-shadow: 0 30px 120px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(138, 66, 98, 0.06) inset;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transform: scale(1);
  transition: transform 0.2s var(--tw-ease);
}

#tw-map-modal.tw-map-modal-hidden .tw-map-modal-card {
  transform: scale(0.96);
}

.tw-map-modal-topbar {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 21px 27px;
  border-bottom: 1px solid rgba(138, 66, 98, 0.12);
  background: rgba(23, 24, 27, 0.4);
}

.tw-map-modal-title {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--tw-sans);
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(244, 237, 229, 0.55);
  flex-shrink: 0;
}

.tw-map-modal-title .tw-map-header-icon { color: var(--tw-accent-text); }

.tw-map-filter {
  display: flex;
  gap: 3px;
  padding: 4.5px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(138, 66, 98, 0.1);
  border-radius: 15px;
  flex: 1;
  max-width: 630px;
  overflow-x: auto;
}

.tw-map-filter-btn {
  flex: 1;
  padding: 9px 21px;
  background: transparent;
  border: none;
  border-radius: 10.5px;
  font-family: var(--tw-sans);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(244, 237, 229, 0.5);
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.18s, color 0.18s;
  white-space: nowrap;
}

.tw-map-filter-btn:hover { color: rgba(244, 237, 229, 0.85); }
.tw-map-filter-btn.tw-active {
  background: rgba(138, 66, 98, 0.16);
  color: var(--tw-accent-text);
}

.tw-map-modal-close {
  width: 54px;
  height: 54px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid rgba(138, 66, 98, 0.30);
  border-radius: 15px;
  cursor: pointer;
  color: var(--tw-accent-text);
  transition: background 0.18s, color 0.18s, border-color 0.18s;
  flex-shrink: 0;
  margin-left: auto;
  -webkit-tap-highlight-color: transparent;
}

.tw-map-modal-close:hover {
  color: var(--tw-cream);
  background: rgba(138, 66, 98, 0.12);
  border-color: rgba(138, 66, 98, 0.55);
}

.tw-map-modal-body {
  position: relative;
  flex: 1;
  min-height: 0;
}

#tw-map-modal-canvas {
  position: absolute;
  inset: 0;
  background: #17181b;
}

#tw-map-modal-canvas .mapboxgl-ctrl-logo { opacity: 0.35; }
#tw-map-modal-canvas .mapboxgl-ctrl-attrib { font-size: 13.5px; opacity: 0.35; }

/* Modal map zoom controls — same branded dark glass as preview map */
#tw-map-modal-canvas .mapboxgl-ctrl-top-right > .mapboxgl-ctrl {
  margin: 8px 8px 0 0 !important;
}
#tw-map-modal-canvas .mapboxgl-ctrl-group {
  background: rgba(23, 24, 27, 0.88) !important;
  border: 1px solid rgba(138, 66, 98, 0.28) !important;
  border-radius: 10px !important;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45) !important;
  overflow: hidden;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
#tw-map-modal-canvas .mapboxgl-ctrl-group button {
  width: 34px !important;
  height: 34px !important;
  background: transparent !important;
  border: none !important;
  border-bottom: 1px solid rgba(138, 66, 98, 0.18) !important;
}
#tw-map-modal-canvas .mapboxgl-ctrl-group button:last-child {
  border-bottom: none !important;
}
#tw-map-modal-canvas .mapboxgl-ctrl-group button:hover {
  background: rgba(138, 66, 98, 0.14) !important;
}
#tw-map-modal-canvas .mapboxgl-ctrl-zoom-in .mapboxgl-ctrl-icon {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'%3E%3Cpath d='M9 3v12M3 9h12' stroke='%23F4EDE5' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") !important;
}
#tw-map-modal-canvas .mapboxgl-ctrl-zoom-out .mapboxgl-ctrl-icon {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'%3E%3Cpath d='M3 9h12' stroke='%23F4EDE5' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") !important;
}

.tw-map-layer-toggle {
  position: absolute;
  bottom: 27px;
  left: 27px;
  z-index: 5;
  display: flex;
  gap: 3px;
  padding: 4.5px;
  background: rgba(23, 24, 27, 0.88);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid rgba(138, 66, 98, 0.18);
  border-radius: 15px;
  box-shadow: 0 9px 36px rgba(0, 0, 0, 0.55);
}

.tw-map-layer-btn {
  padding: 9px 18px;
  background: transparent;
  border: none;
  border-radius: 10.5px;
  font-family: var(--tw-sans);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(244, 237, 229, 0.55);
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.18s, color 0.18s;
}

.tw-map-layer-btn:hover        { color: rgba(244, 237, 229, 0.85); }
.tw-map-layer-btn.tw-active    { background: rgba(138, 66, 98, 0.55); color: var(--tw-accent-text); }

.tw-map-loading {
  position: absolute;
  top: 27px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  padding: 12px 24px;
  background: rgba(23, 24, 27, 0.9);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(138, 66, 98, 0.2);
  border-radius: 1498.5px;
  font-family: var(--tw-sans);
  font-size: 15px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(244, 237, 229, 0.7);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s var(--tw-ease);
}

.tw-map-loading.tw-show { opacity: 1; }

/* ── POI MARKERS + POPUP ─────────────────────────────────────────────────── */

.tw-map-poi-chip {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: rgba(23, 24, 27, 0.92);
  border: 1.5px solid rgba(138, 66, 98, 0.5);
  border-radius: 50%;
  color: var(--tw-cream);
  cursor: pointer;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45), 0 0 0 1.5px rgba(255, 255, 255, 0.10);
  transition: transform 0.15s var(--tw-ease), border-color 0.18s, color 0.18s, background 0.18s;
}

.tw-map-poi-chip:hover {
  transform: scale(1.18);
  border-color: var(--tw-gold);
  background: rgba(23, 24, 27, 0.98);
  color: var(--tw-accent-text);
}

.tw-map-pin-large {
  width: 22px !important;
  height: 22px !important;
  border-radius: 50%;
  background: var(--tw-gold);
  border: 3px solid white !important;
  box-shadow: 0 0 0 6px rgba(138, 66, 98, 0.5), 0 0 0 12px rgba(138, 66, 98, 0.18), 0 4px 18px rgba(0, 0, 0, 0.45);
  animation: tw-pin-pulse 2.2s ease-in-out infinite;
  cursor: default;
}

/* Aerial (drone) pin — gold-filled square with drone icon + numeric badge */
.tw-map-aerial-pin {
  position: relative;
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: var(--tw-gold);
  border: 1.5px solid rgba(23, 24, 27, 0.9);
  border-radius: 12px;
  color: var(--tw-cream);
  cursor: pointer;
  box-shadow: 0 6px 21px rgba(0, 0, 0, 0.7), 0 0 0 4.5px rgba(138, 66, 98, 0.18);
  transition: transform 0.18s var(--tw-ease), box-shadow 0.18s;
}

.tw-map-aerial-pin:hover {
  transform: scale(1.12);
  box-shadow: 0 9px 27px rgba(0, 0, 0, 0.75), 0 0 0 7.5px rgba(138, 66, 98, 0.32);
}

.tw-map-aerial-num {
  position: absolute;
  top: -9px;
  right: -9px;
  min-width: 24px;
  height: 24px;
  padding: 0 6px;
  font: 700 15px/24px var(--tw-sans);
  color: var(--tw-accent-text);
  background: rgba(23, 24, 27, 0.96);
  border: 1px solid var(--tw-gold);
  border-radius: 15px;
  text-align: center;
  box-sizing: border-box;
}

@keyframes tw-pin-pulse {
  0%, 100% { box-shadow: 0 0 0 9px rgba(138, 66, 98, 0.28), 0 6px 24px rgba(0, 0, 0, 0.65); }
  50%      { box-shadow: 0 0 0 21px rgba(138, 66, 98, 0.05), 0 6px 24px rgba(0, 0, 0, 0.65); }
}

.tw-map-popup-wrap .mapboxgl-popup-content {
  background: rgba(23, 24, 27, 0.96);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  border: 1px solid rgba(138, 66, 98, 0.25);
  border-radius: 15px;
  padding: 15px 21px;
  box-shadow: 0 15px 60px rgba(0, 0, 0, 0.6);
  color: var(--tw-cream);
}

.tw-map-popup-wrap .mapboxgl-popup-tip { display: none; }

.tw-map-poi-popup .tw-map-poi-cat {
  font-family: var(--tw-sans);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--tw-accent-text);
}

.tw-map-poi-popup .tw-map-poi-name {
  font-family: var(--tw-serif);
  font-size: 24px;
  font-weight: 400;
  color: var(--tw-cream);
  margin-top: 3px;
  line-height: 1.25;
  max-width: 330px;
}

.tw-map-poi-popup .tw-map-poi-dist {
  font-family: var(--tw-sans);
  font-size: 15px;
  color: rgba(244, 237, 229, 0.55);
  margin-top: 6px;
}

/* Prevent body scroll while modal is open */
body.tw-modal-open { overflow: hidden; }

/* ── RESPONSIVE — MODAL ──────────────────────────────────────────────────── */

@media (max-width: 768px) {
  /* Map modal — full bleed */
  .tw-map-modal-card {
    width: 100vw;
    height: 100dvh;
    max-width: none;
    border-radius: 0;
  }
  .tw-map-modal-topbar {
    flex-wrap: wrap;
    gap: 12px;
    padding: calc(12px + env(safe-area-inset-top)) 16px 12px;
  }
  .tw-map-modal-title { order: 1; flex: 1; font-size: 12px; gap: 8px; min-width: 0; }
  .tw-map-modal-title span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .tw-map-modal-close { order: 2; width: 44px; height: 44px; }
  .tw-map-filter { order: 3; flex-basis: 100%; max-width: none; }
  .tw-map-filter-btn { padding: 9px 14px; font-size: 12.5px; }
  .tw-map-layer-toggle { bottom: calc(18px + env(safe-area-inset-bottom)); left: 18px; padding: 4px; }
  .tw-map-layer-btn { padding: 8px 14px; font-size: 12.5px; }
  .tw-map-popup-wrap .mapboxgl-popup-content { max-width: calc(100vw - 60px); }
  .tw-map-poi-popup .tw-map-poi-name { font-size: 19px; max-width: 240px; }

}

/* ── PANO-ANCHORED HOTSPOT OVERLAY ───────────────────────────────────────── */

#tw-hotspot-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 120;
  overflow: hidden;
}

.tw-hotspot-pin {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  pointer-events: auto;
  cursor: default;
  opacity: 0;
  transition: opacity 0.18s var(--tw-ease);
  user-select: none;
  transform: translate(-14998.5px, -14998.5px);
}

.tw-hotspot-dot {
  width: 21px;
  height: 21px;
  border-radius: 50%;
  background: var(--tw-gold);
  border: 2px solid rgba(23, 24, 27, 0.92);
  box-shadow: 0 0 0 6px rgba(138, 66, 98, 0.22),
    0 6px 18px rgba(0, 0, 0, 0.55);
  animation: tw-hotspot-pulse 2.6s ease-in-out infinite;
}

@keyframes tw-hotspot-pulse {
  0%, 100% { box-shadow: 0 0 0 6px rgba(138, 66, 98, 0.22), 0 6px 18px rgba(0, 0, 0, 0.55); }
  50%      { box-shadow: 0 0 0 12px rgba(138, 66, 98, 0.05), 0 6px 18px rgba(0, 0, 0, 0.55); }
}

.tw-hotspot-label {
  font-family: var(--tw-sans);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--tw-cream, #f4ece0);
  background: rgba(23, 24, 27, 0.78);
  border: 1px solid rgba(138, 66, 98, 0.32);
  padding: 6px 12px;
  border-radius: 6px;
  white-space: nowrap;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 6px 21px rgba(0, 0, 0, 0.45);
}

/* ── REDUCED MOTION ──────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .tw-splash-wordmark-img,
  .tw-splash-sub,
  .tw-splash-rule,
  .tw-splash-location,
  .tw-splash-enter {
    animation: none;
    opacity: 1;
    transform: none;
  }
  .tw-ui-el,
  #tw-toast,
  .tw-dropdown,
  .tw-splash-enter,
  .tw-menu-chevron,
  #tw-loader,
  .tw-loader-fill,
  #tw-map-modal,
  .tw-map-modal-card,
  .tw-map-poi-chip,
  .tw-map-pin-large,
  .tw-map-aerial-pin,
  .tw-hotspot-pin,
  .tw-hotspot-dot { transition: none; animation: none; }
  .tw-loader-fill { transform: scaleX(1); }
}

/* ── ONBOARDING HINT ─────────────────────────────────────────────────────── */
/* Shown once per device after Explore Now (see maybeShowHintAutomatically()
   in the JS), teaching first-time visitors the pano is draggable. Both the
   overlay and card are pointer-events:none throughout — this is a pure
   visual layer that never intercepts a drag gesture aimed at the pano
   underneath (see showHint()'s dismiss listener for why). Only
   .tw-hint-link (the embedded-only "open in a new tab" line) re-enables
   pointer-events on itself, since it's the one genuinely clickable thing
   here.

   DELIBERATELY brand-neutral (Danny 2026-08-06: "I want this to feel like
   it works on any tour, no matter the colours, fonts, etc... like the
   animated hotspot designs we made") — every color/font here comes from
   the --hint-* tokens in :root, never from --sr-*. White frosted glass
   (0.58 alpha + heavy blur) rather than a cool-blue glass treatment.
   the UI uses, specifically so this reads as universal tour CHROME (how
   the interface works) rather than this property's BRAND (which the rest
   of the floating UI already carries). Same reasoning the native 3DVista
   hotspot icons stay white/neutral regardless of client palette. */
#tw-hint-overlay {
  position: fixed;
  inset: 0;
  z-index: 250;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s var(--tw-ease);
}

#tw-hint-overlay.tw-show { opacity: 1; }

.tw-hint-card {
  pointer-events: none;
  position: relative; /* anchors .tw-hint-close */
  max-width: 320px;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 26px 24px 18px;
  border-radius: 22px;
  background: var(--hint-bg);
  backdrop-filter: blur(32px) saturate(180%);
  -webkit-backdrop-filter: blur(32px) saturate(180%);
  border: 1px solid var(--hint-border);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.28), 0 1px 0 rgba(255, 255, 255, 0.6) inset;
  transform: scale(0.96) translateY(6px);
  transition: transform 0.45s var(--tw-ease);
}

#tw-hint-overlay.tw-show .tw-hint-card {
  transform: scale(1) translateY(0);
}

/* Explicit dismiss. `pointer-events: auto` is required — the overlay and card
   are both pointer-events:none so a drag aimed at the pano passes straight
   through, and each genuinely clickable child has to opt back in (same as
   .tw-hint-link). Deliberately quiet: it should read as a way out, not compete
   with the instruction the card is there to deliver. */
.tw-hint-close {
  pointer-events: auto;
  position: absolute;
  top: 10px;
  right: 10px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--hint-ink);
  opacity: 0.4;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 0.18s, background 0.18s;
}

.tw-hint-close:hover { opacity: 0.85; background: rgba(0, 0, 0, 0.06); }
.tw-hint-close:focus-visible { opacity: 0.85; outline: 2px solid var(--hint-ink); outline-offset: 2px; }

.tw-hint-icon-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  height: 34px;
  margin-bottom: 12px;
  color: var(--hint-ink);
}

.tw-hint-chevron {
  display: flex;
  opacity: 0.3;
}

.tw-hint-pointer {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  animation: tw-hint-drag 2.4s ease-in-out infinite;
}

/* Touch variant — HINT_HTML leaves this span genuinely empty (no cursor
   SVG) when IS_TOUCH, so a plain filled dot stands in for a fingertip. */
.tw-hint-pointer:empty {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 6px rgba(22, 22, 26, 0.08);
}

@keyframes tw-hint-drag {
  0%   { transform: translateX(-16px); opacity: 0.5; }
  50%  { transform: translateX(16px);  opacity: 1; }
  100% { transform: translateX(-16px); opacity: 0.5; }
}

.tw-hint-title {
  font-family: var(--hint-sans);
  font-size: 16px;
  font-weight: 600;
  color: var(--hint-ink);
  letter-spacing: 0.002em;
}

.tw-hint-sub {
  font-family: var(--hint-sans);
  font-size: 12.5px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--hint-ink-soft);
  margin-top: 8px;
  max-width: 26ch;
}

.tw-hint-sub b { font-weight: 600; color: var(--hint-ink); }

.tw-hint-footer {
  margin-top: 16px;
  padding-top: 13px;
  width: 100%;
  border-top: 1px solid rgba(22, 22, 26, 0.12);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tw-hint-disclaimer {
  font-family: var(--hint-sans);
  font-size: 10.5px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--hint-ink-faint);
}

.tw-hint-link {
  pointer-events: auto;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  font-family: var(--hint-sans);
  font-size: 10.5px;
  font-weight: 400;
  color: var(--hint-ink-faint);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

.tw-hint-link span {
  color: var(--hint-ink);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.tw-hint-link:hover span,
.tw-hint-link:focus-visible span { color: var(--hint-ink); opacity: 0.7; }
.tw-hint-link:focus-visible { outline: 2px solid var(--hint-ink); outline-offset: 2px; border-radius: 4px; }

@media (max-width: 768px) {
  .tw-hint-card { padding: 22px 20px 16px; border-radius: 18px; }
  .tw-hint-title { font-size: 15px; }
  .tw-hint-sub { font-size: 12px; }
  .tw-hint-footer { margin-top: 14px; padding-top: 11px; }
  .tw-hint-disclaimer,
  .tw-hint-link { font-size: 10px; }
}


/* ── RE-OPEN ONBOARDING HINT ─────────────────────────────────────────────── */
/* Bottom-RIGHT corner, with the Location pill sitting inboard of it. Viewer
   help stays separate from branded controls. */
#tw-hint-trigger {
  position: fixed;
  /* A small, independent corner affordance keeps this viewer help separate
     from the property controls. */
  bottom: 14px;
  right: 16px;
  left: auto;
  z-index: 100;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--hint-bg);
  backdrop-filter: blur(32px) saturate(180%);
  -webkit-backdrop-filter: blur(32px) saturate(180%);
  border: 1px solid var(--hint-border);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.3), 0 1px 0 rgba(255, 255, 255, 0.6) inset;
  color: var(--hint-ink);
  opacity: 0.82;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 0.55s var(--tw-ease), background 0.18s, transform 0.15s var(--tw-ease);
  transition-delay: 0.3s, 0s, 0s;
}

#tw-hint-trigger svg { width: 13px; height: 13px; }

#tw-hint-trigger:hover { opacity: 1; transform: scale(1.06); }
#tw-hint-trigger:focus-visible { opacity: 1; outline: 2px solid var(--hint-ink); outline-offset: 2px; }

/* Hover label sits to the LEFT of the button, which now leaves it sitting
   neatly underneath the Location pill rather than colliding with it — the
   collision was only a problem back when the two shared a row. Vertically
   centred on the button. Pointer-events off so it can never swallow a click
   meant for the button. */
#tw-hint-trigger::after {
  content: 'How to use';
  position: absolute;
  right: calc(100% + 9px);
  top: 50%;
  transform: translateY(-50%) translateX(4px);
  padding: 7px 12px;
  border-radius: 999px;
  background: var(--hint-bg);
  backdrop-filter: blur(32px) saturate(180%);
  -webkit-backdrop-filter: blur(32px) saturate(180%);
  border: 1px solid var(--hint-border);
  box-shadow: 0 8px 26px rgba(0, 0, 0, 0.26);
  color: var(--hint-ink);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s var(--tw-ease), transform 0.18s var(--tw-ease);
}

#tw-hint-trigger:hover::after,
#tw-hint-trigger:focus-visible::after {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

/* Touch devices have no hover state, so the label would either never appear
   or stick after a tap. The icon alone carries it there. */
@media (hover: none) {
  #tw-hint-trigger::after { display: none; }
}


/* ── Help button: responsive positions (same as Sorelle) ─────────────────── */
/* (no tablet override: the help button keeps its normal 26px corner position at every width above phone size) */
@media (max-width: 768px) {
  #tw-hint-trigger { bottom: calc(10px + env(safe-area-inset-bottom)); right: 10px; left: auto; width: 32px; height: 32px; z-index: 170; }
  #tw-hint-trigger svg { width: 15px; height: 15px; }
}
@media (prefers-reduced-motion: reduce) {
  .tw-hint-pointer { animation: none; }
}
