/* Google Fonts for human design personality (May 2026) */
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=Caveat:wght@400;700&display=swap');

/* ═══════════════════════════════════════════════════════════════════
   ███  MATERIAL 3 DESIGN SYSTEM (May 2026 rebrand A-F)  ███
   ═══════════════════════════════════════════════════════════════════
   This is the canonical M3 layer for DormScouter. EVERY new component
   MUST use these tokens — no hard-coded hex/px/shadow/easing values
   anywhere downstream. Existing --ds-* tokens are aliased to M3 below
   so legacy classes inherit the upgrade without rewrites.

   Includes:
   ─ Tonal palette generated from indigo seed #6366f1 (primary 60)
   ─ M3 type scale (15 styles applied to default elements + utility classes)
   ─ M3 shape scale (corner radii: none/xs/sm/md/lg/xl/full)
   ─ M3 elevation (5 levels via box-shadows)
   ─ M3 motion (easing curves + durations)
   ─ M3 state layers (hover/focus/pressed opacities applied universally)
   ─ Component opt-in classes (.md3-button-*, .md3-card-*, .md3-fab-*, etc.)
   ─ Universal element styling so anything inheriting defaults (admin
     tables, forms, links) gets uplifted automatically.

   Color scheme: indigo primary preserved per user request. Generated
   tonal palette uses HSL approximation of M3's HCT algorithm.

   Going forward (per user 2026-05-02): the site assumes M3 site-wide
   including admin + mod surfaces. No backsteps — never reintroduce
   non-M3 patterns. ═══════════════════════════════════════════════════ */

:root {
  /* ─── Typography fonts (human design personality, May 2026) ─────── */
  --font-serif: 'Playfair Display', Georgia, serif;
  --font-handwritten: 'Caveat', cursive;

  /* ─── Indigo tonal palette (primary) — HSL approx of M3 HCT scale ── */
  --md3-primary-0:   #000000;
  --md3-primary-10:  #1c1052;
  --md3-primary-20:  #312076;
  --md3-primary-30:  #4530a0;
  --md3-primary-40:  #5a40c8;  /* primary-darker action */
  --md3-primary-50:  #6e54e4;
  --md3-primary-60:  #6366f1;  /* PRIMARY (current indigo brand) */
  --md3-primary-70:  #8b8df4;
  --md3-primary-80:  #b1b3f8;
  --md3-primary-90:  #d9dafc;  /* primary-container baseline */
  --md3-primary-95:  #ecedfd;
  --md3-primary-99:  #fbfbff;
  --md3-primary-100: #ffffff;

  /* ─── Secondary palette (slate-indigo for supporting roles) ──── */
  --md3-secondary-10:  #1a1d2e;
  --md3-secondary-20:  #2f334a;
  --md3-secondary-30:  #444866;
  --md3-secondary-40:  #5b5f80;
  --md3-secondary-60:  #8488ad;
  --md3-secondary-80:  #c4c6dd;
  --md3-secondary-90:  #e1e2ee;
  --md3-secondary-95:  #f0f0f7;
  --md3-secondary-99:  #fafafd;

  /* ─── Tertiary palette (amber accent — already used for grades) ── */
  --md3-tertiary-10:  #2d1700;
  --md3-tertiary-20:  #4d2900;
  --md3-tertiary-30:  #6e3c00;
  --md3-tertiary-40:  #8e5100;
  --md3-tertiary-60:  #d97706;  /* amber accent (matches --cat-grade) */
  --md3-tertiary-80:  #f5b862;
  --md3-tertiary-90:  #ffe1b3;
  --md3-tertiary-95:  #fff3df;

  /* ─── Error palette ──────────────────────────────────────────── */
  --md3-error-10:  #410002;
  --md3-error-20:  #690005;
  --md3-error-30:  #93000a;
  --md3-error-40:  #ba1a1a;
  --md3-error-60:  #dc2626;
  --md3-error-80:  #ffb4ab;
  --md3-error-90:  #ffdad6;
  --md3-error-95:  #ffedea;

  /* ─── Neutral palette (surfaces / outlines / text) ───────────── */
  --md3-neutral-10:  #1a1c1e;
  --md3-neutral-20:  #2f3033;
  --md3-neutral-30:  #46474a;
  --md3-neutral-40:  #5e5e62;
  --md3-neutral-50:  #76777a;
  --md3-neutral-60:  #909094;
  --md3-neutral-70:  #aaabae;
  --md3-neutral-80:  #c6c6ca;
  --md3-neutral-90:  #e2e2e6;
  --md3-neutral-95:  #f1f0f4;
  --md3-neutral-99:  #fcfcff;

  --md3-neutral-variant-30: #44464f;
  --md3-neutral-variant-50: #74767f;
  --md3-neutral-variant-80: #c4c6d0;
  --md3-neutral-variant-90: #e0e1ec;

  /* ─── M3 semantic color roles (light scheme) ─────────────────── */
  --md3-primary:                var(--md3-primary-60);
  --md3-on-primary:             var(--md3-primary-100);
  --md3-primary-container:      var(--md3-primary-90);
  --md3-on-primary-container:   var(--md3-primary-10);

  --md3-secondary:              var(--md3-secondary-40);
  --md3-on-secondary:           #ffffff;
  --md3-secondary-container:    var(--md3-secondary-90);
  --md3-on-secondary-container: var(--md3-secondary-10);

  --md3-tertiary:               var(--md3-tertiary-60);
  --md3-on-tertiary:            #ffffff;
  --md3-tertiary-container:     var(--md3-tertiary-90);
  --md3-on-tertiary-container:  var(--md3-tertiary-10);

  --md3-error:                  var(--md3-error-60);
  --md3-on-error:                #ffffff;
  --md3-error-container:        var(--md3-error-90);
  --md3-on-error-container:     var(--md3-error-10);

  --md3-background:             #fbfbff;
  --md3-on-background:          var(--md3-neutral-10);
  --md3-surface:                #fcfcff;
  --md3-on-surface:             var(--md3-neutral-10);
  --md3-surface-variant:        var(--md3-neutral-variant-90);
  --md3-on-surface-variant:     var(--md3-neutral-variant-30);

  /* M3 surface tints (5 elevation levels — surface gets tinted toward primary) */
  --md3-surface-container-lowest: #ffffff;
  --md3-surface-container-low:    #f5f5fa;
  --md3-surface-container:        #efeff5;
  --md3-surface-container-high:   #e9eaf0;
  --md3-surface-container-highest:#e3e4ea;

  --md3-outline:                var(--md3-neutral-variant-50);
  --md3-outline-variant:        var(--md3-neutral-variant-80);

  --md3-inverse-surface:        var(--md3-neutral-20);
  --md3-on-inverse-surface:     var(--md3-neutral-95);
  --md3-inverse-primary:        var(--md3-primary-80);

  /* ─── M3 type scale ──────────────────────────────────────────── */
  --md3-font-brand: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --md3-font-plain: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* Display (hero) */
  --md3-display-large-size:    3.5625rem;  /* 57px */
  --md3-display-large-line:    4rem;       /* 64px */
  --md3-display-large-weight:  400;
  --md3-display-medium-size:   2.8125rem;  /* 45px */
  --md3-display-medium-line:   3.25rem;
  --md3-display-medium-weight: 400;
  --md3-display-small-size:    2.25rem;    /* 36px */
  --md3-display-small-line:    2.75rem;
  --md3-display-small-weight:  400;

  /* Headline */
  --md3-headline-large-size:   2rem;       /* 32px */
  --md3-headline-large-line:   2.5rem;
  --md3-headline-large-weight: 400;
  --md3-headline-medium-size:  1.75rem;    /* 28px */
  --md3-headline-medium-line:  2.25rem;
  --md3-headline-medium-weight:400;
  --md3-headline-small-size:   1.5rem;     /* 24px */
  --md3-headline-small-line:   2rem;
  --md3-headline-small-weight: 400;

  /* Title */
  --md3-title-large-size:      1.375rem;   /* 22px */
  --md3-title-large-line:      1.75rem;
  --md3-title-large-weight:    500;
  --md3-title-medium-size:     1rem;       /* 16px */
  --md3-title-medium-line:     1.5rem;
  --md3-title-medium-weight:   500;
  --md3-title-small-size:      0.875rem;   /* 14px */
  --md3-title-small-line:      1.25rem;
  --md3-title-small-weight:    500;

  /* Body */
  --md3-body-large-size:       1rem;       /* 16px */
  --md3-body-large-line:       1.5rem;
  --md3-body-large-weight:     400;
  --md3-body-medium-size:      0.875rem;   /* 14px */
  --md3-body-medium-line:      1.25rem;
  --md3-body-medium-weight:    400;
  --md3-body-small-size:       0.75rem;    /* 12px */
  --md3-body-small-line:       1rem;
  --md3-body-small-weight:     400;

  /* Label */
  --md3-label-large-size:      0.875rem;   /* 14px */
  --md3-label-large-line:      1.25rem;
  --md3-label-large-weight:    500;
  --md3-label-medium-size:     0.75rem;    /* 12px */
  --md3-label-medium-line:     1rem;
  --md3-label-medium-weight:   500;
  --md3-label-small-size:      0.6875rem;  /* 11px */
  --md3-label-small-line:      1rem;
  --md3-label-small-weight:    500;

  /* ─── M3 shape scale ─────────────────────────────────────────── */
  --md3-shape-none:        0;
  --md3-shape-xs:          0.25rem;   /* 4px  */
  --md3-shape-sm:          0.5rem;    /* 8px  */
  --md3-shape-md:          0.75rem;   /* 12px */
  --md3-shape-lg:          1rem;      /* 16px */
  --md3-shape-xl:          1.75rem;   /* 28px */
  --md3-shape-full:        999px;

  /* ─── M3 elevation (5 levels — neutral shadow tinted with primary) */
  --md3-elev-0:  none;
  --md3-elev-1:  0 1px 2px rgba(28, 16, 82, .12), 0 1px 3px 1px rgba(28, 16, 82, .08);
  --md3-elev-2:  0 1px 2px rgba(28, 16, 82, .15), 0 2px 6px 2px rgba(28, 16, 82, .10);
  --md3-elev-3:  0 4px 8px 3px rgba(28, 16, 82, .12), 0 1px 3px rgba(28, 16, 82, .15);
  --md3-elev-4:  0 6px 10px 4px rgba(28, 16, 82, .14), 0 2px 3px rgba(28, 16, 82, .15);
  --md3-elev-5:  0 8px 12px 6px rgba(28, 16, 82, .15), 0 4px 4px rgba(28, 16, 82, .18);

  /* ─── M3 motion ──────────────────────────────────────────────── */
  --md3-motion-emphasized:           cubic-bezier(.2, 0, 0, 1);
  --md3-motion-emphasized-decelerate:cubic-bezier(.05, .7, .1, 1);
  --md3-motion-emphasized-accelerate:cubic-bezier(.3, 0, .8, .15);
  --md3-motion-standard:             cubic-bezier(.2, 0, 0, 1);
  --md3-motion-standard-decelerate:  cubic-bezier(0, 0, 0, 1);
  --md3-motion-standard-accelerate:  cubic-bezier(.3, 0, 1, 1);
  --md3-dur-short-1:    50ms;
  --md3-dur-short-2:    100ms;
  --md3-dur-short-3:    150ms;
  --md3-dur-short-4:    200ms;
  --md3-dur-medium-1:   250ms;
  --md3-dur-medium-2:   300ms;
  --md3-dur-medium-3:   350ms;
  --md3-dur-medium-4:   400ms;
  --md3-dur-long-1:     450ms;
  --md3-dur-long-2:     500ms;

  /* ─── M3 state-layer opacities ───────────────────────────────── */
  --md3-state-hover:    0.08;
  --md3-state-focus:    0.12;
  --md3-state-pressed:  0.12;
  --md3-state-dragged:  0.16;

  /* ─── Per-college color scheme overrides (May 2026) ─────────────
     These are populated by JS when a college page loads, allowing
     each college's branding to personalize the page while maintaining
     accessibility and M3 system consistency. Defaults to M3 primary.
     Only applied inside #view-college to keep home page isolated. ─── */
  --college-primary:               var(--md3-primary-60);
  --college-primary-container:     var(--md3-primary-90);
  --college-on-primary:            var(--md3-primary-100);
  --college-on-primary-container:  var(--md3-primary-10);
}

/* ─── Backward-compat: alias the legacy --ds-* tokens onto M3 roles
       so every existing class flows through the new system without a
       rewrite. ─────────────────────────────────────────────────── */
:root {
  --ds-bg:            var(--md3-background);
  --ds-bg-elevated:   var(--md3-surface-container-lowest);
  --ds-text:          var(--md3-on-surface);
  --ds-text-muted:    var(--md3-on-surface-variant);
  --ds-border:        var(--md3-outline-variant);
  --ds-hover-bg:      var(--md3-surface-container-low);
  --ds-input-bg:      var(--md3-surface-container-lowest);
  --ds-input-border:  var(--md3-outline);
  --ds-shadow:        var(--md3-elev-1);
}

/* ═══ M3 Universal element styling ═══════════════════════════════
   Default semantics for every page so admin tables, forms, blog,
   server-rendered pages, etc., all consume the M3 type scale +
   colors without custom CSS. */

html {
  font-family: var(--md3-font-plain);
  color: var(--md3-on-surface);
  background: var(--md3-background);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  font-size: var(--md3-body-large-size);
  line-height: var(--md3-body-large-line);
  font-weight: var(--md3-body-large-weight);
}

h1 { font-size: var(--md3-headline-large-size);  line-height: var(--md3-headline-large-line);  font-weight: var(--md3-headline-large-weight);  letter-spacing: -0.01em; }
h2 { font-size: var(--md3-headline-medium-size); line-height: var(--md3-headline-medium-line); font-weight: var(--md3-headline-medium-weight); letter-spacing: -0.01em; }
h3 { font-size: var(--md3-headline-small-size);  line-height: var(--md3-headline-small-line);  font-weight: var(--md3-headline-small-weight);  }
h4 { font-size: var(--md3-title-large-size);     line-height: var(--md3-title-large-line);     font-weight: var(--md3-title-large-weight);     }
h5 { font-size: var(--md3-title-medium-size);    line-height: var(--md3-title-medium-line);    font-weight: var(--md3-title-medium-weight);    }
h6 { font-size: var(--md3-title-small-size);     line-height: var(--md3-title-small-line);     font-weight: var(--md3-title-small-weight);     }

a {
  color: var(--md3-primary);
  text-decoration: none;
  transition: color var(--md3-dur-short-3) var(--md3-motion-standard);
}
a:hover { color: var(--md3-primary-40); text-decoration: underline; }
a:focus-visible {
  outline: 2px solid var(--md3-primary);
  outline-offset: 2px;
  border-radius: var(--md3-shape-xs);
}

/* Universal focus ring on every interactive element — M3 wants visible,
   high-contrast focus states. */
button:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex="0"]:focus-visible {
  outline: 2px solid var(--md3-primary);
  outline-offset: 2px;
}

/* ═══ Per-college color scheme styling (May 2026) =════════════════
   Scoped to #view-college so the home page keeps DormScouter's
   indigo identity. When a college has custom colors, these rules
   apply that college's primary color to accent elements. */

/* hero name stays white-on-photo regardless of college theme color —
   the primary accent is used for stats/buttons below the hero, not
   over the campus photo where dark school colors become unreadable */
/* #view-college[data-college-theme] h1#college-hero-name removed */

#view-college[data-college-theme] .college-stat-val {
  color: var(--college-primary);
}

#view-college[data-college-theme] #college-follow-btn {
  background-color: var(--college-primary);
  border-color: var(--college-primary);
}

#view-college[data-college-theme] #college-follow-btn:hover {
  opacity: 0.85;
}

/* Dorm cards on college pages use college colors for the rating/stars */
#view-college[data-college-theme] .dorm-rating-stars {
  color: var(--college-primary);
}

/* Tab styling on college page */
#view-college[data-college-theme] .tabs .tab.active {
  border-bottom-color: var(--college-primary);
}

#view-college[data-college-theme] .college-hero {
  border-top: 4px solid var(--college-primary);
}

#view-college[data-college-theme] #college-hero-name {
  position: relative;
  padding-bottom: .35rem;
}
#view-college[data-college-theme] #college-hero-name::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 56px;
  height: 4px;
  border-radius: 2px;
  background: var(--college-primary);
  box-shadow: 0 1px 4px rgba(0,0,0,.35);
}

#view-college[data-college-theme] .section-header > div > h2,
#view-college[data-college-theme] > .section-header h2 {
  border-left: 4px solid var(--college-primary);
  padding-left: .65rem;
}

#view-college[data-college-theme] .college-stats-bar {
  border-color: var(--college-primary-container, #e5eaf1);
}

/* ═══ M3 Buttons (filled / tonal / outlined / text / icon) ════════
   Variants live as utility classes. The legacy `.btn`, `.btn-primary`,
   `.btn-secondary`, `.btn-ghost`, `.btn-text` classes are also remapped
   below so existing markup gets the M3 treatment automatically. */

.md3-button {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font-family: var(--md3-font-plain);
  font-size: var(--md3-label-large-size);
  line-height: var(--md3-label-large-line);
  font-weight: var(--md3-label-large-weight);
  letter-spacing: 0.01em;
  border-radius: var(--md3-shape-full);
  padding: .625rem 1.5rem;
  min-height: 40px;
  border: none;
  cursor: pointer;
  transition: background var(--md3-dur-short-3) var(--md3-motion-standard),
              box-shadow var(--md3-dur-short-3) var(--md3-motion-standard),
              color var(--md3-dur-short-3) var(--md3-motion-standard),
              opacity var(--md3-dur-short-3) var(--md3-motion-standard);
  position: relative;
  overflow: hidden;
}
.md3-button:disabled {
  opacity: .38; cursor: not-allowed;
}
.md3-button-filled {
  background: var(--md3-primary); color: var(--md3-on-primary);
}
.md3-button-filled:hover:not(:disabled) {
  box-shadow: var(--md3-elev-1);
  background: linear-gradient(rgba(255,255,255,var(--md3-state-hover)), rgba(255,255,255,var(--md3-state-hover))), var(--md3-primary);
}
.md3-button-filled:active:not(:disabled) {
  background: linear-gradient(rgba(255,255,255,var(--md3-state-pressed)), rgba(255,255,255,var(--md3-state-pressed))), var(--md3-primary);
}
.md3-button-tonal {
  background: var(--md3-secondary-container); color: var(--md3-on-secondary-container);
}
.md3-button-tonal:hover:not(:disabled) {
  box-shadow: var(--md3-elev-1);
  background: linear-gradient(rgba(28,16,82,var(--md3-state-hover)), rgba(28,16,82,var(--md3-state-hover))), var(--md3-secondary-container);
}
.md3-button-outlined {
  background: transparent; color: var(--md3-primary);
  border: 1px solid var(--md3-outline);
}
.md3-button-outlined:hover:not(:disabled) {
  background: rgba(99,102,241, var(--md3-state-hover));
}
.md3-button-text {
  background: transparent; color: var(--md3-primary);
  padding: .625rem 1rem;
}
.md3-button-text:hover:not(:disabled) {
  background: rgba(99,102,241, var(--md3-state-hover));
}
.md3-button-elevated {
  background: var(--md3-surface-container-low); color: var(--md3-primary);
  box-shadow: var(--md3-elev-1);
}
.md3-button-elevated:hover:not(:disabled) {
  box-shadow: var(--md3-elev-2);
}

/* Icon-only buttons */
.md3-icon-button {
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--md3-shape-full);
  background: transparent; color: var(--md3-on-surface-variant);
  border: none; cursor: pointer;
  transition: background var(--md3-dur-short-3) var(--md3-motion-standard);
}
.md3-icon-button:hover:not(:disabled) {
  background: rgba(0,0,0, var(--md3-state-hover));
}

/* ═══ M3 FAB (Floating Action Button) ═══════════════════════════ */
.md3-fab {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  height: 56px; min-width: 56px; padding: 0 1rem;
  background: var(--md3-primary-container); color: var(--md3-on-primary-container);
  border: none; border-radius: var(--md3-shape-lg);
  box-shadow: var(--md3-elev-3);
  cursor: pointer; font-family: var(--md3-font-plain);
  font-size: var(--md3-label-large-size); font-weight: var(--md3-label-large-weight);
  transition: box-shadow var(--md3-dur-short-3) var(--md3-motion-standard),
              transform var(--md3-dur-short-3) var(--md3-motion-standard);
}
.md3-fab:hover { box-shadow: var(--md3-elev-4); }
.md3-fab:active { box-shadow: var(--md3-elev-3); }
.md3-fab.md3-fab-small  { height: 44px; min-width: 44px; border-radius: var(--md3-shape-md); }
.md3-fab.md3-fab-large  { height: 96px; min-width: 96px; border-radius: var(--md3-shape-xl); }
.md3-fab.md3-fab-extended { padding: 0 1rem 0 1.25rem; min-width: 80px; }
.md3-fab.md3-fab-primary {
  background: var(--md3-primary); color: var(--md3-on-primary);
}

/* ═══ M3 Cards (elevated / filled / outlined) ═════════════════════ */
.md3-card {
  background: var(--md3-surface-container-lowest);
  color: var(--md3-on-surface);
  border-radius: var(--md3-shape-md);
  padding: 1rem;
}
.md3-card-elevated {
  background: var(--md3-surface-container-low);
  box-shadow: var(--md3-elev-1);
  transition: box-shadow var(--md3-dur-short-3) var(--md3-motion-standard);
}
.md3-card-elevated:hover { box-shadow: var(--md3-elev-2); }
.md3-card-filled {
  background: var(--md3-surface-container-highest);
}
.md3-card-outlined {
  background: var(--md3-surface);
  border: 1px solid var(--md3-outline-variant);
}

/* ═══ M3 Chips (filter / suggestion / input / assist) ═════════════ */
.md3-chip {
  display: inline-flex; align-items: center; gap: .375rem;
  height: 32px; padding: 0 1rem;
  background: var(--md3-surface);
  color: var(--md3-on-surface-variant);
  border: 1px solid var(--md3-outline);
  border-radius: var(--md3-shape-sm);
  font-size: var(--md3-label-large-size); font-weight: var(--md3-label-large-weight);
  cursor: pointer; user-select: none;
  transition: background var(--md3-dur-short-3) var(--md3-motion-standard),
              border-color var(--md3-dur-short-3) var(--md3-motion-standard),
              color var(--md3-dur-short-3) var(--md3-motion-standard);
}
.md3-chip:hover { background: rgba(0,0,0, var(--md3-state-hover)); }
.md3-chip.selected, .md3-chip[aria-selected="true"] {
  background: var(--md3-secondary-container);
  color: var(--md3-on-secondary-container);
  border-color: transparent;
}
.md3-chip-assist  { /* default */ }
.md3-chip-input   { padding-right: .5rem; }
.md3-chip-suggestion { /* default */ }

/* ═══ M3 Text fields (filled — the M3 default) ════════════════════ */
.md3-textfield {
  position: relative; display: block; margin-bottom: .75rem;
}
.md3-textfield-input {
  width: 100%; height: 56px; padding: 1.5rem .75rem .25rem;
  background: var(--md3-surface-container-highest);
  color: var(--md3-on-surface);
  border: none; border-bottom: 1px solid var(--md3-on-surface-variant);
  border-radius: var(--md3-shape-xs) var(--md3-shape-xs) 0 0;
  font-family: var(--md3-font-plain);
  font-size: var(--md3-body-large-size);
  transition: border-color var(--md3-dur-short-3) var(--md3-motion-standard),
              border-bottom-width var(--md3-dur-short-3) var(--md3-motion-standard);
}
.md3-textfield-input:hover  { border-bottom-color: var(--md3-on-surface); }
.md3-textfield-input:focus  { border-bottom-color: var(--md3-primary); border-bottom-width: 2px; outline: none; }

/* ═══ M3 Dialog / modal ════════════════════════════════════════════ */
.md3-dialog {
  background: var(--md3-surface-container-high);
  color: var(--md3-on-surface);
  border-radius: var(--md3-shape-xl);
  padding: 1.5rem;
  box-shadow: var(--md3-elev-3);
  max-width: 560px;
}
.md3-dialog-headline {
  font-size: var(--md3-headline-small-size);
  line-height: var(--md3-headline-small-line);
  margin: 0 0 1rem;
}
.md3-dialog-content {
  font-size: var(--md3-body-medium-size);
  line-height: var(--md3-body-medium-line);
  color: var(--md3-on-surface-variant);
}
.md3-dialog-actions {
  display: flex; justify-content: flex-end; gap: .5rem;
  margin-top: 1.5rem;
}

/* ═══ M3 Top app bar ════════════════════════════════════════════ */
.md3-top-app-bar {
  display: flex; align-items: center; gap: 1rem;
  height: 64px; padding: 0 1rem;
  background: var(--md3-surface);
  color: var(--md3-on-surface);
}
.md3-top-app-bar-headline {
  flex: 1;
  font-size: var(--md3-title-large-size);
  font-weight: var(--md3-title-large-weight);
}

/* ═══ M3 Tabs (primary) ═══════════════════════════════════════════ */
.md3-tabs {
  display: flex; gap: 0;
  background: var(--md3-surface);
  border-bottom: 1px solid var(--md3-outline-variant);
  overflow-x: auto;
}
.md3-tab {
  flex: 1; min-width: 90px;
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  height: 48px; padding: 0 1rem;
  background: transparent; border: none; cursor: pointer;
  font-family: var(--md3-font-plain);
  font-size: var(--md3-title-small-size); font-weight: var(--md3-title-small-weight);
  color: var(--md3-on-surface-variant);
  border-bottom: 3px solid transparent; margin-bottom: -1px;
  transition: color var(--md3-dur-short-3) var(--md3-motion-standard),
              background var(--md3-dur-short-3) var(--md3-motion-standard);
}
.md3-tab:hover  { color: var(--md3-on-surface); background: rgba(0,0,0, var(--md3-state-hover)); }
.md3-tab.active { color: var(--md3-primary); border-bottom-color: var(--md3-primary); }

/* ═══ M3 Lists ═══════════════════════════════════════════════════ */
.md3-list { display: flex; flex-direction: column; }
.md3-list-item {
  display: flex; align-items: center; gap: 1rem;
  min-height: 56px; padding: .5rem 1rem;
  background: var(--md3-surface);
  color: var(--md3-on-surface);
  cursor: pointer;
  transition: background var(--md3-dur-short-3) var(--md3-motion-standard);
}
.md3-list-item:hover { background: rgba(0,0,0, var(--md3-state-hover)); }
.md3-list-item-leading { flex: 0 0 auto; color: var(--md3-on-surface-variant); }
.md3-list-item-content { flex: 1; }
.md3-list-item-headline { font-size: var(--md3-body-large-size); font-weight: 500; }
.md3-list-item-supporting { font-size: var(--md3-body-medium-size); color: var(--md3-on-surface-variant); }

/* ═══ M3 Snackbar / toast ═══════════════════════════════════════ */
.md3-snackbar {
  position: fixed; bottom: 1rem; left: 50%; transform: translateX(-50%);
  background: var(--md3-inverse-surface); color: var(--md3-on-inverse-surface);
  padding: .875rem 1rem; border-radius: var(--md3-shape-xs);
  box-shadow: var(--md3-elev-3);
  font-size: var(--md3-body-medium-size);
  z-index: 2000;
}

/* ═══ Universal modal close (X) button ═════════════════════════════
   New 44px touch-target close button replacing the cramped .btn-close.
   Used by every modal — surfaces the bigger hit target for mobile and
   M3 icon-button styling site-wide. */
.modal-close-x,
.btn-close {
  position: absolute; top: 0.75rem; right: 0.75rem;
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: none; cursor: pointer;
  border-radius: var(--md3-shape-full);
  font-size: 1.25rem; line-height: 1;
  color: var(--md3-on-surface-variant);
  transition: background var(--md3-dur-short-3) var(--md3-motion-standard);
  z-index: 10;
}
.modal-close-x:hover, .btn-close:hover {
  background: rgba(0,0,0, var(--md3-state-hover));
}
.modal-close-x:focus-visible, .btn-close:focus-visible {
  outline: 2px solid var(--md3-primary); outline-offset: 2px;
}

/* ═══ Admin panel polish under M3 (May 2026) ═══════════════════════
   The M3 token system is already site-wide, but admin-specific surfaces
   benefit from a few targeted refinements: tables get proper outline
   colors + elevation, panel cards consume the surface-container tints,
   and stat-grid cells get rounded corners + the elevation-1 shadow.
   Heavy admin tables (Users, Activity Log, Visitors) inherit these
   automatically via element selectors so admins don't see "old admin /
   new public" mismatch. */
#admin-app table,
.admin-table,
.user-table,
.eatery-table,
.attribution-table,
.dining-halls-table,
.audit-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--md3-surface-container-lowest);
  border: 1px solid var(--md3-outline-variant);
  border-radius: var(--md3-shape-md);
  overflow: hidden;
  box-shadow: var(--md3-elev-1);
  font-size: var(--md3-body-medium-size);
}
#admin-app th,
.admin-table th, .user-table th, .eatery-table th, .audit-table th {
  background: var(--md3-surface-container-high);
  color: var(--md3-on-surface-variant);
  font-weight: 600;
  font-size: var(--md3-label-medium-size);
  text-align: left;
  padding: .65rem .85rem;
  border-bottom: 1px solid var(--md3-outline-variant);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
#admin-app td,
.admin-table td, .user-table td, .eatery-table td, .audit-table td {
  padding: .55rem .85rem;
  border-bottom: 1px solid var(--md3-outline-variant);
  vertical-align: middle;
}
#admin-app tr:last-child td,
.admin-table tr:last-child td { border-bottom: none; }
#admin-app tr:hover td,
.admin-table tr:hover td { background: rgba(99,102,241, var(--md3-state-hover)); }

/* Admin dashboard stat cards — give them proper elevation + shape */
.dash-stat-grid > .dash-stat,
#dash-stats .dash-stat,
.admin-stat-card {
  background: var(--md3-surface-container-lowest);
  border: 1px solid var(--md3-outline-variant);
  border-radius: var(--md3-shape-md);
  box-shadow: var(--md3-elev-1);
}

/* Lightbox tightening — promote to M3 elevation + shape (May 2026) */
.lightbox {
  background: rgba(0, 0, 0, 0.92);
}
.lightbox-img {
  border-radius: var(--md3-shape-md);
  box-shadow: var(--md3-elev-3);
  max-width: 92vw; max-height: 78vh;
}
.lightbox-close,
.lightbox-prev, .lightbox-next {
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, 0.12);
  color: white;
  border: none;
  border-radius: var(--md3-shape-full);
  font-size: 1.5rem; font-weight: 600; cursor: pointer;
  transition: background var(--md3-dur-short-3) var(--md3-motion-standard),
              transform var(--md3-dur-short-3) var(--md3-motion-standard);
}
.lightbox-close:hover,
.lightbox-prev:hover, .lightbox-next:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: scale(1.06);
}

/* Dorm gallery thumb — tighten under M3 (cleaner hover lift) */
.dorm-gallery-thumb {
  border-radius: var(--md3-shape-md);
  transition: transform var(--md3-dur-short-3) var(--md3-motion-standard),
              box-shadow var(--md3-dur-short-3) var(--md3-motion-standard);
  cursor: zoom-in;
}
.dorm-gallery-thumb:hover {
  transform: translateY(-2px);
  box-shadow: var(--md3-elev-2);
}

/* ═══ Correction modal — context-specific mode (May 2026 follow-up) ═
   When the user opens the "Suggest a Change" modal by tapping a per-
   field ✏️ pencil (e.g. on the "Room type" stat card), we already know
   which field they're editing. Hide the field-picker dropdown so the
   modal becomes a focused single-field edit. The breadcrumb at the top
   of the modal surfaces what's being edited. */
[data-correction-context-hide] { display: none !important; }

/* ═══ Correction modal — "Other…" reveal for select widgets ═════════
   When a select widget has options including "Other" and the user picks
   it, the inline fill-in field below appears so they can describe a
   value not in the canonical list. Hidden by default; toggled by the
   updateCorrectionInput() select-change handler. */
.correction-other-fillin {
  margin-top: .5rem;
  width: 100%;
  padding: .5rem .65rem;
  border: 1px solid var(--md3-outline);
  border-radius: var(--md3-shape-xs);
  font-family: inherit;
  font-size: var(--md3-body-medium-size);
  background: var(--md3-surface-container-lowest);
  color: var(--md3-on-surface);
}

/* ═══ Quick Capture scope picker (May 2026 follow-up) ═════════════
   "Whole dorm vs Specific room" toggle below the dorm picker. Big
   tap targets, M3 chip-style. */
.mqc-scope-row {
  display: grid; grid-template-columns: 1fr 1fr; gap: .5rem;
  margin-top: .35rem;
}
.mqc-scope-btn {
  background: var(--md3-surface-container-lowest);
  color: var(--md3-on-surface);
  border: 1.5px solid var(--md3-outline);
  border-radius: var(--md3-shape-md);
  padding: .65rem .75rem;
  cursor: pointer; font-family: inherit;
  display: flex; flex-direction: column; align-items: flex-start; gap: .15rem;
  text-align: left; min-height: 60px;
  font-size: var(--md3-label-large-size); font-weight: 600;
  transition: background var(--md3-dur-short-3) var(--md3-motion-standard),
              border-color var(--md3-dur-short-3) var(--md3-motion-standard),
              color var(--md3-dur-short-3) var(--md3-motion-standard);
}
.mqc-scope-btn:hover {
  background: rgba(99,102,241, var(--md3-state-hover));
  border-color: var(--md3-primary);
}
.mqc-scope-btn.selected {
  background: var(--md3-primary-container);
  color: var(--md3-on-primary-container);
  border-color: var(--md3-primary);
}
.mqc-scope-btn small {
  display: block; font-size: var(--md3-body-small-size);
  font-weight: 400; line-height: 1.3;
  color: var(--md3-on-surface-variant);
  margin-top: .15rem;
}
.mqc-scope-btn.selected small { color: var(--md3-on-primary-container); opacity: .85; }
@media (max-width: 480px) {
  .mqc-scope-row { grid-template-columns: 1fr; }
}

/* ═══ Quick Capture typeahead (May 2026 smoke-test fix) ═══════════ */
.mqc-target-results {
  background: var(--md3-surface-container-low);
  border: 1px solid var(--md3-outline-variant);
  border-radius: var(--md3-shape-sm);
  margin-top: .35rem;
  max-height: 280px; overflow-y: auto;
  box-shadow: var(--md3-elev-1);
}
.mqc-ta-group-label {
  font-size: var(--md3-label-small-size); font-weight: 700;
  color: var(--md3-on-surface-variant);
  text-transform: uppercase; letter-spacing: .05em;
  padding: .5rem .75rem .25rem;
}
.mqc-ta-row {
  padding: .55rem .75rem;
  border-top: 1px solid var(--md3-outline-variant);
  cursor: pointer;
  display: flex; align-items: center; gap: .5rem;
  transition: background var(--md3-dur-short-3) var(--md3-motion-standard);
}
.mqc-ta-row:first-child, .mqc-ta-group-label + .mqc-ta-row { border-top: none; }
.mqc-ta-row:hover { background: rgba(99,102,241, var(--md3-state-hover)); }
.mqc-ta-empty { color: var(--md3-on-surface-variant); cursor: default; font-style: italic; }
.mqc-ta-empty:hover { background: transparent; }
.mqc-pick-chip {
  display: inline-flex; align-items: center;
  background: var(--md3-secondary-container);
  color: var(--md3-on-secondary-container);
  border-radius: var(--md3-shape-full);
  padding: .35rem .75rem .35rem 1rem;
  font-size: var(--md3-label-medium-size); font-weight: 600;
}

/* ═══ Legacy class remap — `.btn`, `.card`, `.form-input`, etc. ═══
   Existing markup uses these class names — point them at M3 patterns
   so the visual upgrade flows automatically without HTML changes. */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font-family: var(--md3-font-plain);
  font-size: var(--md3-label-large-size);
  font-weight: var(--md3-label-large-weight);
  letter-spacing: 0.01em;
  border-radius: var(--md3-shape-full);
  padding: .625rem 1.5rem; min-height: 40px;
  border: none; cursor: pointer;
  transition: background var(--md3-dur-short-3) var(--md3-motion-standard),
              box-shadow var(--md3-dur-short-3) var(--md3-motion-standard),
              color var(--md3-dur-short-3) var(--md3-motion-standard);
}
.btn:disabled { opacity: .38; cursor: not-allowed; }
.btn-primary {
  background: var(--md3-primary); color: var(--md3-on-primary);
}
.btn-primary:hover:not(:disabled) {
  box-shadow: var(--md3-elev-1);
  background: var(--md3-primary-40);
}
.btn-secondary {
  background: var(--md3-secondary-container);
  color: var(--md3-on-secondary-container);
}
.btn-secondary:hover:not(:disabled) { box-shadow: var(--md3-elev-1); }
.btn-ghost {
  background: transparent; color: var(--md3-primary);
  border: 1px solid var(--md3-outline);
}
.btn-ghost:hover:not(:disabled) { background: rgba(99,102,241, var(--md3-state-hover)); }
.btn-text, .btn-link {
  background: transparent; color: var(--md3-primary);
  padding: .5rem .75rem; border: none;
  border-radius: var(--md3-shape-sm);
}
.btn-text:hover, .btn-link:hover { background: rgba(99,102,241, var(--md3-state-hover)); text-decoration: none; }
.btn-danger {
  background: var(--md3-error); color: var(--md3-on-error);
}
.btn-danger:hover:not(:disabled) { box-shadow: var(--md3-elev-1); background: var(--md3-error-40); }
.btn-gray {
  background: var(--md3-surface-container-high);
  color: var(--md3-on-surface);
}
.btn-gray:hover:not(:disabled) { background: var(--md3-surface-container-highest); }
.btn-sm { min-height: 32px; padding: .35rem 1rem; font-size: var(--md3-label-medium-size); }

/* Form inputs — outlined M3 style */
.form-input,
input[type="text"]:not([class*="md3"]):not([class*="lightbox"]):not(.dorm-cmp-search),
input[type="email"]:not([class*="md3"]),
input[type="number"]:not([class*="md3"]),
input[type="url"]:not([class*="md3"]),
input[type="search"]:not([class*="md3"]),
textarea:not([class*="md3"]),
select:not([class*="md3"]) {
  width: 100%;
  background: var(--md3-surface-container-lowest);
  color: var(--md3-on-surface);
  border: 1px solid var(--md3-outline);
  border-radius: var(--md3-shape-xs);
  padding: .65rem .85rem;
  font-family: var(--md3-font-plain);
  font-size: var(--md3-body-large-size);
  transition: border-color var(--md3-dur-short-3) var(--md3-motion-standard),
              box-shadow var(--md3-dur-short-3) var(--md3-motion-standard);
}
.form-input:hover, input:hover, textarea:hover, select:hover { border-color: var(--md3-on-surface-variant); }
.form-input:focus, input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--md3-primary);
  box-shadow: 0 0 0 1px var(--md3-primary);
}
.form-label {
  display: block;
  font-size: var(--md3-label-medium-size);
  font-weight: var(--md3-label-medium-weight);
  color: var(--md3-on-surface-variant);
  margin-bottom: .35rem;
}

/* Generic .card class → M3 elevated card */
.card {
  background: var(--md3-surface-container-lowest);
  color: var(--md3-on-surface);
  border-radius: var(--md3-shape-md);
  padding: 1rem;
  box-shadow: var(--md3-elev-1);
  transition: box-shadow var(--md3-dur-short-3) var(--md3-motion-standard);
}
.card:hover { box-shadow: var(--md3-elev-2); }

/* Modal overlay backdrop + dialog get M3 surface tint + shape */
.modal-overlay {
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(2px);
}
.modal-overlay .modal {
  background: var(--md3-surface-container-high);
  color: var(--md3-on-surface);
  border-radius: var(--md3-shape-xl);
  box-shadow: var(--md3-elev-3);
}

/* Tabs that use .tabs / .tab class → align with M3 tabs */
.tabs { border-bottom-color: var(--md3-outline-variant); }
.tab.active { color: var(--md3-primary); border-bottom-color: var(--md3-primary); }

/* Native checkboxes / radios — M3 indigo */
input[type="checkbox"], input[type="radio"] { accent-color: var(--md3-primary); }

/* ═══════════════════════════════════════════════════════════════════
   END Material 3 Design System
═══════════════════════════════════════════════════════════════════ */

/* ─── Reset & base ──────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 16px; scroll-behavior: smooth; }

/* ─── Cookie consent banner (April 2026) — first-visit only ────────── */
#cookie-banner {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 1490;
  background: #1f2937;
  color: white;
  padding: 1rem 1.25rem;
  display: none; /* JS toggles to flex */
  align-items: center;
  gap: 1rem;
  box-shadow: 0 -2px 12px rgba(0,0,0,.2);
  flex-wrap: wrap;
}
.cookie-banner-text { flex: 1 1 280px; min-width: 0; display: flex; flex-direction: column; line-height: 1.4; }
.cookie-banner-text strong { font-weight: 700; font-size: .95rem; margin-bottom: .15rem; }
.cookie-banner-text span { font-size: .82rem; opacity: .9; }
.cookie-banner-actions { display: flex; gap: .4rem; flex-shrink: 0; flex-wrap: wrap; }
.cookie-banner-actions .btn { min-height: 40px; padding: .45rem .85rem; font-size: .85rem; }
.cookie-banner-actions .btn-secondary { background: white; color: #1f2937; border-color: white; }
.cookie-banner-actions .btn-ghost { background: transparent; color: white; border: 1px solid rgba(255,255,255,.4); }
@media (max-width: 640px) {
  #cookie-banner { padding: .85rem 1rem; flex-direction: column; align-items: stretch; }
  .cookie-banner-actions { width: 100%; justify-content: stretch; }
  .cookie-banner-actions .btn { flex: 1 1 auto; }
}

/* ─── PWA install banner (April 2026 — mobile second-visit) ───────── */
#pwa-install-banner {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 1500;
  background: linear-gradient(135deg, #4F46E5, #7c3aed);
  color: white;
  padding: .75rem 1rem;
  display: none; /* JS toggles to flex */
  align-items: center;
  gap: .85rem;
  box-shadow: 0 2px 12px rgba(0,0,0,.18);
  animation: pwaSlideIn .35s ease-out;
}
@keyframes pwaSlideIn { from { transform: translateY(-100%); } to { transform: translateY(0); } }
.pwa-banner-icon { font-size: 1.6rem; flex-shrink: 0; }
.pwa-banner-text { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.pwa-banner-text strong { font-weight: 700; font-size: .95rem; }
.pwa-banner-text span { font-size: .78rem; opacity: .9; }
/* Inline iOS-share glyph rendered alongside the install instructions on
 * iOS Safari. The SVG is sized + vertically centered with the surrounding
 * text so the user reads "Tap [share button] Share → Add to Home Screen"
 * as one fluent line. (Replaces the ⬆️ emoji which didn't read as the
 * Safari share button to non-technical users.) */
.ios-share-icon {
  display: inline-block;
  vertical-align: -.18em;
  width: 1.05em;
  height: 1.05em;
  color: currentColor;
  margin: 0 .12em;
}
.pwa-banner-actions { display: flex; gap: .35rem; align-items: center; flex-shrink: 0; }
.pwa-banner-install {
  background: white; color: #4F46E5;
  border: 0; border-radius: 6px;
  padding: .55rem 1rem;
  font-size: .9rem; font-weight: 700;
  cursor: pointer;
  min-height: 44px;
}
.pwa-banner-dismiss {
  background: transparent; color: white;
  border: 0;
  width: 36px; height: 36px;
  font-size: 1.1rem;
  cursor: pointer;
  opacity: .85;
}
.pwa-banner-dismiss:hover { opacity: 1; }
/* Don't show the banner on desktop — install prompt only matters on mobile */
@media (min-width: 769px) {
  #pwa-install-banner { display: none !important; }
}

/* ─── Pull-to-refresh indicator (April 2026) ──────────────────────── */
.ptr-indicator {
  position: fixed;
  top: 14px;
  left: 50%;
  transform: translateX(-50%) translateY(0);
  z-index: 1450;
  width: 44px; height: 44px;
  border-radius: 50%;
  background: white;
  box-shadow: 0 2px 12px rgba(0,0,0,.15);
  display: flex; align-items: center; justify-content: center;
  font-size: 1.25rem;
  color: #4F46E5;
  transition: opacity .15s, transform .15s;
  pointer-events: none;
}
.ptr-indicator .ptr-spinner {
  display: inline-block;
  transition: transform .1s linear;
}
.ptr-indicator.ptr-refreshing .ptr-spinner {
  animation: ptrSpin 1s linear infinite;
}
@keyframes ptrSpin { from { transform: rotate(0); } to { transform: rotate(360deg); } }

/* ─── Photo upload buttons (April 2026 — public mobile pass) ────────
   Dual-button pattern: every photo upload site renders two visible
   labeled buttons backed by hidden file inputs. "🖼️ Library" → a
   regular accept="image/*" picker. "📷 Take photo" → an input with
   capture="environment" so mobile browsers jump straight to the
   camera app. The camera input's change event is bridged into the
   library input via a DataTransfer handoff (see initPhotoCameraBridges
   in app.js) so existing per-site change handlers don't need rewriting.
   Camera button hidden on desktop where it would be a stub. */
.photo-upload-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin: .35rem 0 .5rem;
}
.photo-upload-btn {
  flex: 1 1 180px;
  min-height: 44px;
  font-size: .92rem;
  font-weight: 600;
  padding: .55rem .9rem;
}
@media (hover: hover) and (pointer: fine) {
  /* Desktop / mouse pointer: hide the camera button — most desktops
     don't have a camera the user wants pointed at their dorm. */
  .photo-upload-btn.camera-btn { display: none; }
}

/* Drag-and-drop photo zone (May 2026). Desktop users see the dashed
   prompt + click-anywhere affordance. Touch users (mobile) hide the
   prompt entirely so the upload area looks like the existing buttons-
   only pattern they already know. */
.photo-dropzone {
  position: relative;
  border: 2px dashed #c7d2fe;
  border-radius: 12px;
  background: #f8fafc;
  padding: 1.25rem 1rem;
  text-align: center;
  transition: border-color .15s, background .15s, transform .12s;
  cursor: pointer;
}
.photo-dropzone:hover { border-color: #6366f1; background: #f5f3ff; }
.photo-dropzone-active {
  border-color: #6366f1 !important;
  background: #eef2ff !important;
  transform: scale(1.005);
}
.photo-dropzone-prompt {
  pointer-events: none; /* clicks fall through to the zone's click handler */
  margin-bottom: .85rem;
}
.photo-dropzone-icon { font-size: 1.7rem; line-height: 1; margin-bottom: .35rem; }
.photo-dropzone-title { font-size: .92rem; color: #1f2937; margin-bottom: .25rem; }
.photo-dropzone-or { color: #6b7280; font-weight: 400; }
.photo-dropzone-sub { font-size: .76rem; color: #6b7280; }
.photo-dropzone .photo-upload-buttons { margin: .5rem 0 0; justify-content: center; }
@media (hover: none) and (pointer: coarse) {
  /* Touch device — drag-drop isn't a thing. Collapse the dropzone to
     just the buttons; hide the prompt + dashed border. */
  .photo-dropzone {
    border: none;
    background: transparent;
    padding: 0;
  }
  .photo-dropzone-prompt { display: none; }
  .photo-dropzone .photo-upload-buttons { margin: 0; }
}

/* ─── Design tokens ────────────────────────────────────────────────────────
 * Surface color tokens used throughout the stylesheet.
 */

/* ─── Common Space modal — clickable type picker (May 2026) ──────────
   Replaces the chained prompt() flow with a real form. Cards are 3 wide
   on desktop, 2 wide below 480px. Selected card gets the indigo accent. */
.cs-type-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: .5rem;
  margin-bottom: .85rem;
}
@media (max-width: 480px) {
  .cs-type-grid { grid-template-columns: repeat(2, 1fr); }
}
.cs-type-card {
  border: 1.5px solid #e5e7eb;
  background: white;
  border-radius: 10px;
  padding: .65rem .35rem;
  text-align: center;
  cursor: pointer;
  transition: border-color .12s, background .12s, transform .1s;
  user-select: none;
  font-size: .82rem;
  color: #374151;
}
.cs-type-card:hover { border-color: #a5b4fc; background: #f5f3ff; }
.cs-type-card.selected {
  border-color: #6366f1;
  background: #eef2ff;
  color: #3730a3;
  font-weight: 600;
}
.cs-type-card-icon { font-size: 1.4rem; line-height: 1; margin-bottom: .25rem; }
.cs-type-card-label { font-size: .78rem; }

/* Photo upload zone inside the common-space modal — same drag-drop pattern
   as the room photo dropzone but scoped + smaller. */
.cs-photo-zone {
  border: 2px dashed #c7d2fe;
  border-radius: 10px;
  background: #f8fafc;
  padding: 1rem .75rem;
  text-align: center;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.cs-photo-zone:hover { border-color: #6366f1; background: #f5f3ff; }
.cs-photo-zone.cs-photo-zone-active {
  border-color: #6366f1 !important;
  background: #eef2ff !important;
}
.cs-photo-zone:focus-within { outline: 2px solid #6366f1; outline-offset: 2px; }

:root {
  --ds-bg:           #f4f6fa;
  --ds-bg-elevated:  #ffffff;
  --ds-text:         #1a202c;
  --ds-text-muted:   #6b7280;
  --ds-border:       #e5e7eb;
  --ds-hover-bg:     #f9fafb;
  --ds-input-bg:     #ffffff;
  --ds-input-border: #d1d5db;
  --ds-shadow:       0 1px 3px rgba(0,0,0,0.06);
}

body {
  font-family: 'Inter', system-ui, sans-serif;
  background: var(--ds-bg);
  color: var(--ds-text);
  min-height: 100vh;
}

/* ─── Mobile bottom nav (Apr 2026) ────────────────────────────────────────
 * Hidden on desktop; visible-and-fixed on ≤640px. Pairs with the hamburger
 * drawer (which holds the long tail of links). 4 tabs: Home / Search /
 * Favorites / Profile — chosen because they're the highest-traffic
 * destinations and map cleanly to thumb-reachable corners on phones.
 * Uses safe-area-inset-bottom so the bar floats above iPhone notches.
 */
/* ─── Mobile Breadcrumb Collapse (May 2026) ────────────────────
   On mobile, the full breadcrumb path (Colleges › Amherst › Valentine Hall › Room 202)
   wraps to 2-3 lines and wastes precious above-fold space. Collapse to show only
   the current page name; expand on tap. */
.breadcrumb-bar .bc-collapsed { display: none; }
@media (max-width: 640px) {
  .breadcrumb-bar {
    padding: 0.5rem 1rem;
  }
  .breadcrumb-bar .bc-sep,
  .breadcrumb-bar #bc-colleges,
  .breadcrumb-bar #bc-college-name,
  .breadcrumb-bar #bc-dorm-name {
    display: none;
  }
  /* Only show the current page name (dorm detail or room number) by default */
  .breadcrumb-bar #bc-dorm-detail-name,
  .breadcrumb-bar #bc-room-number {
    display: inline;
  }
  /* When .bc-expanded class is added via JS, show full breadcrumb */
  .breadcrumb-bar.bc-expanded .bc-sep,
  .breadcrumb-bar.bc-expanded #bc-colleges,
  .breadcrumb-bar.bc-expanded #bc-college-name,
  .breadcrumb-bar.bc-expanded #bc-dorm-name {
    display: inline;
  }
  .breadcrumb-bar.bc-expanded #bc-dorm-detail-name,
  .breadcrumb-bar.bc-expanded #bc-room-number {
    display: inline;
  }
}

.mobile-bottom-nav { display: none; }
@media (max-width: 640px) {
  .mobile-bottom-nav {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    position: fixed;
    bottom: 0; left: 0; right: 0;
    z-index: 1100;
    background: var(--ds-bg-elevated, #fff);
    border-top: 1px solid var(--ds-border, #e5e7eb);
    box-shadow: 0 -2px 12px rgba(0,0,0,0.08);
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .mbn-tab {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    padding: 0.55rem 0.4rem 0.45rem;
    text-decoration: none;
    color: var(--ds-text-muted, #6b7280);
    min-height: 56px;
    transition: color .12s, background .12s;
  }
  .mbn-tab.active { color: #4F46E5; }
  /* Dark-mode active-tab contrast (May 2026): #4F46E5 indigo on a dark
   * background fails WCAG AA. Lift to --md3-primary-80 (the M3 dark-theme
   * accent) so the active state stays readable. Both the system-level
   * media query AND a future explicit data-theme="dark" toggle are
   * covered. */
  @media (prefers-color-scheme: dark) {
    .mbn-tab.active { color: var(--md3-primary-80, #b1b3f8); }
  }
  [data-theme="dark"] .mbn-tab.active { color: var(--md3-primary-80, #b1b3f8); }
  .mbn-tab:active { background: var(--ds-hover-bg, #f9fafb); }
  .mbn-ico { font-size: 1.25rem; line-height: 1; }
  .mbn-lbl { font-size: 0.7rem; font-weight: 600; margin-top: 0.18rem; letter-spacing: 0.01em; }
  /* Reserve the space at the bottom of #main-content so content isn't
     hidden behind the fixed nav. */
  #main-content { padding-bottom: calc(72px + env(safe-area-inset-bottom, 0)); }

  /* Hide the mobile bottom nav whenever ANY modal is open (May 2026 fix
     after smoke test feedback — the nav was covering the Submit/Cancel
     buttons of the Mod Quick Capture modal AND the photo upload modal,
     making both unusable on mobile). The :has() selector covers any
     element with the .modal-overlay class whose computed display is
     flex/block. Caught both the SPA modals (style="display:flex") and
     anything that ever appears via class toggle. Falls back gracefully
     on the few browsers that still don't support :has() — those users
     just see the existing (broken) overlap. */
  body:has(.modal-overlay[style*="display:flex"]),
  body:has(.modal-overlay[style*="display: flex"]),
  body:has(.modal-overlay[style*="display:block"]),
  body:has(.modal-overlay[style*="display: block"]) {
    overflow: hidden;
  }
  body:has(.modal-overlay[style*="display:flex"]) .mobile-bottom-nav,
  body:has(.modal-overlay[style*="display: flex"]) .mobile-bottom-nav,
  body:has(.modal-overlay[style*="display:block"]) .mobile-bottom-nav,
  body:has(.modal-overlay[style*="display: block"]) .mobile-bottom-nav {
    display: none !important;
  }
  /* Modal content gets a generous bottom padding on mobile so even on
     browsers without :has() support, the action buttons clear the nav
     bar. 80px = 56px nav height + 24px breathing room. */
  .modal-overlay .modal {
    padding-bottom: max(1.25rem, calc(80px + env(safe-area-inset-bottom, 0)));
  }
  /* Existing dorm-compare bar already sits at bottom — bump it above the nav. */
  #dorm-compare-bar { bottom: calc(64px + env(safe-area-inset-bottom, 0)); }
  /* MOBILE BOTTOM-FIXED OVERLAP FIX (May 2026) — every fixed-bottom element
     needs to clear the 72px (~64px tab strip + safe-area) mobile nav,
     otherwise it sits invisibly behind the nav OR steals taps from it.
     Audited 2026-05-02 after user reported "stuff isnt clickable and
     scrollable" on mobile — every entry below was overlapping the nav. */
  #compare-bar         { bottom: calc(64px + env(safe-area-inset-bottom, 0)) !important; }
  #admin-edit-fab      { bottom: calc(80px + env(safe-area-inset-bottom, 0)) !important; right: 1rem !important; }
  .toast-container     { bottom: calc(80px + env(safe-area-inset-bottom, 0)) !important; right: 1rem !important; left: 1rem !important; }
  /* When BOTH compare bars (dorm + room) are visible, stack the dorm bar
     above the room bar so neither hides under the nav. */
  #dorm-compare-bar.has-stack { bottom: calc(128px + env(safe-area-inset-bottom, 0)) !important; }
  /* Reserve enough scroll-clearance under #main-content for the worst-case
     stacking: 72px nav + 64px room bar (when active). The base rule above
     already pads 72px; this is the upgrade when the bar is up. JS adds
     .has-bottom-bar to <body> when either bar opens. */
  body.has-bottom-bar #main-content {
    padding-bottom: calc(72px + 64px + env(safe-area-inset-bottom, 0)) !important;
  }
}

/* ─── Dorm-compare modal — mobile redesign (Apr 2026) ─────────────────────
 * On desktop the modal is a horizontal table (good for side-by-side
 * comparison). On phones the table becomes unreadable — too many columns,
 * 3pt text. Mobile flips to a stacked-card layout: each dorm gets its own
 * full-width card, scroll to the next. Existing markup uses .dcmp-table
 * (or similar) for the table; we override on small screens.
 */
@media (max-width: 640px) {
  /* Switch table layout to vertical card stack. The .dcmp-row pattern
     repeats as a row label + value per dorm; on mobile we surface each
     dorm as its own block with all rows underneath. */
  #modal-dorm-compare .dcmp-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  #modal-dorm-compare .dcmp-table thead th { font-size: 0.78rem; }
  #modal-dorm-compare .dcmp-table td,
  #modal-dorm-compare .dcmp-table th { padding: 0.45rem 0.55rem; font-size: 0.85rem; }
  /* Allow horizontal scroll cue — sticky first column so the row label
     stays visible while user scrolls horizontally through dorm columns. */
  #modal-dorm-compare .dcmp-table th:first-child,
  #modal-dorm-compare .dcmp-table td:first-child {
    position: sticky; left: 0;
    background: var(--ds-bg-elevated, #fff);
    z-index: 1;
    box-shadow: 2px 0 4px rgba(0,0,0,0.04);
  }
}

/* ─── Command palette (⌘K) ───────────────────────────────────────────────
 * Linear/Raycast-style. Single column. Top input + scrollable results.
 * Opens centered on viewport, slides down slightly so it doesn't feel
 * stuck to the top. Backdrop is a darker scrim so the rest of the page
 * recedes — palette is the only interactive thing on screen.
 */
.cmdk-overlay {
  position: fixed; inset: 0;
  background: rgba(15,23,42,0.55);
  z-index: 1500;
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 12vh;
  animation: cmdk-fade .12s ease-out;
}
@keyframes cmdk-fade { from { opacity: 0 } to { opacity: 1 } }
.cmdk-modal {
  background: var(--ds-bg-elevated, #fff);
  border: 1px solid var(--ds-border, #e5e7eb);
  border-radius: 12px;
  width: min(620px, 92vw);
  max-height: 70vh;
  display: flex; flex-direction: column;
  box-shadow: 0 24px 64px rgba(0,0,0,0.25), 0 4px 12px rgba(0,0,0,0.12);
  overflow: hidden;
}
.cmdk-input-wrap {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.95rem 1.1rem;
  border-bottom: 1px solid var(--ds-border, #e5e7eb);
}
.cmdk-prefix { font-size: 1.05rem; color: var(--ds-text-muted, #6b7280); font-weight: 700; }
#cmdk-input {
  flex: 1;
  font-size: 1rem; font-weight: 500;
  border: none; outline: none; background: transparent;
  color: var(--ds-text, #1a202c);
}
.cmdk-shortcut {
  font-family: 'SF Mono', Menlo, Consolas, monospace;
  font-size: 0.7rem;
  background: var(--ds-hover-bg, #f3f4f6);
  color: var(--ds-text-muted, #6b7280);
  padding: 0.18rem 0.5rem;
  border-radius: 4px;
  border: 1px solid var(--ds-border, #e5e7eb);
}
.cmdk-results { overflow-y: auto; padding: 0.4rem 0; }
.cmdk-section { padding: 0.4rem 0 0.2rem; }
.cmdk-section-label {
  font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ds-text-muted, #6b7280);
  padding: 0.4rem 1.1rem 0.3rem;
}
.cmdk-item {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.55rem 1.1rem;
  cursor: pointer;
  font-size: 0.92rem;
  color: var(--ds-text, #1a202c);
  border: none; background: transparent;
  width: 100%; text-align: left;
}
.cmdk-item.active { background: #eef2ff; }
.cmdk-item-ico { font-size: 1rem; flex-shrink: 0; }
.cmdk-item-main { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmdk-item-sub { font-size: 0.78rem; color: var(--ds-text-muted, #6b7280); margin-left: 0.4rem; }
.cmdk-item-shortcut {
  font-family: 'SF Mono', Menlo, Consolas, monospace;
  font-size: 0.68rem; color: var(--ds-text-muted, #6b7280);
}
.cmdk-empty {
  padding: 1.5rem 1.1rem;
  text-align: center;
  color: var(--ds-text-muted, #6b7280);
  font-size: 0.9rem;
}

/* ─── Skeleton loaders (Apr 2026) ─────────────────────────────────────────
 * Generic shimmer card. Use by injecting `<div class="skeleton skeleton-card"></div>`
 * (or skeleton-line / skeleton-img) where content will eventually render.
 * Replaces blank/flicker on slower fetches across home, college, room.
 */
.skeleton {
  background: linear-gradient(90deg, #f1f5f9 0%, #e2e8f0 50%, #f1f5f9 100%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.4s ease-in-out infinite;
  border-radius: 8px;
  display: block;
}
.skeleton-card { height: 120px; margin-bottom: 0.6rem; }
.skeleton-line { height: 12px; margin-bottom: 0.5rem; }
.skeleton-line.short { width: 60%; }
.skeleton-line.medium { width: 80%; }
.skeleton-img { aspect-ratio: 16/10; }
@keyframes skeleton-shimmer {
  0%   { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}
/* Show-more button used by the review-list virtualization (basic) */
.show-more-reviews-btn {
  display: block; margin: 1rem auto;
  padding: 0.55rem 1.4rem;
  background: var(--ds-bg-elevated, #fff);
  border: 1px solid var(--ds-border, #e5e7eb);
  border-radius: 8px;
  color: var(--ds-text, #1a202c);
  font-weight: 600; cursor: pointer;
  transition: background .12s, border-color .12s;
}
.show-more-reviews-btn:hover { background: var(--ds-hover-bg, #f9fafb); border-color: #9ca3af; }

/* ─── Review filters (Apr 2026) ────────────────────────────────────────── */
.review-filters {
  display: flex; gap: 0.5rem; flex-wrap: wrap;
  margin: 0.85rem 0 1rem;
  padding: 0.65rem 0.85rem;
  background: var(--ds-bg-elevated, #fff);
  border: 1px solid var(--ds-border, #e5e7eb);
  border-radius: 0.55rem;
  align-items: center;
}
.review-filter-select, .review-filter-input {
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--ds-input-border, #d1d5db);
  background: var(--ds-input-bg, #fff);
  color: var(--ds-text, #1a202c);
  border-radius: 0.4rem;
  font-size: 0.85rem;
  min-width: 140px;
}
.review-filter-clear {
  padding: 0.4rem 0.85rem;
  background: transparent; border: 1px solid var(--ds-border, #e5e7eb);
  color: var(--ds-text-muted, #6b7280);
  border-radius: 0.4rem; font-size: 0.82rem; cursor: pointer;
}
.review-filter-clear:hover { color: var(--ds-text, #1a202c); }

/* ─── First-visit tooltip tour (Apr 2026) ───────────────────────────────── */
.tour-overlay {
  position: fixed; inset: 0;
  background: rgba(15,23,42,0.55);
  z-index: 1450;
  display: flex; align-items: center; justify-content: center;
}
.tour-bubble {
  position: absolute;
  background: var(--ds-bg-elevated, #fff);
  color: var(--ds-text, #1a202c);
  padding: 1.05rem 1.25rem;
  border-radius: 0.7rem;
  box-shadow: 0 12px 32px rgba(0,0,0,0.18);
  max-width: 320px;
  font-size: 0.92rem; line-height: 1.45;
}
.tour-bubble h4 { margin: 0 0 0.4rem; font-weight: 700; font-size: 1rem; }
.tour-bubble-actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 0.85rem; }
.tour-bubble-skip {
  background: transparent; border: none; color: var(--ds-text-muted, #6b7280);
  cursor: pointer; font-size: 0.82rem; padding: 0.4rem 0.7rem;
}
.tour-bubble-next {
  background: #4F46E5; color: white; border: none; border-radius: 0.4rem;
  padding: 0.45rem 1rem; cursor: pointer; font-weight: 600; font-size: 0.85rem;
}
.tour-progress {
  position: absolute; left: 1.25rem; bottom: 1rem;
  font-size: 0.72rem; color: var(--ds-text-muted, #6b7280);
}

/* ─── Community Notes tabs (Apr 2026 — Brief Phase 5) ─────────────────── */
.community-notes-wrap {
  background: var(--ds-bg-elevated, #fff);
  border: 1px solid var(--ds-border, #e5e7eb);
  border-radius: 0.7rem;
  padding: 1rem 0;
  margin-top: 1.25rem;
}
.community-notes-tabs {
  display: flex; gap: 0; border-bottom: 1px solid var(--ds-border, #e5e7eb);
  padding: 0 0.75rem;
}
.community-notes-tab {
  flex: 1; padding: 0.65rem 0.85rem;
  background: transparent; border: none; cursor: pointer;
  font-size: 0.92rem; font-weight: 600; color: var(--ds-text-muted, #6b7280);
  border-bottom: 2px solid transparent;
  transition: color .12s, border-color .12s;
}
.community-notes-tab.active {
  color: #4F46E5; border-bottom-color: #4F46E5;
}
.community-notes-tab:hover { color: var(--ds-text, #1a202c); }
.community-notes-panel { padding: 0.4rem 1rem 0.5rem; }

/* ─── Shopping list section (Apr 2026) ──────────────────────────────────── */
.shopping-list-section {
  background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
  border: 1px solid #fcd34d;
  border-radius: 0.7rem;
  padding: 1.1rem 1.25rem;
  margin-top: 1.25rem;
}
.shopping-list-section h3 { margin: 0 0 0.5rem; font-size: 1rem; color: #78350f; }
.shopping-list-section ul { list-style: none; padding: 0; margin: 0; }
.shopping-list-section li {
  display: flex; gap: 0.6rem; align-items: flex-start;
  padding: 0.4rem 0;
  font-size: 0.9rem; color: #451a03;
}
.shopping-list-section li::before { content: '✓'; color: #65a30d; font-weight: 700; }

/* ── Skip-to-content link (a11y) ────────────────────────────────── */
/* Off-screen until focused; jumps to #main-content for keyboard + SR users. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10000;
  padding: .75rem 1.25rem;
  background: #4338ca;
  color: #fff;
  font-weight: 600;
  border-radius: 0 0 8px 0;
  box-shadow: 0 4px 12px rgba(0,0,0,.15);
}
.skip-link:focus {
  left: 0;
  outline: 3px solid #fbbf24;
  outline-offset: 2px;
}
a { color: inherit; text-decoration: none; }
button { cursor: pointer; font-family: inherit; }
input, textarea, select {
  font-family: inherit;
  font-size: 0.95rem;
  padding: 0.5rem 0.75rem;
  border: 1.5px solid #d1d8e0;
  border-radius: 8px;
  background: #fff;
  width: 100%;
  transition: border-color .2s;
}
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: #3b5bdb;
  box-shadow: 0 0 0 3px rgba(59,91,219,.12);
}
textarea { resize: vertical; }
label { display: flex; flex-direction: column; gap: 0.35rem; font-weight: 500; font-size: 0.9rem; color: #374151; }

/* ─── Layout ────────────────────────────────────────────────────── */
.container { max-width: 1100px; margin: 0 auto; padding: 0 1.25rem; }
.view { padding: 1.5rem 0 3rem; }

/* ─── Header ────────────────────────────────────────────────────── */
.site-header {
  background: #1e3a8a;
  color: #fff;
  position: sticky; top: 0; z-index: 100;
  box-shadow: 0 2px 8px rgba(0,0,0,.18);
}
.header-inner {
  display: flex; align-items: center; gap: 1rem;
  padding-top: 0.85rem; padding-bottom: 0.85rem;
}
.logo { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; }
.logo-icon { font-size: 1.4rem; }
.logo-text { font-size: 1.3rem; font-weight: 700; letter-spacing: -.3px; color: #fff; }
.header-search { flex: 1; max-width: 420px; }
/* Header search input: needs to be readable on the dark indigo header bg.
   M3 universal `input` selectors at the bottom of the M3 block were winning
   on specificity and forcing a white-surface look — making the white-on-white
   placeholder invisible (caught during May 2026 mobile review). The
   `.site-header` prefix lifts our specificity above the universal rules so
   the translucent-white-on-indigo treatment sticks. The :focus state
   intentionally inverts to a solid white surface (typing should feel like
   "you've activated me"); placeholder color flips dark to stay readable. */
.site-header .header-search input {
  width: 100%;
  background: rgba(255,255,255,.15) !important;
  color: #fff !important;
  border: 1px solid rgba(255,255,255,.3) !important;
  border-radius: 8px;
}
.site-header .header-search input::placeholder { color: rgba(255,255,255,.7) !important; }
.site-header .header-search input:focus {
  background: #fff !important;
  color: #1a202c !important;
  border-color: #fff !important;
  outline: none;
}
.site-header .header-search input:focus::placeholder { color: rgba(26,32,44,.5) !important; }
.header-nav { display: flex; align-items: center; gap: .4rem; }

/* ─── Accessibility: keyboard focus rings ───────────────────────── */
/* Global :focus-visible ring so every keyboard-focusable element
   (button, link, input, select, textarea, summary, contenteditable, tabindex)
   gets a consistent, high-contrast indicator. Mouse/touch users do NOT see
   the ring because :focus-visible is only applied for keyboard navigation. */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid #6366f1;
  outline-offset: 2px;
  border-radius: 4px;
}
/* Dark header needs a light ring so the indigo doesn't disappear against indigo. */
.header :focus-visible,
.hamburger-drawer-header :focus-visible {
  outline-color: #fff;
}

/* ─── Breadcrumb ────────────────────────────────────────────────── */
.breadcrumb-bar {
  background: #fff;
  border-bottom: 1px solid #e5eaf1;
  padding: 0.6rem 1.25rem;
  font-size: 0.85rem;
  color: #6b7280;
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.1rem;
}
.bc-link { cursor: pointer; color: #3b5bdb; }
.bc-link:hover { text-decoration: underline; }
.bc-sep { color: #6b7280; margin: 0 0.15rem; }

/* ─── Buttons ───────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.5rem 1.1rem;
  border-radius: 8px; border: none;
  font-size: 0.9rem; font-weight: 600;
  transition: background .15s, transform .1s;
}
.btn:active { transform: scale(.97); }
.btn-primary  { background: #3b5bdb; color: #fff; }
.btn-primary:hover  { background: #2f4dc4; }
.btn-secondary { background: #e8edf8; color: #3b5bdb; border: 1.5px solid #c7d2f0; }
.btn-secondary:hover { background: #d5dff5; }
.btn-ghost { background: transparent; color: #6b7280; border: 1.5px solid #d1d8e0; }
.btn-ghost:hover { background: #f3f4f6; }
.btn-text { background: none; border: none; color: #3b5bdb; font-size: 0.85rem; padding: 0.25rem 0; text-align: left; }
.btn-text:hover { text-decoration: underline; }

/* ─── Hero ──────────────────────────────────────────────────────── */
.hero {
  background: linear-gradient(135deg, #1e3a8a 0%, #3b5bdb 100%);
  color: #fff;
  border-radius: 16px;
  padding: 2.5rem 2rem;
  margin-bottom: 2rem;
  text-align: center;
}
.hero h1 { font-size: clamp(1.5rem, 3vw, 2.2rem); font-weight: 700; line-height: 1.3; margin-bottom: 0.75rem; }
.hero p  { font-size: 1.05rem; opacity: .85; margin-bottom: 1.5rem; }
.accent { color: #fbbf24; }
.home-greeting {
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: .01em;
  opacity: .9;
  margin: 0 0 .75rem;
  color: #fef3c7;
}
.hero-search { max-width: 540px; margin: 0 auto; position: relative; }
.hero-search input { width: 100%; font-size: 1.05rem; padding: .7rem 2.4rem .7rem 1.1rem; border-radius: 10px; }
/* Inline ✕ clear button — sits on the right edge of any input flagged
   `data-clearable`. Wired up by a tiny vanilla-JS helper in app.js that
   shows/hides the button as the input value changes and clears the input
   on click (firing a synthetic `input` event so search handlers re-run). */
.search-clear-btn {
  position: absolute;
  right: .55rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1.65rem; height: 1.65rem;
  border-radius: 999px;
  background: rgba(0,0,0,.06);
  color: #4b5563;
  border: none;
  cursor: pointer;
  font-size: 1.15rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  transition: background .12s;
}
.search-clear-btn:hover { background: rgba(0,0,0,.12); }
.hero-search .search-clear-btn { background: rgba(255,255,255,.22); color: #fff; }
.hero-search .search-clear-btn:hover { background: rgba(255,255,255,.34); }
.hero-hint { font-size: .85rem; opacity: .75; margin-top: .6rem; }
.hero-link { color: #fbbf24; font-weight: 600; }
.hero-link:hover { text-decoration: underline; }
/* Cosmetic gap fix (May 2026): the .hero p rule applies margin-bottom: 1.5rem
   to every paragraph including the LAST one (hero-hint), creating an unbalanced
   64px bottom gap vs. the 40px top gap. Zero out the last child's bottom margin
   so the hero's internal padding is symmetric regardless of which element ends
   up last (hint, recent-searches, search box). */
.hero > :last-child { margin-bottom: 0; }

/* ─── Unified typeahead dropdown ─────────────────────────────────── */
.typeahead-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0; right: 0;
  background: #fff;
  border: 1px solid #d1d5db;
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,.14);
  z-index: 500;
  overflow: hidden;
  text-align: left;
}
.typeahead-group-label {
  font-size: .72rem;
  font-weight: 700;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: .05em;
  padding: .45rem .8rem .2rem;
  background: #f9fafb;
  border-bottom: 1px solid #f3f4f6;
}
.typeahead-opt {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .55rem .85rem;
  cursor: pointer;
  border-bottom: 1px solid #f3f4f6;
  font-size: .9rem;
  color: #1f2937;
}
.typeahead-opt:last-child { border-bottom: none; }
.typeahead-opt:hover { background: #f0f4ff; }
.typeahead-opt-icon { font-size: 1rem; flex-shrink: 0; }
.typeahead-opt-main { font-weight: 600; }
.typeahead-opt-sub  { font-size: .78rem; color: #6b7280; }
.typeahead-no-results { padding: .65rem .85rem; color: #6b7280; font-size: .88rem; }
/* Bolded match substring inside typeahead results — <mark> element */
.typeahead-hl { background: #fef3c7; color: inherit; font-weight: 700; border-radius: 2px; padding: 0 1px; }

/* Character counter for user-write textareas */
.char-counter {
  display: block;
  margin-top: .25rem;
  font-size: .75rem;
  color: #6b7280;
  text-align: right;
  font-variant-numeric: tabular-nums;
  transition: color .15s ease;
}
.char-counter.char-counter-warn { color: #b45309; }
.char-counter.char-counter-over { color: #b91c1c; font-weight: 600; }

/* Dorm gallery "View all N photos →" / "Show fewer ↑" toggle pill */
.dorm-gallery-toggle {
  margin-top: .75rem;
  padding: .4rem .9rem;
  background: #eef2ff;
  color: #4338ca;
  border: 1px solid #c7d2fe;
  border-radius: 999px;
  font-size: .82rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.dorm-gallery-toggle:hover {
  background: #6366f1;
  color: #fff;
  border-color: #6366f1;
}
.dorm-gallery-toggle:focus-visible {
  outline: 2px solid #6366f1;
  outline-offset: 2px;
}

/* ─── Section header ────────────────────────────────────────────── */
.section-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; margin-bottom: 1.25rem; flex-wrap: wrap;
}
.section-header h2 { font-size: 1.4rem; font-weight: 700; }
.muted { color: #6b7280; font-size: 0.9rem; margin-top: 0.2rem; }

/* ─── Card grid ─────────────────────────────────────────────────── */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1.1rem;
}
/* Asymmetric card layout (May 2026 — human design) ─────────────
   Add visual imperfection to break the "AI-generated" look.
   Every other card is offset ±8px; cards vary slightly in width. */
.card:nth-child(odd) {
  transform: translateX(8px);
}
.card:nth-child(even) {
  transform: translateX(-8px);
}
.card:nth-child(1) {
  grid-column: span 1;
}
.card:nth-child(2) {
  grid-column: span 1;
}
/* Vary card widths slightly for a less-gridded feel (subtle, not jarring) */
.card:nth-child(3n+1) {
  max-width: 110%;
}
.card:nth-child(3n+2) {
  max-width: 100%;
}
.card:nth-child(3n+3) {
  max-width: 95%;
}

.card {
  background: #fff;
  border-radius: 12px;
  border: 1.5px solid #e5eaf1;
  padding: 1.2rem 1.35rem;
  cursor: pointer;
  transition: box-shadow .2s, border-color .2s, transform .15s;
}
.card:hover { box-shadow: 0 4px 18px rgba(59,91,219,.12); border-color: #b5c5f0; transform: translateY(-2px); }
.card-title { font-size: 1.05rem; font-weight: 700; margin-bottom: 0.3rem; }
.card-sub   { font-size: 0.85rem; color: #6b7280; margin-bottom: 0.6rem; }
.card-badge {
  display: inline-block; background: #eff3ff; color: #3b5bdb;
  padding: 0.2rem 0.6rem; border-radius: 20px; font-size: 0.78rem; font-weight: 600;
}

/* ─── Dorm card with photo ──────────────────────────────────────
   Phase 3 Mobile optimization (May 2026): responsive images with sizes
   attribute + lazy loading + fade-in animation on load. Cards render at
   ~360px on mobile (<640px), ~500px on tablet, ~600px on desktop.
   ────────────────────────────────────────────────────────────────── */
.dorm-card { padding: 0; overflow: hidden; }
.dorm-card-img-wrap {
  position: relative; width: 100%; height: 170px;
  background: #f0f4ff; overflow: hidden;
}
.dorm-card-img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .3s, opacity .2s;
  /* Responsive image loading: fade in images as they load for smooth UX */
  opacity: 1;
}
/* Loading state: img before loaded adds a subtle fade */
.dorm-card-img:not([src]),
.dorm-card-img[loading="lazy"] {
  opacity: 0.8;
}
/* Loaded image (browser fires load event) */
.dorm-card-img[loaded] {
  opacity: 1;
  animation: fadeInImage .25s ease-in-out;
}
@keyframes fadeInImage {
  from { opacity: 0.7; }
  to { opacity: 1; }
}
.dorm-card:hover .dorm-card-img { transform: scale(1.04); }

/* Mobile image optimization: reduce unnecessary rendering on small screens */
@media (max-width: 640px) {
  .dorm-card-img-wrap { height: 150px; /* Slightly smaller on mobile */ }
  /* Lazy loading hint: images with loading="lazy" on mobile get lower priority */
  .dorm-card-img {
    /* Disable hover zoom on touch devices to save GPU */
    transition: opacity .2s;
  }
  .dorm-card:active .dorm-card-img {
    opacity: 0.95;
  }
}

/* ─── Tap-to-load placeholder (May 2026 — Phase 4 Mobile optimization) ──────
   Deferred content sections (reviews, photos, floor plans) show a "tap to load"
   placeholder until user interacts or scrolls near. Reduces initial page load
   on mobile by deferring heavy content below the fold. */
.tap-to-load-placeholder {
  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
  border: 2px dashed #cbd5e1;
  border-radius: 12px;
  padding: 2rem 1.5rem;
  text-align: center;
  margin: 1.5rem 0;
  transition: all .2s;
}
.tap-to-load-placeholder.loading {
  opacity: 0.6;
  pointer-events: none;
}
.tap-to-load-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}
.tap-to-load-spinner {
  width: 24px;
  height: 24px;
  border: 2px solid #e2e8f0;
  border-top-color: #64748b;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin {
  to { transform: rotate(360deg); }
}
/* Lightbox photo transitions (Phase 6 — May 2026) */
@keyframes lb-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes lb-fade-out {
  from { opacity: 1; }
  to { opacity: 0; }
}
.lb-fade-in {
  animation: lb-fade-in 150ms ease-out;
}
.lb-fade-out {
  animation: lb-fade-out 100ms ease-out;
}
.tap-to-load-placeholder.loading .tap-to-load-spinner {
  animation: spin 0.6s linear infinite;
  border-top-color: #3b82f6;
}
.tap-to-load-label {
  font-size: 0.9rem;
  color: #64748b;
  margin: 0;
  font-weight: 500;
}
.tap-to-load-btn {
  padding: 0.5rem 1.2rem;
  font-size: 0.85rem;
}

/* Mobile: emphasize the tap affordance on touch devices */
@media (max-width: 640px) {
  .tap-to-load-placeholder {
    background: linear-gradient(135deg, #eff6ff 0%, #f0f4ff 100%);
    border-color: #bfdbfe;
    padding: 1.5rem 1.25rem;
  }
  .tap-to-load-label {
    font-size: 0.85rem;
  }
}
.dorm-card-img-placeholder {
  display: flex; align-items: center; justify-content: center;
  font-size: 2.5rem; color: #c0ccee;
}
.dorm-card-img-caption {
  position: absolute; bottom: 0; left: 0; right: 0;
  background: rgba(0,0,0,.45); color: #fff;
  font-size: 0.72rem; padding: 0.2rem 0.5rem;
}
.card-body { padding: 1rem 1.1rem; }
.dorm-card-footer {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 0.7rem; flex-wrap: wrap; gap: 0.3rem;
}
/* Dorm card amenity chips */
.dorm-chip-row {
  display: flex; flex-wrap: wrap; gap: .25rem; margin-top: .4rem;
}
.dorm-chip {
  font-size: .7rem; background: #f3f4f6; color: #374151;
  border-radius: 20px; padding: .15rem .5rem; white-space: nowrap;
  border: 1px solid #e5e7eb;
}
.btn-sm {
  font-size: 0.76rem; padding: 0.22rem 0.6rem; border-radius: 20px;
  cursor: pointer; font-weight: 600; border: 1.5px solid #3b5bdb;
  background: #fff; color: #3b5bdb; transition: background .15s;
}
.btn-sm:hover { background: #eff3ff; }
.btn-outline { background: transparent; }

/* ─── Typography personality (May 2026 — human design) ────────────
   Serif headlines, hand-drawn grades, italic reviewer names,
   fancy quotes for review snippets. */
.section-title, .view-title, h2 {
  font-family: var(--font-serif);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.dorm-grade-letter, .room-grade-letter {
  font-family: var(--font-handwritten);
  font-weight: 700;
  font-size: 3rem;
  line-height: 1;
}
.reviewer-name, .reviewer-info {
  font-style: italic;
  color: #6b7280;
  font-size: 0.9rem;
}
/* Fancy quotes around review tags/snippets (add via CSS before/after) */
.review-snippet::before {
  content: '"';
  font-family: Georgia, serif;
  font-style: italic;
  color: inherit;
  margin-right: 0.1em;
}
.review-snippet::after {
  content: '"';
  font-family: Georgia, serif;
  font-style: italic;
  color: inherit;
  margin-left: 0.1em;
}
/* Asymmetric padding on key content sections (May 2026) */
.content-section {
  padding-left: 1.5rem;
  padding-right: 2rem;
  padding-top: 1rem;
  padding-bottom: 2.5rem;
}
@media (max-width: 640px) {
  .content-section {
    padding-left: 1rem;
    padding-right: 1rem;
    padding-top: 0.5rem;
    padding-bottom: 1.5rem;
  }
}

/* ─── Rooms table ───────────────────────────────────────────────── */
.rooms-controls { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }
.rooms-controls select { width: auto; font-size: 0.85rem; padding: 0.4rem 0.65rem; }
.rooms-table-wrap { overflow-x: auto; }
.rooms-table {
  width: 100%; border-collapse: collapse;
  background: #fff; border-radius: 12px; overflow: hidden;
  border: 1.5px solid #e5eaf1;
  font-size: 0.92rem;
}
.rooms-table th {
  background: #f8faff; text-align: left;
  padding: 0.75rem 1rem; font-weight: 600;
  border-bottom: 1.5px solid #e5eaf1; color: #374151;
}
.rooms-table td { padding: 0.75rem 1rem; border-bottom: 1px solid #f1f3f9; }
.rooms-table tr:last-child td { border-bottom: none; }
.rooms-table tr:hover td { background: #f8faff; }
.rooms-table .btn-link {
  background: none; border: none;
  color: #3b5bdb; font-weight: 600; font-size: 0.88rem;
  cursor: pointer; padding: 0;
}
.rooms-table .btn-link:hover { text-decoration: underline; }

/* ─── Stars ─────────────────────────────────────────────────────── */
.stars { display: inline-flex; gap: 1px; }
.star  { font-size: 1rem; color: #d1d8e0; }
.star.filled { color: #f59e0b; }
.rating-badge {
  display: inline-flex; align-items: center; gap: 0.3rem;
  background: #fffbea; color: #92400e;
  border: 1.5px solid #fde68a;
  padding: 0.2rem 0.55rem; border-radius: 20px;
  font-size: 0.82rem; font-weight: 700;
}
.no-rating { color: #6b7280; font-size: 0.82rem; }

/* ─── Photo gallery ─────────────────────────────────────────────── */
.photo-gallery {
  display: flex; gap: 0.75rem; margin-bottom: 1.5rem;
  max-height: 400px;
}
.gallery-main {
  flex: 1; border-radius: 12px; overflow: hidden;
  background: #1a202c;
  display: flex; align-items: center; justify-content: center;
  min-height: 260px;
}
.gallery-main img { width: 100%; height: 100%; object-fit: cover; cursor: zoom-in; }
.no-photo-placeholder { color: #6b7280; font-size: 1rem; }
.gallery-thumbs {
  display: flex; flex-direction: column; gap: 0.5rem;
  overflow-y: auto; max-height: 400px;
}
.gallery-thumb-wrap {
  position: relative; width: 90px; flex-shrink: 0; cursor: pointer;
  border: 2px solid transparent; border-radius: 8px; transition: border-color .15s; overflow: hidden;
}
.gallery-thumb-wrap img {
  width: 90px; height: 68px; object-fit: cover; display: block;
}
.gallery-thumb-wrap.active { border-color: #3b5bdb; }
.gallery-thumb-wrap:hover { border-color: #93a4e8; }
.photo-cat-tag {
  position: absolute; bottom: 3px; left: 3px;
  font-size: .6rem; font-weight: 600; background: rgba(0,0,0,.65);
  color: #fff; border-radius: 4px; padding: .1rem .3rem;
  pointer-events: none; white-space: nowrap; max-width: 85px; overflow: hidden; text-overflow: ellipsis;
}
.photo-cat-tag-main {
  position: absolute; top: 8px; left: 8px; z-index: 2;
  font-size: .72rem; padding: .2rem .5rem; border-radius: 6px; bottom: auto;
}

/* ─── AI photo grade mini-stars (May 2026) ────────────────────────────
   Compact 3-axis indicator overlaying the bottom-right of each photo
   thumbnail. Pill icons (✨ cleanliness / 💡 lighting / 📐 space) sit on
   semi-transparent black so they read against any image. The empty-star
   span is dimmed so the filled count "pops". Hover surfaces the AI's
   comment via the parent's title attribute. */
.ai-grade-chip {
  position: absolute; bottom: 3px; right: 3px;
  display: flex; gap: 3px; align-items: center;
  background: rgba(0,0,0,.65); color: #fff;
  border-radius: 6px; padding: .15rem .3rem;
  font-size: .58rem; pointer-events: auto;
  cursor: help;
  z-index: 2;
}
.ai-grade-pill { display: inline-flex; align-items: center; gap: 1px; }
.ai-grade-pill-icon { font-size: .7rem; line-height: 1; margin-right: 1px; }
.ai-grade-pill-stars { font-size: .65rem; letter-spacing: -.1em; }
.ai-grade-pill-empty { color: rgba(255,255,255,.35); }

/* Smaller AI chip variant for tiny dorm-photo strips where space is tight. */
.dorm-gallery-thumb-wrap .ai-grade-chip { font-size: .55rem; padding: .1rem .25rem; }

/* ─── Mod Quick Capture FAB + modal (May 2026) ────────────────────── */
#mod-fab {
  display: none !important;
}
#mod-fab:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(67,56,202,.5); }
#mod-fab:focus-visible { outline: 3px solid #c7d2fe; outline-offset: 2px; }
@media (max-width: 640px) {
  #mod-fab {
    /* Match the admin-edit-fab convention so the LEFT-side mod FAB clears
       the same 72px mobile bottom nav + iPhone safe-area inset that the
       RIGHT-side admin FAB clears. Without the safe-area term the rocket
       sat directly on top of the nav strip on notched iPhones. */
    bottom: calc(80px + env(safe-area-inset-bottom, 0)) !important;
    left: 1rem !important;
    padding: .7rem .9rem; font-size: .82rem;
  }
  /* Hide the label on phones — keep just the rocket so it's compact */
  #mod-fab > span:last-child { display: none; }
}

.mqc-mode-grid {
  display: grid; gap: .65rem;
  grid-template-columns: repeat(2, 1fr);
}
.mqc-mode-btn {
  background: white; border: 1.5px solid #e5e7eb; border-radius: .65rem;
  padding: 1rem .75rem; cursor: pointer; font-family: inherit;
  display: flex; flex-direction: column; align-items: center; gap: .35rem;
  text-align: center; transition: border-color .12s, box-shadow .12s, transform .12s;
}
.mqc-mode-btn:hover {
  border-color: #6366f1; box-shadow: 0 2px 8px rgba(99,102,241,.15);
  transform: translateY(-1px);
}
.mqc-mode-btn > span:nth-child(2) { font-weight: 700; color: #1f2937; font-size: .95rem; }
.mqc-mode-btn small { color: #6b7280; font-size: .72rem; line-height: 1.3; }

/* ─── Wizard step 2: occupancy radios + furnishings (May 2026) ────── */
.wizard-occ-btn {
  background: white; border: 1.5px solid #d1d5db; border-radius: 999px;
  padding: .35rem .85rem; font-size: .82rem; font-weight: 500;
  color: #374151; cursor: pointer; transition: all .12s; font-family: inherit;
}
.wizard-occ-btn:hover { border-color: #6366f1; color: #4338ca; }
.wizard-occ-btn.selected {
  background: #6366f1; border-color: #4338ca; color: white; font-weight: 600;
  box-shadow: 0 1px 3px rgba(99,102,241,.3);
}
.wizard-occ-btn:focus-visible { outline: 2px solid #6366f1; outline-offset: 2px; }

.wizard-furnishings-grid {
  /* May 2026: switched grid → flex-wrap to pair with the click-the-word
     toggle pill chips. Pills size to content + wrap naturally. */
  display: flex; flex-wrap: wrap; gap: .5rem;
}
/* Click-the-word toggle chips (May 2026, Joshua's feedback): replace
   tiny native checkboxes with full-pill labels that fill when active.
   "Click any word, it highlights and saves; click again to remove."
   Hidden checkbox stays in DOM so all existing read paths
   (_readEditRoomFurnishings, /api/rooms/:id/furnishings, etc.) still work
   unchanged — only the visual is different. Used in both Edit Room
   modal AND wizard step 2. */
.wizard-furnishing-chip {
  display: inline-flex; align-items: center;
  padding: .42rem .85rem;
  font-size: .85rem; font-weight: 500; color: #166534;
  cursor: pointer; user-select: none;
  border: 1.5px solid #bbf7d0;
  background: white;
  border-radius: 999px;
  transition: background .12s, color .12s, border-color .12s, transform .08s;
}
.wizard-furnishing-chip:hover {
  background: #f0fdf4;
  border-color: #86efac;
}
.wizard-furnishing-chip:active { transform: scale(.97); }
/* Hide the native checkbox — the chip itself IS the toggle target */
.wizard-furnishing-chip input { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; }
/* Filled state when input is checked (modern :has selector — gracefully
   degrades to a no-op on older browsers, but iOS 15+ / Chrome 105+ all
   support it; covers >95% of our visitors per Can-I-Use). */
.wizard-furnishing-chip:has(input:checked) {
  background: #16a34a;
  color: white;
  border-color: #16a34a;
  box-shadow: 0 1px 2px rgba(22,163,74,.25);
}
.wizard-furnishing-chip:has(input:checked):hover {
  background: #15803d;
  border-color: #15803d;
}
/* Same treatment for the Edit Room amenity row (.cb-label). Indigo
   instead of green so amenities visually distinguish from furnishings —
   a small UX cue that these are different categories. */
.cb-label {
  display: inline-flex; align-items: center;
  padding: .42rem .85rem;
  font-size: .85rem; font-weight: 500; color: #3730a3;
  cursor: pointer; user-select: none;
  border: 1.5px solid #c7d2fe;
  background: white;
  border-radius: 999px;
  transition: background .12s, color .12s, border-color .12s, transform .08s;
  margin: 0; /* override default label margin */
}
.cb-label:hover {
  background: #eef2ff;
  border-color: #a5b4fc;
}
.cb-label:active { transform: scale(.97); }
.cb-label input { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; }
.cb-label:has(input:checked) {
  background: #6366f1;
  color: white;
  border-color: #6366f1;
  box-shadow: 0 1px 2px rgba(99,102,241,.25);
}
.cb-label:has(input:checked):hover {
  background: #4f46e5;
  border-color: #4f46e5;
}

/* ─── Dorm-page cross-bar tabs (May 2026) ─────────────────────────── */
/* Mirrors the room-page tab pattern. The bar sits inside .dorm-detail-left
   and groups 25+ stacked sections into 4 tabs. Tagging happens via JS at
   runtime so the existing section IDs / render functions / inline-edit
   zones / correction modals all keep working unchanged. */
/* Dorm tab bar — May 2026 standardization. Earlier this had its own
   white-card-with-rounded-corners chrome; per Joshua's feedback the room-
   page underline-style tabs (.tabs / .tab) read cleaner, so the dorm bar
   now matches that pattern exactly. Different active-color is preserved
   per surface for hierarchy: rooms use #3b5bdb blue, dorms use #6366f1
   indigo, but the structure / spacing / weight is identical. */
.dorm-tabs-bar {
  display: flex;
  gap: 0;
  border-bottom: 2px solid #e5eaf1;
  margin: 1rem 0 1.25rem;
  flex-wrap: wrap;
}
.dorm-tab-btn {
  padding: .65rem 1.25rem;
  background: none;
  border: none;
  font-size: .93rem;
  font-weight: 500;
  color: #6b7280;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  transition: color .15s, border-color .15s;
  font-family: inherit;
  white-space: nowrap;
  border-radius: 0;
}
.dorm-tab-btn:hover { color: #1a202c; }
.dorm-tab-btn.active {
  color: #6366f1;
  border-bottom: 3px solid #6366f1;
  margin-bottom: -2px;
  font-weight: 700;
  background: linear-gradient(180deg, rgba(99,102,241,0.06), rgba(99,102,241,0));
}
.dorm-tab-btn.active::after {
  content: "";
  display: block;
  position: relative;
  height: 0;
}
.dorm-tab-btn:focus-visible {
  outline: 2px solid #6366f1;
  outline-offset: -2px;
}
/* The actual hide rule. Scoped to #view-dorm so it can't accidentally
   hide other surfaces. The !important is needed because inline
   style="display:..." from individual renderers would otherwise win. */
#view-dorm [data-tab-hidden="1"] {
  display: none !important;
}

/* ── Inline edit mode removed (May 2026) ─────────────────────────────
   Admins now use the dedicated /admin.html panel for structural edits
   (college / dorm / room details). The inline-edit overlay system —
   pencil-on-hover per section, the floating ✏️ Edit Mode FAB, and the
   header "Edit Mode" toggle — is no longer needed. Hide them via CSS
   rather than ripping out the wiring; the JS handlers stay harmless and
   can be removed later in a dedicated cleanup pass. */
.edit-zone-btn,
#admin-edit-fab,
#admin-edit-toggle-btn {
  display: none !important;
}
/* Also kill the dashed-outline + pointer cursor that the body.edit-mode
   class layered onto every [data-edit-section] container — keeps the
   page looking clean even if the toggle ever leaks back on. */
body.edit-mode [data-edit-section] {
  outline: none !important;
  cursor: default !important;
}
body.edit-mode [data-edit-section]:hover {
  outline: none !important;
}
@media (max-width: 640px) {
  .dorm-tab-btn {
    flex: 1 1 auto;
    padding: .65rem .5rem;
    font-size: .82rem;
    min-width: 0;
  }
}

/* ─── Room photo album (full-detail grid below the carousel) ──────── */
/* Every photo is shown with its category + caption + uploaded date so
   context isn't lost behind a thumbnail. Pairs with _renderRoomPhotoAlbum
   in app.js — the carousel above is for navigation, this album is for
   browsing every photo with full metadata. */
.room-photo-album {
  background: white; border-radius: 12px; padding: 1.25rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08); margin-bottom: 1rem;
}
.room-photo-album-grid {
  display: grid; gap: .75rem;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.room-album-card {
  background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 10px;
  overflow: hidden; display: flex; flex-direction: column;
  transition: box-shadow .15s, transform .15s;
}
.room-album-card:hover {
  box-shadow: 0 4px 12px rgba(0,0,0,0.08); transform: translateY(-1px);
}
.room-album-card img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block;
  background: #1a202c;
}
.room-album-card-meta {
  padding: .55rem .65rem .65rem; display: flex; flex-direction: column; gap: .35rem;
}
.room-album-cat-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: .35rem; flex-wrap: wrap;
}
.room-album-cat-tag {
  font-size: .68rem; font-weight: 600; background: #eef2ff;
  color: #4338ca; border-radius: 999px; padding: .15rem .55rem;
  white-space: nowrap;
}
.room-album-date {
  font-size: .68rem; color: #94a3b8; font-weight: 500;
}
.room-album-caption {
  font-size: .82rem; color: #1f2937; line-height: 1.35;
  word-break: break-word;
}
.room-album-caption-empty {
  color: #cbd5e1; font-style: italic;
}
@media (max-width: 480px) {
  .room-photo-album-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: .5rem;
  }
}

/* ─── Room Brief (room-level tile strip) ────────────────────────── */
/* Smaller analogue of the dorm Brief — surfaces the key room facts
   (AC, bathroom access, bed setup, window count, etc.) as click-to-open
   tiles. Reuses the .brief-* styles for visual consistency but with a
   slimmer card so it fits inside the room overview tab. */
.room-brief-strip {
  background: white; border-radius: 12px; padding: 1rem 1.25rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08); margin-bottom: 1rem;
}
.room-brief-grid {
  display: grid; gap: .5rem;
  grid-template-columns: repeat(auto-fit, minmax(82px, 1fr));
}
.room-brief-cell {
  background: none; border: none; padding: .25rem; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: .35rem;
  border-radius: 8px; transition: background .12s;
}
.room-brief-cell:hover { background: #f8fafc; }
.room-brief-cell:focus-visible { outline: 2px solid #6366f1; outline-offset: 2px; }
.room-brief-cell .brief-icon { width: 40px; height: 40px; border-radius: 10px; }
.room-brief-cell .brief-icon svg { width: 22px; height: 22px; }
.room-brief-cell .brief-label {
  font-size: .68rem; font-weight: 600; color: #475569; text-align: center;
  line-height: 1.2;
}
.room-brief-cell .brief-value {
  font-size: .72rem; color: #0f172a; font-weight: 700;
}
@media (max-width: 480px) {
  .room-brief-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* ─── Room Details stat-card pencils ────────────────────────────── */
.room-stat-pencil {
  background: rgba(255,255,255,.85); border: 1px solid #e2e8f0;
  border-radius: 999px; width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .8rem; cursor: pointer; line-height: 1;
}
.room-stat-pencil:hover { opacity: 1 !important; border-color: #6366f1; }

/* ─── Room title bar ────────────────────────────────────────────── */
.room-title-bar {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; margin-bottom: 1.25rem; flex-wrap: wrap;
}
.room-title-bar h2 { font-size: 1.5rem; font-weight: 700; }
.room-title-actions { display: flex; align-items: center; gap: 0.65rem; flex-wrap: wrap; }
.avg-rating-badge {
  font-size: 1.4rem; font-weight: 800; color: #f59e0b;
  background: #fffbea; border: 2px solid #fde68a;
  border-radius: 10px; padding: 0.35rem 0.75rem;
  display: flex; align-items: center; gap: 0.3rem;
}

/* ─── Tabs ──────────────────────────────────────────────────────── */
.tabs {
  display: flex; gap: 0; border-bottom: 2px solid #e5eaf1;
  margin-bottom: 1.5rem;
}
.tab {
  padding: 0.65rem 1.25rem; background: none; border: none;
  font-size: 0.93rem; font-weight: 500; color: #6b7280;
  border-bottom: 2px solid transparent; margin-bottom: -2px;
  transition: color .15s, border-color .15s;
}
.tab:hover { color: #1a202c; }
.tab.active { color: #3b5bdb; font-weight: 700; border-bottom-color: #3b5bdb; }
.tab-panel { display: none; }
.tab-panel.active { display: block; }

/* .tab-btn — pill-style tabs used on the home colleges grid (Popular /
   Following / All Schools) and elsewhere where a non-underline tab variant
   is needed. Distinct from .tab (the underline-style sibling above). */
.tab-btn {
  padding: 0.5rem 1rem;
  background: #fff;
  border: 1.5px solid #e5eaf1;
  border-radius: 999px;
  font-size: 0.9rem;
  font-weight: 500;
  color: #4b5563;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, box-shadow .15s;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}
.tab-btn:hover { background: #f9fafb; border-color: #c7d2fe; color: #1f2937; }
.tab-btn.active {
  background: #6366f1;
  border-color: #6366f1;
  color: #fff;
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(99,102,241,.35);
}
.tab-btn:focus-visible { outline: 3px solid rgba(99,102,241,.4); outline-offset: 2px; }

/* ─── Overview grid ─────────────────────────────────────────────── */
.overview-grid { display: flex; flex-direction: column; gap: 1.5rem; }
.overview-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px,1fr)); gap: 0.75rem; }
.stat-card {
  background: #fff; border: 1.5px solid #e5eaf1; border-radius: 10px;
  padding: 0.85rem 1rem; text-align: center;
}
.stat-value { font-size: 1.3rem; font-weight: 700; color: #1e3a8a; }
.stat-label { font-size: 0.78rem; color: #6b7280; margin-top: 0.2rem; text-transform: uppercase; letter-spacing: .4px; }

.pros-cons-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 600px) { .pros-cons-grid { grid-template-columns: 1fr; } }
.pros-box, .cons-box {
  background: #fff; border: 1.5px solid #e5eaf1; border-radius: 10px; padding: 1rem 1.1rem;
}
.pros-box h4 { color: #15803d; margin-bottom: 0.65rem; font-size: 0.95rem; }
.cons-box h4 { color: #b91c1c; margin-bottom: 0.65rem; font-size: 0.95rem; }
.pros-box ul, .cons-box ul { list-style: none; display: flex; flex-direction: column; gap: 0.4rem; margin-bottom: 0.75rem; }
.pros-box li, .cons-box li { font-size: 0.88rem; color: #374151; display: flex; align-items: flex-start; gap: 0.4rem; }
.pros-box li::before { content: '✓'; color: #22c55e; font-weight: 700; flex-shrink: 0; }
.cons-box li::before { content: '✗'; color: #ef4444; font-weight: 700; flex-shrink: 0; }
.empty-list { color: #6b7280; font-size: 0.85rem; font-style: italic; }

/* ─── Amenities ─────────────────────────────────────────────────── */
.amenities-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px,1fr));
  gap: 0.75rem; margin-bottom: 1rem;
}
.amenity-chip {
  display: flex; align-items: center; gap: 0.5rem;
  background: #fff; border: 1.5px solid #e5eaf1;
  border-radius: 10px; padding: 0.65rem 0.9rem;
  font-size: 0.88rem; font-weight: 500;
}
.amenity-chip.has  { border-color: #bbf7d0; background: #f0fdf4; color: #15803d; }
.amenity-chip.miss { border-color: #fecaca; background: #fff5f5; color: #6b7280; text-decoration: line-through; }
.amenity-chip .chip-icon { font-size: 1.05rem; }
.extra-notes-box { background: #fffbea; border: 1.5px solid #fde68a; border-radius: 10px; padding: 0.75rem 1rem; font-size: 0.88rem; }

/* ─── Reviews ───────────────────────────────────────────────────── */
#ratings-breakdown { margin-bottom: 1.25rem; }
.rating-summary {
  background: #fff; border: 1.5px solid #e5eaf1; border-radius: 12px;
  padding: 1.1rem 1.35rem; display: flex; gap: 2rem;
  align-items: center; margin-bottom: 1rem; flex-wrap: wrap;
}
.rating-big-num { font-size: 3rem; font-weight: 800; color: #f59e0b; line-height: 1; }
.rating-big-stars { margin: 0.3rem 0; }
.rating-bars { flex: 1; display: flex; flex-direction: column; gap: 0.4rem; min-width: 200px; }
.rating-bar-row { display: flex; align-items: center; gap: 0.5rem; font-size: 0.82rem; }
.bar-label { width: 80px; color: #6b7280; text-align: right; }
.bar-track { flex: 1; height: 7px; background: #e5eaf1; border-radius: 4px; overflow: hidden; }
.bar-fill  { height: 100%; background: #f59e0b; border-radius: 4px; transition: width .5s; }
.review-card {
  background: #fff; border: 1.5px solid #e5eaf1; border-radius: 10px;
  padding: 1rem 1.2rem; margin-bottom: 0.75rem;
}
.review-header { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.4rem; flex-wrap: wrap; }
.reviewer-name { font-weight: 600; font-size: 0.92rem; }
.review-meta { font-size: 0.8rem; color: #6b7280; }
.review-sub-ratings { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-top: 0.5rem; }
.sub-rating { font-size: 0.78rem; color: #6b7280; }
.sub-rating span { color: #f59e0b; }
.review-verified-badge {
  display: inline-flex; align-items: center; gap: .2rem;
  font-size: .72rem; font-weight: 600; padding: .15rem .45rem;
  background: #eff6ff; color: #1d4ed8; border: 1px solid #bfdbfe; border-radius: 20px;
}
.review-type-tag {
  display: inline-flex; align-items: center; gap: .2rem;
  font-size: .72rem; font-weight: 500; padding: .15rem .45rem; border-radius: 20px;
}
.review-type-lived   { background: #f0fdf4; color: #15803d; border: 1px solid #bbf7d0; }
.review-type-visited { background: #fefce8; color: #92400e; border: 1px solid #fde68a; }
.review-verified-resident-badge {
  display: inline-flex; align-items: center; gap: .2rem;
  font-size: .72rem; font-weight: 700; padding: .2rem .55rem;
  background: linear-gradient(135deg, #ecfdf5, #eff6ff);
  color: #15803d; border: 1.5px solid #86efac; border-radius: 20px;
  box-shadow: 0 1px 3px rgba(21,128,61,.15);
}
.review-stale-warning {
  font-size: .78rem; color: #92400e; background: #fffbeb;
  border: 1px solid #fde68a; border-radius: 6px;
  padding: .3rem .6rem; margin: .35rem 0 .25rem; display: inline-block;
}

/* ─── Voting UI ────────────────────────────────────────────────── */
.vote-controls {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  min-width: 32px; user-select: none; flex-shrink: 0;
}
.vote-btn {
  background: none; border: none; cursor: pointer; font-size: 0.7rem;
  color: #6b7280; padding: 2px 6px; border-radius: 4px; line-height: 1;
  transition: color 0.15s, background 0.15s;
}
.vote-btn:hover { background: #f3f4f6; color: #4b5563; }
.vote-btn.vote-active.vote-up { color: #2563eb; }
.vote-btn.vote-active.vote-down { color: #dc2626; }
.vote-score {
  font-size: 0.8rem; font-weight: 700; color: #374151; text-align: center; min-width: 20px;
}
/* 🔥 Trending chip — shown inside .vote-controls and inline in tips/packing
   when an item's net score reaches TRENDING_THRESHOLD (5). */
.vote-trending-chip {
  display: inline-flex; align-items: center; gap: 2px;
  font-size: 0.72rem; font-weight: 700; color: #c2410c;
  background: #fff7ed; border: 1px solid #fdba74;
  border-radius: 999px; padding: 1px 7px;
  white-space: nowrap; line-height: 1.5;
  animation: trendingPulse 2.5s ease-in-out infinite;
}
/* Inline placement for tips and packing (chip is inside .tip-text) */
.tip-text .vote-trending-chip { margin-left: 0.4rem; vertical-align: middle; }
@keyframes trendingPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(251, 146, 60, 0); }
  50%       { box-shadow: 0 0 0 4px rgba(251, 146, 60, 0); }
}
.sort-select {
  font-size: 0.82rem; padding: 0.3rem 0.5rem; border: 1.5px solid #d1d5db;
  border-radius: 6px; background: #fff; color: #374151; cursor: pointer;
}
.sort-select:focus { border-color: #2563eb; outline: none; }

/* ─── Comments ──────────────────────────────────────────────────── */
.comment-card {
  background: #fff; border: 1.5px solid #e5eaf1; border-radius: 10px;
  padding: 0.9rem 1.1rem; margin-bottom: 0.65rem;
}
.comment-card-votable {
  display: flex; gap: 0.75rem; align-items: flex-start;
}
.comment-card-votable .comment-content { flex: 1; min-width: 0; }
.comment-header { display: flex; gap: 0.75rem; align-items: center; margin-bottom: 0.4rem; flex-wrap: wrap; }
.comment-author { font-weight: 600; font-size: 0.88rem; }
.comment-date   { font-size: 0.78rem; color: #6b7280; }
.comment-text   { font-size: 0.9rem; color: #374151; line-height: 1.55; }
.comment-room-badge {
  font-size: 0.72rem; background: #f0fdf4; color: #166534; padding: 1px 8px;
  border-radius: 10px; font-weight: 500;
}
.comment-category-chip {
  font-size: 0.75rem; background: #fef3c7; color: #78350f; padding: 2px 6px;
  border-radius: 6px; font-weight: 500; display: inline-flex; align-items: center;
  gap: 3px; cursor: default;
}

/* ─── Pros/Cons with votes ─────────────────────────────────────── */
.procon-votable {
  display: flex; align-items: center; gap: 0.5rem; padding: 0.3rem 0;
}
.procon-votable .vote-controls { flex-direction: row; gap: 4px; min-width: auto; }

/* ─── Dining Halls (suggestion #39) ───────────────────────────── */
/* Dining halls are presented as a compact SINGLE-column list on the college
   page (admin feedback 2026-04-30 "one per row, smaller, consistent
   columns across each row"). Each row is ~38px tall and uses a strict
   left-to-right column anatomy: icon · name · hours · meal plan · diet
   chips · grade · → arrow. Wrapping only happens on narrow viewports. */
.dining-hall-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: .55rem;
  overflow: hidden;
}
.dining-card {
  cursor: pointer; background: white;
  transition: background .12s;
}
.dining-card:hover { background: #f9fafb; }
.dining-card-row,
.dining-hall-row-header {
  display: grid;
  /* icon · name · hours · meal · diet · grade · → */
  /* hours got 1.7fr (was 1.2) so abbreviated strings fit; name + diet
     gave up some space to compensate. */
  grid-template-columns: 24px minmax(0, 1.2fr) minmax(0, 1.7fr) auto minmax(0, 1.1fr) auto 16px;
  align-items: center;
  gap: .65rem;
  padding: .45rem .8rem;
  font-size: .85rem;
}
.dining-card-row {
  border-bottom: 1px solid #f1f5f9;
  min-height: 38px;
}
.dining-card-row:last-child { border-bottom: none; }
/* Header row — column labels above the list. Visually distinguished from
   data rows by uppercase tiny labels + light gray background. */
.dining-hall-row-header {
  background: #f9fafb;
  color: #6b7280;
  font-size: .68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid #e5e7eb;
  padding-top: .35rem;
  padding-bottom: .35rem;
  cursor: default;
}
.dining-hall-row-header > span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 720px) {
  .dining-hall-row-header { display: none; }
}
.dining-card-thumb {
  width: 24px; height: 24px; border-radius: .25rem;
  object-fit: cover; flex-shrink: 0; display: block;
}
.dining-card-thumb-placeholder {
  background: linear-gradient(135deg,#fef3c7 0%,#fde68a 100%);
  display: flex; align-items: center; justify-content: center;
  font-size: 1rem; color: #92400e;
}
/* "Cells" inside the row — each maps to one of the 7 grid columns above. */
.dining-cell-name {
  font-weight: 600; font-size: .9rem; color: #111827;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  display: flex; align-items: center; gap: .35rem;
}
.dining-cell-hours {
  font-size: .76rem; color: #6b7280;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.dining-cell-meal { /* sized to its content */ }
.dining-cell-diet {
  display: flex; align-items: center; gap: .25rem;
  flex-wrap: wrap; min-width: 0;
}
.dining-cell-diet > * { flex-shrink: 0; }
.dining-cell-grade { /* grade chip auto-width */ }
.dining-cell-arrow {
  text-align: right; color: #6b7280; font-size: .9rem;
}
/* Below ~720px, drop the dedicated hours / arrow columns and stack chips
   under the name on a second visual line. The grid recomputes; cells that
   don't fit drop down to a wrapped row. */
@media (max-width: 720px) {
  .dining-card-row {
    grid-template-columns: 24px 1fr auto;
    grid-template-rows: auto auto;
    row-gap: .25rem;
  }
  .dining-cell-hours,
  .dining-cell-meal,
  .dining-cell-diet {
    grid-column: 2 / -1;
  }
  .dining-cell-arrow { display: none; }
}
/* Legacy banner photo classes — kept for any other surface still using them */
.dining-card-body { /* legacy fallback wrapper used by dorm-page compact card */
  flex: 1; min-width: 0; padding: 0;
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
}
/* Legacy banner photo classes — kept for any other surface still using them */
.dining-card-photo { width: 100%; height: 110px; object-fit: cover; display: block; }
.dining-card-photo-placeholder {
  height: 110px; background: #f9fafb; display: flex;
  align-items: center; justify-content: center; font-size: 2rem;
}
.dining-card-name { font-weight: 700; font-size: .9rem; margin-bottom: .35rem; }
.dining-chip-row { display: flex; flex-wrap: wrap; gap: .3rem; }
.dining-meal-chip, .dining-diet-chip, .dining-walk {
  font-size: .72rem; padding: 1px 7px; border-radius: 999px;
  border: 1px solid #e5e7eb; white-space: nowrap;
}
.dining-meal-chip { background: #eff6ff; color: #1e40af; border-color: #bfdbfe; }
.dining-meal-chip.dining-cash { background: #f0fdf4; color: #15803d; border-color: #bbf7d0; }
.dining-diet-chip { background: #f0fdf4; color: #166534; border-color: #bbf7d0; }
.dining-walk { background: #fef9c3; color: #92400e; border-color: #fde047; }
.dining-card-compact {
  border: 1px solid #e5e7eb; border-radius: .45rem;
  padding: .55rem .7rem; cursor: pointer; background: white;
  transition: box-shadow .12s; min-width: 160px;
}
.dining-card-compact:hover { box-shadow: 0 2px 8px rgba(0,0,0,.07); }
.dining-grade-chip {
  display: inline-block; font-weight: 800; font-size: .8rem;
  padding: 1px 7px; border-radius: .3rem; margin-left: .3rem;
  vertical-align: middle;
}
.dining-grade-big { font-size: 1.25rem; padding: 3px 10px; border-radius: .4rem; }
.dining-hours-block { font-size: .83rem; }
.dining-hours-row { display: flex; justify-content: space-between; gap: .75rem; color: #374151; padding: .12rem 0; }
/* Quick Facts grid inside the dining detail modal — fills the white space
   below the description with structured info (hours, meals, payment,
   diet, walk-time, building, website, notes). 2-col layout: label · value. */
.dining-facts-grid {
  display: grid;
  grid-template-columns: 1fr;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: .55rem;
  overflow: hidden;
  margin: 0 0 1rem;
}
.dining-fact-row {
  display: grid;
  grid-template-columns: minmax(140px, 0.5fr) 1fr;
  align-items: start;
  gap: .85rem;
  padding: .55rem .85rem;
  font-size: .87rem;
  border-bottom: 1px solid #eef2f7;
}
.dining-fact-row:last-child { border-bottom: none; }
.dining-fact-label {
  color: #6b7280;
  font-weight: 600;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: .35rem;
}
.dining-fact-value {
  color: #111827;
  min-width: 0;
  word-break: break-word;
}
.dining-fact-value > .dining-hours-block { margin: 0; }
@media (max-width: 560px) {
  .dining-fact-row { grid-template-columns: 1fr; row-gap: .15rem; }
  .dining-fact-label { font-size: .78rem; }
}

/* "Suggest hours" form — per-meal-period grid inside #modal-suggest-hours.
   Each row: meal label · days input · hours input. */
.sh-form { display: flex; flex-direction: column; gap: .35rem; }
.sh-row {
  display: grid;
  grid-template-columns: 90px 1.1fr 1.4fr;
  gap: .55rem;
  align-items: center;
}
.sh-row-header { padding: 0 0 .15rem; }
.sh-col-header {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: #6b7280;
  font-weight: 700;
}
.sh-label {
  font-size: .85rem;
  font-weight: 600;
  color: #374151;
  white-space: nowrap;
}
.sh-input {
  font-size: .85rem;
  padding: .4rem .55rem;
  border: 1px solid #d1d5db;
  border-radius: .35rem;
  background: white;
  font-family: inherit;
  min-width: 0;
}
.sh-input:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--md-sys-color-primary, #6366f1) 30%, transparent);
  outline-offset: 1px;
  border-color: var(--md-sys-color-primary, #6366f1);
}
@media (max-width: 560px) {
  .sh-row { grid-template-columns: 1fr; }
  .sh-row-header { display: none; }
  .sh-label { font-size: .8rem; color: #6b7280; }
}
.dining-avg-row { display: flex; gap: .75rem; flex-wrap: wrap; }
.dining-avg-cell { text-align: center; }
.dining-avg-num { font-size: 1.25rem; font-weight: 800; color: #1f2937; }
.dining-avg-lbl { font-size: .68rem; color: #6b7280; text-transform: uppercase; }
.dining-reviews-list { display: flex; flex-direction: column; gap: .5rem; }
.dining-review-card { background: #f9fafb; border: 1px solid #e5e7eb; border-radius: .4rem; padding: .6rem .75rem; }
.dining-vote-btn { transition: background-color 120ms ease, border-color 120ms ease; }
.dining-vote-btn:hover { background: #f3f4f6 !important; }
.dining-vote-btn.dining-vote-active-up { background: #dcfce7 !important; border-color: #86efac !important; color: #166534; }
.dining-vote-btn.dining-vote-active-down { background: #fee2e2 !important; border-color: #fca5a5 !important; color: #991b1b; }
.dining-review-header { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.dining-review-stars { color: #f59e0b; font-size: .85rem; }
.dining-rating-row { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: .5rem; }

/* ─── Dorm community ratings bars (suggestion #31) ────────────── */
.dcr-row {
  display: flex; align-items: center; gap: .6rem;
  margin-bottom: .45rem;
}
.dcr-label {
  font-size: .82rem; font-weight: 500; min-width: 140px;
  color: #374151; white-space: nowrap;
}
.dcr-track {
  flex: 1; height: 7px; background: #e5e7eb; border-radius: 999px;
  overflow: hidden;
}
.dcr-fill {
  height: 100%; background: linear-gradient(90deg, #6366f1, #8b5cf6);
  border-radius: 999px; transition: width .3s ease;
}
.dcr-val {
  font-size: .82rem; font-weight: 700; color: #1f2937; min-width: 36px;
  text-align: right;
}
.dcr-outof { font-weight: 400; color: #6b7280; }

/* ─── Photo vote bar ───────────────────────────────────────────── */
.photo-vote-bar {
  display: flex; align-items: center; gap: 0.5rem; padding: 0.4rem 0.2rem;
}
.photo-vote-bar .vote-controls { flex-direction: row; gap: 4px; min-width: auto; }
.photo-caption-inline { font-size: 0.8rem; color: #6b7280; }

/* ─── Search results ────────────────────────────────────────────── */
.search-result-card {
  background: #fff; border: 1.5px solid #e5eaf1; border-radius: 10px;
  padding: 1rem 1.2rem; margin-bottom: 0.75rem;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; cursor: pointer;
  transition: box-shadow .15s, border-color .15s;
}
.search-result-card:hover { box-shadow: 0 3px 12px rgba(59,91,219,.1); border-color: #b5c5f0; }
.src-main { font-weight: 700; font-size: 1rem; }
.src-sub  { font-size: 0.83rem; color: #6b7280; margin-top: 0.2rem; }

/* ─── Modals ────────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; z-index: 500;
  background: rgba(10,20,50,.45); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; padding: 1rem;
}
.modal {
  background: #fff; border-radius: 16px; padding: 1.75rem;
  max-width: 460px; width: 100%;
  max-height: 85vh;
  max-height: 85dvh; /* mobile-keyboard-safe */
  box-shadow: 0 20px 60px rgba(0,0,0,.2);
  display: flex; flex-direction: column; gap: 0.85rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* position:relative is REQUIRED so that .modal-close-x buttons (which use
     position:absolute;top:.5rem;right:.5rem) anchor to the modal card and
     not the viewport. Without this, 9 modals had their close-X positioned
     relative to <body> — invisible to users. Fixed site-wide 2026-05-07
     after the referral modal close-button bug surfaced this. Adding it
     here means every existing AND future modal gets correct close-X
     positioning automatically. */
  position: relative;
}
.modal-wide { max-width: 800px; }
.modal h3 { font-size: 1.2rem; font-weight: 700; }
.modal h4 { font-size: 0.95rem; font-weight: 600; }
.modal-actions { display: flex; gap: 0.65rem; margin-top: 0.5rem; }
.form-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px,1fr)); gap: 0.75rem; }
.form-row-inline { display: flex; gap: 0.5rem; }
/* Switched grid → flex-wrap May 2026 to pair with the click-the-word
   toggle chip styling (.cb-label). Pills size to content so they
   wrap naturally instead of stretching to fill rigid grid cells. */
.checkbox-grid { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.cb-label { flex-direction: row; align-items: center; gap: 0.5rem; font-weight: 400; cursor: pointer; }
.cb-label input[type=checkbox] { width: auto; accent-color: #3b5bdb; }

/* ─── Modal mobile responsiveness (all modals non-scrolling on mobile) ─── */
@media (max-width: 640px) {
  .modal {
    padding: 1rem;
    max-height: 90vh;
    max-height: 90dvh; /* mobile-keyboard-safe */
  }
  .modal h3 { font-size: 1.1rem; }
  .modal h4 { font-size: 0.9rem; }
  .modal-actions { gap: 0.5rem; margin-top: 0.35rem; }
}

@media (max-width: 480px) {
  .modal {
    padding: 0.75rem;
    max-height: 95vh;
    max-height: 95dvh; /* mobile-keyboard-safe */
  }
  .modal h3 { font-size: 1rem; }
  .modal h4 { font-size: 0.85rem; }
  .form-row { gap: 0.5rem; }
  .form-row-inline { gap: 0.35rem; }
}

/* ─── Star picker ───────────────────────────────────────────────── */
.star-field { display: flex; align-items: center; gap: 1rem; }
.star-field label { width: 90px; flex-shrink: 0; }
.star-picker { display: flex; gap: 2px; }
.star-picker .sp-star {
  font-size: 1.5rem; cursor: pointer; color: #d1d8e0;
  transition: color .1s, transform .1s;
  user-select: none;
}
.star-picker .sp-star:hover,
.star-picker .sp-star.selected { color: #f59e0b; transform: scale(1.15); }

/* ─── Lightbox ──────────────────────────────────────────────────── */
/* ── Photo Tour Lightbox / Carousel ────────────────────────────── */
.lightbox { position: fixed; inset: 0; z-index: 600; display: flex; align-items: center; justify-content: center; }
.lightbox-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.9); }
.lightbox-content { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; max-width: 92vw; }
.lightbox-img { max-width: 88vw; max-height: 80vh; object-fit: contain; border-radius: 8px; box-shadow: 0 4px 32px rgba(0,0,0,.5); }
.lightbox-meta {
  display: flex; flex-direction: column; align-items: center;
  gap: .35rem; margin-top: .6rem;
}
.lightbox-category {
  font-size: .72rem; font-weight: 600;
  background: rgba(99, 102, 241, .25); color: #c7d2fe;
  border: 1px solid rgba(99, 102, 241, .45);
  border-radius: 999px; padding: .2rem .65rem;
  letter-spacing: .02em;
}
.lightbox-caption { color: #e5e7eb; font-size: .9rem; text-align: center; max-width: 60ch; margin: 0; }
.lightbox-counter { color: #d1d5db; font-size: .78rem; margin-top: .25rem; }
/* Safe-area aware (May 2026 — viewport-fit=cover lit up env() values).
 * Without these, the close button on iPhone Pro Max sits under the
 * Dynamic Island and prev/next nav buttons sit under rounded corners.
 * The 1rem fallback matches the original positioning when no inset
 * applies (desktop, non-notched phones). */
.lightbox-close {
  position: absolute;
  top: max(1rem, calc(1rem + env(safe-area-inset-top)));
  right: max(1.25rem, calc(1.25rem + env(safe-area-inset-right)));
  z-index: 2;
  background: rgba(255,255,255,.15); border: none; color: #fff;
  font-size: 1.2rem;
  /* Bumped from 2.2rem (35.2px) to 2.75rem (44px) to clear the 44×44
   * iOS Human-Interface tap-target floor. */
  width: 2.75rem; height: 2.75rem; min-width: 44px; min-height: 44px;
  border-radius: 50%; display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: background .15s;
}
.lightbox-close:hover { background: rgba(255,255,255,.3); }
.lightbox-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  z-index: 2; background: rgba(255,255,255,.15); border: none; color: #fff;
  font-size: 2.2rem;
  width: 2.8rem; height: 2.8rem; min-width: 44px; min-height: 44px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: background .15s; line-height: 1;
}
.lightbox-nav:hover { background: rgba(255,255,255,.3); }
.lightbox-prev { left: max(1rem, calc(1rem + env(safe-area-inset-left))); }
.lightbox-next { right: max(1rem, calc(1rem + env(safe-area-inset-right))); }

/* ─── Toasts ────────────────────────────────────────────────────── */
.toast-container { position: fixed; bottom: 1.5rem; right: 1.5rem; z-index: 700; display: flex; flex-direction: column; gap: 0.5rem; }
.toast {
  background: #1e293b; color: #fff;
  padding: 0.75rem 1.25rem; border-radius: 10px;
  font-size: 0.88rem; font-weight: 500;
  box-shadow: 0 4px 14px rgba(0,0,0,.25);
  animation: slideUp .25s ease;
}
.toast.success { background: #15803d; }
.toast.error   { background: #b91c1c; }
.toast.info    { background: #2563eb; }
@keyframes slideUp { from { opacity:0; transform:translateY(12px) } to { opacity:1; transform:translateY(0) } }

/* ─── Empty state ───────────────────────────────────────────────── */
.empty-state {
  text-align: center; padding: 3rem 1rem; color: #6b7280;
}
.empty-state .empty-icon { font-size: 3rem; margin-bottom: 0.75rem; }
.empty-state p { font-size: 1rem; }

/* ─── Responsive ────────────────────────────────────────────────── */
@media (max-width: 640px) {
  .hero { padding: 1.75rem 1.25rem; }
  .hero-search { flex-direction: column; }
  .header-inner { flex-wrap: wrap; }
  .photo-gallery { flex-direction: column; max-height: none; }
  .gallery-thumbs { flex-direction: row; overflow-x: auto; max-height: none; }
  .gallery-thumb-wrap { flex-shrink: 0; }
  .gallery-thumb-wrap img { width: 80px; height: 60px; }
  .room-title-bar { flex-direction: column; }
  .rating-summary { flex-direction: column; gap: 1rem; }
}

/* ─── College landing page ──────────────────────────────────────── */
.college-hero {
  position: relative; border-radius: 16px; overflow: hidden;
  min-height: 320px; background: #1a2748; margin-bottom: 0;
}
.college-hero-img-wrap {
  position: absolute; inset: 0;
}
.college-hero-img-wrap img {
  width: 100%; height: 100%; object-fit: cover; opacity: .55;
}
.college-hero-placeholder {
  width: 100%; height: 100%; display: flex; align-items: center;
  justify-content: center; font-size: 5rem; opacity: .25;
  background: linear-gradient(135deg,#1a2748 0%,#2d4a8a 100%);
}
.college-hero-overlay {
  position: relative; z-index: 2; padding: 2.5rem 2rem 2rem;
  display: flex; flex-direction: column; gap: 0.75rem;
  min-height: 320px; justify-content: flex-end;
}
.college-hero-logo-wrap {
  position: absolute; top: 1.5rem; right: 1.5rem;
  width: 80px; height: 80px;
}
.college-hero-logo-wrap img {
  width: 100%; height: 100%; object-fit: contain;
  /* Suggestion #S-123 fix (May 2026, Valerie K.): switched from pure-white
     backdrop to a soft slate gradient so white logos (e.g. SUNY ESF's
     wordmark) remain visible. Slate-100 → slate-300 with a slate-400
     border gives white logos clear edges while keeping colored logos
     looking neutral. */
  background: linear-gradient(135deg,#f1f5f9,#cbd5e1);
  border: 1px solid #94a3b8;
  border-radius: 12px; padding: 6px;
}
/* A11y contrast pass — bump amber chips to a darker text color and tighten
   the white-on-gradient hero CTA contrast so they pass WCAG AA at 4.5:1. */
.qf-chip { color: #1f2937; }            /* was inheriting lighter slate */
.themed-floor {
  background: #cffafe;
  color: #155e75;                        /* was #06b6d4 — fails on pale bg */
  border: 1px solid #67e8f9;
}
.freshness-amber {
  color: #78350f;                        /* darken from default amber-on-amber */
  background: #fef3c7;
  border-color: #fcd34d;
}
.freshness-red {
  color: #7f1d1d;
  background: #fee2e2;
  border-color: #fca5a5;
}
.hero-search input,
.hero-hint a.hero-link {
  /* hero is on indigo gradient — bump opacity/weight so it passes contrast */
  font-weight: 500;
}
.hero-hint a.hero-link {
  color: #fff;                           /* was rgba(255,255,255,.78) */
  text-decoration: underline;
}

/* Keyboard navigation focus ring on dorm grid cards */
.dorm-card:focus-visible {
  outline: 3px solid #6366f1;
  outline-offset: 2px;
  border-radius: 0.6rem;
}

/* Reviewer avatar (initial-only, deterministic color from name hash) */
.reviewer-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  font-size: 0.85rem;
  font-weight: 700;
  margin-right: 0.35rem;
  flex: 0 0 30px;
}
/* Inline class-year chip in the review header — visually subordinate to
   the reviewer name but always present so users can scan author standing */
.reviewer-class-inline {
  font-size: 0.72rem;
  background: #eef2ff;
  color: #3730a3;
  border-color: #c7d2fe;
}

/* Unified "How fresh is this data?" block on the room page */
.data-freshness-block {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 0.65rem;
  padding: 0.85rem 1rem;
  margin-bottom: 1.25rem;
}
.data-freshness-title {
  margin: 0 0 .55rem 0;
  font-size: 0.85rem;
  font-weight: 700;
  color: #334155;
  letter-spacing: 0.01em;
}
.data-freshness-block .freshness-strip {
  margin-bottom: 0;
  display: flex; flex-wrap: wrap; gap: 0.4rem;
}
.data-freshness-block #ai-summary-section {
  margin: 0.65rem 0 0 0;
  padding: 0.75rem 0.9rem;
  background: linear-gradient(135deg, #eff6ff 0%, #f0f9ff 100%);
  border: 1px solid #bfdbfe;
  border-radius: 0.5rem;
}
.ai-summary-header {
  display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.4rem;
}
.ai-summary-label {
  font-size: 0.85rem; font-weight: 600; color: #1d4ed8;
}
.ai-summary-badge {
  font-size: 0.72rem; color: #475569;
  background: #e2e8f0; padding: 0.1rem 0.4rem; border-radius: 999px;
}
.ai-summary-text {
  margin: 0; font-size: 0.9rem; color: #1e3a5f; line-height: 1.55;
}

/* "If Walls Could Talk" anecdotes — dorm page section */
.anecdote-card {
  background: linear-gradient(135deg, #f5f3ff 0%, #ede9fe 100%);
  border: 1px solid #ddd6fe;
  border-radius: 0.55rem;
  padding: 0.85rem 1.05rem;
  margin-bottom: 0.55rem;
}
.anecdote-card-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 0.5rem; margin-bottom: 0.45rem; flex-wrap: wrap;
}
.anecdote-chips { display: flex; gap: 0.3rem; flex-wrap: wrap; }
.anecdote-chip {
  background: rgba(255,255,255,0.7); color: #4c1d95;
  padding: 0.12rem 0.5rem; border-radius: 999px;
  font-size: 0.72rem; font-weight: 600;
}
.anecdote-verified-badge {
  background: #dcfce7; color: #14532d; border: 1px solid #bbf7d0;
  padding: 0.1rem 0.5rem; border-radius: 999px;
  font-size: 0.72rem; font-weight: 700;
}
.anecdote-byline {
  font-size: 0.74rem; color: #6b7280;
}
.anecdote-body {
  font-size: 0.91rem; color: #1f2937; line-height: 1.55; margin: 0 0 0.45rem;
}
.anecdote-source {
  font-size: 0.78rem; color: #6d28d9; text-decoration: none; font-weight: 500;
}
.anecdote-source:hover { text-decoration: underline; }

/* Notable alumni / "Famous people who lived here" — dorm page section */
.alumni-card {
  background: linear-gradient(135deg, #fef9c3 0%, #fef3c7 100%);
  border: 1px solid #fde68a;
  border-radius: 0.6rem;
  padding: 0.75rem 1rem;
  margin-bottom: 0.6rem;
}
.alumni-card-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 0.5rem; margin-bottom: 0.35rem; flex-wrap: wrap;
}
.alumni-name {
  font-size: 1rem; font-weight: 700; color: #78350f;
}
.alumni-chips { display: flex; gap: 0.3rem; flex-wrap: wrap; }
.alumni-chip {
  background: rgba(255,255,255,0.65); color: #92400e;
  padding: 0.12rem 0.5rem; border-radius: 999px;
  font-size: 0.72rem; font-weight: 600;
}
.alumni-claim {
  font-size: 0.88rem; color: #1f2937; margin: 0 0 0.45rem; line-height: 1.45;
}
.alumni-source {
  font-size: 0.78rem; color: #4338ca; text-decoration: none; font-weight: 500;
}
.alumni-source:hover { text-decoration: underline; }

/* ── Compact alumni cards (Apr 2026, suggestion #45) ─────────────────────
   The default alumni-card uses a generous vertical layout that takes too
   much real estate when a dorm has 10+ alumni. The compact variant fits
   each card into ~70px (down from ~180px), shows the first 5 in a
   scrollable box, and is click-to-open on the new alumni detail modal. */
.alumni-list-box {
  max-height: 420px;       /* ~5 compact cards visible before scroll */
  overflow-y: auto;
  padding-right: 4px;       /* breathing room for the scrollbar */
  margin-bottom: .6rem;
}
.alumni-list-box::-webkit-scrollbar { width: 6px; }
.alumni-list-box::-webkit-scrollbar-thumb { background: #fde68a; border-radius: 3px; }
.alumni-card-compact {
  padding: .55rem .85rem;
  margin-bottom: .45rem;
  cursor: pointer;
  transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.alumni-card-compact:hover { transform: translateY(-1px); box-shadow: 0 2px 8px rgba(180,131,11,.18); border-color: #f59e0b; }
.alumni-card-compact:focus-visible { outline: 2px solid #6366f1; outline-offset: 2px; }

/* ─── Compact alumni rows on the college page (May 2026) ────────────────────
 * Replaces the card grid with one-row-per-alumnus list. Click anywhere on
 * the row → opens openAlumniDetailModal() with full context. Saves ~70%
 * vertical real estate on schools with deep rosters. */
.alumni-rows-list {
  display: flex;
  flex-direction: column;
  border: 1px solid #e5e7eb;
  border-radius: .5rem;
  overflow: hidden;        /* clip the per-row borders at the rounded corners */
}
.alumni-row {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .55rem .85rem;
  background: white;
  border-top: 1px solid #f3f4f6;
  cursor: pointer;
  transition: background-color .12s ease;
}
.alumni-row:first-child { border-top: 0; }
.alumni-row:hover {
  background: #fafafe;     /* very subtle indigo tint, distinguishable from white */
}
.alumni-row:focus-visible {
  outline: 2px solid var(--md3-primary, #6366f1);
  outline-offset: -2px;
  background: #f5f6ff;
}
.alumni-row-name {
  font-weight: 700;
  font-size: .92rem;
  color: #1f2937;
  flex: 0 0 auto;
  min-width: 140px;
  white-space: nowrap;
}
.alumni-row-chips {
  display: inline-flex;
  flex-wrap: wrap;
  gap: .25rem;
  flex: 0 0 auto;
}
.alumni-row-claim {
  flex: 1 1 100px;
  font-size: .85rem;
  color: #6b7280;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;            /* lets the flex item actually shrink + truncate */
}
.alumni-row-arrow {
  flex: 0 0 auto;
  color: #9ca3af;
  font-size: 1.1rem;
  font-weight: 600;
  margin-left: .25rem;
}
/* On narrow screens, stack name + chips on top, claim below — staying
 * compact but no longer fighting for horizontal space. */
@media (max-width: 720px) {
  .alumni-row {
    flex-direction: column;
    align-items: stretch;
    gap: .35rem;
    padding: .65rem .75rem;
  }
  .alumni-row-name { min-width: 0; white-space: normal; }
  .alumni-row-claim { white-space: normal; flex: 1 1 auto; }
  .alumni-row-arrow { display: none; }
}
.alumni-card-row {
  display: flex; justify-content: space-between; align-items: center;
  gap: .5rem; flex-wrap: wrap; margin-bottom: .25rem;
}
/* Avatar slot on the alumni-card row (May 2026 — every approved
   alumnus gets either a real headshot OR a deterministic colored
   initials circle). Sized to align cleanly with the name + chips
   on the same row; flex-shrink:0 keeps the circle tight when chips
   wrap. Fallback styles use inline background/color from the JS
   render so identical names always get the same color across views. */
.alumni-avatar {
  width: 36px; height: 36px; border-radius: 50%;
  flex-shrink: 0; object-fit: cover;
  border: 1px solid rgba(0, 0, 0, 0.06);
  background: #f3f4f6;
}
.alumni-avatar-fallback {
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: .82rem; letter-spacing: .02em;
  user-select: none;
}
.alumni-name-wrap {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: .15rem;
}
.alumni-card-compact .alumni-name { font-size: .92rem; }
.alumni-claim-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  margin: 0 0 .35rem;
  font-size: .82rem;
  line-height: 1.4;
  color: #1f2937;
}
.alumni-card-footer {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  font-size: .78rem;
}
.alumni-card-footer .vote-buttons {
  display: inline-flex; flex-direction: row; gap: .15rem; align-items: center;
  margin-left: auto;     /* push votes to the right */
}
.alumni-card-footer .vote-buttons button { padding: .1rem .35rem; font-size: .7rem; }
.alumni-card-footer .vote-buttons .vote-score { font-size: .78rem; min-width: 1.5rem; }

/* Alumni detail modal (placeholder for future biographical info) */
.alumni-detail-card { max-width: 560px; padding: 1.5rem 1.75rem 1.25rem; position: relative; }
.alumni-detail-close {
  position: absolute; top: .75rem; right: .85rem; background: none; border: none;
  font-size: 1.3rem; cursor: pointer; color: #6b7280;
}
.alumni-detail-name { margin: 0 0 .5rem; font-size: 1.4rem; color: #78350f; font-weight: 800; }
.alumni-detail-chips { display: flex; gap: .35rem; flex-wrap: wrap; margin-bottom: .85rem; }
.alumni-detail-claim {
  font-size: 1rem; line-height: 1.55; color: #1f2937;
  background: linear-gradient(135deg, #fef9c3 0%, #fef3c7 100%);
  border-left: 4px solid #fbbf24;
  padding: .85rem 1rem; border-radius: .35rem; margin: 0 0 1rem;
}
.alumni-detail-bio { margin: 1rem 0; }
.alumni-detail-bio h3 { font-size: .9rem; color: #78350f; text-transform: uppercase; letter-spacing: .04em; margin: 0 0 .3rem; }
.alumni-detail-bio p { font-size: .9rem; line-height: 1.55; color: #374151; margin: 0; white-space: pre-wrap; }
.alumni-detail-bio-placeholder {
  font-size: .85rem; color: #6b7280; font-style: italic;
  background: #f9fafb; border: 1px dashed #d1d5db; border-radius: .35rem;
  padding: .65rem .85rem; margin: 0 0 1rem;
}
.alumni-detail-sources { display: flex; gap: 1rem; flex-wrap: wrap; padding-top: .75rem; border-top: 1px solid #e5e7eb; }
.alumni-detail-sources a { font-size: .85rem; color: #4338ca; text-decoration: none; }
.alumni-detail-sources a:hover { text-decoration: underline; }

/* "View all" button — compact pill */
.alumni-see-all-btn {
  display: block; margin-top: .35rem; padding: .45rem 1rem;
  background: white; border: 1px solid #fcd34d; color: #78350f;
  border-radius: 999px; cursor: pointer; font-weight: 600; font-size: .82rem;
  transition: background .12s ease;
}
.alumni-see-all-btn:hover { background: #fef3c7; }

/* ── Link report button + modal (Apr 2026 broken-link reporting) ─────────── */
.link-report-btn {
  background: none; border: none; padding: 0 .25rem; margin-left: auto;
  cursor: pointer; font-size: .95rem; opacity: .55; line-height: 1;
  transition: opacity .12s ease, transform .12s ease;
}
.link-report-btn:hover { opacity: 1; transform: scale(1.15); }
.lr-modal {
  position: fixed; inset: 0; z-index: 5000;
  display: none; align-items: center; justify-content: center;
  padding: 1rem;
}
.lr-modal.open { display: flex; }
.lr-modal-backdrop {
  position: absolute; inset: 0; background: rgba(0,0,0,.55);
}
.lr-modal-card {
  position: relative; z-index: 1;
  background: white; border-radius: .7rem;
  max-width: 460px; width: 100%;
  box-shadow: 0 20px 60px rgba(0,0,0,.25);
  display: flex; flex-direction: column;
  max-height: 90vh; overflow-y: auto;
}
.lr-modal-header {
  display: flex; align-items: flex-start; gap: .65rem;
  padding: 1rem 1.1rem .85rem;
  border-bottom: 1px solid #e5e7eb;
}
.lr-modal-body { padding: 1rem 1.1rem .25rem; }
.lr-reason {
  display: flex; align-items: center; gap: .35rem;
  font-size: .85rem; color: #374151; cursor: pointer;
  padding: .35rem .55rem; border: 1px solid #e5e7eb; border-radius: .35rem;
  transition: border-color .12s ease, background .12s ease;
}
.lr-reason:hover { background: #f9fafb; }
.lr-reason input[type="radio"] { accent-color: #6366f1; }
.lr-reason:has(input:checked) { background: #eef2ff; border-color: #6366f1; }

/* Notable alumni chip on the room page (when room_id matches) */
.room-alumni-chips { margin: 0.5rem 0 0.75rem; }
.room-alumni-strip {
  background: #fef9c3; border: 1px solid #fde68a;
  border-radius: 0.55rem; padding: 0.55rem 0.85rem;
  display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap;
}
.room-alumni-label {
  font-size: 0.78rem; font-weight: 700; color: #78350f;
}
.room-alumni-card {
  background: white; border: 1px solid #fde68a; border-radius: 0.4rem;
  padding: 0.35rem 0.6rem; display: inline-flex; flex-direction: column;
  text-decoration: none; color: #1f2937; font-size: 0.8rem;
  transition: transform 0.12s ease;
}
.room-alumni-card:hover { transform: translateY(-1px); }
.room-alumni-card strong { color: #78350f; font-size: 0.86rem; }
.room-alumni-claim { color: #4b5563; font-size: 0.74rem; max-width: 300px; }
.room-alumni-era { color: #92400e; font-size: 0.7rem; font-weight: 600; }

/* Top Dorms strip on the college page */
.college-top-dorms-section {
  background: linear-gradient(135deg, #fef3c7 0%, #fef9c3 100%);
  border: 1px solid #fde68a;
  border-radius: 0.7rem;
  padding: 1rem 1.1rem;
  margin: 1.5rem 0 0.5rem 0;
}
.college-top-dorms-section h2 {
  font-size: 1.05rem; font-weight: 700; color: #78350f;
  margin: 0 0 .15rem 0;
}
.top-dorms-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 0.65rem;
}
.top-dorm-card {
  position: relative; display: flex;
  background: white; border: 1px solid #fde68a; border-radius: 0.55rem;
  text-decoration: none; color: #1f2937;
  overflow: hidden; cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.top-dorm-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(217, 119, 6, 0.18);
}
.top-dorm-rank {
  position: absolute; top: 0.4rem; left: 0.4rem;
  font-size: 1.15rem; line-height: 1;
  background: rgba(255,255,255,.92); border-radius: 999px;
  padding: 0.2rem 0.4rem; z-index: 1;
}
.top-dorm-photo {
  width: 92px; height: 92px; object-fit: cover; flex: 0 0 92px;
}
.top-dorm-photo-placeholder {
  display: flex; align-items: center; justify-content: center;
  background: #f1f5f9; font-size: 2rem;
}
.top-dorm-body {
  padding: 0.55rem 0.7rem; display: flex; flex-direction: column;
  justify-content: center; gap: 0.25rem; min-width: 0;
}
.top-dorm-name {
  font-weight: 700; font-size: 0.92rem; color: #1f2937;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.top-dorm-rating {
  font-size: 0.82rem; display: flex; align-items: center; gap: 0.3rem;
}
.top-dorm-stars { color: #f59e0b; letter-spacing: 0.5px; }
.top-dorm-num { font-weight: 700; color: #78350f; }
.top-dorm-count { font-size: 0.75rem; }

/* Sticky in-page nav for the dorm detail page */
.dorm-section-nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255,255,255,0.96);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid #e5e7eb;
  margin: 0 -1rem 1.25rem -1rem;
  padding: 0.4rem 1rem;
}
.dorm-section-nav-inner {
  display: flex;
  gap: 0.4rem;
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: #cbd5e1 transparent;
}
.dorm-section-nav-inner::-webkit-scrollbar { height: 4px; }
.dorm-section-nav-inner::-webkit-scrollbar-thumb {
  background: #cbd5e1; border-radius: 2px;
}
.dorm-section-nav-link {
  flex: 0 0 auto;
  padding: 0.4rem 0.85rem;
  border-radius: 999px;
  background: #f1f5f9;
  color: #475569;
  font-size: 0.83rem;
  font-weight: 500;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
  white-space: nowrap;
}
.dorm-section-nav-link:hover {
  background: #e2e8f0;
  color: #1e293b;
}
.dorm-section-nav-link.active {
  background: #eef2ff;
  color: #4338ca;
  border-color: #c7d2fe;
  font-weight: 600;
}
@media (max-width: 640px) {
  .dorm-section-nav { padding: 0.3rem 1rem; }
  .dorm-section-nav-link { font-size: 0.8rem; padding: 0.45rem 0.85rem; }
}

/* Zero-results suggestion cards (home search) */
.zero-results-suggestions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.5rem;
  max-width: 540px;
  margin: 0 auto;
}
.zero-results-card {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 0.5rem;
  padding: 0.65rem 0.85rem;
  text-align: left;
  text-decoration: none;
  color: #1f2937;
  transition: border-color 0.12s ease, transform 0.12s ease;
}
.zero-results-card:hover {
  border-color: #6366f1;
  transform: translateY(-1px);
}

/* Mobile tap-target sizing — bumps interactive controls to ≥44px high on
   small screens per WCAG 2.5.5 + iOS HIG guidance. Affects quick-filter
   chips, star pickers, compare bar buttons, and review vote buttons. */
@media (max-width: 640px) {
  .qf-chip {
    min-height: 44px;
    padding: 0.55rem 0.85rem;
    font-size: 0.92rem;
  }
  .star-btn,
  button.star-btn,
  .star-picker button {
    min-width: 40px;
    min-height: 40px;
    font-size: 1.4rem;
    padding: 0.3rem 0.4rem;
  }
  .dorm-cmp-btn,
  .compare-bar button,
  #dorm-compare-bar button,
  #compare-bar button {
    min-height: 44px;
    padding: 0.6rem 1rem;
    font-size: 0.92rem;
  }
  .vote-btn,
  .helpful-vote-btn {
    min-height: 40px;
    min-width: 56px;
    padding: 0.45rem 0.85rem;
    font-size: 0.92rem;
  }
}

/* Shared "Show all N" / "Show fewer" toggle for collapse-long-section pattern */
.show-more-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem;
  margin-top: 0.65rem; padding: 0.35rem 0.85rem;
  background: #f1f5f9; color: #4b5563;
  border: 1px solid #d1d5db; border-radius: 999px;
  font-size: 0.83rem; font-weight: 500; cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.show-more-btn:hover { background: #e5e7eb; color: #1f2937; }

/* Recent-search chips below the home hero search */
.recent-searches {
  display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center;
  margin-top: 0.65rem;
  font-size: 0.82rem;
}
.recent-searches-label {
  color: rgba(255,255,255,.78); font-weight: 600; margin-right: 0.25rem;
}
.recent-search-chip {
  background: rgba(255,255,255,.18); color: #fff;
  border: 1px solid rgba(255,255,255,.32); border-radius: 999px;
  padding: 0.28rem 0.7rem; cursor: pointer;
  font-size: 0.82rem; font-weight: 500;
  transition: background 0.12s ease;
  /* Mobile: long college names like "University of California, Berkeley"
     used to push other chips off-screen. Cap at 60% of the viewport with
     ellipsis so a row of chips stays scannable. Desktop is unrestricted. */
  max-width: 60vw;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.recent-search-chip:hover { background: rgba(255,255,255,.28); }
@media (min-width: 641px) {
  .recent-search-chip { max-width: none; }
}
.recent-search-clear {
  background: transparent; color: rgba(255,255,255,.7);
  border: none; cursor: pointer;
  font-size: 0.78rem; padding: 0.28rem 0.5rem; margin-left: auto;
  text-decoration: underline;
}
.recent-search-clear:hover { color: #fff; }

/* College seal — sits centered directly below the logo on the same vertical
   axis. Matches the logo's 80×80 size; treats the seal as a peer identity
   element rather than a subordinate watermark. The previous treatment
   (right-pinned at 56×56 with opacity 0.85) read as decorative noise; at
   equal size + centered position the seal carries the same weight as the
   logo, which is correct since most schools use both interchangeably. */
.college-hero-seal-wrap {
  /* Center horizontally on the same axis as the logo. The logo sits at
     `right: 1.5rem` with `width: 80px`, so its center is at
     `right: calc(1.5rem + 40px)`. We mirror that with translateX(50%) so
     the seal centers under the logo regardless of viewport width. */
  position: absolute;
  top: calc(1.5rem + 80px + 0.5rem);
  right: calc(1.5rem + 40px);
  transform: translateX(50%);
  width: 80px; height: 80px;
}
.college-hero-seal-wrap img {
  width: 100%; height: 100%; object-fit: contain;
  background: rgba(255,255,255,.92); border-radius: 12px; padding: 6px;
}
.college-hero-info h1 {
  font-size: 2rem; font-weight: 800; color: #fff;
  text-shadow: 0 1px 3px rgba(0,0,0,.9), 0 3px 12px rgba(0,0,0,.6); line-height: 1.2;
}
.college-hero-info p { color: rgba(255,255,255,.9); font-size: 1rem; text-shadow: 0 1px 4px rgba(0,0,0,.7); }
/* College hero action buttons — May 2026: moved OUT of .college-hero-overlay
   so the campus photo stays visible. Mirrors the same pattern as the dorm
   hero — own row directly below the hero card with a soft surface tint. */
.college-hero-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 0.6rem 0 1rem 0;
  padding: 0.75rem 1rem;
  background: var(--md3-surface-1, #f8fafc);
  border: 1px solid var(--md3-outline-variant, #e5e7eb);
  border-radius: 12px;
}
.college-hero-actions .btn { font-size: 0.85rem; padding: 0.4rem 0.9rem; }
@media (max-width: 640px) {
  .college-hero-actions { gap: 0.4rem; padding: 0.6rem 0.75rem; }
  .college-hero-actions .btn { font-size: 0.8rem; padding: 0.4rem 0.75rem; }
}

.college-hero-more-wrap { position: relative; display: inline-flex; }
.college-hero-more-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 220px;
  background: var(--md3-surface, #fff);
  border: 1px solid var(--md3-outline-variant, #e5e7eb);
  border-radius: var(--md3-shape-md, 12px);
  box-shadow: var(--md3-elev-3, 0 8px 24px rgba(0,0,0,.12));
  padding: 0.35rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  z-index: 60;
}
.college-hero-more-menu[hidden] { display: none; }
.college-hero-more-item {
  appearance: none;
  background: transparent;
  border: none;
  text-align: left;
  padding: 0.55rem 0.7rem;
  border-radius: var(--md3-shape-sm, 8px);
  font-size: 0.88rem;
  color: var(--md3-on-surface, #1f2937);
  cursor: pointer;
  font-family: inherit;
}
.college-hero-more-item:hover,
.college-hero-more-item:focus-visible {
  background: var(--md3-state-hover, rgba(99,102,241,.08));
  outline: none;
}
@media (max-width: 640px) {
  .college-hero-more-menu {
    right: auto;
    left: 0;
    min-width: 200px;
  }
}

.college-coldstart-panel {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  background: linear-gradient(135deg, var(--md3-tertiary-container, #fef3c7) 0%, var(--md3-primary-container, #e0e7ff) 100%);
  border: 1px solid var(--md3-outline-variant, #e5e7eb);
  border-left: 4px solid var(--college-primary, var(--md3-primary, #6366f1));
  border-radius: var(--md3-shape-lg, 16px);
  padding: 1.25rem 1.5rem;
  margin: 0 0 1.75rem 0;
  box-shadow: var(--md3-elev-1, 0 1px 3px rgba(0,0,0,.06));
}
.college-coldstart-icon {
  font-size: 2.25rem;
  line-height: 1;
  flex-shrink: 0;
}
.college-coldstart-body { flex: 1; min-width: 0; }
.college-coldstart-title {
  font-size: var(--md3-title-large-size, 1.25rem);
  line-height: var(--md3-title-large-line, 1.4);
  font-weight: 600;
  margin: 0 0 .35rem 0;
  color: var(--md3-on-surface, #1f2937);
}
.college-coldstart-sub {
  font-size: var(--md3-body-medium-size, .9rem);
  line-height: var(--md3-body-medium-line, 1.5);
  color: var(--md3-on-surface-variant, #4b5563);
  margin: 0 0 .85rem 0;
}
.college-coldstart-actions {
  display: flex;
  gap: .55rem;
  flex-wrap: wrap;
}
@media (max-width: 480px) {
  .college-coldstart-panel { flex-direction: column; gap: .5rem; padding: 1rem 1.1rem; }
  .college-coldstart-icon { font-size: 1.85rem; }
}

.shortlist-panel-promoted {
  background: linear-gradient(135deg, var(--md3-primary-container, #e0e7ff) 0%, #ffffff 80%);
  border: 1px solid var(--md3-outline-variant, #e5e7eb);
  border-left: 4px solid var(--college-primary, var(--md3-primary, #6366f1));
  border-radius: var(--md3-shape-lg, 16px);
  padding: 1rem 1.25rem;
  margin: 0 0 1.5rem 0;
  box-shadow: var(--md3-elev-1, 0 1px 3px rgba(0,0,0,.06));
}
.shortlist-panel-promoted .section-header h2 {
  color: var(--college-primary, var(--md3-primary, #6366f1));
}

.college-stats-bar {
  display: flex; gap: 0; background: #fff;
  border: 1.5px solid #e5eaf1; border-radius: 0 0 12px 12px;
  overflow: hidden; margin-bottom: 1.5rem;
  border-top: none;
}
.college-stat {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  padding: 1rem 0.5rem; border-right: 1px solid #e5eaf1; min-width: 0;
}
.college-stat:last-child { border-right: none; }
.college-stat-val { font-size: 1.1rem; font-weight: 700; color: #1a202c; }
.college-stat-lbl { font-size: 0.72rem; color: #6b7280; text-align: center; margin-top: 0.2rem; }
.college-stat-link { font-size: 0.85rem; font-weight: 600; color: #3b5bdb; }

.college-about {
  background: #fff; border: 1.5px solid #e5eaf1; border-radius: 12px;
  padding: 1.25rem 1.5rem; margin-bottom: 1rem; line-height: 1.7;
  color: #374151; font-size: 0.94rem;
}

/* ─── Dorm landing page ─────────────────────────────────────────── */
.dorm-hero {
  position: relative; border-radius: 16px; overflow: hidden;
  min-height: 260px; background: #1a2748; margin-bottom: 0;
}
.dorm-hero-img-wrap {
  position: absolute; inset: 0;
}
.dorm-hero-img-wrap img {
  width: 100%; height: 100%; object-fit: cover; opacity: .5;
}
.dorm-hero-placeholder {
  width: 100%; height: 100%; min-height: 260px; display: flex;
  align-items: center; justify-content: center; font-size: 5rem;
  opacity: .2; background: linear-gradient(135deg,#1a2748 0%,#2d4a8a 100%);
}
.dorm-hero-overlay {
  position: relative; z-index: 2; padding: 2rem 2rem 1.5rem;
  display: flex; flex-direction: column; gap: 0.6rem;
  min-height: 260px; justify-content: flex-end;
}
.dorm-hero-overlay h1 { font-size: 1.8rem; font-weight: 800; color: #fff; text-shadow: 0 2px 8px rgba(0,0,0,.4); }
.dorm-hero-overlay p  { color: rgba(255,255,255,.85); font-size: 0.95rem; }
/* Dorm hero action buttons — May 2026: moved OUT of the .dorm-hero-overlay
   so the building photo stays visible. Now sits in its own row directly
   below the hero card. Background is a faint surface tint that visually
   ties to the hero above without competing with it. Wraps cleanly on
   narrow viewports; mobile shrinks the gap so 9 buttons fit better. */
.dorm-hero-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 0.6rem 0 1rem 0;
  padding: 0.75rem 1rem;
  background: var(--md3-surface-1, #f8fafc);
  border: 1px solid var(--md3-outline-variant, #e5e7eb);
  border-radius: 12px;
}
.dorm-hero-actions .btn { font-size: 0.85rem; padding: 0.4rem 0.9rem; }
@media (max-width: 640px) {
  /* Mobile (May 2026): convert the 9-button action row from a wrap-to-2-lines
     grid into a horizontally-scrollable rail. Two wins: (a) the dorm hero
     stays compact instead of pushing the photo + Brief strip down by 60+px,
     (b) the buttons stay legible at full mobile size instead of shrinking
     to fit. Native momentum scroll on iOS via -webkit-overflow-scrolling. */
  .dorm-hero-actions {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 0.4rem;
    padding: 0.6rem 0.75rem;
    /* Hint at scrollability with a soft fade on the right edge. */
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
            mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
  }
  .dorm-hero-actions::-webkit-scrollbar { display: none; }
  .dorm-hero-actions .btn {
    font-size: 0.8rem;
    padding: 0.4rem 0.75rem;
    flex-shrink: 0;
    white-space: nowrap;
  }
}

/* Social-proof chip in the dorm hero — sits between the subtitle and the
   action buttons. Translucent white pill so it reads over any building
   photo background. Populated by loadDormDetail() only when the dorm has
   at least one approved rating; hidden otherwise. */
.dorm-hero-contrib-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  width: fit-content;
  max-width: 100%;
  padding: 0.3rem 0.75rem;
  background: rgba(255,255,255,0.92);
  color: #1e293b;
  font-size: 0.82rem;
  font-weight: 500;
  border-radius: 999px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.15);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.dorm-hero-contrib-chip strong { font-weight: 700; color: #4f46e5; }

/* Dorm tier list — community-voted S/A/B/C/D ranking on college pages */
.college-tier-board-section {
  margin: 1.75rem 0 1rem 0;
  background: linear-gradient(135deg, #fef3c7 0%, #fef9c3 100%);
  border: 1px solid #fde68a;
  border-radius: 0.65rem;
  padding: 1rem 1.1rem;
}
.college-tier-board-section h2 { font-size: 1.05rem; font-weight: 700; color: #78350f; }
.tier-board { display: flex; flex-direction: column; gap: 0.55rem; }
.tier-row {
  display: flex; align-items: stretch; gap: 0.55rem;
  background: white; border: 1px solid #e5e7eb; border-radius: 0.5rem;
  overflow: hidden;
}
.tier-row-label {
  flex: 0 0 56px;
  display: flex; align-items: center; justify-content: center;
  color: white; font-size: 1.6rem; font-weight: 800; letter-spacing: 0.04em;
}
.tier-row-cards { flex: 1; display: flex; gap: 0.4rem; padding: 0.5rem; flex-wrap: wrap; align-items: center; }
.tier-card {
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 0.4rem;
  padding: 0.3rem 0.45rem;
  display: flex; align-items: center; gap: 0.45rem;
  text-decoration: none;
  color: #1f2937;
  font-size: 0.82rem;
  transition: transform 0.12s ease, border-color 0.12s ease;
  position: relative;
}
.tier-card:hover { transform: translateY(-1px); border-color: #6366f1; }
.tier-card img {
  width: 28px; height: 28px; object-fit: cover; border-radius: 4px;
  flex-shrink: 0;
}
.tier-card-placeholder {
  width: 28px; height: 28px; background: #e5e7eb; border-radius: 4px;
  display: flex; align-items: center; justify-content: center; font-size: 0.85rem;
}
.tier-card-name { font-weight: 500; }
.tier-card-count {
  font-size: 0.7rem; color: #6b7280; font-weight: 600;
  background: #f3f4f6; padding: 0.05rem 0.35rem; border-radius: 999px;
}
.tier-row-empty { color: #6b7280; font-size: 0.78rem; font-style: italic; padding: 0.25rem 0.4rem; }
@media (max-width: 640px) {
  .tier-row-label { flex: 0 0 42px; font-size: 1.3rem; }
  .tier-card-name { display: none; } /* photo + count only on mobile to fit more cards per row */
}

/* Tier-vote chip on dorm hero — 5 small buttons users click to vote */
.dorm-hero-tier-chip {
  display: inline-flex; align-items: center; gap: 0.5rem;
  margin-left: 0.5rem; padding: 0.3rem 0.7rem;
  background: rgba(255,255,255,0.92); border-radius: 999px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.18);
  font-size: 0.78rem; font-weight: 500; color: #1e293b;
}
.dorm-hero-tier-label { white-space: nowrap; }
.dorm-hero-tier-buttons { display: inline-flex; gap: 0.25rem; }
.tier-btn {
  width: 28px; height: 28px;
  background: white; border: 1px solid #d1d5db; border-radius: 6px;
  font-size: 0.85rem; font-weight: 700; color: #1f2937;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform 0.1s ease, background 0.1s ease;
}
.tier-btn:hover { transform: translateY(-1px); border-color: #6366f1; }
.tier-btn-active { color: white; border: none; box-shadow: 0 1px 3px rgba(0,0,0,0.2); }

/* Grade display widget (Phase 3 A–F rework, Apr 2026) */
.grade-display-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0.75rem 1rem;
  background: white;
  border: 2px solid #e5e7eb;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s;
  box-shadow: 0 1px 4px rgba(0,0,0,0.08);
  margin-left: 0.5rem;
}
.grade-display-chip:hover {
  border-color: #6366f1;
  background: #f9fafb;
  box-shadow: 0 2px 6px rgba(0,0,0,0.12);
}
.grade-display-letter {
  font-size: 1.75rem;
  font-weight: 700;
  color: #1f2937;
  line-height: 1;
  margin-bottom: 0.25rem;
}
.grade-display-meta {
  font-size: 0.75rem;
  color: #6b7280;
  text-align: center;
}

/* Grade buttons in modal */
.grade-btn {
  padding: 0.75rem;
  border: 2px solid #cbd5e1;
  border-radius: 6px;
  background: white;
  color: #1f2937;
  font-weight: 700;
  font-size: 1rem;
  cursor: pointer;
  transition: all 0.2s;
}
.grade-btn:hover {
  border-color: #6366f1;
  background: #eff6ff;
}
.grade-btn.selected {
  background: #6366f1;
  color: white;
  border-color: #6366f1;
  box-shadow: 0 2px 4px rgba(99, 102, 241, 0.3);
}

/* Wizard grade picker (Part a: grade question in room submission wizard) */
.wizard-grade-picker {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
  padding: 0.75rem;
  background: #f9fafb;
  border-radius: 6px;
  border: 1px solid #e5e7eb;
}
.wizard-grade-buttons {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  justify-content: center;
}
.wizard-grade-btn {
  padding: 0.6rem 0.9rem;
  border: 2px solid #cbd5e1;
  border-radius: 6px;
  background: white;
  color: #1f2937;
  font-weight: 700;
  font-size: 0.95rem;
  cursor: pointer;
  transition: all 0.2s;
}
.wizard-grade-btn:hover {
  border-color: #6366f1;
  background: #eff6ff;
}
.wizard-grade-btn.selected {
  background: #6366f1;
  color: white;
  border-color: #6366f1;
  box-shadow: 0 2px 4px rgba(99, 102, 241, 0.3);
}
.wizard-grade-hint {
  font-size: 0.8rem;
  color: #6b7280;
  text-align: center;
}

/* Mini campus-map thumbnail on the dorm hero. Sits in the top-right of the
   hero (below the college logo+seal stack); clicking expands to the full
   campus map section on the college page. Auto-hidden when no coords. */
/* Mini-map popover — Apr 2026 evening fix. Floats below #dorm-address-line
 * on hover/tap. Width is wider than the previous always-on thumbnail
 * because real estate is now spent only when the user opts in via hover. */
.dorm-hero-minimap-popover {
  position: absolute;
  /* Positioned dynamically by JS based on the address line's bounding rect.
   * Default offscreen until JS sets top/left. */
  top: -9999px;
  left: -9999px;
  width: 280px;
  background: var(--ds-bg-elevated, #fff);
  border: 1px solid var(--ds-border, #e5e7eb);
  border-radius: 0.55rem;
  padding: 0.4rem;
  box-shadow: 0 12px 32px rgba(0,0,0,0.18);
  z-index: 1100;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
#dorm-hero-minimap-canvas {
  width: 100%;
  height: 200px;
  border-radius: 0.4rem;
  overflow: hidden;
  background: #e2e8f0;
}
.dorm-hero-minimap-fullink {
  font-size: 0.82rem;
  color: #4F46E5;
  text-align: center;
  text-decoration: none;
  padding: 0.25rem;
  border-radius: 0.3rem;
}
.dorm-hero-minimap-fullink:hover { background: var(--ds-hover-bg, #f3f4f6); text-decoration: underline; }
/* Hover-affordance hint on the address line — slight bg tint + cursor */
#dorm-address-line {
  cursor: help;
  border-radius: 0.3rem;
  padding: 0.1rem 0.35rem;
  margin-left: -0.35rem;
  transition: background 0.12s;
}
#dorm-address-line:hover { background: rgba(99, 102, 241, 0.08); }
.dorm-hero-minimap-label {
  font-size: 0.68rem;
  font-weight: 600;
  color: #1e293b;
  text-align: center;
  white-space: nowrap;
}
@media (max-width: 640px) {
  .dorm-hero-minimap { width: 90px; bottom: 0.6rem; right: 0.8rem; }
  #dorm-hero-minimap-canvas { height: 70px; }
  .dorm-hero-minimap-label { font-size: 0.62rem; }
}

/* Hero video-tour chip — sits next to the contrib chip and pulses gently
   on hover to invite the click. Clicks navigate to Browse All Rooms. */
.dorm-hero-video-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-left: 0.5rem;
  padding: 0.3rem 0.85rem;
  background: linear-gradient(135deg, #db2777 0%, #be185d 100%);
  color: #fff;
  border: none;
  font-size: 0.82rem;
  font-weight: 600;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(0,0,0,0.18);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.dorm-hero-video-chip:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 10px rgba(190, 24, 93, 0.35);
}

/* Hero vibe-rating chip — sits alongside the video chip when a logged-in
   user hasn't voted yet. Indigo gradient distinguishes it from the pink
   video chip. Auto-hides once the user votes. */
.dorm-hero-vibe-chip {
  display: inline-flex;
  /* align-self required: the parent .dorm-hero-overlay is a column flex
     container with cross-axis stretch, which was making the chip render
     as a full-width purple bar across the entire hero (visible regression
     reported on PSU's Atherton Hall page after deploy #653). flex-start
     keeps it pill-shaped at content width like the video chip beside it. */
  align-self: flex-start;
  width: auto;
  align-items: center;
  gap: 0.35rem;
  margin-left: 0.5rem;
  padding: 0.3rem 0.85rem;
  background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);
  color: #fff;
  border: none;
  font-size: 0.82rem;
  font-weight: 600;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(0,0,0,0.18);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.dorm-hero-vibe-chip:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 10px rgba(79, 70, 229, 0.35);
}

/* Operational-status banner — sits at the top of the dorm-hero overlay above
   the title when a dorm is closed/demolished/planned. Amber gradient with a
   dark-amber border so it reads as informational, not alarming. Body text is
   the primary status line; the optional <em> below is the closure note. */
.dorm-status-banner {
  display: block;
  margin: 0 0 0.85rem 0;
  padding: 0.7rem 1rem;
  background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
  color: #78350f;
  border: 1px solid #f59e0b;
  border-left: 4px solid #d97706;
  border-radius: 8px;
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.4;
  box-shadow: 0 1px 3px rgba(0,0,0,0.12);
  max-width: 720px;
}
.dorm-status-banner em {
  display: block;
  margin-top: 0.3rem;
  font-style: italic;
  font-weight: 500;
  color: #92400e;
  font-size: 0.85rem;
}
.dorm-status-banner .status-label {
  display: inline-block;
  margin-right: 0.4rem;
  padding: 0.1rem 0.5rem;
  background: #d97706;
  color: white;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Aging meter chip CSS — REMOVED 2026-05-02. The dorm-hero-aging-chip
   was visually overpowering the primary surface (full-width red banner
   on historic buildings). Function in app.js is now a no-op + the
   #dorm-hero-aging-chip markup is gone from index.html. The single
   `display: none` rule below covers any returning visitor whose
   cached HTML still includes the element. */
.dorm-hero-aging-chip { display: none !important; }

/* Translation toggle (UX #91) — appears under any UGC text element marked
   .translatable-text. Click 🌐 to open a small lang picker; click a lang to
   replace inline; click the toggle again to revert. International student
   parents are the primary audience — the toggle is intentionally subtle so
   it doesn't dominate the review card for English readers. */
.translation-toggle {
  position: relative;
  display: inline-block;
  margin-top: 0.35rem;
}
.translation-toggle-btn {
  background: transparent;
  border: 1px solid #e5e7eb;
  border-radius: 999px;
  padding: 0.15rem 0.55rem;
  font-size: 0.72rem;
  color: #6b7280;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.translation-toggle-btn:hover {
  background: #f3f4f6;
  color: #1f2937;
}
.translation-lang-menu {
  position: absolute;
  top: calc(100% + 0.25rem);
  left: 0;
  z-index: 100;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 0.5rem;
  box-shadow: 0 4px 12px rgba(0,0,0,0.08);
  padding: 0.25rem;
  min-width: 140px;
}
.translation-lang-btn {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  padding: 0.4rem 0.6rem;
  font-size: 0.85rem;
  color: #1f2937;
  cursor: pointer;
  border-radius: 0.3rem;
}
.translation-lang-btn:hover {
  background: #f3f4f6;
}
/* When a translatable text element is currently showing a translation,
   add a subtle indigo left-border so users know the text isn't original. */
.translatable-text[data-translated-lang] {
  border-left: 2px solid #6366f1;
  padding-left: 0.6rem;
}

/* College branding (logo + seal) in the dorm-hero top-right corner.
   Populated at runtime from state.college; auto-reveals when either photo
   is present. Click the logo to return to the parent college page. */
.dorm-hero-college-branding {
  position: absolute; top: 1rem; right: 1rem;
  z-index: 3;
  display: flex; flex-direction: column; gap: 0.5rem;
  align-items: center;
  pointer-events: auto;
}
.dorm-hero-college-logo-wrap,
.dorm-hero-college-seal-wrap {
  display: block; width: 56px; height: 56px;
  border-radius: 10px; overflow: hidden;
}
.dorm-hero-college-logo-wrap {
  cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease;
}
.dorm-hero-college-logo-wrap:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0,0,0,.25);
}
.dorm-hero-college-logo-wrap img,
.dorm-hero-college-seal-wrap img {
  width: 100%; height: 100%; object-fit: contain;
  background: rgba(255,255,255,.94);
  border-radius: 10px; padding: 4px;
  display: block;
}
.dorm-hero-college-seal-wrap img {
  /* Seals are often more decorative than logos — a lighter background
     makes them read better without overpowering the logo above. */
  background: rgba(255,255,255,.88);
}
@media (max-width: 540px) {
  .dorm-hero-college-branding { top: 0.6rem; right: 0.6rem; gap: 0.35rem; }
  .dorm-hero-college-logo-wrap,
  .dorm-hero-college-seal-wrap { width: 44px; height: 44px; }
}

.dorm-stats-bar {
  display: flex; gap: 0; background: #fff;
  border: 1.5px solid #e5eaf1; border-radius: 0 0 12px 12px; border-top: none;
  overflow-x: auto; margin-bottom: 1.8rem;
}
.dorm-stat {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  padding: 0.9rem 0.5rem; border-right: 1px solid #e5eaf1; min-width: 90px;
}
.dorm-stat:last-child { border-right: none; }
.dorm-stat-val { font-size: 1rem; font-weight: 700; color: #1a202c; }
.dorm-stat-lbl { font-size: 0.7rem; color: #6b7280; text-align: center; margin-top: 0.2rem; }

.dorm-detail-body {
  display: grid; grid-template-columns: 1fr 340px; gap: 1.5rem; align-items: start;
}
@media (max-width: 900px) { .dorm-detail-body { grid-template-columns: 1fr; } }

.dorm-section {
  background: #fff; border: 1.5px solid #e5eaf1; border-radius: 12px;
  padding: 1.25rem 1.5rem; margin-bottom: 1.25rem;
}
.dorm-section h3 { font-size: 1rem; font-weight: 700; margin-bottom: 0.9rem; color: #1a202c; }
.dorm-section h4 { font-size: 0.9rem; font-weight: 600; margin-bottom: 0.5rem; }
.dorm-detail-desc-text { font-size: 0.93rem; line-height: 1.7; color: #374151; }

/* Dorm photo gallery grid */
.dorm-gallery-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 0.75rem; }
.dorm-gallery-thumb { width: 100%; aspect-ratio: 4/3; object-fit: cover; border-radius: 8px; cursor: zoom-in; border: 1.5px solid #e5eaf1; transition: transform .15s; }
.dorm-gallery-thumb:hover { transform: scale(1.03); }
.dorm-gallery-source { font-size: 0.72rem; color: #6b7280; margin-top: 0.5rem; }

/* Photo theft deterrents (May 2026, expanded 2026-05-02) — light client-
   side guards. Pairs with the JS contextmenu/dragstart handlers in app.js
   `_wirePhotoDeterrents()`, server-side hotlink protection, and X-Robots-
   Tag: noimageindex on /uploads/*. Doesn't stop screenshots / "Save Page
   As" / DevTools — that's impossible on web. Stops drag-to-desktop, the
   right-click save menu, the iOS Safari long-press save sheet, and casual
   image selection. ~85% of casual saves blocked.

   Class list expanded 2026-05-02 to cover every photo-render surface site-
   wide: dorm + room cards, top-dorms strip, college hero + cards, alumni
   cards, dining card thumbs, gallery thumbs, lightbox, hero, etc. */
.photo-protect-img,
.gallery-thumb, .dorm-gallery-thumb, .dorm-hero-img, .lightbox-img,
.room-photo-thumb, .college-hero-img,
.dorm-card-img, .top-dorm-photo, .alumni-card-img, .dining-card-thumb,
img[src*="/uploads/"] {
  -webkit-user-drag: none;
  user-drag: none;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;  /* iOS Safari: no save-image popover on long-press */
}

/* Photo report button (TASK 6) */
/* Photo report button — May 2026: shrunk from a wide "🚩 Report" capsule
   that dominated thumbnails to a 22px corner flag-icon. Sits in the bottom-
   right so it doesn't crowd the AI grade chip in the top-left, and uses a
   semi-transparent background so it doesn't visually compete with the
   photo content. Hover-fades-in only when the parent thumbnail is hovered;
   on touch devices it's permanently visible at low opacity (touch users
   can't hover, and a fully-hidden button is impossible to tap).
   See https://en.wikipedia.org/wiki/Touch_user_interface for the convention. */
.photo-report-btn {
  position: absolute;
  bottom: 0.3rem;
  right: 0.3rem;
  background: rgba(0, 0, 0, 0.55);
  color: white;
  border: none;
  border-radius: 50%;
  width: 22px;
  height: 22px;
  padding: 0;
  font-size: 0.7rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.15s, background 0.15s;
  z-index: 10;
}
.gallery-thumb-wrap:hover .photo-report-btn,
.dorm-gallery-wrap:hover .photo-report-btn,
.gallery-thumb-wrap:focus-within .photo-report-btn,
.dorm-gallery-wrap:focus-within .photo-report-btn {
  opacity: 0.85;
}
.photo-report-btn:hover,
.photo-report-btn:focus-visible {
  opacity: 1 !important;
  background: #dc2626;
  outline: 2px solid white;
  outline-offset: 1px;
}
@media (hover: none) and (pointer: coarse) {
  /* Touch devices — keep the button visible at low opacity since hover
     doesn't exist; tap activates. */
  .photo-report-btn { opacity: 0.55; }
}

/* Dorm facts grid */
.dorm-facts-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.75rem; }
.dorm-fact-card { position: relative; background: #f8fafc; border: 1px solid #e5eaf1; border-radius: 8px; padding: 0.75rem 1rem; }
.dorm-fact-card .fact-val { font-size: 1.2rem; font-weight: 700; color: #2563eb; line-height: 1; }
.dorm-fact-card .fact-lbl { font-size: 0.72rem; color: #6b7280; margin-top: 0.2rem; }
.fact-suggest-btn { position: absolute; top: .3rem; right: .35rem; background: none; border: none; cursor: pointer; font-size: .7rem; opacity: 0; transition: opacity .15s; padding: 0; line-height: 1; }
.dorm-fact-card:hover .fact-suggest-btn { opacity: .7; }
.fact-suggest-btn:hover { opacity: 1 !important; }

/* Amenities + events list */
.dorm-amenity-list { list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0.3rem; }
.dorm-amenity-list li { font-size: 0.85rem; color: #374151; padding: 0.2rem 0; }
.dorm-amenity-list li::before { content: '✓ '; color: #16a34a; font-weight: 700; }

.dorm-proscons { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 600px) { .dorm-proscons { grid-template-columns: 1fr; } }
.dorm-pros ul { list-style: none; }
.dorm-pros li::before { content: '✓ '; color: #16a34a; font-weight: 700; }
.dorm-pros li, .dorm-cons li { font-size: 0.86rem; line-height: 1.5; padding: 0.2rem 0; color: #374151; }
.dorm-cons ul { list-style: none; }
.dorm-cons li::before { content: '✗ '; color: #dc2626; font-weight: 700; }

.dorm-rating-bars { display: flex; flex-direction: column; gap: 0.65rem; }
.rating-bar-row { display: flex; align-items: center; gap: 0.75rem; font-size: 0.85rem; }
.rating-bar-label { width: 90px; color: #6b7280; flex-shrink: 0; }
.rating-bar-track { flex: 1; height: 8px; background: #e5eaf1; border-radius: 4px; overflow: hidden; }
.rating-bar-fill { height: 100%; border-radius: 4px; background: linear-gradient(90deg, #3b5bdb, #4f8ef7); transition: width .4s; }
.rating-bar-val { width: 28px; text-align: right; font-weight: 600; color: #1a202c; }

.dorm-comment-card {
  padding: 0.85rem; background: #f8faff; border-radius: 8px;
  border: 1px solid #e5eaf1; margin-bottom: 0.65rem; font-size: 0.87rem;
}
.dorm-comment-author { font-weight: 600; color: #1a202c; margin-bottom: 0.2rem; }
.dorm-comment-meta { font-size: 0.75rem; color: #6b7280; margin-bottom: 0.35rem; }

/* ─── Distances panel ───────────────────────────────────────────── */
.distances-panel, .amenities-panel {
  background: #fff; border: 1.5px solid #e5eaf1; border-radius: 12px;
  padding: 1.25rem 1.4rem; margin-bottom: 1.25rem;
}
.distances-panel h3, .amenities-panel h3 {
  font-size: 0.97rem; font-weight: 700; margin-bottom: 0.3rem; color: #1a202c;
}
.distances-subtitle { font-size: 0.78rem; color: #6b7280; margin-bottom: 0.9rem; }
.distances-list { display: flex; flex-direction: column; gap: 0; }
.distance-row {
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.6rem 0; border-bottom: 1px solid #f0f4ff; font-size: 0.85rem;
}
.distance-row:last-child { border-bottom: none; }
.distance-icon { font-size: 1rem; width: 22px; text-align: center; flex-shrink: 0; }
.distance-name { flex: 1; color: #374151; }
.distance-name small { display: block; font-size: 0.73rem; color: #6b7280; }
.distance-val {
  font-weight: 700; color: #3b5bdb; white-space: nowrap;
  font-size: 0.88rem; flex-shrink: 0;
}
.distance-val.close { color: #16a34a; }
.distance-val.medium { color: #d97706; }
.distance-val.far { color: #6b7280; }

/* ─── Campus distances area-group chips ────────────────────────── */
.dist-area-chip {
  display: flex; align-items: center; justify-content: space-between;
  padding: 0.45rem 0.65rem; border-radius: 8px; cursor: pointer;
  background: #f0f4ff; border: 1px solid #c7d2fe; margin-bottom: 0.35rem;
  transition: background 0.15s;
}
.dist-area-chip:hover { background: #e0e7ff; }
.dist-area-chip-label { font-weight: 600; font-size: 0.84rem; color: #3730a3; display: flex; align-items: center; gap: 0.4rem; }
.dist-area-chip-meta { font-size: 0.77rem; color: #6b7280; display: flex; align-items: center; gap: 0.5rem; }
.dist-area-arrow { font-size: 0.7rem; transition: transform 0.2s; color: #6366f1; }
.dist-area-buildings { display: none; padding: 0 0 0.2rem 0.5rem; }
.dist-area-buildings.open { display: block; }
.dist-area-buildings .distance-row:first-child { border-top: none; padding-top: 0.3rem; }
.dist-area-ungrouped { margin-top: 0.15rem; }

/* ─── Amenities summary (dorm detail) ──────────────────────────── */
.amenity-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; }
.amenity-chip {
  display: inline-flex; align-items: center; gap: 0.3rem;
  padding: 0.25rem 0.65rem; border-radius: 20px; font-size: 0.78rem; font-weight: 600;
}
.amenity-chip.has { background: #dcfce7; color: #166534; }
.amenity-chip.missing { background: #fee2e2; color: #991b1b; }

/* ─── Footer ─────────────────────────────────────────────────────── */
.site-footer {
  background: #111827;
  color: #9ca3af;
  margin-top: 4rem;
  padding: 2rem 0 1.5rem;
  font-size: 0.82rem;
  line-height: 1.6;
}
.footer-inner {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.footer-disclaimer {
  color: #9ca3af;
  border-left: 3px solid #374151;
  padding-left: 1rem;
}
.footer-disclaimer strong {
  color: #d1d5db;
}
.footer-copy {
  color: #6b7280;
  font-size: 0.78rem;
  text-align: center;
  border-top: 1px solid #1f2937;
  padding-top: 0.75rem;
}

/* ─── Floor Plans ─────────────────────────────────────────────────── */
.floor-plan-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}
.fp-tab {
  background: #f3f4f6;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  padding: 0.28rem 0.65rem;
  font-size: 0.78rem;
  cursor: pointer;
  color: #374151;
  transition: background 0.15s;
}
.fp-tab:hover { background: #e5e7eb; }
.fp-tab.active { background: #1a2748; color: #fff; border-color: #1a2748; }

.floor-plan-viewer {
  border-radius: 10px;
  overflow: hidden;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
}
.floor-plan-viewer img {
  width: 100%;
  display: block;
  max-height: 520px;
  object-fit: contain;
}
.floor-plan-label {
  text-align: center;
  font-size: 0.8rem;
  color: #6b7280;
  padding: 0.4rem 0.6rem;
  background: #f3f4f6;
  margin: 0;
}

/* ─── Dorm Info Bar (address + links) ──────────────────────────── */
.dorm-info-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem 1.2rem;
  background: #f0f4ff;
  border-radius: 8px;
  margin-bottom: 1.2rem;
  font-size: 0.88rem;
  color: #374151;
}
.dorm-info-item { display: flex; align-items: center; gap: 0.3rem; }
.dorm-info-link {
  color: #2563eb;
  font-weight: 500;
  text-decoration: none;
  transition: color 0.15s;
}
.dorm-info-link:hover { color: #1d4ed8; text-decoration: underline; }

/* ─── Themed / Specialty Housing Communities ─────────────────────── */
.themed-card {
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: 0.75rem;
  background: #fafbfc;
}
.themed-card-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  flex-wrap: wrap;
}
.themed-type-badge {
  font-size: 0.72rem;
  font-weight: 600;
  color: #fff;
  padding: 2px 8px;
  border-radius: 4px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.themed-badge {
  font-size: 0.72rem;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 4px;
}
.themed-badge-apply {
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #fcd34d;
}
.themed-badge-open {
  background: #d1fae5;
  color: #065f46;
  border: 1px solid #6ee7b7;
}
.themed-card-name {
  font-size: 0.95rem;
  font-weight: 700;
  color: #1a202c;
  margin: 0 0 0.4rem 0;
}
.themed-card-desc {
  font-size: 0.85rem;
  color: #4b5563;
  line-height: 1.5;
  margin: 0 0 0.5rem 0;
}
.themed-card-footer {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}
.themed-fee {
  font-size: 0.8rem;
  color: #6b7280;
  font-weight: 500;
}
.themed-link {
  font-size: 0.8rem;
  font-weight: 600;
  color: #2563eb;
  text-decoration: none;
}
.themed-link:hover { text-decoration: underline; }
.themed-floor {
  font-size: 0.75rem;
  font-weight: 600;
  color: #0369a1;
  background: #e0f2fe;
  border: 1px solid #bae6fd;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  white-space: nowrap;
}

/* ─── Common spaces (May 2026) ─────────────────────────────────── */
/* Non-residence rooms — living rooms, lounges, bathrooms, closets, etc.
   Rendered as floor-grouped grids on the dorm detail page. */
.dorm-common-spaces-grid { display: flex; flex-direction: column; gap: 1rem; }
.cs-floor-block { }
.cs-floor-label {
  font-size: 0.78rem;
  font-weight: 700;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 0.45rem;
}
.cs-floor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.6rem;
}
.cs-card {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  background: #fafbfc;
  border: 1px solid #e5e7eb;
  border-radius: 0.6rem;
  padding: 0.7rem 0.85rem;
  transition: border-color 0.15s, background 0.15s;
}
.cs-card:hover { border-color: #cbd5e1; background: #fff; }
.cs-icon {
  font-size: 1.4rem;
  line-height: 1;
  flex-shrink: 0;
}
.cs-body { flex: 1; min-width: 0; }
.cs-label {
  font-size: 0.92rem;
  font-weight: 600;
  color: #111827;
  margin-bottom: 0.15rem;
  line-height: 1.3;
}
.cs-sqft {
  font-size: 0.78rem;
  color: #4f46e5;
  font-weight: 600;
}
.cs-notes {
  font-size: 0.78rem;
  color: #6b7280;
  margin-top: 0.2rem;
  line-height: 1.4;
}
.cs-edit-btn {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  background: transparent;
  border: none;
  cursor: pointer;
  font-size: 0.85rem;
  opacity: 0;
  transition: opacity 0.15s;
  padding: 0.2rem 0.35rem;
  border-radius: 0.3rem;
}
.cs-card:hover .cs-edit-btn { opacity: 0.7; }
.cs-edit-btn:hover { opacity: 1; background: #f3f4f6; }
.cs-add-row {
  margin-top: 0.5rem;
  padding-top: 0.6rem;
  border-top: 1px dashed #e5e7eb;
}

/* ─── Floor-specific restrictions (AC + gender) ─────────────────── */
.floor-restrict-card {
  background: #fffbeb;
  border: 1px solid #fcd34d;
  border-radius: 8px;
  padding: 0.85rem 1rem;
  margin-bottom: 0.6rem;
}
.floor-restrict-title {
  margin: 0 0 0.35rem;
  font-size: 0.95rem;
  color: #92400e;
  font-weight: 600;
}
.floor-restrict-body {
  margin: 0;
  font-size: 0.88rem;
  color: #78350f;
  line-height: 1.45;
}
.floor-restrict-notes {
  margin: 0.4rem 0 0;
  font-size: 0.82rem;
  color: #92400e;
  font-style: italic;
  line-height: 1.4;
}

/* ─── Gender / Bathroom Policy Section ─────────────────────────── */
.policy-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
.policy-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.35rem 0.75rem;
  border-radius: 20px;
  font-size: 0.82rem;
  font-weight: 500;
  background: #f3f4f6;
  color: #374151;
  border: 1px solid #e5e7eb;
}
/* Bathroom Facilities multi-row breakdown (May 2026). Compact pill chips
 * inside each .bath-fac-row card — same shape as policy-chip but smaller
 * since multiple chips often share a single row. */
.bath-fac-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  border: 1px solid transparent;
  white-space: nowrap;
}
.policy-chip.policy-co-ed { background: #eff6ff; color: #1e40af; border-color: #bfdbfe; }
.policy-chip.policy-all-female { background: #fdf2f8; color: #9d174d; border-color: #fbcfe8; }
.policy-chip.policy-all-male { background: #f0fdf4; color: #166534; border-color: #bbf7d0; }
.policy-chip.policy-gender-neutral { background: #faf5ff; color: #6b21a8; border-color: #e9d5ff; }
.policy-chip.policy-mixed  { background: #fffbeb; color: #92400e; border-color: #fde68a; }
.policy-chip.policy-lgbtq  { background: #faf5ff; color: #7c3aed; border-color: #ddd6fe; }

/* Floor policy table */
.floor-policy-table-wrap { overflow-x: auto; }
.floor-policy-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
}
.floor-policy-table th {
  background: #f9fafb;
  color: #6b7280;
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid #e5e7eb;
  text-align: left;
}
.floor-policy-table td {
  padding: 0.35rem 0.6rem;
  border-bottom: 1px solid #f3f4f6;
  color: #374151;
}

/* ─── Favorites ───────────────────────────────────────────────── */
.fav-btn {
  background: none;
  border: 1px solid #e5e7eb;
  border-radius: 50%;
  width: 28px;
  height: 28px;
  cursor: pointer;
  font-size: 0.85rem;
  color: #9ca3af;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: all .15s;
  flex-shrink: 0;
}
.fav-btn:hover { color: #ef4444; border-color: #fca5a5; }
.fav-btn.fav-active { color: #ef4444; border-color: #fca5a5; background: #fef2f2; }
.fav-header-btn { font-size: .85rem; }
#dorm-fav-btn.fav-active { background: #fef2f2; color: #ef4444; border-color: #fca5a5; }

/* ─── Dorm filter panel ──────────────────────────────────────── */
/* ─── Dorm Browse Toolbar ───────────────────────────────────────── */
.dorm-browse-toolbar {
  background: #f8fafc;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: .75rem 1rem;
  margin-bottom: .75rem;
}
.dorm-browse-search-row {
  display: flex; gap: .5rem; align-items: center; margin-bottom: .6rem; flex-wrap: wrap;
}
.dorm-browse-search {
  flex: 1; min-width: 180px; padding: .4rem .75rem; font-size: .875rem;
}
.quick-filter-row {
  display: flex; gap: .35rem; align-items: center; flex-wrap: wrap;
}
.quick-filter-label {
  font-size: .75rem; color: #6b7280; font-weight: 600; white-space: nowrap;
  margin-right: .15rem;
}
.qf-chip {
  font-size: .78rem; padding: .25rem .65rem;
  border: 1.5px solid #d1d5db; border-radius: 20px;
  background: #fff; color: #374151; cursor: pointer;
  transition: all .12s; white-space: nowrap; font-weight: 500;
}
.qf-chip:hover { border-color: #6366f1; color: #4f46e5; background: #eef2ff; }
.qf-chip.qf-active { border-color: #6366f1; background: #6366f1; color: #fff; }

@media (max-width: 768px) {
  /* On mobile the toolbar collapses into an envelope. The pill at the top
     is the only visible affordance; tapping it expands the toolbar. */
  .dorm-toolbar-pill {
    display: inline-flex !important;
    align-items: center;
    gap: .45rem;
    background: var(--md3-surface-container-high, #eef2ff);
    color: var(--md3-on-surface, #0f172a);
    border: 1px solid var(--md3-outline-variant, #d1d5db);
    border-radius: 999px;
    padding: .45rem .85rem;
    font-size: .85rem;
    font-weight: 600;
    cursor: pointer;
    margin: 0 0 .5rem;
    box-shadow: var(--md3-elev-1);
    transition: background 150ms var(--md3-motion-standard, ease);
  }
  .dorm-toolbar-pill[hidden] { display: none !important; }
  .dorm-toolbar-pill:hover,
  .dorm-toolbar-pill:focus-visible {
    background: var(--md3-surface-container-highest, #e0e7ff);
  }
  .dorm-toolbar-pill[aria-expanded="true"] .dorm-toolbar-pill-chevron {
    transform: rotate(180deg);
  }
  .dorm-toolbar-pill-chevron {
    transition: transform 200ms var(--md3-motion-standard, ease);
    margin-left: auto;
  }
  .dorm-toolbar-pill-count {
    background: var(--md3-primary, #6366f1);
    color: var(--md3-on-primary, #fff);
    border-radius: 999px;
    padding: 0 .45rem;
    font-size: .72rem;
    font-weight: 700;
  }
  .dorm-toolbar-pill-count[hidden] { display: none; }
  #dorm-browse-toolbar {
    position: sticky;
    top: var(--mobile-sticky-top, 56px);
    z-index: 50;
    background: var(--md3-background, #fbfbff);
    margin: 0 -1rem;
    padding: 0.5rem 1rem;
    border-radius: 0;
    box-shadow: 0 2px 8px rgba(0,0,0,0);
    transition: box-shadow 200ms var(--md3-motion-standard, cubic-bezier(.2,0,0,1));
  }
  #dorm-browse-toolbar.is-stuck {
    box-shadow: var(--md3-elev-2);
  }
  /* Mobile envelope: collapse the toolbar contents by default. The pill
     above takes the toolbar's place when collapsed. */
  #dorm-browse-toolbar:not(.is-expanded) > * {
    display: none !important;
  }
}
.dorm-toolbar-pill { display: none; }  /* Desktop: pill is hidden, toolbar is always visible */

.dorm-filter-panel {
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 1rem 1.25rem;
  margin-bottom: 1.25rem;
}
.dorm-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  align-items: flex-end;
}
.dorm-filter-row label {
  display: flex;
  flex-direction: column;
  gap: .25rem;
  font-size: .8rem;
  font-weight: 500;
  color: #4b5563;
}
.dorm-filter-row select {
  padding: .35rem .6rem;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  font-size: .85rem;
  background: white;
  min-width: 130px;
}
.btn-sm { padding: .35rem .75rem; font-size: .82rem; }

/* ─── Search tabs ──────────────────────────────────────────── */
.search-tabs {
  display: flex;
  gap: .5rem;
  margin-bottom: 1.25rem;
  border-bottom: 2px solid #e5e7eb;
  padding-bottom: .5rem;
}
.search-tab {
  background: none;
  border: none;
  padding: .5rem 1rem;
  font-size: .9rem;
  font-weight: 500;
  color: #6b7280;
  cursor: pointer;
  border-radius: 6px 6px 0 0;
  transition: all .15s;
}
.search-tab:hover { color: #1d4ed8; background: #eff6ff; }
.search-tab.active { color: #1d4ed8; background: #eff6ff; font-weight: 600; }

/* ─── Dorm card college badge in search/favs ──────────────── */
.dorm-card .college-badge {
  font-size: .72rem;
  color: #6b7280;
  margin-bottom: .2rem;
}

/* ─── External Links section ────────────────────────────────── */
.links-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  flex-wrap: wrap;
}
.links-section-header h3 { margin: 0; }

.links-list {
  display: flex;
  flex-direction: column;
  gap: .65rem;
  margin-top: .75rem;
}

/* Link card */
.link-card {
  display: flex;
  gap: .85rem;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: .75rem;
  align-items: flex-start;
  transition: box-shadow .15s;
}
.link-card:hover { box-shadow: 0 2px 8px rgba(0,0,0,.08); }

/* YouTube thumbnail inside link card */
.link-yt-thumb {
  position: relative;
  flex-shrink: 0;
  width: 120px;
  border-radius: 6px;
  overflow: hidden;
  display: block;
  line-height: 0;
}
.link-yt-thumb img { width: 100%; height: 68px; object-fit: cover; }
.yt-play-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  color: #fff;
  background: rgba(0,0,0,.35);
  opacity: 0;
  transition: opacity .15s;
}
.link-yt-thumb:hover .yt-play-overlay { opacity: 1; }

.link-card-body { flex: 1; min-width: 0; }
.link-card-top {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  margin-bottom: .25rem;
}
.link-type-badge {
  font-size: .7rem;
  font-weight: 600;
  padding: .15rem .45rem;
  border-radius: 20px;
  white-space: nowrap;
}
.link-card-title {
  font-size: .9rem;
  font-weight: 600;
  color: #1d4ed8;
  text-decoration: none;
  word-break: break-word;
}
.link-card-title:hover { text-decoration: underline; }
.link-card-desc {
  font-size: .82rem;
  color: #4b5563;
  margin: .15rem 0 .25rem;
}
.link-card-meta {
  font-size: .72rem;
  color: #6b7280;
  margin: 0;
}
/* Footer row in a link card: meta text left, vote buttons right */
.link-card-footer-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; flex-wrap: wrap;
}
/* Compact vote controls inside link cards — horizontal layout */
.link-vote-controls {
  flex-direction: row; gap: 4px; min-width: auto;
}
/* ✨ Most-known chip on alumni cards */
.alumni-most-known {
  background: #fef9c3; color: #854d0e; border-color: #fde047;
}

/* Add link form */
.link-form {
  background: #f0f4ff;
  border: 1px solid #c7d2fe;
  border-radius: 10px;
  padding: .9rem 1rem;
  margin-top: .65rem;
}
.link-form-fields {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  margin-bottom: .65rem;
}
.link-input {
  width: 100%;
  padding: .5rem .65rem;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  font-size: .85rem;
  background: #fff;
  box-sizing: border-box;
}
.link-input:focus { outline: none; border-color: #6366f1; box-shadow: 0 0 0 2px #e0e7ff; }
.link-select {
  width: 100%;
  padding: .5rem .65rem;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  font-size: .85rem;
  background: #fff;
  box-sizing: border-box;
}
.link-form-actions { display: flex; gap: .5rem; }
.btn-sm { padding: .35rem .8rem !important; font-size: .82rem !important; }

/* ─── Room Comparison ──────────────────────────────────────────── */
#compare-bar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 900;
  background: #1e293b; color: white; padding: .65rem 1.5rem;
  display: flex; align-items: center; justify-content: space-between;
  box-shadow: 0 -4px 16px rgba(0,0,0,.2); gap: 1rem;
}
.compare-bar-label { font-size: .88rem; }
.compare-bar-label strong { color: #93c5fd; }
.cmp-check-wrap { display: flex; align-items: center; justify-content: center; cursor: pointer; }
.cmp-check-wrap input[type=checkbox] { width: 15px; height: 15px; accent-color: #3b82f6; cursor: pointer; }
.cmp-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.cmp-table th, .cmp-table td { padding: .45rem .65rem; border: 1px solid #e5e7eb; text-align: center; }
.cmp-label-hdr { width: 140px; background: #f8fafc; }
.cmp-room-hdr { background: #eff6ff; min-width: 140px; }
.cmp-room-name { font-weight: 700; font-size: .95rem; }
.cmp-room-dorm { font-size: .75rem; color: #6b7280; margin-bottom: .2rem; }
.cmp-label { text-align: left !important; color: #6b7280; font-size: .82rem; background: #fafafa; }
.cmp-val { font-weight: 500; }
.cmp-stars { color: #f59e0b; }
.cmp-na { color: #d1d5db; font-size: .8rem; }
.cmp-section-hdr td {
  background: #1e293b; color: white; font-size: .72rem;
  font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
  text-align: left !important; padding: .35rem .65rem;
}

/* ─── Q&A ──────────────────────────────────────────────────────── */
.qa-question {
  background: #fff; border: 1.5px solid #e5eaf1; border-radius: 10px;
  padding: 1rem 1.2rem; margin-bottom: 1rem;
}
.qa-q-header { display: flex; align-items: center; gap: .5rem; margin-bottom: .4rem; }
.qa-q-author { font-weight: 600; font-size: .9rem; }
.qa-meta { font-size: .78rem; color: #6b7280; }
.qa-q-text { font-size: .92rem; color: #1f2937; margin-bottom: .75rem; }
.qa-answers { margin-left: 1.25rem; border-left: 3px solid #e0e7ff; padding-left: .9rem; margin-bottom: .6rem; }
.qa-answer { margin-bottom: .6rem; }
.qa-a-header { display: flex; align-items: center; gap: .4rem; margin-bottom: .25rem; }
.qa-a-badge {
  width: 20px; height: 20px; border-radius: 50%; background: #4f46e5; color: white;
  font-size: .68rem; font-weight: 700; display: inline-flex; align-items: center; justify-content: center;
}
.qa-a-author { font-weight: 600; font-size: .85rem; }
.qa-a-text { font-size: .88rem; color: #374151; }
.qa-answer-btn { font-size: .8rem; color: #4f46e5; }
.qa-answer-btn:hover { text-decoration: underline; }

/* ─── Discrepancy Reports ──────────────────────────────────────── */
.disc-header {
  font-size: .8rem; font-weight: 600; color: #92400e;
  background: #fffbeb; border: 1px solid #fde68a;
  border-radius: 6px 6px 0 0; padding: .4rem .75rem;
}
.disc-item {
  background: #fffbeb; border: 1px solid #fde68a; border-top: none;
  padding: .6rem .75rem;
}
.disc-item:last-of-type { border-radius: 0 0 6px 6px; }
.disc-category {
  display: inline-block; font-size: .72rem; font-weight: 600;
  color: #92400e; background: #fef3c7; border-radius: 20px;
  padding: .1rem .45rem; margin-bottom: .3rem;
}
.disc-text { font-size: .85rem; color: #374151; margin: .2rem 0 .4rem; }
.disc-footer { display: flex; justify-content: space-between; align-items: center; }
.disc-meta { font-size: .75rem; color: #6b7280; }
.disc-upvote-btn { font-size: .78rem; color: #6b7280; }

/* ─── Nearby Amenities ──────────────────────────────────────────── */
.nearby-grid {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}
.nearby-item {
  display: flex;
  align-items: center;
  gap: .4rem;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: .35rem .65rem;
  font-size: .85rem;
}
.nearby-type-tag {
  font-size: .75rem;
  font-weight: 600;
  padding: .1rem .35rem;
  border-radius: 20px;
  background: #eff6ff;
  color: #1d4ed8;
  white-space: nowrap;
}
.nearby-type-dining  { background: #fef3c7; color: #92400e; }
.nearby-type-gym     { background: #d1fae5; color: #065f46; }
.nearby-type-library { background: #ede9fe; color: #5b21b6; }
.nearby-type-academic { background: #dbeafe; color: #1e40af; }
.nearby-type-transit { background: #f3f4f6; color: #374151; }
.nearby-type-other   { background: #f3f4f6; color: #374151; }
.nearby-name { color: #374151; }
.nearby-walk { font-size: .78rem; color: #6b7280; white-space: nowrap; }
.disc-upvote-btn:hover { color: #374151; }
.disc-upvote-btn.disc-upvote-voted {
  color: #15803d;
  font-weight: 600;
  background: #ecfdf5;
  border: 1px solid #bbf7d0;
  border-radius: 6px;
  padding: .15rem .55rem;
}
.disc-upvote-btn.disc-upvote-voted:hover {
  color: #b91c1c;
  background: #fef2f2;
  border-color: #fecaca;
}
.disc-upvote-btn.disc-upvote-voted:hover::after {
  content: ' ✕';
  font-size: .75rem;
}

/* ─── FEATURE 1 & 2: Corrections, Highlights & Watch-Outs ─────────────── */

.highlight-item {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  padding: 0.75rem;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  margin-bottom: 0.5rem;
  background: #fafafa;
}

.highlight-content {
  flex: 1;
}

.highlight-content p {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.4;
  color: #374151;
}

.highlight-author {
  display: block;
  margin-top: 0.4rem;
  font-size: 0.75rem;
  color: #6b7280;
}

.highlight-votes {
  display: flex;
  gap: 0.5rem;
  flex-direction: column;
}

.vote-btn {
  padding: 0.35rem 0.6rem;
  border: 1px solid #d1d5db;
  background: white;
  border-radius: 4px;
  font-size: 0.75rem;
  cursor: pointer;
  transition: all 0.2s ease;
  color: #6b7280;
}

.vote-btn:hover {
  background: #f3f4f6;
  border-color: #9ca3af;
}

.upvote-btn { border-color: #10b981; color: #059669; }
.upvote-btn:hover { background: #ecfdf5; }

.downvote-btn { border-color: #ef4444; color: #dc2626; }
.downvote-btn:hover { background: #fef2f2; }

.highlights-two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
}
@media (max-width: 640px) {
  .highlights-two-col {
    grid-template-columns: 1fr;
  }
}

.highlights-section,
.watchouts-section {
  margin-bottom: 0;
}

.highlights-section h4,
.watchouts-section h4 {
  margin: 0 0 0.75rem 0;
  font-size: 0.95rem;
  color: #1f2937;
  font-weight: 600;
}

.highlights-list,
.watchouts-list {
  display: flex;
  flex-direction: column;
}

#room-highlights-container,
#dorm-highlights-container {
  margin-top: 1.5rem;
  padding: 1rem;
  background: #f9fafb;
  border-radius: 8px;
}

/* ─── Header Auth ───────────────────────────────────────────────── */
.header-auth, .header-user {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}
.btn-outline-white {
  background: transparent;
  border: 1.5px solid rgba(255,255,255,.6);
  color: #fff;
  padding: 0.4rem 1rem;
  border-radius: 8px;
  font-size: 0.875rem;
  font-weight: 600;
  transition: background .15s, border-color .15s;
}
.btn-outline-white:hover { background: rgba(255,255,255,.15); border-color: #fff; }
.btn-ghost-white {
  background: transparent;
  border: none;
  color: rgba(255,255,255,.75);
  padding: 0.4rem 0.6rem;
  font-size: 0.8rem;
  border-radius: 6px;
  transition: color .15s;
}
.btn-ghost-white:hover { color: #fff; }
.header-user-name {
  font-size: 0.875rem;
  font-weight: 600;
  color: #fff;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ─── Auth Modal ────────────────────────────────────────────────── */
.modal-auth-inner { max-width: 420px; position: relative; }
.modal-close-btn {
  position: absolute; top: 0.75rem; right: 0.75rem;
  background: none; border: none;
  font-size: 1.1rem; color: #6b7280;
  cursor: pointer; padding: 0.2rem 0.4rem;
  border-radius: 4px;
  transition: color .15s;
}
.modal-close-btn:hover { color: #374151; }
.auth-tabs {
  display: flex;
  gap: 0;
  border-bottom: 2px solid #e5e7eb;
  margin-bottom: 1.25rem;
}
.auth-tab {
  flex: 1;
  background: none;
  border: none;
  padding: 0.6rem 1rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: #6b7280;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  transition: color .15s, border-color .15s;
}
.auth-tab.active { color: #1e3a8a; border-bottom-color: #1e3a8a; }
.auth-panel { display: flex; flex-direction: column; gap: 1.1rem; }
.auth-note { font-size: 0.875rem; color: #6b7280; margin-bottom: 0.25rem; }
.auth-msg {
  font-size: 0.85rem;
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  display: none;
}
.auth-msg.error { display: block; background: #fef2f2; color: #dc2626; }
.auth-msg.success { display: block; background: #f0fdf4; color: #16a34a; }
.btn-full { width: 100%; justify-content: center; }
.auth-switch { font-size: 0.85rem; color: #6b7280; text-align: center; }
.auth-switch a { color: #1e3a8a; font-weight: 600; }
.auth-switch a:hover { text-decoration: underline; }

/* ── OAuth (Google + Microsoft) sign-in buttons ──────────────────── */
.oauth-divider {
  display: flex; align-items: center; gap: 0.5rem;
  margin: 0.4rem 0 0.2rem;
  color: #6b7280; font-size: 0.78rem;
  text-transform: uppercase; letter-spacing: 0.06em;
}
.oauth-divider::before,
.oauth-divider::after {
  content: ''; flex: 1; height: 1px; background: #e5e7eb;
}
.oauth-btn {
  display: flex; align-items: center; justify-content: center; gap: 0.6rem;
  width: 100%;
  padding: 0.62rem 1rem;
  background: #fff; border: 1px solid #d1d5db; border-radius: 0.5rem;
  color: #1f2937; font-weight: 600; font-size: 0.92rem;
  cursor: pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease, transform 0.05s;
}
.oauth-btn:hover { border-color: #9ca3af; background: #f9fafb; box-shadow: 0 1px 3px rgba(0,0,0,0.06); }
.oauth-btn:active { transform: scale(0.98); }
.oauth-btn:focus-visible { outline: 2px solid #4F46E5; outline-offset: 2px; }
.oauth-btn:disabled { opacity: 0.55; cursor: not-allowed; }
.oauth-btn-icon { width: 18px; height: 18px; flex-shrink: 0; }
.oauth-btn-microsoft .oauth-btn-icon { width: 16px; height: 16px; }
.oauth-btn-facebook .oauth-btn-icon { width: 18px; height: 18px; }

/* ── Autocomplete dropdown ─────────────────────────────────────── */
.ac-wrap { position: relative; }
.ac-dropdown {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 9999;
  background: #fff; border: 1px solid #d1d5db; border-top: none;
  border-radius: 0 0 8px 8px; box-shadow: 0 6px 16px rgba(0,0,0,.12);
  list-style: none; margin: 0; padding: 0; max-height: 220px;
  overflow-y: auto;
}
.ac-dropdown li {
  padding: .55rem .9rem; font-size: .875rem; cursor: pointer;
  border-bottom: 1px solid #f3f4f6; color: #1f2937;
}
.ac-dropdown li:last-child { border-bottom: none; }
.ac-dropdown li:hover, .ac-dropdown li.ac-active { background: #eff6ff; color: #1e3a8a; }
.ac-dropdown li .ac-sub { font-size: .76rem; color: #6b7280; margin-top: 1px; }

/* ── Share modal ───────────────────────────────────────────────── */
.share-options-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: .75rem; margin-bottom: 1rem;
}
.share-copy-btn { grid-column: span 2; }
.share-option-btn {
  display: flex; align-items: center; gap: .6rem;
  padding: .65rem .9rem; border: 1.5px solid #e5e7eb;
  border-radius: 10px; background: #fff; cursor: pointer;
  font-size: .875rem; font-weight: 500; color: #1f2937;
  transition: border-color .15s, background .15s;
}
.share-option-btn:hover { border-color: #4f46e5; background: #f5f3ff; }
.share-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 6px;
  font-size: .8rem; font-weight: 700; color: #fff; flex-shrink: 0;
}
.share-btn { font-size: .82rem; }

/* ─── Mobile responsive overrides ──────────────────────────────── */
@media (max-width: 640px) {
  /* Header */
  .header-inner {
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
  }
  .logo-text { font-size: 1.1rem; }
  .header-search {
    order: 3;
    flex: 1 1 100%;
    margin: 0;
  }
  .header-search input { font-size: 16px; }
  .header-auth, .header-user {
    margin-left: auto;
    gap: 0.35rem;
    order: 98;
  }
  .hamburger-btn { order: 99; margin-left: 0.25rem; }
  .header-user-name { max-width: 90px; font-size: 0.8rem; }
  .btn-outline-white { padding: 0.35rem 0.6rem; font-size: 0.8rem; }

  /* College hero */
  .college-hero { min-height: 220px; }
  .college-hero-overlay {
    padding: 1.25rem 1rem 1rem;
    min-height: 220px;
    gap: 0.5rem;
  }
  .college-hero-info h1 { font-size: 1.35rem; }
  .college-hero-info p { font-size: 0.875rem; }
  .college-hero-logo-wrap {
    width: 52px; height: 52px;
    top: 0.75rem; right: 0.75rem;
  }
  /* Mobile seal: shrink to match the logo + re-anchor under it. The
     `right: calc(0.75rem + 26px)` + translateX(50%) keeps the seal centered
     on the logo's vertical axis at the smaller mobile size. */
  .college-hero-seal-wrap {
    width: 52px; height: 52px;
    top: calc(0.75rem + 52px + 0.4rem);
    right: calc(0.75rem + 26px);
  }
  .college-hero-actions { gap: 0.35rem; }
  .college-hero-actions .btn { font-size: 0.75rem; padding: 0.3rem 0.65rem; }

  /* College stats bar — wrap to 3×2 */
  .college-stats-bar {
    flex-wrap: wrap;
    border-radius: 0 0 10px 10px;
  }
  .college-stat {
    flex: 1 1 33%;
    min-width: 0;
    padding: 0.75rem 0.25rem;
  }
  .college-stat:nth-child(3) { border-right: none; }
  .college-stat .stat-value { font-size: 1.1rem; }
  .college-stat .stat-label { font-size: 0.7rem; }

  /* Modals — full-width, scrollable */
  .modal-overlay { padding: 0.5rem; align-items: flex-end; }
  .modal {
    max-width: 100% !important;
    width: 100%;
    max-height: 80vh;
    max-height: 80dvh; /* mobile-keyboard-safe */
    border-radius: 16px 16px 0 0;
    padding: 1.25rem 1rem;
    /* Push bottom content above the mobile nav bar + safe area */
    padding-bottom: calc(80px + env(safe-area-inset-bottom, 0));
    margin: 0;
  }
  .modal-wide { max-width: 100% !important; }
  .modal-auth-inner { max-width: 100%; }
  .modal-actions { flex-direction: column; }
  .modal-actions .btn { width: 100%; justify-content: center; }

  /* Share modal — single column */
  .share-options-grid { grid-template-columns: 1fr; }
  .share-copy-btn { grid-column: auto; }

  /* Compare bar */
  #compare-bar {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.6rem 1rem;
  }
  #compare-bar > div:last-child { width: 100%; display: flex; gap: 0.5rem; }
  #compare-bar .btn { flex: 1; justify-content: center; font-size: 0.8rem; }

  /* Rooms table */
  .rooms-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .rooms-table { font-size: 0.78rem; min-width: 520px; }
  .rooms-table th, .rooms-table td { padding: 0.4rem 0.5rem; }

  /* Dorm detail */
  .dorm-hero { min-height: 180px; }
  .dorm-hero-overlay { padding: 1rem; }
  .dorm-hero-title { font-size: 1.3rem; }

  /* Leaderboard */
  .lb-row { gap: 0.5rem; }
  .lb-rank { font-size: 1rem; min-width: 1.5rem; }
  .lb-avatar { width: 32px; height: 32px; font-size: 0.85rem; }
  .lb-name { font-size: 0.875rem; }
  .lb-pts { font-size: 0.875rem; }

  /* Form inputs */
  input[type="text"], input[type="email"], input[type="password"],
  select, textarea {
    font-size: 1rem; /* prevent iOS zoom */
  }

  /* Rating stars on mobile */
  .star-row { gap: 0.15rem; }
  .star-input-wrap { font-size: 1.3rem; }

  /* College grid (home) */
  .colleges-grid { grid-template-columns: 1fr 1fr; gap: 0.75rem; }
  .college-card-name { font-size: 0.85rem; }

  /* Section headers */
  .section-header h2 { font-size: 1.2rem; }
}

@media (max-width: 420px) {
  .colleges-grid { grid-template-columns: 1fr; }
  .college-stat { flex: 1 1 50%; }
  .college-stat:nth-child(3) { border-right: 1px solid #e5eaf1; }
  .college-stat:nth-child(2) { border-right: none; }
  .hero h1 { font-size: 1.5rem; }
  .hero p { font-size: 0.875rem; }
}

/* ─── Role badge ────────────────────────────────────────────────── */
.header-role-badge {
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0.2rem 0.45rem;
  border-radius: 4px;
  background: rgba(255,255,255,.2);
  color: #fff;
  letter-spacing: .5px;
  flex-shrink: 0;
}

/* ── Sort controls ──────────────────────────────────────────────── */
.sort-select {
  padding: .35rem .6rem;
  border: 1px solid #d1d8e0;
  border-radius: 6px;
  font-size: .82rem;
  background: #fff;
  color: #374151;
  cursor: pointer;
}
.sort-select:focus { outline: 2px solid #3b5bdb; border-color: #3b5bdb; }
.sortable-th { cursor: pointer; user-select: none; white-space: nowrap; }
.sortable-th:hover { color: #3b5bdb; }
.sort-arrow { font-size: .7rem; opacity: .4; }
.sortable-th.sort-asc .sort-arrow::after { content: ' ▲'; opacity: 1; }
.sortable-th.sort-desc .sort-arrow::after { content: ' ▼'; opacity: 1; }

/* ── Availability badge ─────────────────────────────────────────── */
.availability-badge {
  display: inline-block; padding: .25rem .6rem; border-radius: 12px;
  font-size: .8rem; font-weight: 600; background: #ede9fe; color: #5b21b6;
}
.verified-stamp {
  font-size: .8rem; color: #15803d; font-weight: 600;
}

/* ── Claim room ─────────────────────────────────────────────────── */
.room-claimed-badge {
  display: inline-block; padding: .35rem .75rem; border-radius: 8px;
  background: #fef3c7; color: #92400e; font-size: .85rem; font-weight: 600;
}

/* ── Review tags ────────────────────────────────────────────────── */
.review-tags { display: flex; flex-wrap: wrap; gap: .3rem; margin: .35rem 0; }
.review-tag {
  display: inline-block; padding: .15rem .5rem; border-radius: 10px;
  background: #f0f4ff; color: #3b5bdb; font-size: .75rem; font-weight: 500;
}
.review-vote-row {
  display: flex; align-items: center; gap: .5rem; margin-top: .5rem; padding-top: .5rem;
  border-top: 1px solid #f1f3f5;
}
.review-helpful-label { font-size: .78rem; color: #6b7280; }

/* ── Quick tags (review modal) ──────────────────────────────────── */
.quick-tags-section { margin-top: .5rem; }
.quick-tags-grid { display: flex; flex-wrap: wrap; gap: .35rem; }
.quick-tag-btn {
  padding: .25rem .6rem; border-radius: 14px; border: 1px solid #d1d8e0;
  background: #fff; font-size: .8rem; cursor: pointer; transition: all .15s;
}
.quick-tag-btn:hover { border-color: #3b5bdb; background: #f0f4ff; }
.quick-tag-btn.selected { background: #3b5bdb; color: #fff; border-color: #3b5bdb; }

/* ── Move-in tips ───────────────────────────────────────────────── */
.tip-card {
  padding: .6rem .75rem; margin-bottom: .5rem; border-radius: 8px;
  background: #fffbeb; border-left: 3px solid #f59e0b;
}
.tip-text { font-size: .9rem; margin-bottom: .3rem; }
.tip-meta { display: flex; justify-content: space-between; align-items: center; font-size: .78rem; color: #6b7280; }
.tip-vote-row { display: flex; gap: .4rem; }
.tip-vote-btn { padding: .15rem .4rem; border-radius: 6px; border: 1px solid #e5e7eb; background: #fff; cursor: pointer; font-size: .78rem; }
.tip-vote-btn:hover { background: #f9fafb; }

/* ── Best-of lists ──────────────────────────────────────────────── */
.best-of-section { margin-bottom: 1.25rem; }
.best-of-section h4 { margin: 0 0 .4rem; font-size: .95rem; }
.best-of-list { display: flex; flex-direction: column; gap: .3rem; }
.best-of-item {
  display: flex; align-items: center; gap: .5rem; padding: .4rem .6rem;
  border-radius: 6px; background: #f9fafb; cursor: pointer; transition: background .15s;
}
.best-of-item:hover { background: #f0f4ff; }
.best-of-rank { font-weight: 700; color: #f59e0b; min-width: 28px; }
.best-of-name { flex: 1; font-size: .88rem; }
.best-of-rating { font-size: .85rem; font-weight: 600; color: #92400e; }

/* ── Quiz panel ─────────────────────────────────────────────────── */
.quiz-panel { padding: 1rem; background: #f9fafb; border-radius: 10px; margin-bottom: 1.5rem; }
.quiz-row { display: flex; flex-wrap: wrap; gap: .75rem; align-items: flex-end; margin-bottom: .75rem; }
.quiz-label { font-size: .85rem; font-weight: 600; display: flex; flex-direction: column; gap: .25rem; }
.quiz-match-card {
  display: flex; align-items: center; gap: .75rem; padding: .6rem .75rem;
  border-radius: 8px; background: #fff; border: 1px solid #e5e7eb; margin-bottom: .4rem;
  cursor: pointer; transition: border-color .15s;
}
.quiz-match-card:hover { border-color: #3b5bdb; }
.quiz-match-rank { font-size: 1.2rem; min-width: 28px; text-align: center; }
.quiz-match-info { flex: 1; }
.quiz-match-info strong { display: block; font-size: .92rem; }
.quiz-match-info .muted { font-size: .78rem; }
.quiz-match-rating { font-weight: 600; color: #92400e; font-size: .88rem; }


/* ── Housing countdown banner ───────────────────────────────────── */
.housing-countdown-banner {
  background: linear-gradient(135deg, #eff6ff, #dbeafe);
  border: 1px solid #93c5fd;
  border-radius: .6rem;
  padding: .7rem 1rem;
  font-size: .9rem;
  color: #1e40af;
  display: flex;
  align-items: center;
  gap: .5rem;
}

/* ── Reviewer context line on review cards ──────────────────────── */
.review-context-line {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
  margin-top: .3rem;
  margin-bottom: .1rem;
}
.reviewer-context-tag {
  background: #f3f4f6;
  color: #374151;
  border: 1px solid #e5e7eb;
  border-radius: 999px;
  padding: .1rem .55rem;
  font-size: .75rem;
  font-weight: 500;
}
/* Reviewer is listed in current_residents for this dorm — high signal */
.reviewer-context-tag.reviewer-current-resident {
  background: #dcfce7;
  color: #14532d;
  border-color: #bbf7d0;
  font-weight: 600;
}


/* .edu verified badge — shown next to usernames when is_edu_verified = 1 */
.edu-verified-badge {
  display: inline-block;
  background: #ede9fe;
  color: #5b21b6;
  border: 1px solid #c4b5fd;
  border-radius: 999px;
  padding: .05rem .45rem;
  font-size: .72rem;
  font-weight: 700;
  margin-left: .3rem;
  vertical-align: middle;
  white-space: nowrap;
  letter-spacing: .01em;
}


/* Signup form — optional-field encouragement hints */
.signup-field-hint {
  font-size: .76rem;
  color: #6366f1;
  margin-top: .2rem;
  display: flex;
  align-items: center;
  gap: .3rem;
}
.signup-field-hint .hint-icon { font-size: .85rem; }

/* Signup perks strip — benefit callouts above the form */
.signup-perks-strip {
  background: #eef2ff;
  border: 1px solid #c7d2fe;
  border-radius: .5rem;
  padding: .55rem .8rem;
  display: flex;
  flex-direction: column;
  gap: .3rem;
  margin-bottom: .2rem;
}
.signup-perk {
  display: flex;
  align-items: flex-start;
  gap: .45rem;
  font-size: .76rem;
  color: #3730a3;
  line-height: 1.4;
}
.signup-perk span:first-child { flex-shrink: 0; font-size: .85rem; }

/* ── Known Issues ────────────────────────────────────────────────── */
.issue-card {
  background: #fff;
  border: 1px solid #fecaca;
  border-left: 4px solid #ef4444;
  border-radius: .5rem;
  padding: .75rem 1rem;
  margin-bottom: .6rem;
}
.issue-type-badge {
  display: inline-block;
  font-size: .78rem;
  font-weight: 600;
  background: #fff1f2;
  color: #9f1239;
  border-radius: 999px;
  padding: .15rem .55rem;
  margin-bottom: .35rem;
}
.issue-desc { font-size: .9rem; color: #374151; margin-bottom: .4rem; }
.issue-meta { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; font-size: .8rem; }
.issue-status { font-weight: 600; }
.issue-status-open { color: #dc2626; }
.issue-status-resolved { color: #16a34a; }

/* ── Study Spots ─────────────────────────────────────────────────── */
.study-spot-card {
  background: #f8faff;
  border: 1px solid #dbeafe;
  border-radius: .5rem;
  padding: .7rem .9rem;
  margin-bottom: .55rem;
}

/* ── Floor Plan Pins ─────────────────────────────────────────────── */
.floor-pin { position: absolute; pointer-events: auto; cursor: default; z-index: 10; }
.floor-pin-dot { font-size: 1.1rem; filter: drop-shadow(0 1px 2px rgba(0,0,0,.4)); }
.floor-pin-tooltip {
  position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);
  background: #1e293b; color: white; font-size: .72rem; white-space: nowrap;
  padding: .2rem .5rem; border-radius: .3rem; margin-bottom: .2rem;
  opacity: 0; pointer-events: none; transition: opacity .15s;
}
.floor-pin:hover .floor-pin-tooltip { opacity: 1; }

/* ── Similar Dorms ───────────────────────────────────────────────── */
.similar-dorm-card {
  border: 1px solid #e5e7eb;
  border-radius: .6rem;
  overflow: hidden;
  transition: border-color .15s, box-shadow .15s;
  background: white;
}
.similar-dorm-card:hover { border-color: #3b5bdb; box-shadow: 0 2px 8px rgba(59,91,219,.12); }

/* ── Dorm Compare Bar ────────────────────────────────────────────── */
#dorm-compare-bar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: #1e3a8a;
  color: white;
  padding: .75rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  z-index: 1100;
  box-shadow: 0 -2px 12px rgba(0,0,0,.25);
}
.dorm-cmp-btn { font-size: .85rem; line-height: 1; padding: .2rem .45rem !important; }
.dorm-cmp-active { background: #3b5bdb !important; color: white !important; border-color: #3b5bdb !important; }

/* ── Admin/Mod quick-edit FAB ──────────────────────────────────── */
#admin-edit-fab {
  position: fixed;
  bottom: 1.5rem;
  right: 1.5rem;
  z-index: 1090;
  display: flex;
  align-items: center;
  gap: .4rem;
  padding: .6rem 1rem .6rem .8rem;
  background: #4f46e5;
  color: #fff;
  border: none;
  border-radius: 2rem;
  font-size: .88rem;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(79,70,229,.45);
  transition: background .15s, box-shadow .15s, transform .1s;
}
#admin-edit-fab:hover { background: #4338ca; box-shadow: 0 6px 18px rgba(79,70,229,.55); transform: translateY(-1px); }
#admin-edit-fab.fab-active { background: #d97706; box-shadow: 0 4px 14px rgba(217,119,6,.45); }
#admin-edit-fab.fab-active:hover { background: #b45309; }
#admin-edit-fab-icon { font-size: 1rem; line-height: 1; }

/* ── Dorm Compare Search Dropdown ───────────────────────────────── */
.dorm-search-dropdown {
  position: absolute;
  top: 100%;
  left: 0; right: 0;
  background: white;
  border: 1px solid #d1d5db;
  border-radius: .5rem;
  box-shadow: 0 4px 16px rgba(0,0,0,.12);
  z-index: 200;
  max-height: 220px;
  overflow-y: auto;
}
.dorm-search-opt {
  padding: .5rem .75rem;
  cursor: pointer;
  border-bottom: 1px solid #f3f4f6;
  font-size: .9rem;
}
.dorm-search-opt:last-child { border-bottom: none; }
.dorm-search-opt:hover { background: #f0f4ff; }

/* ── Room Assignment Helper ──────────────────────────────────────── */
.rah-results-list { margin-top: .75rem; display: flex; flex-direction: column; gap: .5rem; }
.rah-result-card {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .75rem 1rem;
  background: #f8faff;
  border: 1px solid #e0e7ff;
  border-radius: .6rem;
  flex-wrap: wrap;
}
.rah-rank { font-size: 1.3rem; flex-shrink: 0; width: 2rem; text-align: center; }
.rah-info { flex: 1; min-width: 180px; }
.rah-meta { font-size: .8rem; color: #6b7280; margin: .15rem 0 .3rem; }
.rah-badges { display: flex; flex-wrap: wrap; gap: .3rem; }
.rah-rating { display: flex; flex-direction: column; align-items: flex-end; gap: .2rem; min-width: 70px; }

/* ── Watch Room ──────────────────────────────────────────────────── */
.btn-active-watch {
  background: #fef3c7 !important;
  color: #92400e !important;
  border-color: #fcd34d !important;
}
.btn-danger {
  background: #fee2e2 !important;
  color: #b91c1c !important;
  border-color: #fca5a5 !important;
}
.btn-danger:hover { background: #fecaca !important; }

/* ── Room Submission Wizard ──────────────────────────────────────── */
.wizard-progress {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  margin-bottom: 1.5rem;
}
.wizard-dot {
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  border: 2px solid #d1d5db;
  background: white;
  color: #6b7280;
  font-size: .8rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .2s, border-color .2s, color .2s;
  flex-shrink: 0;
}
.wizard-dot.active {
  background: #3b5bdb;
  border-color: #3b5bdb;
  color: white;
}

/* Before/After photo wizard progress (May 2026) — uses thinner pill dots
   than the room wizard since the modal is narrower. */
.ba-progress-dot {
  flex: 1;
  height: 6px;
  border-radius: 3px;
  background: #e5e7eb;
  transition: background .2s;
}
.ba-progress-dot.ba-progress-active {
  background: linear-gradient(90deg, #f59e0b 0%, #16a34a 100%);
}
.wizard-dot.done {
  background: #22c55e;
  border-color: #22c55e;
  color: white;
}
.wizard-line {
  width: 2.5rem;
  height: 2px;
  background: #e5e7eb;
  flex-shrink: 0;
}
.wizard-step { display: none; }
.wizard-step.active { display: block; }

/* Wizard resume banner (2026-05-09 — brainstorm idea #1). Sits above
   the hero on the home view when there's a saved wizard session. Two
   buttons: Resume (opens wizard) + Discard (clears session). */
.wizard-resume-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  margin: 0 auto 1rem;
  max-width: var(--ds-max-content, 1100px);
  background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
  border: 1px solid #fbbf24;
  border-radius: 0.6rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.wizard-resume-content {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex: 1 1 auto;
  min-width: 0;
}
.wizard-resume-icon { font-size: 1.4rem; line-height: 1; }
.wizard-resume-text { font-size: 0.86rem; color: #78350f; line-height: 1.4; }
.wizard-resume-detail { font-weight: 400; color: #92400e; }
.wizard-resume-actions { display: flex; gap: 0.4rem; flex-shrink: 0; }
@media (max-width: 480px) {
  .wizard-resume-banner { flex-direction: column; align-items: flex-start; }
  .wizard-resume-actions { width: 100%; }
}

/* Photo coverage chips (2026-05-09 — brainstorm idea #5). Six labeled
   targets that flip from neutral to green when the user uploads a
   matching-category photo. Visual nudge, not a gate. */
.wizard-cov-chip {
  display: inline-flex;
  align-items: center;
  font-size: 0.78rem;
  padding: 0.25rem 0.55rem;
  border-radius: 999px;
  border: 1px solid #cbd5e1;
  background: white;
  color: #64748b;
  font-weight: 500;
  transition: background-color 0.18s, border-color 0.18s, color 0.18s;
}
.wizard-cov-chip.covered {
  background: #dcfce7;
  border-color: #16a34a;
  color: #15803d;
  font-weight: 600;
}
.wizard-cov-chip.covered::before { content: '✓ '; font-weight: 700; }

/* Highlight + shake for required widgets that fail validation. Added by
   _wizardHighlightMissing (app.js, 2026-05-09) and auto-cleared on click
   or after 6s. Outline + offset stays outside the normal layout so we
   don't reflow the form. Soft red tint + shake draws the eye instantly. */
.wizard-required-missing {
  outline: 2px solid #ef4444;
  outline-offset: 4px;
  border-radius: 6px;
  background: rgba(239, 68, 68, 0.06);
  animation: wizardRequiredShake 0.45s ease-in-out;
}
@keyframes wizardRequiredShake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-5px); }
  40% { transform: translateX(5px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(3px); }
}
.wizard-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid #e5e7eb;
  /* Ensure footer is always visible above safe-area on iOS */
  position: sticky;
  bottom: 0;
  background: var(--ds-bg, #fff);
  z-index: 2;
}
#wizard-step-lbl {
  font-size: .8rem;
  color: #6b7280;
  font-weight: 500;
}
.wizard-two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .75rem;
}
@media (max-width: 480px) { .wizard-two-col { grid-template-columns: 1fr; } }
.wizard-msg {
  margin-top: .75rem;
  padding: .5rem .75rem;
  border-radius: .4rem;
  font-size: .85rem;
  display: none;
}
.wizard-msg.error { display: block; background: #fee2e2; color: #b91c1c; border: 1px solid #fca5a5; }
.wizard-msg.success { display: block; background: #dcfce7; color: #15803d; border: 1px solid #86efac; }

/* ── Points counter widget (wizard) ─────────────────────────────── */
/* Sticky-ish indigo panel that lives between the progress dots and the
 * current step content. Updates live as the user fills in each field
 * so the perceived value of every input is visible the entire time.
 * The bump animation flashes amber when the total goes up, which is
 * the dopamine hook that rewards "more detail = more points". */
.wizard-points-widget {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .75rem 1rem;
  margin: -.25rem 0 1.25rem;
  background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
  border-radius: .65rem;
  color: white;
  box-shadow: 0 2px 8px rgba(99, 102, 241, 0.25);
}
.wpw-icon {
  font-size: 1.6rem;
  line-height: 1;
  flex-shrink: 0;
}
.wpw-content { flex: 1; min-width: 0; }
.wpw-label {
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .02em;
  text-transform: uppercase;
  opacity: .9;
  margin-bottom: .1rem;
}
.wpw-value-row { display: flex; align-items: baseline; gap: .35rem; }
.wpw-value {
  font-size: 1.6rem;
  font-weight: 800;
  line-height: 1;
  display: inline-block;
  transition: transform .25s ease, color .25s ease;
}
.wpw-value.bump { transform: scale(1.18); color: #fbbf24; }
.wpw-suffix { font-size: .85rem; font-weight: 600; opacity: .9; }
.wpw-tip { font-size: .72rem; opacity: .85; margin-top: .15rem; }

/* Inline "+N pts" pills next to wizard field labels. Indigo when the
 * field is empty (a promise of points if you fill it in), green when
 * the field is filled (points already earned/queued). */
.field-pts {
  display: inline-block;
  margin-left: .35rem;
  padding: .08rem .4rem;
  border-radius: 999px;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .02em;
  background: #eef2ff;
  color: #4338ca;
  border: 1px solid #c7d2fe;
  vertical-align: middle;
  transition: background .2s, color .2s, border-color .2s;
}
.field-pts.earned {
  background: #dcfce7;
  color: #15803d;
  border-color: #86efac;
}
@media (max-width: 480px) {
  .wizard-points-widget { padding: .6rem .75rem; gap: .5rem; }
  .wpw-icon { font-size: 1.3rem; }
  .wpw-label { font-size: .65rem; }
  .wpw-value { font-size: 1.35rem; }
}

/* ── Tag Toggle Buttons (wizard step 3) ─────────────────────────── */
.tag-toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  padding: .3rem .65rem;
  border-radius: 999px;
  border: 1px solid #d1d5db;
  background: #f9fafb;
  font-size: .82rem;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
  user-select: none;
}
.tag-toggle-btn:hover { background: #e0e7ff; border-color: #a5b4fc; }
.tag-toggle-btn.selected {
  background: #3b5bdb;
  border-color: #3b5bdb;
  color: white;
}

/* ── AI Summary ──────────────────────────────────────────────────── */
#ai-summary-section {
  border-radius: .6rem;
  padding: 1rem 1.1rem;
  margin-bottom: .75rem;
  background: linear-gradient(135deg, #eff6ff 0%, #f5f3ff 100%);
  border: 1px solid #c7d2fe;
}
#ai-summary-section .ai-summary-header {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .4rem;
  font-weight: 600;
  font-size: .9rem;
  color: #3730a3;
}
.ai-summary-badge {
  font-size: .7rem;
  background: #e0e7ff;
  color: #4338ca;
  border-radius: 999px;
  padding: .1rem .5rem;
  font-weight: 500;
}
#ai-summary-text {
  font-size: .9rem;
  color: #374151;
  line-height: 1.55;
  margin: 0;
}

/* ── Proximity / Walking Distances ───────────────────────────────── */
.proximity-list { display: flex; flex-direction: column; gap: .4rem; }
.proximity-row {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .5rem .65rem;
  background: #f8faff;
  border: 1px solid #e0e7ff;
  border-radius: .45rem;
  font-size: .88rem;
}
.proximity-icon { font-size: 1rem; flex-shrink: 0; width: 1.4rem; text-align: center; }
.proximity-name { flex: 1; font-weight: 500; color: #1f2937; }
.proximity-dist { font-size: .78rem; color: #6b7280; white-space: nowrap; }

/* ── Correction modal: toggle buttons ───────────────────────────── */
.correction-toggle-wrap {
  display: flex;
  gap: .5rem;
  margin-top: .1rem;
}
.correction-toggle-btn {
  flex: 1;
  padding: .55rem 1rem;
  border: 2px solid #e5e7eb;
  border-radius: .4rem;
  background: #f9fafb;
  cursor: pointer;
  font-size: .9rem;
  font-weight: 500;
  transition: border-color .15s, background .15s;
}
.correction-toggle-btn:hover { border-color: #a5b4fc; background: #eef2ff; }
.correction-toggle-btn.active { border-color: #6366f1; background: #ede9fe; color: #4338ca; font-weight: 600; }

/* ── Ad Slots (public) ───────────────────────────────────────────── */
.ad-slot { position: relative; }
.ad-slot-full-width { width: 100%; }
.ad-slot-label {
  font-size: .68rem;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: .05em;
  margin-bottom: .3rem;
  font-weight: 500;
}
.ad-placeholder {
  background: #f3f4f6;
  border: 2px dashed #d1d5db;
  border-radius: .5rem;
  padding: 1rem 1.25rem;
  font-size: .85rem;
  color: #6b7280;
  text-align: center;
}
.ad-slot-banner .ad-slot-inner { overflow: hidden; }
.affiliate-link-card {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .55rem .75rem;
  border: 1px solid #e5e7eb;
  border-radius: .45rem;
  text-decoration: none;
  color: inherit;
  background: white;
  margin-bottom: .4rem;
  transition: box-shadow .15s;
}
.affiliate-link-card:hover { box-shadow: 0 2px 8px rgba(0,0,0,.08); border-color: #a5b4fc; }
.affiliate-img { width: 48px; height: 48px; object-fit: cover; border-radius: .3rem; flex-shrink: 0; }
.affiliate-name { font-weight: 600; font-size: .88rem; color: #1f2937; }
.affiliate-desc { font-size: .78rem; color: #6b7280; margin-top: .15rem; }
.sponsored-card {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: .6rem;
  padding: .85rem 1rem;
}
.sponsored-img { width: 80px; height: 60px; object-fit: cover; border-radius: .4rem; flex-shrink: 0; }
.sponsored-title { font-weight: 600; font-size: .95rem; color: #1f2937; margin-bottom: .2rem; }
.sponsored-desc { font-size: .84rem; color: #4b5563; }

/* ── Context-aware affiliate (Apr 2026) — used by affiliate-packing-rules slot ── */
.ad-context-label {
  font-size: .92rem;
  font-weight: 600;
  color: #1f2937;
  margin-bottom: .5rem;
  display: flex;
  align-items: center;
  gap: .5rem;
}
.ad-context-tag {
  font-size: .68rem;
  font-weight: 500;
  color: #6366f1;
  background: #eef2ff;
  padding: 2px 8px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.affiliate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: .5rem;
}
.affiliate-reason {
  font-size: .75rem;
  color: #4338ca;
  margin-top: .15rem;
  font-style: italic;
}
.ad-disclosure {
  font-size: .7rem;
  color: #6b7280;
  margin-top: .5rem;
  text-align: right;
}

/* ── Sponsored housing card (Apr 2026) — sponsored-housing-grid slot ── */
.sponsored-housing-card {
  position: relative;
  display: block;
  text-decoration: none;
  color: inherit;
  background: white;
  border: 1px solid #fbbf24;
  border-radius: .65rem;
  overflow: hidden;
  box-shadow: 0 2px 6px rgba(251, 191, 36, 0.15);
  transition: transform .15s, box-shadow .15s;
}
.sponsored-housing-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(251, 191, 36, 0.25);
}
.sponsored-housing-card .sponsored-tag {
  position: absolute;
  top: .55rem;
  right: .55rem;
  background: #fbbf24;
  color: #78350f;
  font-size: .65rem;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  z-index: 2;
}
.sponsored-housing-img {
  width: 100%;
  height: 180px;
  object-fit: cover;
  display: block;
}
.sponsored-housing-img-placeholder {
  width: 100%;
  height: 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 3rem;
  background: linear-gradient(135deg, #fef3c7, #fde68a);
}
.sponsored-housing-body { padding: .85rem 1rem; }
.sponsored-housing-name { font-weight: 700; font-size: 1.05rem; color: #1f2937; }
.sponsored-housing-loc { font-size: .82rem; color: #6b7280; margin-top: .15rem; }
.sponsored-housing-stats { font-size: .82rem; color: #4b5563; margin-top: .35rem; }
.sponsored-housing-chips {
  display: flex;
  flex-wrap: wrap;
  gap: .25rem;
  margin-top: .5rem;
}
.sh-chip {
  font-size: .7rem;
  background: #f3f4f6;
  color: #374151;
  padding: 2px 7px;
  border-radius: 999px;
}
.sponsored-housing-cta {
  margin-top: .75rem;
  font-weight: 600;
  font-size: .88rem;
  color: #d97706;
}

/* ── Inline Edit Mode ────────────────────────────────────────────── */

/* Edit mode hover effect on editable zones */
.edit-mode [data-edit-section] {
  outline: 2px dashed transparent;
  outline-offset: 4px;
  transition: outline-color .15s;
}
.edit-mode [data-edit-section]:hover {
  outline-color: #6366f1;
  cursor: default;
}

/* Pencil button that appears on hover */
.edit-zone-btn {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 200;
  display: none;
  width: 28px;
  height: 28px;
  padding: 0;
  font-size: .9rem;
  line-height: 28px;
  text-align: center;
  background: #6366f1;
  color: white;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(99,102,241,.4);
  transition: transform .1s, box-shadow .1s;
}
.edit-mode [data-edit-section]:hover .edit-zone-btn { display: block; }
.edit-zone-btn:hover { transform: scale(1.12); box-shadow: 0 2px 8px rgba(99,102,241,.6); }

/* Backdrop (semi-transparent dim) */
#inline-edit-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.25);
  z-index: 1199;
}

/* Floating popover */
#inline-edit-popover {
  display: none;
  position: absolute;
  z-index: 1200;
  width: 360px;
  max-width: calc(100vw - 16px);
  max-height: 85vh;
  overflow-y: auto;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: .7rem;
  box-shadow: 0 8px 24px rgba(0,0,0,.16);
}
.iep-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .75rem 1rem;
  border-bottom: 1px solid #e5e7eb;
  background: #f9fafb;
  border-radius: .7rem .7rem 0 0;
}
.iep-title {
  margin: 0;
  font-size: .95rem;
  font-weight: 600;
  color: #1f2937;
}
.iep-close-btn {
  background: none;
  border: none;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  color: #6b7280;
  padding: 2px 5px;
  border-radius: .25rem;
}
.iep-close-btn:hover { color: #374151; background: #f3f4f6; }
#iep-fields { padding: .85rem 1rem; display: flex; flex-direction: column; gap: .65rem; }
.iep-field { display: flex; flex-direction: column; gap: .2rem; }
.iep-field-check { flex-direction: row; align-items: center; gap: .5rem; padding: .2rem 0; }
.iep-label { font-size: .78rem; font-weight: 600; color: #374151; text-transform: uppercase; letter-spacing: .03em; }
.iep-input {
  padding: .38rem .55rem;
  border: 1px solid #d1d5db;
  border-radius: .35rem;
  font-size: .88rem;
  font-family: inherit;
  color: #1f2937;
  background: white;
  transition: border-color .12s;
  width: 100%;
  box-sizing: border-box;
}
.iep-input:focus { outline: none; border-color: #6366f1; box-shadow: 0 0 0 3px rgba(99,102,241,.12); }
.iep-checkbox { display: flex; align-items: center; gap: .45rem; font-size: .88rem; color: #374151; cursor: pointer; }
.iep-hint { font-size: .73rem; color: #6b7280; margin-top: .15rem; }
.iep-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .65rem 1rem;
  border-top: 1px solid #e5e7eb;
  gap: .5rem;
}
#iep-msg { font-size: .83rem; flex: 1; }
#iep-save {
  padding: .38rem .9rem;
  background: #6366f1;
  color: white;
  border: none;
  border-radius: .35rem;
  font-size: .88rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .12s;
}
#iep-save:hover:not(:disabled) { background: #4f46e5; }
#iep-save:disabled { opacity: .6; cursor: not-allowed; }
#iep-cancel {
  padding: .38rem .75rem;
  background: white;
  color: #6b7280;
  border: 1px solid #d1d5db;
  border-radius: .35rem;
  font-size: .88rem;
  cursor: pointer;
}
#iep-cancel:hover { background: #f9fafb; }

/* ─── Feature #40: Room Videos ─────────────────────────────────────────────── */
.video-card { margin-bottom:1rem; border:1px solid #e5e7eb; border-radius:.6rem; overflow:hidden; background:white; }
.video-card-meta { padding:.5rem .75rem; font-size:.82rem; color:#6b7280; }
.video-link-card { display:flex;align-items:center;gap:.75rem;padding:.75rem;text-decoration:none;color:#1f2937;border:1px solid #e5e7eb;border-radius:.5rem;margin-bottom:.75rem;transition:background .15s; }
.video-link-card:hover { background:#f9fafb; }

/* ─── Feature #42: Review Accuracy Prompts ──────────────────────────────────── */
.accuracy-prompt { font-size:.8rem; color:#92400e; background:#fef3c7; border-left:3px solid #fcd34d; padding:.4rem .75rem; margin-top:.5rem; border-radius:0 .4rem .4rem 0; display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; }
.accuracy-prompt .btn-link { font-size:.8rem; }

/* ─── Feature #46: Noise Level Heatmap ────────────────────────────────────────── */
.noise-floor-row { display:flex; align-items:center; gap:.6rem; margin-bottom:.4rem; font-size:.85rem; }
.noise-floor-label { width:3.5rem; text-align:right; color:#6b7280; flex-shrink:0; }
.noise-floor-bar-wrap { flex:1; background:#f3f4f6; border-radius:4px; height:16px; overflow:hidden; }
.noise-floor-bar { height:100%; border-radius:4px; transition:width .4s; }
.noise-floor-val { width:3.5rem; color:#374151; font-weight:500; flex-shrink:0; }

/* ─── Feature #37: Campus Map View ──────────────────────────────────────────────── */
#campus-map .leaflet-container { font-family: inherit; }
.map-popup-name { font-weight:600; font-size:.9rem; margin-bottom:.2rem; }
.map-popup-meta { font-size:.78rem; color:#6b7280; margin-bottom:.4rem; }
.map-popup-link { font-size:.82rem; color:#6366f1; cursor:pointer; text-decoration:underline; background:none; border:none; padding:0; }

/* ─── Feature #39: Best-For Categories ───────────────────────────────────────── */
.best-for-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:.75rem; }
.best-for-card { background:white; border:1px solid #e5e7eb; border-radius:.6rem; padding:.85rem 1rem; }
.best-for-title { font-size:.82rem; font-weight:700; color:#374151; margin-bottom:.5rem; text-transform:uppercase; letter-spacing:.03em; }
.best-for-dorm-chip { display:inline-block; margin:.2rem .15rem; padding:.25rem .6rem; background:#f3f4f6; border-radius:999px; font-size:.8rem; color:#1f2937; cursor:pointer; border:1px solid #e5e7eb; transition:all .15s; }
.best-for-dorm-chip:hover { background:#ede9fe; border-color:#c4b5fd; color:#5b21b6; }

/* ─── Feature #43: Public Profiles ──────────────────────────────────────────── */
.profile-header { display:flex;align-items:center;gap:1.25rem;padding:1.5rem;background:white;border:1px solid #e5e7eb;border-radius:.7rem;margin-bottom:1.5rem; }
.profile-avatar { width:64px;height:64px;border-radius:50%;background:#ede9fe;display:flex;align-items:center;justify-content:center;font-size:1.8rem;font-weight:700;color:#6366f1;flex-shrink:0; }
.profile-name { font-size:1.25rem;font-weight:700;color:#1f2937;margin:0 0 .2rem; }
.profile-joined { font-size:.82rem;color:#6b7280; }
.profile-stats { display:flex;gap:1.5rem;margin-top:.6rem; }
.profile-stat { text-align:center; }
.profile-stat-val { font-size:1.3rem;font-weight:700;color:#6366f1; }
.profile-stat-lbl { font-size:.72rem;color:#6b7280;text-transform:uppercase;letter-spacing:.04em; }
.profile-review-card { background:white;border:1px solid #e5e7eb;border-radius:.6rem;padding:1rem;margin-bottom:.75rem;text-decoration:none;display:block;color:inherit;transition:box-shadow .15s; }
.profile-review-card:hover { box-shadow:0 2px 8px rgba(0,0,0,.08);border-color:#a5b4fc; }

/* ─── Feature #45: Room Swap Board ──────────────────────────────────────────── */
.swap-card { background:white; border:1px solid #e5e7eb; border-radius:.6rem; padding:.9rem 1rem; margin-bottom:.65rem; }
.swap-type-badge { display:inline-block; padding:.2rem .55rem; border-radius:999px; font-size:.75rem; font-weight:600; margin-bottom:.4rem; }
.swap-type-swap { background:#dbeafe; color:#1e40af; }
.swap-type-available { background:#d1fae5; color:#065f46; }
.swap-type-wanted { background:#fef3c7; color:#92400e; }
.swap-desc { font-size:.92rem; color:#1f2937; margin-bottom:.3rem; }
.swap-meta { font-size:.78rem; color:#6b7280; }
.swap-contact-reveal { font-size:.8rem; }

/* ─── Feature #48/49: Moving/Off-Campus ───────────────────────────────────────── */
.moving-section { background:white; border:1px solid #e5e7eb; border-radius:.7rem; padding:1.25rem 1.5rem; margin-bottom:1rem; }
.moving-section h2 { font-size:1.05rem; font-weight:700; color:#1f2937; margin:0 0 .75rem; }
.moving-tip-list { list-style:none; padding:0; margin:0; }
.moving-tip-list li { padding:.4rem 0; border-bottom:1px solid #f3f4f6; font-size:.9rem; color:#374151; }
.moving-tip-list li:last-child { border-bottom:none; }
.moving-tip-list li::before { content:"✓ "; color:#22c55e; font-weight:700; }

/* ─── Feature #54: Photo datestamps ───────────────────────────────────────────── */
.photo-year-badge { position:absolute; bottom:6px; left:6px; background:rgba(0,0,0,0.6); color:white; font-size:10px; padding:2px 6px; border-radius:4px; pointer-events:none; }

/* ─── Feature #55: Room change flags ───────────────────────────────────────────── */
.room-change-banner { background:#fef3c7; border:1px solid #f59e0b; border-radius:8px; padding:10px 14px; margin-bottom:12px; font-size:.85rem; color:#92400e; display:flex; align-items:center; gap:8px; }

/* ─── Feature #56: Room condition timeline ────────────────────────────────────── */
.freshness-strip { display:flex; flex-wrap:wrap; gap:8px; margin:12px 0; }
.freshness-chip { font-size:.75rem; padding:4px 10px; border-radius:12px; font-weight:500; }
.freshness-green { background:#d1fae5; color:#065f46; }
.freshness-amber { background:#fef3c7; color:#92400e; }
.freshness-red { background:#fee2e2; color:#991b1b; }

/* ─── Feature #60: Room photo challenges ─────────────────────────────────────── */
#photo-challenge-banner { display:none; background:#eef2ff; border:1px solid #6366f1; border-radius:8px; padding:10px 14px; margin-bottom:12px; font-size:.85rem; color:#3730a3; align-items:center; gap:10px; flex-wrap:wrap; }
.challenge-icon { font-size:1.4rem; flex-shrink:0; }
.challenge-text { display:flex; flex-direction:column; gap:2px; flex:1; }
.challenge-text strong { font-size:.88rem; font-weight:600; }
.challenge-text span { font-size:.82rem; color:#4f46e5; }

/* ─── Feature #61: Graduation year on profiles ───────────────────────────────── */
/* (grad_year badge reuses .reviewer-context-tag — no extra CSS needed) */

/* ─── Feature #52: Room furnishings inventory ──────────────────────────────────── */
.furnishing-chip { display:inline-block; background:#f3f4f6; border:1px solid #e5e7eb; border-radius:999px; padding:.22rem .65rem; font-size:.78rem; color:#374151; margin:.2rem .15rem; }

/* ─── Feature #57: Build your shortlist ────────────────────────────────────────── */
.shortlist-card { background:white; border:1px solid #e5e7eb; border-radius:.6rem; padding:1rem; cursor:pointer; transition:box-shadow .15s, border-color .15s; }
.shortlist-card:hover { box-shadow:0 2px 10px rgba(0,0,0,.08); border-color:#a5b4fc; }
.shortlist-card-name { font-size:.95rem; font-weight:700; color:#1f2937; margin-bottom:.25rem; }
.shortlist-card-meta { font-size:.8rem; color:#6b7280; display:flex; flex-wrap:wrap; gap:.4rem; }
.shortlist-card-rating { font-size:.82rem; color:#f59e0b; font-weight:600; margin-top:.35rem; }
#shortlist-results { display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:.75rem; margin-top:1rem; }

/* ─── Feature #53: Fridge / appliance rental ───────────────────────────────────── */
.rental-provider-card { display:flex; align-items:center; gap:.75rem; padding:.6rem .75rem; border:1px solid #e5e7eb; border-radius:.5rem; background:white; margin-bottom:.5rem; text-decoration:none; color:#1f2937; font-size:.88rem; transition:background .15s; }
.rental-provider-card:hover { background:#f9fafb; }

/* ─── Feature #59: Currently living here ──────────────────────────────────────── */
.residents-count-badge { display:inline-flex; align-items:center; gap:.35rem; background:#ecfdf5; color:#065f46; border:1px solid #86efac; border-radius:999px; padding:.25rem .65rem; font-size:.78rem; font-weight:600; }

/* ─── Feature #64: Decision season banner ─────────────────────────────────────── */
#decision-season-banner .decision-title { font-size:1.1rem; font-weight:700; margin-bottom:.3rem; }
#decision-season-banner .decision-sub { font-size:.85rem; opacity:.9; margin-bottom:.6rem; }

/* ─── Feature #66: Blog cards in SPA ──────────────────────────────────────────── */
.blog-preview-card { background:white; border:1px solid #e5e7eb; border-radius:.65rem; padding:1rem 1.25rem; margin-bottom:.75rem; text-decoration:none; color:inherit; display:block; transition:box-shadow .15s; }
.blog-preview-card:hover { box-shadow:0 2px 10px rgba(0,0,0,.08); border-color:#a5b4fc; }
.blog-preview-card h3 { font-size:.98rem; font-weight:700; color:#1f2937; margin:0 0 .3rem; }
.blog-preview-card p { font-size:.83rem; color:#6b7280; margin:0; line-height:1.5; }

/* ========================================================================
   THE BRIEF — compact dorm-page icon strip (April 2026)
   Replaces 8 standalone dorm-page sections (Key Facts, Policy, Class Levels,
   Building Amenities, Accessibility, Laundry, Dining, Appliance Rental) with
   a single 13-icon glanceable strip + expandable "Full details" drawer.
   Canonical visual reference: public/mockups/dorm-brief.html
   ======================================================================== */

/* Category palette — 8 colors grouped by meaning */
:root {
  --cat-climate:   #3b82f6;  /* blue   — AC */
  --cat-kitchen:   #dc2626;  /* red    — shared kitchen */
  --cat-dining:    #f97316;  /* orange — dining on site */
  --cat-bathroom:  #14b8a6;  /* teal   — bathroom, laundry */
  --cat-access:    #10b981;  /* green  — elevator, ADA, parking */
  --cat-inclusive: #a855f7;  /* purple — LGBTQ+, gender-inclusive, pets */
  --cat-structure: #6366f1;  /* indigo — dorm style, gender policy, campus */
  --cat-facts:     #64748b;  /* slate  — year built, capacity, class, floors */
  --cat-grade:     #d97706;  /* amber/gold — dorm grade (distinct 9th category) */
  --cat-laundry:   #14b8a6;

  --brief-unknown-border: #cbd5e1;
  --brief-unknown-bg:     #f1f5f9;
  --brief-unknown-text:   #94a3b8;
  --brief-no-bg:          #f1f5f9;
  --brief-no-text:        #94a3b8;
}

.brief-strip {
  background: white;
  border-radius: 12px;
  padding: 1.25rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
  margin-bottom: 1rem;
}
.brief-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
  flex-wrap: wrap;
  gap: .5rem;
}
.brief-title {
  font-weight: 700;
  font-size: 1rem;
  color: #0f172a;
  letter-spacing: -.01em;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
}
.brief-explainer-btn {
  background: transparent;
  border: 1px solid var(--md3-outline-variant, #e2e8f0);
  width: 22px;
  height: 22px;
  border-radius: 50%;
  font-size: .72rem;
  font-weight: 700;
  color: var(--md3-primary, #6366f1);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  line-height: 1;
  transition: background-color .15s, color .15s;
}
.brief-explainer-btn:hover,
.brief-explainer-btn:focus-visible {
  background: var(--md3-primary-container, rgba(99,102,241,0.1));
  color: var(--md3-on-primary-container, #4338ca);
  outline: none;
}
.brief-explainer {
  position: relative;
  background: var(--md3-primary-container, #e0e7ff);
  color: var(--md3-on-primary-container, #1e1b4b);
  border-radius: var(--md3-shape-md, 12px);
  padding: .65rem 2.25rem .65rem .85rem;
  font-size: .82rem;
  line-height: 1.4;
  margin-bottom: .9rem;
  border: 1px solid rgba(99,102,241,0.15);
}
.brief-explainer-dismiss {
  position: absolute;
  top: 4px;
  right: 6px;
  background: transparent;
  border: none;
  font-size: 1.1rem;
  line-height: 1;
  color: inherit;
  cursor: pointer;
  opacity: .65;
  padding: 4px 8px;
  border-radius: 50%;
}
.brief-explainer-dismiss:hover { opacity: 1; }
.brief-subtitle {
  font-size: .72rem;
  color: #64748b;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .05em;
}
.brief-full-details-btn {
  background: transparent;
  border: 1px solid #e2e8f0;
  border-radius: 999px;
  padding: .4rem .9rem;
  font-size: .8rem;
  font-weight: 600;
  color: #475569;
  cursor: pointer;
  transition: all .15s;
}
.brief-full-details-btn:hover {
  border-color: #6366f1;
  color: #6366f1;
}

.brief-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
  gap: .5rem;
}
@media (max-width: 520px) {
  .brief-grid { grid-template-columns: repeat(4, 1fr); }
}

.brief-cell {
  background: transparent;
  border: none;
  padding: .5rem .25rem;
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .4rem;
  cursor: pointer;
  transition: background .12s;
  font-family: inherit;
  color: inherit;
}
.brief-cell:hover { background: #f8fafc; }
.brief-cell:focus-visible { outline: 2px solid #6366f1; outline-offset: 2px; }

.brief-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
}
.brief-icon svg { width: 26px; height: 26px; }
@media (max-width: 520px) {
  .brief-icon { width: 44px; height: 44px; }
  .brief-icon svg { width: 24px; height: 24px; }
}

/* YES state — filled, colored */
.brief-icon.yes {
  background: var(--cat-color);
  color: white;
}
.brief-icon.yes svg { stroke: white; fill: none; }

/* NO state — muted icon with bold red X across the whole tile */
.brief-icon.no {
  background: var(--brief-no-bg);
  color: var(--brief-no-text);
  position: relative;
  overflow: hidden;
}
.brief-icon.no svg { stroke: var(--brief-no-text); fill: none; opacity: .5; }
.brief-icon.no::before,
.brief-icon.no::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 130%;
  height: 4px;
  background: var(--md3-error);
  border-radius: 2px;
  pointer-events: none;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.6);
}
.brief-icon.no::before { transform: translate(-50%, -50%) rotate(45deg); }
.brief-icon.no::after  { transform: translate(-50%, -50%) rotate(-45deg); }

/* UNKNOWN state — dashed outline with "?" */
.brief-icon.unknown {
  background: var(--brief-unknown-bg);
  color: var(--brief-unknown-text);
  border: 2px dashed var(--brief-unknown-border);
  font-size: 1.5rem;
  font-weight: 700;
}
.brief-icon.unknown svg { display: none; }
.brief-icon.unknown::before {
  content: '?';
  font-size: 1.6rem;
  color: var(--brief-unknown-text);
  font-weight: 700;
  line-height: 1;
}

/* VALUE state — number shown on the face, no icon */
.brief-icon.value {
  background: var(--cat-color);
  color: white;
  font-weight: 700;
  font-size: .95rem;
  line-height: 1;
  flex-direction: column;
}
.brief-icon.value svg { display: none; }
.brief-icon.value .value-big {
  font-size: 1.05rem;
  font-weight: 800;
}
.brief-icon.value .value-small {
  font-size: .62rem;
  font-weight: 600;
  opacity: .85;
  text-transform: uppercase;
  letter-spacing: .03em;
}

/* Tiny dynamic badge anchored to the bottom-right of the tile */
.brief-icon-badge {
  position: absolute;
  right: -4px;
  bottom: -4px;
  background: white;
  color: var(--cat-color);
  border: 2px solid var(--cat-color);
  border-radius: 999px;
  padding: 1px 6px;
  font-size: .55rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .03em;
  white-space: nowrap;
  line-height: 1.1;
}

.brief-label {
  font-size: .68rem;
  font-weight: 600;
  color: #475569;
  text-align: center;
  line-height: 1.25;
  max-width: 90px;
}
.brief-label small {
  display: block;
  color: #94a3b8;
  font-weight: 500;
  font-size: .6rem;
  margin-top: 1px;
}

/* LGBTQ+ rainbow override (used when the dorm is flagged welcoming) */
.brief-icon.rainbow {
  background: linear-gradient(180deg,
    #e74c3c 0%,   #e74c3c 17%,
    #f39c12 17%,  #f39c12 34%,
    #f1c40f 34%,  #f1c40f 51%,
    #27ae60 51%,  #27ae60 67%,
    #2980b9 67%,  #2980b9 84%,
    #8e44ad 84%,  #8e44ad 100%);
  color: white;
}
.brief-icon.rainbow svg { stroke: white; }

/* Bottom-sheet / tap detail popup */
.brief-sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.4);
  display: none;
  align-items: flex-end;
  justify-content: center;
  z-index: 9000;
}
.brief-sheet-backdrop.open { display: flex; }
.brief-sheet {
  background: white;
  border-radius: 18px 18px 0 0;
  width: 100%;
  max-width: 560px;
  padding: 1.5rem 1.25rem 2rem;
  animation: briefSheetUp .2s ease-out;
}
@keyframes briefSheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }

.brief-sheet-grip {
  width: 40px;
  height: 4px;
  background: var(--md3-outline-variant);
  border-radius: 4px;
  margin: -.4rem auto 1rem;
}
.brief-sheet-head {
  display: flex;
  align-items: center;
  gap: .9rem;
  margin-bottom: .75rem;
}
.brief-sheet-icon {
  width: 52px;
  height: 52px;
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
  overflow: hidden;
}
.brief-sheet-icon svg { width: 28px; height: 28px; }
.brief-sheet-icon.no::before,
.brief-sheet-icon.no::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 130%;
  height: 4px;
  background: var(--md3-error);
  border-radius: 2px;
  pointer-events: none;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.6);
}
.brief-sheet-icon.no::before { transform: translate(-50%, -50%) rotate(45deg); }
.brief-sheet-icon.no::after  { transform: translate(-50%, -50%) rotate(-45deg); }
.brief-sheet-title { font-weight: 700; font-size: 1.1rem; color: var(--md3-on-surface); }
.brief-sheet-status {
  font-size: .8rem;
  font-weight: 600;
  padding: 2px 10px;
  border-radius: var(--md3-shape-full);
  display: inline-block;
  margin-top: 3px;
}
.brief-sheet-status.yes { background: var(--md3-secondary-container); color: var(--md3-on-secondary-container); }
.brief-sheet-status.no { background: var(--md3-error-container); color: var(--md3-on-error-container); }
.brief-sheet-status.unknown { background: var(--md3-surface-container); color: var(--md3-on-surface); }
.brief-sheet-body {
  color: var(--md3-on-surface);
  font-size: .92rem;
  line-height: 1.55;
}
.brief-sheet-actions {
  display: flex;
  gap: .5rem;
  margin-top: 1rem;
  flex-wrap: wrap;
}
.brief-sheet-btn {
  padding: .55rem 1rem;
  border-radius: var(--md3-shape-sm);
  border: 1px solid var(--md3-outline-variant);
  background: white;
  font-weight: 600;
  font-size: .85rem;
  cursor: pointer;
  color: var(--md3-on-surface);
  transition: all .12s;
}
.brief-sheet-btn:hover { background: var(--md3-surface-container-low); border-color: var(--md3-primary); color: var(--md3-primary); }
.brief-sheet-btn.primary { background: var(--md3-primary); color: var(--md3-on-primary); border-color: var(--md3-primary); }
.brief-sheet-btn.primary:hover { background: var(--md3-primary-40, #4f46e5); }

/* Full details drawer (expandable <details> below The Brief) */
.brief-details-drawer {
  background: white;
  border-radius: var(--md3-shape-md);
  box-shadow: var(--md3-elev-1);
  overflow: hidden;
  margin-bottom: 1rem;
}
.brief-details-summary {
  padding: 1rem 1.25rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
  color: var(--md3-on-surface);
  list-style: none;
  user-select: none;
}
.brief-details-summary::-webkit-details-marker { display: none; }
.brief-details-summary::before {
  content: '▶';
  color: var(--md3-on-surface-variant);
  font-size: .7rem;
  margin-right: .75rem;
  transition: transform .2s;
}
.brief-details-drawer[open] .brief-details-summary::before {
  transform: rotate(90deg);
}
.brief-details-body {
  padding: 0 1.25rem 1.25rem;
  border-top: 1px solid var(--md3-outline-variant);
  padding-top: 1rem;
}
.brief-kv-grid {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: .5rem 1.25rem;
  font-size: .9rem;
  align-items: baseline;
}
.brief-kv-grid dt {
  color: var(--md3-on-surface-variant);
  font-weight: 600;
  font-size: .82rem;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.brief-kv-grid dd { margin: 0; color: var(--md3-on-surface); }
.brief-kv-grid dd.unknown { color: var(--md3-on-surface-variant); font-style: italic; }
.brief-kv-grid dd.unknown a { font-style: normal; }
.brief-suggest-link {
  display: inline-block;
  margin-left: .4rem;
  font-size: .72rem;
  color: var(--md3-primary);
  text-decoration: none;
  opacity: 0;
  transition: opacity .15s ease, color .15s ease;
  font-weight: 500;
  white-space: nowrap;
}
.brief-kv-grid dd:hover .brief-suggest-link,
.brief-suggest-link:focus {
  opacity: .85;
}
.brief-suggest-link:hover {
  opacity: 1;
  text-decoration: underline;
  color: var(--md3-primary-40, #4338ca);
}
.brief-kv-grid dd.unknown .brief-suggest-link {
  opacity: .9;
  color: var(--md3-primary);
}
.brief-drawer-section { margin-bottom: 1.25rem; }
.brief-drawer-section h4 {
  font-size: .8rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--md3-on-surface-variant);
  margin: 0 0 .6rem;
  font-weight: 700;
}

/* ─── Always-visible amenity quick-facts panel (below The Brief) ── */
.dorm-amenities-quick {
  background: white;
  border-radius: var(--md3-shape-md);
  box-shadow: var(--md3-elev-1);
  padding: .75rem 1rem;
  margin-bottom: .75rem;
}
.aq-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .25rem 1.5rem;
}
@media (max-width: 560px) { .aq-grid { grid-template-columns: 1fr; } }
.aq-row {
  display: flex;
  align-items: flex-start;            /* top-align so wrapped values stay tidy */
  gap: .45rem;
  padding: .28rem 0;
  border-bottom: 1px solid var(--md3-outline-variant);
  font-size: .88rem;
  min-width: 0;                        /* allow flex children to shrink */
}
.aq-row:last-child { border-bottom: none; }
.aq-icon { font-size: 1rem; flex-shrink: 0; width: 1.35rem; text-align: center; }
.aq-label { color: var(--md3-on-surface-variant); flex-shrink: 0; padding-top: .05rem; }
/* Values can wrap onto a second line when long (e.g. "Pod-style (shared
   by a few rooms via the hallway)" used to overflow the grid column;
   nowrap was forcing it into the next column). min-width:0 + flex:1
   lets the value shrink to fit, then wrap inside its column. */
.aq-val {
  margin-left: auto;
  font-weight: 600;
  color: var(--md3-on-surface);
  text-align: right;
  flex: 1;
  min-width: 0;
  word-break: break-word;
  overflow-wrap: anywhere;
  line-height: 1.35;
}
.aq-val-text { color: var(--md3-on-surface); font-weight: 500; }
/* Success state for "yes" — using #15803d directly because M3 doesn't ship
   a dedicated "success" role in our token set; keep this hex but track for
   future when/if a success-container token gets added. */
.aq-yes { color: #15803d; font-weight: 600; }
.aq-no  { color: var(--md3-on-surface-variant); font-weight: 400; }
.aq-unknown { color: var(--md3-on-surface-variant); font-style: italic; font-weight: 400; }
/* Clickable amenity rows (May 2026) — wired to the correction modal so users
   can edit any field without leaving the dorm page. Reset native button
   styling so the row reads as a normal list row, not a button. */
.aq-row-clickable {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--md3-outline-variant);
  width: 100%;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  border-radius: var(--md3-shape-xs);
  transition: background-color .15s ease;
}
.aq-row-clickable:last-child { border-bottom: none; }
.aq-row-clickable:hover, .aq-row-clickable:focus-visible {
  background: var(--md3-surface-container-low);
  outline: none;
}
.aq-row-clickable:focus-visible {
  box-shadow: 0 0 0 2px var(--md3-primary);
}
.aq-edit-hint {
  color: var(--md3-outline-variant);
  font-size: .75rem;
  margin-left: .35rem;
  flex-shrink: 0;
  transition: color .15s ease;
}
.aq-row-clickable:hover .aq-edit-hint,
.aq-row-clickable:focus-visible .aq-edit-hint { color: var(--md3-primary); }

/* ─── Hamburger menu + drawer (Apr 2026) ────────────────────────── */
/* Hamburger button sits at the far right of the header, always visible. */
#user-notif-wrap {
  /* Position notification bell right before the hamburger menu button.
     Hamburger has order: 99, so this positions it at 98. The hamburger's
     margin-left: auto ensures it still anchors to the far right edge of the header. */
  order: 98;
}

.hamburger-btn {
  width: 40px;
  height: 40px;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 8px;
  cursor: pointer;
  padding: 0;
  /* margin-left: auto pins the button to the far right of the .header-inner
     flex row regardless of which other header items are currently visible
     (Sign In, + Add Room, search, bell — any combination). Without auto,
     the hamburger crowds against whatever's to its left. 2026-04-30 fix
     after admin reported it sitting next to the bell on the home page. */
  margin-left: auto;
  flex-shrink: 0;
  transition: background-color 150ms ease, border-color 150ms ease;
}
.hamburger-btn:hover,
.hamburger-btn:focus-visible {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.45);
  outline: none;
}
.hamburger-btn span {
  display: block;
  width: 22px;
  height: 2px;
  background: #fff;
  border-radius: 2px;
  transition: transform 200ms ease, opacity 150ms ease;
}
/* Animate to X when drawer is open */
.hamburger-btn[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.hamburger-btn[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.hamburger-btn[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* ─── Header notification bell + theme-btn family (May 2026 mobile fix) ──
   `.header-theme-btn` was referenced by #user-notif-bell-btn in index.html
   but never defined in styles.css — the bell was rendering as an unstyled
   18px-wide emoji column on every viewport. The class doubles as a generic
   "round white-on-indigo header pill" we can re-use for any future header
   icon button (settings, profile, etc.). 40×40 hit target matches the
   hamburger-btn so the right-edge cluster reads as a single rhythm. */
.header-theme-btn {
  position: relative;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 8px;
  cursor: pointer;
  padding: 0;
  font-size: 1.05rem;
  line-height: 1;
  flex-shrink: 0;
  transition: background-color 150ms ease, border-color 150ms ease, transform 100ms ease;
}
.header-theme-btn:hover,
.header-theme-btn:focus-visible {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.45);
  outline: none;
}
.header-theme-btn:active { transform: scale(0.94); }
/* Mobile: shrink slightly so the bell + invite pill + hamburger row fits
   without crowding the logo. Still well above the 44px iOS hit-target
   minimum because the hamburger is the dominant tap target on mobile. */
@media (max-width: 640px) {
  .header-theme-btn { width: 36px; height: 36px; font-size: 1rem; }
}

/* Backdrop: fades in, closes drawer on click */
.hamburger-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.5);
  z-index: 1400;
  opacity: 0;
  pointer-events: none;
  transition: opacity 200ms ease;
}
.hamburger-backdrop.open {
  opacity: 1;
  pointer-events: auto;
}

/* Drawer: slides in from the right */
.hamburger-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 320px;
  max-width: 86vw;
  background: #ffffff;
  box-shadow: -4px 0 20px rgba(15, 23, 42, 0.18);
  z-index: 1410;
  transform: translateX(100%);
  transition: transform 260ms cubic-bezier(0.4, 0, 0.2, 1);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.hamburger-drawer.open {
  transform: translateX(0);
}

.hamburger-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid #e5e7eb;
  flex-shrink: 0;
}
.hamburger-drawer-title {
  font-size: 1rem;
  font-weight: 700;
  color: #1a202c;
  margin: 0;
  letter-spacing: .01em;
}
.hamburger-drawer-close {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: #6b7280;
  font-size: 1.1rem;
  cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease;
}
.hamburger-drawer-close:hover,
.hamburger-drawer-close:focus-visible {
  background: #f1f5f9;
  color: #1a202c;
  outline: none;
}

.hamburger-drawer-nav {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: .75rem 0 1rem;
}

.hm-section { padding: .5rem 0; }
.hm-section + .hm-section {
  border-top: 1px solid #f1f5f9;
  margin-top: .25rem;
}
.hm-section-label {
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: #94a3b8;
  font-weight: 700;
  padding: .5rem 1.25rem .35rem;
}

.hm-link {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .6rem 1.25rem;
  color: #1a202c;
  font-size: .9rem;
  font-weight: 500;
  text-decoration: none;
  line-height: 1.25;
  transition: background-color 120ms ease, color 120ms ease;
  cursor: pointer;
}
.hm-link:hover,
.hm-link:focus-visible {
  background: #f1f5f9;
  color: #4338ca;
  outline: none;
}
.hm-ico {
  flex-shrink: 0;
  width: 22px;
  text-align: center;
  font-size: 1rem;
  line-height: 1;
}

/* Dim/disable scrolling on the body when drawer is open (applied by app.js) */
body.hm-open { overflow: hidden; }

/* Admin quick-access shortcut — pinned at top of the drawer for admin/mod
   roles. Visually distinct from regular hm-section: indigo-tinted background,
   no top border, prominent role badge on the right. 2026-04-30. */
.hm-section-admin-quick {
  background: linear-gradient(180deg, #eef2ff 0%, #e0e7ff 100%);
  margin: 0 -1.1rem .5rem;
  padding: .6rem 1.1rem;
  border-bottom: 1px solid #c7d2fe;
}
.hm-section-admin-quick + .hm-section { border-top: none; }
.hm-link-admin-quick {
  display: flex !important;
  align-items: center;
  gap: .6rem !important;
  font-weight: 600 !important;
  color: #312e81 !important;
  background: #fff;
  border: 1px solid #c7d2fe;
  border-radius: 8px;
  padding: .6rem .8rem !important;
  text-decoration: none;
  transition: background-color 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.hm-link-admin-quick:hover {
  background: #f5f3ff;
  border-color: #a5b4fc;
  transform: translateY(-1px);
}
.hm-link-admin-quick > span:nth-child(2) {
  flex: 1;
  font-size: .95rem;
}
.hm-quick-badge {
  background: #6366f1;
  color: #fff;
  font-size: .65rem;
  font-weight: 800;
  letter-spacing: .04em;
  padding: .15rem .45rem;
  border-radius: 999px;
  flex-shrink: 0;
}
/* Preview-as role pill row inside the admin-quick section. Lets admin
   preview the site as Mod or User, lets Mod preview as User. The active
   pill is filled indigo; inactive pills are outlined. 2026-04-30. */
.hm-role-toggle-row {
  display: flex;
  align-items: center;
  gap: .35rem;
  margin-top: .55rem;
  flex-wrap: wrap;
}
.hm-role-toggle-label {
  font-size: .72rem;
  color: #4b5563;
  font-weight: 600;
  margin-right: .25rem;
}
.hm-role-pill {
  background: #fff;
  border: 1px solid #c7d2fe;
  color: #4338ca;
  border-radius: 999px;
  padding: .15rem .55rem;
  font-size: .72rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 120ms ease, color 120ms ease;
}
.hm-role-pill:hover:not(.active):not(:disabled) { background: #eef2ff; }
.hm-role-pill.active {
  background: #6366f1;
  border-color: #6366f1;
  color: #fff;
}
.hm-role-pill:disabled { cursor: not-allowed; }
/* Sticky preview banner — visible whenever ds_preview_role !== null.
   Sits below the header so the admin can always see + exit the preview. */
.preview-banner {
  position: sticky;
  top: 0;
  z-index: 90;
  background: #fef3c7;
  color: #92400e;
  border-bottom: 1px solid #fcd34d;
  padding: .35rem .75rem;
  font-size: .82rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .65rem;
}
.preview-banner button {
  background: #fff;
  border: 1px solid #f59e0b;
  color: #92400e;
  border-radius: 6px;
  padding: .15rem .55rem;
  font-size: .76rem;
  font-weight: 600;
  cursor: pointer;
}

@media (max-width: 480px) {
  .hamburger-drawer { width: 300px; }
  .hm-link { font-size: .95rem; padding: .7rem 1.1rem; }
}

/* ── Home-page "Latest from the blog" strip ────────────────────── */
.home-blog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1rem;
}
.home-blog-card {
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 1rem 1.1rem;
  text-decoration: none;
  color: inherit;
  transition: box-shadow .15s ease, border-color .15s ease, transform .15s ease;
  min-height: 140px;
}
.home-blog-card:hover,
.home-blog-card:focus-visible {
  border-color: #6366f1;
  box-shadow: 0 2px 8px rgba(99, 102, 241, 0.12);
  transform: translateY(-1px);
  outline: none;
}
.home-blog-card-title {
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.3;
  color: #1f2937;
  margin: 0 0 .4rem 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.home-blog-card-excerpt {
  font-size: .85rem;
  line-height: 1.45;
  color: #6b7280;
  margin: 0 0 .6rem 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  flex: 1;
}
.home-blog-card-meta {
  font-size: .75rem;
  color: #6b7280;
  display: flex;
  gap: .5rem;
  align-items: center;
  flex-wrap: wrap;
  margin-top: auto;
}
.home-blog-card-tag {
  background: #eef2ff;
  color: #4338ca;
  padding: .1rem .5rem;
  border-radius: 999px;
  font-size: .7rem;
  font-weight: 600;
}

/* ── Housing process narrative (per-college) ────────────────────── */
.housing-process-section {
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: .75rem;
  padding: 1.25rem;
  margin: 1.25rem 0;
}
.housing-process-section .section-title {
  color: #78350f;
  margin: 0 0 .75rem 0;
  font-size: 1.05rem;
  display: flex;
  align-items: center;
  gap: .5rem;
}
.housing-process-body {
  color: #78350f;
  font-size: .92rem;
  line-height: 1.55;
}
.housing-process-body p { margin: 0 0 .65rem 0; }
.housing-process-body p:last-child { margin-bottom: 0; }
.housing-process-body ul,
.housing-process-body ol {
  margin: .35rem 0 .65rem 1.25rem;
  padding-left: .5rem;
}
.housing-process-body li { margin-bottom: .25rem; }
/* Source + as-of footer (May 2026) — lives at the bottom-right of the
   housing-process panel so readers can verify provenance + admins can
   spot stale entries. Both spans auto-hide when their data is missing. */
.housing-process-meta {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 1rem;
  margin-top: 1rem;
  padding-top: .65rem;
  border-top: 1px dashed rgba(146, 64, 14, .25);
  font-size: .78rem;
  color: #92400e;
  font-style: italic;
}
.housing-process-meta a { color: #b45309; text-decoration: underline; }
.housing-process-meta a:hover { color: #78350f; }
@media (max-width: 560px) {
  .housing-process-meta { flex-direction: column; gap: .25rem; align-items: flex-start; }
}
.housing-process-body a {
  color: #b45309;
  text-decoration: underline;
  font-weight: 600;
}
.housing-process-body a:hover { color: #78350f; }
.housing-process-body strong { color: #451a03; }

/* ── Official housing links (per-college) ───────────────────────── */
.official-links-section {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: .75rem;
  padding: 1.25rem;
  margin: 1.25rem 0;
  box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
/* Dining + eateries panel — same white-card treatment as official housing
   links so the section doesn't get scrolled past as bare-heading text
   (Joshua flag, May 2026). Slightly larger min-margin since the section
   often sits between Description and Residence Halls and benefits from
   a visual breathing room beat. */
.college-dining-card {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: .75rem;
  padding: 1.25rem;
  margin: 1.5rem 0;
  box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
.college-dining-card details > summary { outline: none; }

/* ─── Collapsible envelope affordance (May 2026) ────────────────────────────
 * User feedback 2026-05-08: "On all the sections that have the envelope
 * function is there any way to make it more obvious that it can be closed
 * or opened? People could not know."
 *
 * The Brief drawer already had a custom rotating chevron (.brief-details-
 * summary). The dining-halls + common-spaces + alumni envelopes were
 * relying on the native browser triangle — which is small, varies by
 * browser, and reads as decoration. This block applies a consistent
 * chevron + hover treatment to every <details> tagged with .envelope OR
 * matching one of the existing public envelope class hooks.
 *
 * Pattern: hide native marker, render a 1rem chevron on the right of the
 * summary that rotates 90° between closed (▶ pointing right) and open
 * (▼ pointing down). Hover lights up the row with a faint indigo tint
 * + cursor:pointer so the row reads as a button. */
details.envelope > summary,
.college-dining-details > summary,
details.cs-type-group > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
  position: relative;
  padding-right: 2.25rem;       /* room for the chevron */
  border-radius: var(--md3-shape-sm, 8px);
  transition: background-color 150ms ease;
}
details.envelope > summary::-webkit-details-marker,
.college-dining-details > summary::-webkit-details-marker,
details.cs-type-group > summary::-webkit-details-marker {
  display: none;     /* Safari sees this; Chrome uses list-style:none above */
}
details.envelope > summary::after,
.college-dining-details > summary::after,
details.cs-type-group > summary::after {
  content: '▼';
  position: absolute;
  right: .65rem;
  top: 50%;
  transform: translateY(-50%) rotate(0deg);
  transition: transform 200ms ease;
  color: var(--md3-on-surface-variant, #6b7280);
  font-size: .9rem;
  pointer-events: none;          /* don't block summary clicks */
  font-weight: 600;
}
/* When NOT open, rotate the chevron to point right (▶). Default state in
 * the rule above is the open state. Using :not([open]) on the parent so
 * each variant resolves cleanly without per-class duplication. */
details:not([open]).envelope > summary::after,
details:not([open]).college-dining-details > summary::after,
details:not([open]).cs-type-group > summary::after {
  transform: translateY(-50%) rotate(-90deg);
}
details.envelope > summary:hover,
.college-dining-details > summary:hover,
details.cs-type-group > summary:hover {
  background-color: rgba(99, 102, 241, .07);  /* faint indigo tint */
}
details.envelope > summary:focus-visible,
.college-dining-details > summary:focus-visible,
details.cs-type-group > summary:focus-visible {
  outline: 2px solid var(--md3-primary, #6366f1);
  outline-offset: 2px;
}
/* Caller can opt out of the chevron when their summary already has a
 * custom one (e.g. .brief-details-summary). Just don't add the .envelope
 * class. */
.college-dining-card h2 { font-size: 1.05rem; color: #111827; }

/* ── 🦣 School-spirit welcome strip ────────────────────────────────────
   Thin amber bar that fires once per browser session for signed-in users
   we can identify by school. The whole element is sticky-top-pinned via
   position:sticky so it doesn't take vertical space when collapsed but
   stays in view as the user starts scrolling. Auto-dismisses after 8s
   (toggled by JS removing .school-spirit-welcome-visible). */
.school-spirit-welcome {
  position: sticky;
  top: 0;
  z-index: 950; /* below the top header (1000) so it doesn't cover nav */
  background: linear-gradient(90deg, #fde68a 0%, #fcd34d 50%, #fde68a 100%);
  color: #78350f;
  border-bottom: 1px solid #fbbf24;
  font-weight: 600;
  font-size: .87rem;
  text-align: center;
  animation: schoolSpiritSlideIn .35s ease-out;
  box-shadow: 0 1px 3px rgba(0,0,0,.06);
}
.school-spirit-welcome-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  padding: .55rem .85rem;
  max-width: 1200px;
  margin: 0 auto;
  position: relative;
}
.school-spirit-welcome-icon { font-size: 1.15rem; }
.school-spirit-welcome-text { line-height: 1.3; }
.school-spirit-welcome-text strong { font-weight: 800; }
.school-spirit-welcome-text .chant-text {
  margin-left: .35rem;
  font-style: italic;
  color: #92400e;
}
.school-spirit-welcome-close {
  position: absolute;
  right: .65rem;
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: 0;
  color: #78350f;
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  padding: .15rem .35rem;
  border-radius: .25rem;
  line-height: 1;
}
.school-spirit-welcome-close:hover { background: rgba(146, 64, 14, .12); }
@keyframes schoolSpiritSlideIn {
  from { transform: translateY(-100%); opacity: 0; }
  to   { transform: translateY(0);     opacity: 1; }
}
/* On narrow screens, drop the close button to avoid wrap */
@media (max-width: 480px) {
  .school-spirit-welcome-text { font-size: .82rem; }
  .school-spirit-welcome-text .chant-text { display: none; }
}

/* Header invite pill (May 2026) — hover state pop */
.header-invite-pill {
  background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
  border: 0;
  color: #fff;
  cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease, filter .15s ease;
  box-shadow: 0 2px 6px rgba(99, 102, 241, .35);
}
.header-invite-pill:hover { filter: brightness(1.05); transform: translateY(-1px); box-shadow: 0 4px 10px rgba(99, 102, 241, .45); }
.header-invite-pill:active { transform: translateY(0); }
@media (max-width: 480px) {
  .header-invite-pill > span:nth-child(2) { display:none; }   /* hide "Invite" label */
  .header-invite-pill .header-invite-pill-pts { display:none; } /* hide "+10pt" badge */
  .header-invite-pill { padding: .4rem .55rem; }
}

/* Roommate Post button disabled state (Bug E QA round 2 fix, May 2026) */
#rm-form-submit.rm-submit-disabled,
#rm-form-submit:disabled {
  background: #cbd5e1;
  color: #475569;
  cursor: not-allowed;
  opacity: 0.85;
}
.official-links-section .section-title {
  margin: 0 0 .85rem 0;
  font-size: 1.05rem;
  color: #111827;
  display: flex;
  align-items: center;
  gap: .5rem;
}
.official-links-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: .65rem;
}
.official-link-card {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .7rem .9rem;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: .55rem;
  text-decoration: none;
  color: #1f2937;
  font-size: .88rem;
  font-weight: 500;
  transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease, background .12s ease;
}
.official-link-card:hover {
  background: #eef2ff;
  border-color: #a5b4fc;
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(79, 70, 229, 0.12);
  color: #3730a3;
}
.official-link-icon {
  font-size: 1.05rem;
  flex-shrink: 0;
}
.official-link-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.official-link-arrow {
  color: #9ca3af;
  font-size: .9rem;
  flex-shrink: 0;
}
.official-link-card:hover .official-link-arrow { color: #6366f1; }

/* ---- A1: Sticky back-to-parent pill (dorm → college, room → dorm) ---- */
.back-to-college-pill {
  position: sticky;
  top: 58px;
  z-index: 90;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  margin: .5rem 1.25rem;
  padding: .4rem .9rem;
  background: #e8edf8;
  color: #3b5bdb;
  border: 1.5px solid #c7d2f0;
  border-radius: 999px;
  font-size: .88rem;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0,0,0,.08);
  transition: background .15s ease, border-color .15s ease, transform .15s ease;
  max-width: calc(100% - 2.5rem);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.back-to-college-pill:hover {
  background: #d5dff5;
  border-color: #a8b9e8;
}
.back-to-college-pill:active {
  transform: translateY(1px);
}
@media (max-width: 640px) {
  .back-to-college-pill {
    margin: .5rem .75rem;
    font-size: .82rem;
    padding: .35rem .75rem;
  }
}

/* ---- A2: Keyboard shortcuts cheatsheet modal ---- */
.cheatsheet-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: .5rem;
  margin: 1rem 0;
}
.cheatsheet-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: .5rem .75rem;
  background: #f8fafc;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  gap: 1rem;
}
.cheatsheet-desc {
  font-size: .9rem;
  color: #1f2937;
}
.cheatsheet-keys {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  flex-shrink: 0;
}
.cheatsheet-keys kbd {
  display: inline-block;
  padding: .15rem .5rem;
  background: #fff;
  border: 1px solid #cbd5e1;
  border-bottom-width: 2px;
  border-radius: 4px;
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: .78rem;
  font-weight: 600;
  color: #334155;
  box-shadow: 0 1px 0 rgba(0,0,0,.04);
  min-width: 1.25rem;
  text-align: center;
}
.cheatsheet-section-title {
  font-size: .75rem;
  font-weight: 700;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: .05em;
  margin: 1rem 0 .5rem;
}
.cheatsheet-section-title:first-child { margin-top: 0; }

/* ---- A3: Header user chip with avatar initials ---- */
.header-user-chip {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: .25rem .75rem .25rem .25rem;
  background: rgba(255,255,255,.12);
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 999px;
  color: #fff;
  font-size: .88rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease;
  text-decoration: none;
}
.header-user-chip:hover {
  background: rgba(255,255,255,.2);
  border-color: rgba(255,255,255,.3);
}
.header-user-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: linear-gradient(135deg, #6366f1, #8b5cf6);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .02em;
  flex-shrink: 0;
  text-transform: uppercase;
}
.header-user-name {
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (max-width: 640px) {
  .header-user-name { display: none; }
  .header-user-chip { padding: .15rem; border-radius: 50%; }
}

/* ---- B5: Wizard dot clickable-when-done ---- */
.wizard-dot.done {
  cursor: pointer;
}
.wizard-dot.done:hover {
  background: #16a34a;
  border-color: #16a34a;
}

/* ---- B6: Upload progress bar ---- */
.upload-progress-wrap {
  margin: .5rem 0;
  display: flex;
  align-items: center;
  gap: .5rem;
}
.upload-progress-bar {
  flex: 1;
  height: 6px;
  background: #e5e7eb;
  border-radius: 999px;
  overflow: hidden;
  position: relative;
}
.upload-progress-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, #6366f1, #8b5cf6);
  border-radius: 999px;
  transition: width .2s ease;
  width: 0%;
}
.upload-progress-pct {
  font-size: .75rem;
  font-weight: 600;
  color: #6366f1;
  min-width: 2.5rem;
  text-align: right;
}
.upload-progress-label {
  font-size: .8rem;
  color: #6b7280;
  margin-bottom: .25rem;
}
.wizard-photo-progress-row {
  padding: .5rem .75rem;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  margin-bottom: .5rem;
}

/* ─── Wizard per-photo cards ─────────────────────────────────────── */
.wizard-photo-card {
  display: grid;
  grid-template-columns: 80px 1fr auto;
  gap: .6rem;
  align-items: center;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  padding: .5rem .6rem;
}
.wizard-photo-thumb {
  width: 80px;
  height: 60px;
  object-fit: cover;
  border-radius: 5px;
  flex-shrink: 0;
}
.wizard-photo-meta {
  display: flex;
  flex-direction: column;
  gap: .35rem;
  min-width: 0;
}
.wizard-photo-meta .form-input {
  width: 100%;
  box-sizing: border-box;
}
.wizard-photo-remove {
  background: none;
  border: none;
  cursor: pointer;
  color: #6b7280;
  font-size: 1rem;
  padding: .25rem;
  border-radius: 4px;
  flex-shrink: 0;
  transition: color .15s;
}
.wizard-photo-remove:hover { color: #dc2626; }
.wizard-photo-pdf-thumb {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .2rem;
  width: 80px;
  height: 60px;
  border-radius: 5px;
  background: #fef2f2;
  border: 1px solid #fca5a5;
  font-size: 1.4rem;
  flex-shrink: 0;
  overflow: hidden;
}
.wizard-photo-pdf-thumb span {
  font-size: .58rem;
  color: #991b1b;
  line-height: 1.1;
  text-align: center;
  word-break: break-all;
  padding: 0 .2rem;
  max-width: 100%;
}
@media (max-width: 480px) {
  .wizard-photo-card {
    grid-template-columns: 64px 1fr auto;
  }
  .wizard-photo-thumb {
    width: 64px;
    height: 48px;
  }
}

/* ─── Desktop photo upload affordances ───────────────────────────── */
/* On non-touch devices: hide the camera button (useless on Mac/Windows),
   show the drag-and-drop zone instead */
@media (hover: hover) and (pointer: fine) {
  .camera-btn { display: none !important; }
  .wizard-photo-dropzone { display: flex !important; }
}

/* ─── HEIC preview placeholder (May 2026 mobile/PWA pass) ────────────
 * Chrome/Firefox/Edge can't render HEIC/HEIF in <img>. We swap them for
 * this labeled placeholder before upload (the server-side normalizer
 * converts to JPEG, so the post-upload thumbnail is real).
 *
 * Sizing rules: a host class style="width:Npx;height:Npx" wins (callers
 * pass the same dimensions they use for the <img> they replace, so the
 * placeholder occupies the same slot). Without an inline size override
 * it falls back to the .wizard-photo-thumb / general thumbnail look. */
.file-preview-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .15rem;
  background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);
  border: 1px dashed #a5b4fc;
  color: #4338ca;
  font-size: .65rem;
  font-weight: 600;
  text-align: center;
  padding: .25rem;
  overflow: hidden;
  box-sizing: border-box;
}
.file-preview-placeholder .fpp-icon {
  font-size: 1.1rem;
  line-height: 1;
}
/* Converting state (May 2026 — UX_TODO #62 / heic2any) — spin the ↻
 * icon while heic2any chews on the HEIC bytes in the background. The
 * placeholder swaps to a real <img> when conversion settles. */
.file-preview-placeholder.fpp-converting {
  background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
  border-color: #fbbf24;
  color: #78350f;
}
.file-preview-placeholder.fpp-converting .fpp-icon {
  animation: fppConvertSpin 1.1s linear infinite;
  display: inline-block;
}
@keyframes fppConvertSpin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
.file-preview-placeholder .fpp-name {
  font-size: .58rem;
  font-weight: 500;
  color: #6366f1;
  word-break: break-all;
  line-height: 1.1;
  max-width: 100%;
  /* clamp to 2 lines so a long file name doesn't blow out the tile */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.file-preview-placeholder .fpp-note {
  font-size: .55rem;
  font-weight: 400;
  color: #818cf8;
  font-style: italic;
}
/* Inline-injected variant (used when JS auto-creates a placeholder next
 * to an <img>) — defaults to a horizontal pill so it doesn't blow up
 * surrounding layout. */
.file-preview-placeholder-inline {
  display: inline-flex;
  flex-direction: row;
  gap: .35rem;
  padding: .25rem .5rem;
  border-radius: .35rem;
}

.wizard-photo-dropzone {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .3rem;
  border: 2px dashed #c7d2fe;
  border-radius: 10px;
  background: #eef2ff;
  padding: 1.25rem 1rem;
  text-align: center;
  cursor: pointer;
  transition: background .15s, border-color .15s;
  margin-bottom: .5rem;
}
.wizard-photo-dropzone:hover,
.wizard-photo-dropzone.drag-over {
  background: #e0e7ff;
  border-color: #6366f1;
}
.wizard-dropzone-icon { font-size: 1.8rem; }
.wizard-dropzone-text {
  font-weight: 600;
  color: #4338ca;
  font-size: .95rem;
}
.wizard-dropzone-sub {
  font-size: .78rem;
  color: #6b7280;
}

/* ─── Public mobile pass (April 2026) ──────────────────────────────────
   Site-wide responsive cleanup focused on the highest-traffic public
   surfaces. Goals: thumb-friendly tap targets, no iOS auto-zoom on form
   focus, modals that don't get pushed off-screen by the keyboard, and
   wide tables that gracefully horizontal-scroll inside their wrap. */
@media (max-width: 640px) {
  /* iOS auto-zoom prevention — input font-size must be >=16px or Safari
     zooms the page on focus. We can't blanket-set 16px because some UI
     uses tiny text intentionally; scope to form inputs only. */
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="number"],
  input[type="search"],
  input[type="tel"],
  input[type="url"],
  input[type="date"],
  input[type="datetime-local"],
  select,
  textarea {
    font-size: 16px;
  }

  /* Modal sizing — most modals declare max-width:520px or similar.
     On a 360px phone that overflows the viewport. Force full-width
     with a small gutter and a max-height that respects the keyboard. */
  .modal-overlay .modal,
  .modal {
    width: 100%;
    max-width: 100%;
    margin: 0 .5rem;
    max-height: 75vh;
    max-height: 75dvh; /* mobile-keyboard-safe */
    border-radius: .55rem;
  }
  .modal-overlay { padding: .5rem; align-items: flex-start; }

  /* Tap targets — every primary action should be >=44px tall on
     touch surfaces (Apple HIG / WCAG 2.5.5). Bump button + chip
     min-heights without forcing all buttons to be huge. */
  .btn,
  .btn-primary,
  .btn-secondary,
  .btn-ghost,
  button[type="submit"],
  button[type="button"]:not(.btn-icon-only):not(.modal-close-btn):not(.tab-btn) {
    min-height: 44px;
  }
  /* Modal close X stays compact but still tappable */
  .modal-close-btn { min-width: 44px; min-height: 44px; }
  /* Chips (compare, filters, etc.) also need a tap-friendly minimum */
  .qf-chip,
  .filter-chip,
  .reviewer-context-tag {
    min-height: 36px;
  }

  /* Hero photo aspect-ratio — the dorm/college hero photos can be huge
     PNGs. Cap at 220px so they don't dominate above-the-fold on narrow
     screens; let the rest of the hero (name, brief, actions) breathe. */
  .college-hero-photo,
  .dorm-hero-photo {
    max-height: 220px;
    object-fit: cover;
  }

  /* Wide tables (room compare, leaderboard, dorm compare) — wrap them
     in horizontal scroll inside their existing parent. */
  .table-wrap,
  .room-compare-grid,
  .dorm-compare-grid {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Bottom nav already exists from the earlier major UI update — but
     ensure the body has enough padding-bottom that fixed bottom nav
     doesn't cover content. */
  body { padding-bottom: 4.5rem; }

  /* Brief tile grid — the 17-tile strip can get cramped at 360px wide.
     Force 4 columns instead of auto-fit so each tile stays >= 44px. */
  .brief-strip .brief-icon-row,
  .brief-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  /* The Brief bottom-sheet — full-bleed on mobile so the close button
     is reachable with a thumb. */
  .brief-sheet-backdrop .brief-sheet,
  .bottom-sheet {
    width: 100%;
    max-width: 100%;
    border-radius: .85rem .85rem 0 0;
  }
}

/* ─── Dorm identity strip (Greek chapter dual-identity, Phase 5b) ───────── */
#dorm-identity-strip {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  padding: 1.25rem;
  background: white;
  border-radius: .75rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  margin-bottom: 1.25rem;
}

.dorm-identity-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: .6rem;
}

.dorm-identity-logo {
  width: 80px;
  height: 80px;
  object-fit: contain;
  flex-shrink: 0;
}

.dorm-identity-name {
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.25;
  color: #1f2937;
  word-break: break-word;
}

.dorm-identity-caption {
  font-size: .82rem;
  color: #6b7280;
  line-height: 1.4;
}

.dorm-identity-detail {
  font-size: .75rem;
  color: #6b7280;
  margin-top: .15rem;
}

@media (max-width: 640px) {
  #dorm-identity-strip {
    grid-template-columns: 1fr;
    gap: 1rem;
    padding: 1rem;
  }
}

/* ─── Members-only warning banner (Phase 5b) ──────────────────────────────── */
#members-only-banner {
  display: none;
  background: #fef3c7;
  border-left: 4px solid #fbbf24;
  padding: 1rem 1.25rem;
  margin-bottom: 1.25rem;
  border-radius: .5rem;
  font-size: .95rem;
  line-height: 1.5;
  color: #92400e;
  gap: 1rem;
  position: relative;
}

#members-only-banner.active {
  display: flex;
  align-items: flex-start;
}

.members-only-icon {
  font-size: 1.5rem;
  flex-shrink: 0;
  line-height: 1;
}

.members-only-body {
  flex: 1;
  min-width: 0;
}

.members-only-body strong {
  font-weight: 700;
  display: block;
  margin-bottom: .3rem;
}

.members-only-cta {
  color: #b45309;
  text-decoration: underline;
  cursor: pointer;
  font-weight: 500;
  display: inline-block;
  margin-top: .5rem;
}

.members-only-cta:hover {
  color: #92400e;
}

.members-only-dismiss {
  flex-shrink: 0;
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
  color: #92400e;
  padding: 0;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

.members-only-dismiss:hover {
  opacity: 0.7;
}

@media (max-width: 640px) {
  #members-only-banner {
    flex-direction: column;
    align-items: flex-start;
    padding: .85rem 1rem;
  }

  .members-only-dismiss {
    position: absolute;
    top: .5rem;
    right: .5rem;
  }

  .members-only-body {
    padding-right: 2rem;
  }
}

/* ─── Most-searched colleges home strip ───────────────────────────────────── */
.most-searched-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}

@media (max-width: 768px) {
  #most-searched-grid {
    grid-template-columns: repeat(3, 1fr) !important;
  }
}

@media (max-width: 480px) {
  #most-searched-grid {
    grid-template-columns: repeat(2, 1fr) !important;
  }
  #most-searched-grid img {
    height: 60px !important;
  }
}

/* ─── Website suggestion attachment previews ──────────────────────────────── */
#ws-file-previews {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 0.5rem;
  padding: 0;
}

.ws-file-preview {
  position: relative;
  width: 80px;
  height: 80px;
  border-radius: 6px;
  overflow: hidden;
  background: #f3f4f6;
  border: 1px solid #e5e7eb;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  font-size: 0.75rem;
  color: #6b7280;
}

.ws-file-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ws-file-icon {
  font-size: 1.75rem;
}

.ws-file-name {
  width: 100%;
  padding: 0 0.25rem;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 0.25rem;
}

.ws-file-remove {
  position: absolute;
  top: -4px;
  right: -4px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #dc2626;
  color: white;
  border: none;
  cursor: pointer;
  font-size: 0.875rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  line-height: 1;
  opacity: 0;
  transition: opacity 120ms ease-out;
}

.ws-file-preview:hover .ws-file-remove {
  opacity: 1;
}

/* ─── Wizard multi-comment UI ──────────────────────────────────────────────── */
.wizard-comment-row {
  padding: 0.75rem;
  background: #f9fafb;
  border-radius: 6px;
  border: 1px solid #e5e7eb;
}

.wizard-comment-row textarea {
  font-family: inherit;
  font-size: 0.875rem;
}

.wizard-comment-row select {
  font-size: 0.875rem;
}

/* ── Campus Eateries (cafes, grab-n-go, etc.) — added 2026-04-27 ─────────── */
.eatery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: 0.85rem;
}
.eatery-card {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  background: var(--ds-bg-elevated, #fff);
  border: 1px solid var(--ds-border, #e5e7eb);
  border-radius: 10px;
  padding: 0.85rem 1rem;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.eatery-card:hover {
  border-color: #6366f1;
  box-shadow: 0 2px 8px rgba(99, 102, 241, 0.10);
}
.eatery-name {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--ds-text, #1f2937);
}
.eatery-building {
  font-size: 0.78rem;
  color: var(--ds-text-muted, #6b7280);
}
.eatery-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.25rem;
}
.eatery-type-badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 600;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.eatery-type-cafe         { background: #f3e8ff; color: #6b21a8; }
.eatery-type-grab_and_go  { background: #fef3c7; color: #92400e; }
.eatery-type-convenience  { background: #dbeafe; color: #1e40af; }
.eatery-type-food_truck   { background: #fee2e2; color: #991b1b; }
.eatery-type-food_court   { background: #ffedd5; color: #9a3412; }
.eatery-type-restaurant   { background: #dcfce7; color: #166534; }
.eatery-type-market       { background: #e0e7ff; color: #3730a3; }
.eatery-type-dining_hall  { background: #fef9c3; color: #854d0e; }
.eatery-type-other        { background: #f3f4f6; color: #4b5563; }
.eatery-distance {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 500;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: #ecfdf5;
  color: #065f46;
}
.eatery-hours {
  font-size: 0.78rem;
  color: var(--ds-text-muted, #6b7280);
  margin-top: 0.2rem;
}
.eatery-payments {
  font-size: 0.7rem;
  color: var(--ds-text-muted, #6b7280);
  margin-top: 0.15rem;
}
.eatery-link {
  font-size: 0.78rem;
  color: #6366f1;
  text-decoration: none;
  margin-top: 0.25rem;
}
.eatery-link:hover {
  text-decoration: underline;
}

/* ═════════════════════════════════════════════════════════════════════════
 * MD3 — promoted to default 2026-04-30 (was previously the styles-md3.css
 * preview layer, gated behind [data-md3="1"]). All selectors had that
 * prefix stripped; the toggle button + URL param + localStorage flag +
 * preview banner + body padding offset were all removed at the same time.
 * Identity preserved: 8-12px corner radius (NOT MD3's full pill), indigo+
 * amber palette, Inter font, emoji headers, Lucide outline icons.
 * ═════════════════════════════════════════════════════════════════════════ */

/* ─── MD3 design tokens (root scope) ────────────────────────────────────── */
:root {
  /* Color roles (mapped from existing DormScouter palette) */
  --md-sys-color-primary:           #6366f1;
  --md-sys-color-on-primary:        #ffffff;
  --md-sys-color-primary-container: #eef2ff;
  --md-sys-color-on-primary-container: #312e81;
  --md-sys-color-secondary:         #f59e0b;
  --md-sys-color-on-secondary:      #ffffff;
  --md-sys-color-secondary-container: #fef3c7;
  --md-sys-color-on-secondary-container: #78350f;
  --md-sys-color-tertiary:          #10b981;
  --md-sys-color-on-tertiary:       #ffffff;
  --md-sys-color-tertiary-container: #d1fae5;
  --md-sys-color-on-tertiary-container: #065f46;
  --md-sys-color-error:             #dc2626;
  --md-sys-color-on-error:          #ffffff;
  --md-sys-color-error-container:   #fee2e2;
  --md-sys-color-on-error-container: #7f1d1d;
  --md-sys-color-surface:           #ffffff;
  --md-sys-color-on-surface:        #111827;
  --md-sys-color-surface-variant:   #f3f4f6;
  --md-sys-color-on-surface-variant: #6b7280;
  --md-sys-color-outline:           #d1d5db;
  --md-sys-color-outline-variant:   #e5e7eb;
  --md-sys-color-surface-container-lowest:  #ffffff;
  --md-sys-color-surface-container-low:     #fafafa;
  --md-sys-color-surface-container:         #f9fafb;
  --md-sys-color-surface-container-high:    #f3f4f6;
  --md-sys-color-surface-container-highest: #e5e7eb;

  /* Shape scale (corner radius) */
  --md-sys-shape-corner-none:        0;
  --md-sys-shape-corner-extra-small: 4px;
  --md-sys-shape-corner-small:       8px;
  --md-sys-shape-corner-medium:      12px;
  --md-sys-shape-corner-large:       16px;
  --md-sys-shape-corner-extra-large: 28px;
  --md-sys-shape-corner-full:        9999px;

  /* Elevation */
  --md-sys-elevation-0: none;
  --md-sys-elevation-1: 0 1px 2px rgba(0,0,0,0.06), 0 1px 3px rgba(0,0,0,0.10);
  --md-sys-elevation-2: 0 1px 3px rgba(0,0,0,0.08), 0 2px 6px rgba(0,0,0,0.10);
  --md-sys-elevation-3: 0 4px 8px rgba(0,0,0,0.10), 0 1px 3px rgba(0,0,0,0.08);
  --md-sys-elevation-4: 0 6px 12px rgba(0,0,0,0.12), 0 2px 4px rgba(0,0,0,0.10);
  --md-sys-elevation-5: 0 12px 24px rgba(0,0,0,0.14), 0 4px 8px rgba(0,0,0,0.12);

  /* Motion: emphasized easing curves */
  --md-sys-motion-easing-standard:    cubic-bezier(0.2, 0.0, 0.0, 1.0);
  --md-sys-motion-easing-emphasized:  cubic-bezier(0.2, 0.0, 0.0, 1.0);
  --md-sys-motion-easing-emphasized-decelerate: cubic-bezier(0.05, 0.7, 0.1, 1.0);
  --md-sys-motion-easing-emphasized-accelerate: cubic-bezier(0.3, 0.0, 0.8, 0.15);
  --md-sys-motion-duration-short1:  50ms;
  --md-sys-motion-duration-short2: 100ms;
  --md-sys-motion-duration-short3: 150ms;
  --md-sys-motion-duration-short4: 200ms;
  --md-sys-motion-duration-medium1: 250ms;
  --md-sys-motion-duration-medium2: 300ms;
  --md-sys-motion-duration-medium3: 350ms;
  --md-sys-motion-duration-medium4: 400ms;
  --md-sys-motion-duration-long1:   450ms;
  --md-sys-motion-duration-long2:   500ms;

  /* State layer opacities */
  --md-sys-state-hover-opacity:    0.08;
  --md-sys-state-focus-opacity:    0.12;
  --md-sys-state-pressed-opacity:  0.12;
  --md-sys-state-dragged-opacity:  0.16;
}

/* ─── Emphasized motion baseline on common interactive elements ────────── */
.btn,
.qf-chip,
.dorm-card,
.college-card,
.home-blog-card,
.freshness-chip,
.alumni-card-compact,
.eatery-card,
.brief-icon,
.oauth-btn {
  transition-timing-function: var(--md-sys-motion-easing-emphasized) !important;
  transition-duration: var(--md-sys-motion-duration-short3) !important;
}
.btn:active,
.qf-chip:active,
.oauth-btn:active {
  transform: scale(0.97);
  transition-duration: var(--md-sys-motion-duration-short2) !important;
}

/* MD3 focus ring — 3px outline at 80% primary opacity */
:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--md-sys-color-primary) 80%, transparent) !important;
  outline-offset: 2px;
  border-radius: var(--md-sys-shape-corner-extra-small);
}

/* ─── Buttons (MD3 anatomy applied to existing .btn-* classes) ────────── */
.btn.btn-primary {
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
  border: none;
  border-radius: var(--md-sys-shape-corner-small);
  padding: .55rem 1.4rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  box-shadow: var(--md-sys-elevation-0);
  position: relative;
  overflow: hidden;
}
.btn.btn-primary:hover {
  box-shadow: var(--md-sys-elevation-2);
  background: color-mix(in srgb, var(--md-sys-color-primary) 92%, var(--md-sys-color-on-primary));
}
.btn.btn-primary:active { box-shadow: var(--md-sys-elevation-1); }

.btn.btn-secondary {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  border: none;
  border-radius: var(--md-sys-shape-corner-small);
  padding: .55rem 1.4rem;
  font-weight: 600;
  box-shadow: var(--md-sys-elevation-0);
}
.btn.btn-secondary:hover {
  box-shadow: var(--md-sys-elevation-1);
  background: color-mix(in srgb, var(--md-sys-color-secondary-container) 88%, var(--md-sys-color-on-secondary-container));
}

.btn.btn-outline {
  background: transparent;
  color: var(--md-sys-color-primary);
  border: 1px solid var(--md-sys-color-outline);
  border-radius: var(--md-sys-shape-corner-small);
  padding: .55rem 1.4rem;
  font-weight: 600;
}
.btn.btn-outline:hover {
  background: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent);
  border-color: var(--md-sys-color-primary);
}
.btn.btn-outline:active {
  background: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent);
}

.btn.btn-ghost,
.btn.btn-text {
  background: transparent;
  color: var(--md-sys-color-primary);
  border: none;
  border-radius: var(--md-sys-shape-corner-small);
  padding: .55rem 1rem;
  font-weight: 600;
}
.btn.btn-ghost:hover,
.btn.btn-text:hover {
  background: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent);
}

.btn.btn-danger {
  background: var(--md-sys-color-error-container);
  color: var(--md-sys-color-on-error-container);
  border: none;
  border-radius: var(--md-sys-shape-corner-small);
  padding: .55rem 1.4rem;
  font-weight: 600;
}
.btn.btn-danger:hover {
  background: var(--md-sys-color-error);
  color: var(--md-sys-color-on-error);
  box-shadow: var(--md-sys-elevation-2);
}

/* Header buttons (white-on-dark) */
.btn.btn-outline-white {
  background: transparent;
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: var(--md-sys-shape-corner-small);
}
.btn.btn-outline-white:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.5);
}
.btn.btn-ghost-white {
  background: transparent;
  color: #ffffff;
  border: none;
  border-radius: var(--md-sys-shape-corner-small);
}
.btn.btn-ghost-white:hover { background: rgba(255, 255, 255, 0.08); }

/* ─── Cards (Outlined variant by default; elevate on hover) ───────────── */
.dorm-card,
.college-card,
.home-blog-card,
.alumni-card-compact,
.eatery-card,
.shortlist-card,
.profile-review-card,
.themed-card {
  border-radius: var(--md-sys-shape-corner-medium);
  border: 1px solid var(--md-sys-color-outline-variant);
  box-shadow: var(--md-sys-elevation-1);
}
.dorm-card:hover,
.college-card:hover,
.home-blog-card:hover,
.alumni-card-compact:hover,
.eatery-card:hover,
.shortlist-card:hover,
.profile-review-card:hover {
  box-shadow: var(--md-sys-elevation-3);
  transform: translateY(-2px);
}

/* ─── Quick-filter chips ──────────────────────────────────────────────── */
.qf-chip {
  border-radius: var(--md-sys-shape-corner-small);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface);
  color: var(--md-sys-color-on-surface);
  padding: .35rem .85rem;
  font-weight: 500;
}
.qf-chip:hover {
  background: color-mix(in srgb, var(--md-sys-color-primary) 8%, var(--md-sys-color-surface));
  border-color: var(--md-sys-color-primary);
}
.qf-chip.active,
.qf-chip[aria-pressed="true"] {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  border-color: var(--md-sys-color-secondary);
  font-weight: 600;
}

/* ─── Modals — extra-large corner radius + elevation 3 ────────────────── */
.modal-overlay {
  background: rgba(15, 23, 42, 0.45);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.modal {
  border-radius: var(--md-sys-shape-corner-extra-large) !important;
  box-shadow: var(--md-sys-elevation-3) !important;
  border: 1px solid var(--md-sys-color-outline-variant);
  /* Modal scrolling: max-height set to 85vh to allow most content to fit
     naturally. If content exceeds this, the modal scrolls internally with
     overscroll-behavior: contain to prevent page scroll. overflow-x: hidden
     preserves rounded-corner clipping. May 2026 — reduced from 90vh to give
     content more breathing room and reduce scrolling frequency. */
  max-height: 85vh;
  max-height: 85dvh; /* mobile-keyboard-safe */
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
}

/* ─── The Brief icon tiles ─────────────────────────────────────────────── */
.brief-icon {
  border-radius: var(--md-sys-shape-corner-medium);
  position: relative;
}
.brief-icon:hover {
  box-shadow: var(--md-sys-elevation-2);
  transform: translateY(-1px);
}
.brief-icon:active {
  box-shadow: var(--md-sys-elevation-1);
  transform: scale(0.96);
}

/* ─── Card hover state-layer (subtle primary overlay) ─────────────────── */
.dorm-card,
.college-card,
.home-blog-card { position: relative; }
.dorm-card::before,
.college-card::before,
.home-blog-card::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: var(--md-sys-color-primary);
  opacity: 0;
  border-radius: inherit;
  transition: opacity var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-emphasized);
  z-index: 0;
}
.dorm-card:hover::before,
.college-card:hover::before,
.home-blog-card:hover::before {
  opacity: var(--md-sys-state-hover-opacity);
}
.dorm-card > *,
.college-card > *,
.home-blog-card > * {
  position: relative;
  z-index: 1;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * MD3 Phase 3 — 2026-04-30
 * Snackbars, Segmented Buttons, Typography Scale, Bottom Sheet anatomy,
 * Chip variants, Outlined Text Fields, Nav Bar active indicator, FAB types,
 * Linear Progress, List anatomy. All additions are opt-in via new class
 * names; existing surfaces continue to work unchanged.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ─── (1) MD3 Snackbar ──────────────────────────────────────────────────── */
/* Bottom-center container that stacks multiple snackbars vertically. The
   toast() helper in app.js was upgraded to render <div class="md-snackbar">
   nodes here. Each snackbar has 4-second auto-dismiss + optional action
   button slot. Click the close X or wait for auto-dismiss to remove. */
#md-snackbar-container {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9999;
  display: flex;
  flex-direction: column-reverse;
  gap: 8px;
  pointer-events: none; /* container is transparent; only snackbars catch clicks */
  max-width: min(560px, calc(100vw - 32px));
}
.md-snackbar {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 12px;
  background: #322F35; /* MD3 inverse-surface for snackbar */
  color: #F4EFF4;       /* inverse-on-surface */
  border-radius: 4px;   /* MD3 corner-extra-small */
  padding: 14px 16px;
  font-size: .875rem;
  line-height: 1.4;
  box-shadow: 0 6px 12px rgba(0,0,0,0.18), 0 1px 3px rgba(0,0,0,0.12);
  min-height: 48px;
  animation: md-snackbar-in 250ms cubic-bezier(0.05, 0.7, 0.1, 1.0);
  max-width: 100%;
}
.md-snackbar.md-snackbar-leaving { animation: md-snackbar-out 200ms cubic-bezier(0.3, 0.0, 0.8, 0.15) forwards; }
.md-snackbar-text { flex: 1; min-width: 0; }
.md-snackbar-action {
  background: transparent;
  border: 0;
  color: #D0BCFF; /* inverse-primary */
  font-weight: 600;
  font-size: .875rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  padding: 4px 8px;
  border-radius: 4px;
  cursor: pointer;
  flex-shrink: 0;
}
.md-snackbar-action:hover { background: rgba(208, 188, 255, .08); }
.md-snackbar-close {
  background: transparent;
  border: 0;
  color: rgba(244, 239, 244, .8);
  font-size: 1.1rem;
  width: 24px; height: 24px;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.md-snackbar-close:hover { background: rgba(244, 239, 244, .12); }
.md-snackbar-success { background: #1B5E20; color: #fff; }
.md-snackbar-success .md-snackbar-action { color: #A5D6A7; }
.md-snackbar-error { background: #B3261E; color: #fff; }
.md-snackbar-error .md-snackbar-action { color: #FFB4AB; }
.md-snackbar-info { background: #322F35; color: #F4EFF4; }
@keyframes md-snackbar-in {
  0%   { opacity: 0; transform: translateY(20px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes md-snackbar-out {
  0%   { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(20px); }
}

/* ─── (2) MD3 Segmented Buttons ─────────────────────────────────────────── */
/* Border-attached button group with checkmark on active. Pattern:
   <div class="md-segmented-buttons" role="group">
     <button class="md-segmented-btn md-segmented-btn-active">⭐ Popular</button>
     <button class="md-segmented-btn">All</button>
   </div>
   Replaces ad-hoc .tab-btn pill rows on home + leaderboard + admin. */
/* Segmented buttons — May 2026 redesign. Originally rendered as a single
 * connected pill (Popular | Following | All Schools) using negative margins
 * + first/last border-radius tricks. That layout had two recurring bugs:
 *   1. Active button's z-index made its borders overlap adjacent inactive
 *      borders by ~1px, creating a visible double-line at boundaries.
 *   2. Adding/removing buttons (e.g. the new "🗺 By State" pill 2026-05-08)
 *      required rebalancing first/last/only-child rules per count.
 * Switched to gap-based pills with full border-radius on every chip. Each
 * is its own visual unit. flex-wrap so 4+ pills wrap cleanly on narrow
 * screens. The mobile-specific override below is now identical to the
 * desktop styles — kept for clarity but functionally redundant. */
.md-segmented-buttons {
  display: inline-flex;
  flex-wrap: wrap;
  gap: .4rem;
  background: transparent;
}
.md-segmented-btn {
  background: #fff;
  border: 1px solid #79747E; /* MD3 outline */
  color: #1D1B20;            /* MD3 on-surface */
  font-size: .875rem;
  font-weight: 500;
  padding: 0 18px;
  height: 40px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: 9999px;
  transition: background-color 150ms, color 150ms;
  position: relative;
}
.md-segmented-btn:hover:not(.md-segmented-btn-active) { background: #F7F2FA; }
.md-segmented-btn-active {
  background: #E8DEF8; /* MD3 secondary-container */
  color: #1D192B;       /* MD3 on-secondary-container */
  z-index: 1; /* sit above sibling borders */
}
.md-segmented-btn-active::before {
  content: '✓';
  font-size: .9rem;
  font-weight: 700;
  margin-right: 4px;
}
/* Suppress the auto-checkmark when the button already carries its own
   emoji icon (e.g. ⭐ Popular, 🔔 Following). Doubling up the ✓ + emoji
   reads as redundant. Apply md-segmented-btn-no-check on the parent
   group when every button has a leading emoji. */
.md-segmented-btn-no-check .md-segmented-btn-active::before { content: none; }
.md-segmented-btn:focus-visible {
  outline: 2px solid #6750A4;
  outline-offset: 2px;
  z-index: 2;
}

/* Mobile sizing — slightly smaller pills + smaller font on narrow screens.
 * (The wrap + gap layout above already covers the visual overlap fix.) */
@media (max-width: 640px) {
  .md-segmented-btn {
    padding: 0 14px;
    height: 38px;
    font-size: .82rem;
  }
}

/* ─── (3) MD3 Typography Scale ──────────────────────────────────────────── */
/* 13 utility classes mapping to the MD3 type scale. Apply on top of any
   element to swap its size + weight + line-height. Mobile sizes scale down
   ~10% via min(). Inter font is already the site default — only sizes /
   weights / line-heights change. */
.md-display-large    { font-size: 3.5625rem;  line-height: 4rem;       letter-spacing: -.025em; font-weight: 400; }
.md-display-medium   { font-size: 2.8125rem;  line-height: 3.25rem;    letter-spacing: 0;       font-weight: 400; }
.md-display-small    { font-size: 2.25rem;    line-height: 2.75rem;    letter-spacing: 0;       font-weight: 400; }
.md-headline-large   { font-size: 2rem;       line-height: 2.5rem;     letter-spacing: 0;       font-weight: 400; }
.md-headline-medium  { font-size: 1.75rem;    line-height: 2.25rem;    letter-spacing: 0;       font-weight: 400; }
.md-headline-small   { font-size: 1.5rem;     line-height: 2rem;       letter-spacing: 0;       font-weight: 400; }
.md-title-large      { font-size: 1.375rem;   line-height: 1.75rem;    letter-spacing: 0;       font-weight: 500; }
.md-title-medium     { font-size: 1rem;       line-height: 1.5rem;     letter-spacing: .009em;  font-weight: 500; }
.md-title-small      { font-size: .875rem;    line-height: 1.25rem;    letter-spacing: .007em;  font-weight: 500; }
.md-body-large       { font-size: 1rem;       line-height: 1.5rem;     letter-spacing: .031em;  font-weight: 400; }
.md-body-medium      { font-size: .875rem;    line-height: 1.25rem;    letter-spacing: .017em;  font-weight: 400; }
.md-body-small       { font-size: .75rem;     line-height: 1rem;       letter-spacing: .025em;  font-weight: 400; }
.md-label-large      { font-size: .875rem;    line-height: 1.25rem;    letter-spacing: .007em;  font-weight: 500; }
.md-label-medium     { font-size: .75rem;     line-height: 1rem;       letter-spacing: .025em;  font-weight: 500; }
.md-label-small      { font-size: .6875rem;   line-height: 1rem;       letter-spacing: .033em;  font-weight: 500; }

/* ─── (4) MD3 Bottom Sheet anatomy ──────────────────────────────────────── */
/* Enhances the existing .brief-sheet with a drag handle at the top + denser
   scrim. The drag handle is purely visual on desktop; on touch devices the
   swipe-to-dismiss handler in app.js wires actual gesture support. */
.md-bottom-sheet-handle {
  width: 32px;
  height: 4px;
  background: rgba(73, 69, 79, .4); /* MD3 outline-variant */
  border-radius: 2px;
  margin: 12px auto 8px;
  cursor: grab;
}
.md-bottom-sheet-handle:active { cursor: grabbing; }

/* ─── (5) MD3 Chip variants ─────────────────────────────────────────────── */
/* 4 chip types per spec. Existing .policy-chip / .dining-diet-chip / .qf-chip
   stay untouched; new code can opt into the right variant.
   - md-chip-assist: prompts an action ("✏️ Add details")
   - md-chip-filter: toggles a filter (selectable)
   - md-chip-input:  represents a token in an input (X to remove)
   - md-chip-suggestion: clickable suggestion ("Try: Cornell") */
.md-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 0 12px;
  font-size: .875rem;
  font-weight: 500;
  border-radius: 8px;
  border: 1px solid #79747E;
  background: #fff;
  color: #1D1B20;
  cursor: pointer;
  transition: background-color 120ms, border-color 120ms;
}
.md-chip:hover { background: #F7F2FA; }
.md-chip-assist     { border-color: #79747E; }
.md-chip-filter     { border-color: #79747E; }
.md-chip-filter.md-chip-selected {
  background: #E8DEF8;
  color: #1D192B;
  border-color: transparent;
}
.md-chip-filter.md-chip-selected::before { content: '✓'; font-weight: 700; }
.md-chip-input {
  background: #E7E0EC; /* MD3 surface-container-high */
  border: 0;
  padding: 0 12px 0 16px;
}
.md-chip-input::after {
  content: '✕';
  margin-left: 4px;
  font-size: .85rem;
  opacity: .7;
}
.md-chip-input:hover::after { opacity: 1; }
.md-chip-suggestion {
  background: #fff;
  border-color: #79747E;
}

/* ─── (6) MD3 Outlined Text Fields ──────────────────────────────────────── */
/* Pattern:
   <label class="md-text-field md-text-field-outlined">
     <input type="text" placeholder=" " />
     <span class="md-text-field-label">Display name</span>
     <span class="md-text-field-helper">Shown on your reviews</span>
   </label>
   The placeholder=" " trick is what enables the floating-label animation
   without JS. The label slides up + shrinks when the input has content
   or focus; otherwise sits centered as a placeholder. */
.md-text-field {
  position: relative;
  display: block;
  margin-bottom: 16px;
}
.md-text-field-outlined > input,
.md-text-field-outlined > textarea {
  width: 100%;
  padding: 16px 16px 8px;
  border: 1px solid #79747E;
  border-radius: 4px;
  background: #fff;
  font-size: 1rem;
  font-family: inherit;
  color: #1D1B20;
  outline: none;
  transition: border-color 150ms, border-width 150ms;
}
.md-text-field-outlined > input:focus,
.md-text-field-outlined > textarea:focus {
  border-color: #6750A4;
  border-width: 2px;
  padding-top: 15px; padding-left: 15px; padding-right: 15px; /* compensate */
}
.md-text-field-label {
  position: absolute;
  left: 12px;
  top: 16px;
  background: #fff;
  padding: 0 4px;
  color: #79747E;
  pointer-events: none;
  font-size: 1rem;
  transition: top 150ms, font-size 150ms, color 150ms;
}
.md-text-field-outlined > input:focus + .md-text-field-label,
.md-text-field-outlined > input:not(:placeholder-shown) + .md-text-field-label,
.md-text-field-outlined > textarea:focus + .md-text-field-label,
.md-text-field-outlined > textarea:not(:placeholder-shown) + .md-text-field-label {
  top: -8px;
  font-size: .75rem;
  color: #6750A4;
}
.md-text-field-helper {
  display: block;
  font-size: .75rem;
  color: #49454F;
  margin: 4px 12px 0;
}
.md-text-field.md-text-field-error > input,
.md-text-field.md-text-field-error > textarea { border-color: #B3261E; }
.md-text-field.md-text-field-error .md-text-field-label,
.md-text-field.md-text-field-error .md-text-field-helper { color: #B3261E; }

/* ─── (7) MD3 Navigation Bar — active indicator pill ──────────────────── */
/* Refines the existing .mobile-bottom-nav. When .mbn-tab is .active, an
   oval indicator pill (MD3 secondary-container 64×32) sits behind the
   icon. Implemented via ::before pseudo so no markup change required.
   Earlier draft used .nav-tab-icon-wrap which doesn't match the existing
   markup — retargeted to .mbn-tab so it actually applies. */
.mobile-bottom-nav .mbn-tab .mbn-ico {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 32px;
  z-index: 1;
}
.mobile-bottom-nav .mbn-tab.active .mbn-ico::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 16px;
  background: #E8DEF8; /* MD3 secondary-container */
  z-index: -1;
  transition: background-color 200ms;
}

/* ─── (8) MD3 FAB types ─────────────────────────────────────────────────── */
/* Standard / Small / Large / Extended FAB classes. Apply alongside the
   existing #admin-edit-fab or any new floating action button. */
.md-fab {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 1000;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--md-sys-color-primary, #6366f1);
  color: var(--md-sys-color-on-primary, #fff);
  border: 0;
  cursor: pointer;
  box-shadow: var(--md-sys-elevation-3, 0 4px 8px rgba(0,0,0,0.10));
  transition: box-shadow 200ms, background-color 150ms, transform 100ms;
}
.md-fab:hover { box-shadow: var(--md-sys-elevation-4, 0 6px 12px rgba(0,0,0,0.12)); }
.md-fab:active { transform: scale(0.96); }
.md-fab-small  { width: 40px; height: 40px; border-radius: 12px; font-size: 1rem; }
.md-fab-standard { width: 56px; height: 56px; border-radius: 16px; font-size: 1.25rem; }
.md-fab-large  { width: 96px; height: 96px; border-radius: 28px; font-size: 1.75rem; }
.md-fab-extended {
  height: 56px;
  padding: 0 20px;
  border-radius: 16px;
  font-size: .9375rem;
  font-weight: 500;
  gap: 8px;
}

/* ─── (9) MD3 Linear Progress Indicator ─────────────────────────────────── */
/* Pattern:
   <div class="md-progress-linear">
     <div class="md-progress-linear-bar" style="width:42%"></div>
   </div>
   Indeterminate variant: <div class="md-progress-linear md-progress-linear-indeterminate"></div>
   Used for photo upload, dining grade recalc, and any long-running task. */
.md-progress-linear {
  width: 100%;
  height: 4px;
  background: #E7E0EC;
  border-radius: 2px;
  overflow: hidden;
  position: relative;
}
.md-progress-linear-bar {
  height: 100%;
  background: #6750A4;
  border-radius: 2px;
  transition: width 250ms cubic-bezier(0.05, 0.7, 0.1, 1.0);
}
.md-progress-linear-indeterminate::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  height: 100%; width: 30%;
  background: #6750A4;
  border-radius: 2px;
  animation: md-progress-indeterminate 1.5s cubic-bezier(0.4, 0.0, 0.2, 1.0) infinite;
}
@keyframes md-progress-indeterminate {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(400%); }
}

/* ─── (10) MD3 List anatomy ─────────────────────────────────────────────── */
/* Pattern:
   <ul class="md-list">
     <li class="md-list-item">
       <span class="md-list-leading">📸</span>
       <div class="md-list-content">
         <div class="md-list-headline">Title</div>
         <div class="md-list-supporting">Supporting text</div>
       </div>
       <span class="md-list-trailing">→</span>
     </li>
   </ul>
   1-line items omit the .md-list-supporting; 3-line items add another
   .md-list-supporting block. */
.md-list { list-style: none; padding: 0; margin: 0; }
.md-list-item {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 16px;
  min-height: 48px;
  cursor: pointer;
  transition: background-color 120ms;
}
.md-list-item:hover { background: rgba(103, 80, 164, .08); }
.md-list-item:focus-visible { outline: 2px solid #6750A4; outline-offset: -2px; }
.md-list-leading {
  flex-shrink: 0;
  width: 24px; height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  color: #49454F;
}
.md-list-content { flex: 1; min-width: 0; }
.md-list-headline { font-size: 1rem; font-weight: 400; color: #1D1B20; line-height: 1.5rem; }
.md-list-supporting { font-size: .875rem; color: #49454F; line-height: 1.25rem; }
.md-list-trailing { flex-shrink: 0; color: #49454F; font-size: .875rem; }
.md-list-item.md-list-2-line { padding: 8px 16px; min-height: 64px; }
.md-list-item.md-list-3-line { padding: 12px 16px; min-height: 88px; align-items: flex-start; }
.md-list-item.md-list-3-line .md-list-leading { margin-top: 2px; }

/* ─── Tap-target floor (May 2026 mobile/PWA pass) ──────────────────────
 * iOS Human Interface Guidelines: 44×44 pt minimum for any tappable
 * element. Material Design says 48×48dp. Anything smaller misses ~10%
 * of the time on touch devices. This block targets confirmed-small
 * icon-only buttons site-wide and bumps them to the 44 floor on touch
 * pointers only — desktop layouts stay untouched.
 *
 * Selected after a 2026-05-08 audit of every interactive element in
 * styles.css. Other small-but-already-padded elements (.qf-chip,
 * .tag-toggle-btn, .tab-btn) already have enough padding to clear 44
 * vertically on mobile via existing rules; only the icon-only ones
 * needed help. */
@media (pointer: coarse) {
  .fact-suggest-btn,
  .edit-zone-btn,
  .dorm-cmp-btn,
  .tip-vote-btn,
  .disc-upvote-btn,
  .pwa-banner-dismiss,
  .photo-report-btn,
  .iep-btn,
  .modal-close-x,
  .btn-close,
  .helpful-vote-btn,
  #rm-dm-bell-btn,
  #rm-thread-close,
  #rm-thread-block-btn,
  #rm-thread-photo-btn,
  #rm-thread-pending-remove,
  #rm-inbox-btn,
  #rm-inbox-close {
    min-width: 44px;
    min-height: 44px;
    /* If the element relies on inline-flex / inline-block to size
     * itself, force a flex container so the min-* rules clamp the box
     * properly without stretching content. */
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
  }

  /* The fact-suggest-btn is opacity:0 on desktop (hover-revealed). On
   * touch there's no hover — make it always-visible at lower opacity
   * so users can actually tap it. */
  .fact-suggest-btn {
    opacity: .55 !important;
  }

  /* DM thread + inbox modals on iPhone — composer sits flush against the
   * software keyboard. The page-local roommates.html .modal-overlay uses
   * inline height:75vh; max-height:680px which doesn't track the iOS
   * keyboard (vh stays constant when the keyboard opens). Override with
   * dvh so the modal shrinks with the keyboard and Send stays reachable.
   * Also cap the textarea max-height so a user manually drag-resizing
   * can't push Send off-screen. */
  #rm-thread-modal > div,
  #rm-inbox-modal > div {
    height: min(75dvh, 680px) !important;
    max-height: 100dvh !important;
  }
  #rm-thread-input {
    max-height: 6rem !important;
  }
}

/* ──────────────────────────────────────────────────────────────────
   Room Condition Report Wizard (May 2026)
   ────────────────────────────────────────────────────────────────── */
.cw-mode-card {
  display: block;
  border: 2px solid #e5e7eb;
  border-radius: 12px;
  padding: 1rem;
  cursor: pointer;
  text-align: center;
  transition: all 0.15s;
  background: #fff;
}
.cw-mode-card:hover { border-color: #c7d2fe; background: #f5f3ff; }
.cw-mode-card input[type=radio] { display: none; }
.cw-mode-card:has(input:checked) {
  border-color: #6366f1;
  background: #eef2ff;
  box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.18);
}
.cw-mode-icon { font-size: 2rem; margin-bottom: .25rem; }
.cw-mode-title { font-weight: 700; color: #0f172a; margin-bottom: .25rem; }
.cw-mode-sub { font-size: .8rem; color: #64748b; line-height: 1.3; }

/* Photo capture grid card — one per prompt. Tappable: opens file picker.
   Filled state shows thumbnail + caption + damage toggle. */
.cw-photo-card {
  border: 2px dashed #cbd5e1;
  border-radius: 8px;
  padding: .6rem;
  background: #f8fafc;
  cursor: pointer;
  transition: all 0.15s;
  position: relative;
  min-height: 130px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.cw-photo-card:hover { border-color: #6366f1; background: #eef2ff; }
.cw-photo-card.filled {
  border-style: solid;
  border-color: #10b981;
  background: #fff;
  cursor: default;
  align-items: stretch;
  justify-content: flex-start;
}
.cw-photo-card.filled.is-damage { border-color: #dc2626; }
.cw-photo-card-label {
  font-size: .8rem;
  color: #475569;
  font-weight: 500;
}
.cw-photo-card-icon { font-size: 1.5rem; margin-bottom: .3rem; opacity: .6; }
.cw-photo-thumb {
  width: 100%;
  height: 90px;
  object-fit: cover;
  border-radius: 4px;
  margin-bottom: .35rem;
}
.cw-photo-actions {
  display: flex;
  gap: .25rem;
  align-items: center;
  font-size: .72rem;
}
.cw-damage-toggle {
  flex: 1;
  cursor: pointer;
  user-select: none;
  padding: .15rem .35rem;
  border-radius: 4px;
  background: #f1f5f9;
  color: #64748b;
}
.cw-damage-toggle.on { background: #fee2e2; color: #b91c1c; font-weight: 600; }
.cw-photo-remove {
  background: none;
  border: none;
  cursor: pointer;
  color: #94a3b8;
  font-size: .9rem;
  padding: .15rem .35rem;
}
.cw-photo-remove:hover { color: #dc2626; }

/* Photo strip (multi-photo per prompt) */
.cw-photo-card.multi-photo {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.cw-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: .5rem;
  margin-bottom: .25rem;
}

.cw-card-title {
  display: flex;
  align-items: center;
  gap: .35rem;
  font-size: .95rem;
  font-weight: 600;
  color: #0f172a;
}

.cw-card-icon {
  font-size: 1.2rem;
}

.cw-add-another-btn {
  padding: .3rem .6rem;
  border: 1px dashed #c7d2fe;
  border-radius: 6px;
  background: transparent;
  color: #6366f1;
  font-size: .8rem;
  cursor: pointer;
  transition: all .15s;
  font-weight: 500;
}

.cw-add-another-btn:hover {
  border-color: #a5b4fc;
  background: #f5f3ff;
}

.cw-photo-strip {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 4px 0;
  -webkit-overflow-scrolling: touch;
}

.cw-photo-strip-item {
  position: relative;
  flex-shrink: 0;
  width: 80px;
  display: flex;
  flex-direction: column;
  gap: .3rem;
}

.cw-photo-frame {
  position: relative;
  width: 80px;
  height: 80px;
  border-radius: 6px;
  overflow: hidden;
  border: 2px solid #e2e8f0;
  transition: border-color .15s;
}

.cw-photo-frame.is-damage {
  border-color: #fecaca;
  background: #fef2f2;
}

.cw-photo-frame:hover {
  border-color: #cbd5e1;
}

.cw-photo-strip-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.cw-blur-badge {
  position: absolute;
  top: 2px;
  right: 2px;
  background: #fbbf24;
  color: #78350f;
  font-size: .6rem;
  padding: 2px 4px;
  border-radius: 3px;
  font-weight: 600;
  text-shadow: 0 0 2px rgba(255,255,255,.5);
}

.cw-photo-controls {
  position: absolute;
  inset: 0;
  display: none;
  gap: .2rem;
  padding: .3rem;
  background: rgba(0, 0, 0, 0.5);
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
}

.cw-photo-frame:hover .cw-photo-controls {
  display: flex;
}

.cw-photo-btn {
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.9);
  color: #0f172a;
  font-size: .7rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all .15s;
  flex: 0 0 24px;
}

.cw-photo-btn:hover {
  background: white;
  transform: scale(1.1);
}

.cw-photo-btn.remove-btn:hover {
  background: #fee2e2;
  color: #dc2626;
}

.cw-caption-area {
  display: flex;
  flex-direction: column;
  gap: .2rem;
  position: relative;
  font-size: .75rem;
}

.cw-caption-text {
  color: #64748b;
  line-height: 1.2;
  word-break: break-word;
  min-height: 1.4rem;
  text-align: left;
}

.cw-caption-edit-input {
  width: 100%;
  padding: .2rem .3rem;
  font-size: .75rem;
  border: 1px solid #cbd5e1;
  border-radius: 3px;
  font-family: inherit;
}

.cw-caption-edit-btn {
  width: 16px;
  height: 16px;
  padding: 0;
  border: none;
  background: transparent;
  color: #94a3b8;
  font-size: .7rem;
  cursor: pointer;
  display: none;
  align-items: center;
  justify-content: center;
  margin-top: -.2rem;
}

.cw-caption-area:hover .cw-caption-edit-btn {
  display: flex;
}

.cw-caption-edit-btn:hover {
  color: #64748b;
}

.cw-photo-strip-item.editing-caption .cw-caption-edit-btn {
  display: flex;
}

/* ──────────────────────────────────────────────────────────────────
   Quick Survey Modal (Max's Little Bit of Info) (May 2026)
   ────────────────────────────────────────────────────────────────── */
#modal-quick-survey {
  max-width: 400px;
  display: flex;
  flex-direction: column;
  max-height: 85vh;
  max-height: 85dvh; /* mobile-keyboard-safe */
}

.qs-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem;
  background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
  color: white;
  border-radius: 12px 12px 0 0;
  font-weight: 600;
  font-size: .95rem;
  gap: 1rem;
}

.qs-pts-banner {
  display: flex;
  align-items: center;
  gap: .35rem;
  font-size: .9rem;
  font-weight: 500;
  white-space: nowrap;
}

.qs-progress {
  font-size: .8rem;
  opacity: .9;
  white-space: nowrap;
}

.qs-body {
  flex: 1;
  overflow-y: auto;
  padding: 1.5rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.qs-screen {
  display: none;
  animation: slideIn 0.3s ease-out;
}

.qs-screen.active {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

@keyframes slideIn {
  from { transform: translateX(20px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

/* Room Selection Screen */
.qs-room-select {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.qs-dorm-search {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.qs-dorm-search input {
  width: 100%;
  padding: .65rem;
  border: 1px solid #cbd5e1;
  border-radius: 8px;
  font-size: .95rem;
  font-family: inherit;
}

.qs-dorm-search input:focus {
  outline: none;
  border-color: #6366f1;
  box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
}

.qs-dorm-dropdown {
  max-height: 200px;
  overflow-y: auto;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  background: white;
  z-index: 100;
}

.qs-dorm-option {
  padding: .65rem;
  cursor: pointer;
  border-bottom: 1px solid #e5e7eb;
  transition: background-color 0.12s;
}

.qs-dorm-option:last-child { border-bottom: none; }

.qs-dorm-option:hover {
  background-color: #eef2ff;
}

.qs-dorm-option.selected {
  background-color: #ddd6fe;
  font-weight: 600;
}

.qs-room-input {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.qs-room-input label {
  font-weight: 500;
  color: #1f2937;
  font-size: .9rem;
}

.qs-room-input input {
  padding: .65rem;
  border: 1px solid #cbd5e1;
  border-radius: 8px;
  font-size: .95rem;
  font-family: inherit;
}

.qs-room-input input:focus {
  outline: none;
  border-color: #6366f1;
  box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
}

/* Question Screen */
.qs-question {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
  text-align: center;
}

.qs-question-icon {
  font-size: 2.5rem;
  line-height: 1;
}

.qs-question-text {
  font-size: 1.1rem;
  font-weight: 600;
  color: #0f172a;
  line-height: 1.4;
}

.qs-choices {
  display: flex;
  flex-direction: column;
  gap: .75rem;
  width: 100%;
}

.qs-choice-btn {
  width: 100%;
  padding: 1rem;
  font-size: 1rem;
  font-family: inherit;
  font-weight: 500;
  border: 2px solid #cbd5e1;
  border-radius: 12px;
  background: white;
  color: #1f2937;
  cursor: pointer;
  transition: all 0.2s;
  text-align: center;
}

.qs-choice-btn:hover {
  border-color: #a5b4fc;
  background: #eef2ff;
}

.qs-choice-btn.selected {
  border-color: #6366f1;
  background: #ddd6fe;
  color: #4320b5;
  font-weight: 600;
}

.qs-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem;
  background: #f8fafc;
  border-top: 1px solid #e5e7eb;
  border-radius: 0 0 12px 12px;
  font-size: .9rem;
  gap: .75rem;
}

.qs-footer button {
  padding: .5rem 1rem;
  border: none;
  border-radius: 6px;
  font-weight: 500;
  cursor: pointer;
  font-family: inherit;
  transition: all 0.15s;
}

.qs-footer .qs-btn-back {
  background: white;
  border: 1px solid #cbd5e1;
  color: #6366f1;
}

.qs-footer .qs-btn-back:hover {
  background: #f1f5f9;
  border-color: #a5b4fc;
}

.qs-footer .qs-btn-done {
  background: white;
  border: 1px solid #cbd5e1;
  color: #64748b;
  margin-left: auto;
}

.qs-footer .qs-btn-done:hover {
  background: #f1f5f9;
  border-color: #cbd5e1;
}

.qs-footer .qs-btn-next {
  background: #6366f1;
  color: white;
  border: none;
  margin-left: auto;
}

.qs-footer .qs-btn-next:hover {
  background: #4f46e5;
}

.qs-footer .qs-btn-next:disabled {
  background: #cbd5e1;
  cursor: not-allowed;
  opacity: .6;
}

.qs-done-link {
  color: #6366f1;
  cursor: pointer;
  font-weight: 500;
  text-decoration: underline;
  background: none;
  border: none;
  font-family: inherit;
  font-size: .9rem;
  transition: color 0.15s;
}

.qs-done-link:hover {
  color: #4f46e5;
}

/* Mobile responsive */
@media (max-width: 480px) {
  #modal-quick-survey {
    max-width: 100vw;
    max-height: 100vh;
    max-height: 100dvh; /* mobile-keyboard-safe */
    border-radius: 16px 16px 0 0;
  }

  .qs-header {
    font-size: .85rem;
  }

  .qs-pts-banner {
    font-size: .8rem;
  }

  .qs-progress {
    font-size: .75rem;
  }

  .qs-body {
    padding: 1.25rem .75rem;
  }

  .qs-question-icon {
    font-size: 2rem;
  }

  .qs-question-text {
    font-size: 1rem;
  }

  .qs-choice-btn {
    padding: .85rem;
    font-size: .95rem;
  }

  .qs-footer {
    padding: .75rem;
    gap: .5rem;
  }

  .qs-footer button {
    padding: .4rem .75rem;
    font-size: .85rem;
  }
}

/* ─── Visually-hidden helper (a11y) ─────────────────────────────────────────
   Standard "sr-only" / visually-hidden pattern: keeps content in the
   accessibility tree (announced by screen readers, navigable by keyboard)
   while removing it from the visible layout. */
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ─── Mobile hero compression (May 2026 — Home #3) ──────────────────────────
   iPhone SE (375x667) viewport: the default 2.5rem hero padding plus the
   h1/sub/search/recent-searches/hint chain pushes the colleges grid almost
   entirely below the fold. Compress padding, tighten paragraph spacing, and
   hide the "Request it →" hint (it lives in the hamburger drawer's About
   section already). */
@media (max-width: 480px) {
  .hero { padding: 1.5rem 1rem; }
  .hero p { margin-bottom: 0.9rem; }
  .hero-hint { display: none; }
}

/* ─── Placeholder-college badge (May 2026 — Home #6) ────────────────────────
   Card-level chip shown on .dorm-card when the college has zero dorms and
   zero ratings. Links straight to the wizard pre-filled with that college so
   first-time contributors land in the right flow. */
.placeholder-college-badge {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  margin-top: .4rem;
  padding: .2rem .5rem;
  border-radius: var(--md3-shape-full);
  background: var(--md3-tertiary-container);
  color: var(--md3-on-tertiary-container);
  font-size: .68rem;
  font-weight: 600;
  text-decoration: none;
  max-width: calc(100% - 90px);
  border: 1px solid color-mix(in srgb, var(--md3-on-tertiary-container) 18%, transparent);
  transition: background var(--md3-dur-short-3, 150ms) var(--md3-motion-standard, ease);
  position: relative;
  z-index: 2;
}
.placeholder-college-badge:hover {
  background: color-mix(in srgb, var(--md3-on-tertiary-container) 12%, var(--md3-tertiary-container));
}

/* ═══ Home "Add Your Room" CTA card (May 2026 — UX_TODO #onboarding) ═════════
   Single conversion card surfaced above the colleges grid on the Popular tab.
   Routes logged-out users through the auth modal; logged-in users go straight
   to the wizard. Dismissible (30-day cooldown). Permanently hidden after the
   user's first successful wizard submit. */
.home-wizard-cta {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.85rem;
  padding: 1rem 1.25rem;
  margin: 0 0 1.25rem;
  background: var(--md3-primary-container);
  color: var(--md3-on-primary-container);
  border: 1px solid color-mix(in srgb, var(--md3-on-primary-container) 18%, transparent);
  border-radius: var(--md3-shape-lg);
  box-shadow: var(--md3-elev-1);
}
.home-wizard-cta-body {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex: 1 1 auto;
  min-width: 0;
}
.home-wizard-cta-icon {
  font-size: 1.85rem;
  line-height: 1;
  flex-shrink: 0;
}
.home-wizard-cta-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.home-wizard-cta-headline {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.3;
  margin: 0;
}
.home-wizard-cta-sub {
  font-size: 0.86rem;
  font-weight: 400;
  opacity: 0.9;
  margin: 0;
}
.home-wizard-cta-actions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-shrink: 0;
}
.home-wizard-cta-dismiss {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: 999px;
  color: var(--md3-on-primary-container);
  opacity: 0.6;
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  transition: opacity var(--md3-dur-short-3, 150ms) var(--md3-motion-standard, ease), background var(--md3-dur-short-3, 150ms);
}
.home-wizard-cta-dismiss:hover,
.home-wizard-cta-dismiss:focus-visible {
  opacity: 1;
  background: color-mix(in srgb, var(--md3-on-primary-container) 8%, transparent);
}
@media (max-width: 540px) {
  .home-wizard-cta { flex-direction: column; align-items: stretch; padding: 0.9rem 1rem; }
  .home-wizard-cta-actions { justify-content: space-between; width: 100%; }
}

/* Home personalized "things to do at your school" strip (May 2026). Chips
   surface admin/server-supplied next-steps tailored to the user's affiliated
   college. Hidden when items.length === 0. */
.home-personalized-strip {
  margin: 0 0 1.5rem;
  padding: 0.85rem 1rem;
  background: var(--md3-surface-container);
  border: 1px solid var(--md3-outline-variant);
  border-radius: var(--md3-shape-md);
}
.home-personalized-headline {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--md3-on-surface);
  margin: 0 0 0.55rem;
}
.home-personalized-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.home-personalized-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.35rem 0.7rem;
  border-radius: 999px;
  background: var(--md3-surface);
  color: var(--md3-on-surface);
  border: 1px solid var(--md3-outline-variant);
  font-size: 0.82rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--md3-dur-short-3, 150ms), border-color var(--md3-dur-short-3, 150ms);
}
.home-personalized-chip:hover,
.home-personalized-chip:focus-visible {
  background: var(--md3-primary-container);
  border-color: var(--md3-primary);
  color: var(--md3-on-primary-container);
}

/* ═══ Sticky home search (May 2026 — UX_TODO #search) ═══════════════════════
   Compact search bar that pins to the top of the viewport on the home view
   after scrolling past the hero. Hidden by default; .visible toggled via JS
   scroll handler. Mirrors the typeahead behavior of #home-search. */
.sticky-home-search {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translate(-50%, -110%);
  width: calc(100% - 2rem);
  max-width: 600px;
  padding: 0.5rem 1rem;
  background: var(--md3-surface-container-highest);
  border-radius: 0 0 var(--md3-shape-lg) var(--md3-shape-lg);
  box-shadow: var(--md3-elev-2);
  z-index: 1080;
  transition: transform var(--md3-dur-medium-2, 220ms) var(--md3-motion-standard, ease);
  display: none;
}
.sticky-home-search.mounted { display: block; }
.sticky-home-search.visible { transform: translate(-50%, 0); }
.sticky-home-search-form {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.sticky-home-search-form input[type="search"] {
  flex: 1 1 auto;
  font-size: 0.92rem;
  padding: 0.5rem 0.75rem;
  border-radius: var(--md3-shape-md);
  border: 1px solid var(--md3-outline-variant);
  background: var(--md3-surface);
  color: var(--md3-on-surface);
}
.sticky-home-search-form input[type="search"]:focus-visible {
  outline: 2px solid var(--md3-primary);
  outline-offset: 1px;
}
@media (max-width: 540px) {
  .sticky-home-search { width: calc(100% - 1rem); padding: 0.45rem 0.6rem; }
}

/* ═══ Edit conflict modal (May 2026 — UX_TODO #auth-friction / audit #12) ═══
   Surfaced when an admin's PUT to /api/admin/colleges/:id or /api/admin/dorms/:id/meta
   returns HTTP 409 with { error: 'version_mismatch' }. Non-destructive — gives
   the admin a choice of discard / overwrite / cancel rather than silently
   stomping a parallel edit. */
.edit-conflict-modal {
  max-width: 480px;
}
.edit-conflict-modal .md3-dialog-headline {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.edit-conflict-icon {
  font-size: 1.6rem;
  line-height: 1;
}
.edit-conflict-modal p { margin: 0.65rem 0; line-height: 1.45; font-size: 0.92rem; }
.edit-conflict-current-version {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--md3-tertiary-container);
  color: var(--md3-on-tertiary-container);
  font-size: 0.78rem;
  font-weight: 600;
  margin-left: 0.3rem;
}
.edit-conflict-actions {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 1rem;
}
.edit-conflict-actions .btn { justify-content: center; }
@media (min-width: 540px) {
  .edit-conflict-actions { flex-direction: row; flex-wrap: wrap; }
  .edit-conflict-actions .btn { flex: 1 1 auto; }
}

/* Version badge in edit modal footer — surfaces the current cached version
   so admins can spot when another tab has bumped it under their feet. */
.edit-version-badge {
  display: inline-block;
  font-size: 0.74rem;
  font-weight: 600;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--md3-primary) 10%, transparent);
  color: var(--md3-primary);
  border: 1px solid color-mix(in srgb, var(--md3-primary) 30%, transparent);
  margin-left: 0.5rem;
  vertical-align: middle;
}

/* ─── A11y: prefers-reduced-motion (May 2026) ─────────────────────────
   Respects the OS-level reduce-motion preference for users with vestibular
   disorders or motion sensitivity (~5% of the population per OECD estimates).
   The !important chain is unavoidable here — 195+ transition/animation rules
   above this block have their own specificity, and the only practical way to
   neutralize them all is the cascade-trumping pattern recommended by WebAIM.
   Using 0.01ms rather than 0 so any JS code waiting on transitionend / animationend
   still fires, just immediately. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

.points-progress-card {
  background: var(--md3-surface-container, var(--md3-primary-95));
  border: 1px solid var(--md3-outline-variant);
  border-radius: var(--md3-shape-lg);
  padding: 1.25rem 1.4rem;
  margin-bottom: 1.5rem;
  box-shadow: var(--md3-elev-1);
}
.points-progress-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .75rem;
  flex-wrap: wrap;
  margin-bottom: .9rem;
}
.points-progress-title {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: var(--md3-title-medium-size, 1rem);
  font-weight: 700;
  color: var(--md3-on-surface);
  line-height: 1.25;
}
.points-progress-emoji {
  font-size: 1.5rem;
  line-height: 1;
}
.points-progress-points {
  font-size: var(--md3-title-large-size, 1.35rem);
  font-weight: 800;
  color: var(--md3-primary);
  letter-spacing: -0.01em;
}
.points-progress-points-unit {
  font-size: .82rem;
  font-weight: 600;
  color: var(--md3-on-surface-variant);
  margin-left: .15rem;
}
.points-progress-bar-track {
  position: relative;
  width: 100%;
  height: 14px;
  background: var(--md3-surface-variant);
  border-radius: var(--md3-shape-full);
  overflow: hidden;
  border: 1px solid var(--md3-outline-variant);
}
.points-progress-bar-fill {
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--md3-primary) 0%, var(--md3-tertiary) 100%);
  border-radius: var(--md3-shape-full);
  transition: width 700ms var(--md3-motion-emphasized);
}
.points-progress-bar-fill.is-max {
  background: var(--md3-primary);
}
.points-progress-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  flex-wrap: wrap;
  margin-top: .65rem;
  font-size: .85rem;
  color: var(--md3-on-surface-variant);
}
.points-progress-next {
  font-weight: 600;
  color: var(--md3-on-surface);
}
.points-progress-next strong {
  color: var(--md3-primary);
  font-weight: 700;
}
.points-progress-ladder {
  display: flex;
  align-items: center;
  gap: .35rem;
  flex-wrap: wrap;
  margin-top: .85rem;
  padding-top: .85rem;
  border-top: 1px dashed var(--md3-outline-variant);
}
.points-progress-tier {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  padding: .2rem .55rem;
  border-radius: var(--md3-shape-full);
  background: var(--md3-surface-variant);
  color: var(--md3-on-surface-variant);
  font-size: .72rem;
  font-weight: 600;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: background 200ms var(--md3-motion-emphasized), color 200ms var(--md3-motion-emphasized);
}
.points-progress-tier.is-current {
  background: var(--md3-primary-container);
  color: var(--md3-on-primary-container);
  border-color: var(--md3-primary);
}
.points-progress-tier.is-passed {
  background: var(--md3-primary-95);
  color: var(--md3-primary-30);
}
.points-progress-tier-sep {
  color: var(--md3-outline);
  font-size: .7rem;
  user-select: none;
}
@media (max-width: 480px) {
  .points-progress-card { padding: 1rem 1.1rem; }
  .points-progress-points { font-size: 1.15rem; }
  .points-progress-ladder { gap: .25rem; }
  .points-progress-tier { padding: .15rem .45rem; font-size: .68rem; }
}

/* ─── A11y: Windows High-Contrast / forced-colors support (May 2026) ────
   When the user is on the Windows system-level high-contrast theme (or any
   forced-colors-active environment), our gradient backgrounds + colored
   tile fills collapse to a single OS color. This block restores the OS
   palette explicitly so every interactive surface remains navigable. */
@media (forced-colors: active) {
  button, .btn, .md3-button, .tab-btn, .lb-tab, .tab, .dorm-tab-btn, .auth-tab,
  .md-segmented-btn, .qf-chip {
    forced-color-adjust: none;
    border: 1px solid ButtonText !important;
    background: ButtonFace !important;
    color: ButtonText !important;
  }
  button:focus-visible, .btn:focus-visible, .md3-button:focus-visible,
  .tab-btn:focus-visible, .lb-tab:focus-visible, .dorm-tab-btn:focus-visible,
  .auth-tab:focus-visible, .qf-chip:focus-visible, a:focus-visible {
    outline: 2px solid Highlight !important;
    outline-offset: 2px;
  }
  .md3-button.md3-button-filled, .btn-primary, .tab-btn.active, .lb-tab.active,
  .dorm-tab-btn.active, .auth-tab.active, .qf-chip.active,
  .md-segmented-btn-active {
    background: Highlight !important;
    color: HighlightText !important;
    border-color: Highlight !important;
  }
  .modal-overlay { background: Canvas !important; }
  .modal, .md3-card, .card, .dorm-card, .college-card {
    background: Canvas !important;
    color: CanvasText !important;
    border: 1px solid CanvasText !important;
  }
  /* The Brief icon strip — every tile gets a hard border so YES/NO/UNKNOWN
     states remain visually distinct in forced-colors mode where the colored
     tile fills collapse. */
  .brief-icon, .brief-sheet { border: 1px solid CanvasText !important; }
  .brief-icon.no { outline: 2px solid LinkText; }
  .brief-icon.unknown { outline: 2px dashed GrayText; }
  /* Snackbar — Window/OS-themed surface so messages stay legible. */
  .md-snackbar {
    background: Canvas !important;
    color: CanvasText !important;
    border: 1px solid CanvasText !important;
  }
  /* Skip-link gets OS-themed highlight on focus. */
  .skip-link {
    background: Canvas !important;
    color: CanvasText !important;
    border: 2px solid Highlight !important;
  }
  /* Site header / footer — explicit border so layout still parseable. */
  .site-header, .site-footer { border-bottom: 1px solid CanvasText; }
}

/* ─── A11y: visible focus outline for keyboard tabs (May 2026) ─────────
   Buttons get an indigo focus ring on keyboard focus. Mouse focus retains
   the previous look (no outline) — :focus-visible distinguishes the two
   so keyboard users don't lose orientation. */
button:focus-visible, .btn:focus-visible, .md3-button:focus-visible,
[role="tab"]:focus-visible, .tab-btn:focus-visible, .lb-tab:focus-visible,
.dorm-tab-btn:focus-visible, .auth-tab:focus-visible {
  outline: 2px solid var(--md3-primary, #6366f1);
  outline-offset: 2px;
}

.dorm-hero-more-wrap { position: relative; display: inline-block; }
.dorm-hero-more-btn[aria-expanded="true"] { background: var(--md3-secondary-container, #e0e7ff); }
.dorm-hero-more-menu {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 220px;
  background: var(--md3-surface, #ffffff);
  border: 1px solid var(--md3-outline-variant, #e5e7eb);
  border-radius: var(--md3-shape-md, 12px);
  box-shadow: var(--md3-elev-3, 0 10px 25px rgba(15, 23, 42, 0.15));
  padding: .35rem;
  z-index: 1200;
  flex-direction: column;
  gap: 2px;
}
.dorm-hero-more-menu.open { display: flex; }
.dorm-hero-more-item {
  display: flex;
  align-items: center;
  gap: .5rem;
  text-align: left;
  background: transparent;
  border: none;
  width: 100%;
  padding: .55rem .75rem;
  border-radius: var(--md3-shape-sm, 8px);
  font-size: .88rem;
  font-weight: 500;
  color: var(--md3-on-surface, #1f2937);
  cursor: pointer;
  text-decoration: none;
  font-family: inherit;
}
.dorm-hero-more-item:hover,
.dorm-hero-more-item:focus-visible {
  background: var(--md3-state-hover, rgba(99, 102, 241, 0.08));
  outline: none;
}
.dorm-hero-admin-actions {
  display: inline-flex;
  gap: .4rem;
  padding-left: .6rem;
  margin-left: .2rem;
  border-left: 1px solid var(--md3-outline-variant, #e5e7eb);
}
@media (max-width: 640px) {
  .dorm-hero-more-menu { right: auto; left: 0; min-width: 200px; }
  .dorm-hero-admin-actions { border-left: none; padding-left: 0; margin-left: 0; }
}

.dorm-mobile-distances {
  display: none;
  margin: 0.5rem 0 0.9rem;
  padding: 0.6rem 0.75rem;
  background: var(--md3-surface-1, #f8fafc);
  border: 1px solid var(--md3-outline-variant, #e5e7eb);
  border-radius: var(--md3-shape-md, 12px);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.dorm-mobile-distances::-webkit-scrollbar { display: none; }
.dorm-mobile-distances-inner {
  display: inline-flex;
  gap: .45rem;
  white-space: nowrap;
}
.dorm-mobile-distance-chip {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  background: var(--md3-surface, #ffffff);
  border: 1px solid var(--md3-outline-variant, #e5e7eb);
  border-radius: 999px;
  padding: .35rem .7rem;
  font-size: .82rem;
  font-weight: 500;
  color: var(--md3-on-surface, #1f2937);
  cursor: pointer;
  flex-shrink: 0;
  font-family: inherit;
}
.dorm-mobile-distance-chip:hover,
.dorm-mobile-distance-chip:focus-visible {
  background: var(--md3-state-hover, rgba(99,102,241,0.08));
  outline: none;
}
@media (max-width: 900px) {
  .dorm-mobile-distances:not(:empty) { display: block; }
}

/* Cold-start "be the first" panel (UX_TODO Item 3, May 2026) — replaces a
   wall of empty section placeholders with a single bright CTA when a dorm
   has zero ratings, zero photos, zero floor plans, and zero tips. */
.dorm-cold-start {
  background: linear-gradient(135deg, var(--md3-primary-container, #e0e7ff), var(--md3-secondary-container, #ede9fe));
  border: 1px solid rgba(99,102,241,0.2);
  border-radius: var(--md3-shape-lg, 16px);
  padding: 1.25rem 1.4rem;
  margin: 0.5rem 0 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.dorm-cold-start-headline {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--md3-on-primary-container, #312e81);
  line-height: 1.3;
}
.dorm-cold-start-sub {
  font-size: .88rem;
  color: var(--md3-on-primary-container, #312e81);
  opacity: .8;
  line-height: 1.45;
}
.dorm-cold-start-actions {
  display: flex;
  gap: .5rem;
  flex-wrap: wrap;
  margin-top: .35rem;
}
.dorm-cold-start-actions .btn { font-size: .85rem; padding: .45rem .9rem; }
body.cold-start-active .dorm-section-empty-state,
body.cold-start-active #dorm-tips-section,
body.cold-start-active #dorm-packing-section,
body.cold-start-active #dorm-study-spots-section,
body.cold-start-active #dorm-floor-plans-section {
  display: none !important;
}

