/* ═══════════════════════════════════════════════════════════════════════════
   Blue Belmont - Map Explorer Styles
   Enterprise-grade responsive design with mobile-first approach
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Design Tokens (shared with app.css - keep values aligned) ── */
:root {
    font-size: 1rem;
    --gold: #b5942a;
    --gold-light: #d4af37;
    --slate: #1c2331;
    --slate-light: #2a3447;
    --slate-hover: #2a3447;
    --cream: #faf8f4;
    --warm-white: #fffdf8;
    --border: #d5cfc5;
    --text: #2c2c2c;
    --muted: #6b655c;
    --faint: #8b8680;
    --bg-hover: #f0ece4;
    --border-light: #ebe6dd;
    --error: #c62828;
    --warning: #f57c00;
    --success: #2e7d32;
    --scroll-thumb: #b5a99a;
    --sidebar-w: 15rem;
    --transition: 150ms cubic-bezier(0.4, 0, 0.2, 1);
    --anim-fast: 150ms;
    --anim-normal: 250ms;
    --easing: cubic-bezier(0.4, 0, 0.2, 1);
    --font-display: 'Playfair Display', 'Playfair Display Fallback', Georgia, serif;
    --font-body: 'Source Sans 3', system-ui, -apple-system, sans-serif;
    --font-mono: 'DM Mono', 'IBM Plex Mono', monospace;
    --radius-xs: 0.125rem;
    --radius-sm: 0.25rem;
    --radius-md: 0.375rem;
    --shadow-sm: 0 0.0625rem 0.1875rem rgba(0, 0, 0, 0.06);
    --shadow-md: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.08);
    --shadow-lg: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.1);
    --shadow-gold: 0 0 0 0.1875rem rgba(181, 148, 42, 0.18);
}

/* ── Reset & Base ── */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
body {
    font-family: var(--font-body);
    color: var(--text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
body.fullscreen-app {
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
}
#app { display: flex; height: 100%; }

/* ── Focus styles (accessibility) ── */
:focus-visible {
    outline: 0.125rem solid var(--gold);
    outline-offset: 0.125rem;
}
button:focus:not(:focus-visible),
input:focus:not(:focus-visible),
select:focus:not(:focus-visible) {
    outline: none;
}

/* ── Sidebar ── */
#sidebar {
    width: var(--sidebar-w);
    height: 100%;
    background: var(--warm-white);
    border-right: 0.0625rem solid var(--border);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    overflow: hidden;
    transition: transform var(--transition), box-shadow var(--transition);
    z-index: 900;
    will-change: transform;
}
#sidebar-header {
    padding: 0.75rem;
    border-bottom: 0.0625rem solid var(--border-light);
    flex-shrink: 0;
}
.sidebar-brand {
    font-family: var(--font-display);
    font-weight: var(--weight-bold);
    font-size: 0.9375rem;
    color: var(--slate);
    display: block;
    margin-bottom: 0.5rem;
    letter-spacing: 0.02em;
}
#county-selector {
    width: 100%;
    font-family: var(--font-body);
    font-size: 0.75rem;
    padding: 0.375rem 0.5rem;
    border: 0.0625rem solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--cream);
    color: var(--text);
    cursor: pointer;
    font-weight: var(--weight-semibold);
    appearance: auto;
    -webkit-appearance: menulist;
}
#sidebar-layers {
    flex: 1;
    overflow-y: auto;
    padding: 0.75rem;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--scroll-thumb) transparent;
}
#sidebar-layers::-webkit-scrollbar { width: 0.25rem; }
#sidebar-layers::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: var(--radius-xs); }
#sidebar-layers::-webkit-scrollbar-track { background: transparent; }

/* ── Hamburger toggle (mobile) ── */
.hamburger-btn {
    display: none;
    position: absolute;
    top: 0.625rem;
    left: 0.625rem;
    z-index: 1000;
    background: rgba(255, 253, 248, 0.97);
    border: 0.0625rem solid var(--border);
    padding: 0.5rem;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
    width: 2.25rem;
    height: 2.25rem;
    align-items: center;
    justify-content: center;
    transition: background var(--transition), border-color var(--transition), box-shadow var(--transition);
    color: var(--slate);
}
.hamburger-btn:hover { background: #fff; box-shadow: var(--shadow-md); }
.hamburger-btn:focus-visible { outline: none; box-shadow: var(--shadow-gold); }
.hamburger-btn.active { background: var(--slate); color: var(--gold-light); border-color: var(--slate); }
.hamburger-icon {
    display: block;
    width: 1rem;
    height: 0.75rem;
    position: relative;
}
.hamburger-icon span,
.hamburger-icon::before,
.hamburger-icon::after {
    content: '';
    display: block;
    position: absolute;
    left: 0;
    width: 100%;
    height: 0.125rem;
    background: currentColor;
    border-radius: 0.0625rem;
    transition: background var(--transition), border-color var(--transition), box-shadow var(--transition);
}
.hamburger-icon::before { top: 0; }
.hamburger-icon span { top: 50%; transform: translateY(-50%); }
.hamburger-icon::after { bottom: 0; }
.hamburger-btn.active .hamburger-icon::before { top: 50%; transform: translateY(-50%) rotate(45deg); }
.hamburger-btn.active .hamburger-icon span { opacity: 0; }
.hamburger-btn.active .hamburger-icon::after { bottom: 50%; transform: translateY(50%) rotate(-45deg); }

/* Mobile sidebar overlay backdrop */
.sidebar-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(28, 35, 49, 0.5);
    z-index: 899;
    opacity: 0;
    transition: opacity var(--transition);
    -webkit-backdrop-filter: blur(0.125rem);
    backdrop-filter: blur(0.125rem);
}
.sidebar-overlay.visible { opacity: 1; }

/* ── Layer toggles ── */
.layer-group { margin-bottom: 0.5rem; }
.layer-group-title {
    font-family: var(--font-body);
    font-size: var(--text-2xs);
    font-weight: var(--weight-bold);
    color: var(--faint);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    margin-bottom: 0.25rem;
    padding: 0.375rem 0.25rem 0.25rem;
    border-top: 0.0625rem solid var(--border-light);
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-radius: var(--radius-sm);
    transition: color var(--transition), background var(--transition);
}
.layer-group-title:hover { color: var(--text); background: var(--bg-hover); }
.layer-group-title::after {
    content: '\25BE';
    font-size: 0.625rem;
    transition: transform var(--anim-fast) var(--easing);
    flex-shrink: 0;
}
.layer-group.is-collapsed .layer-group-title::after {
    transform: rotate(-90deg);
}
.layer-group-layers {
    overflow: hidden;
    transition: max-height var(--anim-normal) var(--easing);
    max-height: 50rem;
}
.layer-group.is-collapsed .layer-group-layers {
    max-height: 0;
}
.layer-group:first-child .layer-group-title { border-top: none; padding-top: 0.25rem; }
/* Layer count badge in group title */
.layer-group-count {
    font-size: 0.5625rem;
    font-weight: var(--weight-semibold);
    color: var(--faint);
    background: var(--bg-subtle, rgba(0,0,0,0.03));
    padding: 0.0625rem 0.3125rem;
    border-radius: 62.5rem;
    margin-left: 0.25rem;
    letter-spacing: 0;
    text-transform: none;
}
.layer-toggle {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.1875rem 0.25rem;
    font-size: var(--text-xs);
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: background var(--transition);
    user-select: none;
    -webkit-user-select: none;
}
.layer-toggle:hover { background: var(--bg-hover); }
.layer-toggle input[type=checkbox] {
    margin: 0;
    width: 0.875rem;
    height: 0.875rem;
    cursor: pointer;
    accent-color: var(--gold);
    flex-shrink: 0;
}
.layer-toggle .layer-name {
    flex: 1;
    color: var(--muted);
    transition: color var(--transition), font-weight var(--transition);
    font-weight: var(--weight-medium);
}
.layer-toggle input:checked ~ .layer-name { color: var(--text); font-weight: var(--weight-semibold); }
.layer-toggle .layer-link {
    font-size: 0.5rem;
    color: var(--gold);
    text-decoration: none;
    flex-shrink: 0;
    padding: 0.0625rem 0.25rem;
    border-radius: var(--radius-xs);
    transition: background var(--transition);
    font-weight: var(--weight-semibold);
}
.layer-toggle .layer-link:hover { text-decoration: underline; background: rgba(181, 148, 42, .08); }
.layer-swatch {
    width: 0.75rem;
    height: 0.75rem;
    border-radius: var(--radius-xs);
    flex-shrink: 0;
    border: 0.0625rem solid rgba(0, 0, 0, .12);
    opacity: 0.35;
    transition: opacity var(--transition);
}
.layer-toggle input:checked ~ .layer-swatch { opacity: 1; box-shadow: 0 0 0.1875rem rgba(0, 0, 0, .12); }

/* ── Fullscreen 3D viewer ── */
#viewer-3d-fullscreen {
    flex: 1 1 0%;
    min-width: 0;
    position: relative;
    height: 100%;
    overflow: hidden;
    background: var(--slate);
}
#viewer-3d-fullscreen.hidden { display: none; }
#viewer-3d-container { width: 100%; height: 100%; position: absolute; inset: 0; }
#viewer-3d-container canvas { width: 100% !important; height: 100% !important; }
.viewer-label {
    position: absolute;
    bottom: 0.5rem;
    left: 0.75rem;
    color: rgba(255, 255, 255, .5);
    font-size: 0.625rem;
    z-index: 2;
    pointer-events: none;
    font-family: var(--font-body);
    font-style: italic;
}
.back-btn-3d {
    position: absolute;
    top: 0.75rem;
    left: 0.75rem;
    z-index: 10;
    background: rgba(255, 253, 248, .97);
    border: 0.0625rem solid var(--border);
    padding: 0.5rem 1.125rem;
    border-radius: var(--radius-sm);
    font-size: 0.75rem;
    font-weight: var(--weight-semibold);
    cursor: pointer;
    color: var(--slate);
    box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, .2);
    transition: background var(--transition), border-color var(--transition), box-shadow var(--transition);
    font-family: var(--font-body);
    letter-spacing: 0.02em;
}
.back-btn-3d:focus-visible { outline: none; box-shadow: var(--shadow-gold); }
.back-btn-3d:hover { background: #fff; box-shadow: 0 0.125rem 0.75rem rgba(0, 0, 0, .3); }

/* ── Badges ── */
/* The canonical .badge definition lives in app.css. Map-only pages that
   load style.css without app.css still need these jurisdiction variants. */
.badge-inside_town { background: #e3f2fd; color: #1565c0; border: 0.0625rem solid #bbdefb; }
.badge-unincorporated { background: #f3e5f5; color: #6a1b9a; border: 0.0625rem solid #e1bee7; }

/* ── Map ── */
#map-container {
    flex: 1 1 0%;
    min-width: 0;
    position: relative;
    height: 100%;
    overflow: hidden;
}
#map { width: 100%; height: 100%; position: absolute; inset: 0; }
.map-overlay {
    position: absolute;
    top: 0.625rem;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(255, 253, 248, .97);
    padding: 0.375rem 1rem;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
    font-size: var(--text-xs);
    color: var(--muted);
    z-index: 800;
    font-weight: var(--weight-medium);
    font-family: var(--font-body);
    border: 0.0625rem solid rgba(213, 207, 197, .5);
    max-width: calc(100% - 2rem);
    text-align: center;
}
.map-overlay.hidden { display: none; }
.map-overlay-bottom {
    position: absolute;
    bottom: 1.25rem;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(255, 253, 248, .95);
    padding: 0.25rem 0.875rem;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
    font-size: 0.625rem;
    color: var(--muted);
    z-index: 800;
    font-weight: var(--weight-medium);
    font-family: var(--font-body);
    border: 0.0625rem solid rgba(213, 207, 197, .3);
    white-space: nowrap;
}
/* Hide the chip entirely when there's no text - otherwise the empty
   element still renders as a tiny styled pill (background + border +
   shadow) before the count API resolves, looking like a stray white
   box at bottom-center. */
.map-overlay-bottom:empty { display: none; }

/* "Zoom in to see properties" - floats CENTER of the map (not top
   corner) so the user can't miss it. Big, gold accent, prominent.
   The user scrolled out and the parcels disappeared because the
   tiles drop low-zoom features to save bandwidth - this is the only
   feedback that tells them what to do about it. Animated pulse so
   it draws attention without screaming. Auto-hides at zoom 10+. */
.map-parcel-cap-banner {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.5rem;
    background: linear-gradient(180deg, #1c2331 0%, #2a3447 100%);
    color: #ffffff;
    padding: 1.5rem 2.25rem;
    border-radius: 1rem;
    box-shadow:
        0 1rem 2.5rem rgba(28, 35, 49, 0.45),
        0 0 0 0.0625rem rgba(212, 175, 55, 0.6),
        0 0 2rem rgba(212, 175, 55, 0.18);
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.005em;
    z-index: 850;
    border: 0.0625rem solid rgba(212, 175, 55, 0.6);
    pointer-events: none;
    transition: opacity 200ms ease, transform 200ms ease;
    max-width: min(28rem, calc(100% - 2rem));
    font-family: var(--font-body);
    animation: bb-zoom-banner-pulse 2.4s ease-in-out infinite;
}
.map-parcel-cap-banner strong {
    font-family: var(--font-display, Georgia), serif;
    font-size: 1.25rem;
    font-weight: 700;
    color: #f5e9b5;
    letter-spacing: -0.005em;
}
.map-parcel-cap-banner .cap-sub {
    display: block;
    font-size: 0.8125rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.78);
    letter-spacing: 0.01em;
    margin-top: 0.25rem;
}
.map-parcel-cap-banner .cap-icon,
.map-parcel-cap-banner .cap-spinner {
    color: #d4af37;
    flex-shrink: 0;
    width: 1.75rem;
    height: 1.75rem;
}
/* Spinner - gold ring that rotates; only shown while the banner is in
   its loading state (parcels haven't propagated yet). */
.map-parcel-cap-banner .cap-spinner {
    display: none;
    border: 0.1875rem solid rgba(212, 175, 55, 0.22);
    border-top-color: #d4af37;
    border-radius: 50%;
    box-sizing: border-box;
    animation: bb-zoom-banner-spin 0.9s linear infinite;
}
.map-parcel-cap-banner.loading .cap-icon { display: none; }
.map-parcel-cap-banner.loading .cap-spinner { display: inline-block; }
/* Pause the pulsing glow while in loading mode - the spinner already
   conveys activity, the double animation reads as visual noise. */
.map-parcel-cap-banner.loading { animation: none; }
@keyframes bb-zoom-banner-spin {
    to { transform: rotate(360deg); }
}
.map-parcel-cap-banner.hidden {
    opacity: 0;
    transform: translate(-50%, calc(-50% - 0.5rem));
    pointer-events: none;
    visibility: hidden;
    transition: opacity 200ms ease, transform 200ms ease, visibility 0s linear 200ms;
}
@keyframes bb-zoom-banner-pulse {
    0%, 100% { box-shadow: 0 1rem 2.5rem rgba(28, 35, 49, 0.45), 0 0 0 0.0625rem rgba(212, 175, 55, 0.6), 0 0 2rem rgba(212, 175, 55, 0.18); }
    50%      { box-shadow: 0 1rem 2.5rem rgba(28, 35, 49, 0.45), 0 0 0 0.0625rem rgba(212, 175, 55, 0.85), 0 0 3rem rgba(212, 175, 55, 0.32); }
}
@media (max-width: 48em) {
    .map-parcel-cap-banner {
        padding: 1.25rem 1.5rem;
        max-width: calc(100% - 1.5rem);
    }
    .map-parcel-cap-banner strong { font-size: 1.0625rem; }
    .map-parcel-cap-banner .cap-sub { font-size: 0.75rem; }
}

/* ── Scale controls ── */
.maplibregl-ctrl-scale {
    background: rgba(255, 253, 248, .9);
    border: 0.0625rem solid var(--muted);
    border-top: none;
    font-size: 0.625rem;
    font-weight: var(--weight-semibold);
    font-family: var(--font-mono);
    padding: 0.0625rem 0.375rem;
    line-height: 1.4;
    color: var(--muted);
}

/* ── Attribution ── */
.maplibregl-ctrl-attrib {
    background: rgba(255, 253, 248, .85) !important;
    font-family: var(--font-body);
    font-size: 0.625rem;
    color: var(--muted);
    padding: 0.125rem 0.5rem;
}
.maplibregl-ctrl-attrib a { color: var(--muted); text-decoration: none; }

/* ── Map control buttons ── */
.map-btn {
    position: absolute;
    top: 0.625rem;
    right: 3.125rem;
    z-index: 800;
    background: rgba(255, 253, 248, .97);
    border: 0.0625rem solid var(--border);
    padding: 0.4375rem 1rem;
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
    font-size: var(--text-xs);
    cursor: pointer;
    font-weight: var(--weight-bold);
    transition: background 0.3s, color 0.3s;
    font-family: var(--font-body);
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    white-space: nowrap;
}
.btn-pos-2 { right: 10rem; }
.map-btn:hover {
    background: #fff;
    box-shadow: var(--shadow-md);
    border-color: var(--gold);
    color: var(--text);
}
.map-btn:focus-visible { outline: none; box-shadow: var(--shadow-gold); }
.map-btn.active {
    background: var(--slate);
    color: var(--gold-light);
    border-color: var(--slate);
    box-shadow: 0 0.125rem 0.5rem rgba(28, 35, 49, .3);
}

/* ── Parcel-map top-left chrome (back arrow + county selector) ── */
.map-top-left {
    position: absolute;
    top: 0.75rem;
    left: 0.75rem;
    z-index: 810;
    display: flex;
    align-items: stretch;
    gap: 0.5rem;
    max-width: calc(100vw - 1.5rem);
    /* Slide right when the (now LEFT-anchored) property info panel
       opens, so the back arrow + county selector stay visible on the
       map portion to the right of the panel instead of being hidden
       behind it. Matches the panel's own .25s transform-transition. */
    transition: left 0.25s ease;
}
/* Panel width is `min(22rem, calc(100vw - 1rem))`; nudge the top-left
   chrome to clear it plus a 0.5rem breather. */
#map-container:has(#property-info-panel.is-open) .map-top-left {
    left: calc(min(22rem, 100vw - 1rem) + 0.5rem);
}
/* MapLibre's bottom-left scale control sits in .maplibregl-ctrl-bottom-left;
   slide it right by the same offset so the scale stays on the visible
   map portion instead of being hidden behind the panel. */
#map-container:has(#property-info-panel.is-open) .maplibregl-ctrl-bottom-left {
    left: calc(min(22rem, 100vw - 1rem) + 0.5rem);
    transition: left 0.25s ease;
}
.maplibregl-ctrl-bottom-left { transition: left 0.25s ease; }
@media (max-width: 64em) {
    /* Property info panel is hidden at this breakpoint via
       #property-info-panel { display: none } - reset the dodge so the
       top-left chrome doesn't sit shifted into nothing. */
    #map-container:has(#property-info-panel.is-open) .map-top-left,
    #map-container:has(#property-info-panel.is-open) .maplibregl-ctrl-bottom-left {
        left: 0.75rem;
    }
}
.map-back-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    border: 0.0625rem solid var(--border);
    background: rgba(255, 253, 248, 0.97);
    color: var(--slate);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition), box-shadow var(--transition), color var(--transition);
}
.map-back-btn:hover { background: #fff; border-color: var(--gold); box-shadow: var(--shadow-md); }
.map-back-btn:focus-visible { outline: none; box-shadow: var(--shadow-gold); }
.map-back-btn svg { width: 1rem; height: 1rem; display: block; }

.map-county-select {
    appearance: none;
    -webkit-appearance: none;
    height: 2.25rem;
    min-width: min(14rem, calc(100vw - 6rem));
    max-width: min(18rem, calc(100vw - 6rem));
    padding: 0 2rem 0 0.75rem;
    font-family: var(--font-body);
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    color: var(--slate);
    background: rgba(255, 253, 248, 0.97)
        url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%231c2331' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E")
        no-repeat right 0.625rem center;
    background-size: 0.75rem;
    border: 0.0625rem solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
    letter-spacing: 0.02em;
    text-overflow: ellipsis;
    transition: background-color var(--transition), border-color var(--transition), box-shadow var(--transition);
}
.map-county-select:hover { border-color: var(--gold); }
.map-county-select:focus-visible { outline: none; box-shadow: var(--shadow-gold); }

/* ── Parcel-map layer-toggle rail (Topo / Aerial / Street view) ──
   Anchored to the MAP only - never overlaps the property summary
   panel, the county selector, or any other chrome. Reflows through
   four progressively tighter configurations as the viewport shrinks
   (top-right horizontal row → top-right below zoom controls → bottom-
   right horizontal row → bottom-right vertical stack). When the
   property panel slides open on tablet+, the rail shifts left so it
   stays on the visible portion of the map. */
.map-controls-rail {
    position: absolute;
    top: 0.75rem;
    right: 3.25rem;
    /* Above maplibre nav (z 800) and the popup (z 850), below the
       property info panel (z 900) so the panel slides over the rail
       on phones where they share screen real-estate. */
    z-index: 860;
    display: flex;
    align-items: center;
    gap: clamp(0.375rem, 1.2vw, 0.875rem);
    /* Reserve horizontal room for the NavigationControl on the right
       and the back-button + county-selector on the left. flex-wrap
       lets the rail drop to a second row instead of colliding. */
    max-width: calc(100% - 17rem);
    flex-wrap: wrap;
    justify-content: flex-end;
    /* Smoothly slide left when the property info panel opens so the
       buttons stay on the visible map portion to the left of the panel
       instead of vanishing behind it. Matches the panel's own .25s
       transform-transition so they move in lockstep. */
    transition: right 0.25s ease, top 0.25s ease, bottom 0.25s ease;
}
/* Property info panel is now anchored to the LEFT edge of the map, so
   the basemap rail (right side) no longer needs to dodge - the rail
   simply holds its position regardless of panel state. */
/* Below 56em - the top-right corner runs out of room because the
   county selector + back button on the left grow proportionally. Drop
   the rail below the NavigationControl (zoom + compass stack is
   ~5.8rem tall + 0.625rem top offset → ~6.5rem). top: 7.75rem leaves
   a clean ~1rem gap between the bottom of the zoom controls and the
   top of the basemap rail. */
@media (max-width: 56em) {
    .map-controls-rail {
        top: 7.75rem;
        right: 0.625rem;
        max-width: calc(100% - 1.25rem);
    }
}
/* Phones (≤30em) - anchor to the BOTTOM-right of the map, well clear
   of the zoom controls (top) and the parcel-count overlay (bottom-
   left). Buttons wrap right-aligned. */
@media (max-width: 30em) {
    .map-controls-rail {
        top: auto;
        bottom: calc(2.5rem + env(safe-area-inset-bottom, 0rem));
        right: 0.625rem;
        left: auto;
        max-width: calc(100% - 1.25rem);
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: flex-end;
        gap: 0.375rem;
    }
}
/* When a parcel popup is open on a phone, the popup's bottom action
   row (View Full Report) lands exactly where the bottom-anchored
   basemap rail sits - they collide visually. Hide the rail while a
   popup is showing so the user can read & dismiss the popup without
   the Topo / Aerial / Street View pills bleeding through. Closing the
   popup brings the rail back. Scoped to phones since the rail lives
   at the top on wider viewports and there's no collision. */
@media (max-width: 30em) {
    #map-container:has(.maplibregl-popup) .map-controls-rail {
        opacity: 0;
        pointer-events: none;
        visibility: hidden;
    }
}
.map-controls-rail .map-btn {
    position: static;
    top: auto;
    right: auto;
    flex: 0 0 auto;
}

/* Property info panel - slide-in summary on the right side of the map.
   On tablets/phones the panel would consume the entire viewport (covering
   the map you're trying to inspect) AND collides with the basemap rail
   (Topo / Aerial / Street view buttons), so we suppress it below 64em.
   The popup that opens at the same time carries enough field-level info
   for narrow screens; users who need the full summary can tap "View
   Details" / "View Full Report" to navigate to the dedicated property
   page. The !important guarantees inline transform on #property-info-panel
   (set by _showInfoPanel) can't override the hide. */
@media (max-width: 64em) {
    #property-info-panel {
        display: none !important;
        visibility: hidden !important;
        pointer-events: none !important;
    }
}

/* ── Street View prompt banner (appears when streetview mode is active) ── */
.map-streetview-prompt {
    position: absolute;
    top: 3.75rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 820;
    padding: 0.5rem 1rem;
    background: var(--slate);
    color: var(--gold-light);
    border-radius: 62.5rem;
    font-size: var(--text-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: 0.02em;
    box-shadow: 0 0.25rem 0.75rem rgba(28, 35, 49, 0.28);
    white-space: nowrap;
    max-width: calc(100vw - 2rem);
    text-align: center;
    pointer-events: none;
}
.map-streetview-prompt.hidden { display: none; }

/* ── Topo: elevation legend + sun compass (ground-level view) ── */
.map-elevation-legend {
    position: absolute;
    bottom: 2.75rem;
    right: 0.625rem;
    z-index: 5;
    background: rgba(255, 255, 255, 0.94);
    border-radius: 0.5rem;
    padding: 0.625rem 0.75rem;
    font-size: 0.6875rem;
    box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.3);
    pointer-events: auto;
    line-height: 1.4;
    font-family: var(--font-body);
    color: var(--text);
}

#sun-control {
    position: absolute;
    bottom: 3.75rem;
    left: 0.625rem;
    z-index: 800;
    background: rgba(255, 253, 248, 0.94);
    border-radius: 0.25rem;
    padding: 0.25rem 0.375rem 0.125rem;
    box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.2);
    text-align: center;
    width: 5.5rem;
}
#sun-control.hidden { display: none; }
#sun-svg {
    width: 5rem;
    height: 5rem;
    display: block;
    margin: 0 auto;
    cursor: grab;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
}
#sun-svg:active { cursor: grabbing; }
.sun-label {
    font-family: var(--font-mono);
    font-size: 0.4375rem;
    color: var(--muted);
    margin-top: 0.0625rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

/* ── Popups ── */
.maplibregl-popup { pointer-events: none; z-index: 850; }
.maplibregl-popup-content {
    pointer-events: auto;
    font-family: var(--font-body);
    position: relative;  /* anchors the absolutely-positioned close button */
    /* Type + line-height + padding all scale with viewport so the popup
       compresses on small screens INSTEAD of forcing an internal
       scroll. With ~20 rows of content the popup can easily exceed a
       short laptop's viewport - clamp() shrinks the type just enough
       to fit, rather than clipping or scrolling. The vw component lets
       a 360 px iPhone render the popup at ~9 px text and still fit
       every field; a 1440 px laptop clamps to 13 px. */
    font-size: clamp(0.5625rem, 1.6vw, 0.8125rem);
    line-height: 1.25;
    min-width: clamp(10rem, 30vw, 15.5rem);
    /* Width adapts to viewport; never wider than the screen minus a
       small breather. On phones the breather is tighter so the popup
       can use as much horizontal room as possible (more characters per
       line = fewer rows = no scroll). */
    max-width: min(30rem, calc(100vw - 1rem));
    /* Auto-size to content. NO max-height + NO overflow-y:auto - the
       user requested zero internal scrolling. If the popup is taller
       than the viewport, the responsive font/padding above keep it
       compressed; in the extreme case maplibre repositions the popup
       above/below the parcel so it stays in frame. */
    max-height: none;
    height: auto;
    overflow: visible;
    border-radius: var(--radius-md) !important;
    box-shadow: 0 0.25rem 1.25rem rgba(0, 0, 0, .15) !important;
    border: 0.0625rem solid var(--border);
    background: var(--warm-white);
    padding: clamp(0.35rem, 1.2vw, 0.875rem) clamp(0.45rem, 1.4vw, 1rem) !important;
}
/* iPhone-class viewports: lay the popup out in a TWO-COLUMN grid so the
   ~14 label/value rows pack into ~7 visual rows. Title, dividers, and
   action buttons span the full row. Without this the popup stretches
   past the bottom of the viewport and collides with the basemap rail
   (Topo/Aerial/Street view) - and the user can't dismiss either one
   without scrolling. */
@media (max-width: 30em) {
    .maplibregl-popup-content {
        font-size: clamp(0.5rem, 2.4vw, 0.6875rem) !important;
        line-height: 1.15 !important;
        padding: 0.4rem 0.55rem 0.4rem 0.55rem !important;
        max-width: calc(100vw - 0.75rem) !important;
        display: grid !important;
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
        column-gap: 0.5rem !important;
        row-gap: 0 !important;
    }
    .maplibregl-popup-content > .popup-title,
    .maplibregl-popup-content > .popup-divider,
    .maplibregl-popup-content > .popup-actions,
    .maplibregl-popup-content > #assessed-values {
        grid-column: 1 / -1 !important;
    }
    /* Stack label above value inside each cell so a 50%-width column
       fits both without truncation. Tight line-heights and 0 padding
       keep each "row" to ~1.2rem tall. */
    .maplibregl-popup-content .popup-row {
        flex-direction: column !important;
        align-items: flex-start !important;
        justify-content: flex-start !important;
        gap: 0 !important;
        padding: 0.05rem 0 !important;
        min-height: 0 !important;
    }
    .maplibregl-popup-content .popup-label {
        font-size: 0.55rem !important;
        line-height: 1.1 !important;
    }
    .maplibregl-popup-content .popup-value {
        text-align: left !important;
        font-size: 0.65rem !important;
        line-height: 1.1 !important;
        max-width: 100% !important;
        white-space: normal !important;
        word-break: break-word !important;
    }
    /* #assessed-values is a wrapper around 4 popup-rows - let it
       become a sub-grid so its rows merge cleanly with the outer
       2-col layout. */
    .maplibregl-popup-content > #assessed-values {
        display: grid !important;
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
        column-gap: 0.5rem !important;
        row-gap: 0 !important;
    }
    .maplibregl-popup-content .popup-title {
        font-size: 0.78rem !important;
        margin-bottom: 0.15rem !important;
        padding-bottom: 0.15rem !important;
        padding-right: 1.6rem !important; /* room for the red X */
    }
    .maplibregl-popup-content .popup-divider {
        margin: 0.1rem 0 !important;
    }
    .maplibregl-popup-content .popup-actions {
        margin-top: 0.25rem !important;
        padding-top: 0.25rem !important;
    }
    .maplibregl-popup-content .popup-action-btn {
        min-height: 1.65rem !important;
        font-size: 0.6rem !important;
        padding: 0.2rem 0.4rem !important;
    }
}
.maplibregl-popup-tip { pointer-events: none; }
.maplibregl-popup-tip { border-top-color: var(--warm-white) !important; }

/* Popup X close button - a clear "red letter X on a white bubble".
   Subtler than a solid-red disc but still impossible to miss thanks to
   the red glyph against the warm-white popup chrome. Top-right of the
   popup with enough offset that it never overlaps the title text. */
.maplibregl-popup-close-button {
    position: absolute !important;
    top: 0.25rem !important;
    right: 0.25rem !important;
    width: 1.5rem !important;
    height: 1.5rem !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 0 !important;
    margin: 0 !important;
    background: #ffffff !important;
    color: #c0392b !important;
    border: 0.0625rem solid #c0392b !important;
    border-radius: 50% !important;
    font-family: var(--font-body, sans-serif) !important;
    font-size: 1rem !important;
    font-weight: 700 !important;
    line-height: 1 !important;
    text-align: center !important;
    cursor: pointer !important;
    box-shadow: 0 0.0625rem 0.1875rem rgba(0, 0, 0, 0.15) !important;
    z-index: 1 !important;
    transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease !important;
    -webkit-tap-highlight-color: transparent !important;
}
.maplibregl-popup-close-button:hover {
    background: #fef2f0 !important;
    color: #962d22 !important;
    border-color: #962d22 !important;
}
.maplibregl-popup-close-button:focus-visible {
    outline: 0.125rem solid var(--gold, #b5942a) !important;
    outline-offset: 0.125rem !important;
}
/* Larger tap target on touch devices */
@media (pointer: coarse) {
    .maplibregl-popup-close-button {
        width: 1.75rem !important;
        height: 1.75rem !important;
        font-size: 1.125rem !important;
    }
}

.popup-title {
    font-family: var(--font-display);
    font-weight: var(--weight-bold);
    font-size: var(--text-sm);
    margin-bottom: 0.25rem;
    color: var(--slate);
    padding-bottom: 0.1875rem;
    /* Reserve right-side space for the red X close button so the
       title text never slides underneath it. */
    padding-right: 1.75rem;
    border-bottom: 0.0625rem solid var(--border-light);
    line-height: 1.2;
}
.popup-row {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    /* Cut per-row padding in half - 18 rows × 6 px instead of 18 × 3 px
       reclaims ~54 px of vertical space so every field fits without
       scrolling on a typical laptop. */
    padding: 0.0625rem 0;
    min-height: 1.15rem;
}
.popup-label {
    color: var(--muted);
    font-size: 0.625rem;
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    flex-shrink: 0;
}
.popup-value {
    font-family: var(--font-mono);
    font-weight: var(--weight-medium);
    color: var(--text);
    font-size: 0.6563rem;
    text-align: right;
    word-break: break-word;
}
.popup-divider {
    height: 0.0625rem;
    background: var(--border-light, #ebe6dd);
    margin: 0.15rem 0;
}

/* ── Loading Spinner ── */
.map-loading {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 810;
    display: none;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    pointer-events: none;
}
.map-loading.visible { display: flex; }
.map-loading-spinner {
    width: 2rem;
    height: 2rem;
    border: 0.125rem solid var(--border-light);
    border-top-color: var(--gold);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}
.map-loading-text {
    font-size: var(--text-xs);
    color: var(--muted);
    font-weight: var(--weight-medium);
    background: rgba(255, 253, 248, 0.9);
    padding: 0.25rem 0.75rem;
    border-radius: var(--radius-sm);
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Toast notifications are defined in app.css - keeping one source of
   truth so variant backgrounds don't get overridden back to transparent. */

/* ── Empty / Error States ── */
.state-message {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 2rem;
    text-align: center;
    color: var(--muted);
}
.state-message-icon { font-size: 2rem; opacity: 0.3; }
.state-message-text { font-size: 0.75rem; line-height: 1.5; max-width: 20rem; }

/* ═══════════════════════════════════════════════════════════════════════════
   Responsive Breakpoints
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Large desktop (>80rem / 80rem) - default ── */

/* ── Desktop (<=80em) ── */
@media (max-width: 80em) {
    :root { --sidebar-w: 15rem; }
}

/* ── Tablet (<=64em) ── */
@media (max-width: 64em) {
    :root { font-size: 0.9375rem; --sidebar-w: 14rem; }
}

/* ── Small tablet / large phone (<=48em) - sidebar becomes drawer ── */
@media (max-width: 48em) {
    :root { font-size: 0.875rem; --sidebar-w: 18rem; }

    .hamburger-btn { display: flex; }

    #sidebar {
        position: fixed;
        top: 0;
        left: 0;
        height: 100%;
        transform: translateX(-100%);
        box-shadow: none;
    }
    #sidebar.open {
        transform: translateX(0);
        box-shadow: 0.5rem 0 2rem rgba(0, 0, 0, 0.15);
    }
    .sidebar-overlay.visible { display: block; }

    #map-container { width: 100%; }

    .map-btn {
        padding: 0.375rem 0.625rem;
        font-size: 0.625rem;
    }
    .map-btn { right: 2rem; top: 0.625rem; }
    .btn-pos-2 { right: 7.5rem; }

    /* Rail lives at bottom-right at every viewport size now (see the
       default rule above). Tighten the gap on phones so 3 buttons still
       fit on a single row at ~360px. */
    .map-controls-rail {
        gap: 0.375rem;
    }

    .map-overlay { top: 3.25rem; font-size: 0.625rem; padding: 0.25rem 0.75rem; }
}

/* ── Phone (<=30em, bp-xs) ── */
@media (max-width: 30em) {
    :root { font-size: 0.8125rem; --sidebar-w: 85vw; }

    .map-btn { padding: 0.3125rem 0.5rem; font-size: var(--text-2xs); }
    .map-btn { right: 1.5rem; }
    .btn-pos-2 { right: 6rem; }

    .map-overlay-bottom { font-size: var(--text-2xs); padding: 0.1875rem 0.625rem; }

    /* Popup font sizing - `.maplibregl-popup-content` already uses
       clamp() so it scales fluidly; only the inner field type needs
       a phone-tier override since the labels/values are siblings of
       the popup content, not children of font-inheriting elements. */
    .popup-title { font-size: 0.75rem; }
    .popup-label { font-size: var(--text-2xs); }
    .popup-value { font-size: 0.625rem; }

    .back-btn-3d { padding: 0.375rem 0.75rem; font-size: var(--text-xs); }
}

/* ── Micro phone (<=22.5em, bp-2xs) - merged from the old 20em tier
      so the map respects the same floor as the rest of the system. ── */
@media (max-width: 22.5em) {
    :root { font-size: 0.75rem; --sidebar-w: 90vw; }
    .map-btn { padding: 0.25rem 0.375rem; font-size: 0.5rem; }
}

/* ── Landscape phone ── */
@media (max-height: 30em) and (orientation: landscape) {
    .map-overlay-bottom { bottom: 0.5rem; }
    .maplibregl-ctrl-scale { font-size: var(--text-2xs); }
}

/* ── High DPI adjustments ── */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
    .layer-swatch { border-width: 0.0312rem; }
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* ── Print ── */
@media print {
    #sidebar, .hamburger-btn, .map-btn, .map-overlay, .map-overlay-bottom,
    .maplibregl-ctrl-scale, .maplibregl-ctrl-attrib, .toast-container { display: none !important; }
    #map-container { position: static; width: 100%; height: 100vh; }
}
