/* FILE: clsu-virtual-tour/assets/css/style.css — Sprint 2 */

/* ═══════════════════════════════════════════════════════════════════════════
   CLSU Virtual Tour · Main Stylesheet
   Brand: Dark Green #1a5c2a  ·  Gold #f5c400  ·  White #ffffff
   Font : Inter 400/500/600/700 via Google Fonts
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1. CSS Variables ───────────────────────────────────────────────────── */
:root {
  /* Palette */
  --green:        #1a5c2a;
  --green-dk:     #134520;
  --green-md:     #1e6b31;
  --green-lt:     #2d8a47;
  --green-xl:     #3aa058;
  --green-pale:   rgba(26,92,42,0.07);
  --green-pale2:  rgba(26,92,42,0.14);
  --gold:         #f5c400;
  --gold-dk:      #d4a900;
  --gold-lt:      #ffd740;
  --gold-pale:    rgba(245,196,0,0.13);
  --white:        #ffffff;
  /* Card / panel surface. Split out from --white because --white is also
     the text colour on green buttons and the navbar — dark mode must flip
     the surface without inverting that text. */
  /* Brand greens that must NOT shift between themes: the hero gradient,
     solid green buttons and banners. --green* stays free to lift in dark
     mode for link/heading contrast without brightening those surfaces. */
  --brand-dk:     #134520;
  --brand:        #1a5c2a;
  --brand-md:     #1e6b31;
  --brand-lt:     #2d8a47;
  --brand-xl:     #3aa058;
  /* Text on gold surfaces uses --brand-dk, never --green-dk: gold does not
     change between themes, so lifting the green for dark backgrounds would put
     bright green on yellow. */
  --surface:      #ffffff;
  --surface-alt:  #fbfdfb;
  --dark:         #0f1a14;
  --text:         #1c1c1c;
  --text-muted:   #64748b;
  --text-light:   rgba(255,255,255,0.72);
  --bg:           #f6f9f6;
  --bg-alt:       #eef3ee;
  --border:       #dde6dd;
  --border-lt:    rgba(255,255,255,0.14);

  /* Badge / type accent colors */
  --c-academic:       #1a5c2a;
  --c-administrative: #1565c0;
  --c-facility:       #6a1c9a;
  --c-landmark:       #b45309;
  --c-entrance:       #b91c1c;
  --c-dorm:           #0f766e;

  /* Typography */
  --font: 'Inter', system-ui, -apple-system, sans-serif;

  /* Spacing */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px;
  --sp-6:24px; --sp-8:32px; --sp-10:40px; --sp-12:48px; --sp-16:64px;
  --sp-20:80px; --sp-24:96px;

  /* Shadows */
  --sh-xs: 0 1px 3px rgba(0,0,0,0.05);
  --sh-sm: 0 2px 8px rgba(0,0,0,0.07);
  --sh:    0 4px 16px rgba(0,0,0,0.09);
  --sh-md: 0 8px 28px rgba(0,0,0,0.11);
  --sh-lg: 0 16px 48px rgba(0,0,0,0.14);
  --sh-green: 0 4px 20px rgba(26,92,42,0.30);
  --sh-gold:  0 4px 20px rgba(245,196,0,0.40);

  /* Border radius */
  --r-xs:4px; --r-sm:6px; --r:10px; --r-md:14px;
  --r-lg:20px; --r-xl:28px; --r-full:9999px;

  /* Transitions */
  --tf:  0.14s ease;
  --t:   0.22s ease;
  --ts:  0.38s ease;

  /* Layout */
  --nav-h: 70px;
  --max-w: 1200px;
}

/* ── 2. Reset ───────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  padding-top: var(--nav-h);           /* offset for fixed navbar */
}
img, svg { display: block; max-width: 100%; }
a { color: var(--green); text-decoration: none; }
ul, ol { list-style: none; }
button { cursor: pointer; font-family: var(--font); border: none; background: none; }
input, textarea, select { font-family: var(--font); }

/* ── 3. Layout ──────────────────────────────────────────────────────────── */
.container {
  width: 100%;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 var(--sp-6);
}

.section          { padding: var(--sp-20) 0; }
.section--sm      { padding: var(--sp-12) 0; }
.section--alt     { background: var(--bg); }
.section--dark    { background: var(--brand-dk); }

/* ── 4. Typography ──────────────────────────────────────────────────────── */
.section-eyebrow {
  display: inline-block;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--green);
  margin-bottom: var(--sp-3);
}
.section-eyebrow--white { color: rgba(255,255,255,0.65); }

.section-title {
  font-size: clamp(1.6rem, 3vw, 2.4rem);
  font-weight: 700;
  color: var(--text);
  line-height: 1.2;
  letter-spacing: -0.4px;
  margin-bottom: var(--sp-4);
}
.section-title--white { color: var(--white); }

.section-desc {
  font-size: 1.0625rem;
  color: var(--text-muted);
  max-width: 580px;
  line-height: 1.75;
}
.section-desc--white { color: var(--text-light); max-width: 560px; }

.section-header        { margin-bottom: var(--sp-10); }
.section-header.center { text-align: center; }
.section-header.center .section-desc { margin: 0 auto; }

/* ── 5. Navbar ──────────────────────────────────────────────────────────── */
.navbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 1000;
  height: var(--nav-h);
  background: var(--brand);
  box-shadow: 0 2px 12px rgba(0,0,0,0.18);
  transition: background var(--ts), box-shadow var(--ts);
}

/* Transparent variant — used on hero page */
.navbar--hero {
  background: rgba(0,0,0,0);
  box-shadow: none;
}
.navbar--hero.scrolled {
  background: var(--brand);
  box-shadow: 0 2px 20px rgba(0,0,0,0.25);
}
/* Non-hero pages get a subtle scroll enhancement too */
.navbar.scrolled {
  box-shadow: 0 2px 24px rgba(0,0,0,0.22);
}

.nav-inner {
  max-width: 100%;
  margin: 0 auto;
  padding: 0 var(--sp-8);
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
}

/* Brand */
.nav-brand {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-shrink: 0;
  text-decoration: none;
}
.nav-logo {
  width: 60px; height: 60px;
  object-fit: contain;
  flex-shrink: 0;
  display: block;
}
.nav-brand-name    { display: flex; flex-direction: column; line-height: 1.2; }
.nav-brand-top     { font-size: 11px; font-weight: 600; color: rgba(255,255,255,0.72); letter-spacing: 0.4px; text-transform: uppercase; white-space: nowrap; }
.nav-brand-sub     { font-size: 17px; font-weight: 700; color: var(--white); letter-spacing: 0.2px; line-height: 1.1; }

/* Links */
.nav-menu {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
}
.nav-link {
  display: block;
  padding: 8px 13px;
  font-size: 14px;
  font-weight: 500;
  color: rgba(255,255,255,0.85);
  border-radius: var(--r-xs);
  transition: color var(--t), background var(--t);
}
.nav-link:hover,
.nav-link.active {
  color: var(--white);
  background: rgba(255,255,255,0.13);
}
.nav-link.active { font-weight: 600; }

.nav-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  height: 36px; padding: 0 20px; box-sizing: border-box;
  background: var(--gold);
  color: var(--brand-dk);
  font-size: 13.5px;
  font-weight: 600;
  border-radius: var(--r-sm);
  margin-left: var(--sp-2);
  transition: background var(--t), transform var(--t), box-shadow var(--t);
}
.nav-cta:hover {
  background: var(--gold-dk);
  color: var(--brand-dk);
  transform: translateY(-1px);
  box-shadow: var(--sh-gold);
}

/* Hamburger */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 38px; height: 38px;
  padding: 5px;
  border-radius: var(--r-sm);
  background: rgba(255,255,255,0.12);
  transition: background var(--t);
}
.nav-toggle:hover { background: rgba(255,255,255,0.20); }
.nav-toggle-bar {
  display: block;
  height: 2px;
  background: var(--surface);
  border-radius: 2px;
  transition: transform var(--t), opacity var(--t);
}

/* ── 6. Buttons ─────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 13px 28px;
  font-size: 15px;
  font-weight: 600;
  border-radius: var(--r-sm);
  border: 2px solid transparent;
  line-height: 1;
  transition: background var(--t), color var(--t), border-color var(--t),
              transform var(--t), box-shadow var(--t);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--sm  { padding: 9px 18px; font-size: 13px; }
.btn--lg  { padding: 16px 36px; font-size: 16px; }
.btn--full{ width: 100%; justify-content: center; }

.btn--gold {
  background: var(--gold);
  color: var(--brand-dk);
  border-color: var(--gold);
  box-shadow: var(--sh-gold);
}
.btn--gold:hover { background: var(--gold-dk); border-color: var(--gold-dk); color: var(--brand-dk); }

.btn--green {
  background: var(--brand);
  color: var(--white);
  border-color: var(--green);
  box-shadow: var(--sh-green);
}
.btn--green:hover { background: var(--brand-md); border-color: var(--green-md); color: var(--white); }

.btn--outline-white {
  background: transparent;
  color: var(--white);
  border-color: rgba(255,255,255,0.55);
}
.btn--outline-white:hover {
  background: rgba(255,255,255,0.12);
  border-color: var(--white);
  color: var(--white);
}

.btn--outline-green {
  background: transparent;
  color: var(--green);
  border-color: var(--green);
}
.btn--outline-green:hover { background: var(--green-pale); color: var(--green-dk); }

/* ── 7. Badges ──────────────────────────────────────────────────────────── */
.badge {
  display: inline-block;
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 600;
  border-radius: var(--r-full);
  letter-spacing: 0.4px;
  text-transform: capitalize;
}
.badge--academic       { background: rgba(26,92,42,0.10);   color: var(--c-academic); }
.badge--administrative { background: rgba(21,101,192,0.10); color: var(--c-administrative); }
.badge--facility       { background: rgba(106,28,154,0.10); color: var(--c-facility); }
.badge--landmark       { background: rgba(180,83,9,0.10);   color: var(--c-landmark); }
.badge--entrance       { background: rgba(185,28,28,0.10);  color: var(--c-entrance); }
.badge--dorm           { background: rgba(15,118,110,0.10); color: var(--c-dorm); }

/* ── 8. Hero Section ────────────────────────────────────────────────────── */
.hero {
  position: relative;
  /* The negative margin below cancels body's nav-height padding, so the hero
     starts at the very top of the viewport — which makes a full 100vh the
     height that ends it exactly at the fold. Subtracting --nav-h here (the
     obvious-looking value) left a strip of the next section peeking under it. */
  min-height: 100vh;
  min-height: 100dvh;
  margin-top: calc(-1 * var(--nav-h));   /* pull behind fixed nav on hero page */
  padding-top: calc(var(--nav-h) + var(--sp-20));
  padding-bottom: var(--sp-20);
  display: flex;
  align-items: center;
  background: linear-gradient(140deg, var(--brand-dk) 0%, var(--brand) 55%, var(--brand-lt) 100%);
  overflow: hidden;
}

/* Dot-grid pattern overlay */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(255,255,255,0.07) 1px, transparent 1px);
  background-size: 28px 28px;
  pointer-events: none;
}

/* Glow orbs */
.hero::after {
  content: '';
  position: absolute;
  top: -160px; right: -160px;
  width: 560px; height: 560px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(245,196,0,0.09), transparent 70%);
  pointer-events: none;
}

.hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 var(--sp-6);
  display: grid;
  grid-template-columns: 1fr 500px;
  align-items: center;
  gap: var(--sp-16);
}

.hero__text {
  position: relative;
  z-index: 1;
}

/* Decorative gold statue watermark, anchored to the hero's bottom-left corner so
   it always sits flush with the bottom edge regardless of content centering. */
.hero__statue {
  position: absolute;
  left: -40px;
  bottom: 0;
  height: clamp(460px, 74vh, 780px);
  aspect-ratio: 1725 / 2475;
  background: url('../images/hero-statue-gold.png') left bottom / contain no-repeat;
  opacity: 0.9;
  filter: saturate(1.3) contrast(1.05) drop-shadow(0 8px 40px rgba(245,196,0,0.22));
  z-index: 0;
  pointer-events: none;
}
@media (max-width: 1024px) {
  .hero__statue { opacity: 0.7; left: -80px; }
}
@media (max-width: 768px) {
  .hero__statue { height: 420px; left: -120px; opacity: 0.55; }
}

.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 5px 14px;
  background: rgba(245,196,0,0.14);
  border: 1px solid rgba(245,196,0,0.30);
  border-radius: var(--r-full);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: var(--sp-5);
}

.hero__title {
  font-size: clamp(2rem, 5vw, 3.6rem);
  font-weight: 700;
  color: var(--white);
  line-height: 1.13;
  letter-spacing: -1px;
  margin-bottom: var(--sp-5);
}
.hero__title em { font-style: normal; color: var(--gold); }

.hero__desc {
  font-size: 1.125rem;
  color: rgba(255,255,255,0.78);
  line-height: 1.75;
  max-width: 520px;
  margin-bottom: var(--sp-8);
}

.hero__actions { display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap; }

.hero__stats {
  display: flex;
  gap: var(--sp-6);
  margin-top: var(--sp-10);
  padding-top: var(--sp-8);
  border-top: 1px solid rgba(255,255,255,0.12);
}
.hero__stat-val {
  font-size: 1.75rem;
  font-weight: 700;
  color: var(--gold);
  line-height: 1;
}
.hero__stat-label {
  font-size: 12px;
  color: rgba(255,255,255,0.58);
  margin-top: 4px;
}

/* Hero visual card (right column) */
.hero__visual {
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.15);
  border-radius: var(--r-xl);
  padding: var(--sp-6);
  backdrop-filter: blur(8px);
  box-shadow: 0 28px 70px rgba(0,0,0,0.32);
}
.hero__visual-thumb {
  position: relative;
  height: 320px;
  border-radius: var(--r-lg);
  background: linear-gradient(135deg, rgba(255,255,255,0.08), rgba(255,255,255,0.02));
  border: 1px solid rgba(255,255,255,0.10);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--sp-5);
  overflow: hidden;
  text-decoration: none;
  box-shadow: 0 10px 30px rgba(0,0,0,0.25);
}
.hero__visual-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 400ms ease;
}
.hero__visual-thumb:hover .hero__visual-img { transform: scale(1.05); }
/* Live, self-rotating 360° preview embedded in the hero thumb */
.hero__visual-thumb--live { cursor: grab; }
.hero__visual-thumb--live:active { cursor: grabbing; }
.hero__visual-pano { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero__visual-thumb--live .hero__visual-badge { z-index: 5; text-decoration: none; }
.hero__visual-badge {
  position: absolute;
  left: 14px;
  bottom: 14px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 15px;
  border-radius: 100px;
  background: rgba(26,92,42,0.90);
  border: 1px solid rgba(255,255,255,0.20);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  backdrop-filter: blur(4px);
}
.hero__visual-icon {
  width: 72px; height: 72px;
  border-radius: 50%;
  background: rgba(245,196,0,0.18);
  border: 2px solid rgba(245,196,0,0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--gold);
}
.hero__visual-meta { display: flex; flex-direction: column; gap: var(--sp-3); }
.hero__visual-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 14px var(--sp-4);
  background: rgba(255,255,255,0.06);
  border-radius: var(--r);
  border: 1px solid rgba(255,255,255,0.08);
  text-decoration: none;
  transition: background 150ms ease, border-color 150ms ease, transform 150ms ease;
}
a.hero__visual-row:hover {
  background: rgba(255,255,255,0.12);
  border-color: rgba(245,196,0,0.40);
  transform: translateX(2px);
}
.hero__visual-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.hero__visual-text { font-size: 14px; color: rgba(255,255,255,0.80); font-weight: 500; }
.hero__visual-arrow {
  margin-left: auto;
  flex-shrink: 0;
  color: rgba(255,255,255,0.40);
  transition: color 150ms ease, transform 150ms ease;
}
a.hero__visual-row:hover .hero__visual-arrow { color: var(--gold); transform: translateX(2px); }

/* ── 9. Page Banner (inner pages) ───────────────────────────────────────── */
.page-banner {
  background: linear-gradient(135deg, var(--brand-dk) 0%, var(--brand) 100%);
  padding: var(--sp-16) 0;
  position: relative;
  overflow: hidden;
}
.page-banner::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(255,255,255,0.06) 1px, transparent 1px);
  background-size: 24px 24px;
}
.page-banner__inner {
  position: relative;
  z-index: 1;
  max-width: var(--max-w);
  margin: 0 auto;
  padding: 0 var(--sp-6);
}
.page-banner__eyebrow {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: var(--sp-3);
  opacity: 0.85;
}
.page-banner__title {
  font-size: clamp(1.75rem, 4vw, 2.8rem);
  font-weight: 700;
  color: var(--white);
  letter-spacing: -0.5px;
  line-height: 1.15;
  margin-bottom: var(--sp-3);
}
.page-banner__desc {
  font-size: 1.0625rem;
  color: rgba(255,255,255,0.72);
  max-width: 520px;
  line-height: 1.7;
}

/* ── 10. Feature Cards ──────────────────────────────────────────────────── */
.features-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-6);
}

.feature-card {
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-8) var(--sp-6);
  box-shadow: var(--sh-sm);
  transition: transform var(--t), box-shadow var(--t), border-color var(--t);
  position: relative;
  overflow: hidden;
}
.feature-card::after {
  content: '';
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: 3px;
  background: var(--gold);
  transform: scaleX(0);
  transition: transform var(--t);
  transform-origin: left;
}
.feature-card:hover {
  transform: translateY(-5px);
  box-shadow: var(--sh-md);
  border-color: rgba(245,196,0,0.40);
}
.feature-card:hover::after { transform: scaleX(1); }

.feature-card__icon {
  width: 54px; height: 54px;
  border-radius: var(--r);
  background: var(--green-pale);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--green);
  margin-bottom: var(--sp-5);
  transition: background var(--t);
}
.feature-card:hover .feature-card__icon { background: var(--green-pale2); }

.feature-card__title {
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: var(--sp-3);
}
.feature-card__desc {
  font-size: 14px;
  color: var(--text-muted);
  line-height: 1.65;
}

/* ── 11. Location Cards ─────────────────────────────────────────────────── */
.loc-card {
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--sh-sm);
  transition: transform var(--t), box-shadow var(--t), border-color var(--t);
  display: flex;
  flex-direction: column;
}
.loc-card:hover {
  transform: translateY(-5px);
  box-shadow: var(--sh-md);
  border-color: rgba(26,92,42,0.25);
}

.loc-card__thumb {
  height: 190px;
  background: linear-gradient(135deg, var(--brand-dk) 0%, var(--brand-lt) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}
.loc-card__thumb > div {
  padding: var(--sp-4);
}
.loc-card__thumb::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(255,255,255,0.06) 1px, transparent 1px);
  background-size: 20px 20px;
}
.loc-card__thumb-label {
  position: relative;
  font-size: 14px;
  font-weight: 600;
  color: rgba(255,255,255,0.90);
  text-align: center;
  line-height: 1.4;
}
.loc-card__thumb-icon {
  position: relative;
  width: 48px; height: 48px;
  border-radius: 50%;
  background: rgba(255,255,255,0.14);
  border: 2px solid rgba(255,255,255,0.25);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto var(--sp-3);
  color: rgba(255,255,255,0.85);
}

.loc-card__body {
  padding: var(--sp-5) var(--sp-5) var(--sp-6);
  flex: 1;
  display: flex;
  flex-direction: column;
}
.loc-card__meta   { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.loc-card__name   { font-size: 1rem; font-weight: 700; color: var(--text); margin-bottom: var(--sp-2); line-height: 1.3; }
/* Clamped to 3 lines rather than truncated server-side, so the full text is in
   the DOM and main.js can add a Read more toggle. `flex: 1` is deliberately
   gone: it stretched the box past the clamped text, leaving the ellipsis
   floating above dead space. .loc-card__footer's margin-top:auto already pins
   the footer to the bottom of the card. */
.loc-card__desc {
  font-size: 13.5px;
  color: var(--text-muted);
  line-height: 1.6;
  margin-bottom: var(--sp-4);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.loc-card__desc.is-expanded {
  display: block;
  -webkit-line-clamp: unset;
  max-height: 40vh;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.loc-card__footer { margin-top: auto; }

/* ── Card engagement: like + share ────────────────────────────────────────── */
.loc-card__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}
.engage-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 6px 12px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-muted);
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--r-full);
  cursor: pointer;
  transition: color var(--t), border-color var(--t), background var(--t), transform var(--t);
}
.engage-btn:hover { border-color: rgba(26,92,42,0.35); color: var(--text); }
.engage-btn__icon { flex-shrink: 0; transition: transform var(--t); }
.engage-btn__count { font-variant-numeric: tabular-nums; min-width: 8px; }

/* Liked state — filled red heart */
.engage-btn--like.is-liked {
  color: #e0245e;
  border-color: rgba(224,36,94,0.35);
  background: rgba(224,36,94,0.06);
}
.engage-btn--like.is-liked .engage-btn__icon { fill: #e0245e; stroke: #e0245e; }
.engage-btn--like.is-animating .engage-btn__icon { transform: scale(1.35); }

.engage-btn--share:hover { color: var(--green); border-color: rgba(26,92,42,0.35); }

/* ── Toast (copy confirmation) ────────────────────────────────────────────── */
.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translate(-50%, 20px);
  z-index: 9999;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  max-width: 90vw;
  padding: 12px 18px;
  font-size: 14px;
  font-weight: 600;
  color: var(--white);
  background: var(--brand-dk);
  border-radius: var(--r-full);
  box-shadow: var(--sh-lg);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t), transform var(--t);
}
.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

/* Scrollable horizontal strip (index.php preview) */
.locations-scroll-outer {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
  padding-bottom: var(--sp-4);
  /* This strip lives outside .container (full-bleed), so it must NOT use the
     negative side-margins that only make sense inside a padded container —
     those pushed it wider than the viewport and caused horizontal page scroll.
     padding-left keeps the first card aligned with the page gutter. */
  padding-left: var(--sp-6);
}
.locations-scroll-outer::-webkit-scrollbar        { height: 4px; }
.locations-scroll-outer::-webkit-scrollbar-track  { background: transparent; }
.locations-scroll-outer::-webkit-scrollbar-thumb  { background: var(--border); border-radius: 2px; }

.locations-scroll-track {
  display: flex;
  gap: var(--sp-5);
  width: max-content;
  padding-right: var(--sp-6);
  padding-top: var(--sp-2);
}
.locations-scroll-track .loc-card { width: 300px; flex-shrink: 0; }

/* Grid layout (locations.php) */
.locations-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
}
.loc-card--hidden { display: none !important; }

/* ── 12. Search & Filters (locations.php) ───────────────────────────────── */
.search-wrap {
  position: relative;
  max-width: 480px;
  margin-bottom: var(--sp-5);
}
.search-wrap__icon {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  pointer-events: none;
}
.search-input {
  width: 100%;
  height: 48px;
  padding: 0 var(--sp-5) 0 44px;
  border: 1.5px solid var(--border);
  border-radius: var(--r-full);
  font-size: 14.5px;
  color: var(--text);
  background: var(--surface);
  outline: none;
  transition: border-color var(--t), box-shadow var(--t);
}
.search-input::placeholder { color: var(--text-muted); }
.search-input:focus {
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(26,92,42,0.10);
}

.filter-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin-bottom: var(--sp-6);
}
.filter-btn {
  padding: 8px 18px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text-muted);
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--r-full);
  transition: all var(--t);
  cursor: pointer;
}
.filter-btn:hover  { border-color: var(--green); color: var(--green); }
.filter-btn.active { background: var(--brand); border-color: var(--green); color: var(--white); font-weight: 600; }

.results-count {
  font-size: 14px;
  color: var(--text-muted);
  margin-bottom: var(--sp-8);
}
.results-count strong { color: var(--green); font-weight: 600; }

.no-results {
  display: none;
  text-align: center;
  padding: var(--sp-16) 0;
  color: var(--text-muted);
}
.no-results__icon {
  font-size: 3rem;
  margin-bottom: var(--sp-4);
  opacity: 0.35;
}
.no-results h3 { font-size: 1.125rem; font-weight: 600; color: var(--text); margin-bottom: var(--sp-2); }

/* ── 13. CTA Section ────────────────────────────────────────────────────── */
.cta-section {
  background: linear-gradient(135deg, var(--brand-dk) 0%, var(--brand-md) 100%);
  padding: var(--sp-20) 0;
  text-align: center;
  position: relative;
  overflow: hidden;
}
.cta-section::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(255,255,255,0.05) 1px, transparent 1px);
  background-size: 30px 30px;
}
.cta-section__inner { position: relative; z-index: 1; max-width: 640px; margin: 0 auto; padding: 0 var(--sp-6); }
.cta-section__title { font-size: clamp(1.75rem, 4vw, 2.75rem); font-weight: 700; color: var(--white); letter-spacing: -0.5px; margin-bottom: var(--sp-4); }
.cta-section__desc  { font-size: 1.0625rem; color: rgba(255,255,255,0.72); line-height: 1.7; margin-bottom: var(--sp-8); }
.cta-section__actions { display: flex; align-items: center; justify-content: center; gap: var(--sp-4); flex-wrap: wrap; }

/* ── 14. Footer ─────────────────────────────────────────────────────────── */
.site-footer {
  background: var(--dark);
  color: rgba(255,255,255,0.70);
}
.footer-top {
  padding: var(--sp-16) 0;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 2.2fr;
  gap: var(--sp-10);
  max-width: 1700px;
  margin: 0 auto;
  padding: 0 var(--sp-10);
}

.footer-brand__logo {
  width: 76px;
  height: auto;
  display: block;
  object-fit: contain;
  margin-bottom: var(--sp-4);
}
.footer-brand__name {
  font-size: 17px;
  font-weight: 700;
  color: var(--white);
  margin-bottom: var(--sp-2);
}
.footer-brand__tagline {
  font-size: 13px;
  color: rgba(255,255,255,0.50);
  line-height: 1.65;
  margin-bottom: var(--sp-5);
}
.footer-brand__contact { display: flex; flex-direction: column; gap: var(--sp-2); }
.footer-contact-item {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  font-size: 13px;
  color: rgba(255,255,255,0.58);
  line-height: 1.5;
}
.footer-contact-item svg { flex-shrink: 0; margin-top: 2px; }

.footer-col__heading {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--white);
  margin-bottom: var(--sp-5);
}
.footer-links { display: flex; flex-direction: column; gap: var(--sp-3); }
.footer-links a {
  font-size: 13.5px;
  color: rgba(255,255,255,0.58);
  transition: color var(--t);
}
.footer-links a:hover { color: var(--gold); }

.footer-feedback__text {
  font-size: 13px;
  color: rgba(255,255,255,0.50);
  line-height: 1.65;
  margin-bottom: var(--sp-5);
}

.footer-social { display: flex; gap: var(--sp-3); margin-top: var(--sp-2); }
.footer-social-btn {
  width: 38px; height: 38px;
  border-radius: var(--r);
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.10);
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255,255,255,0.60);
  transition: background var(--t), color var(--t), border-color var(--t);
}
.footer-social-btn:hover {
  background: var(--gold-pale);
  border-color: rgba(245,196,0,0.35);
  color: var(--gold);
}

.footer-bottom {
  max-width: 1700px;
  margin: 0 auto;
  padding: var(--sp-5) var(--sp-10);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  flex-wrap: wrap;
}
.footer-bottom p { font-size: 12.5px; color: rgba(255,255,255,0.35); }
.footer-bottom a { color: rgba(255,255,255,0.45); transition: color var(--t); }
.footer-bottom a:hover { color: var(--gold); }

/* ── 15. About Page ─────────────────────────────────────────────────────── */
.about-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-16);
  align-items: center;
}
.about-split--reverse { direction: rtl; }
.about-split--reverse > * { direction: ltr; }

.about-img-placeholder {
  height: 380px;
  border-radius: var(--r-xl);
  background: linear-gradient(135deg, var(--brand-dk), var(--brand-lt));
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: var(--sp-4);
  color: rgba(255,255,255,0.75);
  font-size: 15px;
  font-weight: 500;
  text-align: center;
  padding: var(--sp-6);
  box-shadow: var(--sh-md);
}
.about-img-icon {
  width: 72px; height: 72px;
  border-radius: 50%;
  background: rgba(255,255,255,0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--gold);
}

/* Live, self-rotating 360° tour preview (about page, home hero fallback) */
.pano-preview {
  position: relative;
  height: 380px;
  border-radius: var(--r-xl);
  overflow: hidden;
  box-shadow: var(--sh-md);
  cursor: grab;
}
.pano-preview:active { cursor: grabbing; }
.pano-preview__viewer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, var(--brand-dk), var(--brand-lt));
}
.pano-preview__badge {
  position: absolute;
  left: 14px;
  bottom: 14px;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: 100px;
  background: rgba(26,92,42,0.9);
  border: 1px solid rgba(255,255,255,0.2);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  backdrop-filter: blur(4px);
  transition: background 200ms ease;
}
.pano-preview__badge:hover { background: rgba(26,92,42,1); }

.about-text p {
  font-size: 1.0625rem;
  color: var(--text-muted);
  line-height: 1.8;
  margin-bottom: var(--sp-4);
}
.about-text p:last-child { margin-bottom: 0; }

/* Team cards */
.team-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
  max-width: 800px;
  margin: 0 auto;
}
.team-card {
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-8) var(--sp-6);
  text-align: center;
  box-shadow: var(--sh-sm);
  transition: transform var(--t), box-shadow var(--t);
}
.team-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--sh-md);
}
.team-card__avatar {
  width: 80px; height: 80px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--brand), var(--brand-lt));
  color: var(--white);
  font-size: 1.25rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto var(--sp-4);
  box-shadow: var(--sh-green);
}
/* Real headshot instead of the initials placeholder */
.team-card__avatar--photo {
  display: block;
  background: none;
  object-fit: cover;
  object-position: center;
  border: 2px solid var(--white);
}
/* Reserve two lines so a name that wraps doesn't push its role and badge out of
   line with the neighbouring cards. Reset on mobile, where cards stack. */
.team-card__name  {
  font-size: 1rem; font-weight: 700; color: var(--text); margin-bottom: var(--sp-1);
  line-height: 1.35;
  min-height: 2.7em;
}
.team-card__role  { font-size: 13px; color: var(--text-muted); margin-bottom: var(--sp-3); }
.team-card__badge {
  display: inline-block;
  padding: 4px 12px;
  background: var(--green-pale);
  color: var(--green);
  font-size: 11px;
  font-weight: 600;
  border-radius: var(--r-full);
}

/* Tech stack */
.tech-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-4);
}
.tech-item {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--sh-xs);
  transition: border-color var(--t), box-shadow var(--t);
}
.tech-item:hover { border-color: var(--green); box-shadow: var(--sh-sm); }
.tech-item__icon {
  width: 42px; height: 42px;
  border-radius: var(--r);
  background: var(--green-pale);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--green);
  flex-shrink: 0;
}
.tech-item__name  { font-size: 14px; font-weight: 600; color: var(--text); }
.tech-item__desc  { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

/* Adviser card */
.adviser-card {
  display: flex;
  align-items: center;
  gap: var(--sp-6);
  max-width: 560px;
  margin: 0 auto;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-6) var(--sp-8);
  box-shadow: var(--sh-sm);
}
.adviser-card__avatar {
  width: 72px; height: 72px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center top;
  display: block;
  flex-shrink: 0;
  border: 2px solid var(--white);
  box-shadow: var(--sh-green);
}
.adviser-card__name  { font-size: 1.125rem; font-weight: 700; color: var(--text); margin-bottom: var(--sp-1); }
.adviser-card__title { font-size: 14px; color: var(--text-muted); }
.adviser-card__dept  { font-size: 13px; color: var(--green); font-weight: 500; margin-top: 2px; }

/* ── 16. Chatbot ─────────────────────────────────────────────────────────── */
.chatbot-wrapper {
  position: fixed;
  bottom: var(--sp-6);
  right: var(--sp-6);
  z-index: 9000;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--sp-3);
}

.chatbot-bubble {
  width: 58px; height: 58px;
  border-radius: 50%;
  background: var(--gold);
  color: var(--brand-dk);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 24px rgba(245,196,0,0.55);
  transition: transform var(--t), box-shadow var(--t), background var(--t);
  cursor: pointer;
  border: none;
  position: relative;
}
.chatbot-bubble:hover {
  transform: scale(1.08);
  box-shadow: 0 6px 28px rgba(245,196,0,0.65);
  background: var(--gold-dk);
}
/* Re-use existing IDs from footer.php */
#chatbot-trigger-btn {
  width: 58px; height: 58px;
  border-radius: 50%;
  background: var(--gold);
  color: var(--brand-dk);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 24px rgba(245,196,0,0.50);
  transition: transform var(--t), box-shadow var(--t), background var(--t);
  border: none;
  cursor: pointer;
}
#chatbot-trigger-btn:hover {
  transform: scale(1.08);
  box-shadow: 0 6px 28px rgba(245,196,0,0.65);
  background: var(--gold-dk);
}
.chatbot-icon-close { display: none; }
#chatbot-trigger-btn.is-open .chatbot-icon-open  { display: none; }
#chatbot-trigger-btn.is-open .chatbot-icon-close { display: block; }

.chatbot-window {
  width: 360px;
  max-height: 520px;
  background: var(--surface);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: chatSlide .24s ease;
  border: 1px solid var(--border);
}
.chatbot-window[hidden] { display: none; }

@keyframes chatSlide {
  from { opacity: 0; transform: translateY(14px) scale(.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.chatbot-header {
  background: var(--brand);
  padding: 14px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}
.chatbot-header-info { display: flex; align-items: center; gap: var(--sp-3); }
/* Now an <img> (the CLSU mascot) rather than the old "AI" text placeholder.
   object-fit:cover keeps the artwork centred in the circle instead of squashing
   it, and the gold stays as the backing tint so a failed image load shows a
   brand-coloured disc rather than a broken-image icon. */
.chatbot-avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--gold);
  object-fit: cover;
  flex-shrink: 0;
  display: block;
}
.chatbot-name   { font-size: 14px; font-weight: 600; color: var(--white); }
.chatbot-status { font-size: 11px; color: rgba(255,255,255,0.60); }
.chatbot-close-btn {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: rgba(255,255,255,0.13);
  color: var(--white);
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--t);
  border: none;
  cursor: pointer;
}
.chatbot-close-btn:hover { background: rgba(255,255,255,0.23); }

.chatbot-messages {
  flex: 1;
  overflow-y: auto;
  padding: var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  background: var(--bg);
}
.chatbot-msg { max-width: 85%; }
.chatbot-msg--bot  { align-self: flex-start; }
.chatbot-msg--user { align-self: flex-end; }
.chatbot-msg p {
  padding: 10px 14px;
  border-radius: 12px;
  font-size: 13.5px;
  line-height: 1.55;
}
.chatbot-msg--bot  p { background: var(--surface); color: var(--text); border-radius: 4px 12px 12px 12px; box-shadow: var(--sh-xs); }
.chatbot-msg--user p { background: var(--brand); color: var(--white); border-radius: 12px 4px 12px 12px; }

.chatbot-input-form {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 12px 14px;
  border-top: 1px solid var(--border);
  background: var(--surface);
  flex-shrink: 0;
}

/* Pinned below the input rather than placed in the message log, so it cannot be
   scrolled away or buried above a long conversation. flex-shrink:0 keeps it
   visible when the window is at its max-height. One row carries both the
   disclaimer and the character counter — they used to stack into two thin
   bands under the composer, which made the panel bottom-heavy. */
.chatbot-foot {
  flex-shrink: 0;
  padding: 2px 14px 10px;
  background: var(--surface);
  /* Two slots. The counter's column is held open even while it is invisible,
     so the disclaimer neither shifts when typing starts nor collides with the
     count on a narrow window. */
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  column-gap: 8px;
}
.chatbot-disclaimer {
  justify-self: center;
  max-width: 100%;
  margin: 0;
  font-size: 10px;
  line-height: 1.3;
  /* --text-muted, not --text-light: the latter is rgba(255,255,255,0.72), a
     white token for dark surfaces, and would be invisible on this white panel. */
  color: var(--text-muted);
  opacity: 0.8;
  text-align: center;
  /* Clip rather than wrap. The wording is short enough for one line at the
     360px window width; if a narrower viewport ever squeezes it, one clipped
     line degrades better than a growing grey block with a ragged last line. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chatbot-input {
  flex: 1;
  height: 38px;
  padding: 0 14px;
  border: 1.5px solid var(--border);
  border-radius: var(--r-full);
  font-size: 13.5px;
  font-family: var(--font);
  color: var(--text);
  background: var(--bg);
  outline: none;
  transition: border-color var(--t);
}
.chatbot-input:focus { border-color: var(--green); }
.chatbot-send-btn {
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--brand);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  cursor: pointer;
  flex-shrink: 0;
  transition: background var(--t);
}
.chatbot-send-btn:hover { background: var(--brand-md); }

/* ── 17. Scroll Animations ──────────────────────────────────────────────── */
.fade-up {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity .60s ease, transform .60s ease;
}
.fade-up.visible {
  opacity: 1;
  transform: translateY(0);
}
.fade-up:nth-child(2) { transition-delay: .10s; }
.fade-up:nth-child(3) { transition-delay: .20s; }
.fade-up:nth-child(4) { transition-delay: .30s; }

/* ── 18. Utility ────────────────────────────────────────────────────────── */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.text-center { text-align: center; }
.text-muted  { color: var(--text-muted); }
.d-flex      { display: flex; }
.gap-3       { gap: var(--sp-3); }
.mt-2        { margin-top: var(--sp-2); }
.mt-4        { margin-top: var(--sp-4); }
.mt-8        { margin-top: var(--sp-8); }
.mt-10       { margin-top: var(--sp-10); }

/* ── 19. Responsive ─────────────────────────────────────────────────────── */

/* ── Tablet (≤1024px) ── */
@media (max-width: 1024px) {
  .hero__inner        { grid-template-columns: 1fr; }
  /* Stack the tour-preview card below the text instead of hiding it */
  .hero__visual       { max-width: 460px; margin-top: var(--sp-6); }
  .hero__title        { font-size: clamp(2rem, 5vw, 3rem); }

  .features-grid      { grid-template-columns: repeat(2, 1fr); }

  .locations-grid     { grid-template-columns: repeat(2, 1fr); }

  .about-split        { grid-template-columns: 1fr; gap: var(--sp-10); }
  .about-split--reverse { direction: ltr; }
  .about-img-placeholder { height: 280px; }
  .pano-preview { height: 280px; }

  .team-grid          { grid-template-columns: repeat(3, 1fr); }
  .tech-grid          { grid-template-columns: repeat(2, 1fr); }

  .footer-grid        { grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
  .footer-brand-col   { grid-column: 1 / -1; }
}

/* ── Mobile (≤768px) ── */
@media (max-width: 768px) {
  body { font-size: 15px; }

  /* Nav mobile */
  .nav-toggle { display: flex; }
  .nav-menu {
    display: none;
    position: absolute;
    top: var(--nav-h);
    left: 0; right: 0;
    background: var(--brand-dk);
    flex-direction: column;
    align-items: stretch;
    padding: var(--sp-3) var(--sp-4) var(--sp-5);
    gap: var(--sp-1);
    box-shadow: 0 8px 24px rgba(0,0,0,0.22);
    border-top: 1px solid rgba(255,255,255,0.10);
  }
  .navbar { position: fixed; }  /* ensure fixed on mobile too */
  .navbar .nav-inner { position: relative; }
  .nav-menu.is-open { display: flex; }
  .nav-link   { padding: 11px 14px; }
  .nav-cta    { margin: var(--sp-2) 0 0; text-align: center; justify-content: center; }

  .hero       { padding-top: calc(var(--nav-h) + var(--sp-12)); padding-bottom: var(--sp-12); min-height: auto; }
  .hero__actions { flex-direction: column; align-items: flex-start; }
  .hero__stats   { flex-wrap: wrap; gap: var(--sp-4); }
  .hero__visual        { max-width: none; margin-top: var(--sp-8); }
  .hero__visual-thumb  { height: 240px; }

  .features-grid  { grid-template-columns: 1fr; }
  .locations-grid { grid-template-columns: 1fr; }
  .team-grid      { grid-template-columns: 1fr; max-width: 320px; }
  .team-card__name { min-height: 0; }
  .tech-grid      { grid-template-columns: 1fr; }
  .adviser-card   { flex-direction: column; text-align: center; }

  .footer-grid    { grid-template-columns: 1fr; gap: var(--sp-8); }
  .footer-bottom  { flex-direction: column; text-align: center; gap: var(--sp-2); }

  .section        { padding: var(--sp-12) 0; }
  .cta-section    { padding: var(--sp-12) 0; }
  .page-banner    { padding: var(--sp-10) 0; }

  .chatbot-window { width: calc(100vw - 48px); }
  .chatbot-wrapper { right: var(--sp-4); bottom: var(--sp-4); }
}

/* ── Small mobile (≤375px) ── */
@media (max-width: 375px) {
  :root { --nav-h: 64px; }
  .container { padding: 0 var(--sp-4); }
  .hero__title { font-size: 1.85rem; }
  .btn--lg { padding: 14px 24px; font-size: 15px; }
  .nav-logo       { width: 40px; height: 40px; }
  .nav-brand-top  { font-size: 9.5px; letter-spacing: 0.2px; }
  .nav-brand-sub  { font-size: 15px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Sprint 3 — Tour & Map page styles
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 20. Tour Page Layout ───────────────────────────────────────────────── */

/* Remove default main padding on full-viewport pages */
.tour-layout,
.map-layout {
  height: calc(100vh - var(--nav-h));
  overflow: hidden;
}

/* Shared full-viewport flex shell */
.tour-layout,
.map-layout {
  display: flex;
  background: var(--dark);
}

/* ── Tour Sidebar ────────────────────────────────────────────────────────── */
.tour-sidebar {
  width: 280px;
  flex-shrink: 0;
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: transform var(--ts);
  z-index: 200;
}

.tour-sidebar__head {
  padding: var(--sp-5) var(--sp-5) var(--sp-4);
  border-bottom: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  flex-shrink: 0;
}
/* Title block and close button keep their old side-by-side arrangement; the
   head itself became a column so the search can sit under them. */
.tour-sidebar__head-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-3);
}

/* Sidebar filter. Deliberately the same shape as .map-search-input — both are
   "narrow this list", and looking alike is what tells them apart from the
   navbar search, which navigates. */
.tour-search-wrap { position: relative; }
.tour-search-wrap__icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  pointer-events: none;
}
.tour-search-input {
  width: 100%;
  height: 36px;
  padding: 0 var(--sp-4) 0 34px;
  border: 1.5px solid var(--border);
  border-radius: var(--r-full);
  font-size: 13px;
  font-family: var(--font);
  color: var(--text);
  background: var(--bg);
  transition: border-color var(--tf), background var(--tf);
}
.tour-search-input::placeholder { color: var(--text-muted); }
.tour-search-input:focus {
  outline: none;
  border-color: var(--green);
  background: var(--surface);
}
/* Safari paints its own clear button; hide it so the control matches the map's. */
.tour-search-input::-webkit-search-cancel-button { -webkit-appearance: none; }

.tour-search-empty {
  display: none;
  padding: var(--sp-5);
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-muted);
  text-align: center;
}
.tour-search-empty:not([hidden]) { display: block; }

/* Hidden by the filter. A class rather than an inline style so a re-render or a
   theme change cannot leave a row stuck invisible. */
.tour-route-group--filtered,
.tour-scene-row--filtered { display: none; }

.tour-sidebar__title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 2px;
}

.tour-sidebar__count {
  font-size: 12px;
  color: var(--text-muted);
}

/* Mobile only. On desktop the panel is permanent furniture, not a slide-over:
   the .is-open class it toggles has no effect outside the max-width:768px block,
   so the button was simply inert — it looked like a close control and did
   nothing. Re-shown in the mobile media query where it genuinely closes the
   slide-over panel. */
.tour-sidebar__close {
  display: none;
  width: 28px;
  height: 28px;
  border-radius: var(--r);
  background: var(--bg);
  color: var(--text-muted);
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  flex-shrink: 0;
  transition: background var(--t), color var(--t);
}
.tour-sidebar__close:hover { background: var(--bg-alt); color: var(--text); }

/* NOTE: no markup uses .tour-location-list — the tour sidebar renders
   .tour-route-accordion instead. Kept (correct as written) in case the class is
   reintroduced, but the rule that actually makes the tour sidebar scroll is
   .tour-sidebar > nav. */
.tour-location-list {
  flex: 1;
  min-height: 0;   /* flex items default to min-height:auto and won't shrink */
  overflow-y: auto;
  padding: var(--sp-2) 0;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.tour-location-list::-webkit-scrollbar       { width: 4px; }
.tour-location-list::-webkit-scrollbar-track { background: transparent; }
.tour-location-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

.tour-location-item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 10px var(--sp-5);
  text-decoration: none;
  transition: background var(--tf);
  position: relative;
}
.tour-location-item:hover   { background: var(--bg); }
.tour-location-item.active  { background: var(--green-pale); }
.tour-location-item.active::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--brand);
  border-radius: 0 2px 2px 0;
}

.tour-location-item__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
}
/* Dot colors matching badge palette */
.tour-dot--academic       { background: var(--c-academic); }
.tour-dot--administrative { background: var(--c-administrative); }
.tour-dot--facility       { background: var(--c-facility); }
.tour-dot--landmark       { background: var(--c-landmark); }
.tour-dot--entrance       { background: var(--c-entrance); }
.tour-dot--dorm           { background: var(--c-dorm); }
/* Scene number dot for tour_route.php */
.tour-dot--scene {
  background: var(--brand);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
}

.tour-location-item__text {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}
.tour-location-item__name {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tour-location-item.active .tour-location-item__name { font-weight: 600; color: var(--green-dk); }
.tour-location-item__type {
  font-size: 11px;
  color: var(--text-muted);
  text-transform: capitalize;
}
.tour-location-item__arrow { color: var(--green); flex-shrink: 0; }

/* ── Tour route accordion (tour.php sidebar) ─────────────────────────────── */
/* The sidebar's flex child is the <nav> wrapper, NOT the accordion <ul> inside
   it, and the nav had no rule of its own. So the accordion's flex:1 was inert
   (its parent was a plain block, not a flex container) and its overflow-y never
   engaged because nothing bounded its height — the list just grew and
   .tour-sidebar's overflow:hidden clipped every route below the fold.
   Make the nav the shrinkable flex item so the accordion can scroll inside it.
   Selector rather than a new class to keep this a stylesheet-only change. */
.tour-sidebar > nav {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.tour-route-accordion {
  flex: 1;
  min-height: 0;   /* see .tour-sidebar > nav — without this it will not shrink */
  overflow-y: auto;
  padding: var(--sp-2) 0;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.tour-route-accordion::-webkit-scrollbar       { width: 4px; }
.tour-route-accordion::-webkit-scrollbar-track { background: transparent; }
.tour-route-accordion::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

.tour-route-group { border-bottom: 1px solid rgba(0,0,0,0.04); }

.tour-route-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 12px var(--sp-5);
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  transition: background var(--tf);
}
.tour-route-toggle:hover { background: var(--bg); }
.tour-route-group.is-open .tour-route-toggle { background: var(--bg); }

.tour-route-toggle__text { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.tour-route-toggle__name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tour-route-toggle__meta { font-size: 11px; color: var(--text-muted); margin-top: 1px; }
.tour-route-toggle__chev {
  color: var(--text-muted);
  flex-shrink: 0;
  transition: transform var(--t);
}
.tour-route-group.is-open .tour-route-toggle__chev { transform: rotate(180deg); }

/* Collapsible scene list */
.tour-scene-sublist {
  display: none;
  padding: 4px 0 8px;
  background: var(--surface);
}
.tour-route-group.is-open .tour-scene-sublist { display: block; }

.tour-scene-item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 7px var(--sp-5) 7px var(--sp-6);
  text-decoration: none;
  transition: background var(--tf);
  position: relative;
}
.tour-scene-item:hover  { background: var(--bg); }
.tour-scene-item.active { background: var(--green-pale); }
.tour-scene-item.active::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--brand);
  border-radius: 0 2px 2px 0;
}

.tour-scene-item__thumb {
  width: 44px;
  height: 32px;
  border-radius: 4px;
  overflow: hidden;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--brand-dk), #2d8a47);
  display: flex;
  align-items: center;
  justify-content: center;
}
.tour-scene-item__thumb img { width: 100%; height: 100%; object-fit: cover; }
.tour-scene-item__thumb-ph { color: rgba(255,255,255,0.9); font-size: 10px; font-weight: 700; }

.tour-scene-item__name {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tour-scene-item.active .tour-scene-item__name { font-weight: 600; color: var(--green-dk); }
.tour-scene-empty { padding: 8px var(--sp-6); font-size: 12px; color: var(--text-muted); }

/* ── Tour Main Column ────────────────────────────────────────────────────── */
.tour-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
}

/* ── Viewer Wrap (panorama + overlays) ───────────────────────────────────── */
.tour-viewer-wrap {
  flex: 1;
  position: relative;
  min-height: 0;
  background: #0a0f0c;
  overflow: hidden;
}

.tour-panorama {
  width: 100%;
  height: 100%;
  display: block;
}

/* Pannellum overrides */
.pnlm-container { background: #0a0f0c !important; }
.pnlm-ui .pnlm-controls-container { top: 12px !important; left: 12px !important; }
.pnlm-controls { background: rgba(15,26,20,0.75) !important; border: 1px solid rgba(255,255,255,0.12) !important; }
.pnlm-control button { color: rgba(255,255,255,0.85) !important; }

/* ── Scene watermark overlay ─────────────────────────────────────────────── */
.tour-watermark {
  position: absolute;
  left: var(--sp-4);
  bottom: var(--sp-4);
  z-index: 400;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 14px;
  max-width: 60%;
  background: rgba(15, 26, 20, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-left: 3px solid var(--gold);
  border-radius: var(--r-sm);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  pointer-events: none;
  user-select: none;
}

.tour-watermark__scene {
  font-size: 13px;
  font-weight: 600;
  color: var(--white);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
  line-height: 1.3;
}

.tour-watermark__photographer {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.82);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
  line-height: 1.3;
}
.tour-watermark__photographer svg {
  flex-shrink: 0;
  color: var(--gold);
}

@media (max-width: 768px) {
  .tour-watermark {
    left: var(--sp-3);
    bottom: var(--sp-3);
    padding: 6px 10px;
    max-width: 70%;
  }
  .tour-watermark__scene       { font-size: 12px; }
  .tour-watermark__photographer { font-size: 10px; }
}

/* ── Placeholder (no panorama) ───────────────────────────────────────────── */
.tour-placeholder {
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, var(--brand-dk) 0%, #0d2818 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.tour-placeholder::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(255,255,255,0.04) 1px, transparent 1px);
  background-size: 28px 28px;
}
.tour-placeholder__inner {
  position: relative;
  z-index: 1;
  text-align: center;
  padding: var(--sp-8);
}
.tour-placeholder__icon {
  width: 100px;
  height: 100px;
  border-radius: 50%;
  background: rgba(255,255,255,0.06);
  border: 2px solid rgba(255,255,255,0.12);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto var(--sp-6);
  color: var(--gold);
}
.tour-placeholder__heading {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--white);
  margin-bottom: var(--sp-3);
}
.tour-placeholder__sub {
  font-size: 14px;
  color: rgba(255,255,255,0.60);
  margin-bottom: var(--sp-5);
  max-width: 360px;
}

/* ── Mini-map Overlay ────────────────────────────────────────────────────── */
.tour-minimap {
  position: absolute;
  top: var(--sp-4);
  right: var(--sp-4);
  z-index: 500;
  width: 200px;
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: var(--sh-lg);
  border: 2px solid rgba(255,255,255,0.20);
  background: var(--surface);
}

.tour-minimap__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 5px 10px;
  background: var(--brand);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: rgba(255,255,255,0.90);
}

.tour-minimap__label {
  display: flex;
  align-items: center;
  gap: 5px;
}

/* Leaflet map canvas inside the overlay */
#tour-minimap {
  height: 140px;
  width: 100%;
}

/* Pulsing "you are here" dot in the bar */
.tour-minimap__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 0 0 rgba(245,196,0,0.6);
  animation: tour-minimap-pulse 1.8s ease-out infinite;
}

@keyframes tour-minimap-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(245,196,0,0.6); }
  70%  { box-shadow: 0 0 0 7px rgba(245,196,0,0); }
  100% { box-shadow: 0 0 0 0 rgba(245,196,0,0); }
}

.tour-minimap__expand {
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255,255,255,0.75);
  transition: color var(--t);
  border-radius: var(--r-xs);
  padding: 2px;
}
.tour-minimap__expand:hover { color: var(--gold); }

/* Suppress Leaflet attribution in mini-map */
.tour-minimap .leaflet-control-attribution { display: none; }

/* ── Sidebar Toggle Button (mobile overlay button on panorama) ───────────── */
.tour-sidebar-toggle {
  position: absolute;
  top: var(--sp-4);
  left: var(--sp-4);
  z-index: 500;
  display: none;
  align-items: center;
  gap: var(--sp-2);
  padding: 8px 14px;
  background: rgba(15,26,20,0.82);
  color: var(--white);
  font-size: 13px;
  font-weight: 600;
  border-radius: var(--r-sm);
  border: 1px solid rgba(255,255,255,0.14);
  backdrop-filter: blur(4px);
  transition: background var(--t);
}
.tour-sidebar-toggle:hover { background: rgba(26,92,42,0.90); }

/* ── Pannellum fullscreen icon ───────────────────────────────────────────────
   The .pnlm-controls override above uses the `background` shorthand, which wipes
   the fullscreen button's sprite icon (its dark bg lives on the button itself,
   unlike the zoom buttons whose bg is on their parent). Restore a crisp white
   icon that reads on the dark control. */
.pnlm-fullscreen-toggle-button {
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='16'%20height='16'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23fff'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M8%203H5a2%202%200%200%200-2%202v3m18%200V5a2%202%200%200%200-2-2h-3m0%2018h3a2%202%200%200%200%202-2v-3M3%2016v3a2%202%200%200%200%202%202h3'/%3E%3C/svg%3E") !important;
  background-position: center !important;
  background-repeat: no-repeat !important;
  background-size: 15px 15px !important;
}

/* ── Pannellum zoom buttons ──────────────────────────────────────────────────
   Pannellum ships these as a sprite drawn in dark ink, because its own control
   background is light. Our .pnlm-controls override paints the container dark,
   which left the + and − glyphs black-on-black. Redraw them white to match the
   fullscreen / auto-rotate / hotspot buttons in the same stack. */
.pnlm-zoom-in {
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'16'%20height%3D'16'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'%23fff'%20stroke-width%3D'2.4'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cline%20x1%3D'12'%20y1%3D'6'%20x2%3D'12'%20y2%3D'18'%2F%3E%3Cline%20x1%3D'6'%20y1%3D'12'%20x2%3D'18'%20y2%3D'12'%2F%3E%3C%2Fsvg%3E") !important;
  background-position: center center !important;
  background-repeat: no-repeat !important;
  background-size: 14px 14px !important;
}
.pnlm-zoom-out {
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'16'%20height%3D'16'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'%23fff'%20stroke-width%3D'2.4'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cline%20x1%3D'6'%20y1%3D'12'%20x2%3D'18'%20y2%3D'12'%2F%3E%3C%2Fsvg%3E") !important;
  background-position: center center !important;
  background-repeat: no-repeat !important;
  background-size: 14px 14px !important;
}

/* ── Auto-rotate control (injected into Pannellum's top-left control stack) ────
   Match the fullscreen button's box exactly: 26×26 content box + the 1px
   .pnlm-controls border = 28px, so it lines up with the zoom / fullscreen
   buttons above it. */
.pnlm-autorotate-btn {
  width: 26px !important;
  height: 26px !important;
  box-sizing: content-box !important;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='16'%20height='16'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23fff'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpolyline%20points='23%204%2023%2010%2017%2010'/%3E%3Cpolyline%20points='1%2020%201%2014%207%2014'/%3E%3Cpath%20d='M3.51%209a9%209%200%200%201%2014.85-3.36L23%2010M1%2014l4.64%204.36A9%209%200%200%200%2020.49%2015'/%3E%3C/svg%3E") !important;
  background-position: center center !important;
  background-repeat: no-repeat !important;
  background-size: 14px 14px !important;
}
.pnlm-autorotate-btn.is-on {
  background-color: rgba(26,92,42,0.92) !important;
  border-color: rgba(245,196,0,0.65) !important;
}

/* ── Hotspot visibility toggle (injected next to auto-rotate) ─────────────── */
.pnlm-hotspots-btn {
  width: 26px !important;
  height: 26px !important;
  box-sizing: content-box !important;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='16'%20height='16'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23fff'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M1%2012s4-8%2011-8%2011%208%2011%208-4%208-11%208-11-8-11-8z'/%3E%3Ccircle%20cx='12'%20cy='12'%20r='3'/%3E%3C/svg%3E") !important;
  background-position: center center !important;
  background-repeat: no-repeat !important;
  background-size: 14px 14px !important;
}
.pnlm-hotspots-btn.is-on {
  background-color: rgba(26,92,42,0.92) !important;
  border-color: rgba(245,196,0,0.65) !important;
}
/* Off state: eye-off icon, no green fill, so it reads as "currently hidden" */
.pnlm-hotspots-btn:not(.is-on) {
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='16'%20height='16'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23fff'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M17.94%2017.94A10.94%2010.94%200%200%201%2012%2020c-7%200-11-8-11-8a21.8%2021.8%200%200%201%205.06-6.06M9.9%204.24A10.94%2010.94%200%200%201%2012%204c7%200%2011%208%2011%208a21.8%2021.8%200%200%201-2.16%203.19M14.12%2014.12a3%203%200%200%201-4.24-4.24'/%3E%3Cline%20x1='1'%20y1='1'%20x2='23'%20y2='23'/%3E%3C/svg%3E") !important;
}

/* ── Device-orientation control — removed ──────────────────────────────────────
   This was the blank button on phones. Pannellum adds .pnlm-orientation-button
   on any device reporting motion support; it tilts the view as you physically
   move the handset. Dropped rather than given an icon: it needs an iOS motion
   permission prompt, it competes with drag-to-look, and it adds a third control
   whose purpose is not self-evident to a visitor. Hidden in CSS because
   Pannellum offers no option to suppress it.
   (It rendered blank because the .pnlm-controls override sets the `background`
   shorthand, which wipes the sprite these buttons draw from — the same trap
   noted above for the fullscreen icon. Relevant if it is ever reinstated.) */
.pnlm-orientation-button { display: none !important; }

/* ── Expand control — stand-in for fullscreen where the API does not exist ─────
   iOS Safari on iPhone implements the Fullscreen API only for <video>, so
   Pannellum never builds its fullscreen button there. It is not being hidden by
   our CSS — it is never created. This is the substitute: pure CSS, no API, works
   everywhere. main.js injects the button ONLY where the native API is missing,
   so browsers that support fullscreen keep Pannellum's own control. */
.pnlm-expand-btn {
  width: 26px !important;
  height: 26px !important;
  box-sizing: content-box !important;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='16'%20height='16'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23fff'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M8%203H5a2%202%200%200%200-2%202v3m18%200V5a2%202%200%200%200-2-2h-3m0%2018h3a2%202%200%200%200%202-2v-3M3%2016v3a2%202%200%200%200%202%202h3'/%3E%3C/svg%3E") !important;
  background-position: center center !important;
  background-repeat: no-repeat !important;
  background-size: 15px 15px !important;
}
/* Arrows pointing inward once expanded, so the control reads as "collapse". */
.pnlm-expand-btn.is-on {
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='16'%20height='16'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23fff'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M8%203v3a2%202%200%200%201-2%202H3m18%200h-3a2%202%200%200%201-2-2V3m0%2018v-3a2%202%200%200%201%202-2h3M3%2016h3a2%202%200%200%201%202%202v3'/%3E%3C/svg%3E") !important;
  background-color: rgba(26,92,42,0.92) !important;
  border-color: rgba(245,196,0,0.65) !important;
}

/* The expanded state itself. z-index sits over the navbar (1000) and every tour
   overlay (600 max) but under the chat bubble (9000), so the assistant stays
   reachable while exploring. */
.tour-viewer-wrap.is-expanded {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  height: 100dvh;   /* iOS: discounts the collapsing address bar, unlike 100vh */
  z-index: 8000;
}
body.tour-viewer-expanded { overflow: hidden; }

/* ── Info Panel ──────────────────────────────────────────────────────────── */
.tour-info-panel {
  background: var(--surface);
  border-top: 1px solid var(--border);
  flex-shrink: 0;
  overflow-y: auto;
}

.tour-info-panel__inner {
  padding: var(--sp-4) var(--sp-6);
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: start;
  gap: var(--sp-6);
}

.tour-info-meta {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-2);
}

.tour-info-counter {
  font-size: 12px;
  color: var(--text-muted);
  font-weight: 500;
}

.tour-info-name {
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: var(--sp-1);
  line-height: 1.3;
}

.tour-info-desc {
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.6;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Expanded state. Real descriptions run 300–500 characters, so the 2-line clamp
   hid most of the text with no way to reach it — this is the only place in the
   UI that shows a description in full (the cards elsewhere are teasers that
   link here). max-height keeps a long one from swallowing the panorama on short
   screens; it scrolls instead. */
.tour-info-desc.is-expanded {
  display: block;
  -webkit-line-clamp: unset;
  max-height: 30vh;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}

/* Shared by the tour info panel and the location cards. Injected by main.js
   only when the text actually overflows, so short descriptions never show a
   toggle that reveals nothing. */
.desc-toggle {
  align-self: flex-start;
  margin-top: 2px;
  padding: 0;
  background: none;
  border: 0;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--green);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.desc-toggle:hover { color: var(--green-dk); }
.desc-toggle:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

/* On a card the toggle sits between the clamped text and the actions row, so it
   needs the spacing the paragraph's own margin used to provide. */
.loc-card__desc + .desc-toggle { margin-top: -10px; margin-bottom: var(--sp-4); }

.tour-info-actions {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  flex-shrink: 0;
}

/* ── Prev / Next Arrows ──────────────────────────────────────────────────── */
.tour-nav-arrows {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  flex-shrink: 0;
  min-width: 160px;
}

.tour-nav-btn {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 9px 14px;
  border-radius: var(--r);
  border: 1.5px solid var(--border);
  background: var(--surface);
  text-decoration: none;
  transition: background var(--t), border-color var(--t), color var(--t);
  max-width: 200px;
}
.tour-nav-btn:hover { background: var(--bg); border-color: var(--green); }

.tour-nav-btn--prev { flex-direction: row; }
.tour-nav-btn--next { flex-direction: row-reverse; }

.tour-nav-btn__label {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.tour-nav-btn__direction {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-muted);
}
.tour-nav-btn__name {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tour-nav-btn svg { color: var(--green); flex-shrink: 0; }

/* ── 21. Map Page Layout ────────────────────────────────────────────────── */

/* Sidebar */
.map-sidebar {
  width: 320px;
  flex-shrink: 0;
  background: var(--surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 200;
  transition: transform var(--ts);
}

/* Mirrors .tour-sidebar__close — hidden until the panel becomes a slide-over. */
.map-sidebar__close {
  display: none;
  position: absolute;
  top: 10px;
  right: 10px;
  width: 30px;
  height: 30px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--t, .2s), color var(--t, .2s);
}
.map-sidebar__close:hover { background: var(--bg-alt); color: var(--text); }

.map-sidebar__head {
  position: relative;
  padding: var(--sp-5);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.map-sidebar__title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 2px;
}
.map-sidebar__sub { font-size: 12px; color: var(--text-muted); margin-bottom: var(--sp-4); }

.map-search-wrap { position: relative; }
.map-search-wrap__icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-muted);
  pointer-events: none;
}
.map-search-input {
  width: 100%;
  height: 40px;
  padding: 0 var(--sp-4) 0 36px;
  border: 1.5px solid var(--border);
  border-radius: var(--r-full);
  font-size: 13.5px;
  font-family: var(--font);
  color: var(--text);
  background: var(--bg);
  outline: none;
  transition: border-color var(--t);
}
.map-search-input::placeholder { color: var(--text-muted); }
.map-search-input:focus { border-color: var(--green); background: var(--surface); }

.map-location-list {
  flex: 1;
  min-height: 0;   /* see .tour-location-list — same flexbox clipping bug */
  overflow-y: auto;
  padding: var(--sp-2) 0;
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
.map-location-list::-webkit-scrollbar       { width: 4px; }
.map-location-list::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

.map-location-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 11px var(--sp-5);
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  transition: background var(--tf);
  border-bottom: 1px solid rgba(0,0,0,0.04);
}
.map-location-item:hover  { background: var(--bg); }
.map-location-item.focus  { background: var(--green-pale); }

.map-location-item__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  border: 2px solid rgba(255,255,255,0.6);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.12);
}
.map-location-item__text { flex: 1; min-width: 0; }
.map-location-item__name {
  display: block;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.map-location-item__type {
  display: block;
  font-size: 11px;
  color: var(--text-muted);
  text-transform: capitalize;
  margin-top: 1px;
}
.map-location-item__arrow { color: var(--border); transition: color var(--t); }
.map-location-item:hover .map-location-item__arrow { color: var(--green); }

/* Map canvas */
.map-canvas-wrap {
  flex: 1;
  position: relative;
  min-width: 0;
}

#campus-map {
  width: 100%;
  height: 100%;
}

/* Map sidebar mobile toggle */
.map-sidebar-toggle {
  display: none;
  position: absolute;
  top: var(--sp-3);
  left: var(--sp-3);
  z-index: 800;
  width: 40px;
  height: 40px;
  border-radius: var(--r);
  background: var(--surface);
  color: var(--text);
  align-items: center;
  justify-content: center;
  box-shadow: var(--sh-md);
  border: 1px solid var(--border);
  transition: background var(--t);
}
.map-sidebar-toggle:hover { background: var(--bg); }

/* ── Leaflet Custom Popup ────────────────────────────────────────────────── */
.leaflet-popup-content-wrapper {
  border-radius: var(--r-md) !important;
  box-shadow: var(--sh-md) !important;
  padding: 0 !important;
  border: 1px solid var(--border) !important;
  overflow: hidden;
}
.leaflet-popup-content { margin: 0 !important; width: auto !important; min-width: 240px; }
.leaflet-popup-tip-container { display: none; }

.map-popup {
  font-family: var(--font);
  padding: var(--sp-5);
  max-width: 280px;
}
.map-popup__badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: var(--r-full);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: capitalize;
  margin-bottom: var(--sp-3);
}
.map-popup__name {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: var(--sp-2);
  line-height: 1.3;
}
.map-popup__desc {
  font-size: 12.5px;
  color: var(--text-muted);
  line-height: 1.6;
  margin-bottom: var(--sp-4);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.map-popup__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  width: 100%;
  padding: 9px;
  background: var(--brand);
  color: var(--white);
  font-size: 13px;
  font-weight: 600;
  border-radius: var(--r-sm);
  text-decoration: none;
  transition: background var(--t);
}
.map-popup__btn:hover { background: var(--brand-md); color: var(--white); }
/* Leaflet's own `.leaflet-container a { color:#0078A8 }` (teal) out-specifies
   `.map-popup__btn`, so the button text read teal until hovered. Pin it white
   in both states with a higher-specificity selector. */
.leaflet-container a.map-popup__btn,
.leaflet-container a.map-popup__btn:hover { color: var(--white); }

/* ── Custom SVG marker ───────────────────────────────────────────────────── */
.custom-marker-icon {
  background: none;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,0.35));
  transition: filter var(--t), transform var(--t);
}
.custom-marker-icon:hover { filter: drop-shadow(0 4px 10px rgba(0,0,0,0.5)); transform: scale(1.1); }

/* ── Map Legend ──────────────────────────────────────────────────────────── */
.map-legend {
  background: var(--surface);
  border-radius: var(--r-md);
  padding: var(--sp-4);
  box-shadow: var(--sh-md);
  border: 1px solid var(--border);
  min-width: 160px;
  font-family: var(--font);
}
/* Server-rendered legend (map.php) sits over the Leaflet canvas, bottom-left. */
.map-legend--static {
  position: absolute;
  left: 12px;
  bottom: 22px;
  z-index: 600;
}
.map-legend__title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--sp-3);
}
.map-legend__item {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: 12.5px;
  color: var(--text);
  margin-bottom: var(--sp-2);
  font-weight: 500;
}
.map-legend__item:last-child { margin-bottom: 0; }
.map-legend__dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  flex-shrink: 0;
  border: 2px solid rgba(255,255,255,0.7);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.10);
}

/* ── Tour / Map Responsive ──────────────────────────────────────────────── */
@media (max-width: 1024px) {
  .tour-info-panel__inner {
    grid-template-columns: 1fr;
    gap: var(--sp-4);
  }
  .tour-info-actions { flex-direction: row; flex-wrap: wrap; }
  .tour-nav-arrows   { flex-direction: row; flex-wrap: wrap; }
  .tour-nav-btn      { max-width: none; flex: 1; }
}

@media (max-width: 768px) {
  /* Tour sidebar: off-canvas overlay */
  .tour-sidebar {
    position: absolute;
    top: 0; left: 0; bottom: 0;
    transform: translateX(-100%);
    box-shadow: var(--sh-lg);
  }
  .tour-sidebar.is-open {
    transform: translateX(0);
  }

  /* Here it does something: the panel is a slide-over, so × dismisses it. */
  .tour-sidebar__close { display: flex; }

  /* ── Overlays vs the open side panel ───────────────────────────────────────
     The panel is z-index 200 while the watermark is 400 and the Tours pill 500,
     and none of them sit in a separate stacking context (.tour-viewer-wrap is
     position:relative with z-index:auto, which does not create one), so both
     painted straight over the open panel.

     Raise the panel above the viewer overlays, then hide the two that sat on top
     of it while it is open — neither is useful with the panel covering the
     panorama. The Tours pill in particular no longer needs to be reachable: the
     header's × button and an outside tap both close the panel. */
  .tour-sidebar { z-index: 600; }

  .tour-sidebar.is-open ~ .tour-main .tour-sidebar-toggle,
  .tour-sidebar.is-open ~ .tour-main .tour-watermark {
    display: none !important;
  }
  .tour-sidebar-toggle { display: flex; }
  .tour-minimap        { width: 160px; }
  #tour-minimap        { height: 100px !important; }

  /* Map sidebar: off-canvas overlay */
  .map-sidebar {
    position: absolute;
    top: 0; left: 0; bottom: 0;
    transform: translateX(-100%);
    box-shadow: var(--sh-lg);
  }
  .map-sidebar.is-open { transform: translateX(0); }
  .map-sidebar-toggle  { display: flex; }
  .map-sidebar__close  { display: flex; }

  /* ── The panel vs the map ──────────────────────────────────────────────────
     Same bug the tour sidebar had. .map-sidebar sits at z-index 200, but
     Leaflet's own panes start at 400 and its control containers sit at 1000 —
     all in the same stacking context — so tapping the hamburger slid the panel
     in *underneath* the map. Only the strip above the map canvas was visible,
     which read as "the button does nothing".

     1100 clears Leaflet's controls as well as its tiles. */
  .map-sidebar { z-index: 1100; }

  /* Nothing overlaying the map is worth keeping on top of an open panel, and
     the toggle in particular would sit over the panel it just opened. The ×
     and an outside tap both close it. */
  .map-sidebar.is-open ~ .map-canvas-wrap .map-sidebar-toggle,
  .map-sidebar.is-open ~ .map-canvas-wrap .map-legend,
  .map-sidebar.is-open ~ .map-canvas-wrap .leaflet-control-container {
    display: none;
  }

  /* ── Leaflet's zoom buttons vs the locations toggle ────────────────────────
     Both live in the map's top-left corner, and Leaflet paints its +/- control
     on top, so below this breakpoint it completely covers the button that opens
     the locations panel. The toggle has to win: it is the only way to reach the
     panel, while zoom has other routes at every pointer type — pinch on touch,
     scroll wheel and double-click with a mouse.

     Deliberately not scoped to (pointer: coarse). A narrow desktop window shows
     the toggle too, so scoping by pointer would keep the buttons there and
     leave that toggle just as unreachable — trading a blocked control for a
     redundant one. */
  #campus-map .leaflet-control-zoom { display: none; }

  /* ── Viewer controls vs the Tours button ───────────────────────────────────
     Both sat at the top-left: .pnlm-controls-container at 12px and
     .tour-sidebar-toggle at 16px with z-index 500, so the Tours pill covered
     the zoom / fullscreen / auto-rotate stack outright.

     The Tours button keeps the corner (it is the primary way back to the scene
     list) and the control stack drops below it. Top-right was not an option —
     .tour-minimap already owns that corner down to 480px.

     Zoom in/out are hidden here: pinch-to-zoom is the native gesture on touch,
     so the buttons were redundant, and removing them shortens the stack to the
     two controls that have no gesture equivalent — fullscreen and auto-rotate
     (the "spin" toggle), which stays reachable rather than buried. */
  /* 64px: the Tours pill ends at ~55px (16 top + 16 padding + 2 border + 20.8
     line box), so this clears it with a small margin rather than sitting flush. */
  .pnlm-ui .pnlm-controls-container { top: 64px !important; left: 12px !important; }
  .pnlm-zoom-controls { display: none !important; }

  /* In fullscreen the Tours pill is not painted at all — it lives outside the
     element that goes fullscreen, and only that element's subtree renders in the
     browser's top layer. The 64px offset therefore left the control stack
     hanging below empty space, with no visible reason for the gap. Put it back
     in the corner while fullscreen is active.
     Written as two separate rules on purpose: an unrecognised pseudo-class in a
     comma-separated selector list invalidates the WHOLE list, so combining the
     standard and -webkit- forms would silently disable both. */
  .pnlm-container:fullscreen .pnlm-controls-container { top: 12px !important; }
  .pnlm-container:-webkit-full-screen .pnlm-controls-container { top: 12px !important; }

  .tour-info-panel__inner { padding: var(--sp-3) var(--sp-4); }
  /* Was 1 line, which showed almost nothing. 2 lines plus the Read more toggle
     reads better and still leaves the panorama the bulk of the screen. */
  .tour-info-desc { -webkit-line-clamp: 2; }
  .tour-info-desc.is-expanded { max-height: 40vh; }
}

@media (max-width: 480px) {
  .tour-minimap { display: none; }
  .tour-nav-arrows { flex-direction: column; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   SPRINT 4 — Chatbot enhancements
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── Typing indicator ────────────────────────────────────────────────────── */
.chatbot-typing {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 11px 16px;
  background: var(--surface);
  border-radius: 4px 12px 12px 12px;
  box-shadow: var(--sh-xs);
  width: fit-content;
}

.chatbot-typing-dot {
  width: 7px;
  height: 7px;
  background: var(--brand);
  border-radius: 50%;
  opacity: 0.55;
  animation: typingBounce 1.3s ease-in-out infinite;
}
.chatbot-typing-dot:nth-child(2) { animation-delay: 0.18s; }
.chatbot-typing-dot:nth-child(3) { animation-delay: 0.36s; }

@keyframes typingBounce {
  0%, 60%, 100% { transform: translateY(0);    opacity: 0.55; }
  30%            { transform: translateY(-7px); opacity: 1;    }
}

/* ── Error bubble ────────────────────────────────────────────────────────── */
.chatbot-msg--error { align-self: flex-start; }
.chatbot-msg--error p {
  background: #fff5f5;
  color: #b91c1c;
  border: 1px solid #fecaca;
  border-radius: 4px 12px 12px 12px;
  box-shadow: none;
}

/* ── Location hint link inside bot bubble ────────────────────────────────── */
.chatbot-location-hint {
  display: inline-block;
  margin-top: 8px;
  padding: 5px 12px;
  background: var(--brand);
  color: var(--white) !important;
  font-size: 12px;
  font-weight: 600;
  border-radius: var(--r-full);
  text-decoration: none;
  transition: background var(--t);
}
.chatbot-location-hint:hover { background: var(--brand-md); color: var(--white) !important; }

/* ── Character counter ─────────────────────────────────────────────────────
   Sits at the right end of the disclaimer row (.chatbot-foot) and fades in
   once the visitor starts typing. It used to be a full-width strip with its
   own borders and rounded bottom corners — leftovers from when it was the last
   element in the panel, which drew a seam across the composer once the
   disclaimer moved below it. */
.chatbot-char-counter {
  min-width: 46px;
  text-align: right;
  font-size: 10px;
  line-height: 1;
  color: var(--text-muted);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t);
}
.chatbot-char-counter.is-visible { opacity: 0.9; }
.chatbot-char-counter--warn { color: #92400e; }
.chatbot-char-counter--over { color: #b91c1c; font-weight: 600; }

/* ── Send button disabled ────────────────────────────────────────────────── */
.chatbot-send-btn:disabled { cursor: not-allowed; }

/* ── Wrapper is-open class for mobile full-screen ────────────────────────── */
@media (max-width: 480px) {
  .chatbot-wrapper.is-open {
    inset: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    flex-direction: column;
    justify-content: flex-end;
  }

  .chatbot-wrapper.is-open #chatbot-window {
    width: 100% !important;
    max-height: 100% !important;
    height: 100dvh;
    border-radius: 0;
    border: none;
    animation: none;
  }

  /* Hide trigger behind the full-screen window */
  .chatbot-wrapper.is-open #chatbot-trigger-btn {
    display: none;
  }
}

/* ════════════════════════════════════════════════════════════════════════════
   SPRINT 6 ADDITIONS
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Skip navigation (accessibility) ───────────────────────────────────────── */
.skip-nav {
  position: absolute;
  top: -100%;
  left: 0;
  padding: 10px 20px;
  background: var(--brand);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  z-index: 9999;
  border-radius: 0 0 var(--r-sm) 0;
  transition: top 0.1s ease;
  text-decoration: none;
}
.skip-nav:focus { top: 0; }

/* ── Page fade-in animation ─────────────────────────────────────────────────── */
@keyframes pageFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* NOTE: keep this opacity-only. A transform on <body> would make it the
   containing block for position:fixed children (navbar, chatbot, back-to-top),
   pinning them to the document bottom instead of the viewport. */
.page-fade-in { animation: pageFadeIn 320ms ease both; }

/* ── Back to Top button ─────────────────────────────────────────────────────── */
.back-to-top {
  position: fixed;
  bottom: 100px;
  left: 24px;
  width: 44px;
  height: 44px;
  background: var(--brand);
  color: #fff;
  border: none;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: var(--sh-md);
  z-index: 900;
  transition: background var(--tf), transform var(--tf), box-shadow var(--tf);
  animation: pageFadeIn 220ms ease both;
}
.back-to-top[hidden]     { display: none; }
.back-to-top:hover       { background: var(--brand-lt); transform: translateY(-2px); box-shadow: var(--sh-green); }
.back-to-top:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

/* ── Panorama loading spinner overlay ───────────────────────────────────────── */
.pano-loader {
  position: absolute;
  inset: 0;
  background: var(--brand-dk);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  z-index: 10;
  transition: opacity 0.4s ease;
}
.pano-loader.hidden { opacity: 0; pointer-events: none; }
.pano-spinner {
  width: 44px;
  height: 44px;
  border: 3px solid rgba(255,255,255,0.15);
  border-top-color: var(--gold);
  border-radius: 50%;
  animation: spin 0.85s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.pano-loader__text { color: rgba(255,255,255,0.65); font-size: 13px; font-weight: 500; letter-spacing: 0.5px; }

/* ── Chatbot suggested questions ────────────────────────────────────────────
   Full-width rows rather than wrapped pills. Four questions of four different
   lengths made four differently-sized lozenges down the left edge of a 360px
   panel — a staircase. Equal rows under a quiet caption read as a menu of
   things to tap, which is what they are. */
.chatbot-suggestions {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 2px 0 4px;
}
.chatbot-suggestions::before {
  content: 'Try asking';
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 0 2px 2px;
}
.chatbot-suggestion-pill {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  background: var(--green-pale);
  color: var(--green);
  border: 1px solid var(--border);
  border-radius: 10px;
  font-size: 12px;
  font-weight: 500;
  padding: 8px 12px;
  cursor: pointer;
  transition: background var(--tf), border-color var(--tf), color var(--tf);
  text-align: left;
  line-height: 1.35;
  font-family: var(--font);
}
/* The button's own text is set with textContent, so the chevron has to be a
   pseudo-element or the click handler would have to reach past it. */
.chatbot-suggestion-pill::after {
  content: '\203A';
  font-size: 15px;
  line-height: 1;
  opacity: 0.5;
  flex-shrink: 0;
}
.chatbot-suggestion-pill:hover {
  background: var(--green-pale2);
  border-color: var(--green);
  color: var(--green-dk);
}
.chatbot-suggestion-pill:hover::after { opacity: 0.9; }
.chatbot-suggestion-pill:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 2px;
}

/* ── 404 page ────────────────────────────────────────────────────────────────── */
.error-page {
  min-height: 70vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--sp-20) var(--sp-6);
}
.error-page__code {
  font-size: clamp(5rem, 15vw, 9rem);
  font-weight: 800;
  color: var(--green);
  line-height: 1;
  letter-spacing: -4px;
  margin-bottom: var(--sp-4);
}
.error-page__title  { font-size: 1.6rem; font-weight: 700; color: var(--text); margin-bottom: var(--sp-3); }
.error-page__desc   { color: var(--text-muted); max-width: 460px; margin: 0 auto var(--sp-8); line-height: 1.7; }
.error-page__links  { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }

/* ── Evaluation survey ───────────────────────────────────────────────────────── */
.survey-wrap    { max-width: 780px; margin: 0 auto; padding: var(--sp-10) var(--sp-6) var(--sp-20); }
.survey-intro   { background: var(--green-pale); border-left: 4px solid var(--green); padding: var(--sp-5) var(--sp-6); border-radius: 0 var(--r-sm) var(--r-sm) 0; margin-bottom: var(--sp-8); }
.survey-intro p { color: var(--text); font-size: 14px; line-height: 1.7; }
.criterion-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r); padding: var(--sp-6); margin-bottom: var(--sp-5); box-shadow: var(--sh-xs); }
.criterion-title { font-size: 15px; font-weight: 700; color: var(--green); margin-bottom: var(--sp-2); }
.criterion-desc  { font-size: 12.5px; color: var(--text-muted); margin-bottom: var(--sp-5); }
.likert-question { margin-bottom: var(--sp-5); }
.likert-question:last-child { margin-bottom: 0; }
.likert-question__text { font-size: 13.5px; color: var(--text); margin-bottom: var(--sp-3); font-weight: 500; }
.likert-scale { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.likert-option { position: relative; }
.likert-option input[type="radio"] { position: absolute; opacity: 0; width: 0; height: 0; }
.likert-option label {
  display: block;
  padding: 8px 4px;
  border: 1.5px solid var(--border);
  border-radius: var(--r-sm);
  font-size: 12px;
  font-weight: 500;
  text-align: center;
  cursor: pointer;
  transition: background var(--tf), border-color var(--tf), color var(--tf);
  line-height: 1.3;
  color: var(--text-muted);
}
.likert-option input:checked + label {
  background: var(--brand);
  border-color: var(--green);
  color: #fff;
}
.likert-option label:hover { border-color: var(--green); color: var(--green); }
.likert-option input:focus-visible + label { outline: 2px solid var(--green); outline-offset: 2px; }
.likert-label-row { display: grid; grid-template-columns: repeat(4,1fr); gap: 8px; margin-bottom: 4px; }
.likert-label-row span { font-size: 10.5px; color: var(--text-muted); text-align: center; }

/* Survey results */
.result-score--1 { color: #dc2626; }
.result-score--2 { color: #b45309; }
.result-score--3 { color: #1565c0; }
.result-score--4 { color: #166534; }

/* ── Pannellum hotspot markers — tour_route.php public viewer ─────────────── */
.pnlm-hotspot.pnlm-hotspot-info,
.pnlm-hotspot.pnlm-hotspot-navigation,
.pnlm-hotspot.pnlm-hotspot-media {
  background-image: none !important;
  border: 3px solid rgba(255,255,255,.9) !important;
  border-radius: 50% !important;
  width: 32px !important;
  height: 32px !important;
  box-shadow: 0 2px 8px rgba(0,0,0,.55) !important;
  cursor: pointer !important;
}
.pnlm-hotspot.pnlm-hotspot-info        { background-color: #1a5c2a !important; }
.pnlm-hotspot.pnlm-hotspot-navigation  { background-color: #1565c0 !important; }
.pnlm-hotspot.pnlm-hotspot-media       { background-color: #c62828 !important; }
/* NOTE: the hotspot icon is injected as a <span> by tour.php's createTooltipFunc.
   Do NOT add a ::after { content } here — it would render a second, doubled icon. */
.pnlm-hotspot.pnlm-hotspot-info:hover,
.pnlm-hotspot.pnlm-hotspot-navigation:hover,
.pnlm-hotspot.pnlm-hotspot-media:hover { border-color: #f5c400 !important; }

/* ── Survey invitation popup ─────────────────────────────────────────────────
   Admin-controlled interstitial. Rendered by includes/footer.php, driven by the
   SurveyPopup module in main.js. Hidden via [hidden]; fades in on .is-open. */
.survey-popup {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  opacity: 0;
  pointer-events: none;             /* don't intercept clicks until open */
  transition: opacity var(--t, 0.2s) ease;
}
.survey-popup[hidden] { display: none; }   /* the [hidden] attribute must win over display:flex */
.survey-popup.is-open { opacity: 1; pointer-events: auto; }
.survey-popup__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 30, 20, 0.55);
  backdrop-filter: blur(2px);
}
.survey-popup__card {
  position: relative;
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: var(--sp-8) var(--sp-6) var(--sp-6);
  text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
  transform: translateY(12px) scale(0.98);
  transition: transform var(--t, 0.2s) ease;
}
.survey-popup.is-open .survey-popup__card { transform: translateY(0) scale(1); }
.survey-popup__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--text-muted);
  font-size: 15px;
  cursor: pointer;
  transition: background var(--t, 0.2s), color var(--t, 0.2s);
}
.survey-popup__close:hover { background: var(--green-pale); color: var(--green); }
.survey-popup__icon {
  width: 56px;
  height: 56px;
  margin: 0 auto var(--sp-4);
  border-radius: var(--r-full);
  background: var(--green-pale);
  color: var(--green);
  display: flex;
  align-items: center;
  justify-content: center;
}
.survey-popup__title {
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: var(--sp-2);
}
.survey-popup__message {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-muted);
  margin-bottom: var(--sp-6);
}
.survey-popup__actions {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.survey-popup__actions .btn { width: 100%; justify-content: center; }

@media (prefers-reduced-motion: reduce) {
  .survey-popup,
  .survey-popup__card { transition: none; }
}

/* ── Visitor registration popup ──────────────────────────────────────────────
   Landing-page interstitial. Rendered by includes/footer.php (homepage only),
   driven by the RegisterPopup module in main.js. Same fade/scale pattern as the
   survey popup, but carries a small form instead of a single CTA. */
.register-popup {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t, 0.2s) ease;
}
.register-popup[hidden] { display: none; }
.register-popup.is-open { opacity: 1; pointer-events: auto; }
.register-popup__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 30, 20, 0.55);
  backdrop-filter: blur(2px);
}
.register-popup__card {
  position: relative;
  width: 100%;
  max-width: 440px;
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: var(--sp-8) var(--sp-6) var(--sp-6);
  text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
  transform: translateY(12px) scale(0.98);
  transition: transform var(--t, 0.2s) ease;
}
.register-popup.is-open .register-popup__card { transform: translateY(0) scale(1); }
.register-popup__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--text-muted);
  font-size: 15px;
  cursor: pointer;
  transition: background var(--t, 0.2s), color var(--t, 0.2s);
}
.register-popup__close:hover { background: var(--green-pale); color: var(--green); }
.register-popup__icon {
  width: 56px;
  height: 56px;
  margin: 0 auto var(--sp-4);
  border-radius: var(--r-full);
  background: var(--green-pale);
  color: var(--green);
  display: flex;
  align-items: center;
  justify-content: center;
}
.register-popup__title {
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: var(--sp-2);
}
.register-popup__message {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-muted);
  margin-bottom: var(--sp-5);
}
.register-popup__form { text-align: left; }
.register-field { margin-bottom: var(--sp-4); }
.register-field__label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 6px;
}
.register-field__input {
  width: 100%;
  padding: 11px 13px;
  font-size: 14px;
  font-family: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1.5px solid var(--border, #e2e5e9);
  border-radius: var(--r-sm, 8px);
  transition: border-color var(--t, 0.2s), box-shadow var(--t, 0.2s);
}
.register-field__input:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 3px var(--green-pale);
}
.register-popup__error {
  font-size: 13px;
  color: #c0392b;
  margin: calc(-1 * var(--sp-2)) 0 var(--sp-3);
}
.register-popup__disclaimer {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-muted);
  background: var(--bg-alt, #f8f9fa);
  border-radius: var(--r-sm, 8px);
  padding: 10px 12px;
  margin-bottom: var(--sp-5);
}
.register-popup__disclaimer svg { flex-shrink: 0; margin-top: 2px; color: var(--green); }
.register-popup__actions {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.register-popup__actions .btn { width: 100%; justify-content: center; }

@media (prefers-reduced-motion: reduce) {
  .register-popup,
  .register-popup__card { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   REPORT A PROBLEM (tour.php)
   Deliberately built on the registration popup's shape and its .register-field
   inputs: both are "a short form in a card", and giving the visitor a second
   dialog that looks unlike the first would read as a different site.
══════════════════════════════════════════════════════════════════════════════ */
.report-popup {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t, 0.2s) ease;
}
.report-popup[hidden] { display: none; }   /* the attribute must win over display:flex */
.report-popup.is-open { opacity: 1; pointer-events: auto; }
.report-popup__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 30, 20, 0.55);
  backdrop-filter: blur(2px);
}
.report-popup__card {
  position: relative;
  width: 100%;
  max-width: 460px;
  max-height: calc(100vh - var(--sp-8));
  overflow-y: auto;
  background: var(--surface);
  border-radius: var(--r-lg);
  padding: var(--sp-8) var(--sp-6) var(--sp-6);
  text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
  transform: translateY(12px) scale(0.98);
  transition: transform var(--t, 0.2s) ease;
}
.report-popup.is-open .report-popup__card { transform: translateY(0) scale(1); }
.report-popup__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--text-muted);
  font-size: 15px;
  cursor: pointer;
  transition: background var(--t, 0.2s), color var(--t, 0.2s);
}
.report-popup__close:hover { background: var(--green-pale); color: var(--green); }
.report-popup__icon {
  width: 56px;
  height: 56px;
  margin: 0 auto var(--sp-4);
  border-radius: var(--r-full);
  background: var(--gold-pale);
  color: var(--gold-dk);
  display: flex;
  align-items: center;
  justify-content: center;
}
.report-popup__title {
  font-size: 20px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: var(--sp-2);
}
.report-popup__message {
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-muted);
  margin-bottom: var(--sp-5);
}
.report-popup__form { text-align: left; }

/* Honeypot. Removed from the layout without display:none, which some bots
   check for — and hidden from assistive tech by aria-hidden on the wrapper. */
.report-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.report-textarea {
  min-height: 96px;
  resize: vertical;
  font-family: inherit;
  line-height: 1.55;
}
.report-count {
  display: block;
  margin-top: 4px;
  text-align: right;
  font-size: 11.5px;
  color: var(--text-muted);
}
.report-optional { font-weight: 400; color: var(--text-muted); }

.report-popup__done { text-align: center; }
.report-popup__done p {
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--text-muted);
  margin-bottom: var(--sp-5);
}
.report-popup__done-icon {
  width: 56px;
  height: 56px;
  margin: 0 auto var(--sp-4);
  border-radius: var(--r-full);
  background: var(--green-pale);
  color: var(--green);
  display: flex;
  align-items: center;
  justify-content: center;
}

@media (prefers-reduced-motion: reduce) {
  .report-popup,
  .report-popup__card { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   LEGAL DOCUMENT (privacy notice)
══════════════════════════════════════════════════════════════════════════════ */
.legal-doc {
  max-width: 780px;
  margin: 0 auto;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-10) var(--sp-8);
  box-shadow: var(--sh-sm);
  line-height: 1.75;
}
.legal-doc h3 {
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--green);
  margin: var(--sp-8) 0 var(--sp-3);
}
.legal-doc h3:first-of-type { margin-top: 0; }
.legal-doc p  { color: var(--text-muted); margin-bottom: var(--sp-4); }
.legal-doc ul { margin: 0 0 var(--sp-4) var(--sp-6); color: var(--text-muted); }
.legal-doc li { margin-bottom: var(--sp-2); }
.legal-doc strong { color: var(--text); font-weight: 600; }
.legal-doc a { color: var(--green); font-weight: 500; }

.legal-doc__updated {
  font-size: 13px;
  color: var(--text-muted);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--sp-6);
}
.legal-doc__footnote {
  font-size: 13px;
  font-style: italic;
  padding-top: var(--sp-6);
  border-top: 1px solid var(--border);
  margin-top: var(--sp-8);
}

/* Highlighted aside inside the document */
.legal-callout {
  background: var(--bg-alt);
  border-left: 3px solid var(--green);
  border-radius: 0 8px 8px 0;
  padding: var(--sp-4) var(--sp-5);
}
.legal-callout--warn { border-left-color: var(--gold); }

/* Wide tables scroll on their own instead of the page */
.legal-table-wrap {
  overflow-x: auto;
  margin-bottom: var(--sp-5);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.legal-table { width: 100%; min-width: 520px; border-collapse: collapse; font-size: 14px; }
.legal-table th {
  text-align: left;
  font-weight: 600;
  color: var(--text);
  background: var(--bg-alt);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border);
}
.legal-table td {
  color: var(--text-muted);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.legal-table tr:last-child td { border-bottom: none; }

@media (max-width: 768px) {
  .legal-doc { padding: var(--sp-6) var(--sp-5); }
}

/* Consent tick inside the visitor registration popup */
.register-field--consent { margin-top: var(--sp-1); }
.register-consent {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  cursor: pointer;
  text-align: left;
}
.register-consent__box {
  flex-shrink: 0;
  width: 17px; height: 17px;
  margin-top: 2px;
  accent-color: var(--green);
  cursor: pointer;
}
.register-consent__text { font-size: 12.5px; line-height: 1.55; color: var(--text-muted); }
.register-consent__text a { color: var(--green); font-weight: 600; text-decoration: underline; }

.tour-panorama {
  width: 100%;
  height: 100%;
  display: block;
}
/* Hotspots hidden via the top-left toggle button — see main.js/tour.php */
.hotspots-hidden .pnlm-hotspot {
  display: none !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   DARK MODE
   Applied by the inline bootstrap in includes/header.php (before first paint)
   and toggled by #theme-toggle in main.js. Only tokens are redefined here —
   --white deliberately stays literal white, because it is the text colour on
   green surfaces which keep their brand colour in both themes.
   ══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="dark"] {
  --surface:      #16201a;
  --surface-alt:  #1b2620;
  --bg:           #0f1713;
  --bg-alt:       #141d18;
  --text:         #e8efe9;
  --text-muted:   #9bb0a2;
  --border:       #26332b;
  --border-lt:    rgba(255,255,255,0.10);

  /* Brand surfaces dim ~22% so the hero and green buttons settle into the dark
     palette instead of glowing against it. Same hue, lower value — still
     recognisably CLSU green, just not lit up. */
  --brand-dk:     #0c2b14;
  --brand:        #103a1a;
  --brand-md:     #12421e;
  --brand-lt:     #1c562c;
  --brand-xl:     #246437;

  /* Greens lift for TEXT contrast on a dark ground — the inverse of the
     surfaces above, which is why the two are separate tokens. */
  --green:        #4caf6a;
  --green-dk:     #3d9a58;
  --green-md:     #55bb75;
  --green-lt:     #66c985;
  --green-pale:   rgba(70,184,102,0.12);
  --green-pale2:  rgba(70,184,102,0.20);

  --c-academic:       #4caf6a;
  --c-administrative: #5a9ded;
  --c-facility:       #b57ae0;
  --c-landmark:       #e0a44a;
  --c-entrance:       #e57373;
  --c-dorm:           #4db6ac;

  --sh-xs: 0 1px 3px rgba(0,0,0,0.40);
  --sh-sm: 0 2px 8px rgba(0,0,0,0.45);
  --sh:    0 4px 16px rgba(0,0,0,0.50);
  --sh-md: 0 8px 28px rgba(0,0,0,0.55);
  --sh-lg: 0 16px 48px rgba(0,0,0,0.60);
}

:root[data-theme="dark"] body { background: var(--bg); color: var(--text); }
/* The error bubble's palette is hard-coded light (#fff5f5 on #fecaca), which
   lands as a white flare in a dark panel. */
:root[data-theme="dark"] .chatbot-msg--error p {
  background: rgba(185,28,28,0.16);
  color: #f0b4b0;
  border-color: rgba(229,115,115,0.34);
}
/* Same story for the counter's warning states — both are dark inks meant for a
   white composer. */
:root[data-theme="dark"] .chatbot-char-counter--warn { color: #e0a44a; }
:root[data-theme="dark"] .chatbot-char-counter--over { color: #e57373; }

/* Surfaces that were painted with a literal white or a light grey */
:root[data-theme="dark"] .navbar:not(.navbar--hero),
:root[data-theme="dark"] .navbar.scrolled { background: var(--surface); }
:root[data-theme="dark"] img:not([src*=".svg"]) { filter: brightness(0.94); }
:root[data-theme="dark"] .form-control,
:root[data-theme="dark"] input[type="search"],
:root[data-theme="dark"] input[type="text"],
:root[data-theme="dark"] textarea,
:root[data-theme="dark"] select {
  background: var(--surface-alt);
  color: var(--text);
  border-color: var(--border);
}
:root[data-theme="dark"] ::placeholder { color: var(--text-muted); }

/* Leaflet renders its own light chrome */
:root[data-theme="dark"] .leaflet-tile { filter: brightness(0.78) contrast(1.06); }
:root[data-theme="dark"] .leaflet-popup-content-wrapper,
:root[data-theme="dark"] .leaflet-popup-tip { background: var(--surface); color: var(--text); }

/* ── Header quick search ───────────────────────────────────────────────── */
/* Search + theme toggle + CTA form one utility cluster on the right. The
   .nav-menu gap is only 4px, which is right for text links (their padding
   supplies the visual gap) but leaves these padding-less controls crowded, so
   they carry their own margins. All three are 36px tall so the cluster reads
   as one row rather than three mismatched shapes. */
.nav-search-li { margin-left: var(--sp-4); }
.nav-theme-li  { margin-left: var(--sp-2); }
.nav-search { position: relative; display: flex; align-items: center; }

.nav-search__icon {
  position: absolute; left: 10px; color: var(--text-muted); pointer-events: none;
}
.nav-search__input {
  width: 190px; height: 36px; padding: 0 30px 0 32px; box-sizing: border-box;
  font-family: var(--font); font-size: 13.5px; color: var(--text);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 999px; outline: none;
  transition: width 0.22s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.nav-search__input:focus {
  width: 240px; border-color: var(--green-lt);
  box-shadow: 0 0 0 3px var(--green-pale);
}
.nav-search__input::-webkit-search-cancel-button { display: none; }

/* On hero pages the navbar is transparent over a photo — the default white-on-
   white input would vanish, so it gets a translucent treatment until scrolled. */
.navbar--hero:not(.scrolled) .nav-search__input {
  background: rgba(255,255,255,0.14);
  border-color: var(--border-lt);
  color: var(--white);
}
.navbar--hero:not(.scrolled) .nav-search__input::placeholder { color: rgba(255,255,255,0.72); }
.navbar--hero:not(.scrolled) .nav-search__icon { color: rgba(255,255,255,0.8); }

.nav-search__clear {
  position: absolute; right: 8px; display: grid; place-items: center;
  width: 20px; height: 20px; padding: 0;
  background: none; border: 0; border-radius: 50%;
  color: var(--text-muted); cursor: pointer;
}
.nav-search__clear:hover { background: var(--bg-alt); color: var(--text); }
/* `display: grid` above outranks the [hidden] attribute, which would otherwise
   leave the clear button visible over an empty search box. */
.nav-search__clear[hidden] { display: none; }
.nav-search__results[hidden] { display: none; }

.nav-search__results {
  position: absolute; top: calc(100% + 8px); left: 0;
  width: 300px; max-height: 340px; overflow-y: auto;
  margin: 0; padding: 6px; list-style: none;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: var(--sh-md); z-index: 1200;
}
.nav-search__row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 10px; border-radius: 6px;
  font-size: 13.5px; color: var(--text); text-decoration: none;
}
.nav-search__row:hover, .nav-search__row.is-active { background: var(--green-pale); }
.nav-search__name { font-weight: 500; }
.nav-search__name mark {
  background: var(--gold-pale); color: inherit; font-weight: 700; padding: 0 1px;
}
.nav-search__type {
  flex-shrink: 0; font-size: 10.5px; font-weight: 600; text-transform: capitalize;
  letter-spacing: 0.3px; color: var(--text-muted);
}
.nav-search__empty {
  padding: 12px 10px; font-size: 13px; color: var(--text-muted); text-align: center;
}

/* ── Dark mode toggle ──────────────────────────────────────────────────── */
.nav-theme-btn {
  display: grid; place-items: center;
  width: 36px; height: 36px; padding: 0; box-sizing: border-box;
  background: none; border: 1px solid var(--border);
  border-radius: 50%; color: var(--text-muted); cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
.nav-theme-btn:hover { color: var(--green); border-color: var(--green-lt); background: var(--green-pale); }
.navbar--hero:not(.scrolled) .nav-theme-btn { color: var(--white); border-color: var(--border-lt); }

.nav-theme-icons { position: relative; display: block; width: 18px; height: 18px; flex-shrink: 0; }
.nav-theme-icon { position: absolute; inset: 0; transition: opacity 0.18s ease, transform 0.25s ease; }
.nav-theme-text { display: none; }
.nav-theme-icon--moon { opacity: 0; transform: rotate(-45deg) scale(0.7); }
.nav-theme-icon--sun  { opacity: 1; transform: none; }
:root[data-theme="dark"] .nav-theme-icon--sun  { opacity: 0; transform: rotate(45deg) scale(0.7); }
:root[data-theme="dark"] .nav-theme-icon--moon { opacity: 1; transform: none; }
.nav-theme-li { display: flex; align-items: center; }

@media (max-width: 1024px) {
  .nav-search__input { width: 150px; }
  .nav-search__input:focus { width: 180px; }
}
@media (max-width: 768px) {
  /* The menu stacks vertically here, so the cluster margins that space these
     out on a horizontal bar would just indent them. */
  .nav-search-li { width: 100%; margin-left: 0; order: -1; margin-bottom: var(--sp-2); }
  .nav-theme-li  { width: 100%; margin-left: 0; }
  .nav-search { width: 100%; }
  .nav-search__input, .nav-search__input:focus { width: 100%; height: 40px; }
  .nav-search__results { width: 100%; max-height: 260px; }

  /* A 36px circle alone in a column of full-width rows reads as a stray dot.
     Give it the same shape and rhythm as a nav link, with a text label. */
  .nav-theme-btn {
    width: 100%; height: auto;
    /* Label left, icon right: the text then lines up with the nav links above
       it instead of being pushed in by the icon's width. */
    justify-content: space-between; gap: 12px;
    padding: 11px 14px;
    border: 0; border-radius: var(--r-xs);
    color: rgba(255,255,255,0.85);
    font-family: var(--font); font-size: 15px; font-weight: 500;
    display: flex; align-items: center;
  }
  .nav-theme-btn:hover { background: rgba(255,255,255,0.10); color: var(--white); border: 0; }
  .nav-theme-text { display: inline; }
  .nav-theme-icons { order: 2; }

  /* .nav-cta is inline-flex, so `align-items: stretch` on the column does not
     widen it — it stayed shrink-wrapped while every other row was full width. */
  .nav-cta { display: flex; width: 100%; height: 42px; }
}

/* ── Tour controls tutorial ────────────────────────────────────────────────
   Sits inside .tour-viewer-wrap so it covers the panorama only, not the whole
   page — the scene list stays usable behind it. */
.tour-tutorial {
  position: absolute; inset: 0; z-index: 900;
  display: grid; place-items: center;
  padding: var(--sp-5);
  background: rgba(9,15,11,0.72);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
.tour-tutorial[hidden] { display: none; }

.tour-tutorial__panel {
  position: relative;
  width: min(480px, 100%); max-height: 100%; overflow-y: auto;
  padding: var(--sp-6);
  background: var(--surface); color: var(--text);
  border-radius: 12px; box-shadow: var(--sh-lg);
}
.tour-tutorial__title {
  margin: 0 34px 6px 0; font-size: 20px; font-weight: 700; color: var(--green);
}
.tour-tutorial__lede {
  margin: 0 0 var(--sp-5); font-size: 13.5px; line-height: 1.5; color: var(--text-muted);
}
.tour-tutorial__list { margin: 0 0 var(--sp-5); padding: 0; list-style: none; }
.tour-tutorial__item {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  padding: var(--sp-3) 0; border-top: 1px solid var(--border);
}
.tour-tutorial__item:first-child { border-top: 0; padding-top: 0; }
/* Deliberately identical to a live .pnlm-controls button — same dark chip, same
   1px translucent border, same white glyph — so a row reads as "this button",
   not as decoration. Uniform across every row; no per-row accent colours. */
.tour-tutorial__key {
  flex-shrink: 0; display: grid; place-items: center;
  width: 28px; height: 28px;
  background: rgba(15,26,20,0.75);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 3px;
  color: rgba(255,255,255,0.92);
}
.tour-tutorial__key svg,
.tour-tutorial__key img { width: 15px; height: 15px; }

.tour-tutorial__close {
  position: absolute; top: 10px; right: 10px;
  display: grid; place-items: center;
  width: 30px; height: 30px; padding: 0;
  background: none; border: 0; border-radius: 50%;
  color: var(--text-muted); cursor: pointer;
}
.tour-tutorial__close:hover { background: var(--bg-alt); color: var(--text); }
.tour-tutorial__text { display: flex; flex-direction: column; gap: 2px; }
.tour-tutorial__text strong { font-size: 14px; font-weight: 600; }
.tour-tutorial__desc { font-size: 12.5px; line-height: 1.45; color: var(--text-muted); }
.tour-tutorial__dismiss { width: 100%; }

/* Input-specific wording: only one of the two lines is ever shown. */
.tour-tutorial__desc--touch { display: none; }
@media (hover: none) and (pointer: coarse) {
  .tour-tutorial__desc--pointer { display: none; }
  .tour-tutorial__desc--touch   { display: block; }
}
/* The zoom buttons are hidden at this breakpoint, so drop the row that
   explains them rather than describing a control that is not on screen. */
@media (max-width: 768px) {
  .tour-tutorial__item--pointer-only { display: none; }
  .tour-tutorial__panel { padding: var(--sp-5); }
  .tour-tutorial__title { font-size: 18px; }
}

/* Help button — replays the tutorial. Same box as the auto-rotate control
   (26×26 content-box + the 1px .pnlm-controls border) so the stack stays
   aligned, and the glyph is a fully percent-encoded data URI because the
   .pnlm-controls `background` shorthand wipes anything less specific. */
.pnlm-help-btn {
  width: 26px !important;
  height: 26px !important;
  box-sizing: content-box !important;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'16'%20height%3D'16'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'%23fff'%20stroke-width%3D'2.2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Ccircle%20cx%3D'12'%20cy%3D'12'%20r%3D'9'%2F%3E%3Cpath%20d%3D'M9.4%209.3a2.7%202.7%200%201%201%203.8%202.5c-.8.4-1.2%201-1.2%201.9'%2F%3E%3Ccircle%20cx%3D'12'%20cy%3D'16.8'%20r%3D'1'%20fill%3D'%23fff'%20stroke%3D'none'%2F%3E%3C%2Fsvg%3E") !important;
  background-position: center center !important;
  background-repeat: no-repeat !important;
  background-size: 15px 15px !important;
}
.pnlm-help-btn:hover { border-color: rgba(245,196,0,0.65) !important; }
