/* ============================================
   Responsive Design & Media Queries
   ============================================ */

/* ============================================
   Tablet: 1024px and below
   ============================================ */

@media (max-width: 1024px) {
  :root {
    --size-container-padding: 1.5rem;
  }

  /* Headline drops out of the image overlay into normal flow below it —
     the Figma mobile frame shows this same "stacked" composition, not a
     shrunk version of the desktop overlay. */
  .hero-cover-media {
    height: 420px;
  }

  .hero-cover-body {
    position: static;
    height: auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-32);
    padding-top: var(--space-32);
    padding-bottom: 0;
  }

  /* Font-size unchanged here — .hero-cover-title keeps inheriting desktop's
     56px through the tablet tier. Every H2 on the page (property-intro-title,
     section-title, etc.) also stays at its desktop size until ≤768, so
     dropping H1 to mobile-tier size already at ≤1024 would put it BELOW
     those H2s for the whole 769–1024px range — inverted hierarchy. The
     actual size drop happens at ≤768 instead, alongside the H2 tier's
     own drop to 28px (see below), so H1 > H2 holds at every width. */
  .hero-cover-title {
    max-width: 100%;
    color: var(--color-primary);
  }

  .hero-cover-footer {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-32);
    padding-top: var(--space-32);
    padding-bottom: var(--space-32);
  }

  .hero-scroll-btn {
    position: static;
    transform: none;
    /* No longer centered via translate(-50%,-50%) at this breakpoint (see
       position:static above) — swap to the plain entrance keyframe
       (motion.css) instead of the desktop one, which bakes that centering
       transform into its own from/to values and would otherwise still win
       over transform:none above for as long as it keeps filling forwards. */
    animation-name: heroCoverEnter;
  }

  .section-hero-cover {
    margin-bottom: -64px;
  }

  .main-content {
    gap: var(--space-128);
  }

  .rest-wrapper,
  .content-groups,
  .property-overview {
    gap: var(--space-48);
  }

  .welcome-title,
  .welcome-body {
    width: 100%;
    margin-left: 0;
  }

  .property-intro-row {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-32);
  }

  .property-intro-main,
  .property-credits {
    flex: none;
    width: 100%;
  }

  .delivery-estimate {
    margin-left: 0;
  }

  .property-intro-title {
    font-size: var(--font-size-48);
  }

  .property-intro-specs {
    flex-direction: column;
    gap: var(--space-8);
  }

  .hero-rotator {
    flex-wrap: wrap;
  }

  .hero-slide,
  .hero-slide.is-active {
    flex: 1 1 260px;
    height: 320px;
  }

  /* Desktop's 128px on every side (layout.css) never had a mobile
     override — at narrow widths that's 256px eaten by left+right padding
     alone, squeezing everything into a sliver. Vertical breathing room
     stays generous, horizontal drops to the standard container padding. */
  .section-hygge {
    padding: var(--space-64) var(--size-container-padding);
  }

  .hygge-layout {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-32);
  }

  .hygge-image-main {
    flex: none;
    width: 100%;
    height: auto;
    aspect-ratio: 330 / 313;
    margin: 0;
  }

  /* Desktop's 236px text-column inset (real spacing there, next to a
     330px image column) is just dead space once the layout stacks. */
  .hygge-text-column {
    width: 100%;
    padding-left: 0;
    gap: var(--space-32);
  }

  .hygge-content .section-header {
    width: 100%;
  }

  .hygge-credit {
    width: 100%;
  }

  .section-header,
  .section-header-inset,
  .section-header-flush {
    width: 100%;
  }

  .floor-plans-intro {
    padding-left: 0;
  }

  .location-quote-row {
    padding-left: 0;
  }

  .location-quote {
    width: 100%;
  }

  /* .section-location's sticky-reveal trick (pinned while
     .section-property-details scrolls over it) only reads as intended
     when the section is shorter than the viewport — once the map row
     stacks to a column below, its content is taller than most mobile
     screens and the pin just traps scroll awkwardly. Same call already
     made for .details-title below. */
  .section-location {
    position: static;
    padding-top: 0;
  }

  .location-map-row {
    flex-direction: column;
    padding-left: 0;
  }

  .location-map {
    height: 480px;
    /* Map first, legend second — map is the primary visual/context, the
       12-item distance list is supporting detail. Visual order only;
       DOM/reading order is untouched for screen readers. */
    order: -1;
  }

  .location-legend {
    flex: none;
    width: 100%;
    padding: var(--space-24) 0;
  }

  /* Same reasoning as .section-location above — a stacked-column floor
     plan card is taller than the viewport, so the sticky stacked-cards
     effect just traps scroll instead of reading as intentional. */
  .floor-plans-intro {
    position: static;
    top: auto;
  }

  .floor-plan-section {
    position: static;
    top: auto;
    flex-direction: column;
    gap: var(--space-16);
  }

  .floor-plan-content {
    flex: 1 1 auto;
    padding-top: 0;
    width: 100%;
  }

  .floor-plan-visual {
    width: 100%;
  }

  .floor-plan-pin {
    display: none;
  }

  .floor-plan-gallery {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-16);
    margin-top: var(--space-16);
    padding: 16px
  }

  .philosophy-content {
    width: 100%;
    margin-left: 0;
  }

  .philosophy-description {
    width: 100%;
  }

  .gallery-row {
    flex-wrap: wrap;
  }

  .gallery-item--sm,
  .gallery-item--md,
  .gallery-item--lg,
  .gallery-item--xl {
    flex: 1 1 45%;
  }

  .details-grid {
    grid-template-columns: repeat(2, 1fr);
    row-gap: var(--space-24);
  }

  .property-details-content {
    grid-template-columns: 1fr;
    gap: var(--space-64);
  }

  .details-title {
    top: 80px;
  }

  .header-actions {
    gap: var(--space-16);
  }

  .cta-whatsapp-text {
    display: none;
  }

  .cta-whatsapp {
    width: 48px;
    height: 48px;
    padding: var(--space-16);
  }
}

/* ============================================
   Mobile: 768px and below
   ============================================ */

@media (max-width: 768px) {
  :root {
    --size-container-padding: 1rem;
    --font-size-64: 2rem;
    --font-size-48: 1.875rem;
    /* H2 tier (section-title, property-intro-title, floor-plan-title,
       location-quote, philosophy-title, contact-cta-title, details-title).
       Fixed px, not rem — stays 28px regardless of html's font-size. */
    --font-size-32: 28px;
    --font-size-24: 1.25rem;
    /* Fixed px, not rem — html's font-size below shrinks every rem value
       site-wide (including these two), which was quietly taking reading
       copy (welcome-body, floor-plan-description, details-item,
       philosophy-description, contact-cta-description/legal, ...) below
       the 16px/14px legibility floor. Pinning them here holds their real
       intended size regardless of html's font-size. */
    --font-size-16: 16px;
    --font-size-14: 14px;
    /* Rendered height of the fixed bottom CTA bar — two stacked 48px
       circles + gap + the bar's own padding — reused to keep page content
       and the scroll-to-top button clear of it. */
    --mobile-cta-bar-height: 144px;
    /* Left offset for section intros that keep a partial indent on mobile
       instead of going full-bleed (property intro, floor-plans intro,
       hygge/concept, each floor plan's title+description) — matches the
       Figma mobile mockup's asymmetric rhythm instead of flattening
       everything to the container edge. */
    --mobile-section-indent: calc(25% + 12.5px);
  }

  .hero-cover-media {
    height: 325px;
  }

  /* At this breakpoint .main-content's own gap is already 64px — the exact
     target — so the ≤1024 pull-up is cancelled instead of stacking. Also
     zeroes out margin-top: .header-sticky goes position:fixed here (see
     the header rules below), dropping out of flow entirely — there's no
     256px header-scroll-region gap left to cancel, so the desktop/tablet
     negative margin would just shift the hero off-screen. */
  .section-hero-cover {
    margin-top: 0;
    margin-bottom: 0;
  }

  /* Figma's mobile wordmark is proportionally larger than desktop's
     (140px vs 112px wide, same aspect) — not just carried over at the same
     size. */
  .hero-cover-logo {
    left: var(--size-container-padding);
    top: var(--size-container-padding);
    font-size: 24px;
  }

  /* Literal 32px, not --font-size-32 — that token is the H2 tier and gets
     pinned to 28px at this same breakpoint (see below), so H1 stays
     clearly larger. Same fixed-px tier as .welcome-title's own 32px here. */
  .hero-cover-title {
    font-size: 32px;
  }

  html {
    font-size: 14px;
  }

  .main-content {
    gap: var(--space-64);
  }

  .rest-wrapper,
  .content-groups,
  .property-overview {
    gap: var(--space-32);
  }

  /* H1 — decoupled from --font-size-32 (the H2-tier token) so it keeps
     its own fixed size, immune to html's font-size. */
  .welcome-title {
    font-size: 32px;
  }

  .welcome-body {
    font-size: var(--font-size-16);
  }

  /* Figma's mobile frame (node 940:31) has Property Intro flush against
     the container edge, not on the indented column the other section
     intros below use — no padding-left override here. */

  .property-intro-title {
    font-size: var(--font-size-32);
  }

  /* Figma mobile: proper 2-column grid (not the desktop flex-wrap flow),
     smaller 14px type. */
  .property-intro-specs {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    column-gap: var(--space-24);
    row-gap: var(--space-16);
    font-size: 14px;
  }

  /* Figma mobile: the two credits sit side by side, each with its own
     small label above a larger value — not one combined line each,
     stacked, like desktop. */
  .property-credits {
    flex-direction: row;
    gap: var(--space-24);
  }

  .property-credit {
    flex: 1 0 0;
    flex-direction: column;
    gap: var(--space-8);
  }

  .property-credit-label {
    font-size: 14px;
    font-weight: 400;
  }

  .property-credit-value {
    font-size: 18px;
    font-weight: 500;
  }

  .delivery-estimate {
    padding-left: var(--mobile-section-indent);
  }

  /* Same reset as the desktop margin-left override — the hero's copy of
     this component isn't part of that indented column rhythm. */
  .hero-cover-footer .delivery-estimate {
    padding-left: 0;
  }

  .section-title,
  .floor-plans-title {
    font-size: var(--font-size-32);
  }

  .section-subtitle {
    font-size: var(--font-size-16);
  }

  /* Stacking all 3 slides (main + 2 details) vertically wastes scroll on
     a narrow screen for no benefit — the side-by-side comparison only
     makes sense with room to see them at once. Show just the single
     active photo, full width; the rotator's existing 3s auto-advance
     (unchanged JS) still cycles through all three, one at a time. */
  .hero-slide {
    display: none;
  }

  .hero-slide.is-active {
    display: block;
    flex: 1 1 100%;
    height: auto;
    aspect-ratio: 4 / 3;
  }


  /* Literal 22px, not --font-size-32 (the H2 tier, pinned to 28px here) —
     this is an h3, one step below .floor-plans-title (h2) above it in the
     same section; equal sizing read as flat hierarchy. */
  .floor-plan-title {
    font-size: 22px;
  }

  .floor-plan-description {
    font-size: var(--font-size-16);
  }

  /* Side-centered nav (layout.css) sits over the photo on a small screen —
     move it to a thumb-reachable strip at the bottom instead, left/right
     positions unchanged so the pair stays split to each edge. */
  .lightbox-nav {
    top: auto;
    bottom: var(--space-32);
    margin-top: 0;
  }

  .section-location {
    padding-top: var(--space-128);
  }

  .location-quote {
    font-size: var(--font-size-32);
  }

  .location-legend {
    padding-left: 12px;
    padding-right: 12px;
  }

  .philosophy-title {
    font-size: var(--font-size-32);
  }

  .philosophy-description {
    font-size: var(--font-size-14);
    width: 100%;
  }

  .gallery-item--sm,
  .gallery-item--md,
  .gallery-item--lg,
  .gallery-item--xl {
    flex: 1 1 100%;
  }

  .gallery-item {
    height: auto;
    aspect-ratio: 4 / 3;
  }

  .section-property-details {
    margin-top: 0;
    padding: var(--space-64) 0;
  }

  .property-details-content {
    gap: var(--space-64);
  }

  .details-title {
    font-size: var(--font-size-32);
    top: 56px;
  }

  .details-grid {
    grid-template-columns: 1fr;
    row-gap: var(--space-16);
  }

  .details-item {
    font-size: var(--font-size-16);
  }

  .section-contact-cta {
    padding-top: var(--space-64);
  }

  .contact-cta-content {
    gap: var(--space-96);
  }

  .contact-cta-title {
    font-size: var(--font-size-32);
  }

  .contact-cta-button {
    padding: var(--space-16) var(--space-24);
  }

  .contact-cta-button span {
    font-size: 16px;
  }

  .icon-whatsapp-contact {
    width: 24px;
    height: 24px;
  }

  /* Base rule is max-width:480px!important — needs !important here too to
     actually override it, plain specificity/source-order isn't enough. */
  .contact-cta-signature {
    max-width: 100% !important;
  }

  /* Anchored to the bottom of the viewport instead of the top — an
     app-style action bar, always reachable with a thumb. Share and
     WhatsApp render as a stacked pair of icon-only circles — see
     .header-actions below.
     position:fixed, not sticky — bottom-anchored sticky never catches an
     element positioned first in a tall container (its static position is
     always already scrolled past the viewport, so there's nothing for
     "bottom:0" to clamp against — verified empirically, not a hunch).
     initMobileHeaderRelease (js/main.js) adds .is-header-released once
     .header-scroll-region's bottom edge reaches the viewport bottom,
     switching to position:absolute (below) so it stops there instead of
     following the rest of the page. */
  .header-sticky {
    position: fixed;
    top: auto;
    bottom: 0;
    padding: var(--space-16) var(--size-container-padding) calc(var(--space-16) + env(safe-area-inset-bottom));
    animation: slideUp var(--transition-slow) ease-out;
  }

  .header-sticky.is-header-released {
    position: absolute;
    top: auto;
    bottom: 0;
  }

  @keyframes slideUp {
    from {
      opacity: 0;
      transform: translateY(20px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }
  /* Stacked, not side-by-side: WhatsApp on top, Share underneath, both
     right-aligned at the bottom of the screen. column-reverse (rather than
     reordering the HTML) puts WhatsApp — 2nd in the DOM — above Share,
     1st in the DOM, without touching source order/tab order. */
  .header-actions {
    flex-direction: column-reverse;
    align-items: flex-end;
    gap: var(--space-16);
  }

  .header-actions li {
    flex: 0 0 auto;
  }

  .cta-share,
  .cta-whatsapp {
    width: 48px;
    height: 48px;
    /* Icon-only circle, matching .cta-share — the desktop pill's own
       padding (16px) would otherwise squeeze the 24px icon against a
       16px content box. */
    padding: 0;
  }

  .cta-whatsapp-text {
    display: none;
  }

  .scroll-to-top-wrap {
    position: static;
  }

  .scroll-to-top-btn {
    margin: 32px auto;
  }

  /* Hover-only affordance, irrelevant on touch — and now that .header-sticky
     is position:fixed (no longer clipped by body's overflow-x:hidden the
     way position:sticky was), its off-canvas resting position would
     otherwise make the page genuinely horizontally scrollable. */
  .cta-tooltip {
    display: none;
  }

  .scroll-to-top-btn {
    width: 44px;
    height: 44px;
  }

  .scroll-to-top-btn .icon {
    width: 18px;
    height: 18px;
  }

  .pin-overlay {
    padding: var(--space-16);
  }
}

/* ============================================
   Small Mobile: 480px and below
   ============================================ */

@media (max-width: 480px) {
  :root {
    --size-container-padding: 1rem;
    --font-size-48: 1.5rem;
    /* Stays fixed at the same 28px as the 768px tier — headings shouldn't
       keep shrinking below that on smaller phones. */
    --font-size-32: 28px;
    --font-size-24: 1.125rem;
  }

  .welcome-title {
    font-size: 32px;
  }

  .welcome-body {
    font-size: var(--font-size-16);
  }

  .property-intro-title {
    font-size: var(--font-size-32);
  }

  .section-title,
  .philosophy-title,
  .details-title {
    font-size: var(--font-size-32);
  }

  .details-title {
    /* Header stacks to multiple rows below this width — its height is no
       longer predictable, so sticking the title under it isn't reliable. */
    position: static;
  }

  .location-quote {
    font-size: var(--font-size-32);
  }


  .details-grid {
    grid-template-columns: 1fr;
  }

}

/* ============================================
   High DPI / Retina Displays
   ============================================ */

@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  img {
    image-rendering: -webkit-optimize-contrast;
  }
}

/* ============================================
   Touch Device Support
   ============================================ */

@media (hover: none) and (pointer: coarse) {
  .cta-button {
    min-height: 44px;
    min-width: 44px;
  }

  .scroll-to-top-btn {
    min-height: 44px;
    min-width: 44px;
  }

  .floor-plan-pin {
    min-width: 44px;
    min-height: 44px;
  }
}

/* ============================================
   Print Styles
   ============================================ */

@media print {
  .header-sticky,
  .scroll-to-top-wrap,
  .pin-overlay,
  .lightbox {
    display: none;
  }

  .section-property-details {
    background-color: transparent;
    color: #000;
  }

  .details-title,
  .details-item {
    color: #000;
  }

  section {
    page-break-inside: avoid;
  }

  img {
    max-width: 100%;
    page-break-inside: avoid;
  }
}

/* ============================================
   Accessibility: Reduced Motion
   ============================================ */

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

  html {
    scroll-behavior: auto;
  }

  .header-sticky {
    animation: none;
  }

  .hero-slide-timer-fill {
    animation: none !important;
  }

  /* Reveals must never depend on JS/observer timing under reduced motion —
     show content immediately regardless of whether it was ever observed. */
  .reveal,
  .stagger-item,
  .welcome-title .word {
    opacity: 1 !important;
    transform: none !important;
  }
}
