/* ============================================================
   RESPONSIVE — shared across all pages, loaded after page CSS
   so these rules can override page-specific desktop styles.
   ============================================================ */

/* Prevent any element from forcing horizontal scroll on the page. */
html, body { max-width: 100%; overflow-x: hidden; }
img, video, svg { max-width: 100%; height: auto; }
/* Leaflet (neighborhoods.html map) manages its own 256px tile images
   with absolute positioning — the rule above shrinks them to whatever
   narrow containing block Leaflet's transform panes resolve to,
   scrambling the tile grid. This is a well-known Leaflet conflict;
   exempt its images from the global img reset. */
.leaflet-container img { max-width: none !important; height: auto; }

/* Every section across every page uses the same 52px side-gutter
   convention (now var(--mobile-gutter, 52px) in the source CSS files).
   Shrinking this one variable on mobile/tablet reduces cramped padding
   everywhere at once without touching any top/bottom spacing. */
@media (max-width: 860px) {
  :root { --mobile-gutter: 20px; }
}

/* --- Mobile nav toggle (hamburger) --- */
.nav-toggle {
  display: none;
  background: none;
  border: none;
  padding: 8px;
  cursor: pointer;
  z-index: 200;
  margin-left: auto;
}
.nav-toggle span {
  display: block;
  width: 22px;
  height: 2px;
  background: #262626;
  margin: 5px 0;
  transition: transform .2s, opacity .2s;
}
.nav-toggle.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.nav-mobile-panel { display: none; }

@media (max-width: 860px) {
  nav { padding: 0 20px; }

  .nav-toggle { display: block; }

  .nav-links,
  .nav-cta { display: none !important; }

  /* Mobile dropdown panel, replaces desktop nav-links/dropdown/cta */
  .nav-mobile-panel {
    position: fixed;
    top: 66px; left: 0; right: 0;
    background: #fff;
    border-bottom: 1px solid #D0D0CE;
    box-shadow: 0 12px 24px rgba(0,0,0,0.10);
    max-height: calc(100vh - 66px);
    overflow-y: auto;
    z-index: 150;
    -webkit-overflow-scrolling: touch;
  }
  .nav-mobile-panel.open { display: block; }
  .nav-mobile-panel a {
    display: block;
    padding: 16px 24px;
    font-size: 15px;
    font-weight: 500;
    color: #262626;
    text-decoration: none;
    border-bottom: 1px solid #F0F0EE;
    opacity: 1;
  }
  .nav-mobile-panel a.active { color: #3A6B2A; font-weight: 600; }
  .nav-mobile-panel .nav-mobile-section-label {
    padding: 16px 24px 6px;
    font-size: 11px;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: #808080;
  }
  .nav-mobile-panel .nav-mobile-cta {
    display: block;
    margin: 18px 24px 22px;
    text-align: center;
    padding: 13px 22px;
    border-radius: 100px;
    background: #262626;
    color: #fff !important;
    font-weight: 600;
    border-bottom: none;
  }
}

/* --- Testimonial carousel: fixed-width JS slider doesn't work on
   mobile viewports (cards are wider than the screen and auto-advance
   scrolls them off-screen). Replace with native swipeable scroll.
   .carousel-wrapper is a direct child of .testimonials-section, which
   has no horizontal padding of its own (unlike most other sections'
   "-inner" wrapper) — so the usual "negative margin to bleed full
   width, then re-pad" trick had nothing to cancel and just pushed the
   cards flush against the true viewport edge. Padding alone is enough
   here. --- */
@media (max-width: 860px) {
  .carousel-wrapper {
    padding: 0 20px 24px;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }
  .carousel-track {
    transform: none !important;
    scroll-snap-type: x mandatory;
  }
  .tcard {
    min-width: 82vw !important;
    max-width: 82vw !important;
    scroll-snap-align: start;
  }
  .carousel-btn,
  .carousel-dots {
    display: none !important;
  }
  /* The progress bar is driven by a JS timer that moves .carousel-track
     via transform — blocked above by transform:none since real
     scrolling now handles movement. The timer still runs and still
     resizes the bar every 5s, completely disconnected from actual
     scroll position (looks like it's "auto-scrolling" on its own).
     Hide it rather than leaving a fake/wrong progress indicator. */
  .carousel-progress {
    display: none !important;
  }
}

/* --- Collapse two/three/four-column grid layouts to a single column.
   These grids use fixed pixel columns (e.g. "1fr 480px") or repeat(3/4,1fr)
   with no responsive fallback, so their columns can't shrink below content
   width and the whole row overflows and gets clipped. Small icon+text grids
   (48px 1fr, 44px 1fr) are left alone — those never overflow. --- */
@media (max-width: 860px) {
  .hero-inner,
  .about-inner,
  .guide-inner,
  .buyer-header,
  .buyer-grid,
  .tcard-grid,
  .contact-inner,
  .form-row,
  .intro-inner,
  .services-primary-grid,
  .also-inner,
  .process-layout,
  .market-inner,
  .youtube-inner,
  .concierge-inner,
  .vendor-cta-module,
  .vendor-grid,
  .values-grid,
  .abr-strip,
  .desig-strip {
    grid-template-columns: minmax(0, 1fr) !important;
  }
  /* Vertical divider lines make no sense as their own stacked row. */
  .abr-strip-divider,
  .desig-divider {
    display: none !important;
  }
  /* Catch-all: a few grids are set via inline style="grid-template-columns:..."
     rather than a class (e.g. the "Why are you selling?" cards on sell.html),
     so they aren't reachable by class selectors above. */
  [style*="grid-template-columns"] {
    grid-template-columns: minmax(0, 1fr) !important;
  }
}

/* --- Homepage "process" section: .process-left is a sticky sidebar
   (position:sticky) meant to stay pinned in view while .process-right's
   numbered steps scroll past it beside it, on desktop's two-column
   layout. .process-right also has padding-top:40vh, deliberate empty
   scroll-runway so the sticky sidebar's own content stays fully visible
   before the first step appears. Once collapsed to a single mobile
   column neither makes sense: the sidebar stays stuck on screen for the
   entire ~2700px scroll-through (overlapping whatever comes after it),
   and the 40vh becomes a plain dead gap. Turn it into a normal stacked
   section instead. (buy.html/sell.html use a different, unaffected
   pattern — this is homepage-only.) --- */
@media (max-width: 860px) {
  .process-left {
    position: static;
    padding-top: 40px;
    padding-bottom: 40px;
  }
  .process-right {
    padding-top: 40px;
  }
}

/* --- Quote/fade carousel (buy.html, sell.html): the opacity-crossfade
   JS can get its active/inactive state out of sync (observed a slide
   marked "active" sitting at opacity:0 while another stayed at
   opacity:1). Sidestep it entirely on mobile — show all quotes
   stacked as a simple list instead of a one-at-a-time fader. --- */
@media (max-width: 860px) {
  .carousel-slide {
    position: static !important;
    opacity: 1 !important;
    pointer-events: auto !important;
    margin-bottom: 32px;
  }
  .carousel-slide:last-child { margin-bottom: 0; }
  .carousel-dots { display: none !important; }
}

/* --- Neighborhood map + filter sidebar (neighborhoods.html): a flex ROW
   with a fixed-width (260px) sidebar that has flex-shrink:0 and only
   constrains vertical overflow. Its filter pills spill out sideways past
   260px and get clipped by the page's overflow-x:hidden. Stack instead. --- */
@media (max-width: 860px) {
  .denver-map-row {
    flex-direction: column;
    height: auto;
  }
  .denver-finder-col {
    width: 100%;
    border-right: none;
    border-bottom: 1px solid var(--rule, #D0D0CE);
  }
  .denver-map-wrap {
    flex: none;
    height: auto;
    aspect-ratio: 5 / 4;
  }
  /* The overlay used to be a right-side panel, then an absolutely-
     positioned bottom sheet with its own max-height + overflow-y:auto.
     That trapped touch-scroll: dragging on the card scrolled its own
     tiny internal box (and hit a dead stop at its scroll limits)
     instead of scrolling the page. Make it a normal in-flow block
     that sits right after the map instead of floating on top of it —
     the map stays fully visible above it (still nothing covered),
     and any overflow content just continues the page's own scroll,
     the same as every other section on the site. */
  .denver-map-overlay {
    position: static;
    width: auto;
    max-height: none;
    overflow: visible;
    border-left: none;
    border-top: 1px solid var(--rule, #D0D0CE);
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -6px 20px rgba(20, 28, 18, 0.12);
  }
  .nb-default {
    flex-direction: row;
    justify-content: center;
    gap: 12px;
    padding: 14px 20px;
    height: auto;
    text-align: left;
  }
  .nb-default svg { margin-bottom: 0; width: 22px; height: 22px; flex-shrink: 0; }
}

/* --- General responsive layout fixes, mobile + tablet --- */
@media (max-width: 900px) {
  .footer-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
  }
  .footer-links { justify-content: flex-start; }
}

@media (max-width: 640px) {
  footer { padding: 32px 20px; }
}

/* --- Homepage hero: headline font-size (62px) was set for desktop's
   680px-wide measure and never scaled down, wrapping into oversized
   single/double-word lines on mobile. Scale smoothly with viewport
   instead of a fixed breakpoint jump. Also give the circular avatar
   photo a bit more breathing room than the shared 20px gutter. --- */
@media (max-width: 860px) {
  .hero-headline { font-size: clamp(32px, 8vw, 48px); }
  .hero-content { padding-left: 28px; padding-right: 28px; }
}

/* --- Hero "EN · ES · PT" stat wraps to 2 lines at the desktop 28px
   size inside its narrow mobile stat box. Shrink stat numbers on
   mobile so all four boxes fit their value on one line. --- */
@media (max-width: 860px) {
  .hero-stat-num { font-size: 21px; }
}

/* --- Homepage "About Robin" intro: .intro-text kept its desktop
   80px/72px padding verbatim, squeezing the mobile column to ~230px
   and wrapping text into a narrow ribbon. .intro-photo also kept an
   asymmetric desktop margin (0 left / gutter right, meant to sit
   beside the text column) which reads as off-center once stacked. --- */
@media (max-width: 860px) {
  .intro-text {
    padding: 40px var(--mobile-gutter, 20px);
  }
  .intro-photo {
    margin: 24px var(--mobile-gutter, 20px) 32px;
  }
}

/* --- Several sections keep desktop-scaled vertical padding (96-120px)
   on mobile, reading as oversized dead space between sections on a
   short viewport. Scale it down proportionally. --- */
@media (max-width: 860px) {
  .services-section { padding: 48px var(--mobile-gutter, 20px); }
  .testimonials-section { padding: 48px 0 40px; }
  .market-section { padding: 48px var(--mobile-gutter, 20px); }
  .youtube-section { padding: 40px var(--mobile-gutter, 20px); }
  .cta-section { padding: 64px var(--mobile-gutter, 20px); }
}

/* --- Homepage process section: .process-layout's 80px column-gap
   (meant for the desktop two-column gutter) becomes a large vertical
   gap once the columns stack. Tighten it and the already-reduced
   process-left/process-right padding further for mobile. --- */
@media (max-width: 860px) {
  .process-layout { gap: 24px; }
  .process-left { padding-top: 24px; padding-bottom: 24px; }
  .process-right { padding-top: 24px; }
}

/* --- Homepage-only: .cta-section and <footer> sit inside
   .values-section, which adds a horizontal gutter meant for its own
   "values" content. That gutter also squeezes these two full-bleed
   sections in from the edges. Cancel it out just for these two. --- */
@media (max-width: 860px) {
  .values-section .cta-section,
  .values-section footer {
    margin-left: calc(-1 * var(--mobile-gutter, 20px));
    margin-right: calc(-1 * var(--mobile-gutter, 20px));
  }
}

/* --- Several section headings (services "Every step of the way...",
   testimonials "90+ clients served...", process "A process built
   around you...") share .section-heading / .process-left-heading at
   a flat 40px, wrapping into 3 oversized lines on mobile. The
   "Explore neighborhoods" CTA heading is inline-styled at 48px
   (needs !important to beat the inline style + a class added in the
   HTML so it's targetable at all). Scale all of them down. --- */
@media (max-width: 860px) {
  .section-heading,
  .process-left-heading {
    font-size: clamp(26px, 7vw, 32px);
  }
  .neighborhood-cta-title {
    font-size: clamp(28px, 7vw, 36px) !important;
  }
}

/* --- Homepage-only: the legal disclaimer bar (like .cta-section and
   <footer> above it) sits inside .values-section and inherits its
   20px horizontal gutter, so the white bar reads as a narrow inset
   card instead of a full-width footer strip. --- */
@media (max-width: 860px) {
  .values-section .legal-disclaimer {
    margin-left: calc(-1 * var(--mobile-gutter, 20px));
    margin-right: calc(-1 * var(--mobile-gutter, 20px));
  }
}

/* --- Neighborhoods map: .denver-map-wrap has position:relative with
   no z-index, so it never establishes its own stacking context —
   Leaflet's internal panes (which use z-index up to 600-700) leak
   out and stack directly against the page's root context, outranking
   the mobile nav panel's z-index:150 once you scroll with the menu
   open. Giving the wrap its own z-index contains Leaflet inside it. --- */
@media (max-width: 860px) {
  .denver-map-wrap { z-index: 0; }
}

/* --- YouTube nav link: index/about/buy/sell/contact were missing the
   flex+gap rule that neighborhoods.css/vendors.css already had for
   ".nav-dropdown-menu a.external", so the icon sat on the text
   baseline instead of centered with it (desktop misalignment). The
   mobile nav panel's YouTube link never had an icon at all — it now
   matches desktop's (same SVG, class="external" added to the HTML). --- */
@media (max-width: 860px) {
  .nav-mobile-panel a.external {
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .nav-mobile-panel a.external svg {
    opacity: .45;
    flex-shrink: 0;
  }
}
