/* AAA — Ali Bin Hassan Bin Mohammed For Accounting & Auditing
   Direction D "Vault" — production stylesheet */

:root {
  --ink:      #04120E;
  --ink-2:    #061A14;
  --ink-3:    #020C09;
  --green:    #04513E;
  --green-2:  #093C2E;
  --gold:     #B3A78C;
  --gold-lt:  #E4D9BE;
  --paper:    #EEF2EF;
  --line:     rgba(179,167,140,.18);
  --line-2:   rgba(179,167,140,.32);
  --glass:    rgba(238,242,239,.045);
  --glass-2:  rgba(238,242,239,.075);
  --t1: 'Sora', 'IBM Plex Sans Arabic', system-ui, sans-serif;
  --t2: 'IBM Plex Sans', 'IBM Plex Sans Arabic', system-ui, sans-serif;
  --wrap: 1340px;
  --pad: clamp(20px, 3.6vw, 52px);
  --sec: clamp(52px, 7.5vw, 130px);
  --r: 22px;
}

* { box-sizing: border-box; }
/* `clip` rather than `hidden`: it clips just as reliably (including on iOS, where
   overflow-x: hidden on the body is famously leaky) but does not create a scroll
   container, so `position: sticky` on the header keeps working. `hidden` is
   declared first as the fallback for browsers without `clip`. */
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; overflow-x: clip; }
/* js/aaa.js sets this when it takes over scrolling. Native smooth behaviour and
   the scripted easing fight each other, so only one may be active at a time. */
html.smooth-js { scroll-behavior: auto; }
body {
  margin: 0; background: var(--ink); color: var(--paper);
  font-family: var(--t2); font-weight: 300; font-size: 16px; line-height: 1.6;
  -webkit-font-smoothing: antialiased; overflow-x: hidden; overflow-x: clip;
}
/* ---------- page loader ----------
   The AAA mark written stroke by stroke, then the screen splits open on it.

   Every step is a CSS animation ending in `forwards`, so the loader completes and
   uncovers the page whether or not js/aaa.js ever runs. That is not defensiveness
   for its own sake: script-src is 'self', so no inline script can run before paint,
   and a loader that waited for the deferred bundle to clear it would leave a blank
   screen on any script error. The script only enriches this: it counts the digits
   and swaps in the short version on later pages.

   Timeline, first visit:
     0.00  strokes begin, one every .13s, .72s each   -> last lands at 1.11
     0.00  meter fills over 1.50s
     1.72  mark and meter fade out over .34s
     1.82  panels part, .92s
     2.74  the whole layer goes visibility:hidden */
.preload {
  position: fixed; inset: 0; z-index: 3000; pointer-events: none;
  animation: pl-done 1ms linear 2.74s forwards;
}
.preload-panel {
  position: absolute; inset-inline: 0; height: 50.5%;
  background: var(--ink);
  animation-duration: .92s; animation-delay: 1.82s;
  animation-timing-function: cubic-bezier(.76, 0, .24, 1);
  animation-fill-mode: forwards;
}
/* 101%, not 100%: a fractional viewport height leaves a hairline of the panel on
   screen at exactly 100%. */
.preload-panel--t { top: 0;    animation-name: pl-part-t; }
.preload-panel--b { bottom: 0; animation-name: pl-part-b; }
@keyframes pl-part-t { to { transform: translateY(-101%); } }
@keyframes pl-part-b { to { transform: translateY(101%); } }

.preload-core {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(20px, 3vw, 34px);
  animation: pl-core-out .34s var(--e2) 1.72s forwards;
}
@keyframes pl-core-out { to { opacity: 0; transform: scale(.96); } }

.preload-mark { width: min(380px, 58vw); height: auto; overflow: visible; }
/* The reveal. Each stroke has its own clip rectangle, parked above the artwork and
   slid down across it, so the stroke arrives crown first the way it would be
   drawn. Staggered left to right, which is also the order the strokes ascend. */
.pl-wipe {
  transform: translateY(-824px);
  animation: pl-write .72s var(--e1) forwards;
  animation-delay: calc(var(--i) * .13s);
}
@keyframes pl-write { to { transform: translateY(0); } }
/* Arabic pages write the strokes right to left. */
[dir="rtl"] .pl-wipe { animation-delay: calc((3 - var(--i)) * .13s); }

.preload-meter {
  position: relative; width: min(220px, 44vw); height: 1px;
  background: var(--line-2); overflow: hidden;
}
.preload-meter > i {
  position: absolute; inset-block: 0; inset-inline-start: 0; width: 100%;
  background: var(--gold-lt); transform-origin: left center;
  transform: scaleX(0); animation: pl-meter 1.5s var(--e2) forwards;
}
[dir="rtl"] .preload-meter > i { transform-origin: right center; }
@keyframes pl-meter { to { transform: scaleX(1); } }

.preload-count {
  font-family: var(--t1); font-variant-numeric: tabular-nums;
  font-size: 11px; font-weight: 500; letter-spacing: .3em;
  color: rgba(238,242,239,.42);
  /* The digits are written by js/aaa.js. Latin figures on both language versions,
     matching the rest of the site. */
  direction: ltr;
}
/* Both ends hidden, deliberately. `to { visibility: hidden }` alone does nothing:
   the implied start is the underlying `visible`, and CSS gives visibility a
   special interpolation in which any pairing with `visible` stays visible, so the
   layer sat in the render tree forever. With no visible endpoint there is nothing
   to interpolate, and fill-mode forwards holds it hidden. The animation-delay
   still does the timing: fill is forwards only, so nothing applies until it
   elapses. */
@keyframes pl-done { from, to { visibility: hidden; } }

/* Second and later pages in the same visit. Nobody wants to watch the full
   sequence on every click, so the script marks the layer and it simply lifts. */
.preload.is-quick { animation: pl-done 1ms linear .42s forwards; }
.preload.is-quick .preload-panel { animation: pl-fade .42s var(--e2) forwards; }
.preload.is-quick .preload-core  { animation: pl-fade .3s var(--e2) forwards; }
.preload.is-quick .pl-wipe { animation-delay: 0s; animation-duration: .3s; }
.preload.is-quick .preload-meter { opacity: 0; }
@keyframes pl-fade { to { opacity: 0; } }

/* Cleared outright: bfcache restores, or the script deciding the loader has no
   business being up. Not display:none on .preload itself, which would kill a
   running animation mid-way and flash the panels back. */
.preload.is-off { display: none; }

/* ---------- between pages ----------
   Covers the outgoing page so the browser's own blank frame never shows. Wipes up
   from the bottom edge, and the arriving page's loader lifts in the same
   direction, so the two read as one movement. */
.pagewipe {
  position: fixed; inset: 0; z-index: 2900; pointer-events: none;
  background: var(--ink); visibility: hidden;
  clip-path: inset(100% 0 0 0);
}
.pagewipe.on {
  visibility: visible;
  clip-path: inset(0 0 0 0);
  transition: clip-path .5s cubic-bezier(.76, 0, .24, 1);
}

img { max-width: 100%; display: block; }
a { color: var(--gold); text-decoration: none; transition: color .25s; }
a:hover { color: var(--gold-lt); }
h1, h2, h3, h4 { font-family: var(--t1); font-weight: 500; letter-spacing: -.035em; line-height: 1.06; margin: 0; color: #fff; }
p { margin: 0; text-wrap: pretty; }
::selection { background: var(--gold); color: var(--ink); }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
[dir="rtl"] { font-family: var(--t2); }

/* ---------- Arabic micro-labels ----------
   The small caps-style labels are set at 9 to 10.5px with wide letter-spacing,
   which is a Latin convention. Arabic has no uppercase, and tracking actively
   breaks the script: it pulls apart letters that must stay joined. So every
   label of this family loses its tracking and gains a couple of pixels, because
   Arabic needs more height than Latin to stay legible at the same optical size. */
[dir="rtl"] .eyebrow,
[dir="rtl"] .mono,
[dir="rtl"] .label,
[dir="rtl"] .foot-h,
[dir="rtl"] .foot-c .k,
[dir="rtl"] .stat span,
[dir="rtl"] .field > span,
[dir="rtl"] .contact-row .k,
[dir="rtl"] .fig .ph span {
  letter-spacing: 0;
  text-transform: none;
}
/* ---------- Arabic headings ----------
   The Latin display settings do not transfer. Negative tracking crushes a joined
   script, and a 1.02 line-height lets the deep descenders of one line collide
   with the next, which is what made the hero read as interlocking. Several
   headings carry these values inline, hence !important. */
[dir="rtl"] :is(h1, h2, h3, h4),
[dir="rtl"] :is(.h-xl, .h-lg, .h-md, .h-sm) {
  letter-spacing: 0 !important;
  line-height: 1.3 !important;
}
/* The word-reveal mask clips at the element box. .06em of room below the
   baseline is enough for Latin descenders and nowhere near enough for the tails
   of و ح م ن ي, which were being sliced off. */
[dir="rtl"] .sw { padding-block-end: .26em; margin-block-end: -.26em; }
[dir="rtl"] .stat b { letter-spacing: 0; line-height: 1.28; }

[dir="rtl"] .eyebrow { font-size: 13px; }
[dir="rtl"] .foot-h { font-size: 12.5px; line-height: 1.5; }
[dir="rtl"] .foot-c .k { font-size: 12px; line-height: 1.5; margin-bottom: 6px; }
[dir="rtl"] .stat span,
[dir="rtl"] .field > span,
[dir="rtl"] .contact-row .k { font-size: 12.5px; line-height: 1.6; }
[dir="rtl"] .foot-list a { font-size: 15px; line-height: 1.7; }
[dir="rtl"] .foot-bar { font-size: 13px; line-height: 1.7; }

/* Phone, email and web address stay left-to-right internally, which is correct,
   but that also left-aligns them inside a right-aligned Arabic column. Pin them
   back to the column edge so each value sits under its own label. */
[dir="rtl"] .foot-c .v.ltr-num,
[dir="rtl"] .foot-c .v { text-align: right; }
.wrap { max-width: var(--wrap); margin: 0 auto; padding-inline: var(--pad); }
.sec { padding-block: var(--sec); }
.sec-alt { background: var(--ink-2); border-block: 1px solid var(--line); }
/* The skip link used to be parked at `left: -9999px`. In a left-to-right page
   that is harmlessly off-screen, but in RTL (Right To Left) the scroll origin is
   the right edge, so it extended the scrollable area by 9999px and every Arabic
   page could be dragged sideways into empty space. Clipped to a 1px box instead,
   which is off-screen in both directions. */
.skip {
  position: absolute;
  /* Physical top/left, deliberately not logical. An unpositioned absolute element
     starts at the inline-start edge, which is the RIGHT edge in Arabic, and even
     `inset-inline-start: 0` resolves to that right edge, landing outside the
     client area whenever a scrollbar takes layout width. `left: 0` is inside the
     page in both directions and can never extend the scrollable area. */
  top: 0; left: 0; right: auto;
  width: 1px; height: 1px; margin: 0; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.skip:focus {
  position: fixed; inset-block-start: 12px; inset-inline-start: 12px;
  width: auto; height: auto; margin: 0; overflow: visible; clip-path: none;
  z-index: 999; background: var(--gold); color: var(--ink);
  padding: 10px 16px; border-radius: 999px;
}

/* ---------- header ---------- */
.topbar { background: var(--ink-3); border-bottom: 1px solid var(--line); font-size: 12px; color: rgba(238,242,239,.6); }
.topbar .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding-block: 9px; }
.topbar-info { display: flex; gap: clamp(12px, 2vw, 28px); align-items: center; flex-wrap: wrap; }
.topbar a { color: rgba(238,242,239,.6); }
.topbar a:hover { color: var(--gold); }
.ltr-num { direction: ltr; unicode-bidi: embed; }
/* Bilingual toggle carried over from the previous site: one bordered square
   holding ع and A. The character for the language you would switch TO is the lit
   one, so the control reads as an action rather than a status label. */
.langsw { display: flex; align-items: center; flex: 0 0 auto; }
.langsw .langicon {
  display: grid; place-items: center;
  width: 32px; height: 32px; border-radius: 9px;
  border: 1px solid rgba(179,167,140,.3);
  transition: background .3s var(--e2), border-color .3s var(--e2), transform .2s var(--e2);
}
.langsw .langicon:hover { background: rgba(179,167,140,.12); border-color: var(--gold); }
.langsw .langicon:active { transform: scale(.94); }
.langsw .lg {
  display: flex; align-items: center; gap: 1.5px;
  font-family: var(--t1); font-size: 13px; font-weight: 600; line-height: 1;
  /* Pinned so the pair always reads ع then A. Left to inherit, the flex order
     flips under RTL and the same mark renders two different ways. */
  direction: ltr;
}
.langsw .lg .t { color: var(--gold-lt); }
.langsw .lg .o { color: rgba(238,242,239,.4); transition: color .3s var(--e2); }
.langsw .langicon:hover .lg .o { color: rgba(238,242,239,.72); }

.site-head { position: sticky; top: 0; z-index: 500; padding: clamp(10px, 1.6vw, 20px) var(--pad); background: linear-gradient(180deg, rgba(4,18,14,.94), rgba(4,18,14,.6) 70%, rgba(4,18,14,0)); backdrop-filter: blur(6px); }
.navbar {
  max-width: var(--wrap); margin: 0 auto;
  padding: 10px 12px 10px clamp(14px, 1.6vw, 22px);
  border-radius: 999px; background: rgba(238,242,239,.055);
  backdrop-filter: blur(20px) saturate(140%); border: 1px solid rgba(179,167,140,.2);
  display: flex; align-items: center; gap: clamp(10px, 1.8vw, 30px);
}
.brand { flex: 0 0 auto; display: flex; align-items: center; }
.brand img { height: clamp(28px, 3vw, 40px); width: auto; }
.nav { display: flex; align-items: center; gap: clamp(4px, .9vw, 14px); margin-inline-start: auto; }
.nav a {
  font-family: var(--t1); font-size: clamp(11px, .92vw, 13px); font-weight: 400;
  color: rgba(238,242,239,.62); padding: 8px 11px; border-radius: 999px; white-space: nowrap;
  transition: color .25s, background .25s;
}
.nav a:hover { color: #fff; background: rgba(238,242,239,.07); }
.nav a[aria-current="page"] { color: #fff; font-weight: 600; background: rgba(179,167,140,.18); }
.btn-nav { flex: 0 0 auto; }
.navtoggle { display: none; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--t1); font-size: 13px; font-weight: 600; border-radius: 999px;
  padding: 17px 32px; border: 0; cursor: pointer; white-space: nowrap;
  transition: transform .25s, background .25s, border-color .25s, color .25s;
}
.btn-gold { background: var(--gold); color: var(--ink); box-shadow: 0 18px 44px -16px rgba(179,167,140,.5); }
.btn-gold:hover { background: var(--gold-lt); color: var(--ink); transform: translateY(-2px); }
.btn-ghost { border: 1px solid rgba(238,242,239,.24); background: rgba(238,242,239,.05); color: var(--paper); }
.btn-ghost:hover { background: rgba(238,242,239,.12); border-color: var(--line-2); color: #fff; }
.btn-sm { padding: 12px 22px; font-size: clamp(11px, .95vw, 12.5px); box-shadow: none; }

/* ---------- type helpers ---------- */
.eyebrow { font-size: 10.5px; letter-spacing: .22em; text-transform: uppercase; color: rgba(179,167,140,.9); }
.h-xl { font-size: clamp(38px, 6vw, 96px); letter-spacing: -.04em; line-height: 1.02; }
.h-lg { font-size: clamp(36px, 5.2vw, 84px); letter-spacing: -.04em; line-height: 1.01; }
.h-md { font-size: clamp(28px, 3.4vw, 52px); }
.h-sm { font-size: clamp(24px, 3vw, 42px); letter-spacing: -.032em; }
.lead { font-size: clamp(15px, 1.35vw, 20px); line-height: 1.7; color: rgba(238,242,239,.7); }
.body { font-size: clamp(14.5px, 1.15vw, 17px); line-height: 1.84; color: rgba(238,242,239,.72); }
.numeral { font-family: var(--t1); font-weight: 200; line-height: 1; color: rgba(179,167,140,.4); }
/* At 40px and up a numeral is a decorative mark and .4 alpha reads fine. The
   small ordinals on the industry cards are set at 13px, where that same alpha
   measures 2.23:1 and is genuinely hard to read, so they get real contrast. */
.numeral[style*="font-size:13px"] { color: rgba(179,167,140,.85); font-weight: 400; letter-spacing: .06em; }
.measure { max-width: 60ch; }
.measure-sm { max-width: 46ch; }

/* ---------- hero ---------- */
.hero { position: relative; overflow: hidden; min-height: clamp(520px, 84svh, 900px); display: flex; align-items: center; }
.hero-glow { position: absolute; inset: 0; pointer-events: none; background:
  radial-gradient(90% 70% at 72% 30%, rgba(4,81,62,.55) 0%, rgba(4,18,14,0) 62%),
  radial-gradient(70% 60% at 10% 90%, rgba(179,167,140,.13) 0%, rgba(4,18,14,0) 70%); }
.hero-3d { position: absolute; inset-inline-end: -12%; top: 46%; transform: translateY(-50%); width: clamp(360px, 56vw, 900px); height: clamp(360px, 46vw, 720px); pointer-events: none; }
.hero .wrap { position: relative; z-index: 3; width: 100%; padding-block: clamp(60px, 9vw, 130px); }
.hero-copy { max-width: 760px; }
.badge { display: inline-flex; align-items: center; gap: 10px; padding: 8px 15px; border-radius: 999px; border: 1px solid var(--line-2); background: rgba(179,167,140,.08); }
.badge .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--gold); animation: glow 2.6s ease-in-out infinite; }
.btnrow { display: flex; flex-wrap: wrap; gap: 12px; }
.statrow { display: flex; flex-wrap: wrap; gap: 12px; }
.stat { padding: clamp(14px, 1.8vw, 22px) clamp(20px, 2.4vw, 30px); border-radius: 16px; background: var(--glass); border: 1px solid var(--line); backdrop-filter: blur(10px); }
.stat b { display: block; font-family: var(--t1); font-size: clamp(22px, 2.4vw, 34px); font-weight: 600; letter-spacing: -.03em; line-height: 1; color: #fff; }
.stat span { display: block; font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase; color: rgba(179,167,140,.9); margin-top: 9px; }

.page-head { position: relative; overflow: hidden; padding-block: clamp(56px, 8vw, 130px); }
.page-head.g1 { background: radial-gradient(80% 90% at 78% 10%, rgba(4,81,62,.5), rgba(4,18,14,0) 65%); }
.page-head.g2 { background: radial-gradient(80% 90% at 22% 10%, rgba(4,81,62,.5), rgba(4,18,14,0) 65%); }
.page-head.g3 { background: radial-gradient(80% 90% at 55% 10%, rgba(4,81,62,.5), rgba(4,18,14,0) 65%); }
.page-head.g4 { background: radial-gradient(90% 100% at 50% 100%, rgba(4,81,62,.5), rgba(4,18,14,0) 68%); }
/* Not scoped to .page-head any more: Contact and Complaints keep their split
   layout, so they host the relief on the section itself via .has-3d. */
.head-3d { position: absolute; inset-inline-end: 2%; top: 50%; transform: translateY(-50%); width: clamp(240px, 34vw, 560px); height: clamp(220px, 26vw, 420px); opacity: .5; pointer-events: none; }
.has-3d { position: relative; overflow: clip; }
/* Quieter behind a form, where it sits under real content rather than beside it. */
.has-3d .head-3d { opacity: .3; }

/* ---------- grids & cards ---------- */
.grid { display: grid; gap: clamp(14px, 1.8vw, 24px); }
/* min(<floor>, 100%) is the guard: a bare minmax(290px, 1fr) forces every track
   to be at least 290px even when the container is only 280px wide, which pushes
   the whole grid past the viewport on a 320px phone. */
.g-2 { grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr)); }
.g-3 { grid-template-columns: repeat(auto-fit, minmax(min(270px, 100%), 1fr)); }
.split { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr)); gap: clamp(28px, 4.6vw, 80px); align-items: center; }
.split > * { min-width: 0; }
.split-top { align-items: start; }
.card { border-radius: var(--r); background: var(--glass); border: 1px solid var(--line); padding: clamp(22px, 2.8vw, 44px); }
/* Card titles in a row are levelled by js/aaa.js, not here: a fixed min-height
   reserves space even when every title is one line, which just opens a gap. The
   script measures the tallest title actually in each row and matches the rest. */
.card-hov { transition: border-color .3s, background .3s, transform .3s; }
.card-hov:hover { border-color: rgba(179,167,140,.55); background: var(--glass-2); transform: translateY(-4px); }

/* Was `justify-content: space-between`, which pinned the eyebrow to the top and
   the link to the bottom but left the title floating on whatever space was left
   over. Across four cards that put the four titles on four different lines. Now
   the content stacks from the top and only the link is pushed down, so the
   eyebrows, titles and links each line up across the row. */
.svc { position: relative; overflow: hidden; min-height: clamp(250px, 26vw, 340px); display: flex; flex-direction: column; justify-content: flex-start; gap: 24px; color: var(--paper); }
.svc > .more { margin-block-start: auto; }
.svc .ghost { position: absolute; inset-inline-end: clamp(14px, 2vw, 28px); top: clamp(4px, 1vw, 12px); font-family: var(--t1); font-size: clamp(56px, 7vw, 110px); font-weight: 200; line-height: 1; color: rgba(179,167,140,.13); pointer-events: none; }
.svc > * { position: relative; }
.svc h3 { font-size: clamp(19px, 2vw, 29px); letter-spacing: -.028em; line-height: 1.12; margin-bottom: 14px; }
.svc p { font-size: 14px; line-height: 1.7; color: rgba(238,242,239,.66); }
.svc .more { font-family: var(--t1); font-size: 12px; font-weight: 500; display: inline-flex; align-items: center; gap: 10px; color: var(--gold); }
.svc:hover .more { color: var(--gold-lt); }

.rows { border-top: 1px solid var(--line); }
.row {
  display: grid; grid-template-columns: clamp(50px, 6vw, 96px) minmax(0, 1fr) minmax(0, 1.15fr) auto;
  gap: clamp(14px, 2.6vw, 38px); align-items: center;
  padding: clamp(20px, 2.6vw, 34px) clamp(6px, 1.2vw, 18px);
  border-bottom: 1px solid rgba(179,167,140,.14); transition: background .3s;
}
.row:hover { background: rgba(238,242,239,.05); }
.row .n { font-family: var(--t1); font-size: clamp(18px, 2vw, 30px); font-weight: 200; color: rgba(179,167,140,.55); }
.row h3 { font-size: clamp(16px, 1.7vw, 24px); letter-spacing: -.026em; line-height: 1.16; }
.row p { font-size: 13.5px; line-height: 1.66; color: rgba(238,242,239,.58); }
.row .go { width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--line-2); display: grid; place-items: center; font-size: 14px; color: var(--gold); }

.bullets { display: flex; flex-direction: column; }
/* minmax(0, 1fr), not 1fr: a bare 1fr track will not shrink below the widest
   word it contains, so long service lines pushed the card past the screen. */
.bullets li { display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 12px; align-items: baseline; padding: 12px 0; border-bottom: 1px solid rgba(179,167,140,.14); list-style: none; }
.bullets span { overflow-wrap: break-word; }
.bullets { margin: 0; padding: 0; }
.bullets .n { font-family: var(--t1); font-size: 11px; color: rgba(179,167,140,.8); }
.bullets span { font-size: 14.5px; line-height: 1.62; color: rgba(238,242,239,.86); }

/* ---------- image placeholders / photos ---------- */
.fig { position: relative; border-radius: var(--r); overflow: hidden; border: 1px solid rgba(179,167,140,.25); background: linear-gradient(150deg, rgba(9,60,46,.6), rgba(4,18,14,.9)); }
.fig img { width: 100%; height: 100%; object-fit: cover; }
/* A frame holding a real photograph. The image is cut 16% taller than its frame
   and sits 8% high, so the scroll parallax can slide it +/-8% without ever
   exposing an edge. js/aaa.js drives the transform. */
.fig[data-parallax] img {
  position: absolute; inset-inline: 0; inset-block-start: -8%;
  width: 100%; height: 116%;
  will-change: transform;
  transform: translate3d(0, 0, 0);
}
.fig-4x5 { aspect-ratio: 4 / 5; }
.fig-3x2 { aspect-ratio: 3 / 2; }
.fig-16x10 { aspect-ratio: 16 / 10; }
/* The aerial render carries fine detail and the pin marking the office. A
   16:10 window suits it on a wide screen; on a phone the frame is only a few
   hundred pixels across, so it opens out to the artwork's own ratio and crops
   nothing. Its own class rather than an override on .fig-16x10, which the
   Industries page uses four times. */
.fig-aerial { aspect-ratio: 16 / 10; }
@media (max-width: 700px) { .fig-aerial { aspect-ratio: 1424 / 1104; } }
.fig-21x9 { aspect-ratio: 21 / 9; }
.fig .ph { position: absolute; inset: 0; display: grid; place-content: center; gap: 10px; text-align: center; padding: 24px; }
.fig .ph span { font-size: 10px; letter-spacing: .18em; text-transform: uppercase; color: rgba(179,167,140,.75); }
.fig .ph em { font-style: normal; font-size: 13px; color: rgba(238,242,239,.45); }

/* ---------- contact channels & map ---------- */
.chan-ico {
  display: grid; place-items: center; width: 44px; height: 44px;
  border-radius: 13px; border: 1px solid var(--line-2); color: var(--gold);
  margin-bottom: clamp(16px, 2.2vw, 26px);
  transition: background .35s var(--e2), color .35s var(--e2), border-color .35s var(--e2), transform .5s var(--e3);
}
.card-hov:hover .chan-ico { background: var(--gold); color: var(--ink); border-color: var(--gold); transform: translateY(-3px) rotate(-5deg); }
.chan-ico svg { width: 21px; height: 21px; display: block; }
.chan-note { font-size: 13px; color: rgba(238,242,239,.55); margin-top: 10px; }

/* Google's embed is a light map. Inverting and rotating the hue lands it in the
   same dark register as the rest of the site without shipping a tile API key. */
.mapframe {
  position: relative; border-radius: var(--r); overflow: hidden;
  border: 1px solid var(--line-2); background: var(--ink-2); aspect-ratio: 21 / 9;
}
.mapframe iframe {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
  filter: invert(91%) hue-rotate(180deg) saturate(.7) contrast(.95);
}
@media (max-width: 860px) { .mapframe { aspect-ratio: 4 / 3; } }

/* ---------- forms ---------- */
.form { border-radius: 24px; background: rgba(238,242,239,.05); border: 1px solid rgba(179,167,140,.2); padding: clamp(24px, 3.2vw, 48px); }
.field { display: block; margin-bottom: 16px; }
.field > span { display: block; font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: rgba(238,242,239,.55); margin-bottom: 8px; }
.field input, .field textarea {
  width: 100%; padding: 13px 15px; border-radius: 12px; border: 1px solid rgba(179,167,140,.22);
  background: rgba(4,18,14,.5); font-family: var(--t2); font-size: 15px; color: var(--paper); outline: none;
  transition: border-color .25s;
}
.field textarea { resize: vertical; min-height: 118px; }
.field input:focus, .field textarea:focus { border-color: rgba(179,167,140,.7); }
.field input::placeholder, .field textarea::placeholder { color: rgba(238,242,239,.3); }
.contact-row { border-radius: 18px; background: var(--glass); border: 1px solid var(--line); padding: clamp(16px, 2vw, 24px) clamp(20px, 2.4vw, 28px); display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap; }
.contact-row .k { font-size: 10px; letter-spacing: .18em; text-transform: uppercase; color: rgba(179,167,140,.9); min-width: 92px; }
.contact-row .v { font-family: var(--t1); font-size: clamp(16px, 1.6vw, 23px); font-weight: 500; letter-spacing: -.026em; color: #fff; }
.formnote { font-size: 12px; color: rgba(238,242,239,.5); margin-top: 14px; }

/* ---------- CTA + footer ---------- */
.ctaband { padding: clamp(20px, 3vw, 44px) var(--pad) clamp(44px, 6vw, 96px); max-width: var(--wrap); margin: 0 auto; }
.ctaband-in {
  position: relative; overflow: hidden; border-radius: 28px; border: 1px solid var(--line-2);
  background: linear-gradient(115deg, rgba(179,167,140,.16), rgba(4,81,62,.3) 55%, rgba(4,18,14,.2));
  padding: clamp(32px, 4.6vw, 78px) clamp(24px, 3.6vw, 60px);
  display: flex; align-items: center; justify-content: space-between; gap: clamp(22px, 3.6vw, 56px); flex-wrap: wrap;
}
.ctaband h2 { font-size: clamp(24px, 3.2vw, 46px); max-width: 24ch; }
/* Services keeps the band but drops the headline, so the button carries it alone
   and is centred rather than pushed to one end. */
.ctaband-solo { justify-content: center; padding-block: clamp(30px, 4.4vw, 58px); }
/* The side padding has to give way on a small screen. At 320px the band offers
   232px of content, and "Book a Consultation" plus a fixed 46px each side came
   to 239px, so the button ran past its own band. The Arabic label is shorter and
   never showed it. Unchanged from 768px up. */
.ctaband-solo .btn { padding: 20px clamp(22px, 6vw, 46px); font-size: 14px; }
/* ---------- brand wall ----------
   The company name set as type, filling the width and sinking into the footer.
   No rule above it on purpose: the wall is the transition into the footer, and a
   separator would cut that in half. */
.brandwall {
  position: relative; overflow: clip;
  padding-block-start: clamp(46px, 7vw, 110px);
  /* Plain page dark, no glow. The contrast that carries this section is the
     white name against the dark, then the lighter footer panel it sinks into. */
  background: var(--ink);
}
/* Deliberately NOT full-bleed. The name starts and ends on the same margins as
   the footer columns below it, so the two blocks share one edge. */
.brandwall .wrap { position: relative; z-index: 2; }

/* No entrance and no sweep. The wall is simply there, drawn in full, the moment
   it is scrolled to. Kept free of `.reveal` in the markup as well, so nothing
   further down the sheet can fade or slide it. */
.bw-word {
  position: relative; display: block; user-select: none;
}

.bw-line {
  display: block; white-space: nowrap;
  /* Anton, not the site face. The wall is width-constrained: the name must span
     the footer measure, so the only way to gain height is a narrower letter.
     Sora averages about .60em per capital and caps this string near 76px; Anton
     averages roughly .42em and takes it well past 100px at the same width. */
  font-family: 'Anton', var(--t1); font-weight: 400;
  text-transform: uppercase;
  /* The wordmark is Latin on both language versions, so it is laid out
     left-to-right regardless of the page direction. */
  direction: ltr;
  /* .82 stacked the two lines so tightly that the caps of the second touched the
     baseline of the first. .92 keeps the block dense without them colliding. */
  /* Anton is already tightly fitted, so it needs far less negative tracking than
     Sora did, and a line box close to its own cap height. */
  line-height: .86; letter-spacing: -.005em;
  /* Starting size only. js/aaa.js sets the real font-size per line so each one
     measures exactly the width of the section: two lines of very different
     length cannot both fill a fixed measure, so it has to be computed. */
  font-size: 8vw;
  /* Flat white. The travelling highlight is gone, so the type is painted
     directly rather than clipped out of a gradient. */
  color: rgba(255,255,255,.92);
}
/* The last line sinks. The footer is pulled up over its lower edge so the name
   runs off the bottom instead of sitting politely in a box. */
/* About a fifth of the cap height goes behind the footer: enough that the name
   clearly runs under the panel, not so much that it stops reading. Small in em
   terms because Anton's capitals fill nearly three quarters of the em, so a
   given fraction of the em eats far more letter than it would in Sora. */
.bw-line:last-child { margin-block-end: -.08em; }


/* Lighter than the section above it, so the name reads as sinking out of the
   dark into a raised panel rather than dissolving into more of the same. */
.site-foot { background: #10231C; border-top: 1px solid var(--line); position: relative; z-index: 2; }
.foot-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: clamp(28px, 3.8vw, 58px); padding-block: clamp(44px, 6vw, 92px) clamp(24px, 3vw, 38px); }
/* Width-driven, so the lockup can never be squashed: when the footer column is
   narrower than the logo, the height follows the width instead of staying fixed. */
.foot-grid img.lockup {
  display: block;
  width: min(100%, 292px);
  height: auto;
  object-fit: contain;
  object-position: left center;
}
[dir="rtl"] .foot-grid img.lockup { object-position: right center; }
.foot-h { font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase; color: rgba(179,167,140,.9); margin-bottom: 18px; }
/* ---------- social links ---------- */
.foot-social { display: flex; gap: 10px; margin-top: clamp(20px, 2.6vw, 30px); }
.foot-social a {
  display: grid; place-items: center; width: 40px; height: 40px;
  border-radius: 12px; border: 1px solid var(--line-2); color: rgba(238,242,239,.72);
  transition: background .3s var(--e2), color .3s var(--e2), border-color .3s var(--e2), transform .4s var(--e3);
}
.foot-social a:hover { background: var(--gold); color: var(--ink); border-color: var(--gold); transform: translateY(-3px); }
.foot-social svg { width: 19px; height: 19px; display: block; }
.foot-list { display: flex; flex-direction: column; gap: 10px; }
/* Quick Links: two balanced columns instead of one tall stack of eight.
   grid-auto-flow: column against four fixed rows fills top to bottom and then wraps,
   so links 1 to 4 sit in the first column and 5 to 8 in the second. Column order
   follows the document's dir attribute, so right-to-left needs no override. */
.foot-list--split {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(4, auto);
  column-gap: clamp(18px, 2.2vw, 44px);
  row-gap: 10px;
  justify-content: start;
}
/* Below the footer grid's own wrap point a column has no room for two of these, so
   fall back to the single stack rather than squeezing two unreadable ones. */
@media (max-width: 720px) {
  .foot-list--split { grid-auto-flow: row; grid-template-rows: none; }
}
/* padding-block lifts the hit area from 19px to 25px, over the 24px minimum in
   WCAG (Web Content Accessibility Guidelines) 2.2 for a pointer target. */
.foot-list a { font-size: 13.5px; color: rgba(238,242,239,.66); line-height: 1.4; padding-block: 3px; }
.foot-list a:hover { color: var(--gold); }
/* Was 9px at .38 alpha, which measured 3.23:1 against the footer and failed AA
   (4.5:1). These are real contact details, not decoration. */
.foot-c .k { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: rgba(238,242,239,.62); margin-bottom: 5px; }
.foot-c .v { font-size: 13.5px; color: rgba(238,242,239,.8); }
/* Was .4 alpha at 11.5px, measuring 3.46:1 and failing AA. The copyright and the
   policy links are content, so they have to clear 4.5:1. */
.foot-bar { border-top: 1px solid rgba(179,167,140,.14); padding: 20px 0 clamp(26px, 3.4vw, 42px); display: flex; justify-content: space-between; gap: 18px; flex-wrap: wrap; font-size: 12px; color: rgba(238,242,239,.62); }
.foot-bar a { color: rgba(238,242,239,.62); padding-block: 3px; }
.foot-bar a:hover { color: var(--gold); }
.foot-links { display: flex; gap: 22px; }

/* ---------- 3D relief ---------- */
.relief { position: absolute; inset: 0; perspective: 1500px; animation: drift 14s ease-in-out infinite; }
.relief-plate { position: absolute; inset: 8%; transform-style: preserve-3d; transform: rotateX(60deg) rotateZ(-40deg); transition: transform .6s cubic-bezier(.2,.7,.2,1); }
.relief-cell { position: absolute; animation: wave var(--dur) ease-in-out var(--delay) infinite; }
@keyframes wave { 0%, 100% { transform: translateZ(0); } 50% { transform: translateZ(var(--z)); } }
@keyframes glow { 0%, 100% { opacity: .35; } 50% { opacity: .85; } }
@keyframes drift { 0%, 100% { transform: translateY(-9px); } 50% { transform: translateY(9px); } }

.reveal { opacity: 0; transform: translateY(18px); transition: opacity .8s cubic-bezier(.2,.7,.2,1), transform .8s cubic-bezier(.2,.7,.2,1); }
.reveal.in { opacity: 1; transform: none; }

/* ---------- stacking helpers ---------- */
.stack-xs > * + * { margin-top: 12px; }
.stack-sm > * + * { margin-top: clamp(14px, 1.8vw, 20px); }
.stack > * + * { margin-top: clamp(20px, 2.6vw, 32px); }
.stack-lg > * + * { margin-top: clamp(28px, 3.8vw, 56px); }
.flow-col { display: flex; flex-direction: column; gap: clamp(16px, 2vw, 26px); }

/* ---------- responsive ---------- */
@media (max-width: 1240px) {
  .hero-3d { inset-inline-end: -22%; width: clamp(360px, 62vw, 820px); opacity: .8; }
}
@media (max-width: 1080px) {
  .row { grid-template-columns: clamp(44px, 7vw, 70px) 1fr auto; }
  .row p { display: none; }
}
/* Tighten the navigation in the band where it is snug. The button must NOT be
   hidden here any more: Contact left the navigation when the button became
   "Contact Us", so dropping the button would leave no route to Contact from the
   header at all. */
@media (min-width: 1025px) and (max-width: 1219px) {
  .nav { gap: 2px; }
  .nav a { padding-inline: 9px; }
  .nav a::after { inset-inline: 9px; }
  .btn-sm { padding: 11px 16px; }
}
@media (max-width: 1024px) {
  .nav {
    position: absolute; inset-inline: 0; top: calc(100% + 10px);
    flex-direction: column; align-items: stretch; gap: 4px;
    padding: 12px; border-radius: 22px;
    background: rgba(6,26,20,.98); border: 1px solid var(--line);
    backdrop-filter: blur(20px); box-shadow: 0 30px 60px -20px rgba(0,0,0,.8);
    display: none;
  }
  .navbar { position: relative; }
  .navbar.open .nav { display: flex; }
  .nav a { padding: 13px 14px; font-size: 15px; border-radius: 14px; }
  .navtoggle {
    display: grid; place-items: center; gap: 5px; margin-inline-start: auto;
    width: 42px; height: 42px; border-radius: 999px; flex: 0 0 auto;
    background: rgba(238,242,239,.06); border: 1px solid var(--line); cursor: pointer;
  }
  .navtoggle i { display: block; width: 17px; height: 1.5px; background: var(--paper); transition: transform .25s, opacity .25s; }
  .navbar.open .navtoggle i:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
  .navbar.open .navtoggle i:nth-child(2) { opacity: 0; }
  .navbar.open .navtoggle i:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
  .btn-nav { display: none; }
  .hero-3d { inset-inline-end: -34%; opacity: .5; }
  .head-3d { opacity: .28; }
  .has-3d .head-3d { opacity: .16; }
  .ctaband-in { flex-direction: column; align-items: flex-start; }
  /* The Services band holds only the button, and stacking flips which axis does
     the centring: `justify-content: center` on .ctaband-solo lines it up
     horizontally in a row, but once the container is a column that property
     controls the vertical axis and the button falls to the leading edge. The
     cross axis has to be centred instead. Kept next to the rule that causes it,
     and after it, since both are (0,1,0) and order decides. */
  .ctaband-solo { align-items: center; }
}
/* The home page marks its text column `grid-column: span 2` inline. Once the
   split collapses to a single track that span invents a second, implicit column
   and pushes the section past the screen. Below the width where two tracks
   genuinely fit, pin the grid to one column and make every child occupy it. */
@media (max-width: 700px) {
  .split { grid-template-columns: 1fr; }
  .split > * { grid-column: 1 / -1 !important; }
}
@media (max-width: 620px) {
  body { font-size: 15px; }
  .hero { min-height: 0; }
  .hero .wrap { padding-block: clamp(44px, 12vw, 70px); }
  .hero-3d { inset-inline-end: -46%; top: 68%; opacity: .4; }
  .row { grid-template-columns: 38px 1fr; }
  .row .go { display: none; }
  .stat { flex: 1 1 140px; }
  .foot-bar { flex-direction: column; gap: 12px; }
  /* The top bar now carries only the strapline, so it stays on one row beside the
     language toggle. Phone and email moved to the footer and the contact page. */
  .topbar { font-size: 11.5px; }
  .topbar .wrap { flex-direction: row; align-items: center; gap: 10px; }
  .topbar-info { flex-wrap: nowrap; gap: 10px; min-width: 0; }
  .topbar-info > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
@media (max-width: 360px) {
  .topbar { font-size: 11px; }
  .topbar .wrap { gap: 8px; }
  .topbar-info { gap: 8px; }
  .langsw a { padding: 4px 8px; }
}
/* ============================================================
   MOTION LAYER
   Easing: --e1 expo-out (entrances) · --e2 smooth (states)
   ============================================================ */
:root {
  --e1: cubic-bezier(.16, 1, .3, 1);
  --e2: cubic-bezier(.2, .7, .2, 1);
  --e3: cubic-bezier(.34, 1.24, .64, 1);
}

/* ---- cross-page view transitions ---- */
@view-transition { navigation: auto; }
::view-transition-group(root) { animation-duration: .5s; }
::view-transition-old(root) { animation: vt-out .34s var(--e2) both; }
::view-transition-new(root) { animation: vt-in .5s var(--e1) both; }
@keyframes vt-out { to { opacity: 0; transform: translateY(-10px); } }
@keyframes vt-in { from { opacity: 0; transform: translateY(16px); } }
.topbar, .site-head { view-transition-name: chrome-top; }
.site-foot { view-transition-name: chrome-foot; }
::view-transition-group(chrome-top),
::view-transition-group(chrome-foot) { animation-duration: .4s; animation-timing-function: var(--e2); }

/* fallback fade for browsers without the API */
html.leaving main, html.leaving .ctaband { opacity: 0; transform: translateY(-10px); transition: opacity .3s var(--e2), transform .3s var(--e2); }

/* ---- scroll progress ---- */
.progress { position: fixed; inset-block-start: 0; inset-inline: 0; height: 2px; z-index: 900; background: linear-gradient(90deg, var(--gold), var(--gold-lt)); transform: scaleX(0); transform-origin: left center; will-change: transform; }
[dir="rtl"] .progress { transform-origin: right center; }

/* ---- reveal variants ---- */
.reveal { transition-property: opacity, transform, filter, clip-path; transition-duration: .9s; transition-timing-function: var(--e1); }
.reveal[data-anim="up"]    { transform: translateY(24px); }
.reveal[data-anim="blur"]  { filter: blur(10px); transform: translateY(14px); }
.reveal[data-anim="scale"] { transform: scale(.965) translateY(14px); }
.reveal[data-anim="right"] { transform: translateX(28px); }
.reveal[data-anim="left"]  { transform: translateX(-28px); }
[dir="rtl"] .reveal[data-anim="right"] { transform: translateX(-28px); }
[dir="rtl"] .reveal[data-anim="left"]  { transform: translateX(28px); }
/* The RTL entrance rules above are [dir="rtl"] + class + attribute (0,3,0), which
   outranks a bare `.reveal.in` (0,2,0). Without the second selector here the
   transform is never cleared in Arabic, so every form stayed parked 28px off its
   column for the whole life of the page. Match the specificity to release it. */
.reveal.in,
[dir="rtl"] .reveal.in { opacity: 1; transform: none; filter: none; }

/* ---- split-word headline ---- */
.sw { display: inline-block; overflow: hidden; vertical-align: top; padding-block-end: .06em; margin-block-end: -.06em; }
.sw > i { display: inline-block; font-style: inherit; transform: translateY(115%); transition: transform 1s var(--e1); }
.sw > i.on { transform: none; }

/* ---- animated rule under eyebrows ---- */
.eyebrow-rule { position: relative; padding-block-end: 14px; }
.eyebrow-rule::after { content: ""; position: absolute; inset-block-end: 0; inset-inline-start: 0; width: 56px; height: 1px; background: var(--gold); transform: scaleX(0); transform-origin: left center; transition: transform .9s var(--e1) .15s; }
.reveal.in .eyebrow-rule::after, .eyebrow-rule.in::after { transform: scaleX(1); }

/* ---- nav ---- */
@media (min-width: 1025px) { .nav { position: relative; } }
.nav-ind { position: absolute; z-index: 0; border-radius: 999px; background: rgba(238,242,239,.08); opacity: 0; pointer-events: none; transition: transform .45s var(--e2), width .45s var(--e2), opacity .3s var(--e2); }
/* js/aaa.js drives the indicator with translate(link.left - nav.left), which
   measures from the nav's physical LEFT edge. With no inset set, an absolutely
   positioned flex child instead starts at the INLINE-start edge, which is the
   right edge under RTL, so the pill landed a nav-width away from its link.
   Pinning it to the physical top-left makes the existing maths hold in Arabic.
   Left-to-right already resolves to this position, so it is untouched. */
[dir="rtl"] .nav-ind { left: 0; right: auto; top: 0; bottom: auto; }
.nav a { position: relative; z-index: 1; }
.nav a::after { content: ""; position: absolute; inset-block-end: 4px; inset-inline: 11px; height: 1px; background: var(--gold); transform: scaleX(0); transform-origin: left center; transition: transform .45s var(--e2); }
.nav a[aria-current="page"]::after { transform: scaleX(1); }
.navbar { transition: box-shadow .4s var(--e2), background .4s var(--e2), border-color .4s var(--e2); }
.site-head.stuck .navbar { background: rgba(6,26,20,.86); border-color: rgba(179,167,140,.3); box-shadow: 0 20px 48px -24px rgba(0,0,0,.85); }
.brand img { transition: transform .5s var(--e2), filter .5s var(--e2); }
.brand:hover img { transform: scale(1.03); filter: brightness(1.12); }

/* ---- buttons ---- */
.btn { position: relative; overflow: hidden; isolation: isolate; }
.btn > * { position: relative; z-index: 2; }
.btn::after {
  content: ""; position: absolute; z-index: 1; inset-block: -60%; width: 34%; inset-inline-start: -45%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.42), transparent);
  transform: skewX(-18deg); opacity: 0; transition: none;
}
.btn:hover::after { animation: sheen .75s var(--e2) forwards; }
@keyframes sheen { from { inset-inline-start: -45%; opacity: 1; } to { inset-inline-start: 115%; opacity: 1; } }
.btn:active { transform: translateY(0) scale(.975); transition-duration: .1s; }
.btn-ghost::before { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; background: rgba(179,167,140,.16); transform: scale(.4); opacity: 0; transition: transform .5s var(--e2), opacity .4s var(--e2); }
.btn-ghost:hover::before { transform: scale(1); opacity: 1; }

/* ---- cards: cursor-tracked glow + lift ---- */
.card-hov { position: relative; }
.card-hov::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 0;
  background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 0%), rgba(179,167,140,.16), transparent 70%);
  opacity: 0; transition: opacity .45s var(--e2);
}
.card-hov:hover::before { opacity: 1; }
.card-hov > * { position: relative; z-index: 1; }
.svc .ghost { transition: transform .6s var(--e2), color .45s var(--e2); }
.svc:hover .ghost { transform: translateY(-6px) scale(1.06); color: rgba(179,167,140,.2); }
.svc h3 { transition: transform .5s var(--e2); }
.svc:hover h3 { transform: translateX(4px); }
[dir="rtl"] .svc:hover h3 { transform: translateX(-4px); }
.svc .more span { transition: transform .45s var(--e3); }
.svc:hover .more span { transform: translateX(7px); }
[dir="rtl"] .svc:hover .more span { transform: translateX(-7px); }

/* ---- rows: wipe + arrow travel ---- */
.row { position: relative; overflow: hidden; }
.row::before { content: ""; position: absolute; inset: 0; z-index: 0; background: linear-gradient(90deg, rgba(179,167,140,.12), rgba(238,242,239,.03) 60%, transparent); transform: scaleX(0); transform-origin: left center; transition: transform .6s var(--e2); }
.row:hover::before { transform: scaleX(1); }
.row > * { position: relative; z-index: 1; }
.row .n, .row h3 { transition: transform .55s var(--e2), color .45s var(--e2); }
.row:hover .n { color: var(--gold); transform: translateX(4px); }
.row:hover h3 { transform: translateX(8px); }
[dir="rtl"] .row:hover .n { transform: translateX(-4px); }
[dir="rtl"] .row:hover h3 { transform: translateX(-8px); }
.row .go { transition: transform .5s var(--e3), background .4s var(--e2), border-color .4s var(--e2), color .4s var(--e2); }
.row:hover .go { background: var(--gold); border-color: var(--gold); color: var(--ink); transform: translateX(6px) rotate(45deg); }
[dir="rtl"] .row:hover .go { transform: translateX(-6px) rotate(-45deg); }

/* ---- bullets: staggered rule draw ---- */
.bullets li { position: relative; }
.bullets li::after { content: ""; position: absolute; inset-block-end: -1px; inset-inline: 0; height: 1px; background: var(--gold); transform: scaleX(0); transform-origin: left center; transition: transform .8s var(--e1); }
.bullets.in li::after { transform: scaleX(1); }
.bullets li .n { transition: color .35s var(--e2); }
.bullets li:hover .n { color: var(--gold-lt); }

/* ---- figures ---- */
.fig { transition: transform .6s var(--e2), border-color .5s var(--e2); }
.fig::after { content: ""; position: absolute; inset: 0; background: linear-gradient(105deg, transparent 30%, rgba(238,242,239,.07) 48%, transparent 62%); transform: translateX(-100%); animation: shimmer 4.5s var(--e2) infinite; pointer-events: none; }
@keyframes shimmer { 0% { transform: translateX(-100%); } 55%, 100% { transform: translateX(100%); } }
/* The shimmer sweep marks an empty placeholder. Over a photograph it reads as a
   rendering defect, so frames holding a photo opt out. */
.fig[data-parallax]::after { animation: none; opacity: 0; }
.card-hov:hover .fig { border-color: var(--line-2); }
.split:hover .fig .ph em, .fig .ph span { transition: color .4s var(--e2); }
.fig:hover .ph em { color: rgba(238,242,239,.65); }

/* ---- stats & counters ---- */
.stat { transition: transform .5s var(--e2), border-color .5s var(--e2), background .5s var(--e2); }
.stat:hover { transform: translateY(-4px); border-color: var(--line-2); background: var(--glass-2); }
.stat b { font-variant-numeric: tabular-nums; }

/* ---- contact rows & form ---- */
.contact-row { transition: transform .5s var(--e2), border-color .45s var(--e2), background .45s var(--e2); }
.contact-row:hover { transform: translateX(5px); border-color: var(--line-2); background: var(--glass-2); }
[dir="rtl"] .contact-row:hover { transform: translateX(-5px); }
.field { position: relative; }
.field > span { transition: color .3s var(--e2), transform .35s var(--e2); transform-origin: left center; }
.field:focus-within > span { color: var(--gold); }
.field input, .field textarea { transition: border-color .3s var(--e2), background .3s var(--e2), box-shadow .35s var(--e2); }
.field input:focus, .field textarea:focus { background: rgba(4,18,14,.72); box-shadow: 0 0 0 4px rgba(179,167,140,.1); }

/* ---- CTA band ---- */
.ctaband-in::after { content: ""; position: absolute; inset: 0; background: radial-gradient(420px circle at var(--mx, 30%) var(--my, 50%), rgba(179,167,140,.18), transparent 70%); opacity: 0; transition: opacity .6s var(--e2); pointer-events: none; }
.ctaband-in:hover::after { opacity: 1; }

/* ---- footer ---- */
.foot-list a { position: relative; width: fit-content; }
.foot-list a::after { content: ""; position: absolute; inset-block-end: -2px; inset-inline: 0; height: 1px; background: var(--gold); transform: scaleX(0); transform-origin: left center; transition: transform .4s var(--e2); }
.foot-list a:hover::after { transform: scaleX(1); }
.foot-grid img.lockup { transition: transform .6s var(--e2); }
.foot-grid img.lockup:hover { transform: scale(1.02); }

/* ---- RTL: wipe from the leading (right) edge ---- */
[dir="rtl"] .eyebrow-rule::after,
[dir="rtl"] .nav a::after,
[dir="rtl"] .row::before,
[dir="rtl"] .bullets li::after,
[dir="rtl"] .foot-list a::after { transform-origin: right center; }

/* ---- back to top ---- */
.totop {
  position: fixed; inset-block-end: 24px; inset-inline-end: 24px; z-index: 850;
  width: 46px; height: 46px; border-radius: 999px; border: 1px solid var(--line-2);
  background: rgba(6,26,20,.86); backdrop-filter: blur(12px); color: var(--gold);
  display: grid; place-items: center; cursor: pointer; font-size: 15px;
  opacity: 0; transform: translateY(14px) scale(.86); pointer-events: none;
  transition: opacity .45s var(--e2), transform .45s var(--e3), background .35s var(--e2), color .35s var(--e2);
}
.totop.on { opacity: 1; transform: none; pointer-events: auto; }
.totop:hover { background: var(--gold); color: var(--ink); }

/* ---- mobile menu choreography ---- */
@media (max-width: 1024px) {
  .nav { position: absolute; display: flex; opacity: 0; visibility: hidden; transform: translateY(-8px) scale(.98); pointer-events: none; transition: opacity .35s var(--e2), transform .4s var(--e1), visibility .35s; }
  .navbar.open .nav { opacity: 1; visibility: visible; transform: none; pointer-events: auto; }
  .nav a { opacity: 0; transform: translateY(10px); transition: opacity .4s var(--e1), transform .5s var(--e1); }
  .navbar.open .nav a { opacity: 1; transform: none; }
  .navbar.open .nav a:nth-child(1) { transition-delay: .04s; }
  .navbar.open .nav a:nth-child(2) { transition-delay: .08s; }
  .navbar.open .nav a:nth-child(3) { transition-delay: .12s; }
  .navbar.open .nav a:nth-child(4) { transition-delay: .16s; }
  .navbar.open .nav a:nth-child(5) { transition-delay: .2s; }
  .navbar.open .nav a:nth-child(6) { transition-delay: .24s; }
  .navbar.open .nav a:nth-child(7) { transition-delay: .28s; }
  .nav-ind { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .sw > i { transform: none !important; }
  .fig::after, .progress, .totop { animation: none !important; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none !important; }
  @view-transition { navigation: none; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  /* Second selector for the same reason as the `.in` reset: the RTL entrance
     rules are (0,3,0) and would otherwise beat a bare `.reveal`, leaving Arabic
     content displaced for visitors who asked for no motion at all. */
  .reveal,
  [dir="rtl"] .reveal[data-anim] { opacity: 1; transform: none; }
  html { scroll-behavior: auto; }
  /* No loader at all: its whole content is motion. `* { animation: none }` above
     would otherwise strand the panels across the screen forever, because the
     animation that hides them is the thing being switched off. */
  .preload, .pagewipe { display: none !important; }
  /* No parallax: sit the photograph flat in its frame. */
  .fig[data-parallax] img {
    position: static; inset-block-start: 0; height: 100%;
    transform: none !important; will-change: auto;
  }
  .hero-copy { transform: none !important; opacity: 1 !important; }
}
