:root{
  --void:#0B0E11; --graphite:#12171C; --steel:#1E252C; --line:#2C343C;
  --concrete:#8B939C; --bone:#E9E4D9; --gold:#967F31;
  --gold-lit:#C6A452; --gold-glow:rgba(198,164,82,.14);
  /* typography tokens — swapped wholesale when the page switches script */
  --f-disp:'Archivo','Arial Narrow',sans-serif;
  --f-body:'Manrope',system-ui,-apple-system,'Segoe UI',sans-serif;
  --f-mono:'IBM Plex Mono',ui-monospace,monospace;
  --tt:uppercase; --ls-mono:.18em; --ls-disp:-.015em; --lh-disp:.94; --fs-mono:.68rem;
}
body.rtl{
  --f-disp:'Noto Kufi Arabic',sans-serif;
  --f-body:'Noto Sans Arabic',sans-serif;
  --f-mono:'Noto Sans Arabic',sans-serif;
  --tt:none; --ls-mono:0; --ls-disp:0; --lh-disp:1.44; --fs-mono:.8rem;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0; background:var(--void); color:var(--bone);
  font-family:var(--f-body); font-weight:300; line-height:1.6;
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
h1,h2,h3,.dsp{
  font-family:var(--f-disp); font-weight:700; text-transform:var(--tt);
  letter-spacing:var(--ls-disp); line-height:var(--lh-disp); margin:0;
}
.mono{font-family:var(--f-mono); font-size:var(--fs-mono); letter-spacing:var(--ls-mono); text-transform:var(--tt)}
a{color:inherit;text-decoration:none}
:focus-visible{outline:2px solid var(--gold-lit); outline-offset:3px}
.wrap{width:min(1280px,92vw); margin-inline:auto}
section{position:relative}

/* ---------- tick / annotation language (signature) ---------- */
.ticks{position:absolute; inset:0; pointer-events:none}
.ticks span{position:absolute; width:14px; height:14px; border:1px solid var(--gold); opacity:.55}
.ticks span:nth-child(1){top:0;left:0;border-right:0;border-bottom:0}
.ticks span:nth-child(2){top:0;right:0;border-left:0;border-bottom:0}
.ticks span:nth-child(3){bottom:0;left:0;border-right:0;border-top:0}
.ticks span:nth-child(4){bottom:0;right:0;border-left:0;border-top:0}
.eyebrow{display:flex; align-items:center; gap:12px; color:var(--gold-lit)}
.eyebrow::before{content:''; width:34px; height:1px; background:var(--gold); flex:0 0 34px}

/* ---------- top bar ---------- */
.topbar{
  position:fixed; inset:0 0 auto 0; z-index:60; display:flex; align-items:center;
  justify-content:space-between; gap:16px; padding:12px max(4vw,20px);
  border-bottom:1px solid transparent;
  /* padding animates too, so the bar tightens as it sticks rather than only
     changing colour -- it reads as a response to scrolling, not a state flip. */
  transition:background .35s, border-color .35s, padding .35s cubic-bezier(.2,.7,.2,1);
}
.topbar.stuck{
  background:rgba(11,14,17,.88); backdrop-filter:blur(14px);
  border-bottom-color:var(--line); padding-block:7px;
}
.brand{display:flex; align-items:center; gap:11px}
/* Height, not transform: scaling would blur the wordmark at this size. */
.brand img{height:34px; width:auto; display:block; transition:height .35s cubic-bezier(.2,.7,.2,1)}
.topbar.stuck .brand img{height:29px}
/* Two cuts of the same logo: the full lockup by default, the mark alone once
   the bar gets tight. Only ever one is in the flow. Both selectors carry the
   .brand img specificity so neither loses to the shared sizing rule above. */
.brand img.brand-mark{display:none}
.nav{display:flex; gap:24px; align-items:center}
.nav a{font-size:var(--fs-mono); letter-spacing:var(--ls-mono); text-transform:var(--tt); color:#B9BFC6; font-family:var(--f-mono); position:relative; padding:6px 0}
.nav a::after{content:''; position:absolute; inset-inline-start:0; bottom:0; height:1px; width:0; background:var(--gold-lit); transition:width .3s}
.nav a:hover::after{width:100%}
.nav a:hover{color:var(--bone)}
.tools{display:flex; align-items:center; gap:10px}
/* ---------- language: globe menu ---------- */
.lang{position:relative}
.lang-toggle{
  display:inline-flex; align-items:center; gap:7px; cursor:pointer;
  background:transparent; border:1px solid var(--line); color:#9AA2AA;
  padding:8px 11px; font-family:var(--f-mono); font-size:.66rem;
  letter-spacing:.1em; transition:color .25s, border-color .25s;
}
.lang-toggle:hover,.lang-toggle[aria-expanded="true"]{color:var(--bone); border-color:var(--gold-lit)}
.lang-toggle svg{width:17px; height:17px; flex:0 0 17px; display:block}
/* The code beside the globe is a language tag, never uppercased or tracked --
   both mangle Arabic script. */
.lang-current{letter-spacing:0; text-transform:none; font-family:var(--f-mono)}
body.rtl .lang-current{font-family:'Noto Sans Arabic',sans-serif; font-size:.72rem}

.lang-menu{
  position:absolute; inset-inline-end:0; top:calc(100% + 8px); z-index:70;
  margin:0; padding:6px; min-width:190px; list-style:none;
  background:var(--graphite); border:1px solid var(--line);
  box-shadow:0 18px 40px rgba(0,0,0,.45);
}
.lang-menu[hidden]{display:none}
.lang-menu a{
  display:flex; flex-direction:column; gap:2px; padding:9px 11px;
  color:#B9BFC6; transition:background .2s, color .2s;
}
.lang-menu a:hover{background:var(--steel); color:var(--bone)}
.lang-menu a[aria-current="true"]{background:var(--gold); color:#0B0E11}
.lang-menu a[aria-current="true"] .lang-name{color:rgba(11,14,17,.72)}
.lang-native{font-size:.86rem; font-family:var(--f-body)}
.lang-name{font-family:var(--f-mono); font-size:.58rem; letter-spacing:.12em; text-transform:uppercase; color:var(--concrete)}
body.rtl .lang-name{letter-spacing:0; text-transform:none; font-family:'Noto Sans Arabic',sans-serif}
.cta{
  border:1px solid var(--gold); color:var(--bone); padding:10px 18px; font-family:var(--f-mono);
  font-size:var(--fs-mono); letter-spacing:var(--ls-mono); text-transform:var(--tt); background:transparent; cursor:pointer;
  transition:background .3s,color .3s;
}
.cta:hover{background:var(--gold); color:#0B0E11}
.burger{display:none; background:none; border:1px solid var(--line); padding:9px 11px; cursor:pointer}
.burger i{display:block; width:18px; height:1px; background:var(--bone); margin:4px 0}

/* ---------- hero ---------- */
.hero{position:relative; min-height:100svh; display:flex; align-items:flex-end; padding:104px 0 0; overflow:hidden}
.slides{position:absolute; inset:0; z-index:3; display:grid}
/* All slides share one grid cell and are stacked, so the hero never jumps as
   they cross-fade. Each is its own positioning context so its background
   image covers the whole section rather than just the copy block. */
.slide{position:relative; grid-area:1/1; display:flex; align-items:flex-end; padding:104px 0 96px; opacity:0; visibility:hidden; transition:opacity .7s ease, visibility .7s}
.slide.is-active{opacity:1; visibility:visible}

/* Slide content arrives after its background, heading first. Driven entirely by
   .is-active, which go() in site.js toggles: an inactive slide resets to the
   start state on its own, so clicking through the arrows quickly cannot leave a
   slide half-animated the way a JS-timed sequence could. */
.slide .hero-inner > *{
  opacity:0; transform:translateY(16px);
  transition:opacity .6s cubic-bezier(.2,.7,.2,1), transform .6s cubic-bezier(.2,.7,.2,1);
}
.slide.is-active .hero-inner > *{opacity:1; transform:none}
.slide.is-active .hero-inner h1{transition-delay:120ms}
.slide.is-active .hero-inner .lede{transition-delay:240ms}
.slide.is-active .hero-inner .hero-actions{transition-delay:340ms}
.slide .hero-bg{z-index:0}
.hero-bg{position:absolute; inset:0; z-index:0}
/* Video and image are treated identically: a slide background must cover the
   hero whichever it is. Without the video selector here the element fell back
   to its intrinsic size and left a band of empty page beside it. */
.hero-bg img,
.hero-bg video{width:100%; height:100%; object-fit:cover; object-position:60% 40%; filter:grayscale(.45) contrast(1.08) brightness(.72)}
/* A video is replaced content sitting on a text baseline, so without this it
   also carries a few pixels of descender gap under it. */
.hero-bg video{display:block}
.hero-bg::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(to top,var(--void) 3%,rgba(11,14,17,.6) 46%,rgba(11,14,17,.28) 100%),
             linear-gradient(to right,rgba(11,14,17,.92),rgba(11,14,17,.06) 66%);
}
body.rtl .hero-bg img,
body.rtl .hero-bg video{object-position:40% 40%}
body.rtl .hero-bg::after{
  background:linear-gradient(to top,var(--void) 3%,rgba(11,14,17,.6) 46%,rgba(11,14,17,.28) 100%),
             linear-gradient(to left,rgba(11,14,17,.92),rgba(11,14,17,.06) 66%);
}
.grid-overlay{position:absolute; inset:0; z-index:1; opacity:.5; pointer-events:none}


.hero-inner{position:relative; z-index:3; width:min(1280px,92vw); margin-inline:auto}
.hero h1{font-size:clamp(2.3rem,5.8vw,5.1rem); max-width:17ch; margin:18px 0 22px}
body.rtl .hero h1{font-size:clamp(1.7rem,4.2vw,3.5rem); max-width:20ch}
.hero h1 em{font-style:normal; color:var(--gold-lit)}
.hero p.lede{max-width:46ch; color:#C4CAD1; font-size:clamp(.98rem,1.2vw,1.1rem)}
.hero-actions{display:flex; gap:14px; flex-wrap:wrap; margin:26px 0 40px}
.btn-solid{background:var(--gold); color:#0B0E11; border:1px solid var(--gold); padding:14px 26px; font-family:var(--f-mono); font-size:var(--fs-mono); letter-spacing:var(--ls-mono); text-transform:var(--tt); cursor:pointer; transition:transform .25s, background .25s}
.btn-solid:hover{transform:translateY(-2px); background:var(--gold-lit)}
.btn-ghost{border:1px solid var(--line); background:transparent; color:var(--bone); padding:14px 26px; font-family:var(--f-mono); font-size:var(--fs-mono); letter-spacing:var(--ls-mono); text-transform:var(--tt); cursor:pointer; transition:border-color .25s,color .25s}
.btn-ghost:hover{border-color:var(--gold-lit); color:var(--gold-lit)}
/* Lives at the foot of the About section, not over the hero photo. */
.stats{display:grid; grid-template-columns:repeat(4,1fr); gap:1px; margin-top:56px; border-top:1px solid var(--line); overflow:hidden}
.stats > *{box-shadow:-1px 0 0 var(--line), 0 -1px 0 var(--line)}
@media (max-width:760px){.stats{grid-template-columns:repeat(2,1fr)}}
.stat{background:var(--void); padding:26px 20px 30px}
/* Tabular figures: every digit is the same width, so a counting number does
   not jitter as its digits change. */
.stat b{display:block; font-family:var(--f-disp); font-weight:700; font-size:clamp(1.9rem,3.6vw,3rem); line-height:1; color:var(--bone); font-variant-numeric:tabular-nums; font-feature-settings:"tnum" 1}
.stat b i{font-style:normal; color:var(--gold-lit); font-size:.5em; vertical-align:top; margin-inline-start:2px}
/* Direct child only: the figure itself is wrapped in a span for the count-up
   animation, and must keep the display size set on .stat b above. */
.stat > span{color:var(--concrete); font-family:var(--f-mono); font-size:.62rem; letter-spacing:var(--ls-mono); text-transform:var(--tt); display:block; margin-top:9px}
body.rtl .stat > span{font-size:.78rem}

/* ---------- section heads ---------- */
.sec{padding:clamp(72px,10vw,132px) 0}
.sec-head{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.15fr); gap:40px; align-items:end; margin-bottom:56px}
.sec-head h2{font-size:clamp(1.9rem,4.4vw,3.4rem)}
body.rtl .sec-head h2{font-size:clamp(1.5rem,3.2vw,2.5rem)}
.sec-head p{color:var(--concrete); margin:0; max-width:52ch}
.idx{color:var(--gold); font-family:var(--f-mono); font-size:var(--fs-mono); letter-spacing:var(--ls-mono); display:block; margin-bottom:14px; text-transform:var(--tt)}

/* ---------- about ---------- */
.about-grid{display:grid; grid-template-columns:1.05fr .95fr; gap:clamp(30px,5vw,74px); align-items:center}
.about-copy p{color:#BFC6CD; max-width:56ch}
.about-copy p + p{margin-top:18px}
.sig-list{list-style:none; padding:0; margin:34px 0 0; border-top:1px solid var(--line)}
.sig-list li{display:flex; gap:18px; padding:15px 0; border-bottom:1px solid var(--line); align-items:baseline}
.sig-list li b{font-family:var(--f-mono); font-size:.66rem; letter-spacing:.16em; color:var(--gold-lit); min-width:44px}
.sig-list li span{font-size:.94rem; color:#CDD3D9}
.frame{position:relative; padding:14px}
.frame img{width:100%; display:block; filter:grayscale(.35) contrast(1.05) brightness(.92)}
.frame .cap{position:absolute; inset-inline-start:14px; bottom:-30px; color:var(--concrete)}

/* ---------- services ---------- */
.svc{border-top:1px solid var(--line)}
.svc-row{
  display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,1.4fr) 46px; gap:28px; align-items:center;
  padding:26px 0; border-bottom:1px solid var(--line); position:relative; transition:padding-inline-start .35s;
}
.svc-row::before{content:''; position:absolute; inset-inline-start:0; top:0; bottom:0; width:0; background:linear-gradient(90deg,var(--gold-glow),transparent); transition:width .45s}
.svc-row:hover::before{width:100%}
.svc-row:hover{padding-inline-start:16px}
.svc-row h3{font-size:clamp(1.05rem,1.9vw,1.5rem); letter-spacing:0}
.svc-row p{margin:0; color:var(--concrete); font-size:.9rem}
.svc-row .arw{justify-self:end; color:var(--concrete); transition:transform .35s,color .35s}
body.rtl .svc-row .arw{transform:scaleX(-1)}
.svc-row:hover .arw{transform:translateX(6px); color:var(--gold-lit)}
body.rtl .svc-row:hover .arw{transform:scaleX(-1) translateX(6px)}

/* ---------- projects ---------- */
.filters{display:flex; gap:10px; flex-wrap:wrap; margin-bottom:34px}
.filters button{
  background:transparent; border:1px solid var(--line); color:var(--concrete); padding:9px 16px; cursor:pointer;
  font-family:var(--f-mono); font-size:.65rem; letter-spacing:var(--ls-mono); text-transform:var(--tt); transition:.25s;
}
body.rtl .filters button{font-size:.8rem}
.filters button:hover{color:var(--bone); border-color:#465059}
.filters button[aria-pressed="true"]{background:var(--gold); border-color:var(--gold); color:#0B0E11}
/* Rules drawn by the cells themselves, not by a painted container behind a
   1px gap -- see .team-grid: an unfilled cell in a short last row has no
   child over it, so the container colour shows through as a grey block.
   overflow:hidden clips the leading rules off the outer edges. */
.proj-grid{display:grid; grid-template-columns:repeat(auto-fill,minmax(310px,1fr)); gap:1px; overflow:hidden}
.proj-grid > *{box-shadow:-1px 0 0 var(--line), 0 -1px 0 var(--line)}
.proj{background:var(--graphite); position:relative; transition:background .35s; overflow:hidden}
.proj:hover{background:var(--steel)}
.proj .plate{aspect-ratio:16/10; background:radial-gradient(120% 120% at 70% 20%,#1B222A,#0E1317); position:relative; overflow:hidden}
.proj .plate svg{position:absolute; inset:0; width:100%; height:100%}
.plate .mv{transition:transform .6s cubic-bezier(.2,.7,.2,1)}
.proj:hover .plate svg .mv{transform:translateY(-4px)}
.proj .body{padding:22px 22px 26px}
.proj h3{font-size:1.05rem; letter-spacing:0; margin-bottom:10px}
.proj .meta{display:flex; gap:14px; flex-wrap:wrap; color:var(--concrete); font-family:var(--f-mono); font-size:.62rem; letter-spacing:var(--ls-mono); text-transform:var(--tt)}
body.rtl .proj .meta{font-size:.78rem}
.proj .meta i{font-style:normal; color:var(--gold-lit)}
.proj .tagline{position:absolute; top:14px; inset-inline-end:14px; background:rgba(11,14,17,.72); border:1px solid var(--line); padding:5px 10px; font-family:var(--f-mono); font-size:.58rem; letter-spacing:var(--ls-mono); text-transform:var(--tt); color:var(--gold-lit)}
body.rtl .proj .tagline{font-size:.74rem}
/* A hiding utility must beat whatever display a component sets on itself.
   .proj{display:block} is declared later in this file, and on equal
   specificity the later rule wins -- which silently disabled the project
   filter: cards took the class but kept displaying. !important pins the
   utility so it does not depend on where in the file a component lands. */
.is-hidden{display:none !important}

/* ---------- leadership ---------- */
.lead{background:linear-gradient(180deg,var(--graphite),var(--void)); border-block:1px solid var(--line)}
.lead-grid{display:grid; grid-template-columns:minmax(260px,.72fr) minmax(0,1.28fr); gap:clamp(30px,6vw,80px); align-items:center}
.portrait{position:relative; padding:16px}
.portrait svg{width:100%; display:block; background:linear-gradient(180deg,#1A2027,#0C1015)}
/* The drawn placeholder gets its height from its 400x500 viewbox. An uploaded
   photo has no such guarantee, so pin the same 4/5 ratio and crop to it --
   otherwise a wide or square picture changes the frame height and drags the
   name badge, which is positioned against it, out of place. */
.portrait-photo{width:100%; display:block; aspect-ratio:4/5; object-fit:cover;
  background:linear-gradient(180deg,#1A2027,#0C1015); filter:grayscale(.35) contrast(1.05)}

.portrait .badge{position:absolute; inset-inline:16px; bottom:16px; padding:14px; background:linear-gradient(0deg,rgba(11,14,17,.94),transparent)}
.portrait .badge b{font-family:var(--f-disp); text-transform:var(--tt); font-size:.9rem; letter-spacing:.02em; color:var(--bone)}
.portrait .badge span{display:block; color:var(--gold-lit); font-family:var(--f-mono); font-size:.6rem; letter-spacing:var(--ls-mono); margin-top:5px; text-transform:var(--tt)}
body.rtl .portrait .badge span{font-size:.78rem}
.lead blockquote{margin:0; font-family:var(--f-disp); font-weight:600; text-transform:none; font-size:clamp(1.25rem,2.5vw,2.05rem); line-height:1.24; letter-spacing:-.01em}
body.rtl .lead blockquote{font-size:clamp(1.05rem,1.9vw,1.5rem); line-height:1.75; letter-spacing:0}
.lead blockquote span{color:var(--gold-lit)}
.lead .who{margin-top:28px; padding-top:22px; border-top:1px solid var(--line); color:var(--concrete); font-size:.92rem; max-width:54ch}
.lead .who b{color:var(--bone); display:block; font-family:var(--f-disp); text-transform:var(--tt); letter-spacing:.02em; margin-bottom:6px}

/* ---------- team ---------- */
/* No painted container behind a 1px gap: when the last row is short the
   unfilled cells have no card over them and the container colour shows through
   as a grey block. Each card draws its own LEADING rules instead, so a rule
   exists only where two cards actually meet -- never along an outer edge and
   never trailing off beside an empty cell. */
.team-grid{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(210px,1fr)); gap:1px;
  /* auto-fill means the column count changes with the viewport, so which cards
     open a row is not knowable in CSS. Clipping at the container removes the
     leading rules that would otherwise run down the left edge and across the
     top, whatever the count resolves to. */
  overflow:hidden;
}
.team-grid > *{box-shadow:-1px 0 0 var(--line), 0 -1px 0 var(--line)}
/* Mixed photo and initials cards live in the same row, so pin the contact
   rows to the bottom and keep every card the same height. */
.member{display:flex; flex-direction:column; background:var(--graphite); padding:24px 20px 22px; transition:background .3s}
.member-contact{margin-top:auto}
.member:hover{background:var(--steel)}
.member .mono-badge{
  width:52px; height:52px; display:grid; place-items:center; border:1px solid var(--gold);
  color:var(--gold-lit); font-family:'Archivo',sans-serif; font-weight:700; font-size:1rem; margin-bottom:18px;
}
.member b{display:block; font-size:.98rem; font-weight:500; font-family:var(--f-body); color:var(--bone)}
.member span{color:var(--concrete); font-family:var(--f-mono); font-size:.6rem; letter-spacing:var(--ls-mono); text-transform:var(--tt); display:block; margin-top:8px}
body.rtl .member span{font-size:.78rem}

/* ---------- partners ---------- */
.partners{display:grid; grid-template-columns:repeat(3,1fr); gap:1px; overflow:hidden}
.partners > *{box-shadow:-1px 0 0 var(--line), 0 -1px 0 var(--line)}
.partner{background:var(--graphite); display:grid; place-items:center; padding:44px 26px; gap:18px; text-align:center; transition:background .3s}
.partner:hover{background:var(--steel)}
/* A logo sits in generous padding rather than filling a frame, so it lifts by
   less than a photo does -- and the cell is not clipped, so a large scale would
   push it into the hairline rules. */
.partner img{max-height:70px; max-width:190px; opacity:.82;
  transition:opacity .3s, transform .5s cubic-bezier(.2,.7,.2,1)}
.partner:hover img{opacity:1; transform:scale(1.04)}
.partner span{color:var(--concrete); font-family:var(--f-mono); font-size:.6rem; letter-spacing:var(--ls-mono); text-transform:var(--tt)}
body.rtl .partner span{font-size:.78rem}

/* ---------- contact ---------- */
.contact-grid{display:grid; grid-template-columns:1fr 1fr; gap:1px; background:var(--line); border:1px solid var(--line)}
.contact-side{background:var(--graphite); padding:clamp(28px,4vw,48px)}
.field{margin-bottom:18px}
.field label{display:block; font-family:var(--f-mono); font-size:.6rem; letter-spacing:var(--ls-mono); text-transform:var(--tt); color:var(--concrete); margin-bottom:8px}
body.rtl .field label{font-size:.8rem}
.field input,.field textarea,.field select{
  width:100%; background:#0C1116; border:1px solid var(--line); color:var(--bone); padding:13px 14px;
  font-family:var(--f-body); font-size:.94rem; transition:border-color .25s;
}
.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--gold); outline:none}
.field textarea{min-height:110px; resize:vertical}
.two{display:grid; grid-template-columns:1fr 1fr; gap:14px}
.info-row{display:flex; gap:16px; padding:18px 0; border-bottom:1px solid var(--line); align-items:flex-start}
.info-row:last-of-type{border-bottom:0}
.info-row .k{font-family:var(--f-mono); font-size:.6rem; letter-spacing:var(--ls-mono); text-transform:var(--tt); color:var(--gold-lit); min-width:82px; padding-top:4px}
body.rtl .info-row .k{font-size:.8rem; min-width:96px}
.info-row .v{font-size:.98rem; color:#CBD1D7}
.info-row .v a{border-bottom:1px solid transparent; transition:border-color .25s}
.info-row .v a:hover{border-bottom-color:var(--gold)}
.mapbox{margin-top:26px; border:1px solid var(--line); background:#0C1116; position:relative; aspect-ratio:16/9; overflow:hidden}
.mapbox svg{position:absolute; inset:0; width:100%; height:100%}
.mapbox .pin-label{position:absolute; left:50%; bottom:12px; transform:translate(-50%,0); font-family:var(--f-mono); font-size:.58rem; letter-spacing:var(--ls-mono); color:var(--gold-lit); text-transform:var(--tt); white-space:nowrap}
body.rtl .mapbox .pin-label{font-size:.74rem}

/* ---------- whatsapp / footer ---------- */
footer{border-top:1px solid var(--line); padding:44px 0 30px}
.foot{display:flex; justify-content:space-between; gap:26px; flex-wrap:wrap; align-items:center}
.foot small{color:#5F6871; font-family:var(--f-mono); font-size:.62rem; letter-spacing:.1em}
body.rtl .foot small{font-size:.76rem; letter-spacing:0}
.foot img{height:30px; opacity:.9}

/* ---------- reveal ---------- */
.rv{opacity:0; transform:translateY(22px); transition:opacity .8s cubic-bezier(.2,.7,.2,1),transform .8s cubic-bezier(.2,.7,.2,1)}
.rv.in{opacity:1; transform:none}

/* Staggered grids: the container itself no longer moves -- if it faded as well,
   its own transition would run against the children's and the cascade would be
   muddied. The children carry the motion, each with the delay set by site.js. */
.rv-stagger{opacity:1; transform:none}
.rv-stagger > *{opacity:0; transform:translateY(18px)}

/* The reveal's transition is declared per child type, appended to whatever that
   element already animates on hover. A blanket `.rv-stagger > *` transition
   cannot work: any form of it replaces the child's own declaration, so the
   cards stopped fading their background and the service rows stopped sliding
   their padding -- the hover snapped instead of gliding. */
.rv-stagger > .proj,
.rv-stagger > .member,
.rv-stagger > .partner{
  transition:opacity .7s cubic-bezier(.2,.7,.2,1), transform .7s cubic-bezier(.2,.7,.2,1),
             background .35s;
}
.rv-stagger > .svc-row{
  transition:opacity .7s cubic-bezier(.2,.7,.2,1), transform .7s cubic-bezier(.2,.7,.2,1),
             padding-inline-start .35s;
}
.rv-stagger.in > *{opacity:1; transform:none}

/* Section headings open on a beat: the gold label lands, then the heading, then
   the standfirst. The parts need their own transition -- a transition-delay on
   an element that is not itself transitioning does nothing, since only the
   .sec-head container was animating before. */
.sec-head.rv .idx,
.sec-head.rv h2,
.sec-head.rv > div > *,
.sec-head.rv > p{
  opacity:0; transform:translateY(12px);
  transition:opacity .6s cubic-bezier(.2,.7,.2,1), transform .6s cubic-bezier(.2,.7,.2,1);
}
.sec-head.rv.in .idx{opacity:1; transform:none; transition-delay:0ms}
.sec-head.rv.in h2{opacity:1; transform:none; transition-delay:90ms}
.sec-head.rv.in > div > *{opacity:1; transform:none}
.sec-head.rv.in > p{opacity:1; transform:none; transition-delay:160ms}

@media (max-width:1080px){ .nav{gap:16px} .topbar .cta{display:none} }
@media (max-width:980px){
  .nav{display:none}
  .topbar{padding-inline:max(4vw,14px); gap:10px}
  .burger{display:block}
  .topbar.open .nav{
    display:flex; position:fixed; inset:62px 0 auto 0; flex-direction:column; gap:0;
    background:rgba(11,14,17,.97); border-block:1px solid var(--line); padding:10px 6vw 22px;
  }
  .topbar.open .nav a{padding:15px 0; border-bottom:1px solid var(--line); width:100%; font-size:.8rem}
  .about-grid,.lead-grid,.contact-grid{grid-template-columns:1fr}
  .sec-head{grid-template-columns:1fr; gap:18px}
  .stats{grid-template-columns:1fr 1fr}
  .stat{border-bottom:1px solid var(--line); padding:20px 0 22px}
  .stat:nth-child(2n){border-inline-end:0}
  .svc-row{grid-template-columns:1fr; gap:8px 18px}
  .svc-row p{grid-column:1/-1}
  .svc-row .arw{display:none}
  .partners{grid-template-columns:1fr}
  .two{grid-template-columns:1fr}
}
/* The wordmark and the burger cannot share this width: drop to the mark. */
@media (max-width:430px){ .brand img.brand-full{display:none} .brand img.brand-mark{display:block} }
/* ---------- slideshow controls ---------- */
.slide-nav{
  position:absolute; z-index:5; inset-inline:0; bottom:30px;
  display:flex; align-items:center; justify-content:center; gap:18px;
}
.slide-arrow{
  display:inline-flex; align-items:center; justify-content:center;
  width:42px; height:42px; padding:0; cursor:pointer;
  background:rgba(11,14,17,.45); border:1px solid var(--line); color:var(--bone);
  transition:border-color .25s, background .25s;
}
.slide-arrow:hover{border-color:var(--gold-lit); background:rgba(11,14,17,.75)}
.slide-arrow svg{width:19px; height:19px}
/* The chevrons are directional glyphs, so mirror them for RTL. */
body.rtl .slide-arrow svg{transform:scaleX(-1)}
.slide-dots{display:inline-flex; gap:9px}
.slide-dot{
  width:30px; height:3px; padding:0; cursor:pointer;
  background:rgba(233,228,217,.28); border:0; transition:background .3s;
}
.slide-dot:hover{background:rgba(233,228,217,.55)}
.slide-dot.is-active{background:var(--gold)}

/* ---------- play button ---------- */
.btn-play{
  display:inline-flex; align-items:center; gap:11px; cursor:pointer;
  border:1px solid var(--line); background:rgba(11,14,17,.35); color:var(--bone);
  padding:14px 24px 14px 16px;
  font-family:var(--f-mono); font-size:var(--fs-mono);
  letter-spacing:var(--ls-mono); text-transform:var(--tt);
  transition:border-color .25s, color .25s;
}
.btn-play:hover{border-color:var(--gold-lit); color:var(--gold-lit)}
.play-mark{
  display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:30px; flex:0 0 30px; border-radius:50%;
  background:var(--gold); color:#0B0E11;
}
.play-mark svg{width:15px; height:15px; margin-inline-start:2px}
body.rtl .play-mark svg{transform:scaleX(-1); margin-inline-start:0; margin-inline-end:2px}

/* ---------- video modal ---------- */
.video-modal{
  position:fixed; inset:0; z-index:120; display:flex;
  align-items:center; justify-content:center; padding:5vmin;
  background:rgba(6,8,10,.93); backdrop-filter:blur(6px);
}
.video-modal[hidden]{display:none}
.video-frame{width:min(1100px,100%); aspect-ratio:16/9; background:#000; border:1px solid var(--line)}
.video-frame iframe,.video-frame video{width:100%; height:100%; display:block; border:0}
.video-close{
  position:absolute; top:22px; inset-inline-end:22px;
  width:44px; height:44px; padding:0; cursor:pointer;
  background:transparent; border:1px solid var(--line); color:var(--bone);
  transition:border-color .25s, color .25s;
}
.video-close:hover{border-color:var(--gold-lit); color:var(--gold-lit)}
.video-close svg{width:20px; height:20px}

/* ---------- team cards ---------- */
/* The photo must be clipped before it can be zoomed: without this the scaled
   image spills over the name and role beneath it. */
.member-photo{margin-bottom:15px; overflow:hidden}
.member-photo img{
  display:block; width:100%; aspect-ratio:1/1; object-fit:cover;
  filter:grayscale(.35) contrast(1.05);
  /* transform as well as filter, or the zoom snaps while the colour fades. */
  transition:filter .35s, transform .6s cubic-bezier(.2,.7,.2,1);
}
.member:hover .member-photo img{filter:grayscale(0) contrast(1); transform:scale(1.06)}
.member-role{
  color:var(--concrete); font-family:var(--f-mono); font-size:.6rem;
  letter-spacing:var(--ls-mono); text-transform:var(--tt);
  display:block; margin-top:8px;
}
.member-contact{
  list-style:none; margin:14px 0 0; padding:14px 0 0;
  border-top:1px solid var(--line); display:grid; gap:7px;
}
.member-contact a{
  display:flex; align-items:center; gap:8px;
  color:var(--concrete); font-family:var(--f-mono); font-size:.63rem;
  letter-spacing:.04em; transition:color .25s; word-break:break-all;
}
.member-contact a:hover{color:var(--gold-lit)}
.member-contact svg{width:13px; height:13px; flex:0 0 13px}
.member-note{display:flex; flex-direction:column; justify-content:center}
.member-note b{color:var(--gold-lit)}

@media (max-width:760px){
  .slide{padding-bottom:104px}
  .slide-nav{gap:12px; bottom:22px}
}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important; transition:none!important}
  /* Everything that starts hidden and is revealed by a transition must be
     forced visible here: with transitions off it would otherwise never arrive
     and the content would simply be missing. */
  .rv{opacity:1; transform:none}
  .rv-stagger > *,
  .sec-head.rv .idx,
  .sec-head.rv h2,
  .sec-head.rv > div > *,
  .sec-head.rv > p,
  .slide .hero-inner > *{opacity:1; transform:none}
  html{scroll-behavior:auto}
}

/* ============================================================
   Project detail page
   ============================================================ */
.pd {
  padding-top: 104px;
}

.pd-head {
  padding: 40px 0 28px;
}

.pd-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 22px;
  color: var(--concrete);
  font-family: var(--f-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--ls-mono);
  text-transform: var(--tt);
  transition: color .25s;
}

.pd-back:hover { color: var(--gold-lit); }

/* The arrow points back toward the start of the reading direction. */
[dir="ltr"] .pd-back span { transform: scaleX(-1); }

.pd-head h1 {
  font-size: clamp(2rem, 5vw, 3.6rem);
  max-width: 20ch;
  margin: 16px 0 0;
}

.pd-sub {
  max-width: 52ch;
  margin: 16px 0 0;
  color: #C4CAD1;
  font-size: clamp(.98rem, 1.2vw, 1.1rem);
}

.pd-status {
  display: inline-block;
  margin-top: 20px;
  padding: 7px 14px;
  border: 1px solid var(--line);
  color: var(--gold-lit);
}

.pd-hero {
  position: relative;
  margin-bottom: 44px;
}

.pd-hero img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* ---------- long description ---------- */
.pd-body {
  max-width: 68ch;
  margin-bottom: 52px;
  color: #C4CAD1;
  font-size: 1.02rem;
  line-height: 1.85;
}

.pd-body h2 {
  margin: 1.8em 0 .6em;
  font-size: clamp(1.3rem, 2.4vw, 1.7rem);
  color: var(--bone);
}

.pd-body h3 {
  margin: 1.5em 0 .5em;
  font-size: 1.15rem;
  color: var(--bone);
}

.pd-body p { margin: 0 0 1.1em; }

.pd-body ul,
.pd-body ol {
  margin: 0 0 1.2em;
  padding-inline-start: 1.5em;
}

.pd-body li { margin-bottom: .5em; }

.pd-body a {
  color: var(--gold-lit);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.pd-body blockquote {
  margin: 1.6em 0;
  padding-inline-start: 20px;
  border-inline-start: 2px solid var(--gold);
  color: var(--bone);
}

.pd-body hr {
  margin: 2em 0;
  border: 0;
  border-top: 1px solid var(--line);
}

/* ---------- video ---------- */
.pd-video { margin-bottom: 56px; }

.pd-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
  border: 1px solid var(--line);
}

.pd-frame iframe,
.pd-frame video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* ---------- related ---------- */
.pd-related {
  padding: 48px 0 40px;
  border-top: 1px solid var(--line);
}

/* .sec-head's 56px is measured for the main page, where it carries a large h2
   and a paragraph. This block is just a mono label over the grid, so that gap
   -- and the label's own 14px -- leaves the heading floating away from the
   cards it introduces. Scoped here so the main page keeps its rhythm. */
.pd-related .sec-head { margin-bottom: 22px; }
.pd-related .idx { margin-bottom: 0; }

/* Project cards are links now; keep them from picking up underline styling. */
.proj { display: block; color: inherit; text-decoration: none; }
.proj .plate img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* .plate is overflow:hidden, so the picture grows inside a fixed frame and
     the card itself never changes size. */
  transition: transform .6s cubic-bezier(.2, .7, .2, 1);
}
.proj:hover .plate img { transform: scale(1.06); }

@media (max-width: 700px) {
  .pd { padding-top: 88px; }
  .pd-head { padding: 24px 0 20px; }
  .pd-hero img { aspect-ratio: 4 / 3; }
  .pd-body { font-size: .98rem; }
  .pd-related { padding: 36px 0 32px; }
}

/* The scroll lock is set on <body> in the markup so it applies before first
   paint; adding it from the deferred script would let the page jump first.
   It lives on <body> rather than <html> because the localisation tests assert
   on the exact <html> tag, and a stray class there breaks them. */
body.is-loading {
  overflow: hidden;
}

/* ============================================================
   Preloader
   ============================================================
   A skyline builds itself in the centre of the screen, then the whole overlay
   fades away and is removed. Filled bars rather than outline strokes: at this
   size thin lines read as fragile and all but vanish on a phone, and the solid
   masses echo the vertical bars in the logo. */
.preloader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--void);
  opacity: 1;
  transition: opacity .55s ease;
}

/* Added by site.js once the page is ready; the element is then removed. */
.preloader.is-done {
  opacity: 0;
  pointer-events: none;
}

.pl-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 34px;
  padding: 24px;
}

/* ---------- the skyline ---------- */
.pl-site {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 10px;
  height: 132px;
}

.pl-bar {
  display: block;
  width: 26px;
  background: var(--gold);
  transform-origin: 50% 100%;
  /* Each bar scales up from the ground. The custom property staggers them so
     the skyline assembles instead of appearing all at once. */
  transform: scaleY(0);
  animation: pl-rise .5s cubic-bezier(.2, .8, .3, 1) forwards;
  animation-delay: calc(var(--i) * .11s);
}

/* Varied heights so it reads as a skyline, not a bar chart. */
.pl-bar:nth-child(1) { height: 54px; }
.pl-bar:nth-child(2) { height: 88px; }
.pl-bar:nth-child(3) { height: 132px; }
.pl-bar:nth-child(4) { height: 76px; }
.pl-bar:nth-child(5) { height: 100px; }

/* The middle tower is the focus, so it keeps full strength; the others sit
   back a little to give the group depth. */
.pl-bar:nth-child(1),
.pl-bar:nth-child(5) { background: var(--gold); opacity: .55; }
.pl-bar:nth-child(2),
.pl-bar:nth-child(4) { opacity: .78; }
.pl-bar:nth-child(3) { background: var(--gold-lit); }

/* ---------- crane ---------- */
/* The crane stands ON the tallest tower, which is the middle of five bars, so
   it is anchored to the flex centre. The jib then reaches to one side; in RTL
   the whole group mirrors so it still reaches outward rather than back over
   the skyline. */
.pl-crane {
  position: absolute;
  left: 50%;
  bottom: 132px;
  width: 0;
  height: 0;
}

body.rtl .pl-crane {
  transform: scaleX(-1);
}

.pl-crane-mast {
  position: absolute;
  left: -2px;
  bottom: 0;
  width: 4px;
  height: 34px;
  background: var(--gold-lit);
  transform-origin: 50% 100%;
  transform: scaleY(0);
  animation: pl-rise .4s ease forwards .62s;
}

.pl-crane-jib {
  position: absolute;
  left: -2px;
  bottom: 30px;
  width: 74px;
  height: 4px;
  background: var(--gold-lit);
  transform-origin: 0 50%;
  transform: scaleX(0);
  animation: pl-reach .45s cubic-bezier(.2, .8, .3, 1) forwards .95s;
}

.pl-crane-hook {
  position: absolute;
  left: 62px;
  bottom: 8px;
  width: 2px;
  height: 22px;
  background: var(--gold-lit);
  opacity: 0;
  transform-origin: 50% 0;
  animation: pl-drop .5s ease forwards 1.3s;
}

/* ---------- ground ---------- */
.pl-ground {
  position: absolute;
  left: 50%;
  bottom: -14px;
  width: 260px;
  height: 3px;
  margin-left: -130px;
  background: var(--gold);
  transform-origin: 50% 50%;
  transform: scaleX(0);
  animation: pl-reach .5s cubic-bezier(.2, .8, .3, 1) forwards .1s;
}

/* ---------- logo ---------- */
/* 145px, not larger: the source is 323px wide, so anything above 160px CSS
   cannot cover a 2x display and the wordmark goes soft. This is also the only
   raster that exists -- Picture1.png is 211x118, smaller still -- so the size
   is capped by the artwork rather than by taste.
   Kept subordinate to the skyline: the animation leads, the logo confirms. */
.pl-logo {
  width: 145px;
  height: auto;
  opacity: 0;
  animation: pl-in .6s ease forwards 1.5s;
}

/* ---------- progress ---------- */
.pl-progress {
  width: 180px;
  height: 2px;
  background: var(--line);
  overflow: hidden;
}

.pl-progress-fill {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--gold);
  transform-origin: 0 50%;
  transform: scaleX(0);
  /* Deliberately not a real progress figure -- it eases toward full and the
     overlay leaves when the page is actually ready, so it never sits at 100%
     waiting or claims a number it does not know. */
  animation: pl-progress 2.4s cubic-bezier(.25, .8, .3, 1) forwards;
}

@keyframes pl-rise { to { transform: scaleY(1); } }
@keyframes pl-reach { to { transform: scaleX(1); } }
@keyframes pl-in { to { opacity: 1; } }
@keyframes pl-drop { from { opacity: 0; transform: scaleY(.3); } to { opacity: .9; transform: scaleY(1); } }
@keyframes pl-progress { to { transform: scaleX(1); } }

/* ---------- phones ---------- */
@media (max-width: 560px) {
  .pl-site { height: 104px; gap: 8px; }
  .pl-bar { width: 20px; }
  .pl-bar:nth-child(1) { height: 42px; }
  .pl-bar:nth-child(2) { height: 70px; }
  .pl-bar:nth-child(3) { height: 104px; }
  .pl-bar:nth-child(4) { height: 60px; }
  .pl-bar:nth-child(5) { height: 80px; }
  .pl-crane { bottom: 104px; }
  .pl-ground { width: 200px; margin-left: -100px; }
  .pl-logo { width: 124px; }
  .pl-inner { gap: 26px; }
}

/* Someone who has asked for less motion still needs the overlay to leave, so
   the build-up is skipped and everything is shown in its finished state. */
@media (prefers-reduced-motion: reduce) {
  .pl-bar,
  .pl-crane-mast,
  .pl-crane-jib,
  .pl-crane-hook,
  .pl-ground,
  .pl-logo,
  .pl-progress-fill {
    animation: none;
    opacity: 1;
    transform: none;
  }

  .preloader { transition: none; }
}
