/* ════════════════════════════════════════════════════════════════
   ng-system.css   —   the consistency layer
   Load LAST, after every other stylesheet.

   ── WHAT THIS FIXES, MEASURED ─────────────────────────────────
   Across the 16 public stylesheets:
       77 distinct px spacing values   (a system uses 6–8)
       72 distinct font sizes          (a system uses 8–10)
        4 different .container widths  (1200 / 992 / 770 / 1560)
       12 different section conventions

   That is what "margins and paddings not properly done" actually
   measures as. It is not one bad page — it is sixteen stylesheets
   written at different times with no shared scale.

   ── WHY A LAYER RATHER THAN A REWRITE ─────────────────────────
   Rewriting sixteen stylesheets would break a working site in ways
   that only show up on the one page nobody tested. This normalises
   the STRUCTURE — containers, section rhythm, heading scale, body
   measure — and leaves components alone. Structure is where the
   inconsistency is visible; components are where the risk is.
   ════════════════════════════════════════════════════════════════ */

:root {
  /* ── ONE SPACING SCALE ──────────────────────────────────────
     A 1.5× ratio. Every gap on the site should be one of these
     eight, not one of seventy-seven. */
  --ng-1: 0.5rem;    /*  8px  tight — inside a chip, icon gaps      */
  --ng-2: 0.75rem;   /* 12px  small — between related lines         */
  --ng-3: 1.125rem;  /* 18px  base  — inside a card                 */
  --ng-4: 1.75rem;   /* 28px  card padding, gaps between cards      */
  --ng-5: 2.75rem;   /* 44px  between blocks within a section       */
  --ng-6: 4.5rem;    /* 72px  between sections                      */
  --ng-7: 7rem;      /* 112px hero, major breaks                    */

  /* ── ONE TYPE SCALE ─────────────────────────────────────────
     Fluid, so nothing needs a breakpoint to stay readable. The
     ratio is deliberately tighter at the small end — 13px and
     14px doing different jobs is how you end up with 72 sizes. */
  --ng-xs:  0.78rem;                        /* 12.5px  meta, captions   */
  --ng-sm:  0.875rem;                       /* 14px    secondary        */
  --ng-md:  1rem;                           /* 16px    body             */
  --ng-lg:  clamp(1.06rem, 1.4vw, 1.15rem); /*         lead paragraph   */
  --ng-h4:  clamp(1.05rem, 1.7vw, 1.2rem);
  --ng-h3:  clamp(1.2rem,  2.2vw, 1.45rem);
  --ng-h2:  clamp(1.5rem,  3.2vw, 2.05rem);
  --ng-h1:  clamp(1.9rem,  4.6vw, 2.9rem);

  /* ── LINE HEIGHTS ───────────────────────────────────────────
     Headings tighten as they grow; body stays open. */
  --ng-lh-tight: 1.14;
  --ng-lh-head:  1.24;
  --ng-lh-body:  1.68;

  /* ── MEASURE ────────────────────────────────────────────────
     65–75 characters is where reading speed peaks. Prose running
     the full width of a 1400px monitor is the most common
     readability fault on the site. */
  --ng-measure: 68ch;

  /* ── ONE CONTAINER WIDTH ───────────────────────────────────
     Four different widths meant sections visibly stepped in and
     out as you scrolled. */
  --ng-shell: min(1200px, 100% - 2.5rem);

  /* ── CORRECTED COLOURS ─────────────────────────────────────
     Measured against white. The old greys failed WCAG at
     2.24–3.90:1; body text needs 4.5:1. */
  --ng-ink:    #16130D;   /* 18.53:1  AAA */
  --ng-body:   #3D372E;   /* 11.24:1  AAA */
  --ng-soft:   #5A5348;   /*  7.59:1  AAA */
  --ng-mute:   #6E675A;   /*  5.60:1  AA  — was #918A7C at 3.43 */
  --ng-line:   #EFE8DB;
  --ng-line-2: #F5F0E6;

  /* Orange is 2.31:1 — a background colour, never small text.
     This is the variant that passes when orange must carry text. */
  --ng-accent:    #FF8C42;
  --ng-accent-tx: #B3540F;   /*  5.01:1  AA  */
  --ng-accent-bg: #FFF3E9;
  --ng-blue:      #1B5BA8;   /*  6.76:1  AA  */
}

/* Containers are handled in the typography block below, where the
   selector can be made specific enough to beat `.sx .container`. */
.ng-shell { width: var(--ng-shell); max-width: var(--ng-shell); margin-inline: auto; }

/* ══════════════════════════════════════════════════════════════
   SECTION RHYTHM
   Twelve conventions collapse to one. Sections were running from
   40px to 120px of vertical padding with no pattern, which is why
   the page reads as assembled rather than designed.
   ══════════════════════════════════════════════════════════════ */
section,
.section, .sx-sec, .jb-sec, .rf-sec, .lg-page,
.section-hoods, .section-faq, .section-voices, .svc-teaser {
  padding-block: clamp(2.75rem, 6vw, var(--ng-6));
}

/* A tinted band needs no extra space around it — the colour change
   already does the separating. */
.sx-soft, .section.alt, .band, [class*="-band"] {
  padding-block: clamp(2.5rem, 5vw, 4rem);
}

/* Consecutive sections of the same tone would otherwise double
   their padding at the seam. */
section + section { padding-top: clamp(2rem, 4.5vw, 3.5rem); }

/* ══════════════════════════════════════════════════════════════
   TYPOGRAPHY

   ── WHY THESE SELECTORS LOOK ODD ──────────────────────────────
   A plain `h2 { font-size }` here loses. Every page defines its own
   `.sx-h2`, `.ln-h2`, `.jb-h2`, `.bl-h1` at specificity (0,1,0),
   and a bare element selector is (0,0,1) — load order does not save
   it. Measured: 99 rules across the old stylesheets beat a plain
   element selector.

   So the heading rules below use attribute selectors. `[class*="-h2"]`
   is also (0,1,0), which TIES with `.sx-h2` — and a later stylesheet
   wins ties. Descendant rules use `[class*="-card"] p`, which is
   (0,1,1) and ties with `.sx-card p` the same way.

   That is the whole trick, and it only works because the naming
   convention is consistent across all sixteen stylesheets.
   ══════════════════════════════════════════════════════════════ */

h1, .h1 { font-size: var(--ng-h1); line-height: var(--ng-lh-tight);
          letter-spacing: -0.022em; text-wrap: balance; }
/* h1 inside a page wrapper — .cm-head h1, .fv-head h1, .rf-hero h1. */
[class*="-head"] h1, [class*="-hero"] h1, [class*="-copy"] h1,
[class*="-wrap"] h1, [class*="-card"] h1 {
  font-size: var(--ng-h1); line-height: var(--ng-lh-tight); letter-spacing: -0.022em;
}
h2, .h2 { font-size: var(--ng-h2); line-height: var(--ng-lh-head);
          letter-spacing: -0.018em; text-wrap: balance; }
h3, .h3 { font-size: var(--ng-h3); line-height: var(--ng-lh-head);
          letter-spacing: -0.012em; }
h4, .h4 { font-size: var(--ng-h4); line-height: 1.32; }

/* The per-page heading classes — .sx-h1, .bl-h1, .bp-h1 and so on.
   Ties on specificity, wins on order. */
[class*="-h1"] { font-size: var(--ng-h1); line-height: var(--ng-lh-tight);
                 letter-spacing: -0.022em; }
[class*="-h2"] { font-size: var(--ng-h2); line-height: var(--ng-lh-head);
                 letter-spacing: -0.018em; }
[class*="-h3"] { font-size: var(--ng-h3); line-height: var(--ng-lh-head); }
[class*="-h4"] { font-size: var(--ng-h4); line-height: 1.32; }

/* Headings nested inside the page's own wrappers — .sx-card h3,
   .ln-step h3, .ab-feature h3. (0,1,1), same tie-break. */
[class*="-card"] h2, [class*="-item"] h2, [class*="-hero"] h2,
[class*="-head"] h2, [class*="-cta"] h2, [class*="-body"] h2,
[class*="-wrap"] h2, [class*="-sec"] h2, [class*="-empty"] h2,
[class*="-intro"] h2, [class*="-copy"] h2 {
  font-size: var(--ng-h2); line-height: var(--ng-lh-head);
}
[class*="-card"] h3, [class*="-item"] h3, [class*="-step"] h3,
[class*="-body"] h3, [class*="-cta"] h3, [class*="-feature"] h3,
[class*="-panel"] h3, [class*="-block"] h3, [class*="-method"] h3,
[class*="-ben"] h3, [class*="-role"] h3, [class*="-callback"] h3 {
  font-size: var(--ng-h3); line-height: var(--ng-lh-head);
}
[class*="-card"] h4, [class*="-item"] h4 {
  font-size: var(--ng-h4); line-height: 1.32;
}

/* Headings own their space above, not below. Setting both creates
   collapsing-margin arguments that differ per browser. */
h1, h2, h3, h4,
[class*="-h1"], [class*="-h2"], [class*="-h3"] { margin-block: 0 var(--ng-3); }
* + h2 { margin-top: var(--ng-5); }
* + h3 { margin-top: var(--ng-4); }

/* ── Body copy ───────────────────────────────────────────────
   Same problem: `.sx-card p`, `.ln-step p`, `.jb-role p` all beat a
   plain `p`. One line-height everywhere, or paragraphs breathe
   differently on every page — which is exactly what reads as
   "the spacing is off" without being able to point at it. */
p { line-height: var(--ng-lh-body); margin-block: 0 var(--ng-3); }
[class*="-card"] p, [class*="-item"] p, [class*="-step"] p,
[class*="-hero"] p, [class*="-body"] p, [class*="-cta"] p,
[class*="-role"] p, [class*="-feature"] p, [class*="-text"] p,
[class*="-intro"] p, [class*="-panel"] p, [class*="-block"] p,
[class*="-voice"] p, [class*="-empty"] p, [class*="-wrap"] p,
[class*="-method"] p, [class*="-ben"] p, [class*="-callback"] p,
[class*="-testi"] p, [class*="-done"] p, .empty p {
  line-height: var(--ng-lh-body);
}
p:last-child { margin-bottom: 0; }

/* Prose gets a measure. Cards, navs and grids do not — those are
   layout, and a measure would fight the grid. */
section > .container > p,
.prose p, .lead, .section-sub, .sec-sub {
  max-width: var(--ng-measure);
}
.lead, .section-sub, .sec-sub {
  font-size: var(--ng-lg);
  color: var(--ng-soft);
}

/* ── Container ────────────────────────────────────────────────
   `.sx .container` is (0,2,0) and beats a plain `.container`. This
   matches it, so services stops being 60px narrower than every
   other page. */
[class] .container, .container {
  width: var(--ng-shell);
  max-width: var(--ng-shell);
  margin-inline: auto;
}

/* Numbers should line up between rows. Proportional digits make a
   column of prices look ragged. */
.price, [class*="-price"], [class*="-stat"] b, .kpi b, .stats-row b,
[class*="-rate"] b, [class*="-total"] b {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.012em;
}

/* ══════════════════════════════════════════════════════════════
   ALIGNMENT

   Measured: 38 flex rows across the stylesheets set `display:flex`
   with no `align-items`. The default is `stretch`, so a short label
   next to a tall button stretches to match it, and an icon floats
   above the text it belongs to. That is most of what reads as
   "the alignment is off" without being nameable.

   `align-items:center` is right for a row of mixed-height items
   nine times out of ten. Columns and explicitly-aligned rows opt
   out below.
   ══════════════════════════════════════════════════════════════ */
[class*="-row"], [class*="-actions"], [class*="-acts"],
[class*="-meta"], [class*="-foot"], [class*="-tools"],
[class*="-chips"], [class*="-tags"] {
  align-items: center;
}

/* An icon beside text should sit on the text, not above it. */
[class*="-icon"] + *, [class*="-ic"] + * { align-self: center; }

/* Columns must not inherit the centring above. */
[style*="flex-direction:column"], [style*="flex-direction: column"],
[class*="-col"], [class*="-stack"] { align-items: stretch; }

/* ── Gaps ─────────────────────────────────────────────────────
   35 distinct gap values were in use. Snapped to the scale, so a
   card grid and a chip row no longer breathe differently for no
   reason. */
[class*="-grid"]  { gap: var(--ng-4); }
[class*="-chips"], [class*="-tags"], [class*="-pills"] { gap: var(--ng-1); }
[class*="-row"]   { gap: var(--ng-2); }
[class*="-acts"], [class*="-actions"] { gap: var(--ng-1); }

/* A grid whose children can shrink below their content width is
   what causes the horizontal scrollbar nobody can find the source
   of. */
[class*="-grid"] > *, [class*="grid"] > * { min-width: 0; }

/* ══════════════════════════════════════════════════════════════
   ACCESSIBILITY
   ══════════════════════════════════════════════════════════════ */

/* Tap targets. Anything below 44px fails on a phone, and 99% of
   this traffic is on one. */
a.btn, button, .btn, [role="button"], input[type="submit"] {
  min-height: 44px;
}
/* Small variants opt out explicitly — a chip is not a primary action. */
.btn.sm, .btn-sm, .chip, .pill { min-height: 32px; }

/* Every interactive element needs a visible focus ring. Several
   places had outline:none with nothing replacing it, which makes
   the site unusable by keyboard. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--ng-accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Never underline every child of a card link. It reads as a
   rendering fault, not a hover state. */
a:hover > *, a:focus > * { text-decoration: none; }

/* Small text in brand orange fails contrast at 2.31:1. */
.txt-accent, .accent-sm { color: var(--ng-accent-tx); }
.chip-accent {
  background: var(--ng-accent-bg);
  color: var(--ng-accent-tx);
  border: 1px solid #F5D9C2;
}

/* White on WhatsApp green is 1.98:1 — one of the worst pairings
   possible. Dark ink on green is 7.33:1. */
[class*="whatsapp" i], .btn-wa, .fab-whatsapp { color: #06301A; }

/* Long unbroken strings — a URL, an account number, a RERA code —
   push the page sideways on a phone. */
body { overflow-wrap: break-word; }

/* ══════════════════════════════════════════════════════════════
   IMAGES
   ══════════════════════════════════════════════════════════════ */
img, video, iframe, embed { max-width: 100%; height: auto; }
/* An image with width/height attributes reserves its space, which
   is what stops the layout jumping as it loads. */
img[width][height] { height: auto; }

/* ══════════════════════════════════════════════════════════════
   MOBILE
   Everything above is fluid, so this is only where the desktop
   assumption genuinely breaks.
   ══════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  :root { --ng-shell: min(1200px, 100% - 2rem); }

  section, .section, .sx-sec, .jb-sec, .rf-sec {
    padding-block: clamp(2rem, 8vw, 2.75rem);
  }
  /* A two-column grid on a 360px screen gives each column ~165px.
     Nothing meaningful fits. */
  .grid2, .grid-2, [class*="grid-2"] { grid-template-columns: 1fr; }

  /* Buttons side by side end up 140px wide with the label wrapping. */
  .btn-row, .cta-row, .hero-cta { flex-direction: column; }
  .btn-row > *, .cta-row > *, .hero-cta > * { width: 100%; }
}

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

/* ══════════════════════════════════════════════════════════════
   PRINT
   Buyers print property pages to take to a site visit or show a
   spouse. Currently that prints the nav, the footer and a floating
   WhatsApp button across the page.
   ══════════════════════════════════════════════════════════════ */
@media print {
  header, footer, nav, .fab-whatsapp, .pdp-bar,
  .pdp-share, .ec-form, .ngc, .skip-link { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .container { width: 100%; max-width: none; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
  img { max-width: 45% !important; page-break-inside: avoid; }
}

/* ══════════════════════════════════════════════════════════════
   SERVICES DROPDOWN
   Opens on hover for a mouse and on focus for a keyboard, so it is
   reachable both ways. The invisible bridge above the panel stops
   it closing when the pointer crosses the gap between the link and
   the menu - the single most annoying bug in any dropdown.
   ══════════════════════════════════════════════════════════════ */
/* The wrapper div breaks any `.fh-nav > a` direct-child rule, so the
   trigger has to carry its own appearance rather than inherit one.
   `inherit` picks up whatever .fh-nav sets, so this matches the other
   links without needing to know what they look like. */
.fh-drop { position: relative; display: inline-flex; align-items: center; }
.fh-drop > a {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: inherit;
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
  padding: inherit;
  line-height: inherit;
  letter-spacing: inherit;
}
/* Match the sibling links exactly, whatever they are. */
.fh-nav > a, .fh-drop > a { font-size: inherit; font-weight: inherit; }
.fh-caret { opacity: .55; transition: transform .18s ease; flex: none; }
.fh-drop:hover .fh-caret,
.fh-drop:focus-within .fh-caret { transform: rotate(180deg); opacity: 1; }

.fh-drop-menu {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translate(-50%, 6px);
  min-width: 208px;
  padding: 7px;
  background: #fff;
  border: 1px solid var(--ng-line, #EFE8DB);
  border-radius: 14px;
  box-shadow: 0 20px 44px -22px rgba(22, 19, 13, .4);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .16s ease, transform .16s ease, visibility .16s;
  z-index: 200;
}
/* The bridge. Without it the menu closes as the pointer crosses the
   gap, and the whole thing feels broken. */
.fh-drop-menu::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: -12px;
  height: 12px;
}
.fh-drop:hover .fh-drop-menu,
.fh-drop:focus-within .fh-drop-menu {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translate(-50%, 2px);
}
.fh-drop-menu a {
  display: block;
  padding: 9px 13px;
  border-radius: 9px;
  font: 500 .87rem/1.3 'Poppins', system-ui, sans-serif;
  color: var(--ng-body, #3D372E);
  text-decoration: none;
  white-space: nowrap;
}
.fh-drop-menu a:hover,
.fh-drop-menu a:focus-visible {
  background: var(--ng-accent-bg, #FFF3E9);
  color: var(--ng-accent-tx, #B3540F);
}

/* On a phone the header nav is a stacked drawer, so a floating panel
   makes no sense - the children just become part of the list. */
@media (max-width: 900px) {
  .fh-drop { display: block; width: 100%; }
  .fh-drop-menu {
    position: static;
    transform: none;
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    box-shadow: none;
    border: 0;
    border-left: 2px solid var(--ng-line, #EFE8DB);
    border-radius: 0;
    margin: 2px 0 6px 12px;
    padding: 0 0 0 10px;
    min-width: 0;
  }
  .fh-drop-menu::before { display: none; }
  .fh-caret { display: none; }
}