/* ============================================================
   Public Profile — dedicated, isolated design system.
   Deliberately does NOT share home/base.html's style.css or CSS
   variables - this page needs to feel like the owner's own site,
   not a page inside 2Hame. See public_profile_base.html.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@500;600;700;800&family=Jost:wght@300;400;500;600;700&display=swap');

:root {
  --pp-gold: #B8935A;
  --pp-gold-light: #D4B483;
  --pp-black: #0B0B0C;
  --pp-black-soft: #16161A;

  --pp-bg: #FBFAF8;
  --pp-surface: #FFFFFF;
  --pp-text: #16161A;
  --pp-text-muted: #6B6B70;
  --pp-border: #E8E4DD;

  --pp-font-display: 'Playfair Display', Georgia, serif;
  --pp-font-body: 'Jost', -apple-system, sans-serif;

  --pp-radius: 4px;
  --pp-radius-lg: 8px;
  --pp-transition: all 0.25s ease;
  --pp-container: 1200px;
  /* Topbar has been removed - kept at 0 (rather than deleting the
     variable outright) so every existing calc(var(--pp-topbar-h) + Npx)
     below still resolves correctly without hunting down each usage. */
  --pp-topbar-h: 0px;
}

[data-pp-theme="dark"] {
  --pp-bg: #0B0B0C;
  --pp-surface: #16161A;
  --pp-text: #F2F0EB;
  --pp-text-muted: #9C9A96;
  --pp-border: #2A2A2E;
}

* { box-sizing: border-box; }

html {
  /* Whole-page scroll snapping between major sections (hero, feature
     strip, about, categories, featured, listings, reviews, connect,
     footer - see scroll-snap-align below). "proximity" (not
     "mandatory") snaps once the scroll naturally comes to rest near a
     section boundary rather than forcing every scroll gesture to a
     snap point - "mandatory" fights normal scrolling inside the long,
     interactive Listings section (filters, pagination) and the
     Contact form, which is exactly the kind of trapped-scroll feeling
     that makes snap scrolling frustrating rather than pleasant. */
  scroll-snap-type: y proximity;
  scroll-behavior: smooth;
  /* Keeps a snapped section's top edge clear of the fixed
     topbar-less header (~90px tall) instead of tucking straight
     under it. */
  scroll-padding-top: 90px;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-snap-type: none; scroll-behavior: auto; }
}

body.pp-body {
  margin: 0;
  font-family: var(--pp-font-body);
  background: var(--pp-bg);
  color: var(--pp-text);
  transition: background 0.3s ease, color 0.3s ease;
  overflow-x: hidden;
  /* Numbered section eyebrows below (see .pp-eyebrow::before) - reset
     once here at the page root, incremented once per numbered section
     in document order (About, Categories, Listings, Reviews, Connect). */
  counter-reset: pp-section-counter;
}

.pp-container {
  max-width: var(--pp-container);
  margin: 0 auto;
  padding: 0 1.5rem;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

.pp-splash {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--pp-black);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  transition: opacity 0.6s ease, visibility 0.6s ease;
}

.pp-splash.pp-splash-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.pp-splash-avatar {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--pp-gold);
  opacity: 0;
  animation: pp-fade-in 0.8s ease forwards 0.15s;
}

.pp-splash-name {
  font-family: var(--pp-font-display);
  color: #F2F0EB;
  font-size: 1.5rem;
  letter-spacing: 0.04em;
  opacity: 0;
  animation: pp-fade-in 0.8s ease forwards 0.4s;
}

.pp-splash-rule {
  width: 40px;
  height: 1px;
  background: var(--pp-gold);
  opacity: 0;
  animation: pp-fade-in 0.8s ease forwards 0.65s;
}

@keyframes pp-fade-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .pp-splash-avatar, .pp-splash-name, .pp-splash-rule { animation: none; opacity: 1; }
}

/* Top contact bar removed - see public_profile_base.html. */

.pp-header {
  position: fixed;
  top: var(--pp-topbar-h);
  left: 0;
  right: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.25rem 1.5rem;
  background: transparent;
  transition: var(--pp-transition), top 0.35s ease;
}

.pp-header.pp-header-solid {
  top: 0;
  background: var(--pp-surface);
  border-bottom: 1px solid var(--pp-border);
  padding: 0.85rem 1.5rem;
}

.pp-header-brand {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-width: 0;
}

.pp-header-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--pp-gold);
  flex-shrink: 0;
}

.pp-header-avatar-fallback {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--pp-black);
  color: var(--pp-gold);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--pp-font-display);
  font-weight: 700;
  flex-shrink: 0;
}

.pp-header-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.pp-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.6rem 1.25rem;
  border-radius: var(--pp-radius);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  cursor: pointer;
  border: 1px solid var(--pp-gold);
  transition: var(--pp-transition);
}

.pp-btn-gold {
  background: var(--pp-gold);
  color: var(--pp-black);
}

.pp-btn-gold:hover { background: var(--pp-gold-light); }

.pp-btn-outline {
  background: transparent;
  color: var(--pp-text);
  border-color: var(--pp-border);
}

.pp-btn-outline:hover { border-color: var(--pp-gold); }

.pp-theme-toggle {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--pp-border);
  background: var(--pp-surface);
  color: var(--pp-text);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}

.pp-hero {
  position: relative;
  scroll-snap-align: start;
  /* display:flex (rather than leaving vertical centering to
     .pp-hero-content's own height:100%) so centering keeps working
     even when this section's height comes from min-height instead of
     an explicit height - see the mobile override below, where height
     is "auto" and only min-height is set. A child's height:100% does
     NOT reliably resolve against a min-height floor on an auto-height
     parent (the spec falls back to "auto" in that case), which is
     exactly why the mobile hero text used to end up hugging the top
     with a dead gap below it instead of sitting in the middle. Flex
     alignment doesn't have that problem - it centers the child within
     whatever height the section actually ends up with. */
  display: flex;
  flex-direction: column;
  /* Belt-and-suspenders with .pp-hero-content's own height:100% +
     justify-content:center: if that percentage height doesn't end up
     resolving for any reason, this still centers the (then
     shrink-to-fit) content block within the section's actual height
     directly, since flex justify-content never depends on the item
     having a resolved height in the first place. */
  justify-content: center;
  /* Deliberately shorter than a full 100dvh: the goal is for the top
     sliver of .pp-feature-strip (below) to already be visible on
     first load, within the same viewport - a visual cue that there's
     more to scroll to, rather than a hero that fills the whole screen
     and hides everything below it. vh first as a safe fallback for
     browsers without dvh support; the dvh rule after it wins where
     supported and tracks the *actual* visible viewport on mobile
     (excluding the address bar), so the peek amount stays consistent
     instead of shifting as browser chrome shows/hides. */
  height: 78vh;
  height: 78dvh;
  min-height: 460px;
  overflow: hidden;
  background: var(--pp-black);
}

/* Below ~640px the fixed 78vh/460px box stops being safe: the full content
   stack (logo + eyebrow badge + heading + rotating tagline + bio + CTAs +
   counters, all stacked in a single column here) can genuinely run to
   ~700-750px on a phone with only ~567-620px of hero height available
   (e.g. a 375x667 iPhone SE) - taller names, a present rotating tagline,
   or a longer bio push it further still. With overflow:hidden that's a
   silent clip, not a scrollbar - exactly what reads as "content
   overlapping/cut off". Switching to height:auto + a generous min-height
   + overflow:visible lets the section grow to fit whatever content is
   actually there instead of guessing a height that fits most of the time.
   The background slides/overlay below are position:absolute;inset:0, so
   they stretch to match this new, content-driven height automatically -
   nothing else needs to change for the photo to still fill the section. */
@media (max-width: 640px) {
  .pp-hero {
    height: auto;
    /* Unlike the desktop 78dvh peek above, phones get the full
       viewport height here - the feature strip should sit fully
       below the fold on first load, not peek into it. svh/dvh (not
       plain vh) excludes the mobile browser's address-bar chrome,
       where plain vh can itself trigger the address-bar-collapses-
       and-reflows jump this rule exists to avoid. */
    min-height: 100vh;
    min-height: 100svh;
    min-height: 100dvh;
    overflow: visible;
  }
}

/* Short viewports - small/older laptops in the 1024x600-1366x768 range -
   have the opposite problem from narrow phones: plenty of *width* (so the
   max-width rules above never fire and .pp-hero-name keeps sizing off its
   6vw clamp, landing near its 4rem ceiling), but very little *height* to
   fit that large text plus the logo, eyebrow, hr, taglines, CTAs and
   counters into. With .pp-hero pinned to a fixed 78vh/460px and
   overflow:hidden, the stack simply overshoots that box - and because
   .pp-hero-content is vertically centered, the overshoot pushes the top
   of the stack up behind the fixed header instead of showing as a
   scrollbar, which is exactly what reads as "the eyebrow is tucked under
   the logo". Fixed here the same way as the narrow-phone case: let the
   section grow to fit its content instead of clipping it, and shrink the
   text/spacing so there's less to fit in the first place. Keyed off
   max-height rather than max-width so it also catches wide-but-short
   screens the width breakpoints above don't touch. */
@media (max-height: 760px) and (min-width: 641px) {
  .pp-hero {
    height: auto;
    min-height: 100vh;
    min-height: 100svh;
    overflow: visible;
  }

  .pp-hero-content {
    /* Tighter than the 130px desktop reserve - a short screen can't
       spare that much just for clearance above/below the centered
       stack. Still clears the fixed topbar+header. */
    padding-top: calc(var(--pp-topbar-h) + 90px);
    padding-bottom: 90px;
  }

  .pp-hero-logo {
    height: clamp(56px, 10vh, 90px);
    margin-bottom: 1rem;
  }

  .pp-hero-eyebrow {
    font-size: 0.7rem;
    margin-bottom: 0.6rem;
  }

  .pp-hero-name {
    /* Same idea as the width-based clamp above, just capped lower so a
       short-but-wide viewport can't push it toward its 4rem ceiling. */
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    margin-bottom: 0.4rem;
  }

  .pp-hero-hr { margin-top: 0.85rem; }

  .pp-hero-rotating-tagline {
    font-size: clamp(0.95rem, 1.8vw, 1.1rem);
    margin: 0.75rem 0 0.15rem;
  }

  .pp-hero-tagline {
    font-size: clamp(0.85rem, 1.4vw, 0.95rem);
    margin-bottom: 1.25rem;
  }

  .pp-hero-counters { margin-top: 1.25rem; }
}

.pp-hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.6s ease;
}

.pp-hero-slide.pp-hero-slide-active { opacity: 1; }

.pp-hero-slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pp-hero-overlay {
  position: absolute;
  inset: 0;
  /* Mobile/default: simple top-to-bottom scrim, image visible full-bleed.
     The left-to-right dark-to-light treatment only kicks in on wider
     screens below - see the @media block right after this rule. */
  background: linear-gradient(180deg, rgba(11,11,12,0.55) 0%, rgba(11,11,12,0.25) 40%, rgba(11,11,12,0.85) 100%);
}

/* Desktop only: text sits on a fully solid dark field on the left,
   which fades away moving right so the image reveals itself
   progressively - left-to-right, dark-to-image. Note the left edge is
   opaque var(--pp-black), not a translucent rgba - text needs a truly
   solid backing here, not just "mostly dark". Mobile keeps the plain
   scrim above since left-aligned text over a horizontally-varying
   background reads as patchy on a narrow screen. */
@media (min-width: 981px) {
  .pp-hero-overlay {
    background:
      /* Vertical layer: barely any darkening at the top (this used to be
         0.3 here, which stacked with the horizontal layer below and made
         the whole top band - right where the header and logo sit - go
         nearly solid black, hiding the photo exactly where it should be
         most visible). Only the bottom, where the hero transitions into
         the feature strip, still needs real darkening. */
      linear-gradient(180deg, rgba(11,11,12,0.05) 0%, rgba(11,11,12,0.05) 50%, rgba(11,11,12,0.55) 100%),
      linear-gradient(90deg,
        var(--pp-black) 0%,
        rgba(11,11,12,0.97) 20%,
        rgba(11,11,12,0.82) 34%,
        rgba(11,11,12,0.5) 48%,
        rgba(11,11,12,0.18) 62%,
        rgba(11,11,12,0) 78%
      );
  }
}

.pp-hero-content {
  position: relative;
  z-index: 2;
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  text-align: left;
  /* Deliberately NOT the shared centered .pp-container - this hugs the
     true viewport edge (matching .pp-header's own padding) instead of
     sitting inside a 1200px box centered with empty space to its left
     on wide screens. */
  padding-left: clamp(2rem, 7vw, 7rem);
  padding-right: 1.5rem;
  /* Guaranteed clearance below the fixed topbar+header (they float
     above the hero, transparent, at a higher z-index) - without this,
     vertically-centering a tall content block (logo + heading + tagline
     + ctas + counters) in the hero can place its top edge - the hero's
     own logo image - underneath the header on shorter viewports,
     regardless of how tall the hero section itself is. This reserves
     the space up front so centering only ever happens in what's left.
     padding-bottom mirrors it (rather than being 0) so the centered
     content block reads as sitting in the middle of the hero, with
     even breathing room top and bottom - with only padding-top set,
     justify-content:center still centers the content in the remaining
     space, but that remaining space itself is pushed low by the
     one-sided reserve, so the block visibly hugs the header instead of
     looking centered. */
  padding-top: calc(var(--pp-topbar-h) + 130px);
  padding-bottom: 130px;
}

@media (max-width: 640px) {
  /* .pp-hero is now height:auto here (see the @media block on .pp-hero
     above) rather than a fixed viewport fraction, so this no longer
     needs to reserve room for centering within a capped box - it just
     needs enough clearance to clear the fixed topbar+header, plus a
     bottom breather before the next section. Slightly tighter than the
     100px desktop reserve since the mobile header is shorter too.
     padding-bottom mirrors the 76px (the part of padding-top that
     isn't specifically the topbar clearance - nothing needs clearing
     at the bottom) rather than being a much smaller, unrelated value -
     same reasoning as the matching desktop fix: one-sided padding-top
     pushes the centered content up against the header instead of
     looking centered in the section. */
  .pp-hero-content {
    padding-top: calc(var(--pp-topbar-h) + 76px);
    padding-bottom: 76px;
    /* Left-aligned, matching desktop - the vertical centering fix on
       .pp-hero above (display:flex; flex-direction:column) does the
       real work of putting this block in the middle of the screen
       instead of hugging the top with empty space below it. */
    align-items: flex-start;
    text-align: left;
  }
}

.pp-hero-logo {
  height: clamp(70px, 14vh, 110px);
  width: auto;
  max-width: 220px;
  object-fit: contain;
  margin-bottom: 1.75rem;
}

.pp-hero-logo-fallback {
  border-radius: 6px;
}

@media (min-width: 981px) {
  .pp-hero-logo { height: clamp(110px, 18vh, 170px); }
}

/* Below 1024px - which covers both phones and small/short laptop
   screens (e.g. 1024x600) - the hero is tight on vertical space (see
   the height:auto fix on .pp-hero above for the sub-640px case, and
   the fixed topbar+header eating into a short viewport for the
   1024-width case) - the owner's avatar isn't load-bearing information
   here (it's shown again, larger, in the About section further down,
   and it's still visible up in the header), so it's dropped entirely
   rather than just shrunk, freeing up space for the name/badge/CTAs to
   start higher. */
@media (max-width: 1024px) {
  .pp-hero-logo { display: none; }
}

.pp-hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  color: var(--pp-gold-light);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin: 0 0 1rem;
  opacity: 0.95;
}

.pp-hero-name {
  font-family: var(--pp-font-display);
  color: #FBFAF8;
  font-size: clamp(2.25rem, 6vw, 4rem);
  font-weight: 600;
  margin: 0 0 0.6rem;
  letter-spacing: 0.01em;
  line-height: 1.15;
}

.pp-hero-hr {
  width: 130px;
  height: 2px;
  background: var(--pp-gold);
  border: none;
  margin: 1.5rem 0 0;
}

/* Rotating line under the hr - owner's own tagline first, then a few
   generic phrases, cycled by JS (see extra_js block below). Deliberately
   normal block flow with an explicit width (not absolutely positioned)
   - an earlier version of this used absolute positioning with no width,
   which collapsed to a 1-character-wide column once JS started swapping
   in different-length phrases. Don't reintroduce that. */
.pp-hero-rotating-tagline {
  width: 100%;
  color: var(--pp-gold-light);
  font-family: var(--pp-font-display);
  font-style: italic;
  font-size: clamp(1.05rem, 2.4vw, 1.35rem);
  font-weight: 500;
  margin: 1.1rem 0 0.25rem;
  line-height: 1.4;
  transition: opacity 0.5s ease;
}

/* Subtext paragraph - width is always explicit (100% up to max-width) so
   it renders as a normal centered block, never a collapsed column (the
   old absolutely-positioned word-rotator here used to squash it into a
   1-char column). */
.pp-hero-tagline {
  width: 100%;
  color: rgba(251,250,248,0.85);
  font-size: clamp(0.95rem, 2vw, 1.15rem);
  font-weight: 300;
  max-width: 560px;
  margin: 0 0 2rem;
  line-height: 1.6;
}

.pp-hero-ctas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 1rem;
}

.pp-hero-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.9rem 2rem;
  background: var(--pp-gold);
  color: var(--pp-black);
  border-radius: var(--pp-radius);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: var(--pp-transition);
}

.pp-hero-cta:hover { background: var(--pp-gold-light); transform: translateY(-1px); }

.pp-hero-cta-secondary {
  background: transparent;
  color: #FBFAF8;
  border: 1px solid rgba(251,250,248,0.4);
}

.pp-hero-cta-secondary:hover {
  background: rgba(251,250,248,0.08);
  border-color: #FBFAF8;
  transform: translateY(-1px);
}

@media (max-width: 480px) {
  .pp-hero-ctas { flex-direction: column; width: 100%; max-width: 320px; }
  .pp-hero-cta { width: 100%; justify-content: center; }
  /* Tightens the stack a little further right where it's tallest relative
     to the viewport - none of this is required for correctness (the
     height:auto fix above already guarantees nothing clips), just keeps
     the hero from growing taller than it needs to before a visitor
     reaches the feature strip below it. */
  .pp-hero-logo { margin-bottom: 1.25rem; }
  .pp-hero-tagline { margin-bottom: 1.5rem; }
  .pp-hero-counters { margin-top: 1.75rem; gap: 1.75rem; }
}

.pp-feature-strip {
  background: var(--pp-black);
  border-top: 1px solid rgba(255,255,255,0.08);
  padding: 3rem 0;
  scroll-snap-align: start;
}

.pp-feature-strip .pp-container {
  width: 100%;
}

.pp-feature-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 1rem;
}

/* Each feature is now its own bordered card (rather than a bare column
   separated by a divider line) - sits closer to a real "why choose us"
   panel than a loose icon strip, and gives hover something to lift. */
.pp-feature {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.9rem;
  padding: 1.75rem 1rem;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--pp-radius-lg);
  background: rgba(255,255,255,0.02);
  transition: var(--pp-transition), transform 0.3s ease;
}

.pp-feature:hover {
  border-color: rgba(184,147,90,0.5);
  background: rgba(184,147,90,0.06);
  transform: translateY(-4px);
}

.pp-feature-icon {
  width: 68px;
  height: 68px;
  border-radius: 50%;
  border: 1.5px solid var(--pp-gold);
  color: var(--pp-gold-light);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: transform 0.3s ease, background 0.3s ease;
}

.pp-feature:hover .pp-feature-icon {
  background: var(--pp-gold);
  color: var(--pp-black);
}

.pp-feature-label {
  color: #F2F0EB;
  font-size: 0.85rem;
  font-weight: 500;
  line-height: 1.4;
  max-width: 140px;
}

@media (max-width: 900px) {
  .pp-feature-grid { grid-template-columns: repeat(3, 1fr); }
  .pp-feature-strip { padding: 2.5rem 0; }
}

@media (max-width: 480px) {
  .pp-feature-grid { grid-template-columns: repeat(2, 1fr); gap: 0.75rem; }
  .pp-feature-strip { padding: 2.25rem 0; }
  .pp-feature { padding: 1.4rem 0.75rem; }
  .pp-feature-icon { width: 58px; height: 58px; }
}

.pp-marquee {
  background: var(--pp-black);
  color: var(--pp-gold-light);
  padding: 0.75rem 0;
  overflow: hidden;
  white-space: nowrap;
  border-top: 1px solid rgba(184,147,90,0.25);
  border-bottom: 1px solid rgba(184,147,90,0.25);
}

.pp-marquee-track {
  display: inline-block;
  padding-left: 100%;
  animation: pp-marquee-scroll 28s linear infinite;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-weight: 500;
}

.pp-marquee-track span { margin: 0 2.5rem; }

@keyframes pp-marquee-scroll {
  0% { transform: translateX(0); }
  100% { transform: translateX(-100%); }
}

@media (prefers-reduced-motion: reduce) {
  .pp-marquee-track { animation: none; padding-left: 1.5rem; }
}

.pp-about {
  padding: 5rem 0;
  scroll-snap-align: start;
}

.pp-about-grid {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: 3.5rem;
  align-items: center;
}

.pp-about-image {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--pp-radius-lg);
  box-shadow: 0 20px 45px -15px rgba(0,0,0,0.35), 0 0 0 1px rgba(201,162,75,0.12);
}

.pp-about-image-fallback {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: var(--pp-radius-lg);
  background: var(--pp-black);
  color: var(--pp-gold);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--pp-font-display);
  font-size: 4rem;
  font-weight: 600;
}

.pp-eyebrow {
  color: var(--pp-gold);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  margin: 0 0 0.75rem;
}

.pp-about-heading {
  font-family: var(--pp-font-display);
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  font-weight: 600;
  margin: 0 0 1.25rem;
  line-height: 1.25;
}

.pp-about-hr {
  width: 70px;
  height: 2px;
  background: var(--pp-gold);
  border: none;
  margin: -0.35rem 0 1.25rem;
}

.pp-about-desc {
  color: var(--pp-text-muted);
  line-height: 1.8;
  font-size: 1rem;
  white-space: pre-line;
}

@media (max-width: 860px) {
  .pp-about-grid { grid-template-columns: 1fr; gap: 2rem; }
  /* Square (1/1) is now set once above and applies at every screen size -
     this used to override it to 16/10 here specifically for the stacked
     single-column mobile layout, which is exactly what's not wanted
     anymore. */
  .pp-about { padding: 3.5rem 0; }
}

.pp-section {
  padding: 5rem 0;
  counter-increment: pp-section-counter;
  scroll-snap-align: start;
}

.pp-section-header {
  text-align: center;
  max-width: 560px;
  margin: 0 auto 3rem;
}

/* Small "01 —" style index before every numbered section's eyebrow label
   (About, Categories, Listings, Reviews, Connect - anywhere .pp-eyebrow
   is used as a section label) - a small editorial touch that costs
   nothing structurally since it hooks the existing .pp-eyebrow class,
   no template changes needed. .pp-about increments its own counter too
   (it isn't a .pp-section) since it's the first section in reading
   order, so numbering starts there rather than at 00. */
.pp-about { counter-increment: pp-section-counter; }

.pp-about .pp-eyebrow::before,
.pp-section .pp-eyebrow::before {
  content: "0" counter(pp-section-counter) "  ";
  color: var(--pp-text-muted);
  font-weight: 700;
}

@media (max-width: 640px) {
  .pp-section { padding: 3rem 0; }
}

.pp-listings-layout {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 2.5rem;
  align-items: start;
}

.pp-filters {
  position: sticky;
  top: 90px;
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-lg);
  padding: 1.5rem;
}

.pp-filters h4 {
  font-family: var(--pp-font-display);
  font-size: 1.1rem;
  margin: 0 0 1.25rem;
}

.pp-filter-group { margin-bottom: 1.25rem; }

.pp-filter-group label {
  display: block;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pp-text-muted);
  margin-bottom: 0.5rem;
}

.pp-filter-group select,
.pp-filter-group input {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius);
  background: var(--pp-bg);
  color: var(--pp-text);
  font-family: var(--pp-font-body);
  font-size: 0.85rem;
}

.pp-filters-mobile-btn {
  display: none;
}

@media (max-width: 900px) {
  .pp-listings-layout { grid-template-columns: 1fr; }
  .pp-filters {
    position: fixed;
    top: 0;
    right: -100%;
    height: 100%;
    width: min(320px, 88vw);
    z-index: 300;
    border-radius: 0;
    overflow-y: auto;
    transition: right 0.3s ease;
  }
  .pp-filters.pp-filters-open { right: 0; }
  .pp-filters-mobile-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.85rem;
    margin-bottom: 1.5rem;
    border: 1px solid var(--pp-border);
    border-radius: var(--pp-radius);
    background: var(--pp-surface);
    color: var(--pp-text);
    cursor: pointer;
  }
  .pp-filters-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    z-index: 290;
  }
  .pp-filters-backdrop.pp-filters-backdrop-visible { display: block; }
}

.pp-property-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.75rem;
}

@media (max-width: 1024px) {
  .pp-property-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .pp-property-grid { grid-template-columns: 1fr; }
}

#pp-listings-results {
  transition: opacity 0.25s ease;
}

#pp-listings-results.pp-listings-loading {
  opacity: 0.45;
  pointer-events: none;
}

.pp-card {
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-lg);
  overflow: hidden;
  transition: var(--pp-transition);
}

.pp-card:hover { border-color: var(--pp-gold); }

.pp-card-image {
  width: 100%;
  height: 200px;
  object-fit: cover;
  background: var(--pp-black-soft);
  transition: transform 0.5s ease;
}

/* Elevation + a subtle image zoom, desktop/mouse only - guarded by
   hover:hover + pointer:fine so this never fires as a "sticky" hover
   state on touch devices, where :hover only clears on a second, unrelated
   tap and would otherwise leave a card looking permanently lifted. */
@media (hover: hover) and (pointer: fine) {
  .pp-card:hover {
    transform: translateY(-6px);
    box-shadow: 0 20px 36px -16px rgba(0,0,0,0.22);
  }
  .pp-card:hover .pp-card-image { transform: scale(1.06); }
  .pp-region-card:hover { transform: translateY(-3px); }
}

.pp-card-image-fallback {
  width: 100%;
  height: 200px;
  background: var(--pp-black-soft);
  color: var(--pp-gold);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.75rem;
}

.pp-card-body { padding: 1.25rem; }

.pp-card-price {
  font-family: var(--pp-font-display);
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--pp-gold);
  margin: 0 0 0.35rem;
}

.pp-card-title {
  font-size: 0.95rem;
  font-weight: 600;
  margin: 0 0 0.35rem;
}

.pp-card-location {
  font-size: 0.8rem;
  color: var(--pp-text-muted);
  display: flex;
  align-items: center;
  gap: 0.3rem;
  margin-bottom: 0.75rem;
}

.pp-card-meta {
  display: flex;
  gap: 1rem;
  font-size: 0.8rem;
  color: var(--pp-text-muted);
  margin-bottom: 1rem;
}

.pp-card-actions {
  display: flex;
  gap: 0.5rem;
}

.pp-card-actions .pp-btn { flex: 1; justify-content: center; padding: 0.6rem 0.75rem; font-size: 0.78rem; }

.pp-btn-whatsapp {
  background: transparent;
  border-color: var(--pp-border);
  color: var(--pp-text);
}

.pp-btn-whatsapp:hover { border-color: var(--pp-gold); }

.pp-whatsapp-icon { color: #25D366; }

.pp-pagination {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 3rem;
}

.pp-pagination a, .pp-pagination span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--pp-radius);
  border: 1px solid var(--pp-border);
  font-size: 0.85rem;
  color: var(--pp-text);
}

.pp-pagination a:hover { border-color: var(--pp-gold); }

.pp-pagination .pp-page-active {
  background: var(--pp-gold);
  border-color: var(--pp-gold);
  color: var(--pp-black);
}

.pp-empty {
  text-align: center;
  padding: 4rem 1rem;
  color: var(--pp-text-muted);
}

.pp-connect-grid {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 2rem;
  align-items: start;
}

@media (max-width: 860px) {
  .pp-connect-grid { grid-template-columns: 1fr; }
}

.pp-connect-form-card,
.pp-social-card {
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-lg);
  padding: 2rem;
}

/* .pp-social-card previously stood alone, centered, at a capped width
   (max-width:420px;margin:0 auto) - now it's one column of the grid
   above, so its own width/centering is no longer needed; text stays
   centered since that still suits a short "follow us" card, while the
   contact form card next to it is left-aligned (form fields read
   naturally left-to-right, not centered). */
.pp-social-card { text-align: center; height: 100%; display: flex; flex-direction: column; justify-content: center; }

.pp-social-links {
  display: flex;
  justify-content: center;
  gap: 0.9rem;
  margin-top: 1.25rem;
}

.pp-social-links a {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid var(--pp-border);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: var(--pp-transition);
}

.pp-social-links a:hover { border-color: var(--pp-gold); color: var(--pp-gold); }

/* ── Contact form (owner_portfolio.html #connect) ── */
.pp-contact-form { display: flex; flex-direction: column; gap: 0.9rem; }

.pp-form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.9rem;
}

@media (max-width: 480px) {
  .pp-form-row { grid-template-columns: 1fr; }
}

.pp-form-input,
.pp-contact-form input,
.pp-contact-form textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 0.75rem 1rem;
  background: var(--pp-bg);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius);
  color: var(--pp-text);
  font-family: var(--pp-font-body);
  font-size: 0.9rem;
  transition: var(--pp-transition);
}

.pp-contact-form input:focus,
.pp-contact-form textarea:focus {
  outline: none;
  border-color: var(--pp-gold);
}

.pp-contact-form textarea { resize: vertical; min-height: 100px; }

/* ── Django messages (success/error banner after a form submit
   redirect) - this page has no prior use of the messages framework, so
   there's no existing styling for it to inherit. ── */
.pp-form-messages { max-width: 640px; margin: 0 auto 2rem; }

.pp-form-message {
  padding: 0.85rem 1.1rem;
  border-radius: var(--pp-radius);
  font-size: 0.88rem;
  margin: 0 0 0.6rem;
  border: 1px solid var(--pp-border);
  background: var(--pp-surface);
}

.pp-form-message-success { border-color: rgba(34,197,94,0.4); color: #4ADE80; }
.pp-form-message-error { border-color: rgba(239,68,68,0.4); color: #F87171; }

.pp-footer {
  background: var(--pp-black);
  color: rgba(251,250,248,0.7);
  scroll-snap-align: start;
}

.pp-footer-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  padding: 1.75rem 0;
  border-bottom: 1px solid rgba(255,255,255,0.08);
}

.pp-footer-cta-text {
  font-family: var(--pp-font-display);
  color: #FBFAF8;
  font-size: 1.2rem;
  margin: 0;
}

.pp-footer-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr 1fr;
  gap: 2rem;
  padding: 3rem 0;
}

@media (max-width: 980px) {
  .pp-footer-grid { grid-template-columns: repeat(2, 1fr); }
  .pp-footer-brand { grid-column: 1 / -1; }
}

@media (max-width: 560px) {
  .pp-footer-grid { grid-template-columns: 1fr; gap: 1.75rem; }
}

.pp-footer-logo {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--pp-gold);
  margin-bottom: 0.85rem;
}

.pp-footer-brand-name {
  font-family: var(--pp-font-display);
  color: #FBFAF8;
  font-size: 1.15rem;
  margin: 0 0 0.6rem;
}

.pp-footer-desc {
  font-size: 0.85rem;
  line-height: 1.7;
  max-width: 320px;
  margin: 0;
}

.pp-footer-heading {
  color: var(--pp-gold-light);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin: 0 0 1rem;
}

.pp-footer-col { display: flex; flex-direction: column; gap: 0.65rem; }

.pp-footer-col a,
.pp-footer-location {
  color: rgba(251,250,248,0.7);
  font-size: 0.85rem;
  transition: color 0.2s ease;
}

.pp-footer-col a:hover { color: var(--pp-gold-light); }

.pp-footer-social {
  display: flex;
  gap: 0.65rem;
}

.pp-footer-social a {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(251,250,248,0.75);
  transition: var(--pp-transition);
}

.pp-footer-social a:hover {
  border-color: var(--pp-gold);
  color: var(--pp-gold-light);
}

.pp-footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 1.25rem 0;
  border-top: 1px solid rgba(255,255,255,0.08);
  font-size: 0.75rem;
}

.pp-footer-bottom p { margin: 0; }

.pp-footer-sub {
  letter-spacing: 0.05em;
  color: rgba(251,250,248,0.4);
}

/* ── Analytics dashboard ── */
.pp-analytics-page {
  padding: 7rem 0 4rem;
  min-height: 100vh;
}

.pp-analytics-title {
  font-family: var(--pp-font-display);
  font-size: 2rem;
  font-weight: 600;
  margin: 0 0 0.35rem;
}

.pp-analytics-sub {
  color: var(--pp-text-muted);
  font-size: 0.9rem;
  margin-bottom: 2rem;
}

.pp-stat-grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 1rem;
  margin-bottom: 2.5rem;
}

@media (max-width: 1024px) {
  .pp-stat-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 560px) {
  .pp-stat-grid { grid-template-columns: repeat(2, 1fr); }
}

.pp-stat-card {
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-lg);
  padding: 1.25rem;
}

.pp-stat-value {
  font-family: var(--pp-font-display);
  font-size: 1.75rem;
  font-weight: 600;
  color: var(--pp-gold);
  margin: 0 0 0.15rem;
}

.pp-stat-label {
  font-size: 0.75rem;
  color: var(--pp-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.pp-analytics-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 2rem;
  align-items: center;
}

.pp-range-btn {
  padding: 0.5rem 1.1rem;
  border-radius: var(--pp-radius);
  border: 1px solid var(--pp-border);
  background: var(--pp-surface);
  color: var(--pp-text);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}

.pp-range-btn.pp-range-active {
  background: var(--pp-gold);
  border-color: var(--pp-gold);
  color: var(--pp-black);
}

.pp-custom-range-form {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.pp-custom-range-form input {
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius);
  background: var(--pp-bg);
  color: var(--pp-text);
  font-family: var(--pp-font-body);
  font-size: 0.8rem;
}

.pp-analytics-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  margin-bottom: 1.5rem;
}

@media (max-width: 900px) {
  .pp-analytics-grid { grid-template-columns: 1fr; }
}

.pp-chart-card {
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-lg);
  padding: 1.5rem;
}

.pp-chart-card h3 {
  font-family: var(--pp-font-display);
  font-size: 1.1rem;
  margin: 0 0 1rem;
}

.pp-analytics-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.pp-analytics-table th {
  text-align: left;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pp-text-muted);
  padding: 0.5rem 0.25rem;
  border-bottom: 1px solid var(--pp-border);
}

.pp-analytics-table td {
  padding: 0.6rem 0.25rem;
  border-bottom: 1px solid var(--pp-border);
}

.pp-bar-track {
  background: var(--pp-bg);
  border-radius: 999px;
  height: 6px;
  overflow: hidden;
  width: 80px;
  display: inline-block;
  margin-right: 0.5rem;
  vertical-align: middle;
}

.pp-bar-fill {
  height: 100%;
  background: var(--pp-gold);
}

/* ── Alternating section backgrounds ──
   Odd sections (About, Listings, Connect) sit on deep black; even
   sections (Categories, Reviews) sit on a lighter charcoal shade - two
   distinct, fully-opaque tones of black, not a translucent tint (the
   old dark-mode --pp-alt-bg was only 8% opacity over an already-black
   page background, which was visually almost identical to no tint at
   all). A hairline border marks the seam between every section so the
   alternation actually reads as sections, not one continuous field. */
:root { --pp-alt-bg: rgba(184,147,90,0.06); }
[data-pp-theme="dark"] { --pp-alt-bg: var(--pp-black-soft); }

.pp-bg-light { background: var(--pp-alt-bg); }
.pp-bg-default { background: var(--pp-bg); }

.pp-bg-light, .pp-bg-default, .pp-feature-strip, .pp-region-marquee {
  border-top: 1px solid var(--pp-border);
}

/* ── Header nav + hamburger ── */
.pp-header-nav {
  display: flex;
  align-items: center;
  gap: 1.75rem;
}

.pp-header-nav a:not(.pp-btn) {
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  /* While the header is still transparent (floating over the dark hero
     photo/overlay, both themes), nav links need a light color regardless
     of the page theme - in light mode, var(--pp-text) is near-black and
     unreadable over the dark hero. Once .pp-header-solid kicks in below,
     the header itself becomes var(--pp-surface) (light in light mode,
     dark in dark mode), so links switch to the theme-aware var(--pp-text)
     there instead. */
  color: rgba(251,250,248,0.92);
  opacity: 0.9;
}

.pp-header-nav a:not(.pp-btn):hover { opacity: 1; color: var(--pp-gold-light); }

.pp-header-solid .pp-header-nav a:not(.pp-btn) {
  color: var(--pp-text);
  opacity: 0.85;
}

.pp-header-solid .pp-header-nav a:not(.pp-btn):hover { opacity: 1; color: var(--pp-gold); }

/* Below the 860px breakpoint the nav becomes a slide-in drawer with its
   own solid var(--pp-surface) background (see the drawer rules further
   down) regardless of whether .pp-header-solid is set - so links inside
   it always need the theme-aware dark-on-light/light-on-dark color, never
   the light-on-transparent-hero color above. */
@media (max-width: 860px) {
  .pp-header-nav a:not(.pp-btn) {
    color: var(--pp-text);
    /* Full opacity here (not the 0.85/0.9 used above) - those exist to
       keep nav text from overpowering the hero photo behind a
       *transparent* header, which doesn't apply once the nav is this
       solid, opaque drawer. Carrying that dimming over just made the
       links look washed out against the drawer's own background for
       no reason. */
    opacity: 1;
    font-size: 0.95rem;
  }
}

.pp-header-nav-actions {
  display: flex;
  gap: 0.6rem;
}

.pp-hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--pp-border);
  background: var(--pp-surface);
  cursor: pointer;
  align-items: center;
}

.pp-hamburger span {
  width: 16px;
  height: 2px;
  background: var(--pp-text);
  transition: var(--pp-transition);
}

.pp-nav-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 150;
}

.pp-nav-backdrop.pp-nav-backdrop-visible { display: block; }

/* Hidden by default (only meant for the drawer) - shown by the 860px
   rule below once the standalone header toggle disappears. Must come
   BEFORE that @media block in source order: two rules of equal
   specificity resolve by source order regardless of which one is
   inside a media query, so a later unconditional rule would otherwise
   cancel out the media query's display:flex even while it's active. */
.pp-nav-theme-toggle {
  display: none;
  align-items: center;
  justify-content: flex-start;
  gap: 0.65rem;
  width: 100%;
  height: auto;
  border-radius: 0;
  margin-top: auto;
  padding-top: 1.5rem;
  padding-left: 0;
  padding-right: 0;
  padding-bottom: 0;
  border-top: 1px solid var(--pp-border);
  border-left: none;
  border-right: none;
  border-bottom: none;
  background: none;
  color: var(--pp-text);
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

.pp-nav-theme-toggle-label { flex: 1; text-align: left; }

@media (max-width: 860px) {
  .pp-hamburger { display: flex; }

  /* The standalone header toggle only makes sense while the full nav is
     visible inline (desktop) - once it collapses into the drawer below
     860px, .pp-nav-theme-toggle inside that drawer takes over instead,
     so this doesn't just duplicate it as a second control up top. */
  .pp-header-actions > .pp-theme-toggle { display: none; }

  .pp-header-nav {
    position: fixed;
    top: 0;
    right: -100%;
    height: 100%;
    width: min(300px, 85vw);
    background: var(--pp-surface);
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    padding: 5.5rem 1.75rem 2rem;
    gap: 1.5rem;
    z-index: 200;
    transition: right 0.3s ease;
    box-shadow: -8px 0 24px rgba(0,0,0,0.15);
  }

  .pp-header-nav.pp-nav-open { right: 0; }

  .pp-header-nav-actions {
    flex-direction: column;
    width: 100%;
  }

  .pp-header-nav-actions .pp-btn { width: 100%; justify-content: center; }

  .pp-nav-theme-toggle {
    display: flex;
  }
}

/* ── Hero: animated counters ── */
.pp-hero-counters {
  display: flex;
  gap: 2.5rem;
  margin-top: 2.25rem;
  flex-wrap: wrap;
  justify-content: flex-start;
}
.pp-hero-counter-value {
  font-family: var(--pp-font-display);
  color: var(--pp-gold-light);
  font-size: clamp(1.5rem, 3.5vw, 2.25rem);
  font-weight: 600;
  line-height: 1;
}

.pp-hero-counter-label {
  color: rgba(251,250,248,0.65);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-top: 0.35rem;
}

/* ── Hero: scroll cue ── */
.pp-hero-scroll-cue {
  position: absolute;
  left: 50%;
  bottom: 1.75rem;
  transform: translateX(-50%);
  z-index: 2;
  color: rgba(251,250,248,0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid rgba(251,250,248,0.3);
  border-radius: 50%;
  transition: var(--pp-transition);
  animation: pp-scroll-cue-bounce 2.2s ease-in-out infinite;
}

.pp-hero-scroll-cue:hover {
  border-color: var(--pp-gold);
  color: var(--pp-gold-light);
}

@keyframes pp-scroll-cue-bounce {
  0%, 100% { transform: translate(-50%, 0); }
  50% { transform: translate(-50%, 8px); }
}

@media (prefers-reduced-motion: reduce) {
  .pp-hero-scroll-cue { animation: none; }
}

/* Dropped below 640px: the hero is already content-driven (height:auto,
   see .pp-hero above) rather than a fixed viewport box with guaranteed
   spare room at the bottom for this to float in, and it's a "nice to
   have" nudge, not a functional control - not worth adding it back into
   the vertical space budget on the smallest screens. */
@media (max-width: 640px) {
  .pp-hero-scroll-cue { display: none; }
}

/* ── Region marquee (below hero) ── */
.pp-region-marquee {
  background: var(--pp-black);
  padding: 1.5rem 0;
  overflow: hidden;
}

.pp-region-track {
  display: flex;
  gap: 1rem;
  width: max-content;
  animation: pp-region-scroll 34s linear infinite;
}

.pp-region-marquee:hover .pp-region-track { animation-play-state: paused; }

@keyframes pp-region-scroll {
  0% { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

.pp-region-card {
  display: flex;
  align-items: stretch;
  flex-shrink: 0;
  width: 260px;
  border: 1px solid rgba(184,147,90,0.3);
  border-radius: var(--pp-radius);
  background: rgba(255,255,255,0.03);
  transition: var(--pp-transition);
  overflow: hidden;
}

.pp-region-card:hover {
  border-color: var(--pp-gold);
  background: rgba(184,147,90,0.08);
}

.pp-region-card-image {
  width: 88px;
  flex-shrink: 0;
  background-size: cover;
  background-position: center;
}

.pp-region-card-body {
  padding: 0.9rem 1.1rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}

.pp-region-card-name {
  color: #F2F0EB;
  font-family: var(--pp-font-display);
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0 0 0.2rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pp-region-card-count {
  color: var(--pp-gold-light);
  font-size: 0.78rem;
  letter-spacing: 0.03em;
}

@media (prefers-reduced-motion: reduce) {
  .pp-region-track { animation: none; flex-wrap: wrap; }
}

/* ── About: features list ── */
.pp-about-features {
  list-style: none;
  margin: 1.75rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.9rem;
}

.pp-about-feature {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-size: 0.88rem;
  font-weight: 500;
}

.pp-about-feature-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid var(--pp-gold);
  color: var(--pp-gold-light);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

@media (max-width: 480px) {
  .pp-about-features { grid-template-columns: 1fr; }
}

/* ── Category section ── */
.pp-category-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.25rem;
}

@media (max-width: 860px) {
  .pp-category-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 560px) {
  .pp-category-grid { grid-template-columns: repeat(2, 1fr); }
}

.pp-category-card {
  position: relative;
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-lg);
  padding: 1.75rem 1.25rem 1.5rem;
  text-align: center;
  transition: var(--pp-transition), box-shadow 0.3s ease;
  cursor: pointer;
  overflow: hidden;
}

/* Thin gold accent bar across the top - hidden until hover, when it
   slides fully into view, echoing the lift/border-color treatment used
   on hover elsewhere in this design system. */
.pp-category-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--pp-gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s ease;
}

.pp-category-card:hover {
  border-color: var(--pp-gold);
  transform: translateY(-4px);
  box-shadow: 0 12px 28px -12px rgba(11,11,12,0.25);
}

.pp-category-card:hover::before { transform: scaleX(1); }

.pp-category-card-icon {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 1.5px solid var(--pp-gold);
  color: var(--pp-gold-light);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 0.9rem;
  transition: transform 0.3s ease, background 0.3s ease;
}

.pp-category-card:hover .pp-category-card-icon {
  background: var(--pp-gold);
  color: var(--pp-black);
  transform: translateY(-2px);
}

.pp-category-card-label {
  font-family: var(--pp-font-display);
  font-size: 1.05rem;
  font-weight: 600;
  margin: 0 0 0.3rem;
}

.pp-category-card-count {
  color: var(--pp-text-muted);
  font-size: 0.78rem;
  margin: 0 0 0.85rem;
}

.pp-category-card-link {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--pp-gold);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.25s ease, transform 0.25s ease;
}

.pp-category-card:hover .pp-category-card-link {
  opacity: 1;
  transform: translateY(0);
}

/* ── Featured properties ── */
.pp-featured-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

@media (max-width: 980px) {
  .pp-featured-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .pp-featured-grid { grid-template-columns: 1fr; }
}

.pp-featured-card {
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-lg);
  overflow: hidden;
  transition: var(--pp-transition), box-shadow 0.3s ease;
}

.pp-featured-card:hover {
  border-color: var(--pp-gold);
  transform: translateY(-4px);
  box-shadow: 0 16px 32px -14px rgba(11,11,12,0.3);
}

.pp-featured-media {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--pp-black);
}

.pp-featured-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s ease;
}

.pp-featured-card:hover .pp-featured-media img { transform: scale(1.06); }

.pp-featured-badge {
  position: absolute;
  top: 0.9rem;
  left: 0.9rem;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: var(--pp-gold);
  color: var(--pp-black);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0.3rem 0.65rem;
  border-radius: 999px;
}

.pp-featured-body { padding: 1.35rem; }

.pp-featured-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
}

.pp-featured-title {
  font-family: var(--pp-font-display);
  font-size: 1.15rem;
  font-weight: 600;
  margin: 0;
  line-height: 1.3;
}

.pp-featured-rating {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--pp-gold);
  flex-shrink: 0;
}

.pp-featured-location {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--pp-text-muted);
  font-size: 0.82rem;
  margin: 0.4rem 0 0.75rem;
}

.pp-featured-desc {
  color: var(--pp-text-muted);
  font-size: 0.88rem;
  line-height: 1.6;
  margin: 0 0 0.9rem;
}

.pp-featured-meta {
  display: flex;
  gap: 1rem;
  font-size: 0.8rem;
  color: var(--pp-text-muted);
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--pp-border);
  margin-bottom: 0.9rem;
}

.pp-featured-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.pp-featured-price {
  font-family: var(--pp-font-display);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--pp-gold);
  margin: 0;
}

.pp-featured-link {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--pp-text);
  white-space: nowrap;
  transition: color 0.2s ease;
}

.pp-featured-link:hover { color: var(--pp-gold); }

/* ── Testimonials ── */
.pp-testimonial-fallback-tag {
  display: inline-block;
  font-size: 0.65rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pp-text-muted);
  border: 1px solid var(--pp-border);
  border-radius: 999px;
  padding: 0.15rem 0.6rem;
  margin-bottom: 0.75rem;
}

/* ── Reviews: a 3-up card grid per "page", crossfading between pages
   when there are more than 3 - stacked absolutely-positioned panels
   (same approach as the hero slideshow), one fully opaque at a time.
   The track's height is set from JS (see the review-carousel script)
   to match whichever panel is active, since a 1-column mobile stack of
   3 cards is far taller than the same 3 cards in a desktop row. */
.pp-review-carousel {
  position: relative;
}

.pp-review-track {
  position: relative;
  min-height: 280px;
  transition: height 0.35s ease;
}

.pp-review-panel {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1s ease-in-out;
}

.pp-review-panel.pp-review-panel-active {
  opacity: 1;
  z-index: 1;
}

.pp-review-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

@media (max-width: 900px) {
  .pp-review-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  .pp-review-grid { grid-template-columns: 1fr; }
}

.pp-review-card {
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-lg);
  padding: 1.75rem;
  height: 100%;
  text-align: left;
}

.pp-review-stars {
  color: var(--pp-gold);
  font-size: 1rem;
  margin-bottom: 1rem;
}

.pp-review-quote {
  color: var(--pp-text-muted);
  line-height: 1.7;
  font-size: 0.95rem;
  font-style: italic;
  margin: 0 0 1.5rem;
  min-height: 3.4em;
}

.pp-review-person {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-top: 1rem;
  border-top: 1px solid var(--pp-border);
}

.pp-review-avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--pp-black);
  color: var(--pp-gold);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--pp-font-display);
  font-weight: 700;
  font-size: 0.95rem;
  flex-shrink: 0;
}

.pp-review-author {
  font-weight: 600;
  font-size: 0.9rem;
  margin: 0;
}

.pp-review-property {
  font-size: 0.78rem;
  color: var(--pp-text-muted);
  margin: 0.1rem 0 0;
}

.pp-review-dots {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 1.75rem;
}

.pp-review-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: none;
  background: var(--pp-border);
  cursor: pointer;
  padding: 0;
  transition: background 0.3s ease, transform 0.3s ease;
}

.pp-review-dot-active {
  background: var(--pp-gold);
  transform: scale(1.3);
}

@media (prefers-reduced-motion: reduce) {
  .pp-review-panel { transition: none; }
}

/* ── Scroll-reveal ── */
.pp-reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}

.pp-reveal.pp-revealed {
  opacity: 1;
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .pp-reveal { opacity: 1; transform: none; transition: none; }
}

/* ── Property detail page ── */
.pp-property-detail {
  padding: 7rem 0 4rem;
}

.pp-back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--pp-text-muted);
  margin-bottom: 1.5rem;
}

.pp-back-link:hover { color: var(--pp-gold); }

.pp-pd-gallery { margin-bottom: 2rem; }

.pp-pd-main-frame {
  position: relative;
  width: 100%;
  height: 460px;
  border-radius: var(--pp-radius-lg);
  overflow: hidden;
  background: var(--pp-black-soft);
}

.pp-pd-main-photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.pp-pd-main-fallback {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--pp-gold);
}

.pp-pd-counter {
  position: absolute;
  bottom: 1rem;
  left: 1rem;
  background: rgba(11,11,12,0.7);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
}

.pp-pd-thumb-row {
  display: flex;
  gap: 0.6rem;
  overflow-x: auto;
  padding: 0.75rem 0.1rem 0;
}

.pp-pd-thumb {
  display: block;
  flex-shrink: 0;
  width: 90px;
  height: 68px;
  border-radius: var(--pp-radius);
  overflow: hidden;
  border: 2px solid transparent;
  padding: 0;
  cursor: pointer;
  opacity: 0.6;
  background: none;
  transition: var(--pp-transition);
}

.pp-pd-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

.pp-pd-thumb:hover { opacity: 0.85; }

.pp-pd-thumb-active {
  opacity: 1;
  border-color: var(--pp-gold);
}

.pp-pd-layout {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 2.5rem;
  align-items: start;
}

@media (max-width: 900px) {
  .pp-pd-layout { grid-template-columns: 1fr; }
  .pp-pd-main-frame { height: 300px; }
}

.pp-pd-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
}

.pp-pd-price {
  font-family: var(--pp-font-display);
  font-size: 1.9rem;
  font-weight: 700;
  color: var(--pp-gold);
  margin: 0 0 0.35rem;
}

.pp-pd-price-suffix { font-size: 1rem; color: var(--pp-text-muted); font-weight: 400; }

.pp-pd-title {
  font-family: var(--pp-font-display);
  font-size: 1.5rem;
  font-weight: 600;
  margin: 0 0 0.4rem;
}

.pp-pd-location {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--pp-text-muted);
  font-size: 0.9rem;
}

.pp-pd-status-badge {
  padding: 0.4rem 0.9rem;
  border-radius: 999px;
  border: 1px solid var(--pp-gold);
  color: var(--pp-gold);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.pp-pd-facts {
  display: flex;
  gap: 2rem;
  flex-wrap: wrap;
  padding: 1.25rem 0;
  border-top: 1px solid var(--pp-border);
  border-bottom: 1px solid var(--pp-border);
  margin-bottom: 2rem;
}

.pp-pd-fact { display: flex; flex-direction: column; }

.pp-pd-fact-value {
  font-family: var(--pp-font-display);
  font-size: 1.3rem;
  font-weight: 600;
}

.pp-pd-fact-label {
  font-size: 0.72rem;
  color: var(--pp-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: 0.15rem;
}

.pp-pd-section { margin-bottom: 2rem; }

.pp-pd-section-title {
  font-family: var(--pp-font-display);
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0 0 1rem;
}

.pp-pd-desc {
  color: var(--pp-text-muted);
  line-height: 1.8;
}

.pp-pd-amenities {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
}

.pp-pd-amenities li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.88rem;
}

.pp-pd-amenities svg { color: var(--pp-gold); flex-shrink: 0; }

.pp-pd-sidebar { position: sticky; top: 90px; }

.pp-pd-contact-card {
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-lg);
  padding: 1.5rem;
}

.pp-pd-contact-owner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.pp-pd-contact-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--pp-gold);
}

.pp-pd-contact-name { font-weight: 700; font-size: 0.95rem; margin: 0; }

.pp-pd-contact-role { font-size: 0.78rem; color: var(--pp-text-muted); margin: 0; }

@media (max-width: 480px) {
  .pp-pd-amenities { grid-template-columns: 1fr; }
  .pp-pd-facts { gap: 1.25rem; }
}
/* ── Floating actions: WhatsApp quick-contact + back-to-top ──
   Fixed to the viewport (not the page), so both float above every
   section regardless of scroll position or which section's own
   background/z-index is in play. z-index above .pp-header (100)/
   mobile nav drawer (200) so they're never hidden
   behind the header or an open filter/nav drawer. */
.pp-float-whatsapp {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 250;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: #25D366;
  color: #FFFFFF;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 24px -6px rgba(0,0,0,0.35);
  transition: var(--pp-transition);
}

.pp-float-whatsapp:hover {
  transform: translateY(-2px) scale(1.05);
  box-shadow: 0 12px 28px -6px rgba(0,0,0,0.4);
}

/* Overrides both the inline width/height and the standalone
   .pp-whatsapp-icon color rule (which sets the brand green - invisible
   against this button's own green circle background) with a higher-
   specificity, higher-cascade-order rule so the mark actually shows. */
.pp-float-whatsapp .pp-whatsapp-icon {
  width: 24px !important;
  height: 24px !important;
  color: #FFFFFF;
}

.pp-float-top {
  position: fixed;
  right: 1.25rem;
  bottom: 5.5rem;
  z-index: 250;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--pp-border);
  background: var(--pp-surface);
  color: var(--pp-text);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 8px 20px -8px rgba(0,0,0,0.25);
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease, border-color 0.25s ease;
}

.pp-float-top.pp-float-top-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.pp-float-top:hover { border-color: var(--pp-gold); color: var(--pp-gold); }

/* No WhatsApp button configured (owner hasn't set owner_whatsapp_number)
   -> back-to-top takes that slot instead of leaving an empty gap above
   nothing. :has() (not :only-of-type, which only compares elements of
   the same tag name and can't detect a different element's presence) is
   the correct tool here. */
body:not(:has(.pp-float-whatsapp)) .pp-float-top { bottom: 1.25rem; }

@media (max-width: 640px) {
  .pp-float-whatsapp { width: 50px; height: 50px; right: 1rem; bottom: 1rem; }
  .pp-float-whatsapp .pp-whatsapp-icon { width: 22px !important; height: 22px !important; }
  .pp-float-top { width: 40px; height: 40px; right: 1rem; bottom: 4.75rem; }
  body:not(:has(.pp-float-whatsapp)) .pp-float-top { bottom: 1rem; }
}

@media (prefers-reduced-motion: reduce) {
  .pp-float-whatsapp:hover { transform: none; }
  .pp-float-top { transition: opacity 0.25s ease; transform: none; }
}