/* ============================================================
   ÉVORA DEVELOPMENTS — SHARED DESIGN SYSTEM
   ============================================================
   Brand: Inspired by Heritage. Built for the Future.
   Colors: #173F35 / #4E5B31 / #90906F / #B15533 / #F5F1EB
   Fonts:  Beautique Display (headlines) / Attack (body)
           Almarai (AR body) / Athelas ARA (AR headlines)
   Signature shape: ARCH (rounded top, flat bottom)
   ============================================================ */

/* ---------------- Fonts ---------------- */

/* Beautique Display — English HEADLINES (and, via the 'Beautique Latin' alias
   further down, the Latin runs inside Arabic headlines).
   ?v=20260813a: the vendor OTF ships THREE disagreeing vertical metrics with the
   flag that picks the wrong one turned on —
       hhea.ascent      1000   <- what Blink on macOS/iOS reads
       OS/2 sTypoAsc     800   <- what Blink on Windows/Android reads, because
                                  fsSelection bit 7 (USE_TYPO_METRICS) is set
       OS/2 usWinAsc    1000
   Real ink of 'É' reaches 976. So on Windows/Android every cap and accent sat
   0.176em OUTSIDE its own content box — sliced flat by any overflow:hidden
   ancestor ("Évora Éd" rendered as "Evora Ed") — and the baseline sat 0.10em
   high in every fixed-line-height heading, while line-height:normal came out
   1.20em instead of 1.40em. iOS was unaffected, which is why this only ever got
   reported on Windows/Android.
   The woff2s are re-saved from the brand-kit OTFs with sTypoAscender raised
   800 -> 1000 so hhea == typo == usWin and NO platform can diverge.
   Deliberately unchanged so macOS/iOS rendering is byte-identical to before:
   descender -200, lineGap 200, usWin 1000/200, all outlines and advance widths.
   If these are ever regenerated from the OTF, re-apply the fix or the bug returns:
     from fontTools.ttLib import TTFont
     f = TTFont('BeautiqueDisplay-Regular.otf')
     f['OS/2'].sTypoAscender = 1000        # was 800; match hhea.ascent
     f.flavor = 'woff2'; f.save('BeautiqueDisplay-Regular.woff2')
   (-Medium additionally had the BOLD bit set in fsSelection; corrected to 192.) */
@font-face { font-family: 'Beautique Display'; src: url('fonts/BeautiqueDisplay-Light.woff2?v=20260817b')   format('woff2'); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: 'Beautique Display'; src: url('fonts/BeautiqueDisplay-Regular.woff2?v=20260817b') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Beautique Display'; src: url('fonts/BeautiqueDisplay-Medium.woff2?v=20260817b')  format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Beautique Display'; src: url('fonts/BeautiqueDisplay-Bold.woff2?v=20260817b')    format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }
/* Attack — English BODY (and, via the 'Attack Latin' alias further down, the Latin
   runs inside Arabic body copy).
   ?v=20260817f: lowercase 's' sat one pixel BELOW the baseline on Windows only,
   sitewide, at every size, while every other glyph was correct. Not a subset gap
   and not a bad outline — 's' is present in all three cmap subtables and its
   outline is byte-identical to the vendor OTF. The cause was the CFF alignment
   zones in the Private dict, which the vendor shipped broken and differently
   broken per weight:
       weight     BlueValues (shipped)          second zone corresponds to
       Light      [-8,0, 543,549, 541,548]      nothing; OVERLAPS the next zone
                                                (invalid per the CFF spec)
       Regular    [-8,0, 464,470, 541,548]      nothing (real x-height ~547)
       Medium     [-8,0, 385,391, 541,548]      nothing
       Bold       [-8,0, 228,234, 541,548]      nothing
   These faces ship entirely UNHINTED (zero stem hints in any charstring), so the
   rasterizer autohints from the blue zones alone. Windows/DirectWrite uses the
   Adobe CFF engine, which honours them; macOS/CoreText renders the unhinted
   outline and ignores them — hence Windows-only. The baseline zone was -8..0
   (+BlueFuzz 1 = -9..1), and 's' has the deepest x-height overshoot in the
   family: yMin -9 in Light/Medium/Bold, i.e. exactly ON the zone edge, while
   every sibling round letter (a -6, c -7, e -7, o -7) sits comfortably inside.
   So Windows aligned every other lowercase to the baseline and left 's' to round
   independently, one pixel low. Size-independent because zone membership is.
   Repaired to [-11, 0, 540, 551] in all four weights: baseline zone widened to
   cover 's' (and 'u' at -10 in Bold), and the bogus/overlapping second and third
   zones replaced by ONE accurate x-height zone spanning the real range (flat
   n/m/r 546-551, round o/c/e/a/s 546-550, short u/v/w/x/z 540-541).
   Deliberately NOT added: a cap-height zone. The shipped 541..548 zone was never
   one (caps are at 700-710), so caps get no zone alignment today; adding one
   would be a new Windows behaviour change beyond this fix.
   Metadata-only edit. Outlines, advance widths, Subrs, OtherBlues, StdHW/StdVW,
   StemSnap*, hhea/sTypo/usWin metrics and the name table are all unchanged and
   verified byte-identical, so macOS rendering and all layout are untouched.
   Still just outside the zone and liable to the same bug if it ever shows:
   'five' (-14 Medium, -18 Bold), 'nine' (-13 Light), 'J' (-13 Light/Regular).
   comma/semicolon/quotedblbase (-43..-52) and at/copyright/registered (-26..-37)
   are intentional descenders, correctly excluded.
   If these are ever regenerated from the OTF, re-apply the fix or the bug returns:
     from fontTools.ttLib import TTFont
     f = TTFont('ATTACK-Regular.otf')
     f['CFF '].cff[f['CFF '].cff.fontNames[0]].Private.BlueValues = [-11, 0, 540, 551]
     f.flavor = 'woff2'; f.save('ATTACK-Regular.woff2') */
@font-face { font-family: 'Attack'; src: url('fonts/ATTACK-Light.woff2?v=20260817f')    format('woff2'); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: 'Attack'; src: url('fonts/ATTACK-Regular.woff2?v=20260817f')  format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Attack'; src: url('fonts/ATTACK-Medium.woff2?v=20260817f')   format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Attack'; src: url('fonts/ATTACK-Bold.woff2?v=20260817f')     format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }

/* Inter — English TEXT (body copy, links, form fields, legal pages) and, via the
   'Inter Latin' alias further down, the Latin runs inside Arabic body copy.

   WHY THIS FACE EXISTS. Attack renders lowercase 's' below the baseline on
   Windows, sitewide, at every size. ?v=20260817f attempted a CFF blue-zone
   repair (commit 2f7d33a); it deployed clean, was verified byte-for-byte in
   production, and did NOT fix the symptom on Windows. The blue-zone hypothesis
   is disproven and Attack is not being patched further. The real problem is that
   Attack ships fully UNHINTED: it carries no fpgm/prep/cvt/gasp at all, so at
   text sizes it is at the mercy of DirectWrite's grid-fitting. No amount of
   metadata fixes that. Attack stays on DISPLAY (all-caps labels, eyebrows, nav,
   buttons), where the sizes are large enough that hinting does not decide the
   outcome; everything small and sentence-case moved here.

   Inter 4.1, subset from the vendor TTFs, retaining fpgm + prep + cvt + gasp —
   the hinting is the entire point of the swap, so if these are ever re-subset,
   do NOT pass --no-hinting.
   Subset range: Basic Latin, Latin-1 Supplement, Latin Extended-A, General
   Punctuation, + EUR/TM. U+00C9 (É) is inside Latin-1 Supplement and is required
   by "Évora" — verify it survives any re-subset. No italic face is shipped:
   the one italic TEXT element (about.html's heritage note) synthesised its
   oblique under Attack too, so that is unchanged, not a regression.
   Weights: 400 for body copy, 700 for the <strong> runs in the legal pages. 500
   and 600 are deliberately NOT shipped — no TEXT selector resolves to either, so
   they would have been dead files. Add the matching weight before styling any
   text at 500/600, or the browser will synthesise it. */

@font-face { font-family: 'Inter'; src: url('fonts/Inter-Regular.woff2?v=20260817g') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('fonts/Inter-Bold.woff2?v=20260817g')    format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }

/* Athelas Arabic — NO LONGER APPLIED. Was the Arabic headline face per brand
   guidelines; replaced by 'Almarai Display' below because Athelas's final reh is
   too thin to survive Windows/DirectWrite hinting (see the note on that alias for
   the measured ink figures). These four faces are left declared but unreferenced,
   so nothing fetches them — restoring the brand face is a one-line change: put
   'Athelas Arabic' back ahead of 'Almarai Display' in the RTL display stack.
   The metric history below still applies to the files themselves.
   ?v=m430: the shipped files' hhea/typo descent (-259/1000em) was shallower than
   the real glyph ink (ع/ج/م tails reach -370, deepest form -679), so renderers
   that clip text to the font's metric box cut descenders off. The woff2s are
   re-saved with descent raised to -430 (covers all letters used in the AR copy);
   ascent 741 + descent 430 = 1171 stays inside the 1.4 line-height floor forced
   on AR headings, so line boxes—and therefore layout—are unchanged.

   ?v=utm4: final-reh fix. Windows/Chrome (DirectWrite) takes its line-layout
   ascent/descent from OS/2 usWinAscent/usWinDescent unless fsSelection bit 7
   (USE_TYPO_METRICS) is set — and that bit is only honoured on OS/2 version 4+,
   while these files shipped as version 3. So macOS/iOS read hhea (741/-430)
   while Windows read usWin (1388/430): the baseline sat 0.65em lower in the line
   box, leaving only 0.02em under it at the 1.4 line-height forced on AR headings.
   Every letter with a below-baseline tail lost it, and final reh (ر, ink to
   -203) — whose whole body sits at the baseline — vanished outright, so "أكثر"
   read as "أكث". Fixed by bumping OS/2 to v4 and setting USE_TYPO_METRICS, so
   Windows uses the same 741/-430 as hhea; usWin* is widened to the true ink
   bounds since it now only clips the raster. hhea/sTypo* are untouched, so
   macOS/iOS rendering and all layout are bit-identical to before. */
@font-face { font-family: 'Athelas Arabic'; src: url('fonts/AthelasArabic-Book.woff2?v=20260817b')     format('woff2'); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: 'Athelas Arabic'; src: url('fonts/AthelasArabic-Regular.woff2?v=20260817b')  format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Athelas Arabic'; src: url('fonts/AthelasArabic-SemiBold.woff2?v=20260817b') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'Athelas Arabic'; src: url('fonts/AthelasArabic-Bold.woff2?v=20260817b')     format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }

/* Almarai — Arabic BODY (self-hosted woff2, converted from brand-kit TTF).
   Maps to the Attack body role when dir=rtl.
   ?v=utm4: same OS/2 v3 → v4 + USE_TYPO_METRICS fix as Athelas above. These
   already carried the bit but shipped as version 3, so Windows ignored it and
   used usWin (1108/453) against hhea's 905/-211 — the same baseline drop, and
   Almarai-Bold was additionally missing the bit entirely. */
@font-face { font-family: 'Almarai'; src: url('fonts/Almarai-Light.woff2?v=20260817b')     format('woff2'); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: 'Almarai'; src: url('fonts/Almarai-Regular.woff2?v=20260817b')   format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Almarai'; src: url('fonts/Almarai-Bold.woff2?v=20260817b')      format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: 'Almarai'; src: url('fonts/Almarai-ExtraBold.woff2?v=20260817b') format('woff2'); font-weight: 800; font-style: normal; font-display: swap; }

/* Almarai Display — the Arabic DISPLAY face, replacing Athelas Arabic in headings.
   Athelas's final reh renders thin enough that Windows/DirectWrite hinting can
   reduce it to near-nothing, so "أكثر" reads as "أكث". Measured reh ink mass
   inside the word, rasterised at the sizes AR display copy actually uses:

       px    Athelas 400   Almarai 400   Almarai 700   Almarai 800
       12        11            12            18            20
       14        14            18            24            28
       16        20            24            33            39
       20        31            37            49            60

   Almarai at REGULAR is only 9–29% heavier — not enough on its own. The real
   margin is weight: Almarai 700 carries 64–71% more reh ink than Athelas 400,
   and 800 carries 82–95% more. A stroke with that much mass cannot hint away.

   Hence this alias rather than simply swapping the family: it remaps the display
   role's weights UP (400 -> Bold file, 700 -> ExtraBold file) so Arabic renders
   heavy while the element's own font-weight stays 400 — which matters because
   'Beautique Latin' sits ahead of it in the same stack and must keep rendering
   Latin runs ("Pulse Medical Hub", "Évora") at their original Regular weight.
   Setting font-weight:700 on the rule instead would have bolded the Latin too. */
@font-face { font-family: 'Almarai Display'; src: url('fonts/Almarai-Bold.woff2?v=20260817b')      format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Almarai Display'; src: url('fonts/Almarai-ExtraBold.woff2?v=20260817b') format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }

/* ---------------- Base ---------------- */
:root {
  --evora-dark:   #173F35;
  --evora-forest: #4E5B31;
  --evora-olive:  #90906F;
  --evora-terra:  #B15533;
  --evora-cream:  #F5F1EB;
  --ink:          #0a0a0a;
}
html, body { background: var(--ink); color: var(--evora-cream); font-family: 'Inter', system-ui, sans-serif; -webkit-font-smoothing: antialiased; overflow-x: hidden; }
.font-display { font-family: 'Beautique Display', Georgia, serif; }

/* Hide the scrollbar on mobile only (≤767px) — scrolling still works, the bar is
   just not painted. Desktop (≥768px) keeps its normal scrollbar untouched.
   Diagnosis: the page scroller is the root <html> element (document.scrollingElement) —
   there is NO inner full-page scroll wrapper — so the rule targets html explicitly.
   scrollbar-width:none hides it on Firefox + modern Blink; the ::-webkit-scrollbar
   pseudo (targeted on html/body, not just a bare *) hides classic WebKit/Blink bars.
   !important guards against the Tailwind Play CDN base layer injected after this file.
   Note: on macOS *overlay* scrollbars this is a no-op (they're already invisible and
   unstyleable); it matters on platforms that render CLASSIC bars (Win/Linux/Android). */
@media (max-width: 767px) {
  html, body { scrollbar-width: none !important; -ms-overflow-style: none !important; }  /* Firefox / legacy Edge */
  html::-webkit-scrollbar,
  body::-webkit-scrollbar,
  *::-webkit-scrollbar { display: none !important; width: 0 !important; height: 0 !important; }  /* WebKit / Blink classic bars */
}

/* ---------------- Custom cursor ---------------- */
@media (hover: hover) and (pointer: fine) {
  * { cursor: none !important; }
  .cursor-dot, .cursor-ring { position: fixed; top: 0; left: 0; pointer-events: none; z-index: 9999; mix-blend-mode: difference; border-radius: 9999px; transform: translate(-50%, -50%); }
  .cursor-dot  { width: 6px;  height: 6px;  background: var(--evora-terra); transition: transform 0.15s ease; }
  .cursor-ring { width: 38px; height: 38px; border: 1px solid rgba(245,241,235,0.6); transition: transform 0.25s ease, width 0.25s ease, height 0.25s ease, border-color 0.25s ease; }
  .cursor-hover .cursor-ring { width: 60px; height: 60px; border-color: var(--evora-terra); }
}

/* ---------------- Film grain ---------------- */
.grain { position: fixed; inset: 0; pointer-events: none; z-index: 60; opacity: 0.05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0'/></filter><rect width='200' height='200' filter='url(%23n)'/></svg>");
}

/* ---------------- Navbar ---------------- */
/* Navbar scroll state (Emaar-style): transparent over hero → solid #173F35 on scroll.
   Solid color animates via background-color; the subtle top veil animates via ::before
   opacity (a gradient-image → solid swap can't transition, so the two are split). */
.navbar { position: fixed; top: 0; left: 0; right: 0; z-index: 50; background-color: transparent; transition: background-color .35s ease, border-color .35s ease, box-shadow .35s ease; }
.navbar::before { content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none; background: linear-gradient(to bottom, rgba(0,0,0,0.35) 0%, transparent 100%); opacity: 1; transition: opacity .35s ease; }
.navbar.scrolled, .navbar.navbar--solid { background-color: #173F35; border-bottom: 1px solid rgba(245,241,235,0.08); box-shadow: 0 2px 24px rgba(10,10,10,0.18); }
.navbar.scrolled::before, .navbar.navbar--solid::before { opacity: 0; }
.nav-inner { position: relative; z-index: 1; max-width: 1600px; margin: 0 auto; padding: 18px 24px; display: flex; align-items: center; justify-content: space-between; }
@media (min-width: 1024px) { .nav-inner { padding: 18px 48px; } }

/* Navbar/footer logo — fit whole logo, preserve aspect ratio, no clip */
.nav-logo { display: block; height: 44px; width: auto; flex-shrink: 0; }
.nav-logo img { display: block; height: 100%; width: auto; max-height: 44px; object-fit: contain; }
@media (max-width: 1023px) { .nav-logo { height: 38px; } }
/* Navbar top-bar logo — larger & more prominent (Emaar-like); footer/mobile-menu unchanged */
.nav-inner .nav-logo { height: 56px; }
.nav-inner .nav-logo img { max-height: 56px; }
@media (max-width: 1023px) { .nav-inner .nav-logo { height: 46px; } .nav-inner .nav-logo img { max-height: 46px; } }
/* Footer logo — a touch larger than navbar for balance; navbar/mobile-menu unchanged */
footer .nav-logo { height: 60px; }
footer .nav-logo img { max-height: 60px; }
@media (max-width: 1023px) { footer .nav-logo { height: 50px; } footer .nav-logo img { max-height: 50px; } }

.nav-center { display: none; align-items: center; gap: 56px; font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase; }
.nav-right  { display: none; align-items: center; gap: 28px; font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase; }
@media (min-width: 1024px) { .nav-center, .nav-right { display: flex; } }

.nav-link { position: relative; transition: color .3s ease; }
.nav-link::after { content: ''; position: absolute; left: 0; bottom: -6px; width: 0; height: 1px; background: var(--evora-terra); transition: width 0.35s ease; }
.nav-link:hover::after, .nav-link.active::after { width: 100%; }
.nav-link.active { color: var(--evora-cream); }

.nav-icon-link { display: inline-flex; align-items: center; gap: 8px; transition: color .3s ease; }
.nav-icon-link:hover { color: var(--evora-terra); }

/* Language toggle — desktop (sits in .nav-right). Matches the 11px tracked,
   uppercase nav rhythm; the label shows the language you'd switch TO. */
/* Language switch — dual-label "EN | ع". Each label is an independent target:
   clicking it sets that language via applyLang(); the active label is cream, the
   inactive one is dimmed. direction:ltr is forced so the EN | ع order stays the same
   in LTR and RTL (the switch as a whole still repositions with the mirrored nav). */
.lang-switch { display: inline-flex; align-items: center; gap: 9px; direction: ltr;
  font-family: 'Attack', sans-serif; line-height: 1; color: var(--evora-cream); }
.lang-switch .lang-opt {
  background: transparent; border: 0; padding: 0; margin: 0; cursor: pointer;
  font: inherit; text-transform: uppercase; letter-spacing: 0.18em; line-height: 1;
  color: inherit; opacity: 0.42; transition: opacity .3s ease, color .3s ease;
}
/* The Arabic glyph reads small in the Latin face — give it the brand Arabic font, no tracking, a touch larger.
   Almarai's "ع" ink sits low in its line box (Arabic baseline ≠ Latin cap baseline), so box-centering alone
   leaves it dropping below "EN". Lift it with an em-based transform (scales across all three switch sizes)
   so EN, the divider, and ع share one optical centreline. */
.lang-switch .lang-opt[data-lang="ar"] { font-family: 'Almarai', system-ui, sans-serif; letter-spacing: 0; font-size: 1.2em; transform: translateY(-0.28em); }
.lang-switch .lang-opt.is-active { opacity: 1; }
.lang-switch .lang-opt:hover      { opacity: 1; color: var(--evora-terra); }
.lang-switch .lang-sep { width: 1px; height: 11px; flex: 0 0 auto; background: rgba(245,241,235,0.32); }
/* Size + placement variants (match each nav context; mobile bar hidden ≥768px). */
.lang-switch--nav  { font-size: 11px; }
.lang-switch--bar  { font-size: 13px; display: none; }
.lang-switch--menu { font-size: 12px; width: 100%; justify-content: center; padding: 12px 0; }
@media (max-width: 767px) { .lang-switch--bar { display: inline-flex; } }

.hamburger { display: flex; flex-direction: column; gap: 6px; padding: 8px; background: transparent; border: 0; }
.hamburger span { display: block; width: 24px; height: 1px; background: var(--evora-cream); }
@media (min-width: 1024px) { .hamburger { display: none; } }

/* ---------------- Mobile top-bar actions (≤767px only) ----------------
   Restructures the mobile navbar into: [Call] · centered logo · [ع][hamburger].
   (WHATSAPP: removed 2026-08-25 — the bar was [WhatsApp][Call]; the left group
   self-heals to one icon because both side groups are flex:1 1 0, keeping the
   logo perfectly centered.) Every new element is hidden ≥768px, so the tablet
   (768–1023px) and desktop (≥1024px) navbars render exactly as before. */
.nav-mobile-left  { display: none; }
.nav-mobile-right { display: none; }

.nav-mobile-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  color: var(--evora-cream);
  transition: color .3s ease;
}
.nav-mobile-icon:hover { color: var(--evora-terra); }


/* Show the hamburger cluster on tablet + mobile (hamburger itself hides ≥1024). */
@media (max-width: 1023px) {
  .nav-mobile-right { display: flex; align-items: center; gap: 4px; }
}

/* Mobile: three-part bar with a perfectly centered logo. */
@media (max-width: 767px) {
  /* Single Call icon since the WhatsApp removal: the -8px still cancels the
     40px hit-area's inner padding so the glyph sits on the page gutter. */
  .nav-mobile-left  { display: flex; align-items: center; gap: 2px; flex: 1 1 0; justify-content: flex-start; margin-left: -8px; }
  .nav-mobile-right { flex: 1 1 0; justify-content: flex-end; }
  .nav-inner .nav-logo { flex: 0 0 auto; }
}

/* ---------------- Home hero — mobile type hierarchy (≤767px only) ----------
   Bigger headline + smaller subcopy for stronger hierarchy on small screens.
   Only font-size/line-height change; fonts, colors and text are untouched, and
   the ≥768px (tablet + desktop) hero sizing is left exactly as authored. The
   two headline steps mirror the existing <640 / sm: breakpoints so the vw
   scaling stays proportional. Selectors use the stable data-i18n hooks. */
@media (max-width: 639px) {
  #hero h1[data-i18n="home.hero.headline"] { font-size: 14.5vw !important; line-height: 1.0 !important; }
}
@media (min-width: 640px) and (max-width: 767px) {
  #hero h1[data-i18n="home.hero.headline"] { font-size: 11vw !important; line-height: 1.0 !important; }
}
@media (max-width: 767px) {
  #hero p[data-i18n="home.hero.subline"] { font-size: 0.8125rem !important; line-height: 1.5 !important; }
}

/* ---------------- Mobile menu — right slide-in drawer (mobile only) ----------------
   Emaar-style drawer in the Évora skin. The panel covers 88vw (max 420px), leaving a
   ~44px sliver of the page on the leading edge; the backdrop dims that sliver and is
   the tap-to-close target. GSAP owns transform/opacity while animating and clears its
   inline props on close, so the CSS closed-state below is always the resting state.
   RTL mirrors the whole thing via logical properties + the [dir="rtl"] block further
   down. Desktop (≥1024px) never renders this — the drawer is display:none there. */
.menu-backdrop {
  position: fixed; inset: 0; z-index: 155;
  background: rgba(0, 0, 0, 0.5);
  opacity: 0; pointer-events: none;
  -webkit-tap-highlight-color: transparent;
}
.menu-backdrop.is-open { pointer-events: auto; }

.mobile-menu {
  position: fixed; top: 0; bottom: 0; inset-inline-end: 0; z-index: 160;
  width: 88vw; max-width: 420px;
  background: var(--ink);                         /* #0a0a0a — original menu bg */
  display: flex; flex-direction: column;
  transform: translateX(100%);                    /* closed (LTR) */
  visibility: hidden;
  overflow-y: auto; overscroll-behavior: contain;
  box-shadow: -18px 0 48px -24px rgba(0, 0, 0, 0.55);
}
.mobile-menu.is-open { visibility: visible; }

/* Head — no wordmark; the big X sits alone on the trailing edge */
.menu-head { display: flex; align-items: center; justify-content: flex-end; padding: 18px 22px 0; }
.menu-close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; margin-inline-end: -10px;   /* 48px tap target, optically flush */
  color: var(--evora-cream); background: none; border: 0;
  -webkit-tap-highlight-color: transparent;
}
.menu-close svg { width: 26px; height: 26px; display: block; }
.menu-close:active { color: var(--evora-terra); }

/* Items — original scale (text-2xl / 1.5rem) and original vertical placement:
   the list takes the free space and centres itself, leaving generous negative
   space above. The 20px gap + 44px tap targets reproduce the original ~64px row
   pitch (text-2xl line-box 32px + gap-8 32px) while keeping rows tappable. */
/* The <nav> is the drawer's flex child, so it must carry the grow — otherwise the
   list would only centre inside its own auto height and the whole panel stacks up
   against the head. */
.mobile-menu > nav { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center; }
.menu-items {
  list-style: none; margin: 0; padding: 0 32px;
  display: flex; flex-direction: column; justify-content: center; gap: 20px;
}
.menu-item {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 44px;
  font-family: 'Beautique Display', Georgia, serif;
  font-size: 1.5rem; line-height: 1.3;
  color: var(--evora-cream); text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: color .3s ease;
}
.menu-chev {
  flex: 0 0 auto; display: inline-flex; color: var(--evora-terra);
  transition: transform .3s cubic-bezier(.22,1,.36,1);
}
.menu-chev svg { width: 20px; height: 20px; display: block; }
.menu-item:active,
.menu-item:focus-visible { color: var(--evora-terra); }
.menu-item:active .menu-chev,
.menu-item:focus-visible .menu-chev { transform: translateX(6px); }
@media (hover: hover) and (pointer: fine) {
  .menu-item:hover { color: var(--evora-terra); }
  .menu-item:hover .menu-chev { transform: translateX(6px); }
}

/* Language toggle — HEAD's original spot: first row of the utility block, just
   above the hairline + Call Us. It takes no part in the free-space
   distribution, so the item list keeps HEAD's vertical position. The only
   departure from HEAD is that it is centred horizontally rather than flush left,
   which the shared .lang-switch--menu component already does on its own. */
.menu-lang { display: flex; justify-content: center; }
.menu-lang .lang-switch--menu { padding: 0; min-height: 44px; }

/* Utility block — toggle, then the hairline paired to the Call Us row. */
.menu-utility { padding: 0 32px; display: flex; flex-direction: column; gap: 16px; }
.menu-contact {
  /* WHATSAPP: removed 2026-08-25 — was space-between for the Call Us/WhatsApp
     pair; centred now so the lone Call Us link reads as intentional. Restore
     space-between when the WhatsApp link returns. */
  display: flex; align-items: center; justify-content: center;
  padding-top: 16px; border-top: 1px solid rgba(255, 255, 255, 0.1);
}
/* Icon + label share one tap target; gap 8px matches the header's .nav-icon-link.
   flex + gap mirrors automatically in RTL, so the icon stays on the leading edge. */
.menu-contact a {
  font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--evora-cream); text-decoration: none;
  min-height: 44px; display: inline-flex; align-items: center; gap: 8px;
  transition: color .3s ease;
}
.menu-contact a svg { flex: 0 0 auto; }
.menu-contact a:active { color: var(--evora-terra); }

/* CTA — pinned to the bottom, full width. Outline treatment restored verbatim from
   the original .btn-primary (transparent fill, cream hairline border, cream text)
   including its terracotta slide-up ::before fill on hover/tap. */
.menu-cta-wrap { padding: 16px 32px calc(40px + env(safe-area-inset-bottom, 0px)); }
.menu-cta {
  position: relative; overflow: hidden; display: block; width: 100%; cursor: pointer;
  padding: 14px 28px;
  border: 1px solid rgba(245, 241, 235, 0.4);
  color: var(--evora-cream);
  background: transparent;
  font-family: 'Attack', sans-serif;
  font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase;
  text-align: center;
  -webkit-tap-highlight-color: transparent;
  transition: color .4s ease, border-color .4s ease;
}
.menu-cta::before {
  content: ''; position: absolute; inset: 0; background: var(--evora-terra);
  transform: translateY(101%); transition: transform .5s cubic-bezier(.77,0,.18,1); z-index: 0;
}
.menu-cta span { position: relative; z-index: 1; }
/* :active carries the interaction on touch, where :hover is unreliable. */
.menu-cta:hover, .menu-cta:active { border-color: var(--evora-terra); color: #fff; }
.menu-cta:hover::before, .menu-cta:active::before { transform: translateY(0); }

/* Desktop never shows the drawer — the ≥lg navbar is untouched by all of the above. */
@media (min-width: 1024px) {
  .mobile-menu, .menu-backdrop { display: none !important; }
}

/* Reduced motion — fade only; no slide, no chevron travel. */
@media (prefers-reduced-motion: reduce) {
  .mobile-menu { transform: none; }
  .menu-chev, .menu-item { transition: none; }
  .menu-item:active .menu-chev, .menu-item:hover .menu-chev { transform: none; }
}

/* ---------------- Buttons ---------------- */
.btn-primary {
  position: relative; overflow: hidden; display: inline-block;
  padding: 14px 28px;
  border: 1px solid rgba(245,241,235,0.4);
  color: var(--evora-cream);
  font-family: 'Attack', sans-serif;
  font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase;
  transition: color .4s ease, border-color .4s ease;
  background: transparent;
}
.btn-primary::before { content: ''; position: absolute; inset: 0; background: var(--evora-terra); transform: translateY(101%); transition: transform .5s cubic-bezier(.77,0,.18,1); z-index: 0; }
.btn-primary:hover { border-color: var(--evora-terra); color: #fff; }
.btn-primary:hover::before { transform: translateY(0); }
.btn-primary span { position: relative; z-index: 1; }

.btn-terra {
  display: inline-block;
  padding: 14px 28px;
  background: var(--evora-terra);
  color: #fff;
  font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase;
  transition: background .3s ease, transform .3s ease;
}
.btn-terra:hover { background: #c4623d; }

.btn-ghost {
  display: inline-block;
  padding: 14px 28px;
  border: 1px solid rgba(245,241,235,0.3);
  color: var(--evora-cream);
  font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase;
  transition: all .3s ease; background: transparent;
}
.btn-ghost:hover { background: rgba(245,241,235,0.08); border-color: var(--evora-cream); }

.btn-cream {
  display: inline-block;
  padding: 14px 28px;
  border: 1px solid rgba(23,63,53,0.3);
  color: var(--evora-dark);
  font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase;
  transition: all .3s ease;
}
.btn-cream:hover { background: var(--evora-dark); color: var(--evora-cream); border-color: var(--evora-dark); }

/* ---------------- ARCH — the brand's signature shape ---------------- */
/* A rounded-top, flat-bottom container. Used to frame photos, panels, hero card. */
.arch {
  position: relative;
  border-radius: 50% 50% 0 0 / 35% 35% 0 0;
  overflow: hidden;
}
.arch-outline {
  border: 1px solid rgba(245,241,235,0.25);
  border-radius: 50% 50% 0 0 / 35% 35% 0 0;
}
.arch-outline-dark { border-color: rgba(23,63,53,0.25); }
.arch-shadow-bg {
  position: absolute;
  background: rgba(144,144,111,0.08);
  border-radius: 50% 50% 0 0 / 35% 35% 0 0;
  z-index: 0;
  pointer-events: none;
}

/* ---------------- Yew tree icon (inline SVG component) ---------------- */
.yew { display: inline-block; }
.yew svg { display: block; }

/* ---------------- Eyebrow label ----------------
   Refined headline treatment: 14px desktop / 13px mobile, medium (Attack has
   400/500/700 — 700 reads clumsy at this scale, 500 keeps presence without
   weight). Tracking opened 0.22em -> 0.24em so the smaller letters breathe. */
.eyebrow {
  display: inline-flex; align-items: center;
  font-size: 14px; font-weight: 500; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--evora-olive);
}
/* The leading 24x1px rule that used to sit before every eyebrow label is gone —
   a dash reads as an introduction to prose, not as part of a title-label. It was
   a ::before pseudo-element here, so dropping this one rule clears it from every
   .eyebrow sitewide in both directions at once. inline-flex stays (the markup
   leans on it for the `justify-center` utility); `gap` went with the pseudo —
   with a single anonymous flex item it had nothing left to space. */
/* Eyebrows read a touch smaller on mobile than desktop, still clearly legible. */
@media (max-width: 767px) { .eyebrow { font-size: 13px; } }

/* Home hero brand line ("Évora Developments · Since 2001") — its own understated
   tier: over busy video footage it must stay quieter than the section eyebrows,
   so it opts out of the headline scale above (id selector wins on specificity).
   Stepped down with the sitewide eyebrow scale (was 14/13) so it stays one clear
   tier below; keeps the near-cream contrast lift. */
#hero .eyebrow { font-size: 12px; font-weight: 500; letter-spacing: 0.26em; color: rgba(245, 241, 235, 0.92); }
/* (the near-cream ::before recolour that lived here died with the dash itself) */
@media (max-width: 767px) { #hero .eyebrow { font-size: 11px; } }

/* ---------------- Footer group headings (EXPLORE / PROJECTS / LEGAL) ----------------
   Governed sitewide here so all 10 pages update together, overriding the inline
   `text-[10px]` utility on nav.footer-col > p (higher specificity, no !important
   needed). Brand-column tagline (a div.footer-col > p) is untouched. */
nav.footer-col > p { font-family: 'Attack', sans-serif; font-size: 14px; font-weight: 500; letter-spacing: 0.24em; }
@media (max-width: 767px) { nav.footer-col > p { font-size: 13px; } }

/* ---------------- Footer link-column row rhythm (EXPLORE / PROJECTS / LEGAL) ----
   One row-gap governs all three columns at every width, overriding the per-list
   `gap-[12px] lg:gap-[14px]` utilities (higher specificity, no !important). This
   is the flex gap, i.e. the space between item *boxes* — so it stays constant
   whether an item sits on one line or wraps to two ("Pulse Medical Hub",
   "Terms & Conditions" and "Privacy Policy" all wrap in the third-width mobile
   columns, and "Terms & Conditions" wraps around 1024px). A wrapped item's own
   two lines stay tied together by line-height, well inside this gap, so each
   entry still reads as one item and the column rhythm reads even. Mobile keeps a
   slightly tighter value to suit the 15px/1.3 mobile link scale. */
.footer-evora nav.footer-col > ul { row-gap: 18px; }
@media (max-width: 767px) { .footer-evora nav.footer-col > ul { row-gap: 16px; } }

/* Tablet + desktop (≥768px): the eyebrow-to-first-item gap matches the 18px
   item rhythm exactly, overriding the inline mb-4/lg:mb-5 (16/20px) utilities so
   every gap in all three columns is identical. Mobile keeps its own tuned 12px
   (set in the ≤767px footer block below). */
@media (min-width: 768px) { .footer-evora nav.footer-col > p { margin-bottom: 18px; } }

/* Desktop: equalize the RENDERED eyebrow-to-first-item gap. The three column
   boxes are geometrically identical (baselines probe equal), but the visible
   gap is set by glyph ink, and EXPLORE loses on both sides at once —
   EN: "Home" is cap-only ink (9.8px ascent) vs the ascender words in the other
       columns (11.45px) → its gap renders ~2px larger;
   AR: «استكشف» has no descenders (ink stops 0.35px below baseline) while
       «المشاريع»/«قانوني» drop 5.3–5.5px tails, and «الرئيسية» is also
       0.5–1px shorter than its neighbours → ~5.7px larger.
   Pull the EXPLORE list up by the measured ink delta so all three gaps match
   in rendered pixels (probe-verified spread <0.75px after). Values are tied to
   the current eyebrow/first-item wording — retune if that copy changes.
   Mobile (<768px) untouched. */
@media (min-width: 768px) {
  .footer-evora nav.footer-col[aria-label="Explore"] > ul { margin-top: -2px; }
  [dir="rtl"] .footer-evora nav.footer-col[aria-label="Explore"] > ul { margin-top: -6px; }
}

/* ---------------- Reveal helpers (GSAP hooks) ---------------- */
/* The overflow:hidden mask must not crop Beautique's deep descenders (g y j p q).
   padding-bottom opens room below the baseline; the equal negative margin-bottom
   cancels it in layout (inline-block margin box is unchanged) so line spacing is
   untouched. The hidden span is pushed 150% down so the extra padded area still
   fully conceals it before the reveal. */
.reveal-line { overflow: hidden; display: inline-block; padding-bottom: 0.24em; margin-bottom: -0.24em; }
.reveal-line > span { display: inline-block; transform: translateY(150%); }

/* ---------------- Display-heading typography safety (sitewide) ----------------
   Beautique Display sets loose by design; the negative `tracking-tight` utility
   pulls large display glyphs until serifs collide/overlap. Neutralise it on any
   display heading (keeps the elegant look, never lets glyphs touch). Also floor
   the flagship hero's line-height to ≥1 so descenders never crowd the next line
   (mobile ≤767 keeps its own tuned value in the media block above). */
.font-display.tracking-tight { letter-spacing: 0; }
#hero h1[data-i18n="home.hero.headline"] { line-height: 1.02; }
.gsap-fadeup { opacity: 0; transform: translateY(40px); }
.gsap-fade   { opacity: 0; }

/* ---------------- Hero ---------------- */
/* Sticky hero: stays pinned at top while content sections slide over it */
#hero {
  position: sticky;
  top: 0;
  z-index: 1;
}
.hero-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; will-change: transform; }
.hero-overlay { position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(10,10,10,0.45) 0%, rgba(10,10,10,0.15) 35%, rgba(10,10,10,0.88) 100%),
    linear-gradient(90deg, rgba(10,10,10,0.40) 0%, rgba(10,10,10,0) 60%);
}
/* Vertical scroll indicator */
#scroll-line-inner {
  animation: scrollDraw 1.8s ease-in-out infinite !important;
}
@keyframes scrollDraw {
  0%   { height: 0px;  top: 0px; }
  50%  { height: 80px; top: 0px; }
  100% { height: 0px;  top: 80px; }
}

/* --- Cinematic pinned hero (Emaar-style): content slides over hero --- */
#hero ~ section,
#hero ~ footer {
  position: relative;
  z-index: 2;
}

/* ---------------- Modal ---------------- */
.modal-backdrop { position: fixed; inset: 0; z-index: 200; background: rgba(10,10,10,0.85); backdrop-filter: blur(8px); opacity: 0; pointer-events: none; transition: opacity .4s ease; }
.modal-backdrop.open { opacity: 1; pointer-events: auto; }
.modal-panel { background: var(--evora-dark); border: 1px solid rgba(245,241,235,0.08); transform: translateY(40px); opacity: 0; transition: all .5s cubic-bezier(.77,0,.18,1); }
.modal-backdrop.open .modal-panel { transform: translateY(0); opacity: 1; }
.modal-input { background: transparent; border: 0; border-bottom: 1px solid rgba(245,241,235,0.2); padding: 12px 0; color: var(--evora-cream); width: 100%; font-family: 'Inter', sans-serif; outline: none; transition: border-color .3s ease; }
.modal-input:focus { border-color: var(--evora-terra); }
.modal-input::placeholder { color: rgba(245,241,235,0.4); letter-spacing: 0.1em; text-transform: uppercase; font-size: 11px; }

/* Boxed form (Emaar-style register modal — Évora identity) */
.modal-field { display: block; }
.modal-field > label {
  display: block;
  font-size: 10px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(245,241,235,0.55);
  margin-bottom: 10px;
}
.modal-field .req { color: var(--evora-terra); margin-left: 4px; }
.modal-box {
  width: 100%; display: block;
  background: transparent;
  border: 1px solid rgba(245,241,235,0.22);
  padding: 14px 16px;
  color: var(--evora-cream);
  font-family: 'Inter', sans-serif;
  font-size: 14px;
  outline: none;
  transition: border-color .3s ease;
  border-radius: 0;
}
.modal-box:focus { border-color: var(--evora-terra); }
.modal-box::placeholder { color: rgba(245,241,235,0.3); font-size: 12px; }
.modal-select {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'><path d='M1 1l4 4 4-4' stroke='%23F5F1EB' stroke-opacity='0.6' stroke-width='1.2'/></svg>");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 38px;
  cursor: pointer;
}

.modal-checkbox { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; user-select: none; }
.modal-checkbox input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 18px; height: 18px; flex-shrink: 0; margin-top: 2px;
  border: 1px solid rgba(245,241,235,0.35);
  background: transparent;
  position: relative; cursor: pointer;
  transition: background .2s ease, border-color .2s ease;
}
.modal-checkbox input[type="checkbox"]:checked { background: var(--evora-terra); border-color: var(--evora-terra); }
.modal-checkbox input[type="checkbox"]:checked::after {
  content: ''; position: absolute; left: 5px; top: 1px;
  width: 5px; height: 10px;
  border: solid #fff; border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
}
.modal-checkbox span { font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(245,241,235,0.65); line-height: 1.5; }

.btn-submit-cream {
  width: 100%; display: block;
  padding: 16px 28px;
  background: var(--evora-cream);
  color: var(--evora-dark);
  font-family: 'Attack', sans-serif;
  font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase;
  border: 0; cursor: pointer;
  transition: background .3s ease, color .3s ease;
}
.btn-submit-cream:hover { background: var(--evora-terra); color: #fff; }

/* Modal close — same treatment as the mobile drawer's X (.menu-close):
   26px stroke icon centred in a 48px tap target, optically flush to the panel
   corner. inset-inline-end keeps it on the trailing edge in RTL automatically. */
.modal-close {
  position: absolute; top: 8px; inset-inline-end: 8px; z-index: 10;
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px;
  color: rgba(245, 241, 235, 0.7); background: none; border: 0; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color .3s ease;
}
.modal-close svg { width: 24px; height: 24px; display: block; }
.modal-close:hover { color: var(--evora-terra); }
.modal-close:active { color: var(--evora-terra); }

/* ---------------- Image hover scale (for arch-framed photos) ---------------- */
.img-zoom { transition: transform 1.2s cubic-bezier(.77,0,.18,1); transform: scale(1.05); }
.img-zoom-parent:hover .img-zoom { transform: scale(1.1); }

/* ============================================================
   CONTACT PAGE — scoped to body[data-page="contact"]
   ============================================================ */

/* Paper texture overlay for the dark form section */
.paper-tex::before {
  content: '';
  position: absolute; inset: 0;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='p'><feTurbulence type='fractalNoise' baseFrequency='0.6' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.96  0 0 0 0 0.95  0 0 0 0 0.92  0 0 0 0.45 0'/></filter><rect width='220' height='220' filter='url(%23p)'/></svg>");
  mix-blend-mode: overlay;
}

/* Hero text initial state (GSAP fades to opacity:1) */
.contact-hero-eyebrow,
.contact-hero-title,
.contact-hero-sub { will-change: opacity, transform; }

/* Mobile: pull hero text in from the edge so it doesn't kiss the screen */
@media (max-width: 767px) {
  .contact-hero-content { padding: 0 6vw 7vh 6vw !important; }
}

/* --- Hero image: warm color-grading + face-anchor --- */
.hero-contact-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 55% 42%;     /* desktop — Évora flags centered, logos in frame */
  z-index: 0;
  filter:
    saturate(1.18)
    contrast(1.08)
    brightness(1.04)
    sepia(0.08)
    hue-rotate(-3deg);
}
@media (max-width: 768px) {
  .hero-contact-image { object-position: 58% 40%; }
}

/* --- Overlay 1+3 stacked in ::before ---
   Top layer (rendered first in `background:` = painted on top):
     bottom-left radial vignette that grounds the headline text.
   Bottom layer:
     softened 100deg dark-green wash (Step 1) — keeps left side anchored,
     lets right side breathe. */
.hero-contact::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(
      ellipse 70% 60% at 20% 80%,
      rgba(23, 63, 53, 0.7)  0%,
      rgba(23, 63, 53, 0.45) 35%,
      rgba(23, 63, 53, 0)    70%
    ),
    linear-gradient(
      100deg,
      rgba(23, 63, 53, 0.65) 0%,
      rgba(23, 63, 53, 0.35) 45%,
      rgba(23, 63, 53, 0.05) 100%
    );
}

/* --- Overlay 2: warm golden glow bleeding from the right --- */
.hero-contact::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    270deg,
    rgba(220, 165, 95, 0.15) 0%,
    rgba(220, 165, 95, 0)   40%
  );
}

/* Text sits above both overlays */
.contact-hero-content { z-index: 2; }

/* Cinematic 21:9 cap on desktop — no vertical clipping of the woman */
@media (min-width: 1024px) {
  body[data-page="contact"] .hero-contact {
    height: auto;
    aspect-ratio: 21 / 9;
    min-height: 60vh;
    max-height: 85vh;
  }
}

/* Contact info rows (cream section) */
.contact-row {
  display: grid;
  grid-template-columns: 32% 1fr;
  gap: 16px;
  padding: 20px 0;
  border-bottom: 1px solid rgba(144,144,111,0.2);
  align-items: baseline;
}
.contact-row:first-child { padding-top: 0; }
.contact-row:last-child { border-bottom: none; }
.contact-label {
  font-size: 10px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--evora-olive);
  font-family: 'Attack', sans-serif;
  font-weight: 500;
}
.contact-value {
  font-size: 15px;
  color: var(--evora-dark);
  font-family: 'Inter', sans-serif;
  line-height: 1.5;
}
.contact-link {
  color: var(--evora-dark);
  transition: color .25s ease;
}
.contact-link:hover {
  color: var(--evora-terra);
  text-decoration: underline;
  text-underline-offset: 4px;
}
@media (max-width: 639px) {
  .contact-row { grid-template-columns: 1fr; gap: 4px; padding: 16px 0; }
}

/* Social icons (cream section) */
.contact-social a {
  display: inline-flex;
  width: 42px; height: 42px;
  align-items: center; justify-content: center;
  border-radius: 9999px;
  color: var(--evora-dark);
  border: 1px solid rgba(23,63,53,0.15);
  transition: color .25s ease, border-color .25s ease, transform .25s ease;
}
.contact-social a:hover {
  color: var(--evora-terra);
  border-color: var(--evora-terra);
  transform: translateY(-2px);
}

/* Contact split — info (left, padded) + map (right, edge-flush full-height).
   Mirrors O West /contact-us. Section has no horizontal padding so the map
   can bleed to the viewport edge; the info column supplies its own padding. */
.contact-split-grid {
  display: grid;
  grid-template-columns: 1fr;
}
.contact-split-info {
  padding: 88px 24px;
}
.contact-split-map {
  display: flex;
  min-height: 60vh;          /* mobile: full-width, edge-to-edge, sensible height */
}
@media (min-width: 768px) {
  .contact-split-info { padding: 104px 48px; }
}
@media (min-width: 1024px) {
  .contact-split-grid {
    grid-template-columns: 1fr 1fr;
    align-items: stretch;
  }
  .contact-split-info {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-top: 128px;
    padding-bottom: 128px;
    padding-right: 72px;
    /* align left edge with the site's centered 1500px container */
    padding-left: max(48px, calc((100vw - 1500px) / 2 + 48px));
  }
  .contact-split-map { min-height: 100%; }
}

/* Map — full-height, flush (no card/shadow/radius) */
.contact-map {
  position: relative;
  overflow: hidden;
  background: rgba(23,63,53,0.05);
  width: 100%;
  height: 100%;
}
.contact-map iframe {
  width: 100%;
  height: 100%;
  min-height: 350px;
  border: 0;
  display: block;
  filter: saturate(0.85);
}
.map-pin {
  position: absolute; top: 18px; left: 18px;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 10px 18px;
  background: rgba(245,241,235,0.88);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-radius: 9999px;
  color: var(--evora-dark);
  font-family: 'Attack', sans-serif;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  pointer-events: none;
  box-shadow: 0 4px 20px rgba(23,63,53,0.12);
}

/* Guest / Home Owner toggle — O West-style two-segment switch (dark form section).
   Outer track = translucent green + soft border; active segment = cream + dark text. */
.interest-toggle {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  padding: 6px;
  border-radius: 9999px;
  background: rgba(245,241,235,0.06);
  border: 1px solid rgba(245,241,235,0.2);
}
.interest-pill {
  padding: 14px 20px;
  border-radius: 9999px;
  font-family: 'Attack', sans-serif;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-align: center;
  color: rgba(245,241,235,0.6);
  background: transparent;
  border: 0;
  cursor: none;
  transition: background .3s ease, color .3s ease;
}
.interest-pill:hover { color: rgba(245,241,235,0.85); }
.interest-pill.is-active {
  background: var(--evora-cream);
  color: var(--evora-dark);
}
.interest-pill.is-active:hover { color: var(--evora-dark); }

/* Floating label form fields (dark form section) */
.field-float { position: relative; }
.field-float input,
.field-float textarea,
.field-float select {
  width: 100%;
  background: rgba(245,241,235,0.06);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  border: 1px solid rgba(245,241,235,0.2);
  border-radius: 9999px;                 /* O West-style pill inputs */
  padding: 20px 30px 8px 30px;           /* compact single-line height (~51px) */
  color: var(--evora-cream);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 15px;
  line-height: 1.4;
  outline: none;
  transition: border-color .3s ease, background .3s ease;
  -webkit-appearance: none;
  appearance: none;
}
.field-float textarea {
  resize: vertical;
  min-height: 150px;
  border-radius: 24px;                   /* rounded-2xl for the multi-line field */
  padding-top: 30px;
}
.field-float select {
  cursor: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23F5F1EB' stroke-opacity='0.6' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M1 1l5 5 5-5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 26px center;
  padding-right: 50px;
}
.field-float select option {
  background: var(--evora-dark);
  color: var(--evora-cream);
}
.field-float label {
  position: absolute;
  top: 50%;
  left: 28px;
  transform: translateY(-50%) scale(1);
  transform-origin: left center;
  font-size: 14px;
  color: rgba(245,241,235,0.6);
  font-family: 'Inter', sans-serif;
  pointer-events: none;
  transition: top .2s ease, transform .2s ease, font-size .2s ease, color .2s ease, letter-spacing .2s ease;
  background: transparent;
}
.field-float textarea + label { top: 26px; transform: none; }

/* Floated state — inputs & select: keep `top` fixed and float the label UPWARD
   purely via transform (translate up + scale to shrink), so the motion animates
   smoothly on the compositor instead of the %→px `top` jump that dropped it down. */
.field-float input:focus + label,
.field-float input:not(:placeholder-shown) + label,
.field-float select:focus + label,
.field-float.is-filled label {
  transform: translateY(calc(-50% - 20px)) scale(0.72);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--evora-terra);
}

/* Floated state — textarea: label rests near the top (top:26px), so its float
   animates cleanly px→px on `top`. */
.field-float textarea:focus + label,
.field-float textarea:not(:placeholder-shown) + label {
  top: 8px;
  transform: none;
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--evora-terra);
}

/* Focus state on the field itself */
.field-float input:focus,
.field-float textarea:focus,
.field-float select:focus {
  border-color: var(--evora-terra);
  background: rgba(245,241,235,0.1);
}

/* Error state */
.field-float.has-error input,
.field-float.has-error textarea,
.field-float.has-error select {
  border-color: var(--evora-terra);
  background: rgba(177,85,51,0.06);
}
.field-err {
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--evora-terra);
  margin-top: 6px;
  padding-left: 4px;
  min-height: 14px;
  line-height: 1.3;
}
.field-err.hidden { display: none; }

/* Honeypot — visually hidden, kept in tab/AT order out of the way */
.hp {
  position: absolute !important;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Terracotta pill CTA */
.btn-terra {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: var(--evora-terra);
  color: var(--evora-cream);
  padding: 18px 36px;
  border-radius: 9999px;
  font-family: 'Attack', sans-serif;
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  border: 0;
  cursor: none;
  min-width: 200px;
  transition: background .3s ease, transform .15s ease, opacity .25s ease;
}
.btn-terra:hover { background: #963F22; }
.btn-terra:hover .contact-arrow { transform: translateX(4px); }
.btn-terra:active { transform: scale(0.98); }
.btn-terra:disabled { opacity: 0.6; cursor: not-allowed; }
.contact-arrow { transition: transform .25s ease; }
@media (max-width: 767px) {
  .btn-terra { width: 100%; min-width: 0; }
  body[data-page="contact"] .gsap-fadeup .btn-terra ~ * { width: 100%; }
}

/* White pill CTA — O West-style submit (dark text + arrow on cream) */
.btn-white {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: var(--evora-cream);
  color: var(--evora-dark);
  padding: 18px 40px;
  border-radius: 9999px;
  font-family: 'Attack', sans-serif;
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  border: 0;
  cursor: none;
  min-width: 200px;
  transition: box-shadow .3s ease, transform .15s ease, opacity .25s ease;
}
.btn-white:hover { box-shadow: 0 12px 34px rgba(245,241,235,0.18); }
.btn-white:hover .contact-arrow { transform: translateX(4px); }
.btn-white:active { transform: scale(0.98); }
.btn-white:disabled { opacity: 0.6; cursor: not-allowed; }
@media (max-width: 767px) {
  .btn-white { width: 100%; min-width: 0; }
}

/* ============================================================
   GRACEFUL DEGRADATION — hero text visibility without GSAP
   ============================================================
   Why: .reveal-line > span has transform: translateY(110%) baked into
   CSS so GSAP can animate it in. If GSAP fails to load (CDN block, JS
   disabled, reduced-motion preference), the title would never appear.

   Two layers below + a 3-second JS safety net in scripts.js.
   ============================================================ */

/* Layer 1 — respect reduced-motion preference */
@media (prefers-reduced-motion: reduce) {
  .reveal-line > span,
  .hero-eyebrow,
  .hero-subtitle,
  [class*="opacity-0"] {
    transform: none !important;
    opacity: 1 !important;
    animation: none !important;
    transition: none !important;
  }
}

/* Layer 2 — .no-js fallback: applies when the inline <script> in <head>
   didn't run (JS disabled or scripts.js failed to load) */
.no-js .reveal-line > span,
.no-js .hero-eyebrow,
.no-js .hero-subtitle,
.no-js [class*="opacity-0"] {
  transform: none !important;
  opacity: 1 !important;
}

/* ============================================================
   RTL / ARABIC  (dir="rtl", lang="ar")
   ============================================================
   Phase 1 RTL machinery. Everything below is scoped under [dir="rtl"] so the
   English (LTR) layout is byte-for-byte unchanged when Arabic is off. The
   heavy lifting (text-align, flex main-axis, justify-content, inline flow)
   comes free from dir="rtl" itself; the rules below fix what the browser does
   NOT auto-mirror: physical Tailwind utilities, absolute offsets, decorative
   pseudo-elements, the mobile-menu slide direction, and the Pulse sidebar.

   Deliberately NOT mirrored: the logo image, hero/section videos, and phone
   numbers (kept in LTR digit order via unicode-bidi: plaintext).
   ============================================================ */

/* ---- Latin-only aliases of the brand faces, for use inside RTL ----
   In AR mode the kept-English runs ("Pulse Medical Hub", "Pulse Hub", Latin
   "Évora") were rendering in Athelas Arabic's / Almarai's Latin glyphs — a
   visibly different face from the English pages. These aliases re-point those
   runs at the real brand faces.

   The unicode-range is the whole point. Listing plain 'Beautique Display' first
   in the RTL stack would also hand it the SPACE and shared punctuation, which
   measurably changed Arabic word-spacing (the Arabic headline moved 780.39px ->
   761.52px in testing). Restricting the alias to Latin LETTERS only means every
   character an Arabic string is actually made of — Arabic letters, the Arabic
   comma, the em dash, the period, and critically the space — still resolves to
   Athelas Arabic / Almarai exactly as before, so Arabic metrics are untouched.

   BEAUTIQUE (display) additionally aliases DIGITS + the numeric "+ ," so the
   17346 hotline and the display stat numerals (+20, 2,500+…) render in the same
   brand face AR headings use in EN. Attack Latin (body) deliberately does NOT
   take digits: numerals inside Arabic body copy keep rendering in Almarai. */
@font-face { font-family: 'Beautique Latin'; src: url('fonts/BeautiqueDisplay-Light.woff2?v=20260817b')   format('woff2'); font-weight: 300; font-display: swap; unicode-range: U+0041-005A, U+0061-007A, U+00C0-00FF, U+0100-017F, U+0030-0039, U+002B-002C, U+0021, U+0026-0027, U+003F, U+2019; }
@font-face { font-family: 'Beautique Latin'; src: url('fonts/BeautiqueDisplay-Regular.woff2?v=20260817b') format('woff2'); font-weight: 400; font-display: swap; unicode-range: U+0041-005A, U+0061-007A, U+00C0-00FF, U+0100-017F, U+0030-0039, U+002B-002C, U+0021, U+0026-0027, U+003F, U+2019; }
@font-face { font-family: 'Beautique Latin'; src: url('fonts/BeautiqueDisplay-Medium.woff2?v=20260817b')  format('woff2'); font-weight: 500; font-display: swap; unicode-range: U+0041-005A, U+0061-007A, U+00C0-00FF, U+0100-017F, U+0030-0039, U+002B-002C, U+0021, U+0026-0027, U+003F, U+2019; }
@font-face { font-family: 'Beautique Latin'; src: url('fonts/BeautiqueDisplay-Bold.woff2?v=20260817b')    format('woff2'); font-weight: 700; font-display: swap; unicode-range: U+0041-005A, U+0061-007A, U+00C0-00FF, U+0100-017F, U+0030-0039, U+002B-002C, U+0021, U+0026-0027, U+003F, U+2019; }
@font-face { font-family: 'Attack Latin'; src: url('fonts/ATTACK-Light.woff2?v=20260817f')   format('woff2'); font-weight: 300; font-display: swap; unicode-range: U+0041-005A, U+0061-007A, U+00C0-00FF, U+0100-017F, U+0021, U+0026-0027, U+002C, U+003F, U+2019; }
@font-face { font-family: 'Attack Latin'; src: url('fonts/ATTACK-Regular.woff2?v=20260817f') format('woff2'); font-weight: 400; font-display: swap; unicode-range: U+0041-005A, U+0061-007A, U+00C0-00FF, U+0100-017F, U+0021, U+0026-0027, U+002C, U+003F, U+2019; }
@font-face { font-family: 'Attack Latin'; src: url('fonts/ATTACK-Medium.woff2?v=20260817f')  format('woff2'); font-weight: 500; font-display: swap; unicode-range: U+0041-005A, U+0061-007A, U+00C0-00FF, U+0100-017F, U+0021, U+0026-0027, U+002C, U+003F, U+2019; }
@font-face { font-family: 'Attack Latin'; src: url('fonts/ATTACK-Bold.woff2?v=20260817f')    format('woff2'); font-weight: 700; font-display: swap; unicode-range: U+0041-005A, U+0061-007A, U+00C0-00FF, U+0100-017F, U+0021, U+0026-0027, U+002C, U+003F, U+2019; }

/* INTER LATIN — the text-face counterpart of 'Attack Latin'. Latin runs inside
   Arabic body copy ("Évora", "Pulse Medical Hub", "6th of October") hit the same
   unhinted-Attack defect on Windows that the English pages did, so the RTL body
   stack moves to Inter alongside the LTR one.

   The unicode-range is byte-identical to 'Attack Latin' above and is the whole
   point of the alias — DO NOT simplify this to a plain 'Inter' in the RTL stack.
   Inter carries the SPACE and the shared punctuation, so listing it unrestricted
   would hand it every space in an Arabic string and shift Arabic word-spacing —
   the exact regression measured when this was got wrong for Beautique (an Arabic
   headline moved 780.39px -> 761.52px). Restricting the alias to Latin LETTERS
   means the space, the Arabic comma, the em dash and the period all still resolve
   to Almarai, so Arabic metrics are untouched. Verified after this change: the
   RTL body stack and a pure-Almarai control measure the same string at 462.88px
   and 462.88px — a 0.00px delta.
   Like 'Attack Latin', it deliberately does NOT take digits, so numerals inside
   Arabic body copy keep rendering in Almarai. */
@font-face { font-family: 'Inter Latin'; src: url('fonts/Inter-Regular.woff2?v=20260817g') format('woff2'); font-weight: 400; font-display: swap; unicode-range: U+0041-005A, U+0061-007A, U+00C0-00FF, U+0100-017F, U+0021, U+0026-0027, U+002C, U+003F, U+2019; }
@font-face { font-family: 'Inter Latin'; src: url('fonts/Inter-Bold.woff2?v=20260817g')    format('woff2'); font-weight: 700; font-display: swap; unicode-range: U+0041-005A, U+0061-007A, U+00C0-00FF, U+0100-017F, U+0021, U+0026-0027, U+002C, U+003F, U+2019; }

/* ================= DISPLAY face re-assertion (Attack) =================
   The sitewide default moved from Attack to Inter on `html, body` above, because
   Attack is unhinted and breaks down at text sizes on Windows. Everything below
   is DISPLAY — all-caps eyebrows, nav, labels, badges and buttons — which keeps
   Attack. These selectors previously had NO font-family of their own and simply
   inherited Attack from the body, so flipping that default would have silently
   dragged them to Inter. Each one is re-asserted here instead.

   Nothing in this block changes what any element looked like before the swap:
   every selector here resolved to Attack by inheritance and still resolves to
   Attack. No size, weight, tracking or leading is touched.

   The [class~="uppercase"] rule is the governing rule for the 55 inline Tailwind
   all-caps sites across the 10 pages (footer column headings, section eyebrows,
   the "Coming Soon" badge, board member titles, projects/contact eyebrows and
   pills, pulse's sidebar labels, the legal pages' "Last Updated" line). They are
   captured by the utility class they already carry, so no markup was touched.
   `~=` is a whole-token match, not a substring: an audit of all 10 pages found
   `uppercase` to be the only class token containing that word (55 occurrences),
   and every one of them is genuinely all-caps DISPLAY — no body prose. If a
   future element gets the uppercase utility but wants the text face, give it an
   explicit font-family; this rule is only (0,1,0). */
[class~="uppercase"] { font-family: 'Attack', sans-serif; }

/* All-caps surfaces whose uppercasing comes from CSS rather than a utility class,
   so the rule above cannot see them. Declared sitewide here (including the ones
   whose other properties live in a page-level <style> block — those pages never
   declare font-family on these selectors, so there is no cascade tie to lose). */
.nav-center, .nav-right,          /* desktop nav, 11px tracked caps            */
.menu-contact a,                  /* mobile drawer Call Us, 11px               */
.btn-ghost, .btn-cream,           /* outline buttons, 11px caps                */
.eyebrow,                         /* sitewide section eyebrow, 14/13px         */
.modal-field > label,             /* boxed-form labels, 10px                   */
.modal-checkbox span,             /* consent line, 11px                        */
.hero-scroll-label,               /* vertical SCROLL cue (index/about/pulse)   */
.section-eyebrow,                 /* pulse.html, 14/13px                       */
.intro-eyebrow,                   /* pulse.html, 14px                          */
.acc-eyebrow,                     /* pulse.html, 9px                           */
.image-caption-chip {             /* pulse.html, 11.2px                        */
  font-family: 'Attack', sans-serif;
}
/* ====================== end DISPLAY re-assertion ====================== */

/* ---- Arabic type: Almarai for body, Athelas Arabic for display/headlines ----
   Latin alias first, Arabic face second — per-glyph fallback, see the note above. */
[dir="rtl"] body { font-family: 'Inter Latin', 'Almarai', system-ui, sans-serif; }
[dir="rtl"] .font-display,
[dir="rtl"] h1, [dir="rtl"] h2, [dir="rtl"] h3, [dir="rtl"] h4, [dir="rtl"] h5, [dir="rtl"] h6,
[dir="rtl"] .menu-item {
  font-family: 'Beautique Latin', 'Almarai Display', 'Almarai', Georgia, serif;
}
/* Components that hard-code the Latin 'Attack' face: Latin runs keep Attack,
   Arabic falls through to Almarai. */
[dir="rtl"] .btn-primary,
[dir="rtl"] .btn-terra,
[dir="rtl"] .btn-white,
[dir="rtl"] .eyebrow,
[dir="rtl"] .nav-center,
[dir="rtl"] .nav-right,
/* Surfaces that hard-code 'Attack' with no Arabic face behind it. Without these
   the Arabic in each one had NO Arabic-capable font in its stack at all and fell
   through to the platform's last-resort face — SF Arabic on iOS (which is why it
   looked fine there) but Segoe UI / Noto Naskh on Windows / Android. */
[dir="rtl"] .lang-switch,
[dir="rtl"] .menu-cta,
[dir="rtl"] .btn-submit-cream,
[dir="rtl"] .contact-label,
[dir="rtl"] .map-pin,
[dir="rtl"] .interest-pill,
/* Declared in pulse.html's own <style> block, so it never went through the
   sitewide audit. [dir=rtl] + class (0,2,0) outranks the page rule (0,1,0). */
[dir="rtl"] .gallery-tab,
/* The DISPLAY selectors re-asserted in the block above. Each one now hard-codes
   the Latin 'Attack' face where it previously inherited from body, so without an
   entry here its Arabic would have had NO Arabic-capable font in the stack at
   all — the same last-resort-face bug documented directly above. The
   [class~="uppercase"] entry covers all 55 inline Tailwind all-caps sites at
   (0,2,0), which outranks the (0,1,0) LTR rule. */
[dir="rtl"] [class~="uppercase"],
[dir="rtl"] .menu-contact a,
[dir="rtl"] .btn-ghost,
[dir="rtl"] .btn-cream,
[dir="rtl"] .modal-field > label,
[dir="rtl"] .modal-checkbox span,
[dir="rtl"] .hero-scroll-label,
[dir="rtl"] .section-eyebrow,
[dir="rtl"] .intro-eyebrow,
[dir="rtl"] .acc-eyebrow,
[dir="rtl"] .image-caption-chip { font-family: 'Attack Latin', 'Almarai', system-ui, sans-serif; }

/* The same list, for the surfaces whose LTR counterpart moved to Inter: form
   fields the user types sentence case into, the contact value rows, and pulse's
   accordion body copy. Latin runs get Inter, Arabic falls through to Almarai. */
[dir="rtl"] .modal-input,
[dir="rtl"] .modal-box,
[dir="rtl"] .contact-value,
[dir="rtl"] .field-float input,
[dir="rtl"] .field-float textarea,
[dir="rtl"] .field-float select,
[dir="rtl"] .field-float label,
/* Also declared in pulse.html's own <style> block. */
[dir="rtl"] .acc-body { font-family: 'Inter Latin', 'Almarai', system-ui, sans-serif; }

/* about.html's heritage note carries font-family in an inline style attribute,
   which outranks every selector — !important is the only lever that reaches it.
   Scoped to this one element so no other inline font declaration is affected. */
[dir="rtl"] p[data-i18n="about.heritage"] { font-family: 'Inter Latin', 'Almarai', system-ui, sans-serif !important; }

/* ---- Arabic vertical rhythm ----
   Arabic script rides taller and drops deeper than the Latin display face, so
   the tight Latin leading used sitewide (leading-none, leading-[0.95..1.15] and
   inline line-height:1.15/1.25 on split headlines) makes Arabic lines collide.
   Give Arabic its own, roomier line-height. !important is deliberate: it must
   beat both the Tailwind leading-* utilities AND the inline style="line-height"
   on the hero / horizon / values headlines. Every rule is scoped to [dir="rtl"],
   so the English (LTR) layout is byte-for-byte unchanged. */
[dir="rtl"] h1, [dir="rtl"] h2, [dir="rtl"] h3,
[dir="rtl"] h4, [dir="rtl"] h5, [dir="rtl"] h6,
[dir="rtl"] .font-display { line-height: 1.4 !important; }

/* Eyebrows / small-caps labels: a touch of breathing room in case they wrap. */
[dir="rtl"] .eyebrow { line-height: 1.65 !important; }

/* ---- Arabic eyebrow weight: match the English eyebrows' visual pop ----
   In EN an eyebrow pops through TWO devices: Attack Medium (500) plus wide
   tracking (0.22–0.28em). Arabic gets neither — it is cursive, so it must never
   be letter-spaced (the sitewide `[dir="rtl"] * { letter-spacing: 0 !important }`
   rule below owns that and is deliberately left untouched), and Almarai ships
   only 300/400/700/800, so a 500 request snaps DOWN to Regular. The result was an
   Arabic eyebrow that read thinner than English while also losing all its
   tracking — visibly weak next to the Latin.
   Weight is the only lever left, so spend it: Almarai Bold (700) carries the same
   label authority the tracked Attack Medium does. 700 rather than the available
   800 — an eyebrow is a supporting label and must stay under the Athelas headline
   it introduces, and 700 is already a two-step jump from the 400 it was resolving
   to. Verified as a real loaded face, not a synthesized bold.
   COLOR IS DELIBERATELY NOT SET HERE — every eyebrow already declares its own
   (inline #B15533 in the footer / hero cards, .text-evora-terra on the section
   labels, the .eyebrow olive default on the quieter ones) and those apply in both
   directions, so each Arabic eyebrow already inherits its English counterpart's
   exact color. Forcing terracotta here would flatten the intentional olive tier.
   Size is untouched too (14/13px, tuned earlier) — this is weight only.
   Covers every eyebrow surface sitewide: the shared .eyebrow (incl. #hero's
   quieter tier and the modal label), the footer group headings, pulse's
   .section-eyebrow / .intro-eyebrow / .acc-eyebrow, and the four utility-built
   eyebrows (FLAGSHIP PROJECT, ON THE HORIZON ×2, LET'S CONNECT) which share the
   `p.font-medium.uppercase` signature. about.html's .hero-eyebrow is bolded in
   its own page <style>, where its existing [dir="rtl"] rule already lives. */
[dir="rtl"] .eyebrow,
[dir="rtl"] nav.footer-col > p,
[dir="rtl"] .section-eyebrow,
[dir="rtl"] .intro-eyebrow,
[dir="rtl"] .acc-eyebrow,
[dir="rtl"] p.font-medium.uppercase { font-weight: 700; }

/* ---- Arabic eyebrow optical size: the other half of the same problem ----
   The weight rule above lands (computed 700, real Almarai Bold, terracotta
   inherited) and it still read thin next to English — because weight was never
   the whole gap. An English eyebrow is UPPERCASE and tracked 0.24em, so 14px of
   Latin occupies a wide band of cap-height letterforms. Arabic has no case and
   must not be tracked, and Almarai's letterforms sit optically smaller at the
   same nominal px — so 14px of Arabic renders as a visibly quieter mark than
   14px of tracked Latin caps.
   Tracking is off the table permanently (see the [dir="rtl"] * letter-spacing
   rule below) and 700 is already the sensible weight ceiling for a supporting
   label, which leaves size as the honest lever.
   Re-measured against the EN reference with the fonts actually loaded, because
   the first pass (+2px -> 16px) still read quieter than English. The comparison
   that matters is INK, not nominal px: 14px Attack Medium sets all-caps, so its
   whole word is one solid 9.93px cap band. Almarai's baseline letter bodies
   (ح س م ن — the mass an Arabic reader actually sees) rise only 0.472em, so at
   16px they reach 7.55px — 76% of the English cap band. That 24% shortfall IS
   the "slightly smaller" everyone was seeing; the tall alef/lam strokes overshoot
   the cap line but they are hairlines and carry no mass.
   1.29x the English size is the setting where the two read as equals: 18px
   desktop (body band 8.50px) / 17px mobile off EN's 13px. Deliberately short of
   a literal ink match — that would need 21px, which would out-shout the Athelas
   headline the eyebrow introduces. Applied to every AR eyebrow surface — the
   same selector list as the weight rule — so the whole tier moves together
   rather than one-off patching. */
[dir="rtl"] .eyebrow,
[dir="rtl"] nav.footer-col > p,
[dir="rtl"] .section-eyebrow,
[dir="rtl"] .intro-eyebrow,
[dir="rtl"] .acc-eyebrow,
[dir="rtl"] p.font-medium.uppercase { font-size: 18px; }
@media (max-width: 767px) {
  [dir="rtl"] .eyebrow,
  [dir="rtl"] nav.footer-col > p,
  [dir="rtl"] .section-eyebrow,
  [dir="rtl"] .intro-eyebrow,
  [dir="rtl"] .acc-eyebrow,
  [dir="rtl"] p.font-medium.uppercase { font-size: 17px; }
  /* The footer group headings need a longer selector on mobile only: the phone
     footer block near the end of this file re-declares them at 13px through
     `.footer-evora nav.footer-col > p`, which ties the plain [dir="rtl"] variant
     on specificity (0,2,2) and wins on order — so AR footer headings were sitting
     out the optical bump on phones. One class deeper settles it. Desktop needs no
     equivalent: there the EN rule is the shorter `nav.footer-col > p`. */
  [dir="rtl"] .footer-evora nav.footer-col > p { font-size: 17px; }
}

/* The home hero brand line opts out of the eyebrow scale via an ID selector
   (#hero .eyebrow, above), which outranks the [dir="rtl"] .eyebrow rule — so it
   needs its own AR treatment at matching specificity. It keeps its quieter tier:
   the same 1.29x optical step off its own 12/11px base (not the section 18/17),
   so it still sits one clear step below them, and still the near-cream
   over-video color. */
[dir="rtl"] #hero .eyebrow { font-weight: 700; font-size: 15px; }
@media (max-width: 767px) { [dir="rtl"] #hero .eyebrow { font-size: 14px; } }

/* Athelas Arabic descenders (ع/ج/م tails, ق/ن bowls) reach ~0.37em below the
   baseline — deeper than Beautique's, which the EN 0.24em reveal-mask padding
   was tuned for. Open the mask further in AR; the negative margin cancels the
   padding in layout exactly like the base rule, so line spacing is unchanged. */
[dir="rtl"] .reveal-line { padding-bottom: 0.45em; margin-bottom: -0.45em; }

/* Arabic script has no italic: the .italic utility only synthesizes an oblique
   slant that mangles the joined letterforms (and made kept-Latin runs such as
   "DRN" read like a fallback face). Render those accents upright in AR — the
   color/weight treatment still carries the emphasis. EN keeps its true italics. */
[dir="rtl"] .italic { font-style: normal; }

/* Body copy reads better in Arabic with more leading (Emaar-style spacing). */
[dir="rtl"] p, [dir="rtl"] li { line-height: 1.9 !important; }

/* Arabic is cursive — letter-spacing splits the joins and stretches words apart.
   The Latin layout leans on tracked utilities (Tailwind tracking-*, inline
   letter-spacing) across nav, buttons, eyebrows, chips, the scroll cue and the
   pulse meta labels — every one of which becomes Arabic in RTL mode. The old rule
   only zeroed a handful of named selectors, so ~12–21 tracked Arabic elements per
   page were still spaced. Zero letter-spacing on ALL descendants under [dir="rtl"]
   so no Arabic is ever spaced; !important beats the tracking-* utilities and the
   inline letter-spacing on the hero scroll label. Harmless on the few Latin tokens
   kept in AR (Pulse, DRN, digits) — none of them rely on tracking. */
[dir="rtl"], [dir="rtl"] * { letter-spacing: 0 !important; }

/* ---- Phone numbers, tel: links and the hotline stay in LTR digit order ---- */
[dir="rtl"] [href^="tel:"],
[dir="rtl"] .footer-hotline,
[dir="rtl"] .footer-website { unicode-bidi: plaintext; }

/* ---- Navbar underline grows from the (visual) trailing edge ---- */
[dir="rtl"] .nav-link::after { left: auto; right: 0; }

/* ---- Mobile menu slides in from the left in RTL ---- */
/* Drawer mirrors in Arabic: inset-inline-end already flips it to the LEFT edge, so
   only the closed-state translate and the chevron direction need explicit mirroring
   (the chevron glyph itself is a right-pointing SVG, flipped with scaleX). */
[dir="rtl"] .mobile-menu { transform: translateX(-100%); }
[dir="rtl"] .menu-chev { transform: scaleX(-1); }
[dir="rtl"] .menu-item:active .menu-chev,
[dir="rtl"] .menu-item:focus-visible .menu-chev { transform: scaleX(-1) translateX(6px); }
@media (hover: hover) and (pointer: fine) {
  [dir="rtl"] .menu-item:hover .menu-chev { transform: scaleX(-1) translateX(6px); }
}
[dir="rtl"] .menu-close { margin-inline-end: -10px; }

/* ---- Global Tailwind physical-utility flips (used across pages) ---- */
[dir="rtl"] .text-left  { text-align: right; }
[dir="rtl"] .text-right { text-align: left; }

/* ---- Pulse floating action sidebar mirrors to the LEFT edge ---- */
[dir="rtl"] #pulseSidebar {
  right: auto; left: 0;
  border-radius: 0 1rem 1rem 0;   /* was rounded-l-2xl (right edge); now rounded on the inner (right) edge */
}

/* ---- Physical Tailwind utilities that dir="rtl" does NOT auto-mirror ----
   Only the classes actually used across the pages are listed. Centering pairs
   (left-1/2 + -translate-x-1/2) are deliberately left alone. Responsive
   variants are mirrored only inside their own breakpoint so LTR-at-other-widths
   is never affected. */
[dir="rtl"] .text-left,
[dir="rtl"] .sm\:text-left { text-align: right; }
[dir="rtl"] .text-right { text-align: left; }

[dir="rtl"] .pl-6 { padding-left: 0; padding-right: 1.5rem; }

[dir="rtl"] .left-0  { left: auto;  right: 0; }
[dir="rtl"] .right-0 { right: auto; left: 0; }
[dir="rtl"] .left-3  { left: auto;  right: 0.75rem; }
[dir="rtl"] .right-3 { right: auto; left: 0.75rem; }
[dir="rtl"] .right-5 { right: auto; left: 1.25rem; }

@media (min-width: 640px) {
  [dir="rtl"] .sm\:-ml-2 { margin-left: 0; margin-right: -0.5rem; }
}
@media (min-width: 768px) {
  [dir="rtl"] .md\:left-6  { left: auto;  right: 1.5rem; }
  [dir="rtl"] .md\:right-6 { right: auto; left: 1.5rem; }
}
@media (min-width: 1024px) {
  [dir="rtl"] .lg\:pr-10   { padding-right: 0; padding-left: 2.5rem; }
  [dir="rtl"] .lg\:pl-20   { padding-left: 0; padding-right: 5rem; }
  [dir="rtl"] .lg\:border-l { border-left-width: 0; border-right-width: 1px; }
}

/* ---- Page-specific absolute copy blocks & decorative anchors ---- */
[dir="rtl"] .about-hero-copy    { left: auto; right: 0; }
[dir="rtl"] .image-caption-chip { left: auto; right: 1rem; }
[dir="rtl"] .hero-scroll { right: auto; left: 22px; }
@media (min-width: 768px) { [dir="rtl"] .hero-scroll { left: 34px; } }

/* ============================================================
   MOBILE FOOTER (≤767px) — compact, structured layout.
   The sitewide footer's Tailwind grid stacks its groups in one very tall
   column on phones. Here we override ONLY the ≤767px layout into a proper
   compact footer:
     Brand (tagline, hotline — full width, top; logo hidden, see below)
     EXPLORE  |  PROJECTS            ← row 1 of the link grid
     LEGAL                           ← row 2
     ── divider ──
     socials (centred) + copyright (centred), outside .footer-band2
   TWO columns, not three: at 375px a third-width column is ~110px, which
   forced "Pulse Medical Hub", "Terms & Conditions" and "Privacy Policy" to
   wrap onto two lines each. Half-width columns fit every link on one line.
   Desktop/tablet (≥768px) is untouched. Logical properties + grid
   auto-mirroring keep it RTL-safe; the higher-specificity
   `.footer-evora …` selectors win over the single-class utilities. */
@media (max-width: 767px) {
  .footer-evora > div { padding-top: 3rem; }          /* was pt-16 (4rem) */

  .footer-evora .footer-band2 {
    grid-template-columns: repeat(2, 1fr);             /* EXPLORE | PROJECTS, then LEGAL */
    column-gap: 1.5rem;                                /* two columns can breathe */
    row-gap: 2.5rem;                                   /* gap-y-10 between link rows */
    padding-bottom: 2rem;                              /* tighter than pb-10 */
  }
  /* Brand — full width, top row */
  .footer-evora .footer-band2 > :nth-child(1) { grid-column: 1 / -1; grid-row: 1; }
  /* EXPLORE | PROJECTS on row 2, LEGAL alone on row 3 */
  .footer-evora .footer-band2 > :nth-child(2) { grid-column: 1; grid-row: 2; }
  .footer-evora .footer-band2 > :nth-child(3) { grid-column: 2; grid-row: 2; }
  .footer-evora .footer-band2 > :nth-child(4) { grid-column: 1; grid-row: 3; }

  /* Trim the group-heading gap a touch for a tighter rhythm */
  .footer-evora .footer-col > p { margin-bottom: 0.75rem; }

  /* Links read at 15px on mobile (desktop stays text-sm/14px). Row rhythm is NOT
     set here — the single sitewide `.footer-evora nav.footer-col > ul` rule above
     owns the row-gap at both breakpoints so the three columns can't drift apart. */
  .footer-evora .footer-col ul { font-size: 15px; line-height: 1.3; }
  .footer-evora .footer-col > p { font-size: 9px; letter-spacing: 0.14em; }
  /* Group headings (EXPLORE/PROJECTS/LEGAL/CONTACT) match the sitewide 13px
     mobile eyebrow scale; tracking a hair tighter than the sitewide 0.24em so
     the longest heading (PROJECTS) keeps clear margin in its third-width column
     at 375px. Brand tagline stays at 9px. */
  .footer-evora nav.footer-col > p { font-size: 13px; letter-spacing: 0.22em; }

  /* Brand tagline — it is a sentence of body copy, not a group label, so the 9px
     rule above (meant for the uppercase column headings) left it unreadable on a
     phone. Lift it back to the desktop body size. Desktop is untouched. */
  .footer-evora .footer-brand > p[data-i18n="footer.brand.tagline"] {
    font-size: 14px; line-height: 1.6; letter-spacing: normal; margin-bottom: 0;
  }

  /* The social row is CENTRED on mobile now (the bottom bar is flex-col-reverse
     items-center), so the old -0.625rem optical pull toward the left content edge
     would throw it visibly off-centre. Zero it out; ≥768px never had it. */
  .footer-evora .footer-social { margin-inline-start: 0; }

  /* Mobile only: drop the footer brand logo (tagline/website/links stay).
     Scoped to the footer so the header logo is unaffected. */
  .footer-evora .nav-logo { display: none; }
}

/* ============================================================
   MOBILE (≤767px) — REGISTER INTEREST MODAL DENSITY
   ============================================================
   Desktop spacing (p-10, space-y-5, mb-8 under the intro) makes the panel run
   well past a phone screen. Tighten the heading block, the field rhythm and
   the control padding so the whole form — crest through Submit — fits without
   cramping. Fields, country selector, checkbox, submit and every name=""
   attribute are untouched; this is spacing only. ≥768px unchanged. */
@media (max-width: 767px) {
  .modal-backdrop .modal-panel {
    padding: 24px 22px 26px !important;                /* was p-8 (32px) */
    margin-top: 3vh !important;                        /* was my-[6vh] */
    margin-bottom: 3vh !important;
    max-height: 94vh !important;                       /* was 88vh */
  }
  /* Yew crest */
  #modal .modal-panel > .mb-5 { margin-bottom: 12px !important; }
  #modal .modal-panel > .eyebrow { margin-bottom: 8px !important; }
  #modal .modal-panel > h3 { font-size: 1.75rem !important; margin-bottom: 6px !important; }
  #modal .modal-panel > p[data-i18n="modal.body"] {
    margin-bottom: 18px !important; line-height: 1.5 !important;
  }
  /* Field rhythm: space-y-5 (20px) → 13px, and the same for the 3-col row gap */
  #registerForm > * + * { margin-top: 13px !important; }
  #registerForm .grid { gap: 10px !important; }
  #modal .modal-field > label { margin-bottom: 5px !important; }
  #modal .modal-box { padding: 11px 13px !important; }
  #modal .modal-checkbox { padding-top: 4px !important; }
  #modal .btn-submit-cream { margin-top: 8px !important; padding: 14px 24px !important; }
  /* Close X reads a touch larger on a phone — matches the drawer's 26px */
  .modal-close svg { width: 26px; height: 26px; }
}

/* ============================================================================
   ARABIC FIRST-PAINT GUARD
   ----------------------------------------------------------------------------
   Every translatable node ships its English string as markup; scripts.js swaps
   in the AR dictionary from applyLang(), which runs at DOMContentLoaded — long
   after the browser has painted that English text. On an AR page that showed as
   a one-frame flash of English under the Arabic-ready layout (the <head>
   bootstrap sets dir="rtl" synchronously, so only the WORDS were wrong).

   The bootstrap now also stamps html.ar-pending, and this rule holds the
   translated nodes invisible until applyLang() clears it. visibility (not
   display) keeps every box in flow, so nothing reflows when the text lands.

   Fail-safes, both of which reveal English rather than a blank page:
     · the bootstrap self-clears the class after 2s if scripts.js never runs;
     · .no-js pages never get the class applied at all.
   ========================================================================== */
html.ar-pending [data-i18n],
html.ar-pending [data-i18n-html] { visibility: hidden; }
