/* ============================================================
   style.css - Reusable Landing Page Template (editorial-premium)
   ------------------------------------------------------------
   Component / layout implementation. All colour, font, and
   spacing values come from theme.css custom properties (--ink,
   --paper, --gold, --font-serif, etc.) - nothing here is a
   project-specific hex or font name. Base layout below is the
   approved SOBHA One World design concept; everything after the
   "PRODUCTION ADDITIONS" marker is new: hero lead-capture form,
   mandatory mobile sticky CTA, mobile nav drawer, and real
   form/loading/error states wired to lead-engine.js + script.js.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@300;400;500;600&family=Manrope:wght@300;400;500;600&family=Playfair+Display:ital,wght@0,500;0,600;1,500&display=swap');
/* NOTE: these are STATIC-LAYER FALLBACKS only, used if theme.css ever fails
   to load - every token name here matches theme.css's [data-theme="..."]
   blocks exactly (--font-serif/--font-sans/--font-wide/--container-width),
   so a theme can actually override typography and container width, not just
   color. (A prior version of this file defined its own differently-named
   --serif/--sans/--wide tokens that theme.css never touched - themes could
   silently fail to change fonts if a future theme used different font
   stacks. Fixed: every component rule below now reads the --font-* names.) */
:root{--ink:#12120f;--paper:#f3f0e9;--warm:#ded8ca;--gold:#b69a61;--line:rgba(18,18,15,.16);--white:#faf9f5;--muted:#77746c;--font-serif:'Playfair Display',Georgia,serif;--font-sans:'DM Sans',Arial,sans-serif;--font-wide:'Manrope',Arial,sans-serif;--container-width:1240px}
*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--font-sans);font-weight:400}body:before{content:'';position:fixed;inset:0;pointer-events:none;opacity:.025;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140' viewBox='0 0 140 140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");z-index:20}a{text-decoration:none;color:inherit}button{font:inherit;border:0;cursor:pointer}.wrap{width:min(var(--container-width,1240px),calc(100% - 80px));margin:auto}.eyebrow{font:11px var(--font-wide);letter-spacing:.25em;text-transform:uppercase;color:var(--gold)}
/* nav */
.nav{position:fixed;z-index:30;top:0;left:0;right:0;height:82px;display:flex;align-items:center;transition:.35s;padding:0 40px;color:#fff}.nav.scrolled{background:rgba(15,15,13,.88);backdrop-filter:blur(14px);height:70px}.nav-inner{width:100%;display:flex;align-items:center;justify-content:space-between}.brand{display:flex;align-items:center;gap:13px}.brand-mark{width:31px;height:31px;border:1px solid rgba(255,255,255,.55);border-radius:50%;display:grid;place-items:center;font-family:var(--font-serif);font-size:19px}.brand-text{font-size:13px;letter-spacing:.17em;text-transform:uppercase}.brand-sub{font-size:8px;letter-spacing:.12em;opacity:.58;margin-top:4px}.nav-links{display:flex;gap:31px;font-size:11px;letter-spacing:.14em;text-transform:uppercase}.nav-links a{opacity:.78;transition:.2s}.nav-links a:hover{opacity:1;color:#e3d3ad}.nav-cta{padding:13px 19px;border:1px solid rgba(255,255,255,.55);color:#fff;background:transparent;font-size:10px;letter-spacing:.17em;text-transform:uppercase}.menu{display:none;color:#fff;background:none;font-size:25px}
/* hero */
.hero{height:100svh;min-height:700px;position:relative;overflow:hidden;background:#111}
/* Automated hero slideshow - each slide is an absolutely-positioned,
   full-bleed layer sharing the exact same box, so every image (whatever
   its native size) is forced through the same object-fit:cover crop -
   this is what keeps slides visually "consistent in size" regardless of
   the source photo's own dimensions. Crossfade via opacity transition;
   JS (initHeroSlideshow in script.js) just toggles .active on a timer. */
.hero-slideshow{position:absolute;inset:0;width:100%;height:100%}
.hero-slide{position:absolute;inset:0;width:100%;height:100%;opacity:0;transition:opacity 1.6s ease;will-change:opacity}
.hero-slide.active{opacity:1}
.hero-slide img{width:100%;height:100%;object-fit:cover;filter:saturate(.82) contrast(1.03)}
.hero:after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,rgba(5,5,4,.66) 0%,rgba(5,5,4,.28) 43%,rgba(5,5,4,.16) 100%),linear-gradient(0deg,rgba(5,5,4,.68) 0%,transparent 42%)}
/* Slide position dots - minimal, bottom-left, purely decorative/automated
   (no click handlers needed; the show advances on its own timer). */
.hero-dots{position:absolute;z-index:3;left:6.2%;bottom:13.5%;display:flex;gap:8px}
.hero-dots span{width:5px;height:5px;border-radius:50%;background:rgba(255,255,255,.4);transition:background .3s,transform .3s}
.hero-dots span.active{background:#fff;transform:scale(1.35)}
@media(max-width:900px){.hero-dots{display:none}}
/* .hero-grid is the ONE positioned layout box for hero copy + hero form -
   both used to be independently position:absolute with no shared container,
   which is why the form overlapped the headline at every width. Now they're
   flex siblings that negotiate space together. */
.hero-grid{position:absolute;z-index:2;inset:0;display:flex;align-items:flex-end;justify-content:space-between;gap:48px;padding:0 6.2% 11.5%;}
.hero-content{color:#fff;max-width:640px;min-width:0;flex:1 1 auto;}.hero-kicker{
  font:700 15px var(--font-wide);
  letter-spacing:.28em;
  text-transform:uppercase;
  color:#f0d79b;
  margin-bottom:25px;
  text-shadow:0 2px 10px rgba(0,0,0,.55);
}.hero h1{font:500 clamp(62px,8vw,128px)/.9 var(--font-serif);letter-spacing:-.045em;margin:0 0 27px}.hero h1 em{font-style:italic;font-weight:500}.hero-meta{display:flex;align-items:center;gap:22px;font:12px var(--font-wide);letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.86)}.hero-meta i{width:4px;height:4px;border-radius:50%;background:var(--gold)}.hero-actions{display:flex;gap:13px;margin-top:32px}.btn{padding:15px 23px;font:10px var(--font-wide);letter-spacing:.18em;text-transform:uppercase}.btn-light{background:#f6f3ec;color:#111}.btn-outline{border:1px solid rgba(255,255,255,.55);background:transparent;color:#fff}.hero-scroll{position:absolute;z-index:3;right:40px;bottom:42px;color:#fff;display:flex;align-items:center;gap:13px;font:9px var(--font-wide);letter-spacing:.2em;text-transform:uppercase;writing-mode:vertical-rl}.hero-scroll span{height:56px;width:1px;background:rgba(255,255,255,.55)}.video-label{position:absolute;right:42px;top:110px;z-index:3;color:#fff;font:9px var(--font-wide);letter-spacing:.2em;text-transform:uppercase;opacity:.65;display:flex;align-items:center;gap:9px}.pulse{width:7px;height:7px;border-radius:50%;background:#fff;box-shadow:0 0 0 0 rgba(255,255,255,.5);animation:pulse 2s infinite}@keyframes pulse{70%{box-shadow:0 0 0 9px transparent}100%{box-shadow:0 0 0 0 transparent}}
/* intro */
.section{padding:130px 0}.intro{background:var(--paper)}.intro-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:100px;align-items:end}.display{font:500 clamp(45px,5.3vw,78px)/1.02 var(--font-serif);letter-spacing:-.035em;margin:20px 0 30px}.display em{font-style:italic}.lead{font:300 17px/1.75 var(--font-wide);color:#4e4b45;max-width:600px}.rule{height:1px;background:var(--line);margin:42px 0}.facts{display:grid;grid-template-columns:repeat(3,1fr);gap:0}.fact{padding:0 22px;border-left:1px solid var(--line)}.fact:first-child{padding-left:0;border:0}.fact b{font:500 29px var(--font-serif);display:block}.fact span{display:block;margin-top:7px;font:9px var(--font-wide);letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
/* about (merges the old image-feature banner + stats strip into the
   single About section - same visual language, compact inline sizing
   instead of full-bleed 780px/85px-padded standalone sections) */
.about-visual{margin-top:70px;display:flex;flex-direction:column;gap:22px}
.about-image{width:100%;height:460px;object-fit:cover;border-radius:2px}
.about-body{font:300 15px/1.75 var(--font-wide);color:#4e4b45;max-width:720px}
.about-stats{margin-top:56px;padding-top:0}
.about-stats .stat-row{border-bottom:0}
/* residences */
.residences{background:#181815;color:#f6f2e9}.res-head{display:grid;grid-template-columns:1fr 1fr;gap:80px;align-items:end;margin-bottom:70px}.res-head .display{margin-bottom:0}.res-intro{font:300 15px/1.8 var(--font-wide);color:#aaa79f;max-width:440px}
/* FIX: was display:grid;grid-template-columns:repeat(3,1fr) - a fixed
   3-column grid leaves a leftover card (or cards) pinned to the left
   edge of the final row with empty space beside it whenever
   CONFIGURATIONS in config.js isn't a multiple of 3 (4 or 5 cards, the
   normal case - see :has() rule below for what happens with exactly 1).
   flex-wrap + justify-content:center lets any incomplete final row
   center itself automatically, for any card count, with zero per-project
   CSS changes. */
.res-grid{display:flex;flex-wrap:wrap;justify-content:center;border-top:1px solid rgba(255,255,255,.15)}
.res-card{flex:1 1 300px;max-width:380px;padding:30px 24px 34px 0;border-right:1px solid rgba(255,255,255,.12);margin-right:24px;position:relative}
.res-card:last-child{border-right:0;margin-right:0}
/* Config-driven enlarge + center: if CONFIGURATIONS in config.js has only
   one entry, render.js emits a single .res-card with no siblings - give it
   room to read as a deliberate centerpiece instead of a left-pinned
   one-of-three column. Triggered purely by card COUNT, so nothing needs
   configuring per project - reducing to one configuration "just works".
   Scoped to ≥901px so it never fights the ≤900px stacked mobile layout
   (which already goes full-width for any card count). */
@media(min-width:901px){
  .res-grid:has(>.res-card:only-child){gap:0}
  .res-grid:has(>.res-card:only-child) .res-card{flex:0 1 620px;max-width:620px;margin-right:0;border-right:0;padding-right:0}
  .res-grid:has(>.res-card:only-child) .plan{height:320px}
  .res-grid:has(>.res-card:only-child) h3{font-size:58px}
}
.res-card .num{font:11px var(--font-wide);letter-spacing:.2em;color:#8c887e}.res-card h3{font:500 43px var(--font-serif);margin:25px 0 4px}.res-card .size{font:10px var(--font-wide);letter-spacing:.13em;text-transform:uppercase;color:#aaa79f}.plan{margin-top:28px;background:#e9e5dc;height:235px;display:grid;place-items:center;overflow:hidden;position:relative;cursor:pointer}.plan img{width:88%;height:88%;object-fit:contain;filter:contrast(.92) blur(6px);transform:scale(1.04);transition:filter .35s ease, transform .35s ease;pointer-events:none;user-select:none;-webkit-user-drag:none}.res-card:hover .plan img,.plan:focus-visible img{filter:contrast(.96) blur(2.5px);transform:scale(1.01)}.plan:after{content:'';position:absolute;inset:0;background:linear-gradient(0deg,rgba(20,20,17,.18),transparent 45%);pointer-events:none}.lock{position:absolute;bottom:12px;right:12px;background:rgba(20,20,17,.88);color:#fff;padding:8px 11px;font:8px var(--font-wide);letter-spacing:.12em;text-transform:uppercase;display:flex;align-items:center;gap:6px}.lock:before{content:'';width:9px;height:9px;border:1.5px solid rgba(255,255,255,.85);border-bottom:0;border-radius:2px 2px 0 0}.price{font:500 20px var(--font-serif);margin:25px 0 18px}.card-link{font:10px var(--font-wide);letter-spacing:.17em;text-transform:uppercase;color:#d6c294;border-bottom:1px solid rgba(214,194,148,.4);padding-bottom:6px}
/* stat-row grid - used inline by .about-stats above */
/* FIX: was display:grid;grid-template-columns:repeat(5,1fr) with mobile
   nth-child(2..5) border math hardcoding "exactly 5 stats" - breaks (or
   silently drops dividers in the wrong places) for any other count in
   config.js's ABOUT.stats array. flex-wrap adapts to any number of stats. */
.stat-row{display:flex;flex-wrap:wrap;border-top:1px solid rgba(18,18,15,.18);border-bottom:1px solid rgba(18,18,15,.18)}.stat{flex:1 1 140px;padding:29px 18px;border-right:1px solid rgba(18,18,15,.15)}.stat:last-child{border-right:0}.stat b{font:500 37px var(--font-serif);display:block}.stat span{font:9px var(--font-wide);letter-spacing:.12em;text-transform:uppercase;color:#67635a;line-height:1.5;display:block;margin-top:8px}
/* lifestyle (merges the old full-bleed pool banner + the grouped
   amenities section into one two-column section: compact feature
   image + copy on the left, the full amenity list on the right) */
.lifestyle{background:var(--paper)}
/* FIX: was grid-template-columns:.85fr 1.15fr with no align-items override
   (default stretch) and a FIXED-height image. Between ~900–1400px the left
   column's actual width could shrink to ~240px - far too narrow for a
   fixed 340px-tall image (it read as a cropped, oddly "shortened" sliver)
   - while default align-items:stretch forced the whole left column to
   match the taller amenity-list's height, leaving a slab of empty space
   below the lead paragraph ("the text on the left keeps going on"). Fix:
   give the text column a guaranteed minimum width, size the image by
   aspect-ratio instead of a fixed pixel height (so it scales with the
   column instead of cropping tighter as it narrows), and let each column
   size to its own content (align-items:start) instead of stretching to
   match the taller one. */
.lifestyle-layout{display:grid;grid-template-columns:minmax(300px,.9fr) 1.3fr;gap:70px;align-items:start}
.lifestyle-copy .display{margin:18px 0 22px}
/* background:var(--warm) shows as a plain tile instead of a broken-image
   icon for the instant before render.js sets the real src from
   LIFESTYLE.image (see the index.html fix: the hardcoded placeholder src
   that used to live in markup is gone, so there's nothing to 404 on). */
.lifestyle-image{width:100%;aspect-ratio:4/3;height:auto;object-fit:cover;border-radius:2px;margin-bottom:22px;background:var(--warm)}
/* FIX: the right column is 1.3fr specifically so the amenity list never
   feels squeezed next to the (fixed-minimum-width) left text column - but
   that leaves a lot of unused width once the column is wider than the
   amenity rows actually need, with everything pinned to the left edge of
   that wide column (a big empty gap down the right side). Capping the
   list's own width and centering it moves it toward the middle of its
   column instead. max-width:620px is a no-op at mobile/narrow widths
   (the column itself is already narrower than that there), so this only
   visibly shifts things at desktop widths, without a separate breakpoint. */
.amenity-list{border-top:1px solid var(--line);max-width:620px;margin:0 auto}
.amenity{padding:20px 0;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between}.amenity strong{font:600 20px var(--font-serif);display:inline-block;margin-right:22px;vertical-align:baseline}
.amenity small{font:9px var(--font-wide);letter-spacing:.15em;text-transform:uppercase;color:var(--muted);display:inline-block;vertical-align:baseline}
/* FIX: the shared ≤900px breakpoint (further down) already stacks
   .lifestyle-layout to one column, but the 2-column layout has no real
   room to breathe below ~1150px (the minmax(300px,...) column plus the
   amenity list's own natural minimum width don't both fit) - stack a
   little earlier, just for this section, so that squeezed zone never
   renders. */
@media(max-width:1150px){
  .lifestyle-layout{grid-template-columns:1fr;gap:45px}
}
@media(max-width:600px){
  .amenity{align-items:flex-start;gap:16px}
  .amenity strong{display:block;margin:0 0 5px}
  .amenity small{display:block}
}.amenity-arrow{font-size:18px;color:var(--gold)}
/* ============================================================
   LOCATION MAP - ACTUAL PROJECT MAP
   ============================================================ */

.mapbox {
  min-height: 520px;
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,.14);
  background: #11110f;
}

.location-map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  border: 0;
  object-fit: cover;
  object-position: center;
}

.map-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(
      180deg,
      rgba(10,10,8,.05) 0%,
      rgba(10,10,8,.02) 60%,
      rgba(10,10,8,.45) 100%
    );
}

.map-note {
  position: absolute;
  z-index: 2;
  bottom: 18px;
  left: 20px;
  right: 20px;

  font: 8px var(--font-wide);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(255,255,255,.62);

  text-shadow: 0 1px 8px rgba(0,0,0,.8);
}
/* gallery */
.gallery{padding-bottom:150px}.gallery-head{display:flex;justify-content:space-between;align-items:end;margin-bottom:45px}.gallery-head .display{margin-bottom:0}.gallery-grid{display:grid;grid-template-columns:1.2fr .8fr;grid-template-rows:300px 300px;gap:15px}.gallery-grid img{width:100%;height:100%;object-fit:cover;display:block}.g1{grid-row:1/3}.gallery-grid img{transition:transform .7s}.gallery-item{overflow:hidden}.gallery-item:hover img{transform:scale(1.035)}
/* faq (accordion) */
.faq{background:#181815;color:#f6f2e9}
.faq-layout{display:grid;grid-template-columns:.7fr 1.3fr;gap:90px;align-items:start}
.faq-head .display{color:#f6f2e9}
.faq-list{border-top:1px solid rgba(255,255,255,.15)}
.faq-item{border-bottom:1px solid rgba(255,255,255,.15)}
.faq-q{width:100%;display:flex;align-items:center;justify-content:space-between;gap:24px;padding:26px 0;background:none;border:0;text-align:left;font:500 19px var(--font-serif);color:#f6f2e9;cursor:pointer}
.faq-q:hover{color:#e3d3ad}
.faq-icon{position:relative;flex:0 0 20px;width:20px;height:20px}
.faq-icon:before,.faq-icon:after{content:'';position:absolute;top:50%;left:50%;background:var(--gold);transform:translate(-50%,-50%)}
.faq-icon:before{width:14px;height:1.5px}
.faq-icon:after{width:1.5px;height:14px;transition:transform .25s ease}
.faq-q[aria-expanded="true"] .faq-icon:after{transform:translate(-50%,-50%) rotate(90deg) scaleY(0)}
.faq-a{overflow:hidden;transition:grid-template-rows .3s ease;display:grid;grid-template-rows:0fr}
.faq-a.open{grid-template-rows:1fr}
.faq-a > p{min-height:0;overflow:hidden;font:300 15px/1.75 var(--font-wide);color:#aaa79f;max-width:640px;padding:0 0 26px;margin:0}
@media(max-width:900px){
  .faq-layout{grid-template-columns:1fr;gap:36px}
}
/* final */
/* ============================================================
   FOOTER - PROJECT / CONTACT / DISCLAIMER
   ============================================================ */

.footer {
  background: #11110f;
  color: #aaa79f;
  padding: 78px 0 0;
  font-family: var(--font-wide);
}

.footer-main {
  display: grid;
  grid-template-columns: 1.15fr .65fr 1.25fr;
  gap: 100px;
  padding-bottom: 70px;
}

.footer-column {
  min-width: 0;
}

.footer-project-name {
  font: 500 24px var(--font-serif);
  color: #f6f2e9;
  margin-bottom: 8px;
}

.footer-location {
  font: 600 9px var(--font-wide);
  letter-spacing: .16em;
  color: #d0b77e;
  margin-bottom: 25px;
}

.footer-column p {
  max-width: 440px;
  font: 300 11px/1.8 var(--font-wide);
  color: #85827a;
  margin: 0;
}

.footer-heading {
  font: 600 9px var(--font-wide);
  letter-spacing: .22em;
  color: #d0b77e;
  margin-bottom: 20px;
}

.footer-contact {
  display: block;
  color: #f2eee5;
  font: 500 14px var(--font-wide);
  margin-bottom: 13px;
}

.footer-contact:hover {
  color: #d0b77e;
}

.footer-location-line {
  font: 10px var(--font-wide);
  color: #85827a;
  margin-top: 16px;
}

.footer-disclaimer p {
  max-width: 540px;
  margin-bottom: 20px;
}

.footer-disclaimer strong {
  color: #d8d2c6;
  font-weight: 600;
}

.footer-disclaimer a {
  color: #d0b77e;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 24px;
  font: 9px var(--font-wide);
}

.footer-links a {
  color: #aaa79f;
  text-decoration: none;
}

.footer-links a:hover {
  color: #d0b77e;
}

.footer-bottom {
  border-top: 1px solid rgba(255,255,255,.1);
  padding: 25px 0;
}

.footer-bottom .wrap {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 30px;
}

.footer-bottom span {
  font: 9px var(--font-wide);
  color: #68665f;
}

@media (max-width: 900px) {

  .footer {
    padding-top: 55px;
  }

  .footer-main {
    grid-template-columns: 1fr;
    gap: 45px;
    padding-bottom: 50px;
  }

  .footer-column p {
    max-width: 100%;
  }

  .footer-bottom .wrap {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }

  .footer-bottom span {
    line-height: 1.6;
  }
}
/* modal */
.modal{
  position:fixed;
  inset:0;
  background:rgba(7,7,6,.78);
  backdrop-filter:blur(7px);
  -webkit-backdrop-filter:blur(7px);
  z-index:1000;
  display:none;
  align-items:center;
  justify-content:center;
  padding:24px;
}
.modal.open{display:flex;}
.modal-card{
  position:relative;
  width:min(520px,100%);
  max-height:calc(100svh - 48px);
  overflow:auto;
  background:#f3f0e9;
  color:#12120f;
  padding:46px 42px 40px;
  border:1px solid rgba(18,18,15,.12);
  border-radius:4px;
  box-shadow:0 30px 100px rgba(0,0,0,.35);
}
.modal-card .eyebrow{margin-bottom:12px;}
.modal-card h2{font:600 clamp(34px,5vw,44px)/1.03 var(--font-serif);letter-spacing:-.025em;margin:0 38px 10px 0;}
.modal-card p{font:300 13px/1.7 var(--font-wide);color:#66635b;margin:0 0 20px;}
.modal-card .field{border-bottom:1px solid #bcb6aa;padding:13px 0;margin:0;}
.modal-card .field input{display:block;width:100%;height:22px;padding:0;background:transparent;border:0;outline:0;color:#111;font:400 13px var(--font-wide);appearance:none;-webkit-appearance:none;}
.modal-card .field input::placeholder{color:#77736a;opacity:1;}
.modal-card .field:focus-within{border-bottom-color:#8d774d;}
.modal-card .submit{width:100%;margin-top:20px;padding:15px;background:#181815;color:#f6f2e9;border:0;border-radius:2px;font:600 10px var(--font-wide);letter-spacing:.16em;text-transform:uppercase;transition:.2s;}
.modal-card .submit:hover{transform:translateY(-1px);background:#24241f;}
.modal-card .submit:disabled{opacity:.6;cursor:wait;transform:none;}
.modal-close{position:absolute;top:20px;right:22px;width:34px;height:34px;display:grid;place-items:center;background:transparent;color:#171714;font-size:23px;line-height:1;border-radius:50%;}
.modal-close:hover{background:rgba(18,18,15,.06);}
.success{display:none;text-align:center;padding:35px 0;}
.success strong{font:600 34px var(--font-serif);display:block;margin-bottom:10px}
@media(max-width:600px){
  .modal{padding:14px;}
  .modal-card{max-height:calc(100svh - 28px);padding:38px 24px 28px;}
  .modal-card h2{font-size:34px;}
}
/* reveal */
/* CONTENT SAFETY: section content must remain visible even if an observer
   is delayed/blocked. The reveal class is retained for JS compatibility,
   but it no longer hides page content by default. */
.reveal{opacity:1;transform:none;transition:opacity .8s ease,transform .8s ease}
.reveal.visible{opacity:1;transform:none}

/* STRONGER SECTION TITLES - retain the editorial type system while using
   the loaded Playfair Display 600 weight for clearer hierarchy. */
.section .display,
.about .display,
.residences .display,
.lifestyle .display,
.location .display,
.gallery .display,
.faq .display,
.final .display{
  font-weight:600;
}

@media(max-width:900px){.wrap{width:min(100% - 40px,680px)}.nav{padding:0 20px}.nav-links,.nav-cta{display:none}.menu{display:block}.hero{height:auto;min-height:100svh;}.hero-grid{position:relative;flex-direction:column;align-items:stretch;padding:110px 20px 28px;gap:24px;}.hero-content{max-width:none;}.hero h1{font-size:clamp(42px,13vw,72px)}.hero-meta{gap:10px;flex-wrap:wrap}.hero-scroll,.video-label{display:none}.section{padding:90px 0}.intro-grid,.res-head,.location-grid,.final-grid,.lifestyle-layout{grid-template-columns:1fr;gap:45px}
/* FIX (was .about-visual{height:420px}): a fixed height shorter than its own
   children (a 460px image alone already exceeds it) made the image + body
   paragraph overflow the box and visually collide with .about-stats right
   below it - the "numbers overlapping the paragraph" bug. .about-visual is
   already a flex column with no fixed height needed; just size the image
   down to something sane for a narrow screen instead. */
.about-image{height:300px}
.res-grid{flex-direction:column;align-items:stretch}.res-card{flex:1 1 auto;max-width:none;border-right:0;border-bottom:1px solid rgba(255,255,255,.12);margin:0;padding-right:0}
/* FIX (was grid-template-columns:repeat(2,1fr) + nth-child(2..5) border
   rules): that hardcoded "exactly 5 stats, 2 per row" math breaks for any
   other count from config.js's ABOUT.stats array. flex-wrap handles any
   number of stats at any width without per-count CSS. */
.stat{flex:1 1 calc(50% - 1px)}
.gallery-grid{grid-template-columns:1fr;grid-template-rows:300px 220px 220px}.g1{grid-row:auto}.footer .wrap{flex-direction:column;gap:10px}.facts{grid-template-columns:1fr 1fr;row-gap:25px}.fact:nth-child(3){grid-column:1/3}}

/* ============================================================
   PRODUCTION ADDITIONS
   ============================================================ */

/* ── Mobile nav drawer (the concept's ☰ button had no menu) ── */
.mobile-nav{display:none;position:fixed;top:0;right:0;bottom:0;width:min(320px,84vw);z-index:35;background:var(--ink);padding:100px 32px 40px;flex-direction:column;gap:4px;transform:translateX(100%);transition:transform .35s cubic-bezier(.2,.8,.2,1);box-shadow:-24px 0 60px rgba(0,0,0,.35);}
.mobile-nav.open{display:flex;transform:translateX(0);}
.mobile-nav a{color:rgba(255,255,255,.82);font:12px var(--font-wide);letter-spacing:.14em;text-transform:uppercase;padding:16px 0;border-bottom:1px solid rgba(255,255,255,.1);}
.mobile-nav .nav-cta{margin-top:20px;width:100%;text-align:center;color:#fff;}
.menu{position:relative;z-index:40;}
.menu.open{color:#fff;}
.nav-scrim{display:none;position:fixed;inset:0;z-index:32;background:rgba(0,0,0,.5);opacity:0;transition:opacity .3s;}
.nav-scrim.open{display:block;opacity:1;}
@media(min-width:901px){.mobile-nav,.nav-scrim{display:none !important;}}

/* ── Hero form card - the conversion addition on top of the
   original concept (which only opened a modal from CTA buttons).
   Sits as a flex sibling of .hero-content inside .hero-grid (see the
   .hero-grid comment above) - NOT position:absolute (an earlier
   revision made it absolute, which reintroduced the exact
   hero-content/form overlap bug that had already been fixed once).
   No align-self override: it shares .hero-grid's own
   `align-items:flex-end`, so it stays bottom-anchored at the same
   height as the headline rather than floating up near the nav. ── */
.hero-form-card{
  flex:0 0 500px;
  width:500px;
  max-width:100%;
  background:rgba(18,18,15,.76);
  backdrop-filter:blur(18px);
  -webkit-backdrop-filter:blur(18px);
  border:1px solid rgba(255,255,255,.18);
  border-radius:4px;
  padding:46px 42px;
  box-shadow:0 24px 70px rgba(0,0,0,.28);
}
.hero-form-card .eyebrow{color:#e0c98f;margin-bottom:14px;}
.hero-form-card h3{font:500 29px var(--font-serif);color:#fff;margin:0 0 7px;line-height:1.15;}
.hero-form-card .hf-sub{font:14px/1.6 var(--font-wide);color:rgba(255,255,255,.62);margin-bottom:26px;}
.hero-form-card .field{border-bottom:1px solid rgba(255,255,255,.22);padding:16px 0;margin-bottom:4px;}
.hero-form-card .field input{width:100%;background:none;border:0;outline:0;color:#fff;font:16px var(--font-wide);}
.hero-form-card .field input::placeholder{color:rgba(255,255,255,.45);}
.hero-form-card .field.error{border-bottom-color:#d98b6b;}
.hero-form-card .submit{margin-top:24px;width:100%;background:var(--white);color:var(--ink);padding:19px;font:11px var(--font-wide);letter-spacing:.16em;text-transform:uppercase;border-radius:2px;transition:.2s;}
.hero-form-card .submit:hover{background:#fff;transform:translateY(-1px);}
.hero-form-card .submit:disabled{opacity:.6;cursor:not-allowed;transform:none;}
.hero-form-card .fine{font:9px/1.6 var(--font-wide);color:rgba(255,255,255,.4);margin-top:18px;}
.hero-form-card .fine a{color:rgba(255,255,255,.65);text-decoration:underline;}
/* .hero-grid already switches to a stacked column at ≤900px (see the base
   layout's own @media block above) - .hero-form-card just needs to stop
   pinning to a 500px flex-basis once it's a full-width stacked child. */
@media(max-width:900px){
  .hero-form-card{
    width:100%;
    flex-basis:auto;
    max-width:none;
    padding:26px 24px;
  }
}
/* Narrow-desktop/tablet-landscape balance: the full 500px card plus a
   640px-max hero-content can get tight between ~901–1200px. Scale both
   down together rather than letting the headline wrap awkwardly. */
@media(min-width:901px) and (max-width:1200px){
  .hero-form-card{flex:0 0 400px;width:400px;padding:34px 30px;}
  .hero-content{max-width:460px;}
}

/* ── Honeypot (bot deterrence - see lead-engine.js BotGuard) ── */
.honeypot{position:absolute !important;left:-9999px !important;width:1px;height:1px;opacity:0;pointer-events:none;}

/* ── Toast (validation / success feedback) ── */
.toast{position:fixed;bottom:24px;left:50%;transform:translate(-50%,120%);background:var(--ink);color:#fff;padding:14px 22px;border-radius:3px;font:12px var(--font-wide);box-shadow:0 12px 40px rgba(0,0,0,.3);z-index:9999;transition:transform .3s cubic-bezier(.2,.8,.2,1);border-left:3px solid var(--gold);}
.toast.show{transform:translate(-50%,0);}
.toast.error{border-left-color:#d9705a;}

/* ── Mandatory mobile sticky CTA (WhatsApp / Get Price / Call).
   Fixed to viewport bottom, safe-area padded, hidden ≥901px where
   the header nav-cta covers the same job. ── */
.floating-cta{display:none;position:fixed;left:0;right:0;bottom:0;z-index:801;gap:8px;padding:10px 14px calc(10px + env(safe-area-inset-bottom));background:rgba(18,18,15,.94);backdrop-filter:blur(14px);border-top:1px solid rgba(255,255,255,.1);}
.floating-cta a,.floating-cta button{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:48px;padding:12px 6px;border-radius:2px;font:11px var(--font-wide);letter-spacing:.06em;font-weight:600;white-space:nowrap;transition:.2s;}
.floating-cta .fc-wa{background:transparent;border:1px solid rgba(255,255,255,.3);color:#fff;}
.floating-cta .fc-price{background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.3);color:#fff;}
.floating-cta .fc-call{background:var(--white);color:var(--ink);}
@media(max-width:900px){
  .floating-cta{display:flex;}
  body{padding-bottom:calc(66px + env(safe-area-inset-bottom));}
}

/* ── Real form field error state (validation from lead-engine.js) ── */
.field.error input{color:#c8543a;}
.field.error{border-bottom-color:#c8543a !important;}

/* ── Accessibility: focus states + reduced motion ── */
a:focus-visible,button:focus-visible,input:focus-visible{outline:2px solid var(--gold);outline-offset:2px;}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.01ms !important;transition-duration:.01ms !important;}
  .reveal{opacity:1;transform:none;}
}

/* ── Loading/disabled cursor for submit buttons mid-request ── */
.submit:disabled,.hero-form-card .submit:disabled{opacity:.65;cursor:wait;}


/* ============================================================
   RESTORED SECTION LAYOUTS
   These rules restore the original location + final CTA styling
   that was missing after the footer was added.
   ============================================================ */

/* LOCATION */
.location {
  background: #11110f;
  color: #f6f2e9;
}

.location-grid {
  display: grid;
  grid-template-columns: .9fr 1.1fr;
  gap: 90px;
  align-items: stretch;
}

.location-copy {
  font: 300 15px/1.8 var(--font-wide);
  color: #aaa79f;
  max-width: 520px;
  margin: 0 0 34px;
}

.destinations {
  border-top: 1px solid rgba(255,255,255,.14);
  max-width: 560px;
}

.location-cta {
  margin-top: 34px;
  color: #fff;
  border-color: rgba(255,255,255,.55);
}

.destination {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 20px;
  padding: 17px 0;
  border-bottom: 1px solid rgba(255,255,255,.10);
  color: #e8e3d9;
  font: 11px var(--font-wide);
  letter-spacing: .03em;
}

.destination span:last-child {
  color: #d0b77e;
  font-size: 10px;
  letter-spacing: .08em;
}

.location .mapbox {
  min-height: 590px;
  height: 100%;
  border: 1px solid rgba(255,255,255,.12);
  background: #11110f;
}

.location .map-note {
  bottom: 16px;
}

/* FINAL CTA */
.final {
  background: #ded8ca;
  color: var(--ink);
  padding: 120px 0 90px;
}

.final-grid {
  display: grid;
  grid-template-columns: 1fr .78fr;
  gap: 100px;
  align-items: center;
}

.final-copy .display {
  max-width: 720px;
  margin-bottom: 24px;
}

.final-copy > p {
  font: 300 15px/1.8 var(--font-wide);
  color: #555149;
  max-width: 520px;
  margin: 0;
}

.enquire {
  background: #181815;
  color: #f6f2e9;
  padding: 38px 34px;
  border: 1px solid rgba(18,18,15,.12);
  border-radius: 4px;
  box-shadow: 0 24px 70px rgba(18,18,15,.12);
}

.enquire h3 {
  font: 500 26px var(--font-serif);
  margin: 0 0 7px;
}

.enquire > p {
  font: 300 12px/1.6 var(--font-wide);
  color: #aaa79f;
  margin: 0 0 22px;
}

.enquire .field {
  border-bottom: 1px solid rgba(255,255,255,.20);
  padding: 12px 0;
  margin-bottom: 2px;
}

.enquire .field input {
  width: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  color: #fff;
  font: 13px var(--font-wide);
  padding: 0;
}

.enquire .field input::placeholder {
  color: rgba(255,255,255,.45);
}

.enquire .submit {
  width: 100%;
  margin-top: 17px;
  padding: 15px;
  background: var(--white);
  color: var(--ink);
  border-radius: 2px;
  font: 10px var(--font-wide);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
}

.enquire .fine {
  font: 9px/1.65 var(--font-wide);
  color: rgba(255,255,255,.42);
  margin-top: 14px;
}

.enquire .fine a {
  color: rgba(255,255,255,.68);
  text-decoration: underline;
}

/* Keep the map visually rich and prevent it from becoming an empty box. */
.location .location-map {
  object-fit: cover;
  object-position: center;
}

/* Responsive restoration */
@media (max-width: 900px) {
  .location-grid,
  .final-grid {
    grid-template-columns: 1fr;
    gap: 45px;
  }

  .location .mapbox {
    min-height: 420px;
  }

  .final {
    padding: 90px 0 70px;
  }

  .enquire {
    padding: 30px 24px;
  }
}

@media (max-width: 600px) {
  .location .mapbox {
    min-height: 330px;
  }

  .destination {
    padding: 15px 0;
  }

  .final {
    padding: 75px 0 60px;
  }
}


/* ============================================================
   SOBHA ONE WORLD - UI RECTIFICATION PATCH
   ============================================================ */

/* 1. MORE PROMINENT SECTION TITLES */
.section .display,
.about .display,
.residences .display,
.lifestyle .display,
.location .display,
.gallery .display,
.faq .display,
.final .display {
  font-weight: 600 !important;
  letter-spacing: -0.035em;
  text-rendering: optimizeLegibility;
}

.residences .display,
.location .display,
.faq .display,
.residences .display em,
.location .display em,
.faq .display em {
  color: #f6f2e9 !important;
}

@media (min-width: 901px) {
  .about .display,
  .residences .display,
  .lifestyle .display,
  .location .display,
  .gallery .display,
  .faq .display {
    font-size: clamp(52px, 5.6vw, 84px) !important;
  }
}

/* 2. AMENITY TITLE / SUPPORTING TEXT SPACING */
/* FIX: align-items was baseline - fine while every description fit on
   one line, but once long descriptions wrap (see .amenity small below)
   baseline alignment only anchors the first line, so a 2-line
   description could visually drift against its title. flex-start keeps
   the title and the top of a wrapped description level, whether the
   description is 1 line or 2. */
.amenity > div {
  display: flex !important;
  align-items: flex-start !important;
  gap: 22px !important;
  min-width: 0;
  flex: 1 1 auto;
  padding-right: 20px;
}

.amenity strong {
  display: inline-block !important;
  margin: 0 !important;
  white-space: nowrap;
  flex: 0 0 auto;
}

/* FIX: was white-space:nowrap - forced the full amenity description
   ("BADMINTON COURT · SQUASH COURT · INDOOR GAMES - CARROM, TABLE
   TENNIS & MORE") onto one unbreakable line. With a fixed-width row
   and an arrow icon pinned to the right edge, a long description had
   nowhere to go but under/through that arrow - the "text colliding
   with the arrow" bug. Letting it wrap (min-width:0 so flexbox will
   actually shrink it instead of forcing the row wider) keeps every
   description inside the row, however long. */
.amenity small {
  display: inline-block !important;
  margin: 0 !important;
  white-space: normal;
  flex: 1 1 auto;
  min-width: 0;
}

.amenity-arrow {
  flex: 0 0 auto;
  margin-left: auto;
  align-self: flex-start;
}

@media (max-width: 900px) {
  .amenity > div {
    gap: 8px !important;
    flex-wrap: wrap;
  }
  .amenity strong,
  .amenity small {
    white-space: normal;
  }
}

@media (max-width: 600px) {
  .amenity > div {
    display: block !important;
    padding-right: 10px;
  }
  .amenity strong {
    display: block !important;
    margin-bottom: 5px !important;
  }
  .amenity small {
    display: block !important;
  }
}

/* 3. HERO FORM - superseded. The hero form's size, spacing, and
   positioning are now defined once, as a flex sibling of .hero-content
   (see the ".hero-form-card" rule near the top PRODUCTION ADDITIONS
   section). An earlier version of this patch re-applied
   `position: absolute !important` here, which silently overrode that
   fix via cascade order + !important and reintroduced the exact
   hero-content/form overlap bug that fix was written to solve. Do not
   re-add a second `.hero-form-card` position override - edit the one
   definition instead. */

/* 4. MODAL FORM - FORCE THE INTENDED EDITORIAL INPUT STYLE */
.modal {
  z-index: 5000 !important;
}

.modal-card {
  width: min(560px, calc(100vw - 32px)) !important;
  background: #f3f0e9 !important;
  color: #12120f !important;
  padding: 46px 42px 40px !important;
  border-radius: 4px !important;
  overflow: visible !important;
}

.modal-card #modal-title {
  color: #12120f !important;
  font-family: var(--font-serif) !important;
  font-weight: 600 !important;
}

.modal-card > #formState > p {
  color: #66635b !important;
  font-family: var(--font-wide) !important;
}

.modal-card .lead-form {
  display: block !important;
  width: 100% !important;
  margin: 0 !important;
}

.modal-card .field {
  display: block !important;
  width: 100% !important;
  height: 52px !important;
  margin: 0 !important;
  padding: 14px 0 10px !important;
  border: 0 !important;
  border-bottom: 1px solid #bcb6aa !important;
  background: transparent !important;
  box-sizing: border-box !important;
}

.modal-card .field:focus-within {
  border-bottom-color: #8d774d !important;
}

.modal-card .field input,
.modal-card .field input[type="text"],
.modal-card .field input[type="tel"],
.modal-card .field input[type="email"] {
  display: block !important;
  width: 100% !important;
  height: 27px !important;
  min-height: 27px !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  outline: none !important;
  background: transparent !important;
  box-shadow: none !important;
  color: #12120f !important;
  font-family: var(--font-wide) !important;
  font-size: 14px !important;
  font-weight: 400 !important;
  line-height: 27px !important;
  appearance: none !important;
  -webkit-appearance: none !important;
}

.modal-card .field input::placeholder {
  color: #77736a !important;
  opacity: 1 !important;
  font-family: var(--font-wide) !important;
  font-size: 14px !important;
}

.modal-card .submit {
  display: block !important;
  width: 100% !important;
  min-height: 48px !important;
  margin: 22px 0 0 !important;
  padding: 15px 18px !important;
  border: 0 !important;
  border-radius: 2px !important;
  background: #181815 !important;
  color: #f6f2e9 !important;
  font-family: var(--font-wide) !important;
  font-size: 10px !important;
  font-weight: 600 !important;
  letter-spacing: .16em !important;
  line-height: 18px !important;
  text-transform: uppercase !important;
  box-shadow: none !important;
}

.modal-card .submit:hover {
  background: #24241f !important;
  transform: translateY(-1px);
}

.modal-card .honeypot,
.honeypot {
  position: absolute !important;
  left: -99999px !important;
  width: 1px !important;
  height: 1px !important;
  opacity: 0 !important;
  pointer-events: none !important;
}

@media (max-width: 600px) {
  .modal {
    padding: 14px !important;
  }
  .modal-card {
    width: 100% !important;
    max-height: calc(100svh - 28px) !important;
    overflow-y: auto !important;
    padding: 38px 24px 28px !important;
  }
  .modal-card #modal-title {
    font-size: 34px !important;
  }
}