/* =========================================================
   RTL motion + Arabic typography hierarchy.
   Imported FIRST so its CSS variable defaults can be
   overridden by the site tokens below where intentional.
   See BILINGUAL-RTL-MOTION-RULE.md.
   ========================================================= */
@import url('rtl-motion.css');

/* =========================================================
   THE GATE INVESTMENTS — SHARED SITE STYLES
   Used by all pages: index.html, careers.html, rate-my-property.html, landing/*
   ========================================================= */
:root{
  --navy-deep:#061533;
  --navy:#0A1F44;
  --navy-soft:#1A3060;
  --gold:#C9A961;
  --gold-soft:#E5C77A;
  --gold-deep:#A88A3F;
  --white:#FFFFFF;
  --offwhite:#F8F9FB;
  --stone:#E5E7EB;
  --slate:#6B7280;
  --charcoal:#0A0A0A;
  --whatsapp:#25D366;

  --font-display:'Playfair Display', serif;
  --font-body:'Inter', sans-serif;
  --font-ar:'Tajawal', sans-serif;

  --shadow-soft:0 2px 8px rgba(6,21,51,.06);
  --shadow-md:0 8px 24px rgba(6,21,51,.10);
  --shadow-lift:0 20px 60px rgba(6,21,51,.18);

  --radius-card:16px;
  --radius-btn:8px;

  --container:1280px;
  --container-pad:24px;

  /* ═══════════════════════════════════════════════════════════════════
     P2B — VISUAL SYSTEM TOKENS (Mobile + Responsive Polish proposal)
     ───────────────────────────────────────────────────────────────────
     Added 2026-05-17. UNUSED ON ADD: this block introduces the token
     vocabulary; existing CSS rules continue to use raw px values until
     subsequent P2C–P2H phases migrate them. No visual change should
     occur from this commit alone.

     Existing tokens above (--shadow-soft / --shadow-md / --shadow-lift,
     --radius-card / --radius-btn) are kept for back-compat. The new
     names below either complement them (--shadow-premium) or sit at
     a different abstraction level (--radius-sm/md/lg/pill replace
     ad-hoc per-page literals — the old --radius-card/--radius-btn stay
     as semantic aliases for now).

     CSS limitation: var() inside @media() is not supported, so
     breakpoint values are listed here as documentation only and must
     be typed literally in @media rules. The numbers below are the
     canonical set; future PRs should standardise on these.
     ═══════════════════════════════════════════════════════════════════ */

  /* — Spacing rhythm (vertical) ——————————————————————————————— */
  --space-section-mobile:  64px;   /* phones (≤540px) */
  --space-section-tablet:  80px;   /* tablets (541–1024px) */
  --space-section-desktop: 96px;   /* desktop (≥1025px) */
  --space-hero-mobile:     56px;   /* tighter for hero blocks on mobile */
  --space-hero-desktop:    80px;

  /* — Fine-grained spacing scale (4-px grid) ——————————————————— */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 48px;
  --space-9: 64px;

  /* — Heading fluid sizes — single source of truth ————————————— */
  --h1-fluid: clamp(28px, 5.5vw, 56px);
  --h2-fluid: clamp(22px, 3.5vw, 36px);
  --h3-fluid: clamp(18px, 2vw, 24px);
  --h4-fluid: 18px;

  /* — Border radius scale —————————————————————————————————————— */
  --radius-xs:   4px;     /* tiny chips / badges */
  --radius-sm:   8px;     /* buttons / inputs (alias of --radius-btn) */
  --radius-md:   14px;    /* cards (most common) */
  --radius-lg:   20px;    /* premium cards / hero panels */
  --radius-pill: 999px;   /* pills / segmented controls */
  /* 50% (circle) stays inline — not a token */

  /* — Shadow / elevation scale ————————————————————————————————
     The three existing shadows are kept above and referenced by name.
     --shadow-premium is new — for hero panels and modal backdrops. */
  --shadow-premium: 0 28px 80px rgba(6,21,51,.22);

  /* — Mobile FAB stack — single source of truth (Bugfix Sprint).
     iOS Safari's bottom URL bar overlays the last ~50px of viewport
     when scrolled to top, AND the gesture home-indicator on iPhone
     12+ adds another ~34px of safe-area. We add a small constant
     (12px) on top of safe-area so the bottom-most FAB never collides
     with the Safari toolbar shadow / home indicator on real devices.

     Stack arithmetic on mobile (from bottom up):
       WhatsApp:    bottom = --fab-bottom-mobile                  (≈70px from edge)
       back-to-top: bottom = --fab-bottom-mobile + 56 + gap-v     (≈140px from edge)
     On project.html and other sticky-CTA pages, the per-page
     overrides bump WhatsApp + back-to-top further up to clear the
     sticky bar (existing behavior — unchanged). */
  --fab-bottom-mobile:   calc(24px + 12px + env(safe-area-inset-bottom, 0px));
  --fab-bottom-desktop:  24px;
  --fab-bottom-tablet:   32px;   /* V228 — tablet 769–1599: floats sit ~8px higher than desktop for better thumb-zone clearance */
  --fab-gap-vertical:    14px;
  --space-section-tablet: 60px;  /* V228 — tablet 769–1599 section rhythm (between mobile 64 and desktop 96) */

  /* — Z-index layers ——————————————————————————————————————————
     Max value 1200. Replaces ad-hoc values that today run up to 99999.
     Per-rule migration is deferred to P2F. */
  --z-base:     1;
  --z-elevated: 10;     /* decorative overlap, hover-lift */
  --z-sticky:   100;    /* nav, sticky CTA */
  --z-fab:      200;    /* WhatsApp / back-to-top floats */
  --z-overlay:  1000;   /* lightboxes, dimmers */
  --z-modal:    1100;   /* modal dialogs */
  --z-toast:    1200;   /* top-most ephemeral */

  /* — Motion: durations + easing curves ———————————————————————— */
  --motion-fast: 150ms;
  --motion-base: 250ms;
  --motion-slow: 400ms;
  --ease-out:     ease;
  --ease-premium: cubic-bezier(.22, .61, .36, 1);

  /* — Breakpoints (documentation; not consumable inside @media) ——
     --bp-xs:  380px    very small phones (use sparingly)
     --bp-sm:  540px    most phones — single-column trigger
     --bp-md:  768px    small tablets — 2-column grids
     --bp-lg:  1024px   large tablets / small laptops — 3-column grids
     --bp-xl:  1280px   desktop standard layout
     Container-widening trio (1400 / 1600 / 1920) lives elsewhere. */
}

/* === RESPONSIVE CONTAINER WIDTH ===
   Default 1280px stays for ≤1399px viewports (laptops + small desktops).
   Widens progressively on larger screens so the site uses more of the canvas
   without ever getting so wide that line-lengths become uncomfortable.
   Side padding scales up too for a premium balanced feel. */
@media (min-width:1400px){ :root{ --container:1360px; --container-pad:32px } }
@media (min-width:1600px){ :root{ --container:1480px; --container-pad:36px } }
@media (min-width:1920px){ :root{ --container:1600px; --container-pad:40px } }
html[dir="rtl"]{ --font-display:'Tajawal', sans-serif; --font-body:'Tajawal', sans-serif; }

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  font-family:var(--font-body);color:var(--charcoal);background:var(--white);
  line-height:1.6;-webkit-font-smoothing:antialiased;
  /* overflow-x:clip — modern alternative to hidden that doesn't break position:sticky inside */
  overflow-x:clip;
}
/* Fallback for very old browsers — keep hidden if clip isn't supported */
@supports not (overflow-x: clip){
  body{overflow-x:hidden}
}
img{max-width:100%;display:block}
a{text-decoration:none;color:inherit}
button{font-family:inherit;cursor:pointer;border:none;background:none}

.container{max-width:var(--container);margin:0 auto;padding:0 var(--container-pad)}
@media (max-width:540px){ .container{ padding:0 16px } }
/* P2C — Section rhythm now consumes --space-section-desktop / --space-section-mobile
   tokens (defined in :root above). Identical pixel values to before (96/64);
   tokenisation makes future global tuning a one-line change. The tablet-band
   token (--space-section-tablet: 80px) is reserved for sections that opt into
   a one-step-tighter rhythm — currently used as-is by .dev-section,
   .lead-section, and .similar-section (their individual rules below). */
section{padding:var(--space-section-desktop) 0}
@media(max-width:768px){ section{padding:var(--space-section-mobile) 0} }
/* Bugfix sprint — on the very narrow phones the 64px rhythm still
   leaves visibly large blank gaps between alternating dark/white
   sections; tighten to 44px so neighbouring sections feel connected. */
@media(max-width:540px){ section{padding:44px 0} }
/* V228 — T2: tablet section rhythm. 769–1599 gets its own tier (60/60)
   sitting between mobile 64 and desktop 96. Bare `section` selector only —
   sections with their own padding rules (.hero, .market-pulse, .areas, .lead-section,
   .dev-section, .similar-section, etc.) keep winning by specificity. ≤540 mobile
   rule above wins inside its own scope. */
@media (min-width:768px) and (max-width:1599px){
  section{ padding: var(--space-section-tablet) 0 }
}

h1,h2,h3,h4{font-family:var(--font-display);font-weight:600;color:var(--navy-deep);letter-spacing:-.5px}

/* Auto-white headings inside dark sections (prevents "invisible heading" bug) */
.page-hero h1, .page-hero h2, .page-hero h3, .page-hero h4,
.area-cover h1, .area-cover h2, .area-cover h3, .area-cover h4,
.dev-cover h1, .dev-cover h2, .dev-cover h3, .dev-cover h4,
.cta-band h1, .cta-band h2, .cta-band h3,
footer h1, footer h2, footer h3, footer h4, footer h5, footer h6,
.area-card .ac-img-content h1, .area-card .ac-img-content h2, .area-card .ac-img-content h3,
.glance-card h1, .glance-card h2, .glance-card h3,
.area-lead h1, .area-lead h2,
.dev-lead h1, .dev-lead h2{color:#fff}
/* P2D — Global heading rules now consume the --h*-fluid tokens defined in
   :root (see P2B block above). Per-page hero overrides remain where the
   visual brief calls for a larger or differently-tuned size; everywhere
   else the global cascade wins. */
h1{font-size:var(--h1-fluid);line-height:1.1;font-weight:700}
h2{font-size:var(--h2-fluid);line-height:1.2}
h3{font-size:var(--h3-fluid);line-height:1.3}
h4{font-size:var(--h4-fluid);line-height:1.4}
.eyebrow{
  display:inline-block;font-family:var(--font-body);font-size:13px;font-weight:600;
  text-transform:uppercase;letter-spacing:2px;color:var(--gold-deep);margin-bottom:16px;
}
/* =========================================================
   PREMIUM SECTION HEADER — editorial drama for "New Launches",
   "Featured", "Areas", etc. Subtle watermark, gold dividers,
   reveal motion. Backwards-compatible with existing markup.
   ========================================================= */
.section-head{
  text-align:center;max-width:760px;margin:0 auto 56px;
  position:relative;
  /* Generous top padding so the large gold watermark can breathe FULLY ABOVE
     the white heading — never overlap. The watermark is up to ~156px tall,
     so the slogan needs to start below that. Hierarchy reads:
       1. large gold word
       2. white slogan
       3. supporting paragraph */
  padding-top:170px;
}
@media(max-width:1100px){
  .section-head{ padding-top:140px }
}
@media(max-width:768px){
  .section-head{ padding-top:115px }
}
/* The New Launches watermark is intentionally smaller, so its slogan can sit
   a touch closer for a tighter cinematic feel. */
.launches-section .section-head{ padding-top:130px }
@media(max-width:1100px){
  .launches-section .section-head{ padding-top:110px }
}
@media(max-width:768px){
  .launches-section .section-head{ padding-top:90px }
}
.section-head .eyebrow{
  display:inline-flex;align-items:center;justify-content:center;gap:14px;
  font-size:11.5px;font-weight:800;letter-spacing:5px;text-transform:uppercase;
  color:var(--gold-deep);margin-bottom:18px;
}
.section-head h2{
  font-family:var(--font-display);
  font-size:clamp(28px, 4vw, 42px);font-weight:600;line-height:1.15;
  color:var(--navy-deep);margin:0 0 10px;letter-spacing:-.4px;
  position:relative;
}
.section-head h2::after{
  content:"";display:block;width:48px;height:2px;border-radius:2px;
  background:linear-gradient(90deg, transparent, var(--gold) 50%, transparent);
  margin:18px auto 0;
}
.section-head p{
  color:var(--slate);font-size:17px;line-height:1.65;margin:8px auto 0;max-width:600px;
  letter-spacing:.1px;
}

/* ============================================================================
   ARCHITECTURAL WATERMARK — section identity layer (cinematic backdrop)
   ----------------------------------------------------------------------------
   Oversized display word sitting behind each section heading. Opacity tuned
   to read clearly without dominating: ~28% gold at the top, holding visible
   density through the upper third of the heading box, then fading to 0
   beyond the H2's baseline. Subtle drop-shadow gives architectural depth.
   In Arabic mode the same effect uses [data-watermark-ar] when authored.
   ============================================================================ */
.section-head[data-watermark]::before{
  content:attr(data-watermark);
  /* Anchored at the very top of the section-head's padded zone so the white
     heading below has clear breathing room. */
  position:absolute;top:0;left:50%;transform:translateX(-50%);
  font-family:var(--font-display);
  /* Cinematic architectural type, slight tracking for editorial drama */
  font-size:clamp(88px, 11.5vw, 156px);
  font-weight:800;
  letter-spacing:-.5px;
  /* Stronger gold gradient — fades from a bold shoulder at the top to clean
     transparency at the H2's baseline. Reads clearly without dominating. */
  background:linear-gradient(180deg,
    rgba(201,169,97,.46) 0%,
    rgba(201,169,97,.34) 28%,
    rgba(201,169,97,.18) 60%,
    rgba(201,169,97,0)   92%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  /* Layered glow — a tight inner halo + a wider warm bronze drop for depth */
  filter:
    drop-shadow(0 2px 0 rgba(255,255,255,.55))
    drop-shadow(0 10px 28px rgba(201,169,97,.22));
  pointer-events:none;white-space:nowrap;line-height:1;z-index:0;
  user-select:none;
  max-width:100vw;overflow:hidden;text-overflow:ellipsis;
}
@media(max-width:768px){
  .section-head[data-watermark]::before{
    /* Mobile bugfix — make the watermark feel like faint luxury background
       typography rather than a visible floating gold object. The previous
       40%/28%/12% gradient stops were strong enough that short words like
       "Map" or "Why Us" read as a solid gold rectangle on phones. New values:
         • font-size cut from 64–104 → 48–84 (subtler footprint)
         • opacity stops reduced ~60% (.40→.16, .28→.10, .12→.05) so the
           gradient sits as background texture, not foreground signal
         • drop-shadow halved + softer + closer (no halo on phones)
         • shift slightly upward (top:-6px) so the bottom of the fade
           tucks closer to the heading instead of floating mid-air
       Headings stay fully readable in foreground (their z-index:1 + their
       opaque navy/white color sits ABOVE this faint texture). */
    font-size:clamp(48px, 11vw, 84px);
    top:-6px;
    background:linear-gradient(180deg,
      rgba(201,169,97,.16) 0%,
      rgba(201,169,97,.10) 32%,
      rgba(201,169,97,.05) 65%,
      rgba(201,169,97,0)   92%);
    filter:
      drop-shadow(0 1px 0 rgba(255,255,255,.30))
      drop-shadow(0 4px 12px rgba(201,169,97,.08));
  }
}
/* Arabic mode — swap to Arabic watermark when authored, hide otherwise so
   no English ghost-word lingers in RTL. The Tajawal display font keeps
   the same elegant feeling. */
html[dir="rtl"] .section-head[data-watermark-ar]::before{
  content:attr(data-watermark-ar);
  font-family: 'Tajawal', var(--font-display);
  letter-spacing: 0;
}
html[dir="rtl"] .section-head[data-watermark]:not([data-watermark-ar])::before{
  content:'';
}
.section-head h2,.section-head p,.section-head .eyebrow{position:relative;z-index:1}

@keyframes secHeadIn{
  from{opacity:0;transform:translateY(18px)}
  to  {opacity:1;transform:translateY(0)}
}

.divider-gold{
  display:inline-block;width:32px;height:1px;
  background:linear-gradient(90deg, transparent, var(--gold), transparent);
  vertical-align:middle;
}

/* Dark-section variants — used if the section sits on a navy background */
section[class*="dark"] .section-head h2,
.section-head.is-dark h2{color:#fff}
section[class*="dark"] .section-head p,
.section-head.is-dark p{color:rgba(255,255,255,.78)}

/* On dark sections (navy background), the gold gradient on the watermark
   reads as a slightly muted bronze. Bump the gold-light stop and add a
   warm white blend so the architectural word reads with the same density
   as on light sections. */
section[class*="dark"] .section-head[data-watermark]::before,
.section-head.is-dark[data-watermark]::before,
.launches-section .section-head[data-watermark]::before{
  /* Brighter shoulder + warm bronze deep — reads with the same visual density
     as the light variant but tuned for navy backgrounds. */
  background:linear-gradient(180deg,
    rgba(241,210,125,.62) 0%,
    rgba(201,169,97,.44)  28%,
    rgba(201,169,97,.20)  60%,
    rgba(201,169,97,0)    92%);
  -webkit-background-clip:text;background-clip:text;
  filter:
    drop-shadow(0 2px 0 rgba(0,0,0,.25))
    drop-shadow(0 10px 28px rgba(201,169,97,.32));
}
/* Mobile bugfix — soften the dark-background watermark variant on phones
   in lockstep with the light-background fix above. The dark variant uses
   higher gold opacity (.62/.44/.20) because navy backgrounds visually
   absorb gold; on mobile the same stops still read as a solid gold blob
   over short words like "Map" or "Why Us". Reduce to ~half intensity
   so it reads as textured background, not foreground signal. */
@media(max-width:768px){
  section[class*="dark"] .section-head[data-watermark]::before,
  .section-head.is-dark[data-watermark]::before,
  .launches-section .section-head[data-watermark]::before{
    background:linear-gradient(180deg,
      rgba(241,210,125,.28) 0%,
      rgba(201,169,97,.18)  32%,
      rgba(201,169,97,.08)  65%,
      rgba(201,169,97,0)    92%);
    -webkit-background-clip:text;background-clip:text;
    filter:
      drop-shadow(0 1px 0 rgba(0,0,0,.18))
      drop-shadow(0 4px 12px rgba(201,169,97,.12));
  }
}

/* Section-specific size override — New Launches reads slightly more balanced
   (still bold, cinematic, premium, but a touch smaller than the master scale). */
.launches-section .section-head[data-watermark]::before{
  font-size:clamp(72px, 9.5vw, 124px);
}
@media(max-width:768px){
  .launches-section .section-head[data-watermark]::before{
    font-size:clamp(54px, 12vw, 88px);
  }
}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  padding:14px 28px;font-weight:600;font-size:15px;border-radius:var(--radius-btn);
  transition:all .25s ease;white-space:nowrap;letter-spacing:.3px;
}
.btn-primary{background:var(--navy);color:var(--white)}
.btn-primary:hover{background:var(--navy-deep);transform:translateY(-2px);box-shadow:var(--shadow-md)}
.btn-gold{background:var(--gold);color:var(--navy-deep)}
.btn-gold:hover{background:var(--gold-soft);transform:translateY(-2px);box-shadow:var(--shadow-md)}
.btn-outline{border:1.5px solid var(--gold);color:var(--gold);background:transparent}
.btn-outline:hover{background:var(--gold);color:var(--navy-deep)}
.btn-outline-light{border:1.5px solid rgba(255,255,255,.4);color:var(--white);background:transparent}
.btn-outline-light:hover{background:var(--white);color:var(--navy-deep);border-color:var(--white)}
/* ============================================================================
   WHATSAPP CONCIERGE — BESPOKE NAVY/GOLD ENGRAVED CTA (v4)
   ----------------------------------------------------------------------------
   Designed specifically for The Gate's identity. Reads as a small
   architectural squircle rather than a generic WhatsApp circle. White
   icon + tiny green availability pulse = brand recognition without the
   loud green chrome. Subtle inner highlight + shadow give the button an
   "engraved" feel. On hover the gold ring intensifies, a soft gold halo
   blooms beneath, and the icon picks up a warm gold glow. Symmetric in
   LTR/RTL by construction.
   ============================================================================ */
.btn-whatsapp{
  position:relative;
  /* Layered backgrounds: top-left highlight + main navy gradient =
     subtle dimensional surface, like brushed metal under glass. */
  background:
    radial-gradient(ellipse at 28% 22%, rgba(255,255,255,.08) 0%, transparent 55%),
    linear-gradient(135deg, #0C2655 0%, #061533 100%);
  color:#fff;overflow:visible;
  border:1px solid rgba(201,169,97,.40);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.07),     /* top edge highlight */
    inset 0 -1px 0 rgba(0,0,0,.42),          /* bottom edge shadow */
    0 4px 14px -4px rgba(6,21,51,.42),       /* lift */
    0 1px 0 rgba(0,0,0,.18);                 /* hairline base */
  transition:
    transform .35s cubic-bezier(.22,.61,.36,1),
    box-shadow .35s ease,
    border-color .25s ease,
    background .35s ease;
}
.btn-whatsapp i{
  color:#fff;
  /* Icon stays white at rest — recognizable via shape, not colour. */
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.3));
  transition:
    transform .35s cubic-bezier(.22,.61,.36,1),
    filter .35s ease,
    color .35s ease;
}
/* Soft gold halo behind the button — fades in on hover */
.btn-whatsapp::before{
  content:"";position:absolute;inset:-5px;border-radius:inherit;
  background:radial-gradient(ellipse, rgba(201,169,97,.42) 0%, rgba(201,169,97,0) 68%);
  opacity:0;transition:opacity .35s ease;
  pointer-events:none;z-index:-1;
}
/* Tiny green availability pulse dot — bottom-right corner. Smaller and
   more refined than v3 — reads as a "live status" indicator on a luxury
   appliance, not a notification dot. Bordered with navy for a "set into
   the metal" feel. */
.btn-whatsapp::after{
  content:"";position:absolute;bottom:4px;right:4px;
  width:7px;height:7px;border-radius:50%;
  background:#10B981;
  border:1.5px solid var(--navy-deep);
  box-shadow:0 0 0 1px rgba(16,185,129,.30), 0 0 6px rgba(16,185,129,.18);
  animation:waPulse 2.6s ease-in-out infinite;
  pointer-events:none;
}
html[dir="rtl"] .btn-whatsapp::after{right:auto;left:4px}
@keyframes waPulse{
  0%,100%{box-shadow:0 0 0 1px rgba(16,185,129,.30), 0 0 6px rgba(16,185,129,.18)}
  50%    {box-shadow:0 0 0 2px rgba(16,185,129,.45), 0 0 12px rgba(16,185,129,.32)}
}
.btn-whatsapp:hover{
  transform:translateY(-2px);
  border-color:var(--gold);
  background:
    radial-gradient(ellipse at 28% 22%, rgba(255,255,255,.12) 0%, transparent 55%),
    linear-gradient(135deg, #0E2C64 0%, #082146 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.10),
    inset 0 -1px 0 rgba(0,0,0,.45),
    0 12px 28px -8px rgba(6,21,51,.55),
    0 0 0 4px rgba(201,169,97,.10);
}
.btn-whatsapp:hover::before{opacity:1}
.btn-whatsapp:hover i{
  transform:scale(1.1);
  color:var(--gold-light, #F1D27D);          /* icon picks up gold on hover */
  filter:drop-shadow(0 0 10px rgba(201,169,97,.55));
}
.btn-whatsapp:focus-visible{outline:2px solid var(--gold);outline-offset:3px}
.btn-lg{padding:18px 36px;font-size:16px}
.btn-block{width:100%}

/* TOPBAR */
.topbar{background:var(--navy-deep);color:rgba(255,255,255,.85);font-size:13px;padding:10px 0}
.topbar .container{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap}
.topbar .left,.topbar .right{display:flex;align-items:center;gap:20px;flex-wrap:wrap}
.topbar a{color:inherit;display:inline-flex;align-items:center;gap:6px}
.topbar a:hover{color:var(--gold)}

/* ─────────────────────────────────────────────────────────────────────
   Contact label cleanup — visible text is always a label
   ("Call Us" / "Email" / "WhatsApp") on every viewport. The dual-span
   swap pattern was replaced site-wide with a single label span so the
   raw email address never appears in the visible markup. tel: / mailto: /
   wa.me hrefs are unchanged; the user-facing label is the only thing
   the eye reads. Tighter topbar padding kept for narrow phones below. */
@media(max-width:540px){
  /* Tighten topbar spacing on small screens — fits "Call Us · Email"
     on the left and "Head Office · عربي" on the right comfortably. */
  .topbar{padding:8px 0;font-size:12.5px}
  .topbar .container{gap:10px}
  .topbar .left,.topbar .right{gap:14px}
  .topbar a{gap:5px}
}
@media(max-width:380px){
  /* iPhone SE — drop topbar gap one more notch */
  .topbar .left,.topbar .right{gap:10px}
}
.topbar .lang-switch{cursor:pointer;color:var(--gold);font-weight:600}
/* Lang switcher repositioned into topbar — slim pill that sits with the
   Head Office link. Removes the original button-y nav styling. */
.topbar .lang-switcher,
.topbar-lang{
  background:transparent;border:1px solid rgba(201,169,97,.4);
  color:rgba(255,255,255,.85);
  padding:4px 12px;border-radius:var(--radius-pill);
  font-family:inherit;font-size:12px;font-weight:600;letter-spacing:.4px;
  display:inline-flex;align-items:center;gap:6px;
  cursor:pointer;transition:background .2s ease, color .2s ease, border-color .2s ease;
}
.topbar .lang-switcher i,.topbar-lang i{font-size:10px;color:var(--gold)}
.topbar .lang-switcher:hover,.topbar-lang:hover{
  background:rgba(201,169,97,.12);color:var(--gold);border-color:var(--gold);
}
@media(max-width:540px){
  .topbar .lang-switcher,.topbar-lang{padding:3px 10px;font-size:11px}
}

/* NAVBAR */
.navbar{position:sticky;top:0;z-index:1000;background:var(--white);box-shadow:0 1px 0 rgba(0,0,0,.04);transition:all .3s ease}
.navbar .container{display:flex;align-items:center;padding-top:12px;padding-bottom:12px;gap:40px}
/* Bugfix sprint — slimmer header on phones. 12px vertical padding shrinks
   to 8px so the navbar takes ~16px less vertical space, leaving more room
   for the content the user actually came to read. Desktop unchanged. */
@media(max-width:540px){
  .navbar .container{padding-top:8px;padding-bottom:8px;gap:16px}
}
.navbar .nav-cta{margin-left:auto}
html[dir="rtl"] .navbar .nav-cta{margin-left:0;margin-right:auto}

.logo{display:inline-flex;align-items:center;flex-shrink:0;line-height:0}
.logo img{height:56px;width:auto;display:block;transition:transform .25s}
.logo:hover img{transform:scale(1.04)}
.logo-footer img{height:90px}
@media(max-width:540px){ .logo img{height:46px} }

.nav-menu{display:flex;align-items:center;gap:4px;list-style:none}

/* ============================================================================
   NAV ACTIVE STATE — ARCHITECTURAL CINEMASCOPE (v3)
   ----------------------------------------------------------------------------
   Inspired by luxury watch dials and architectural studio sites: two hairline
   gold strokes (top + bottom) animated from the center outward, framing the
   active link like a cinemascope letterbox. A soft gold ambient halo glows
   between them. Hover reveals a single lower stroke as a preview.

   Symmetric in both directions by construction: every stroke is centered
   via left:50% + translateX(-50%), the halo is a centered radial gradient,
   and there is no directional logic at all. LTR and RTL render identically.
   ============================================================================ */
.nav-menu a{
  position:relative;
  display:inline-flex;align-items:center;gap:6px;
  padding:14px 16px;
  color:var(--navy-deep);font-weight:700;font-size:13.5px;letter-spacing:.2px;
  white-space:nowrap;
  background:transparent;
  transition:
    color .35s cubic-bezier(.22,.61,.36,1),
    letter-spacing .35s cubic-bezier(.22,.61,.36,1),
    text-shadow .35s ease,
    background .4s ease;
  isolation:isolate;
}

/* Hover — gold-deep colour change only. The sliding gold indicator below
   each link is now drawn by assets/nav-indicator.js, which measures the
   actual link bounding box and slides a single shared element under it.
   That measurement-based approach means LTR and RTL render pixel-identical
   with zero CSS directional logic. */
.nav-menu a:hover{
  color:var(--gold-deep);
}

/* Active — the chosen page. Colour, weight and a soft gold halo behind the
   text. The actual indicator BAR is drawn by JS. */
.nav-menu a.active{
  color:var(--gold-deep);font-weight:800;letter-spacing:.5px;
  text-shadow:0 0 12px rgba(201,169,97,.18);
  background:radial-gradient(ellipse 75% 60% at 50% 50%, rgba(201,169,97,.12) 0%, rgba(201,169,97,.04) 50%, rgba(201,169,97,0) 80%);
}

/* Subtle press feedback */
.nav-menu a:active{transform:scale(.98)}
.nav-menu a.nav-rate{color:var(--gold-deep);font-weight:800}
.nav-menu a.nav-rate i{margin-right:4px}
.nav-cta{display:flex;align-items:center;gap:10px;flex-shrink:0;flex-wrap:nowrap}
/* Defensive: lang-switcher must always stay visible, even when the nav-cta
   gets crowded. Keep it on its own line if needed instead of overflowing. */
.nav-cta .lang-switcher{flex-shrink:0;order:-1}
/* Header CTAs (Rate My Property, language switcher, etc.) — match bold weight */
.nav-cta .btn{font-weight:700;letter-spacing:.3px}
.nav-cta .lang-switcher{font-weight:700}
.btn-rate-cta{padding:10px 18px !important;font-size:13px !important;font-weight:700 !important}
.btn-rate-cta i{font-size:14px}
/* Square-ish pill in the navbar — icon-only button, sized to balance the
   Rate My Property CTA on its left/right. */
.nav-cta .btn-whatsapp{
  padding:0;width:42px;height:42px;border-radius:50%;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:18px;
}
.nav-toggle{display:none;font-size:24px;color:var(--navy-deep)}
/* Topbar text (phone / email / Head Office) — also bolder for consistency */
.topbar a{font-weight:600}

@media(max-width:1180px){ .nav-menu a.nav-rate{display:none} }
/* V141 — PUBLIC NAV COLLAPSE BREAKPOINT raised 1024 → 1599.
   Why 1599 (not ~1460): the navbar lives inside `.container{max-width:var(--container)}`
   and --container is a STEP function — 1280px (≤1399 viewports), 1360px (≥1400),
   1480px (≥1600). The inner-page nav cluster (11 links + العربية language toggle +
   Rate-My-Property CTA + account pill) has a natural width ≈1470px, so it only fits
   once the container reaches 1480px, i.e. at viewport ≥1600. Measured (search/projects/
   unit, EN+AR): overflow 1366→140, 1440→71, 1500→41, 1600→0, 1710→0. A breakpoint near
   1460 would leave 1461–1599 still clipping the right-side CTA/account/lang controls
   (body{overflow-x:clip} hides the scrollbar). 1599 makes the full horizontal nav appear
   ONLY at ≥1600 where it provably fits (owner's 1710 stays full nav); everything ≤1599
   uses the hamburger panel = zero clipping on every public page. ≤1024 behaviour is an
   unchanged subset. Frontend/CSS-only; admin + account-portal navs use different markup
   (.gan-menu / admin shell) and are untouched. */
/* SIDEBAR-PATCH (2026-06-14) — Owner-approved defensive change.
   Previously: position:absolute (resolved against nearest positioned
   ancestor — usually .navbar via position:sticky). At certain viewports
   (especially small-tablet ~768–1024 with a Chrome extension or any
   future ancestor `transform`/`filter`/`will-change`/`contain` value)
   the offset reference could collapse to a narrower box, producing a
   "centered narrow strip" appearance.
   Now: position:fixed pins the dropdown to the VIEWPORT (not to any
   ancestor), with explicit width:100vw + max-width:100vw to bypass any
   inherited width constraint. Visual outcome at every viewport where
   this rule applies is identical to the intended full-width dropdown.
   Desktop ≥1600px unaffected. The 1280–1599 homepage override on
   index.html:4310 still wins by source order at that range. Admin +
   account-portal navs use different markup (.gan-menu / admin shell)
   and remain untouched. Comment placed OUTSIDE the @media block so the
   V141 contract regex `@media(max-width:1599px)\{\s*\.nav-menu\{display:none`
   continues to match without contract evolution. */
@media(max-width:1599px){
  .nav-menu{display:none;position:fixed;top:var(--navbar-h, 80px);left:0;right:0;width:100vw;max-width:100vw;background:var(--white);
    flex-direction:column;align-items:stretch;gap:0;padding:16px 0;box-shadow:var(--shadow-md);z-index:999}
  .nav-menu.open{display:flex}
  .nav-menu li{padding:0 24px}
  /* Mobile menu — items are full-width stacked, so the desktop pill capsule
     is replaced by a subtle leading-edge gold accent + soft gold-tint
     background on the active row. Symmetric in LTR/RTL via logical
     border-inline-start. */
  .nav-menu a{
    display:block;padding:14px 18px;
    border-bottom:1px solid var(--stone);
    border-radius:0;background:transparent;
    box-shadow:none;text-shadow:none;
    letter-spacing:.2px;
    border-inline-start:3px solid transparent;
  }
  /* Hide the desktop cinemascope strokes on mobile — items are full-width
     stacked, so the leading-edge gold accent is the active indicator. */
  .nav-menu a::before,
  .nav-menu a::after{display:none}
  .nav-menu a:hover{
    background:rgba(201,169,97,.06);
    box-shadow:none;
  }
  .nav-menu a.active{
    background:rgba(201,169,97,.10);
    border-inline-start-color:var(--gold);
    box-shadow:none;letter-spacing:.2px;
  }
  .nav-menu a.active:hover{
    background:rgba(201,169,97,.14);
    box-shadow:none;
  }
  .nav-menu a.nav-rate{display:block;color:var(--gold-deep)}
  .nav-toggle{display:block}
}
/* V228 — T1: TABLET INLINE-NAV UNLOCK (Plan-B preempted, conservative threshold).
   Background: V141 (above) shows the natural EN nav cluster overflows by 140px at 1366,
   71px at 1440, 41px at 1500, 0 at ≥1600. AR labels are ~15-18% longer. Plan-B was
   approved by owner 2026-06-04 with explicit direction "stability > forcing nav at 1024".

   Strategy: at a CONSERVATIVE tablet-laptop range we restore the inline nav with
   compressed typography (smaller font, tighter gap, tighter padding) so all 11 items
   + lang chip + Rate-My-Property pill fit inside the container. No nav item removed,
   no item merged, no "More" menu, no Brand voice change.

   Threshold is initially set at min-width:1280px and validated empirically across:
     EN + AR  ×  1280 / 1366 / 1440 / 1500  ×  portrait + landscape.
   If AR overflows at 1280, threshold is raised to 1366; if still failing, to 1440.
   Whichever value passes verification is the final shipped value. ≤(threshold-1) keeps
   the V141 hamburger behaviour, ≥1600 keeps the desktop full-nav default. */
@media (min-width:1280px) and (max-width:1599px){
  .nav-menu{
    display:flex; position:static;
    flex-direction:row; align-items:center;
    background:transparent; box-shadow:none;
    padding:0; gap:14px;
    /* override V141 absolute positioning */
    top:auto; left:auto; right:auto;
  }
  .nav-menu li{ padding:0 }
  .nav-menu a{
    display:inline-block; padding:8px 6px;
    font-size:13px; letter-spacing:0.1px;
    border-bottom:none; border-inline-start:none;
    background:transparent; border-radius:0;
  }
  /* desktop gold-stroke hover indicators belong to the default state — restore */
  .nav-menu a::before, .nav-menu a::after{ display:initial }
  .nav-menu a.active{ background:transparent }
  .nav-cta{ gap:8px }
  .btn-rate-cta{ padding:8px 12px; font-size:13px }
  .btn-rate-cta span{ display:inline }
  .nav-toggle{ display:none }
}
@media(max-width:768px){
  .btn-rate-cta span{display:none}
  .btn-rate-cta{padding:10px 14px !important}
}

/* FORMS */
.form-row{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:14px}
@media(max-width:480px){.form-row{grid-template-columns:1fr}}
.form-group{display:flex;flex-direction:column}
.form-group label{font-size:12px;font-weight:600;color:var(--slate);text-transform:uppercase;letter-spacing:1.2px;margin-bottom:6px}
.form-group input,.form-group select,.form-group textarea{
  border:1.5px solid var(--stone);background:var(--offwhite);
  padding:12px 14px;border-radius:var(--radius-sm);font-size:15px;font-family:inherit;
  outline:none;transition:all .2s;color:var(--charcoal);
}
.form-group input:focus,.form-group select:focus,.form-group textarea:focus{
  border-color:var(--gold);background:var(--white);
}
.form-group textarea{resize:vertical;min-height:90px}
.form-group .field-required{color:var(--gold-deep);margin-left:2px}

/* =========================================================
   FOOTER (full-width, always centered, works in LTR and RTL)
   Hardened: breaks out of any accidental parent grid/flex.
   ========================================================= */
footer{
  background:var(--charcoal);color:rgba(255,255,255,.7);
  padding:80px 0 0;
  width:100% !important;
  max-width:100% !important;
  display:block !important;
  margin-left:0 !important;margin-right:0 !important;
  /* Break out of any accidental parent grid */
  grid-column:1 / -1 !important;
  /* Break out of any accidental parent flex */
  flex:1 1 100% !important;
  align-self:stretch !important;
  /* Force LTR layout for footer container even if parent is flipped */
  box-sizing:border-box;
  clear:both;
}
footer > .container{
  max-width:var(--container);
  margin-left:auto !important;margin-right:auto !important;
  padding-left:24px;padding-right:24px;
  width:100%;box-sizing:border-box;
}
.footer-grid{
  display:grid;
  grid-template-columns:1.4fr 1fr 1fr 1.2fr;
  gap:48px;padding-bottom:56px;
  width:100%;
}
@media(max-width:900px){.footer-grid{grid-template-columns:1fr 1fr;gap:40px}}
@media(max-width:540px){.footer-grid{grid-template-columns:1fr}}
/* Batch 2.2 — dynamic footer: keep brand-wide (1.4fr) + contact-wide (1.2fr)
   proportions for ANY number of admin-managed link columns. Desktop only —
   the ≤900 / ≤540 mobile rules above are untouched (they don't match ≥901). */
@media(min-width:901px){
  .footer-grid.ft-flex{ grid-template-columns:1.4fr repeat(var(--ft-cols,2),1fr) 1.2fr; }
}
.footer-brand{min-width:0}
.footer-brand p{margin-top:18px;font-size:14px;line-height:1.8;color:rgba(255,255,255,.6);max-width:320px}
footer h5{
  font-family:var(--font-body);color:var(--white);font-size:13px;font-weight:700;
  text-transform:uppercase;letter-spacing:2px;margin-bottom:24px;position:relative;padding-bottom:14px;
}
footer h5::after{content:"";position:absolute;bottom:0;width:32px;height:2px;background:var(--gold);left:0}
html[dir="rtl"] footer h5::after{left:auto;right:0}
footer ul{list-style:none;display:flex;flex-direction:column;gap:10px;padding:0;margin:0}
footer ul a{font-size:14px;transition:color .2s;color:rgba(255,255,255,.7)}
footer ul a:hover{color:var(--gold)}
.contact-line{display:flex;gap:12px;align-items:flex-start;margin-bottom:14px;font-size:14px}
.contact-line i{color:var(--gold);width:18px;flex-shrink:0;padding-top:4px}
.socials{display:flex;gap:10px;margin-top:20px;flex-wrap:wrap}
.socials a{
  width:38px;height:38px;border-radius:50%;border:1px solid rgba(255,255,255,.2);
  display:grid;place-items:center;font-size:14px;transition:all .25s;color:#fff;text-decoration:none;
}
.socials a:hover{background:var(--gold);border-color:var(--gold);color:var(--navy-deep)}
/* =========================================================
   FOOTER MOBILE ACCORDION — collapsible columns < 540px
   Each .footer-grid > div:has(h5) becomes a button-like header
   that toggles its <ul>. Pure CSS via :checked hack with the
   <input type="checkbox"> injected by JS in i18n.js.
   ========================================================= */
@media(max-width:540px){
  /* V213 — mobile footer accordion removed: every section is always visible
     by default. Replaces the V212 luxury-polish-on-accordion block. Reasons
     (inspection): the renderFooter dynamic rebuild (V170) replaces Explore /
     Services columns AFTER applyFooterAccordion runs in i18n.js, so only the
     Contact h5 actually receives the click listener; Explore + Services are
     dead taps on every public page. Owner direction = remove the accordion
     pattern entirely on mobile, show all sections visibly, center-aligned,
     gold headings, no chevron, no harsh divider. CSS-only. The accordion
     listener still fires on Contact h5 (i18n.js untouched) but its visual
     effect becomes a no-op because these rules force visibility regardless
     of `.is-open` state. */
  .footer-grid > div:has(h5){
    border-top:none;            /* drop the V212 .04 hairline — sections are one block now */
    text-align:center;
    padding:18px 0 4px;
    position:relative;
  }
  .footer-grid > div:has(h5):first-of-type{padding-top:0}
  .footer-grid > div:has(h5) ul,
  .footer-grid > div:has(h5) .contact-line{
    max-height:none;            /* was 0 — always expanded */
    overflow:visible;
    opacity:1;                  /* was 0 */
    margin-top:10px;
  }
  .footer-grid h5{
    margin:0;cursor:default;    /* was pointer — no longer interactive */
    display:flex;justify-content:center;align-items:center;
    font-size:13px;letter-spacing:1.5px;
    padding:6px 0;
    color:var(--gold);          /* owner direction: gold section headings on mobile */
  }
  .footer-grid h5::after{display:none}                              /* hide dropdown chevron */
  .footer-grid > div.is-open{background:none}                       /* drop V212 gold wash — meaningless without toggling */
  html[dir="rtl"] .footer-grid > div.is-open{background:none}
  .contact-line{justify-content:center}                             /* center contact-line icons + text per text-align */
  /* Brand block stays open always */
  .footer-grid > .footer-brand{border-top:none;padding-top:0}
  .footer-grid > .footer-brand p,
  .footer-grid > .footer-brand .socials{max-height:none;opacity:1}
}

/* =========================================================
   FOOTER MOBILE POLISH (M4) — additive refinements only.
   ───────────────────────────────────────────────────────
   Mobile-only via @media(max-width:540px) + a small tablet
   tap (@media(max-width:768px)). Desktop layout is unchanged.

   What this block refines (no markup changes, no link removals):
     • Top padding tightens from 80→56 so the footer doesn't
       feel "loud" right after a long scroll.
     • Brand block centres on mobile (logo, paragraph, socials).
     • Accordion items get more comfortable tap padding and a
       slightly larger margin-top when expanded so the link list
       breathes away from the heading.
     • The .footer-apps cluster (download badges + title) centres
       cleanly with a tighter top gap, taking up less vertical
       space near the floating button stack.
     • .footer-bottom stacks vertically on mobile (was a flex row
       that wrapped awkwardly), with centred text and tighter
       vertical rhythm — readable + premium feel.
     • Footer ul gap nudged from 10→12 so tapped links don't feel
       cramped on a thumb.
   ========================================================= */
@media(max-width:768px){
  /* Slight tap-friendly padding bump on the column links — applies
     on small tablets too, not just phones. Improves reachability
     without changing layout. */
  footer ul{gap:12px}
  footer ul a{padding:2px 0}
}

@media(max-width:540px){
  /* — Top padding tightens on phones to reduce empty top space — */
  footer{padding:56px 0 0}

  /* — Brand block centres on mobile — */
  .footer-brand{text-align:center}
  .footer-brand p{
    margin-left:auto;margin-right:auto;
    /* keep max-width:320 from the base rule; it now centres */
  }
  .socials{justify-content:center}

  /* — Accordion comfort + Bugfix-sprint compression. The previous
     16/6 padding plus expanded 12px margin produced visible empty
     gaps between collapsed rows on iPhone. Tightened to 12/4 with
     8px expanded margin — still meets the 44px tap-target floor
     (12 + 13.5 line-height + 12 ≈ 37 → bumped by adding min-height). — */
  .footer-grid > div:has(h5){padding:12px 0 4px}
  .footer-grid h5{min-height:32px}
  .footer-grid > div.is-open ul,
  .footer-grid > div.is-open .contact-line{margin-top:8px}

  /* — App download cluster: centred, tighter gap, no horizontal
     overflow on iPhone SE (the two 140px badges with 10px gap
     fit comfortably; if the viewport is too narrow they wrap
     onto two rows, which still reads cleanly). — */
  .footer-apps{text-align:center;margin-top:8px}
  .footer-apps .app-badges{justify-content:center;gap:8px}

  /* — Bottom row: vertical stack with breathable line-height.
       Bugfix sprint — add extra bottom padding so the © + Founded-by
       lines don't sit behind the WhatsApp / back-to-top FAB stack on
       Safari iOS. The +60px buys clearance below the WhatsApp FAB
       which sits at --fab-bottom-mobile (~70px from viewport edge). — */
  .footer-bottom{
    flex-direction:column;
    text-align:center;
    gap:6px;
    padding:18px 0 calc(22px + var(--fab-bottom-mobile, 24px) + 24px);
    line-height:1.6;
  }

  /* — Footer column links: a hair more breathing room between
     items so they don't read as a wall of text on a 320px screen. — */
  footer ul{gap:14px}
}


/* =========================================================
   HOMEPAGE SECTION DIVIDERS — luxury motif between sections
   Apply by adding <div class="section-divider"></div> between
   sections OR rely on the auto-injected ones from i18n.js.
   ========================================================= */
.section-divider{
  display:flex;align-items:center;justify-content:center;gap:18px;
  max-width:520px;margin:0 auto;padding:36px 24px;
  opacity:.85;
}
.section-divider::before,.section-divider::after{
  content:"";flex:1;height:1px;
  background:linear-gradient(90deg, transparent, rgba(201,169,97,.32), transparent);
}
.section-divider .sd-mark{
  width:8px;height:8px;border-radius:50%;
  background:radial-gradient(circle,#F1D27D 0%,#A88A3F 70%);
  box-shadow:0 0 0 4px rgba(201,169,97,.10),0 0 12px rgba(201,169,97,.35);
  flex-shrink:0;
}
.section-divider .sd-mark + .sd-mark{margin-left:6px}
@media(max-width:540px){.section-divider{padding:24px 16px}}

/* =========================================================
   PAGE-LOAD FADE — every page softly fades in on first paint.
   Makes navigation between pages feel continuous instead of
   disconnected reloads. JS toggles .page-ready when DOM is in.
   ========================================================= */
body{
  opacity:0;
  transition:opacity .4s cubic-bezier(.22,.61,.36,1);
  /* DEPLOY-4 Fix #2 (2026-06-13) — safety net. If JS is delayed or fails to
     add .page-ready, the body would stay invisible forever (iPad Safari worst
     case: 3 MB synchronous JS = 4-7 s blank screen). This animation runs in
     parallel and forces opacity:1 after 4 s as an absolute fallback. The
     transition above still wins normally because JS toggles .page-ready
     within ~100-500 ms on capable devices. */
  animation: gate-page-ready-safety 0s 4s forwards;
}
body.page-ready{opacity:1}
@keyframes gate-page-ready-safety {
  to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce){
  body{opacity:1;transition:none;animation:none}
}

/* =========================================================
   FOOTER LEGAL STRIP — horizontal compact line of links
   sits between the 4-column grid and the © bottom row.
   ========================================================= */
.footer-legal-strip{
  display:flex;flex-wrap:wrap;justify-content:center;
  gap:6px 22px;
  padding:22px 0 18px;margin-top:8px;
  border-top:1px solid rgba(255,255,255,.06);
  font-size:12px;color:rgba(255,255,255,.55);
  letter-spacing:.3px;
}
.footer-legal-strip a{
  color:rgba(255,255,255,.7);text-decoration:none;font-weight:500;
  position:relative;padding:2px 0;
  transition:color .2s ease;
}
.footer-legal-strip a:hover{color:var(--gold)}
.footer-legal-strip a + a::before{
  content:"";position:absolute;left:-13px;top:50%;transform:translateY(-50%);
  width:3px;height:3px;border-radius:50%;background:rgba(201,169,97,.45);
}
html[dir="rtl"] .footer-legal-strip a + a::before{left:auto;right:-13px}
@media(max-width:540px){
  .footer-legal-strip{gap:4px 16px;font-size:11px;padding:18px 0 14px}
  .footer-legal-strip a + a::before{left:-9px;width:2.5px;height:2.5px}
  html[dir="rtl"] .footer-legal-strip a + a::before{left:auto;right:-9px}
}

.footer-bottom{
  border-top:1px solid rgba(255,255,255,.08);padding:20px 0;
  display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:12px;font-size:13px;
  width:100%;
}

/* =========================================================
   GLOBAL RTL ADJUSTMENTS (when html[dir="rtl"])
   Minimal & non-destructive — let the browser's native RTL flow
   handle most layout, only override the few things that need it.
   ========================================================= */
html[dir="rtl"] body{font-family:'Tajawal','Inter',sans-serif !important}
/* Container padding stays symmetric in RTL — only the nav-cta margin needs
   mirroring, and that's handled correctly above by the rule at line ~207
   (margin-left:0; margin-right:auto). The previous override here had the
   axes swapped and was pushing the CTA back to the right side, colliding
   with the logo. Keeping container padding only. */
html[dir="rtl"] .navbar .container{padding-left:var(--container-pad);padding-right:var(--container-pad)}

/* =============================================================
   GLOBAL PROJECT-STATUS BADGES
   Single source of truth — used on home, projects, search, area,
   developer, project-detail similar, etc. Each status has a
   distinct premium visual that matches its meaning:

     - new_launch     → fresh green with subtle pulse glow (premium fresh)
     - coming_soon    → soft blue teaser, semi-transparent, italic feel
     - open_inventory → active gold (the brand's "available now" color)
     - eoi            → exclusive royal purple with shine accent
     - delivered      → stable navy + gold (completed milestone)
     - sold_out       → muted maroon, slightly lower opacity (disabled)
   ============================================================= */
.proj-status-badge{
  display:inline-flex;align-items:center;gap:6px;
  padding:6px 12px;border-radius:var(--radius-pill);
  font-size:11px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;
  white-space:nowrap;line-height:1;
  border:1px solid transparent;
  box-shadow:0 4px 10px rgba(6,21,51,.18);
  backdrop-filter:saturate(1.1);
}
.proj-status-badge i{font-size:10px}

/* New Launch — fresh green with pulsing emerald glow */
.proj-status-badge.new_launch{
  background:linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
  color:#04210f;border-color:rgba(255,255,255,.3);
  box-shadow:0 0 0 0 rgba(34,197,94,.6), 0 4px 12px rgba(34,197,94,.32);
  animation:gateLaunchPulse 2.4s ease-out infinite;
}
@keyframes gateLaunchPulse{
  0%   { box-shadow:0 0 0 0 rgba(34,197,94,.55), 0 4px 12px rgba(34,197,94,.32); }
  70%  { box-shadow:0 0 0 8px rgba(34,197,94,0),  0 4px 12px rgba(34,197,94,.32); }
  100% { box-shadow:0 0 0 0 rgba(34,197,94,0),    0 4px 12px rgba(34,197,94,.32); }
}

/* Coming Soon — soft teaser, semi-translucent blue with italic vibe */
.proj-status-badge.coming_soon{
  background:rgba(59,130,246,.85);
  color:#fff;border-color:rgba(255,255,255,.25);
  font-style:italic;letter-spacing:.8px;
  box-shadow:0 4px 10px rgba(59,130,246,.25);
}

/* Open Inventory — the active gold brand color */
.proj-status-badge.open_inventory{
  background:linear-gradient(135deg, var(--gold) 0%, var(--gold-deep) 100%);
  color:var(--navy-deep);border-color:rgba(255,255,255,.4);
  box-shadow:0 4px 12px rgba(201,169,97,.32);
}

/* EOI — exclusive royal purple with subtle inner shine */
.proj-status-badge.eoi{
  background:linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%);
  color:#fff;border-color:rgba(255,255,255,.3);
  box-shadow:0 4px 12px rgba(139,92,246,.30), inset 0 1px 0 rgba(255,255,255,.18);
  letter-spacing:1px;
}

/* Delivered — stable navy + gold for "completed milestone" */
.proj-status-badge.delivered{
  background:linear-gradient(135deg, var(--navy) 0%, var(--navy-deep) 100%);
  color:var(--gold);border-color:rgba(201,169,97,.5);
  box-shadow:0 4px 10px rgba(6,21,51,.32);
}

/* Sold Out — muted maroon, slightly lower opacity = closed */
.proj-status-badge.sold_out{
  background:linear-gradient(135deg, #9b1c1c 0%, #6b0e0e 100%);
  color:rgba(255,255,255,.92);border-color:rgba(255,255,255,.18);
  opacity:.95;
  box-shadow:0 4px 10px rgba(155,28,28,.30);
}

/* Sold Out banner — shown on the detail page and over sold-out card images */
.sold-out-banner{
  background:linear-gradient(135deg, #9b1c1c 0%, #6b0e0e 100%);
  color:#fff;border-radius:var(--radius-md);padding:20px 24px;margin:20px 0;
  display:flex;align-items:center;gap:16px;box-shadow:0 8px 24px rgba(155,28,28,.18);
}
.sold-out-banner .sob-icon{
  width:48px;height:48px;border-radius:50%;background:rgba(255,255,255,.14);
  display:grid;place-items:center;font-size:22px;color:#fff;flex-shrink:0;
}
.sold-out-banner .sob-text{flex:1}
.sold-out-banner .sob-text h4{
  font-family:var(--font-display);font-size:18px;color:#fff !important;margin:0 0 4px;font-weight:700;
}
.sold-out-banner .sob-text p{font-size:13px;color:rgba(255,255,255,.85);margin:0;line-height:1.5}
.sold-out-banner .sob-cta{
  background:#fff;color:#9b1c1c;padding:10px 18px;border-radius:var(--radius-sm);font-size:12px;
  font-weight:700;text-transform:uppercase;letter-spacing:.5px;text-decoration:none;
  display:inline-flex;align-items:center;gap:8px;flex-shrink:0;transition:all .2s;
}
.sold-out-banner .sob-cta:hover{background:var(--gold);color:var(--navy-deep)}
@media(max-width:640px){
  .sold-out-banner{flex-direction:column;text-align:center;align-items:stretch}
  .sold-out-banner .sob-icon{margin:0 auto}
}

/* =========================================================
   REUSABLE PREMIUM PAGINATION — site-wide (light theme)
   Used by Gate.Paginate. Apply container class .dev-pager-wrap
   below any large list to inherit margin spacing.
   ========================================================= */
.gp-pager{
  display:flex;align-items:center;justify-content:center;
  flex-wrap:wrap;gap:10px;
  margin:48px auto 0;padding:0 16px;
}
.gp-pager-pages{display:flex;gap:4px;align-items:center}
.gp-pager-page,.gp-pager-step{
  min-width:38px;height:38px;padding:0 12px;
  display:inline-flex;align-items:center;justify-content:center;
  background:#fff;border:1px solid rgba(10,31,68,.10);
  color:var(--navy-deep,#061533);
  font-family:inherit;font-size:13px;font-weight:600;
  border-radius:10px;cursor:pointer;
  transition:transform .18s ease,background .2s ease,border-color .2s ease,color .2s ease,box-shadow .2s ease;
  font-variant-numeric:tabular-nums;
  position:relative;
}
.gp-pager-page:hover:not(.is-current),
.gp-pager-step:hover:not([disabled]){
  border-color:rgba(201,169,97,.55);color:var(--gold-deep,#A88A3F);
  transform:translateY(-1px);
  box-shadow:0 6px 16px -8px rgba(6,21,51,.18);
}
.gp-pager-page.is-current{
  background:linear-gradient(135deg,#0A1F44 0%,#061533 100%);color:#fff;
  border-color:transparent;
  box-shadow:0 8px 18px -6px rgba(6,21,51,.4);
}
.gp-pager-page.is-current::after{
  content:"";display:block;width:18px;height:2px;border-radius:2px;
  background:#C9A961;position:absolute;bottom:-7px;left:50%;transform:translateX(-50%);
}
.gp-pager-step[disabled]{opacity:.35;cursor:not-allowed}
.gp-pager-gap{
  display:inline-flex;align-items:center;justify-content:center;
  width:24px;height:38px;color:rgba(10,31,68,.4);font-weight:700;letter-spacing:1px;
}
.gp-pager-readout{
  flex-basis:100%;text-align:center;
  font-size:12px;color:var(--slate,#5e6b80);letter-spacing:.3px;
  margin-top:6px;
}
.gp-pager-flat{margin-top:24px}
.gp-pager-flat .gp-pager-readout{flex:none;margin:0}
@media(max-width:480px){
  .gp-pager-page,.gp-pager-step{min-width:34px;height:34px;font-size:12px;padding:0 10px}
  .gp-pager-pages{gap:3px}
  .gp-pager{gap:8px}
}
.dev-pager-wrap{margin-top:8px}

/* Universal pager host — visible only when Gate.Paginate injects controls
   (totalPages > 1). Empty when single-page so it consumes no space.
   Used by area.html, developer.html, project.html, and any future
   public list that wraps a grid with Gate.Paginate. */
.gp-pager-host{margin-top:28px;display:flex;justify-content:center}
.gp-pager-host:empty{display:none}

/* =========================================================
   SOLD-OUT corner ribbon — spans the top-right corner cleanly.
   Card needs position:relative + overflow:hidden so the ribbon
   clips precisely to the corner with no overflow on either side.
   ========================================================= */
.prop-card.is-sold-out,
.unit-card.is-sold-out,
.project-card.is-sold-out{ position:relative; overflow:hidden; }
.prop-card.is-sold-out .pc-img,
.unit-card.is-sold-out .uc-img,
.project-card.is-sold-out .img,
.project-card.is-sold-out .pc-img{ filter:grayscale(.55); }
.prop-card.is-sold-out::after,
.unit-card.is-sold-out::after,
.project-card.is-sold-out::after{
  content:"SOLD OUT";
  position:absolute;top:22px;right:-60px;
  width:220px;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg,#bf2222 0%,#9b1c1c 50%,#6b0e0e 100%);
  color:#fff;
  padding:7px 0;font-size:11px;font-weight:800;letter-spacing:3px;
  font-family:'Inter','Tajawal',sans-serif;
  transform:rotate(45deg);transform-origin:center;
  box-shadow:
    0 6px 18px rgba(155,28,28,.45),
    0 1px 0 rgba(255,255,255,.18) inset,
    0 -1px 0 rgba(0,0,0,.25) inset;
  text-shadow:0 1px 2px rgba(0,0,0,.4);
  z-index:5;pointer-events:none;
  /* hairline gold edges — quiet brand echo */
  border-top:1px solid rgba(201,169,97,.55);
  border-bottom:1px solid rgba(201,169,97,.45);
}
/* RTL: ribbon flips to the top-left corner */
html[dir="rtl"] .prop-card.is-sold-out::after,
html[dir="rtl"] .unit-card.is-sold-out::after,
html[dir="rtl"] .project-card.is-sold-out::after{
  right:auto;left:-60px;transform:rotate(-45deg);
}
/* Inline icon spacing inside buttons (icons before text in LTR; after text in RTL) */
html[dir="rtl"] .btn i:first-child{margin-right:0;margin-left:6px}
/* Form inputs read right-to-left */
html[dir="rtl"] input[type="text"],
html[dir="rtl"] input[type="email"],
html[dir="rtl"] input[type="tel"],
html[dir="rtl"] input[type="number"],
html[dir="rtl"] input[type="search"],
html[dir="rtl"] textarea,
html[dir="rtl"] select{text-align:right;direction:rtl}
/* Numeric inputs (price/coords) keep LTR — Arabic numerals are easier to read LTR */
html[dir="rtl"] input[type="number"][step]{text-align:left;direction:ltr}
/* Text helpers */
html[dir="rtl"] .text-left{text-align:right !important}
html[dir="rtl"] .text-right{text-align:left !important}
/* Don't flip these — they should keep their visual orientation */
html[dir="rtl"] .map-shell,
html[dir="rtl"] .leaflet-container,
html[dir="rtl"] code,
html[dir="rtl"] .code-cell,
html[dir="rtl"] .proj-coords{direction:ltr;text-align:left}
/* Decorative arrows: leave them as-is (the chevrons are pure decoration; users learn) */

/* Language switcher button (bilingual EN/AR toggle) */
.lang-switcher{
  display:inline-flex;align-items:center;gap:6px;
  padding:8px 14px;border:1.5px solid var(--stone);border-radius:var(--radius-pill);
  background:var(--white);color:var(--navy-deep);
  font-weight:700;font-size:12px;letter-spacing:.5px;cursor:pointer;
  transition:all .2s;
}
.lang-switcher:hover{border-color:var(--gold);color:var(--gold-deep)}
.lang-switcher i{color:var(--gold-deep);font-size:13px}

/* =========================================================
   APP DOWNLOAD BADGES (rectangular, clean — like the official ones)
   ========================================================= */
.app-badges{display:inline-flex;gap:10px;flex-wrap:wrap;align-items:center}
.app-badge{
  display:inline-flex;align-items:center;gap:10px;
  padding:9px 16px;border-radius:10px;background:#000;color:#fff;
  text-decoration:none;border:1px solid rgba(255,255,255,.18);
  transition:transform .2s,background .2s,border-color .2s;
  min-width:160px;height:54px;line-height:1;
}
.app-badge:hover{transform:translateY(-2px);background:#111;border-color:var(--gold)}
.app-badge i{font-size:26px;flex-shrink:0}
.app-badge .ab-text{display:flex;flex-direction:column;gap:2px;line-height:1.1}
.app-badge .ab-small{font-size:9.5px;color:rgba(255,255,255,.78);font-weight:500;letter-spacing:.4px;text-transform:uppercase}
.app-badge .ab-big{font-family:var(--font-display);font-size:17px;font-weight:600;letter-spacing:.2px}
@media(max-width:540px){.app-badge{min-width:140px;padding:8px 12px;height:48px}.app-badge i{font-size:22px}.app-badge .ab-big{font-size:14px}}

/* =========================================================
   UNIFIED DARK FOOTER (logo + socials + app badges + copyright)
   ========================================================= */
.site-footer{
  background:linear-gradient(135deg,var(--navy-deep) 0%,#02091e 100%);
  color:#fff;padding:50px 0 0;border-top:3px solid var(--gold);
  margin-top:0;
}
.site-footer .container{padding-top:0;padding-bottom:0}
.sf-grid{
  display:grid;grid-template-columns:1.2fr 1fr;gap:40px;
  align-items:center;padding-bottom:36px;
}
@media(max-width:768px){.sf-grid{grid-template-columns:1fr;text-align:center;gap:30px}}
.sf-brand{display:flex;flex-direction:column;gap:14px}
@media(max-width:768px){.sf-brand{align-items:center}}
.sf-logo{height:44px;width:auto;filter:brightness(0) invert(1);opacity:.95}
.sf-tagline{color:var(--gold);font-style:italic;font-size:14px;font-weight:500;letter-spacing:.3px}
.sf-socials{display:flex;gap:10px;margin-top:4px}
.sf-socials a{
  width:38px;height:38px;border-radius:50%;background:rgba(255,255,255,.08);
  display:grid;place-items:center;color:#fff;font-size:14px;text-decoration:none;
  transition:all .2s;border:1px solid rgba(255,255,255,.12);
}
.sf-socials a:hover{background:var(--gold);color:var(--navy-deep);border-color:var(--gold);transform:translateY(-2px)}

.sf-apps{display:flex;flex-direction:column;gap:12px}
@media(max-width:768px){.sf-apps{align-items:center}}
.sf-apps-title{
  font-size:11px;color:var(--gold);text-transform:uppercase;letter-spacing:2.5px;
  font-weight:700;
}
.sf-apps .app-badges{justify-content:flex-start}
@media(max-width:768px){.sf-apps .app-badges{justify-content:center}}

.sf-bottom{
  border-top:1px solid rgba(255,255,255,.08);
  padding:18px 0;text-align:center;
  font-size:12px;color:rgba(255,255,255,.6);
}
.sf-bottom a{color:var(--gold);text-decoration:none;font-weight:500}
.sf-bottom a:hover{text-decoration:underline}

/* legacy class — keep but unused now */
.app-footer-bar{display:none}

/* App badges row INSIDE rich footer (used by index.html etc.) */
.footer-apps{
  border-top:1px solid rgba(255,255,255,.08);
  padding:24px 0;display:flex;align-items:center;justify-content:space-between;
  flex-wrap:wrap;gap:18px;
}
.footer-apps .fa-title{
  font-size:11px;color:var(--gold);text-transform:uppercase;letter-spacing:2.5px;
  font-weight:700;
}
@media(max-width:768px){.footer-apps{justify-content:center;text-align:center}}

/* RTL adjustments for footer */
html[dir="rtl"] .footer-brand p{max-width:none}
html[dir="rtl"] .contact-line{flex-direction:row-reverse;text-align:right}
html[dir="rtl"] .contact-line i{padding-top:4px}
html[dir="rtl"] .footer-bottom{direction:rtl}
html[dir="rtl"] .socials{justify-content:flex-end}
html[dir="rtl"] footer h5{text-align:right}
html[dir="rtl"] footer ul{text-align:right}
/* In Arabic mode, the navbar CTA cluster (Rate / WhatsApp / nav-toggle) reads
   naturally from right to left because the flex container inherits direction:rtl.
   Force a tighter gap so the icons feel evenly distributed and don't crowd
   the menu, and make the WhatsApp icon button mirror its margin. */
html[dir="rtl"] .nav-cta{flex-direction:row-reverse}
html[dir="rtl"] .nav-cta .btn-whatsapp{margin-right:0;margin-left:6px}
html[dir="rtl"] .nav-cta .btn-rate-cta{margin-left:0}
/* V204 — Issue #14: on MOBILE (<=768) the live CTA cluster is
   [Rate, Sign-in pill (.gan-mount, injected by account-nav.js), hamburger] and
   the lang-switcher is relocated out of .nav-cta. The desktop row-reverse above
   then drives the hamburger to the FAR RIGHT in Arabic, breaking RTL hierarchy.
   On mobile RTL only, fall back to flex-direction:row so the natural RTL main
   axis (right->left) yields visual left->right = hamburger | Sign in | Rate, with
   the hamburger at the extreme left edge. Neutralize the JS inline margin on the
   pill so the uniform 10px flex gap owns the (balanced) spacing. EN, desktop and
   tablet (>=769) are untouched; pages without .gan-mount are unaffected. */
@media(max-width:768px){
  html[dir="rtl"] .nav-cta{flex-direction:row}
  html[dir="rtl"] .nav-cta .gan-mount{margin-left:0 !important;margin-right:0 !important}
  /* Topbar-LESS pages (e.g. search.html) keep the lang-switcher inside .nav-cta as
     their only language toggle, making a 4-item cluster that overflows narrow AR
     phones (<=390) and would clip the now-far-left hamburger. Shrink that in-nav
     switcher to its globe icon on mobile RTL so all four items fit and the
     hamburger stays fully tappable at the left edge. Language access is preserved
     (icon still toggles), matching the existing icon-only Rate button on mobile.
     Pages whose lang-switcher lives in the topbar (e.g. homepage) are unaffected
     — they have no .nav-cta .lang-switcher. EN mobile is left exactly as-is. */
  html[dir="rtl"] .nav-cta .lang-switcher span[data-lang-label]{display:none}
  html[dir="rtl"] .nav-cta .lang-switcher{padding-left:10px;padding-right:10px}
}
/* V205 — Issue #18 safety net: at very narrow widths (<=360, e.g. iPhone SE
   320), even after the #14 RTL guard the topbar-less pages (search/map/areas
   prior to the V205 topbar additions, and any other topbar-less public page
   that retains the in-nav lang-switcher) can still push the hamburger off
   screen. Shrink the in-nav lang-switcher to its globe icon in BOTH languages
   at <=360 so the four-item cluster fits and the hamburger remains visible
   and tappable. Pages whose lang lives in the topbar are unaffected (selector
   targets .nav-cta .lang-switcher only). >=361 keeps EN behaviour exactly as
   pre-V205 (preserves the "EN exactly" rule above 360). */
@media(max-width:360px){
  .nav-cta .lang-switcher span[data-lang-label]{display:none}
  .nav-cta .lang-switcher{padding-left:10px;padding-right:10px}
}
/* FFC-3 (2026-06-05) — narrow-laptop nav-cta overflow guard.
   Reproducible inspection: at 1366×900 viewport, unit.html and developer.html
   show body.scrollWidth = 1409–1410 (overflow +43–44px past viewport).
   Probe-confirmed rightmost element is .nav-cta (offsetW 377, right_edge 1409).
   Container max-width is 1280 at 1366 viewport (overflows container by 86px).
   Root cause: assets/i18n.js applyTopbarLang() (line 1869) moves
   .navbar .nav-cta .lang-switcher into .topbar .right at runtime.
   Pages WITH .topbar (index/project/search/map/properties/contact/areas/
   developers/careers/trending/sell/rate-my-property): lang-switcher is
   relocated → nav-cta has 3 children (Rate / Sign-in / hamburger) → 1366 clean.
   Pages WITHOUT .topbar (unit/developer/projects/area/about): the relocation
   no-ops → lang-switcher stays in .nav-cta → 4 children → 1366 overflow.
   Fix: extend the existing V205 <=360 label-hide pattern up to 1599 (above
   1600 the larger --container 1480 absorbs the cluster naturally). Selector
   only matches lang-switchers still IN nav-cta, so topbar pages are
   unaffected — i18n.js has already moved theirs out. Globe icon remains
   visible. Hamburger-active range is 0–1599 per V141. Smallest-safe additive
   CSS, no layout / design / token change. */
@media (min-width:361px) and (max-width:1599px){
  .nav-cta .lang-switcher span[data-lang-label]{display:none}
  .nav-cta .lang-switcher{padding-left:10px;padding-right:10px}
}
/* Topbar lang switcher / contact icons: in RTL push them to the start (left) */
html[dir="rtl"] .topbar-actions{flex-direction:row-reverse;margin-left:0;margin-right:auto}
/* Footer social row: in RTL, pull the cluster to the right edge of the brand
   column (which is now the visual start). */
html[dir="rtl"] .footer-brand .socials{justify-content:flex-start}

/* =========================================================
   STICKY MAP QUICK-ACCESS BUTTON (listing pages)
   ========================================================= */
.map-quick-fab{
  position:fixed;top:88px;right:20px;z-index:900;
  display:inline-flex;align-items:center;gap:8px;
  padding:10px 18px;border-radius:var(--radius-pill);
  background:var(--navy);color:#fff;
  font-weight:700;font-size:13px;letter-spacing:.4px;
  text-decoration:none;
  box-shadow:0 8px 22px rgba(6,21,51,.28),0 0 0 1px rgba(255,255,255,.12) inset;
  transition:all .25s;
}
.map-quick-fab:hover{
  background:var(--gold);color:var(--navy-deep);transform:translateY(-2px);
  box-shadow:0 12px 28px rgba(201,169,97,.45);
}
.map-quick-fab i{font-size:14px;color:var(--gold)}
.map-quick-fab:hover i{color:var(--navy-deep)}
html[dir="rtl"] .map-quick-fab{right:auto;left:20px}
@media(max-width:540px){
  .map-quick-fab{padding:9px 14px;font-size:12px;top:74px;right:12px}
  html[dir="rtl"] .map-quick-fab{right:auto;left:12px}
}

/* SCROLL-TO-TOP FLOAT BUTTON (.back-to-top is alias)
   Mobile Polish P1 — bottom now adds env(safe-area-inset-bottom) so the
   button clears the iPhone home-indicator strip on devices with notches.
   Falls back to 0 on older browsers / non-notched devices.

   Mobile Polish M2 — Removed the `border:2px solid var(--gold)` that
   previously stacked on top of `box-shadow:var(--shadow-lift)`. The
   combination created a visible "double circle" effect next to the
   WhatsApp FAB on small screens. The button now matches the WhatsApp
   FAB's clean shadow-only resting state. Navy/gold identity is preserved
   via: navy resting background, gold hover background. No changes to
   position, size, z-index, or safe-area handling. */
.scroll-top-float, .back-to-top{
  /* Bugfix sprint — back-to-top now stacks above WhatsApp via the
     shared --fab-bottom-mobile / --fab-gap-vertical variables, so
     a single :root edit moves both. Desktop value unchanged. */
  position:fixed;bottom:calc(96px + env(safe-area-inset-bottom, 0px));right:24px;width:48px;height:48px;
  background:var(--navy);color:var(--white);border-radius:50%;
  display:none;place-items:center;font-size:18px;cursor:pointer;
  box-shadow:var(--shadow-lift);z-index:998;transition:all .25s;
  text-decoration:none;
}
.scroll-top-float:hover, .back-to-top:hover{background:var(--gold);color:var(--navy-deep);transform:translateY(-3px)}
.scroll-top-float.visible, .back-to-top.show{display:grid}
html[dir="rtl"] .scroll-top-float, html[dir="rtl"] .back-to-top{right:auto;left:24px}
@media(max-width:540px){
  /* WhatsApp height ≈ 56px on mobile + gap → back-to-top sits ~140px up. */
  .scroll-top-float, .back-to-top{
    bottom:calc(var(--fab-bottom-mobile) + 56px + var(--fab-gap-vertical));
    width:42px;height:42px;font-size:16px;
  }
}

/* HERO PHOTO BACKGROUND HELPER */
.hero-photo{position:absolute;inset:0;z-index:0;overflow:hidden}
.hero-photo::before{
  content:"";position:absolute;inset:0;
  background:linear-gradient(135deg,rgba(6,21,51,.78) 0%,rgba(10,31,68,.72) 50%,rgba(6,21,51,.85) 100%);
  z-index:2;
}
.hero-photo::after{
  content:"";position:absolute;inset:0;
  background:radial-gradient(ellipse at 75% 30%,rgba(201,169,97,.18) 0%,transparent 55%);
  z-index:3;pointer-events:none;
}
.hero-photo img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  z-index:1;filter:saturate(1.05) contrast(1.05);
}

/* TRACK A · H-D (2026-06-13) — opt-in modifier for pages that use the
   inline brand SVG canvas (assets/hero-canvas.svg) instead of a real
   photo. The SVG is already navy with its own 3-stop depth + soft gold
   radial accent, so the global .hero-photo::before navy tint at 72-85%
   becomes redundant and reads as flat. This modifier softens the
   overlay to a subtle navy mood layer so the underlying SVG breathes,
   and neutralises the photo-only saturate/contrast filter that was a
   no-op on a flat gradient. BEM pattern mirrors existing
   .hero-photo--flipping modifier (HERO-RTL-2 contract). */
.hero-photo.hero-photo--canvas::before{
  background:linear-gradient(135deg,rgba(6,21,51,.18) 0%,rgba(10,31,68,.10) 50%,rgba(6,21,51,.22) 100%);
}
.hero-photo.hero-photo--canvas img{
  filter:none;
}
/* TRACK A · R2-B (2026-06-13) — Owner-approved follow-up. R1 added the
   canvas modifier but the resulting hero stack still read as flat:
   each affected page's wrapper (.page-hero / .contact-hero / .cs-hero
   / .sell-hero / .rate-hero / .s-hero) ALREADY carries the same brand
   linear navy gradient + radial gold accent as about.html's .legal-hero
   success baseline. Adding the canvas img on top covered the wrapper's
   gold accent + introduced competing gradients and gold radials. R2-B
   hides the canvas layer entirely so the wrapper's brand identity (the
   one that owner approved on about.html) serves as the hero on its own.
   DOM markup preserved — display:none keeps the data-hero-key admin
   override path intact (admin can later remove --canvas class via
   override path if a real photo is supplied). */
.hero-photo.hero-photo--canvas{ display:none; }

/* WHATSAPP FLOAT
   Mobile Polish P1 —
   • `bottom` adds env(safe-area-inset-bottom) so the button clears the
     iPhone home-indicator strip. Per-page overrides (e.g. project.html's
     sticky-CTA stack at bottom:80px+safe-area) win over this base via
     specificity + position in the cascade.
   • Pulse animation is now gated behind `prefers-reduced-motion: no-preference`
     so users who request reduced motion (iOS Settings → Accessibility →
     Motion → Reduce Motion, or Windows / Android equivalents) see a still
     button — better for battery, vestibular comfort, and the "premium"
     still-feel. */
.whatsapp-float{
  /* Bugfix sprint — bottom offset now uses --fab-bottom-desktop, with a
     mobile @media block below taking it to --fab-bottom-mobile (which
     adds an extra 12px buffer on top of env(safe-area-inset-bottom) to
     clear iOS Safari's bottom toolbar / home-indicator). Size also
     drops to 56×56 on mobile so the FAB stack feels more proportionate
     to the smaller viewport. */
  position:fixed;bottom:var(--fab-bottom-desktop);right:24px;width:60px;height:60px;
  background:var(--whatsapp);color:var(--white);border-radius:50%;
  display:grid;place-items:center;font-size:28px;box-shadow:var(--shadow-lift);
  z-index:999;transition:all .25s;
}
@media (prefers-reduced-motion: no-preference){
  .whatsapp-float{animation:pulse 2s infinite}
}
.whatsapp-float:hover{transform:scale(1.08)}
html[dir="rtl"] .whatsapp-float{right:auto;left:24px}
@media(max-width:540px){
  .whatsapp-float{
    bottom:var(--fab-bottom-mobile);
    width:56px;height:56px;font-size:26px;
  }
}
/* V228 — T6: TABLET FAB OFFSETS (769–1599).
   Tablet floats sit 32px from the bottom edge (vs desktop 24px). Why: tablet
   landscape vh shrinks to 768/820 and the bottom safe-zone for thumb reach is
   slightly different from desktop. The 8px raise improves clearance from
   tab-bar / system-bar overlays on iPadOS. Stack arithmetic (tablet, bottom up):
     WhatsApp:    bottom = --fab-bottom-tablet                   (32px from edge)
     back-to-top: bottom = --fab-bottom-tablet + 60 + gap-v     (106px from edge)
   Desktop ≥1600 keeps --fab-bottom-desktop (24px). Mobile ≤540 keeps --fab-bottom-mobile. */
@media (min-width:768px) and (max-width:1599px){
  .whatsapp-float{ bottom: var(--fab-bottom-tablet) }
  .scroll-top-float, .back-to-top{
    bottom: calc(var(--fab-bottom-tablet) + 60px + var(--fab-gap-vertical));
  }
}
@keyframes pulse{
  0%,100%{box-shadow:0 0 0 0 rgba(37,211,102,.5),var(--shadow-lift)}
  50%{box-shadow:0 0 0 14px rgba(37,211,102,0),var(--shadow-lift)}
}

/* EXIT-INTENT POPUP */
.exit-popup{
  position:fixed;inset:0;background:rgba(6,21,51,.85);backdrop-filter:blur(8px);
  z-index:9999;display:none;align-items:center;justify-content:center;padding:20px;
  animation:fadeIn .3s ease;
}
.exit-popup.active{display:flex}
.exit-popup-card{
  background:var(--white);border-radius:24px;max-width:520px;width:100%;
  overflow:hidden;box-shadow:var(--shadow-lift);position:relative;
  animation:slideUp .4s ease;
}
.exit-popup-close{
  position:absolute;top:16px;right:16px;width:38px;height:38px;border-radius:50%;
  background:rgba(0,0,0,.06);color:var(--slate);font-size:14px;z-index:2;
  display:grid;place-items:center;transition:all .2s;
}
.exit-popup-close:hover{background:var(--navy);color:var(--white);transform:rotate(90deg)}
.exit-popup-banner{
  background:linear-gradient(135deg, var(--navy) 0%, var(--navy-deep) 100%);
  color:var(--white);padding:36px 32px;position:relative;overflow:hidden;
}
.exit-popup-banner::before{
  content:"";position:absolute;top:-30px;right:-30px;width:200px;height:200px;
  background:radial-gradient(circle, rgba(201,169,97,.25) 0%, transparent 65%);
}
.exit-popup-banner .eyebrow{color:var(--gold);position:relative;z-index:2}
.exit-popup-banner h3{color:var(--white);font-size:26px;line-height:1.2;margin-bottom:8px;position:relative;z-index:2}
.exit-popup-banner p{color:rgba(255,255,255,.85);font-size:15px;position:relative;z-index:2}
.exit-popup-body{padding:28px 32px}
.exit-popup-body .form-row{margin-bottom:14px}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes slideUp{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}

/* TRUST BADGES & URGENCY */
.urgency-badge{
  display:inline-flex;align-items:center;gap:6px;
  background:rgba(220,38,38,.1);color:#dc2626;
  padding:6px 12px;border-radius:var(--radius-pill);font-size:11px;font-weight:700;
  text-transform:uppercase;letter-spacing:1px;
}
.urgency-badge i{font-size:9px;animation:blink 1.5s infinite}
@keyframes blink{0%,100%{opacity:1}50%{opacity:.4}}

/* Reveal animation */
.reveal{opacity:0;transform:translateY(24px);transition:all .8s ease}
.reveal.visible{opacity:1;transform:translateY(0)}

/* =========================================================
   ARABIC RTL POLISH — directional flips so the experience
   feels natively Arabic, not mirrored-English. Applied via
   html[dir="rtl"] so the LTR site is untouched.
   ========================================================= */

/* Native Arabic typography preference — Tajawal first in RTL */
html[dir="rtl"] body,
html[dir="rtl"] input,
html[dir="rtl"] textarea,
html[dir="rtl"] select,
html[dir="rtl"] button{
  font-family:'Tajawal','Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif;
}
/* Display headings keep their Cormorant feel but pair with Tajawal weights */
html[dir="rtl"] h1,html[dir="rtl"] h2,html[dir="rtl"] h3,html[dir="rtl"] h4,html[dir="rtl"] h5,html[dir="rtl"] h6{
  font-family:'Cormorant Garamond','Tajawal',serif;letter-spacing:0;
}
/* Slightly relax line-height — Arabic glyphs are taller */
html[dir="rtl"] body{line-height:1.75; font-size:17px}
html[dir="rtl"] p{line-height:1.9; font-size:1.04em}

/* === Arabic typography size compensation =================================
   Tajawal renders smaller than Inter at the same px size — match the English
   visual weight using ABSOLUTE clamp values (em-based multipliers were broken
   because they cascade against the relaxed body font-size of 17px and produced
   tiny headings). These mirror the English clamp targets with a small visual
   bump so Arabic feels equal-or-larger, never smaller. */
html[dir="rtl"] h1{font-size:clamp(42px, 5.6vw, 68px); line-height:1.18; letter-spacing:0}
html[dir="rtl"] h2{font-size:clamp(32px, 3.8vw, 48px); line-height:1.25}
html[dir="rtl"] h3{font-size:clamp(23px, 2.1vw, 30px); line-height:1.35}
html[dir="rtl"] h4{font-size:clamp(19px, 1.6vw, 24px); line-height:1.45}
html[dir="rtl"] h5{font-size:16.5px; line-height:1.55}
html[dir="rtl"] h6{font-size:14.5px; line-height:1.55}

/* Hero — explicit override so the cinematic balance survives the lang switch */
html[dir="rtl"] .hero h1,
html[dir="rtl"] .tr-hero h1{
  font-size:clamp(44px, 6vw, 72px); line-height:1.2; letter-spacing:0;
  font-weight:700;
}
html[dir="rtl"] .hero p.lead,
html[dir="rtl"] .tr-hero p.lead{
  font-size:18.5px; line-height:1.85;
}

/* Section heads inside premium templates */
html[dir="rtl"] .section-head h2{font-size:clamp(28px, 3.4vw, 42px); line-height:1.28}
html[dir="rtl"] .eyebrow{font-size:13px; letter-spacing:1.6px}

/* Buttons + form controls keep visual weight; use absolute units so they
   don't compound against a relaxed body size. */
html[dir="rtl"] .btn,
html[dir="rtl"] .btn-primary,
html[dir="rtl"] .btn-gold{font-size:15.5px; line-height:1.2}
html[dir="rtl"] .btn-lg{font-size:16.5px}
html[dir="rtl"] .btn-sm{font-size:13.5px}

html[dir="rtl"] .nav-menu a{font-size:15.5px;letter-spacing:.1px}
html[dir="rtl"] .topbar{font-size:13.5px}
html[dir="rtl"] label,
html[dir="rtl"] input,
html[dir="rtl"] select,
html[dir="rtl"] textarea{font-size:15.5px;line-height:1.6}

/* Footer + small text — keep readable, not shrunken */
html[dir="rtl"] footer{font-size:14.5px;line-height:1.85}
html[dir="rtl"] footer .footer-grid h5{font-size:14px;letter-spacing:.6px}
html[dir="rtl"] footer .footer-grid a{font-size:13.5px}

/* KPI/stat numbers — keep tabular feel even in Arabic, force LTR for digits */
html[dir="rtl"] .kpi-val,
html[dir="rtl"] .stat-val,
html[dir="rtl"] [data-numeric]{
  direction:ltr;display:inline-block;font-variant-numeric:tabular-nums;
}

/* Icon flips — arrows that point in a direction should mirror in RTL.
   We exclude logos, brand marks, and non-directional icons. */
html[dir="rtl"] .fa-arrow-left,
html[dir="rtl"] .fa-arrow-right,
html[dir="rtl"] .fa-chevron-left,
html[dir="rtl"] .fa-chevron-right,
html[dir="rtl"] .fa-angle-left,
html[dir="rtl"] .fa-angle-right,
html[dir="rtl"] .fa-arrow-trend-up{
  transform:scaleX(-1);display:inline-block;
}
/* Phone numbers stay LTR (numerals) */
html[dir="rtl"] [href^="tel:"]{direction:ltr;display:inline-block}

/* Topbar — align Head Office + lang to the leading (right) edge.
   Container is flex with space-between, so the natural flip happens. */
html[dir="rtl"] .topbar .left{flex-direction:row}
html[dir="rtl"] .topbar .right{flex-direction:row}

/* Navbar — logo + menu + CTA naturally flip with the parent flex.
   Account-nav slot already inserts before .nav-toggle which is correct
   in both directions. */
html[dir="rtl"] .nav-menu{padding-right:0}
/* Nav active state is now a symmetric gold-glass capsule (see .nav-menu a
   above). It uses padding + box-shadow + background only — no directional
   logic — so RTL needs zero overrides. */

/* Footer — legal strip dot separator already RTL-aware. Footer-grid
   and contact lines flow naturally with flexbox. */
html[dir="rtl"] .contact-line{flex-direction:row}
html[dir="rtl"] .contact-line i{margin-left:8px;margin-right:0}

/* Section heads — keep watermark centered in BOTH directions; the previous
   translateX(50%) override was the cause of the "watermark sliding right
   in Arabic" bug. We keep translateX(-50%) for both LTR and RTL because
   the watermark is positioned at left:50% which is a viewport offset, not
   a writing-mode-relative one. */
html[dir="rtl"] .section-head[data-watermark]::before{transform:translateX(-50%)}

/* Cards — image hover zoom is direction-neutral. Pagination arrow icons
   already flip via the .fa-chevron-* rule above. Active dot under
   pagination centers on its own — fine. */

/* Nav active state is the gold-glass capsule defined above — symmetric
   by construction, no RTL anchoring concerns. */

/* Search/filter bars — input padding flips naturally via flexbox.
   Form labels with floating animation keep their transform-origin
   on the leading (right) edge (handled in auth-cinema.css). */

/* Inline icon spacing inside buttons — already exists below; reinforce */
html[dir="rtl"] .btn i:first-child{margin-right:0;margin-left:8px}
html[dir="rtl"] .btn i:last-child{margin-left:0;margin-right:8px}

/* Quotes use opposite typographic marks in Arabic */
html[dir="rtl"] blockquote::before{content:"\00AB"}
html[dir="rtl"] blockquote::after {content:"\00BB"}

/* Native-feel numerals: when the user wants Arabic-Indic digits in
   contexts where it reads better (counts, dates), opt-in via .ar-num.
   Default keeps Western digits since prices/counts are easier to scan. */
html[dir="rtl"] .ar-num{font-feature-settings:"ss03";font-variant-numeric:normal}

/* =========================================================
   PREMIUM PRICE TYPOGRAPHY — global upgrade
   Applies to ALL price/money/stat values across the site.
   --------------------------------------------------------
   Goals:
   · Tabular figures so digits align perfectly (8.5M lines up with 12.5M)
   · Tighter letter-spacing on big numbers for refined display feel
   · Currency suffix (EGP / mo) styled as small gold uppercase chip
   · Consistent Playfair Display weight + navy color across pages
   ========================================================= */

/* ---- All price-displaying selectors share the same typographic base ---- */
.price,
.money,
.pc-price,
.um-price,
.uc-price,
.cp-amount,
.cp-monthly b,
.cps-value,
.pp-value,
.pb-value,
.pay-item .pay-value,
.qi-item .value,
.gs-value,
.glance-stat .gs-value,
.hero-stats .stat strong,
.dev-tile-stats .stat strong,
.ph-stat strong,
.trust-grid .item strong,
.related-card .rc-price,
.sc-price,
.um .um-price,
.prop-card .pc-price,
.prop-price,
.search-results .price-tag {
  font-family: var(--font-display) !important;
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum", "lnum";
  letter-spacing: -.4px;
  font-weight: 700;
}

/* ---- Currency / unit suffix ("EGP", "/mo", "Years") ----
   Style: smaller, gold uppercase, with a subtle separator effect.
   Applied to <small> tags inside any of the above price selectors. */
.price small,
.money small,
.pc-price small,
.um-price small,
.uc-price small,
.cp-amount small,
.pp-value small,
.pb-value small,
.pay-item .pay-value small,
.qi-item .value small,
.related-card .rc-price small,
.um .um-price small,
.prop-price small {
  font-family: var(--font-body) !important;
  font-size: .54em !important;
  font-weight: 600;
  color: var(--gold-deep);
  letter-spacing: 1.5px;
  text-transform: uppercase;
  margin-left: .35em;
  vertical-align: .18em;
  display: inline-block;
}
html[dir="rtl"] .price small,
html[dir="rtl"] .money small,
html[dir="rtl"] .pc-price small,
html[dir="rtl"] .um-price small,
html[dir="rtl"] .uc-price small,
html[dir="rtl"] .cp-amount small,
html[dir="rtl"] .pp-value small,
html[dir="rtl"] .pb-value small,
html[dir="rtl"] .qi-item .value small,
html[dir="rtl"] .um .um-price small,
html[dir="rtl"] .prop-price small{
  margin-left: 0;
  margin-right: .35em;
}

/* ---- Reusable utility class for new markup ----
   Use: <span class="money">8.5<small>M EGP</small></span> */
.money {
  color: var(--navy-deep);
  display: inline-flex;
  align-items: baseline;
}
.money.gold { color: var(--gold-deep); }
.money.white { color: #fff; }

/* ---- "From" / pre-label prefix ---- */
.price-from-prefix,
.money .pre {
  font-family: var(--font-body) !important;
  font-size: 11px;
  font-weight: 600;
  color: var(--slate);
  text-transform: uppercase;
  letter-spacing: 2px;
  margin-right: .55em;
  display: inline-block;
}
html[dir="rtl"] .price-from-prefix,
html[dir="rtl"] .money .pre {
  margin-right: 0;
  margin-left: .55em;
}

/* ---- Price hierarchy sizes (optional helpers) ---- */
.money-xs { font-size: 14px; }
.money-sm { font-size: 18px; }
.money-md { font-size: 22px; }
.money-lg { font-size: 32px; line-height: 1; }
.money-xl { font-size: 42px; line-height: 1; letter-spacing: -.6px; }
.money-2xl { font-size: 56px; line-height: 1; letter-spacing: -.8px; }

/* ---- Price-context micro-label (e.g. "Starting Price", "Monthly Rent") ---- */
.price-eyebrow {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--gold-deep);
  text-transform: uppercase;
  letter-spacing: 2px;
  display: block;
  margin-bottom: 6px;
}


/* ============================================================================
   APPLICATION-READINESS POLISH (added by audit #124–129)
   ----------------------------------------------------------------------------
   Lightweight defensive rules to make the public site behave well inside
   mobile-app webview containers (iOS WKWebView, Android WebView, capacitor,
   PWA installs). Non-invasive — pure progressive enhancement.
   ============================================================================ */
/* Prevent iOS Safari zoom-on-focus by ensuring inputs stay ≥16px font-size on
   small screens. Browsers ignore the zoom heuristic at 16px+. */
@media(max-width:639px){
  input:not([type="checkbox"]):not([type="radio"]),
  select, textarea{
    font-size:16px !important;
  }
}
/* Honour the iOS notch / Android gesture areas on any element flagged as
   safe-area-aware. */
.safe-area-inset-bottom{ padding-bottom:max(env(safe-area-inset-bottom), 12px) }
.safe-area-inset-top{    padding-top:max(env(safe-area-inset-top), 12px) }
/* Disable rubber-banding pull-to-refresh inside webviews — webview hosts
   already drive their own pull-to-refresh. */
@supports(overscroll-behavior:none){
  html, body{ overscroll-behavior-y:none }
}
/* Smoother, momentum-style scrolling in iOS webviews */
html, body{ -webkit-overflow-scrolling:touch }
/* Disable the gray default tap highlight on touch devices — it looks unfinished
   in webview/PWA contexts. Per-component styles already handle pressed states. */
*{ -webkit-tap-highlight-color:transparent }

/* ── Inline lead-form success banner (Pre-Owner Sprint, owner-approved) ──
   Premium in-page confirmation that replaces the native browser alert() on
   public lead forms (index callback + exit popup, contact, properties,
   request-consultant, sell-your-property). Additive, new class only — no
   existing rule is overridden. Hidden until the form's onsubmit reveals it. */
.lead-ok{display:flex;gap:10px;align-items:flex-start;margin-top:14px;padding:13px 16px;
  border-radius:12px;background:rgba(34,197,94,.10);border:1px solid rgba(34,197,94,.38);
  color:#15803d;font-size:14px;line-height:1.55}
.lead-ok[hidden]{display:none}
.lead-ok i{color:#16a34a;font-size:18px;line-height:1.4;flex:none}
html[dir="rtl"] .lead-ok{flex-direction:row-reverse;text-align:right}

/* ============================================================
   V228 — T8: TABLET LANDSCAPE HERO COMPRESSION
   ============================================================
   Scope: orientation:landscape AND tablet-width range AND max-height ≤ 870.
   This intersection matches: iPad landscape 1024×768, iPad Air landscape 1180×820,
   iPad Pro 11" landscape ~1194×834. Excludes iPad Pro 13" landscape 1366×1024 (h>870
   → search already above the fold per V228 audit measurements).

   Effect: on these specific landscape orientations, hero typography + paddings
   are compressed so the search-bar rises above the fold (search_Vh ≤ 0.85).
   Portrait orientations (768/820/1024 portrait) and desktop ≥1600 are untouched.
   Brand voice preserved — only proportions adjust on tight landscape viewports.
   ============================================================ */
@media (min-width:1024px) and (max-width:1599px) and (orientation:landscape) and (max-height:870px){
  .hero{ padding-block: 80px 60px }
  .hero h1{ font-size: 40px; line-height: 1.1 }
  .hero p{ margin-bottom: 18px }
  .hero-actions{ margin-bottom: 18px }
}

/* =====================================================================
   QW1 — Wave A · Quick Wins (2026-06-10, owner-approved PRE-QW1 → Wave A)
   ---------------------------------------------------------------------
   Contains scoped CSS for:
     · Item 9 — Tablet 2-column safe wins (listing grids @ 768–1023)
     · Item 7 — Sticky TOC chrome (mobile + tablet only, ≤ 1023)
   Desktop ≥ 1024 is UNCHANGED. Mobile < 768 is UNCHANGED for Item 9.
   Mobile + tablet ≤ 1023 receives Item 7. Desktop receives nothing.

   Rollback: delete this block. site.css returns to its PRE-QW1 SHA.
   ===================================================================== */

/* ── Item 9 — Tablet 2-column grids (768–1023 only) ───────────────── */
@media (min-width: 768px) and (max-width: 1023px) {
  .props-grid    { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 18px; }
  .projects-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 18px; }
  .dev-grid      { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 18px; }
  .areas-grid    { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 18px; }
}

/* ── Item 7 — Sticky TOC chrome (mobile + tablet only, ≤ 1023) ────── */
@media (max-width: 1023px) {
  .qw1-toc {
    position: sticky;
    top: 60px; /* under public nav */
    z-index: 50;
    background: rgba(255, 250, 240, 0.97); /* paper */
    backdrop-filter: saturate(140%) blur(6px);
    -webkit-backdrop-filter: saturate(140%) blur(6px);
    border-top: 1px solid #C9A961; /* gold */
    border-bottom: 1px solid #C9A961;
    padding: 8px 0;
    margin: 0 0 8px 0;
    overflow: hidden;
  }
  .qw1-toc__rail {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    padding: 0 16px;
    margin: 0;
    list-style: none;
  }
  .qw1-toc__rail::-webkit-scrollbar { display: none; }
  .qw1-toc__chip {
    flex: 0 0 auto;
    scroll-snap-align: start;
    padding: 6px 14px;
    border: 1px solid #B89656; /* gold-deep */
    border-radius: 999px;
    background: transparent;
    color: #0a1f44; /* navy */
    font-family: 'Cinzel', serif;
    font-size: 11px;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    transition: background 160ms ease, color 160ms ease;
    cursor: pointer;
  }
  .qw1-toc__chip:hover,
  .qw1-toc__chip:focus-visible {
    background: #f4ede0; /* cream */
    color: #0a1f44;
    outline: none;
  }
  .qw1-toc__chip.is-active {
    background: #0a1f44; /* navy */
    color: #C9A961;     /* gold */
    border-color: #0a1f44;
  }
  /* respect reduced motion */
  @media (prefers-reduced-motion: reduce) {
    .qw1-toc__chip { transition: none; }
    html { scroll-behavior: auto !important; }
  }
  /* RTL safety — logical scrolling */
  html[dir="rtl"] .qw1-toc__rail { direction: rtl; }
}
/* Desktop (≥ 1024) — TOC chrome stays hidden so no desktop layout change. */
@media (min-width: 1024px) {
  .qw1-toc { display: none !important; }
}
/* QW1 — Wave A END */

/* ===========================================================================
   QW1 — Wave B · Mobile-only refinements (2026-06-10, owner-approved Wave A → Wave B)
   ---------------------------------------------------------------------------
   Item 1 — Footer mobile accordion (<768px)
   Item 2 — Simplified single Concierge dock/pill (<768px)

   Owner constraints honored:
     · Mobile-only under 768px; tablet/desktop layout UNCHANGED.
     · Single pill (no 3-button CTA bar).
     · Direction B voice — "Concierge" / "Talk to Concierge".
     · No overlap with whatsapp-float (bottom-right) or back-to-top.
     · Reuses existing data-config-href="wa:contact.whatsapp" pattern.
     · No nav / map / Gate 5 / cutover / IA work touched.
   =========================================================================== */
@media (max-width: 767px) {
  /* ---------- Item 1 — Footer mobile accordion ---------- */
  /* Hooks V226's existing data-foot-state="open|closed" attribute (the JS
     contract is unchanged; we just expand its visual range from ≤540 to
     ≤767 to honor the owner's <768 mobile spec). Rules below override the
     V213 always-visible block ≤540 with attribute-keyed selectors (same
     specificity = a single class/attribute pair; declared later → wins). */

  /* Make the h5 a tappable surface again (V213 forced cursor:default at ≤540) */
  footer .footer-grid > div[data-foot-state] > h5 {
    cursor: pointer !important;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    position: relative;
    padding-right: 22px; /* chevron room */
    text-align: center;
  }
  html[dir="rtl"] footer .footer-grid > div[data-foot-state] > h5 {
    padding-right: 0;
    padding-left: 22px;
  }
  footer .footer-grid > div[data-foot-state] > h5::after {
    content: "";
    display: inline-block;
    position: absolute;
    right: 4px;
    top: 50%;
    width: 8px; height: 8px;
    margin-top: -6px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
    transition: transform 220ms ease;
    opacity: 0.85;
  }
  html[dir="rtl"] footer .footer-grid > div[data-foot-state] > h5::after {
    right: auto;
    left: 4px;
  }
  footer .footer-grid > div[data-foot-state="open"] > h5::after {
    transform: rotate(-135deg);
    margin-top: -1px;
  }

  /* Collapsed body — overrides V213 `max-height:none` AND feeds V212's
     `var(--foot-mh)` chain in admin-polish.css. We set both the body
     properties AND the parent's CSS custom properties so the V212 rule
     (which has the same specificity but later source order) resolves to
     our values via inheritance. */
  footer .footer-grid > div[data-foot-state="closed"] {
    --foot-mh: 0px;
    --foot-op: 0;
    --foot-pe: none;
  }
  footer .footer-grid > div[data-foot-state="open"] {
    --foot-mh: 800px;
    --foot-op: 1;
    --foot-pe: auto;
  }
  footer .footer-grid > div[data-foot-state="closed"] ul,
  footer .footer-grid > div[data-foot-state="closed"] .contact-line {
    max-height: 0 !important;
    overflow: hidden !important;
    opacity: 0 !important;
    margin-top: 0 !important;
    /* NO transition on max-height/opacity — V226-fix1d documented that var()-
       backed properties don't interpolate; transitions on them short-circuit
       and leave the value stuck at the start. Snap open/close is intentional. */
  }
  /* Use `html` prefix so the open rule outranks the V212 var-based rule on
     specificity (V212 = (0,2,3); html-prefixed open = (0,2,4) wins). */
  html footer .footer-grid > div[data-foot-state="open"] ul,
  html footer .footer-grid > div[data-foot-state="open"] .contact-line {
    max-height: 800px !important;
    overflow: visible !important;
    opacity: 1 !important;
    /* No transition — see V226-fix1d note above. Panel snaps open. */
  }
  /* Brand block stays fully visible regardless */
  footer .footer-grid > .footer-brand[data-foot-state] > h5 { cursor: default !important; padding-right: 0; }
  footer .footer-grid > .footer-brand[data-foot-state] > h5::after { display: none; }
  @media (prefers-reduced-motion: reduce) {
    footer .footer-grid > div[data-foot-state] ul,
    footer .footer-grid > div[data-foot-state] .contact-line { transition: none; }
    footer .footer-grid > div[data-foot-state] > h5::after { transition: none; }
  }

  /* ---------- Item 2 — Concierge dock/pill ---------- */
  /* Single pill, centered at bottom-center on mobile. Does NOT collide with
     .whatsapp-float (bottom-right) or back-to-top (bottom-right) — they keep
     their right column; the pill sits centered with horizontal margins so
     touch targets don't overlap. Max-width caps so it never crosses the
     whatsapp-float region. */
  .qw1-concierge {
    position: fixed;
    bottom: 16px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 999;            /* below whatsapp-float to avoid stacking conflict */
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 20px;
    background: #0a1f44;     /* navy */
    color: #C9A961;          /* gold */
    border: 1px solid #C9A961;
    border-radius: 999px;
    font-family: 'Cinzel', serif;
    font-size: 12px;
    letter-spacing: 1.8px;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    box-shadow: 0 8px 24px rgba(10, 31, 68, 0.32);
    /* Cap so we never overlap the floats on tiny screens (whatsapp-float right
       inset ≈ 24px + ~52px diameter = ~76px reserved on each side) */
    max-width: calc(100vw - 168px);
    overflow: hidden;
    text-overflow: ellipsis;
    transition: transform 200ms ease, box-shadow 200ms ease;
  }
  .qw1-concierge:hover,
  .qw1-concierge:focus-visible {
    background: #C9A961;     /* gold */
    color: #0a1f44;          /* navy */
    outline: none;
    transform: translateX(-50%) translateY(-2px);
    box-shadow: 0 12px 28px rgba(10, 31, 68, 0.4);
  }
  .qw1-concierge i,
  .qw1-concierge .qw1-concierge__icon {
    font-size: 14px;
  }
  @media (prefers-reduced-motion: reduce) {
    .qw1-concierge { transition: none; }
    .qw1-concierge:hover,
    .qw1-concierge:focus-visible { transform: translateX(-50%); }
  }
}
/* Tablet + Desktop (≥ 768) — Concierge pill stays HIDDEN. No tablet/desktop
   layout change. Owner constraint: "Concierge dock/pill must be mobile-only
   under 768px." */
@media (min-width: 768px) {
  .qw1-concierge { display: none !important; }
}
/* QW1 — Wave B END */


/* ============================================================================
   W7 SIDEBAR-SCROLL (2026-07-26) — Mobile-landscape recovery.
   Reproduced bug: at 844×390 (phone landscape) the open .nav-menu panel is
   ~649px tall inside a 386px-tall viewport with overflow:visible — the last
   4-5 nav items (Sell / Contact / Careers...) render BELOW the screen and can
   never be reached because the panel itself doesn't scroll.
   Fix (additive, same ≤1599 hamburger scope as V141/SIDEBAR-PATCH):
     • cap the open panel to the real dynamic viewport below the navbar
     • make the panel itself scrollable with momentum scrolling
     • overscroll-behavior:contain stops scroll chaining to the page behind
       (lightweight body-lock equivalent without JS state to desync).
   Desktop ≥1600 untouched. Admin/portal navs untouched. */
@media(max-width:1599px){
  .nav-menu.open{
    /* -40px extra: the fixed panel actually sits below navbar+topbar (~114px
       measured) while --navbar-h resolves 80px — the margin guarantees the
       last item is fully reachable at the smallest landscape heights. */
    max-height:calc(100dvh - var(--navbar-h, 80px) - 40px);
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
    overscroll-behavior:contain;
  }
  /* Fallback for browsers without dvh */
  @supports not (height: 100dvh){
    .nav-menu.open{ max-height:calc(100vh - var(--navbar-h, 80px) - 40px); }
  }
}


/* ============================================================================
   W7-HARDEN (2026-07-26) — Mobile nav: make the "narrow clipped strip"
   failure mode physically impossible.
   ROOT CAUSE: .nav-menu's base rule carries `align-items:center`. The ≤1599
   hamburger rule flips it to `stretch`, but in a column flex `center` sizes
   every row to its TEXT (~92px) instead of the panel width — producing a thin
   centred strip with clipped labels. Any cascade accident (stale cached CSS,
   source-order change, future override) that lets `center` win re-breaks it.
   FIX: stop depending on align-items at all — pin the rows to full width
   explicitly. Immune to whatever align-items resolves to.
   Scope: same ≤1599 hamburger range. Desktop ≥1600 untouched. Admin/portal
   navs use different markup and are unaffected. */
@media(max-width:1599px){
  .nav-menu{ align-items:stretch; }
  .nav-menu li{
    width:100%;
    align-self:stretch;
    box-sizing:border-box;
    flex:0 0 auto;
  }
  .nav-menu a{
    width:100%;
    box-sizing:border-box;
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
  }
}

/* ============================================================================
   M-WMI (2026-08-10) — LAPTOP NAV COLLAPSE FIX (1280–1599px)

   The W7-HARDEN block directly above targets max-width:1599px and gives every
   .nav-menu li width:100% — correct for the ≤1279px DROPDOWN, wrong for the
   1280–1599px INLINE row unlocked earlier in this file. Both blocks have equal
   specificity and W7 is later in source order, so it won.

   Measured on index.html at 1440px BEFORE this fix: 11 nav <li>, each 844px
   wide, laid out nowrap at x = 199, 1057, 1915, 2774 … 8782. One item visible;
   the other ten clipped by body{overflow-x:clip} with no horizontal scroll. And
   .nav-toggle is display:none in this band, so there was no fallback route to
   any nav item on a 1280–1599px laptop — the most common laptop width there is.

   This restores auto sizing for the inline row only. ≤1279px (hamburger
   dropdown) and ≥1600px (full desktop nav) are untouched.
   ============================================================================ */
@media (min-width:1280px) and (max-width:1599px){
  .nav-menu{ align-items:center; }
  .nav-menu li{ width:auto; flex:0 1 auto; align-self:auto; }
  .nav-menu a{ width:auto; }
}


/* ============================================================================
   RS-SWEEP (2026-07-26) — Responsive sweep fixes found by real-viewport audit.
   #1 projects.html @320/@390 overflowed by 164px/94px. Offender measured:
      <select id="filterDev"> intrinsic width 468px — a <select> sizes itself to
      its WIDEST <option>, and the developer list contains very long legal
      names. Nothing capped it, so it pushed the document wider than the
      viewport. Applies to any future long-option select too.
   Fix: cap every select to its container and allow it to shrink inside flex/
   grid parents (min-width:0 defeats the automatic min-content floor).
   Additive, no behaviour/binding change — the control still opens the same
   native list with the full text.
   ============================================================================ */
select{ max-width:100%; min-width:0; }
.filters select, .filter-bar select, .properties-controls select, .areas-controls select{
  max-width:100%; min-width:0; text-overflow:ellipsis;
}
