/* ════════════════════════════════════════════════════════════════════════
   MAKKA · Design System V3
   Deep black · charcoal · gunmetal · metallic silver · ruby · dark crimson

   V3 scroll policy: NATIVE. No Lenis, no wheel interception, no scroll
   hijacking. Motion is triggered BY scroll, never driven INSTEAD of it.
   ════════════════════════════════════════════════════════════════════════ */

/* ── 1 · TOKENS ─────────────────────────────────────────────────────────── */
:root{
  --void:#050506; --ink:#0a0a0c; --charcoal:#111114; --graphite:#17181c;
  --gunmetal:#23262c; --slate:#31353d;

  --steel:#7d8592; --silver:#b9c0c9; --chrome:#e9edf2;
  --metal:linear-gradient(145deg,#3a3f47,#8d949e 22%,#d7dce2 42%,#767d87 62%,#2c3037 88%);
  --metal-btn:linear-gradient(145deg,#c9cfd6,#f2f5f8 38%,#aeb5bf 74%,#dfe4e9);
  --metal-edge:linear-gradient(180deg,rgba(233,237,242,.30),rgba(233,237,242,.04) 40%,transparent);

  --ruby:#e01b24; --ruby-hi:#ff3d43; --crimson:#8b0f16; --glow:rgba(224,27,36,.42);
  /* --ruby-hi tops out at 4.14:1 on pure black, so it can never pass AA for
     small text no matter how dark the surface behind it is. This tint keeps
     the brand hue and clears 4.5:1 — use it for ruby TEXT, not for fills. */
  --ruby-txt:#ff7176;

  --bg:var(--void);
  --surface:rgba(255,255,255,.030); --surface-2:rgba(255,255,255,.055);
  --glass:rgba(18,19,23,.72);
  --line:rgba(233,237,242,.11); --line-2:rgba(233,237,242,.20);
  --text:#eceff3; --text-2:#a2aab5; --text-3:#9aa2ae;

  --s1:.5rem; --s2:1rem; --s3:1.5rem; --s4:2rem; --s5:3rem; --s6:4rem; --s7:5rem; --s8:6.5rem;
  --r:12px; --r-lg:20px; --r-xl:28px;
  --maxw:1340px; --hdr-h:68px;

  /* Motion system — micro 200-350 · reveal 400-700 · scene 700-1200 */
  --t-micro:250ms; --t-reveal:520ms; --t-scene:900ms;
  --e-out:cubic-bezier(.16,1,.3,1); --e-io:cubic-bezier(.76,0,.24,1);

  --fs-display:clamp(2.4rem,6.4vw,6rem);
  --fs-h2:clamp(1.8rem,3.8vw,3.2rem);
  --fs-h3:clamp(1.1rem,1.8vw,1.5rem);
  --fs-body:clamp(1rem,1.05vw,1.08rem);
}

/* ── 2 · RESET ──────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
*{margin:0;padding:0}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:calc(var(--hdr-h) + 12px)}
body{
  background:var(--bg);color:var(--text);
  font-family:"Tajawal",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:var(--fs-body);line-height:1.75;
  -webkit-font-smoothing:antialiased;overflow-x:clip;
}
html[lang="en"] body{font-family:"Inter","Tajawal",system-ui,sans-serif}
img,svg,canvas,video{display:block;max-width:100%}
img{height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
ul,ol{list-style:none}
:focus-visible{outline:2px solid var(--ruby-hi);outline-offset:3px;border-radius:4px}
::selection{background:var(--ruby);color:#fff}
.lat{font-family:"Space Grotesk","Tajawal",sans-serif;direction:ltr;unicode-bidi:isolate}
html[lang="en"] .lat{unicode-bidi:normal}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip-link{position:fixed;inset-block-start:-100px;inset-inline-start:1rem;z-index:300;background:var(--ruby);
  color:#fff;padding:.7rem 1.2rem;border-radius:0 0 var(--r) var(--r);transition:inset-block-start var(--t-micro)}
.skip-link:focus{inset-block-start:0}

/* ── 3 · LAYOUT + SECTION RHYTHM ────────────────────────────────────────── */
.wrap{width:min(100% - 2.5rem,var(--maxw));margin-inline:auto}
.sec{position:relative;padding:var(--s8) 0;z-index:1}
/* DEFERRED RENDERING — read this before re-adding it to .sec.
   This used to be `.sec:not(.sec--live){content-visibility:auto}`, i.e. the
   property was ADDED and REMOVED by a class an IntersectionObserver toggled.
   Two costs came with that, and both landed at section boundaries:
     · flipping content-visibility is a style recalc plus a full layout AND
       first paint of the whole subtree inside one frame; and
     · every section shared one 700px intrinsic placeholder, so a section that
       really measures 628px or 1444px resized the document the moment it
       rendered — the scrollbar moved under the wheel.
   That is the stutter felt on the clients page between the government wall and
   the pending wall. Deferral now applies ONLY where the box size is fully
   determined by CSS (width + aspect-ratio), so nothing can resize on render. */
.pcard{content-visibility:auto}
.sec--tight{padding:var(--s6) 0}
.sec--charcoal{background:linear-gradient(180deg,transparent,var(--charcoal) 16%,var(--charcoal) 84%,transparent)}
.sec--graphite{background:linear-gradient(180deg,transparent,var(--graphite) 20%,var(--graphite) 80%,transparent)}
.sec--ruby{background:radial-gradient(90% 60% at 50% 0%,rgba(224,27,36,.10),transparent 62%),
  linear-gradient(180deg,transparent,var(--ink) 18%,var(--ink) 82%,transparent)}

.eyebrow{display:inline-flex;align-items:center;gap:.65rem;font-size:.73rem;font-weight:700;
  letter-spacing:.2em;color:var(--ruby-txt);text-transform:uppercase;margin-bottom:var(--s2)}
.eyebrow::before{content:"";width:26px;height:1px;background:var(--ruby);box-shadow:0 0 8px var(--glow)}
h1,h2,h3,h4{line-height:1.16;font-weight:800;letter-spacing:-.02em;text-wrap:balance}
h2{font-size:var(--fs-h2);margin-bottom:var(--s3)}
h3{font-size:var(--fs-h3)}
.lead{font-size:clamp(1.02rem,1.4vw,1.2rem);color:var(--text-2);max-width:64ch;text-wrap:pretty}
.sec-head{margin-bottom:var(--s5)}

/* ── 4 · REVEAL (IntersectionObserver + CSS — no GSAP) ──────────────────── */
[data-rv]{opacity:0;transition:opacity var(--t-reveal) var(--e-out),transform var(--t-reveal) var(--e-out),
  filter var(--t-reveal) var(--e-out),clip-path var(--t-scene) var(--e-out)}
[data-rv="up"]{transform:translateY(34px)}
[data-rv="fade"]{transform:none}
[data-rv="blur"]{filter:blur(12px);transform:scale(.97)}
[data-rv="wipe"]{clip-path:inset(0 100% 0 0);opacity:1}
html[dir="ltr"] [data-rv="wipe"]{clip-path:inset(0 0 0 100%)}
[data-rv="persp"]{transform:perspective(900px) rotateY(10deg) translateY(20px)}
[data-rv].in{opacity:1;transform:none;filter:none;clip-path:inset(0 0 0 0)}
[data-rv-d="1"]{transition-delay:70ms}  [data-rv-d="2"]{transition-delay:140ms}
[data-rv-d="3"]{transition-delay:210ms} [data-rv-d="4"]{transition-delay:280ms}
[data-rv-d="5"]{transition-delay:350ms} [data-rv-d="6"]{transition-delay:420ms}

/* ── 5 · INTRO — full-viewport cinematic entrance ───────────────────────── */
#intro{position:fixed;inset:0;z-index:250;background:var(--void);overflow:hidden;
  animation:introFail .5s ease 5.4s forwards}          /* failsafe if JS dies */
@keyframes introFail{to{opacity:0;visibility:hidden;pointer-events:none}}
#intro.js{animation:none}
#intro canvas{position:absolute;inset:0;width:100%;height:100%}
/* The progress bar and wordmark were removed on purpose: a bar is what made
   the entry read as a loader. The canvas carries the whole moment. */
.skip{position:absolute;inset-block-end:var(--s4);inset-inline-end:var(--s4);font-size:.75rem;
  letter-spacing:.12em;color:var(--text-3);border:1px solid var(--line);padding:.5rem 1.1rem;border-radius:999px;z-index:2}
.skip:hover{color:var(--chrome);border-color:var(--line-2)}

/* ── 6 · HEADER + MEGA MENU ─────────────────────────────────────────────── */
.hdr{position:fixed;inset-block-start:0;inset-inline:0;z-index:120;height:var(--hdr-h);
  display:flex;align-items:center;border-block-end:1px solid transparent;transition:border-color var(--t-micro)}
/* backdrop-filter on ::before — on .hdr it would become the containing block
   for the fixed mobile nav and break its off-screen transform. */
.hdr::before{content:"";position:absolute;inset:0;z-index:-1;background:rgba(8,8,10,.88);
  backdrop-filter:blur(16px);opacity:0;transition:opacity var(--t-micro)}
/* At the top of the page the header is transparent, so nav text sits on
   whatever the hero happens to show — and the hero is a moving film. Measured
   from rendered pixels, "About" over the bright monolith came out at 3.22:1.
   A soft top scrim gives the nav a guaranteed dark ground; it fades out once
   the solid stuck background takes over. */
.hdr::after{content:"";position:absolute;inset-inline:0;inset-block-start:0;z-index:-2;
  block-size:calc(var(--hdr-h) * 2.1);pointer-events:none;
  background:linear-gradient(to bottom,rgba(4,4,6,.90),rgba(4,4,6,.55) 52%,transparent);
  transition:opacity var(--t-micro)}
.hdr.stuck::after{opacity:0}
.hdr.stuck::before{opacity:1}
.hdr.stuck{border-block-end-color:var(--line)}
/* NO width:100% here. .hdr-in also carries .wrap, and .wrap's whole job is
   width:min(100% - 2.5rem, --maxw) — the page gutter. A same-specificity
   width:100% declared later silently cancelled it, which is why the logo sat
   flush against the right edge of the window and read as clipped. (Identical
   mistake to the one .scrub-copy made with inline-size.) */
.hdr-in{display:flex;align-items:center;justify-content:space-between;gap:var(--s3)}
.brand img{width:142px}
.nav{display:flex;align-items:center;gap:1.15rem}
.nav-link{font-size:.88rem;color:var(--silver);position:relative;padding:.35rem 0;white-space:nowrap;
  transition:color var(--t-micro)}
.nav-link::after{content:"";position:absolute;inset-block-end:0;inset-inline-start:0;width:0;height:1.5px;
  background:var(--ruby);transition:width var(--t-micro) var(--e-out)}
.nav-link:hover,.nav-link[aria-current="page"]{color:var(--chrome)}
.nav-link:hover::after,.nav-link[aria-current="page"]::after{width:100%}
.hdr-tools{display:flex;align-items:center;gap:.55rem}
.lang{display:inline-flex;border:1px solid var(--line);border-radius:999px;overflow:hidden}
.lang a,.lang span{padding:.45rem .85rem;font-size:.78rem;font-weight:700;letter-spacing:.06em;
  color:var(--silver);min-height:44px;display:grid;place-items:center;transition:var(--t-micro)}
.lang [aria-current="true"]{background:var(--ruby);color:#fff}
.lang a:hover{color:var(--chrome)}
.nav a.btn,.nav a.btn:hover{color:#fff}
.nav a.btn::after{display:none}

.has-mega{position:relative}
.mega{position:fixed;inset-block-start:var(--hdr-h);inset-inline:0;background:rgba(10,10,12,.97);
  backdrop-filter:blur(18px);border-block-end:1px solid var(--line);
  opacity:0;visibility:hidden;translate:0 -10px;transition:opacity var(--t-micro),translate var(--t-micro),visibility 0s linear var(--t-micro);
  z-index:119;box-shadow:0 30px 60px -30px #000}
.has-mega:hover .mega,.mega:hover,.mega.open{opacity:1;visibility:visible;translate:0 0;transition-delay:0s}
.mega-in{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s4);padding:var(--s5) 0}
.mega-col h4{font-size:.72rem;letter-spacing:.18em;color:var(--ruby-hi);text-transform:uppercase;
  margin-bottom:var(--s2);display:flex;align-items:center;gap:.5rem}
.mega-col h4 svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.7}
.mega-col li{margin-bottom:.15rem}
.mega-col a{display:block;padding:.45rem .6rem;margin-inline:-.6rem;border-radius:8px;font-size:.9rem;
  color:var(--text-2);transition:var(--t-micro)}
.mega-col a:hover{background:var(--surface-2);color:var(--chrome)}
.burger{display:none;width:44px;height:44px;place-items:center;align-content:center;gap:5px}
.burger span{display:block;width:22px;height:2px;background:var(--chrome);transition:var(--t-micro) var(--e-io)}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* ── 7 · BUTTONS ────────────────────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.55rem;padding:.85rem 1.7rem;
  border-radius:999px;font-weight:700;font-size:.94rem;min-height:48px;position:relative;
  transition:transform var(--t-micro) var(--e-out),box-shadow var(--t-micro),border-color var(--t-micro),color var(--t-micro)}
/* fill is constant on hover — lightening it drops white text below AA */
.btn-primary{background:var(--ruby);color:#fff;box-shadow:0 8px 30px -12px var(--glow)}
.btn-primary:hover{transform:translateY(-2px);box-shadow:0 16px 46px -12px rgba(224,27,36,.85)}
.btn-ghost{border:1px solid var(--line-2);color:var(--chrome)}
.btn-ghost:hover{border-color:var(--ruby);color:var(--ruby-hi);transform:translateY(-2px)}
.btn-metal{background:var(--metal-btn);color:#0b0b0d;font-weight:800}
.btn-metal:hover{transform:translateY(-2px);box-shadow:0 16px 40px -14px rgba(233,237,242,.55)}
.btn-sm{padding:.55rem 1.15rem;min-height:44px;font-size:.86rem}
.btn-row{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:var(--s4)}

/* ── 8 · FLOATING DOCK ──────────────────────────────────────────────────── */
.dock{position:fixed;inset-inline-end:clamp(.7rem,2vw,1.4rem);inset-block-end:clamp(1rem,4vh,2rem);
  z-index:130;display:grid;gap:.6rem}
.dock a{width:54px;height:54px;border-radius:50%;display:grid;place-items:center;position:relative;
  border:1px solid var(--line-2);background:var(--glass);backdrop-filter:blur(10px);
  transition:transform var(--t-micro) var(--e-out),background var(--t-micro),border-color var(--t-micro)}
.dock a svg{width:24px;height:24px;fill:var(--chrome);transition:fill var(--t-micro)}
.dock a:hover{transform:scale(1.08)}
.dock .wa{border-color:rgba(37,211,102,.35)}
.dock .wa:hover{background:#25d366;border-color:#25d366}
.dock .wa svg{fill:#25d366}
.dock .wa:hover svg{fill:#fff}
.dock .tel:hover{background:var(--ruby);border-color:var(--ruby)}
.dock .tel:hover svg{fill:#fff}
.dock a::after{content:attr(data-label);position:absolute;inset-inline-end:calc(100% + .55rem);
  white-space:nowrap;font-size:.78rem;background:var(--glass);border:1px solid var(--line);
  padding:.35rem .75rem;border-radius:999px;opacity:0;pointer-events:none;
  transition:opacity var(--t-micro);backdrop-filter:blur(8px)}
.dock a:hover::after,.dock a:focus-visible::after{opacity:1}

/* ── 9 · HERO — layered video, HTML copy on top ─────────────────────────── */
.hero{position:relative;min-height:100svh;display:grid;align-items:end;overflow:hidden;
  padding-block:calc(var(--hdr-h) + var(--s6)) var(--s7)}
.hero-media{position:absolute;inset:0;z-index:0}
.hero-media img,.hero-media video{width:100%;height:100%;object-fit:cover}
/* Scrim guarantees text contrast regardless of what the video frame shows. */
.hero-scrim{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(to left,rgba(5,5,6,.93) 0%,rgba(5,5,6,.80) 34%,rgba(5,5,6,.28) 66%,rgba(5,5,6,.55) 100%),
    linear-gradient(to top,rgba(5,5,6,.95),transparent 45%)}
html[dir="ltr"] .hero-scrim{background:
  linear-gradient(to right,rgba(5,5,6,.93) 0%,rgba(5,5,6,.80) 34%,rgba(5,5,6,.28) 66%,rgba(5,5,6,.55) 100%),
  linear-gradient(to top,rgba(5,5,6,.95),transparent 45%)}
.hero-copy{position:relative;z-index:2;max-width:min(46rem,90%)}
.hero h1{font-size:var(--fs-display);font-weight:900}
.hero h1 span{display:block}
.hero .ruby{color:var(--ruby-hi);text-shadow:0 0 40px var(--glow)}
.hero .lead{margin-top:var(--s3)}
.hero-meta{display:flex;flex-wrap:wrap;gap:var(--s4);margin-top:var(--s5);padding-block-start:var(--s3);
  border-block-start:1px solid var(--line-2);position:relative;z-index:2}
.hero-meta b{display:block;font-family:"Space Grotesk",sans-serif;font-size:1.6rem;line-height:1.1;color:var(--chrome)}
.hero-meta span{font-size:.78rem;color:var(--text-2)}
.scroll-cue{position:absolute;inset-block-end:var(--s3);inset-inline-start:50%;translate:-50% 0;z-index:2;
  display:grid;justify-items:center;gap:.4rem;font-size:.66rem;letter-spacing:.24em;color:var(--text-3)}
.scroll-cue i{display:block;width:1px;height:34px;background:linear-gradient(var(--ruby),transparent);
  animation:cue 2.4s var(--e-io) infinite}
@keyframes cue{0%{transform:scaleY(0);transform-origin:top}50%{transform:scaleY(1);transform-origin:top}
  51%{transform-origin:bottom}100%{transform:scaleY(0);transform-origin:bottom}}
/* page hero (inner pages) */
.phero{position:relative;padding-block:calc(var(--hdr-h) + var(--s7)) var(--s6);overflow:hidden}
.phero::after{content:"";position:absolute;inset:0;z-index:-1;
  background:radial-gradient(70% 90% at 85% 10%,rgba(224,27,36,.13),transparent 60%)}
html[dir="ltr"] .phero::after{background:radial-gradient(70% 90% at 15% 10%,rgba(224,27,36,.13),transparent 60%)}
.crumb{display:flex;gap:.5rem;font-size:.8rem;color:var(--text-3);margin-bottom:var(--s2);flex-wrap:wrap}
.crumb a:hover{color:var(--chrome)}
.crumb li+li::before{content:"/";margin-inline-end:.5rem;color:var(--line-2)}
.crumb ol{display:flex;gap:.5rem;flex-wrap:wrap}

/* ── 10 · BENTO STATISTICS ──────────────────────────────────────────────── */
.bento{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s2)}
.stat{position:relative;overflow:hidden;border:1px solid var(--line);border-radius:var(--r-lg);
  padding:var(--s4);background:var(--surface);display:flex;flex-direction:column;justify-content:flex-end;
  min-height:170px;transition:border-color var(--t-reveal),background var(--t-reveal)}
.stat::before{content:"";position:absolute;inset-block-start:0;inset-inline:0;height:1px;background:var(--metal-edge)}
.stat:hover{border-color:var(--line-2);background:var(--surface-2)}
.stat b{display:block;font-family:"Space Grotesk",sans-serif;font-weight:700;line-height:.92;
  color:var(--chrome);font-size:clamp(2.1rem,4vw,3.1rem);letter-spacing:-.03em}
.stat span{display:block;margin-top:.5rem;color:var(--text);font-size:.95rem;font-weight:500}
.stat small{display:block;color:var(--text-2);font-size:.83rem}
.stat em{display:block;margin-top:var(--s2);font-style:normal;font-size:.72rem;color:var(--text-3)}
/* hero tile — the strongest verified metric dominates */
.stat--hero{grid-column:span 2;grid-row:span 2;min-height:360px;
  background:radial-gradient(120% 90% at 85% 15%,rgba(224,27,36,.18),transparent 58%),var(--surface)}
html[dir="ltr"] .stat--hero{background:radial-gradient(120% 90% at 15% 15%,rgba(224,27,36,.18),transparent 58%),var(--surface)}
.stat--hero b{font-size:clamp(3.6rem,9vw,7.5rem);
  background:var(--metal);-webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent}
.stat--hero span{font-size:1.15rem;font-weight:700;color:var(--chrome)}
.stat--wide{grid-column:span 2}
/* 1fr is minmax(auto,1fr): without this a long unbreakable figure inflates its
   track and the sibling columns collapse. */
.stat{min-width:0}
.stat b,.stat span,.stat em{min-width:0;overflow-wrap:anywhere}

/* ── 11 · CARDS ─────────────────────────────────────────────────────────── */
.grid{display:grid;gap:var(--s3)}
.g2{grid-template-columns:repeat(2,1fr)} .g3{grid-template-columns:repeat(3,1fr)} .g4{grid-template-columns:repeat(4,1fr)}
.grid>*{min-width:0}

.card{position:relative;overflow:hidden;border:1px solid var(--line);border-radius:var(--r-lg);
  background:var(--surface);display:flex;flex-direction:column;
  transition:border-color var(--t-reveal),transform var(--t-reveal) var(--e-out),background var(--t-reveal)}
.card::before{content:"";position:absolute;inset-block-start:0;inset-inline:0;height:1px;background:var(--metal-edge);z-index:2}
.card:hover{border-color:var(--line-2);transform:translateY(-4px);background:var(--surface-2)}
.card-media{position:relative;aspect-ratio:16/10;overflow:hidden;background:var(--charcoal)}
.card-media img{width:100%;height:100%;object-fit:cover;transition:transform var(--t-scene) var(--e-out)}
.card:hover .card-media img{transform:scale(1.06)}
.card-body{padding:var(--s3);display:flex;flex-direction:column;gap:.5rem;flex:1}
/* Stretched link — the card title anchor covers the whole card, so the touch
   target is the card (≥300×260) rather than a 20px line of text. Any other
   interactive child inside the card must sit above it (z-index:2). */
.card h3 a{position:static}
.card h3 a::after{content:"";position:absolute;inset:0;z-index:1;border-radius:inherit}
.card h3 a:hover{color:var(--ruby-hi)}
.card h3 a:focus-visible{outline:none}
.card:has(h3 a:focus-visible){outline:2px solid var(--ruby-hi);outline-offset:3px}
.card .card-body>*:not(h3){position:relative;z-index:2}
.card p{color:var(--text-2);font-size:.93rem}
.card .num{font-family:"Space Grotesk",sans-serif;font-size:.75rem;letter-spacing:.16em;color:var(--ruby-hi)}
.tags{display:flex;flex-wrap:wrap;gap:.38rem;margin-top:auto;padding-top:.5rem}
.tags li,.tags span{font-size:.72rem;color:var(--silver);border:1px solid var(--line);padding:.24rem .62rem;border-radius:999px}
.badge{position:absolute;inset-block-start:.7rem;inset-inline-start:.7rem;z-index:3;font-size:.68rem;
  font-weight:700;letter-spacing:.06em;padding:.3rem .7rem;border-radius:999px;backdrop-filter:blur(8px)}
/* Opaque, not tinted: a badge overlays a photograph, so a translucent fill
   leaves the label sitting on whatever the image happens to be — measured at
   1.00:1 over a bright signage shot. These pairs are ≥7:1 on their own plate. */
.badge--real{background:#08301b;color:#7cf0ad;border:1px solid rgba(124,240,173,.42)}
.badge--concept{background:#3d070c;color:#ff9095;border:1px solid rgba(255,144,149,.40)}

/* ── 12 · RAILS — native scroll + snap. No JS ticker. ───────────────────── */
.rail-head{display:flex;align-items:end;justify-content:space-between;gap:var(--s3);flex-wrap:wrap}
.rail-nav{display:flex;gap:.5rem}
.rail-btn{width:44px;height:44px;border-radius:50%;border:1px solid var(--line-2);display:grid;place-items:center;
  color:var(--silver);transition:var(--t-micro)}
.rail-btn:hover:not(:disabled){border-color:var(--ruby);color:var(--ruby-hi)}
.rail-btn:disabled{opacity:.3;cursor:default}
.rail-btn svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2}
.rail{display:flex;gap:var(--s3);overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;scroll-padding-inline:var(--s3);
  padding-block:.35rem var(--s3);padding-inline:max(1.25rem,calc((100vw - var(--maxw))/2));
  cursor:grab;scrollbar-width:thin;scrollbar-color:var(--ruby) transparent;-webkit-overflow-scrolling:touch}
.rail::-webkit-scrollbar{height:4px}
.rail::-webkit-scrollbar-thumb{background:var(--ruby);border-radius:4px}
.rail::-webkit-scrollbar-track{background:var(--line)}
.rail.drag{cursor:grabbing;scroll-snap-type:none;scroll-behavior:auto}
.rail>*{scroll-snap-align:center;flex:0 0 auto}

/* phone-proportioned card — art-directed, never a blind cover-crop */
.pcard{width:clamp(190px,22vw,258px);aspect-ratio:9/19.5;position:relative;overflow:hidden;
  border-radius:28px;border:1px solid var(--line-2);background:var(--charcoal);
  box-shadow:0 22px 50px -24px #000;transition:border-color var(--t-reveal),transform var(--t-reveal) var(--e-out)}
.pcard:hover{border-color:var(--ruby);transform:translateY(-6px)}
/* blurred same-image backdrop fills the tall frame; the real image sits
   contained on top, so square sources are never violently cropped */
.pcard-bg{position:absolute;inset:-12%;background-size:cover;background-position:center;
  filter:blur(26px) saturate(1.25) brightness(.5);transform:scale(1.15)}
.pcard-fg{position:absolute;inset:0;display:grid;place-items:center;padding:.5rem}
.pcard-fg img{width:100%;height:auto;max-height:100%;object-fit:contain;border-radius:16px;
  transition:transform var(--t-scene) var(--e-out)}
.pcard:hover .pcard-fg img{transform:scale(1.04)}
.pcard figcaption{position:absolute;inset-block-end:0;inset-inline:0;padding:var(--s5) .85rem .85rem;
  /* reaches full opacity well before the text starts — a plain
     transparent→black ramp left the title on the bright part of the artwork */
  background:linear-gradient(180deg,transparent 0,rgba(5,5,6,.55) 26%,
    rgba(5,5,6,.93) 56%,rgba(5,5,6,.99) 100%);z-index:2}
.pcard figcaption b{display:block;font-size:.85rem;line-height:1.35}
.pcard figcaption span{font-size:.7rem;color:var(--silver)}

.wcard{width:clamp(250px,28vw,380px);position:relative;overflow:hidden;border-radius:var(--r-lg);
  border:1px solid var(--line);background:var(--charcoal);
  transition:border-color var(--t-reveal),transform var(--t-reveal) var(--e-out)}
.wcard img{width:100%;aspect-ratio:4/3;object-fit:cover;transition:transform var(--t-scene) var(--e-out)}
.wcard:hover{border-color:var(--ruby)}
.wcard:hover img{transform:scale(1.05)}
.wcard figcaption{position:absolute;inset-block-end:0;inset-inline:0;padding:var(--s5) .9rem .8rem;
  /* opaque before the first line of text, not after it — the caption overlays
     a photograph and a late ramp left the title on the bright pixels */
  background:linear-gradient(180deg,transparent 0,rgba(5,5,6,.62) 28%,
    rgba(5,5,6,.95) 58%,rgba(5,5,6,.99) 100%)}
.wcard figcaption b{display:block;font-size:.9rem}
.wcard figcaption span{font-size:.73rem;color:var(--silver)}

/* perspective rail — depth applied by JS on scroll, cheap transform only */
.prail>*{transition:transform 520ms var(--e-out),opacity 520ms var(--e-out)}
.pitem{width:clamp(240px,32vw,430px);border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);
  background:var(--charcoal);transform-style:preserve-3d}
.pitem img{width:100%;aspect-ratio:1;object-fit:cover}
.pitem figcaption{padding:.8rem 1rem;border-block-start:1px solid var(--line)}
.pitem figcaption b{display:block;font-size:.92rem}
.pitem figcaption span{font-size:.75rem;color:var(--text-2)}

/* marquee — CSS only, paused offscreen by IntersectionObserver */
.marquee{overflow:hidden;position:relative;padding-block:.5rem;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 10%,#000 90%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 10%,#000 90%,transparent)}
.marquee-track{display:flex;gap:var(--s3);width:max-content;animation:slide 48s linear infinite;animation-play-state:paused}
.marquee.run .marquee-track{animation-play-state:running}
.marquee--rev .marquee-track{animation-direction:reverse;animation-duration:62s}
.marquee:hover .marquee-track{animation-play-state:paused}
@keyframes slide{to{transform:translateX(-50%)}}
.chip{border:1px solid var(--line);border-radius:var(--r);padding:.8rem 1.35rem;white-space:nowrap;
  color:var(--silver);font-weight:600;font-size:.92rem;background:var(--surface);position:relative;
  overflow:hidden;transition:var(--t-micro)}
.chip::before{content:"";position:absolute;inset-block-start:0;inset-inline:0;height:1px;background:var(--metal-edge)}
.chip:hover{border-color:var(--ruby);color:var(--chrome);background:var(--surface-2)}
.chip small{display:block;font-size:.7rem;color:var(--text-3);font-weight:400}

/* ── 13 · SCROLL STORY — canvas scene + text ────────────────────────────── */
.story{position:relative}
.story-stage{position:sticky;inset-block-start:var(--hdr-h);height:calc(100svh - var(--hdr-h));
  display:grid;grid-template-columns:1fr 1fr;align-items:center;gap:var(--s5);overflow:hidden}
.story-visual{position:relative;aspect-ratio:4/3;border-radius:var(--r-xl);overflow:hidden;
  border:1px solid var(--line-2);background:var(--charcoal)}
/* When the motion scene is running the canvas IS the picture; the <img>
   stack stays in the DOM as the no-JS / reduced-motion fallback and as the
   source the canvas draws from. */
.story-cv{position:absolute;inset:0;width:100%;height:100%;z-index:2;border-radius:inherit}
.story-visual.has-cv img{opacity:0 !important}
.story-visual img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;
  transition:opacity 620ms var(--e-out),transform 900ms var(--e-out);transform:scale(1.08)}
.story-visual img.on{opacity:1;transform:scale(1)}
.story-visual::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,transparent 55%,rgba(5,5,6,.65))}
.story-steps{position:relative}
.story-step{position:absolute;inset-block-start:50%;translate:0 -50%;inset-inline:0;opacity:0;
  transition:opacity 480ms var(--e-out),transform 620ms var(--e-out);transform:translateY(24px);pointer-events:none}
.story-step.on{opacity:1;transform:translateY(0);pointer-events:auto}
.story-step .k{font-family:"Space Grotesk",sans-serif;font-size:.74rem;letter-spacing:.3em;color:var(--ruby-hi)}
.story-step .v{font-size:clamp(1.5rem,3.4vw,2.6rem);font-weight:900;line-height:1.2;margin-block:.6rem}
.story-step .d{color:var(--text-2);max-width:44ch}
.story-rail{position:absolute;inset-block-end:6%;inset-inline:0;height:2px;background:var(--line);border-radius:2px;overflow:hidden}
.story-rail i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--crimson),var(--ruby-hi));
  box-shadow:0 0 12px var(--glow);transition:width 120ms linear}
.story-spacer{height:480vh}

/* ── 14 · PORTFOLIO ─────────────────────────────────────────────────────── */
.filters{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:var(--s4)}
.filter{padding:.55rem 1.1rem;border-radius:999px;border:1px solid var(--line);font-size:.84rem;
  color:var(--silver);min-height:44px;transition:var(--t-micro);display:inline-flex;align-items:center;gap:.4rem}
.filter i{font-style:normal;font-size:.72rem;color:var(--text-3)}
.filter[aria-pressed="true"]{background:var(--ruby);border-color:var(--ruby);color:#fff}
.filter[aria-pressed="true"] i{color:rgba(255,255,255,.7)}
.filter:hover:not([aria-pressed="true"]){border-color:var(--ruby);color:var(--chrome)}
.pf-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(258px,1fr));gap:var(--s3)}
.pf{position:relative;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);
  background:var(--charcoal);transition:border-color var(--t-reveal),transform var(--t-reveal) var(--e-out);
  text-align:start;width:100%;display:block}
.pf.hide{display:none}
.pf img{width:100%;aspect-ratio:4/3;object-fit:cover;transition:transform var(--t-scene) var(--e-out)}
.pf:hover{border-color:var(--ruby);transform:translateY(-5px)}
.pf:hover img{transform:scale(1.07)}
.pf figcaption{padding:.85rem 1rem}
.pf figcaption b{display:block;font-size:.93rem}
.pf figcaption span{font-size:.76rem;color:var(--text-2)}
.pf-count{position:absolute;inset-block-start:.7rem;inset-inline-end:.7rem;z-index:3;font-size:.7rem;
  background:rgba(5,5,6,.8);border:1px solid var(--line-2);padding:.22rem .55rem;border-radius:999px;
  color:var(--silver);backdrop-filter:blur(6px)}
.pf-empty{padding:var(--s6) 0;text-align:center;color:var(--text-2)}

/* ── 15 · LIGHTBOX ──────────────────────────────────────────────────────── */
dialog.lb{border:0;padding:0;background:transparent;max-width:100vw;max-height:100vh;width:100vw;height:100dvh;
  color:var(--text);overflow:hidden}
dialog.lb::backdrop{background:rgba(3,3,4,.94);backdrop-filter:blur(10px)}
.lb-in{position:relative;width:100%;height:100%;display:grid;grid-template-rows:auto 1fr auto;padding:.75rem}
.lb-top{display:flex;align-items:center;justify-content:space-between;gap:var(--s2);padding:.35rem .5rem}
.lb-title b{display:block;font-size:.98rem}
.lb-title span{font-size:.8rem;color:var(--text-2)}
.lb-stage{position:relative;display:grid;place-items:center;overflow:hidden;touch-action:pan-y}
.lb-stage img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;border-radius:var(--r);
  transition:opacity 240ms var(--e-out)}
.lb-bottom{display:flex;align-items:center;justify-content:center;gap:var(--s2);padding:.5rem}
.lb-count{font-family:"Space Grotesk",sans-serif;font-size:.82rem;color:var(--text-2);min-width:5ch;text-align:center}
.lb-btn{width:48px;height:48px;border-radius:50%;border:1px solid var(--line-2);display:grid;place-items:center;
  background:var(--glass);color:var(--chrome);transition:var(--t-micro)}
.lb-btn:hover{border-color:var(--ruby);color:var(--ruby-hi)}
.lb-btn svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:2}
.lb-nav{position:absolute;inset-block-start:50%;translate:0 -50%;z-index:2}
.lb-prev{inset-inline-start:.5rem} .lb-next{inset-inline-end:.5rem}
.lb-cap{text-align:center;font-size:.85rem;color:var(--text-2);padding:.35rem 1rem}

/* ── 16 · WEBSITE CARDS ─────────────────────────────────────────────────── */
.site-card{border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);
  transition:var(--t-reveal) var(--e-out);display:flex;flex-direction:column}
.site-card:hover{border-color:var(--ruby);transform:translateY(-5px)}
.browser{background:var(--ink);padding:.5rem .8rem;display:flex;align-items:center;gap:.4rem;border-block-end:1px solid var(--line)}
.browser i{width:8px;height:8px;border-radius:50%;background:var(--line-2);display:block}
.browser i:first-child{background:var(--ruby)}
.browser .url{flex:1;margin-inline-start:.5rem;background:var(--void);border-radius:999px;padding:.24rem .8rem;
  font-family:"Space Grotesk",sans-serif;font-size:.73rem;color:var(--silver);direction:ltr;text-align:left;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.site-shot{aspect-ratio:16/10;background:
  repeating-linear-gradient(45deg,rgba(255,255,255,.012) 0 12px,transparent 12px 24px),var(--charcoal);
  display:grid;place-items:center;overflow:hidden;position:relative}
.site-shot img{width:100%;height:100%;object-fit:cover;object-position:top}
.site-shot .pending{font-size:.8rem;color:var(--text-3);text-align:center;padding:var(--s3)}
.site-shot .pending svg{width:28px;height:28px;margin:0 auto .5rem;stroke:var(--steel);fill:none;stroke-width:1.5}
.site-body{padding:var(--s3);display:flex;flex-direction:column;gap:.45rem;flex:1}
.site-body h3{font-size:1.05rem}
.site-body p{font-size:.86rem;color:var(--text-2)}
.live{display:inline-flex;align-items:center;gap:.4rem;font-size:.76rem;color:#4ade80}
.live::before{content:"";width:6px;height:6px;border-radius:50%;background:#4ade80;
  box-shadow:0 0 0 0 rgba(74,222,128,.6);animation:pulse 2.2s infinite;animation-play-state:paused}
.marquee.run .live::before,.sec--live .live::before{animation-play-state:running}
.live.dev{color:var(--text-2)}
.live.dev::before{background:var(--text-2);animation:none}
@keyframes pulse{70%{box-shadow:0 0 0 7px rgba(74,222,128,0)}100%{box-shadow:0 0 0 0 rgba(74,222,128,0)}}
.site-actions{display:flex;gap:.5rem;flex-wrap:wrap;margin-top:auto;padding-top:.6rem}

/* ── 17 · BRANCHES ──────────────────────────────────────────────────────── */
.branches{display:grid;grid-template-columns:1fr 1.05fr;gap:var(--s5);align-items:center}
.branches>*{min-width:0}
.branch-list{display:grid;gap:.7rem}
.branch{display:flex;align-items:center;justify-content:space-between;gap:var(--s2);width:100%;text-align:start;
  border:1px solid var(--line);border-radius:var(--r-lg);padding:1rem 1.2rem;background:var(--surface);
  cursor:pointer;position:relative;overflow:hidden;transition:var(--t-micro) var(--e-out)}
.branch::before{content:"";position:absolute;inset-block-start:0;inset-inline:0;height:1px;background:var(--metal-edge)}
.branch[aria-pressed="true"]{border-color:var(--ruby);background:rgba(224,27,36,.08);box-shadow:0 0 34px -18px var(--glow)}
.branch:hover{border-color:var(--line-2)}
.branch b{display:block;font-size:1.05rem}
.branch small{color:var(--text-2);font-size:.8rem}
.hq{font-size:.66rem;letter-spacing:.1em;background:var(--ruby);color:#fff;padding:.24rem .6rem;
  border-radius:999px;font-weight:700;white-space:nowrap}
.branch-actions{display:flex;gap:.4rem;margin-top:.55rem;flex-wrap:wrap}
.map{position:relative;aspect-ratio:1;border:1px solid var(--line);border-radius:var(--r-xl);overflow:hidden;
  background:radial-gradient(circle at 55% 45%,var(--graphite),var(--void) 74%)}
.map svg{width:100%;height:100%}
.map .terr{fill:url(#mapFill);stroke:rgba(233,237,242,.22);stroke-width:.35;stroke-linejoin:round}
.map .grat{stroke:rgba(233,237,242,.05);stroke-width:.25;fill:none}
.pin{cursor:pointer}
/* invisible finger pad — the visible dot is 2.6px in a 100-unit viewBox,
   far below a 44px touch target on a phone-width map */
.pin .hit{fill:transparent;pointer-events:all}
.pin .dot{fill:var(--steel);transition:fill var(--t-micro),r var(--t-micro)}
.pin .halo{fill:none;stroke:var(--ruby);stroke-width:.5;opacity:0}
.pin .lbl{fill:var(--text-2);font-size:2.6px;font-family:"Tajawal",sans-serif;transition:fill var(--t-micro)}
.pin.on .dot{fill:var(--ruby-hi);r:1.9}
.pin.on .halo{opacity:1;animation:halo 2.4s ease-out infinite}
.pin.on .lbl{fill:var(--chrome);font-weight:700}
@keyframes halo{0%{r:2.2;opacity:.85}100%{r:8;opacity:0}}

/* ── 18 · MISC ──────────────────────────────────────────────────────────── */
.notice{border:1px dashed var(--line-2);border-radius:var(--r);padding:var(--s3);
  background:rgba(224,27,36,.05);color:var(--text-2);font-size:.89rem}
.notice b{color:var(--chrome)}
.proof{display:flex;gap:.6rem;align-items:flex-start;border-inline-start:2px solid var(--ruby);
  padding:.7rem 0 .7rem var(--s2);padding-inline-start:var(--s2);color:var(--text-2);font-size:.9rem}
html[dir="rtl"] .proof{border-inline-start:0;border-inline-end:2px solid var(--ruby)}
.faq{display:grid;gap:.7rem}
.faq details{border:1px solid var(--line);border-radius:var(--r);background:var(--surface);overflow:hidden}
.faq summary{padding:1rem 1.2rem;cursor:pointer;font-weight:700;font-size:.98rem;list-style:none;
  display:flex;justify-content:space-between;gap:1rem;align-items:center;min-height:56px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";color:var(--ruby-hi);font-size:1.3rem;line-height:1}
.faq details[open] summary::after{content:"–"}
.faq p{padding:0 1.2rem 1.1rem;color:var(--text-2);font-size:.93rem}
.prose p{margin-bottom:var(--s3);color:var(--text-2);max-width:68ch}
.prose strong{color:var(--chrome)}
.split{display:grid;grid-template-columns:1.05fr .95fr;gap:var(--s5);align-items:center}
.split>*{min-width:0}
.media-frame{border-radius:var(--r-xl);overflow:hidden;border:1px solid var(--line-2);position:relative}
.media-frame img{width:100%;display:block}

/* ── 19 · FORM ──────────────────────────────────────────────────────────── */
.wizard{border:1px solid var(--line);border-radius:var(--r-xl);padding:clamp(1.2rem,3vw,2.4rem);
  background:var(--surface);position:relative;overflow:hidden}
.wizard::before{content:"";position:absolute;inset-block-start:0;inset-inline:0;height:1px;background:var(--metal-edge)}
.steps-head{display:flex;align-items:center;gap:.6rem;margin-bottom:var(--s4);flex-wrap:wrap}
.pip{display:flex;align-items:center;gap:.45rem;font-size:.79rem;color:var(--text-3)}
.pip i{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;border:1px solid var(--line);
  font-style:normal;font-size:.75rem}
.pip.on{color:var(--chrome)} .pip.on i{background:var(--ruby);border-color:var(--ruby);color:#fff}
.pip.done i{border-color:var(--ruby);color:var(--ruby-hi)}
.step{display:none} .step.on{display:block;animation:stepIn .4s var(--e-out)}
@keyframes stepIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.pick-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:.7rem}
/* opaque plate: --surface is a 3% white wash, so inside the ruby-lit contact
   section the label was reading against the red behind it */
.pick{background:var(--ink);border:1px solid var(--line);border-radius:var(--r);padding:1rem .8rem;text-align:center;font-size:.88rem;
  color:var(--silver);min-height:56px;display:grid;place-items:center;
  transition:var(--t-micro) var(--e-out)}
.pick:hover{border-color:var(--line-2);color:var(--chrome);transform:translateY(-2px)}
.pick[aria-pressed="true"]{border-color:var(--ruby);background:rgba(224,27,36,.12);color:#fff}
.form{display:grid;gap:var(--s3);grid-template-columns:repeat(2,1fr)}
.field{display:grid;gap:.4rem} .field.full{grid-column:1/-1}
.field label{font-size:.85rem;color:var(--silver);font-weight:600}
.field input,.field select,.field textarea{background:var(--ink);border:1px solid var(--line);border-radius:var(--r);
  padding:.8rem 1rem;color:var(--chrome);font:inherit;font-size:.94rem;min-height:48px;width:100%;
  transition:border-color var(--t-micro),background var(--t-micro)}
.field textarea{min-height:120px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--ruby);background:var(--charcoal);outline:none}
.field input[aria-invalid="true"]{border-color:var(--ruby-hi);background:rgba(224,27,36,.07)}
.field .err{font-size:.76rem;color:var(--ruby-hi);min-height:1em}
.field option{background:var(--ink)}
.wiz-nav{display:flex;gap:.7rem;margin-top:var(--s4);flex-wrap:wrap}
.hp{position:absolute;inset-inline-start:-9999px;width:1px;height:1px;overflow:hidden}

/* ── 20 · FOOTER ────────────────────────────────────────────────────────── */
.ftr{border-block-start:1px solid var(--line);padding-block:var(--s6) var(--s4);
  background:linear-gradient(180deg,transparent,var(--ink));position:relative;z-index:2}
.ftr-top{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:var(--s4);margin-bottom:var(--s5)}
.ftr h4{font-size:.76rem;letter-spacing:.18em;color:var(--ruby-hi);margin-bottom:var(--s2);text-transform:uppercase}
.ftr li{margin-bottom:.45rem}
.ftr a{color:var(--text-2);font-size:.89rem;transition:color var(--t-micro)}
.ftr a:hover{color:var(--chrome)}
/* `.ftr a` (0,2,0) outranks `.btn-metal` (0,1,0): without this the CTA inside
   the footer renders grey-on-silver at 1.93:1. */
.ftr a.btn-metal,.ftr a.btn-metal:hover{color:#0b0b0d}
.ftr a.btn-primary,.ftr a.btn-primary:hover{color:#fff}
.ftr-word{font-family:"Space Grotesk",sans-serif;font-weight:700;font-size:clamp(2.4rem,14vw,11rem);
  line-height:.84;letter-spacing:-.045em;color:transparent;-webkit-text-stroke:1px rgba(233,237,242,.11);
  text-align:center;margin-block:var(--s4) var(--s3);user-select:none}
.ftr-bot{display:flex;flex-wrap:wrap;gap:var(--s2);justify-content:space-between;align-items:center;
  padding-block-start:var(--s3);border-block-start:1px solid var(--line);font-size:.83rem;color:var(--text-3)}

/* ── 21 · RESPONSIVE ────────────────────────────────────────────────────── */
@media (max-width:1180px){ .nav{gap:.9rem} .nav-link{font-size:.83rem} .brand img{width:126px} }
@media (max-width:1024px){
  /* The pre-reveal rotateY widens the painted box of a full-width figure and
     pushes the page 6px sideways once .split collapses to one column. The tilt
     earns nothing in a single-column layout, so it goes. */
  [data-rv="persp"]{transform:translateY(20px)}
  .g4,.g3{grid-template-columns:repeat(2,1fr)}
  .split,.branches,.story-stage{grid-template-columns:1fr}
  .bento{grid-template-columns:repeat(2,1fr)}
  .stat--hero{grid-column:span 2;grid-row:span 1;min-height:260px}
  .ftr-top{grid-template-columns:1fr 1fr}
  .mega-in{grid-template-columns:repeat(2,1fr);gap:var(--s3);padding:var(--s4) 0}
  /* Below the desktop breakpoint the sticky stage is replaced by a scrolled
     sequence: the picture stays pinned at the top, the chapters flow past it.
     The steps MUST leave absolute positioning here — stacked absolutely with
     a zero-height spacer, only chapter 1 would ever be reachable. */
  .story-stage{height:auto;position:relative;inset-block-start:auto;padding-block:var(--s5);gap:var(--s4)}
  .story-visual{position:sticky;inset-block-start:calc(var(--hdr-h) + .6rem);aspect-ratio:16/10;z-index:1}
  .story-steps{min-height:0}
  .story-step{position:relative;inset-block-start:auto;translate:0;transform:none;
    opacity:.34;pointer-events:auto;margin-block:var(--s6);
    transition:opacity .45s var(--e-out)}
  .story-step:first-child{margin-block-start:var(--s4)}
  .story-step.on{opacity:1}
  .story-rail{position:sticky;inset-block-end:1rem;margin-block-start:var(--s4)}
  .story-spacer{height:0}
}
@media (max-width:760px){
  :root{--s7:3rem;--s8:4rem}
  .burger{display:grid}
  .nav{position:fixed;inset:0;height:100dvh;background:rgba(5,5,6,.985);flex-direction:column;
    justify-content:center;align-items:flex-start;gap:var(--s2);padding:var(--s7) var(--s4);
    translate:0 -100%;visibility:hidden;z-index:140;overflow-y:auto;
    transition:translate .5s var(--e-io),visibility 0s linear .5s}
  .nav.open{translate:0 0;visibility:visible;transition:translate .5s var(--e-io),visibility 0s}
  .nav-link{font-size:1.5rem;opacity:0;translate:0 16px;min-height:52px;display:flex;align-items:center;width:100%}
  .nav.open .nav-link{opacity:1;translate:0 0;transition:opacity .38s var(--e-out),translate .38s var(--e-out)}
  .nav.open .nav-link:nth-child(1){transition-delay:.12s} .nav.open .nav-link:nth-child(2){transition-delay:.17s}
  .nav.open .nav-link:nth-child(3){transition-delay:.22s} .nav.open .nav-link:nth-child(4){transition-delay:.27s}
  .nav.open .nav-link:nth-child(5){transition-delay:.32s} .nav.open .nav-link:nth-child(6){transition-delay:.37s}
  .nav.open .nav-link:nth-child(7){transition-delay:.42s} .nav.open .nav-link:nth-child(8){transition-delay:.47s}
  .nav-link::before{content:attr(data-n);font-family:"Space Grotesk",sans-serif;font-size:.66rem;
    color:var(--ruby);margin-inline-end:.8rem;vertical-align:super;opacity:.8}
  .mega{display:none}
  .g2,.g3,.g4,.form,.ftr-top{grid-template-columns:1fr}
  .bento{grid-template-columns:repeat(2,1fr);gap:.7rem}
  .stat{min-height:132px;padding:var(--s3)}
  .stat--hero{grid-column:1/-1;min-height:210px}
  .stat b{font-size:clamp(1.7rem,7vw,2.3rem)}
  .stat--hero b{font-size:clamp(3rem,16vw,4.6rem)}
  .stat em{display:none}                      /* source line moves to detail pages on mobile */
  .sec{padding:var(--s7) 0}
  .dock a{width:50px;height:50px}
  .dock a::after{display:none}
  .hero{align-items:center;padding-block:calc(var(--hdr-h) + var(--s5)) var(--s6)}
  .hero-meta{gap:var(--s3)} .hero-meta b{font-size:1.3rem}
  .hero-meta div:nth-child(n+3){display:none}  /* two strongest metrics only */
  .rail{padding-inline:1.25rem}
  .pcard{width:min(64vw,240px)}
  .wcard{width:min(76vw,300px)}
  .pitem{width:min(82vw,340px)}
  .lb-nav{inset-block-end:.5rem;inset-block-start:auto;translate:0 0}
  .lb-prev{inset-inline-start:1rem} .lb-next{inset-inline-end:1rem}

  /* Touch targets — WCAG 2.5.8. Every standalone link in a list, a crumb
     trail or a card gets a finger-sized box; inline links inside running
     prose are exempt by the success criterion and are left alone. */
  .ftr li a,.crumb a,.crumb li,.chip,.tab,.mega a,.dock a,.lang a,
  .scard a,.wcard a,.pcard a,.branch-list a,.site-links a{
    min-height:44px;display:inline-flex;align-items:center}
  .ftr li{margin-bottom:0}
  .ftr li a{padding-block:.35rem}
  .crumb,.crumb ol{gap:.15rem .6rem;flex-wrap:wrap;align-items:center}
  .brand{min-height:44px;display:inline-flex;align-items:center}
}
@media (max-width:400px){
  .pick-grid{grid-template-columns:1fr 1fr}
  .bento{grid-template-columns:1fr}
  /* The bento is one column here. A leftover `span 2` would fabricate an
     implicit second track sized to content, squeezing the real column to a
     sliver and stacking the label one character per line. */
  .stat--wide,.stat--hero{grid-column:1/-1}
}

/* ── 22 · REDUCED MOTION ────────────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important}
  [data-rv]{opacity:1 !important;transform:none !important;filter:none !important;clip-path:none !important}
  .marquee-track{animation:none;flex-wrap:wrap;width:auto;justify-content:center}
  .marquee{mask-image:none;-webkit-mask-image:none}
  .story-stage{position:relative;height:auto;inset-block-start:auto}
  .story-step{position:relative;opacity:1;transform:none;inset-block-start:auto;translate:0;margin-bottom:var(--s4)}
  .story-spacer{display:none}
  .story-visual img{opacity:1;transform:none;position:relative}
  .story-visual img+img{display:none}
  .scroll-cue i{animation:none;transform:scaleY(1)}
  #intro{display:none}
  .hero-media video{display:none}
}
/* ── 23 · NO-JS ─────────────────────────────────────────────────────────── */
.no-js #intro{display:none}
.no-js [data-rv]{opacity:1;transform:none;filter:none;clip-path:none}
.no-js .story-step{position:relative;opacity:1;transform:none;inset-block-start:auto;translate:0;margin-bottom:var(--s4)}
.no-js .story-stage{position:relative;height:auto} .no-js .story-spacer{display:none}
.no-js .marquee-track{animation-play-state:running}

/* ── 24 · CLIENT WALL ───────────────────────────────────────────────────── */
/* Monochrome at rest so the wall reads as one system; the client's own colour
   returns on hover. The tile art is real executed work, never a scraped logo. */
.cwall{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:var(--s2)}
.ctile{position:relative;overflow:hidden;border:1px solid var(--line);border-radius:var(--r-lg);
  background:var(--surface);display:flex;flex-direction:column;min-width:0;contain:layout paint;
  transition:border-color var(--t-micro),transform var(--t-reveal) var(--e-out),background var(--t-micro)}
.ctile:hover{border-color:var(--line-2);transform:translateY(-4px);background:var(--surface-2)}
.ct-media{position:relative;aspect-ratio:4/3;overflow:hidden;background:var(--charcoal)}
.ct-media img{width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) contrast(1.06) brightness(.82);
  transition:filter var(--t-reveal) var(--e-out),transform var(--t-scene) var(--e-out)}
.ctile:hover .ct-media img{filter:none;transform:scale(1.05)}
.ct-media::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,transparent 55%,rgba(5,5,6,.72));
  opacity:1;transition:opacity var(--t-micro)}
.ctile:hover .ct-media::after{opacity:.45}
/* no real asset → a typographic monogram, not a logo from an unofficial source */
.ct-mono{display:grid;place-items:center;background:
  radial-gradient(120% 100% at 30% 0%,rgba(224,27,36,.14),transparent 60%),var(--graphite)}
.ct-mono span{font-family:"Space Grotesk",sans-serif;font-weight:700;font-size:2.1rem;
  letter-spacing:.04em;color:transparent;background:var(--metal);-webkit-background-clip:text;background-clip:text}
.ct-body{padding:var(--s2) var(--s3) var(--s3);display:flex;flex-direction:column;gap:.3rem;flex:1;min-width:0}
.ct-body h3{font-size:.98rem;line-height:1.3}
.ct-body p{font-size:.82rem;color:var(--text-2)}
.ct-body .proof{font-size:.76rem;color:var(--text-3)}
@media (max-width:760px){
  .cwall{grid-template-columns:repeat(2,1fr);gap:.7rem}
  .ct-body{padding:.7rem .8rem .9rem}
  .ct-body h3{font-size:.88rem}
}

/* ── 25 · BRANCH PANELS — premium pass ──────────────────────────────────── */
/* The first version read as a thin list beside a faint outline. Bigger panels,
   a map with real presence, and a location pulse you actually notice. */
.branches{gap:var(--s4);align-items:start}
.branch-list{display:flex;flex-direction:column;gap:.9rem}
.branch{width:100%;text-align:start;position:relative;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--r-lg);
  padding:var(--s3) var(--s3) var(--s3);
  background:linear-gradient(140deg,var(--surface),transparent 70%);
  display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s2);
  transition:border-color var(--t-micro),transform var(--t-reveal) var(--e-out),background var(--t-micro)}
.branch::before{content:"";position:absolute;inset-block:0;inset-inline-start:0;width:3px;
  background:linear-gradient(180deg,transparent,var(--ruby),transparent);opacity:0;
  transition:opacity var(--t-micro)}
.branch:hover,.branch[aria-pressed="true"]{border-color:var(--line-2);transform:translateY(-3px);
  background:linear-gradient(140deg,var(--surface-2),transparent 70%)}
.branch:hover::before,.branch[aria-pressed="true"]::before{opacity:1}
.branch b{display:block;font-size:clamp(1.15rem,2vw,1.55rem);font-weight:800;letter-spacing:-.02em;
  line-height:1.2;margin-bottom:.25rem}
.branch small{display:block;font-size:.86rem;color:var(--text-2);line-height:1.6}
.branch small+small{color:var(--text-3);font-size:.8rem}
.branch-actions{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:var(--s2)}
.branch-actions .btn{min-height:44px}
.hq{align-self:flex-start;flex:none;background:var(--ruby);color:#fff;font-size:.68rem;font-weight:800;
  letter-spacing:.1em;padding:.4rem .75rem;border-radius:999px;white-space:nowrap;
  box-shadow:0 8px 24px -10px var(--glow)}

/* map: a lit stage, not a wireframe */
.map{position:relative;border:1px solid var(--line);border-radius:var(--r-xl);overflow:hidden;
  background:radial-gradient(90% 70% at 55% 30%,rgba(224,27,36,.07),transparent 62%),var(--ink);
  min-height:min(70vh,560px);display:grid;place-items:center;padding:var(--s3)}
.map svg{width:100%;height:auto}
.map .terr{fill:url(#mapFill);stroke:rgba(233,237,242,.22);stroke-width:.35}
.map .grat path{stroke:rgba(233,237,242,.05);stroke-width:.18}
.pin .dot{fill:var(--silver);r:1.5}
.pin .lbl{font-size:3px;fill:var(--text-2);font-weight:700}
.pin.on .dot{fill:var(--ruby-hi);r:2.3;filter:drop-shadow(0 0 3px var(--ruby))}
.pin.on .halo{stroke:var(--ruby);stroke-width:.6;opacity:1}
.pin.on .lbl{fill:var(--chrome);font-size:3.6px}
@media (max-width:1024px){ .map{min-height:340px} }

/* ── 26 · 320px HARDENING + LONG-LIST CONTROL ───────────────────────────── */
@media (max-width:400px){
  /* the off-screen mobile nav was measuring 360px inside a 320px viewport and
     dragging the document width with it */
  .nav{inline-size:100vw;max-inline-size:100vw;padding-inline:var(--s3)}
  .nav-link{font-size:1.28rem;min-height:48px;max-inline-size:100%}
  .hdr-in{gap:.45rem}
  .brand img{width:104px}
  .hdr-tools .btn{display:none}          /* the dock already carries contact */
  .lang a,.lang span{padding:.45rem .6rem;font-size:.72rem}
  .wrap{width:min(100% - 1.6rem,var(--maxw))}
  .branch{padding:var(--s2);flex-direction:column}
  .branch-actions .btn{flex:1 1 auto;justify-content:center}
  .ctile .ct-body{padding:.55rem .6rem .7rem}
}

/* A 115-project archive is 46,000px tall on a phone at one card per row.
   Two columns, and only the first batch rendered until asked for more. */
@media (max-width:760px){
  .pf-grid{grid-template-columns:repeat(2,1fr);gap:.7rem}
  .pf figcaption{padding:.6rem .7rem}
  .pf figcaption b{font-size:.82rem}
  .pf figcaption span{font-size:.7rem}
}
.pf.beyond{display:none}
.pf-more{display:flex;justify-content:center;margin-top:var(--s4)}
.pf-more[hidden]{display:none}

/* `place-items:center` sized the map's grid track to the SVG's intrinsic
   300px rather than the container, pushing the document 33px wide at 320. */
.map{display:block;min-width:0}
.map svg{width:100%;max-width:100%;height:auto;display:block}

/* `1fr` is `minmax(auto,1fr)`: the map's min-content still set the track floor.
   minmax(0,1fr) is the only form that actually lets the column shrink. */
.branches{grid-template-columns:minmax(0,1fr)}
@media (min-width:1025px){ .branches{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr)} }
.map{overflow:hidden}
.map{max-inline-size:100%;inline-size:100%}

/* The 3D hero film is brighter than the old montage, so the ruby eyebrow lost
   contrast against it on phones. Deepen the scrim under the copy rather than
   desaturating the brand colour. */
@media (max-width:760px){
  /* Measured, not guessed: the copy band sits at ~25% height on a phone and
     the film runs ~140 grey there. Ruby text needs the surface under it at or
     below ~45 grey to clear 4.5:1, which is a 0.70 veil. */
  html .hero-scrim{background:
    linear-gradient(180deg,rgba(5,5,6,.74) 0%,rgba(5,5,6,.70) 40%,rgba(5,5,6,.90) 74%,rgba(5,5,6,.97) 100%)}
  .hero-copy .eyebrow{text-shadow:0 1px 10px rgba(5,5,6,.85)}
}

/* ── client marks and nameplates ──────────────────────────────────────────
   Two problems the first pass had: a client logo pasted as a flat white
   rectangle looked like a sticker on the page, and a client with no logo file
   got a two-letter stub that read as a broken image.

   Fix for both: the tile is always a dark, brand-consistent panel. A real mark
   floats inside a rounded light chip with its own shadow — supplied on white,
   shown on white, never knocked out, but framed instead of dumped. A client
   with no mark gets a designed nameplate: their name set large over the same
   dark panel with a ruby rule. Nothing on the page reads as missing.        */
.ct-logo,.site-logo{
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(255,61,67,.10), transparent 60%),
    linear-gradient(160deg,#15161a,#0b0c0e);
  display:grid;place-items:center;padding:clamp(.9rem,2.4vw,1.5rem)}
.ct-chip,.site-chip{
  display:grid;place-items:center;inline-size:100%;max-inline-size:230px;
  background:#f6f7f9;border-radius:14px;padding:.85rem 1rem;
  box-shadow:0 14px 30px rgba(0,0,0,.55), 0 0 0 1px rgba(255,255,255,.08)}
.ct-chip img,.site-chip img{
  inline-size:100%;block-size:auto;max-block-size:118px;object-fit:contain;display:block;
  filter:saturate(.2) contrast(1.02);transition:filter .45s var(--ease)}
.ctile:hover .ct-chip img,.ctile:focus-within .ct-chip img,
.site-card:hover .site-chip img{filter:none}

/* nameplate — used by clients with no supplied mark, and by domain cards */
/* The nameplate used to carry a 1px repeating-linear-gradient at 115deg. On
   a wall of eleven plates that texture is rasterised eleven times in the frame
   the wall first paints — measurable, and it bought almost nothing visually.
   One diagonal sheen over a flat gradient reads the same and costs one pass. */
.ct-plate,.site-plate{
  position:relative;display:grid;place-items:center;overflow:hidden;
  padding:clamp(1rem,3vw,1.7rem);
  background:
    linear-gradient(157deg,rgba(255,255,255,.06),rgba(255,255,255,0) 58%),
    linear-gradient(160deg,#141519,#0a0b0d)}
.ct-plate::after,.site-plate::after{
  content:"";position:absolute;inset-block-end:0;inset-inline:18%;height:2px;
  background:linear-gradient(90deg,transparent,var(--ruby),transparent);opacity:.8}
.ct-plate-in,.site-plate>span{display:block;text-align:center;max-inline-size:100%}
.ct-plate-in b,.site-plate b{
  display:block;font-size:clamp(1rem,2.3vw,1.32rem);line-height:1.35;font-weight:700;
  color:var(--chrome);text-wrap:balance}
.ct-plate-in i,.site-plate i{
  display:block;margin-block-start:.45rem;font-style:normal;font-size:.76rem;
  letter-spacing:.05em;color:var(--muted)}
.pendingtile .ct-plate{opacity:.9}
/* A wall holding two or three tiles must not stretch across a six-column
   auto-fill track: the result is a screen-wide strip of nothing, which reads
   as the page having stalled rather than as a short section. */
.cwall--few{grid-template-columns:repeat(auto-fit,minmax(210px,268px));justify-content:start}
/* Plated tiles carry the name inside the plate, so the body is only a badge or
   a note — it should sit tight rather than reserve room for a heading. */
/* A nameplate is type, not a photograph, so it must not be locked to the 4:3
   box the image tiles use — "أكاديمية روبوتكس للذكاء الاصطناعي" simply does not
   fit in it, and overflow:hidden was slicing the last line in half. The plate
   sizes to its own text instead, and the grid stretches the row to match. */
.ctile--plated .ct-media{aspect-ratio:auto;min-block-size:clamp(140px,16vw,190px)}
.ctile--plated .ct-plate-in b{font-size:clamp(.95rem,1.9vw,1.2rem);line-height:1.45}
.ctile--plated .ct-body{padding-block-start:.75rem}
.ctile--plated .ct-body:empty{display:none}
/* A grid row reveals as one row, so without this every tile in the row
   promotes a compositing layer in the same frame. Four steps spread it. */
.cwall .ctile:nth-child(4n+2){transition-delay:55ms}
.cwall .ctile:nth-child(4n+3){transition-delay:110ms}
.cwall .ctile:nth-child(4n+4){transition-delay:165ms}
.pendingbadge{display:inline-block;inline-size:fit-content;margin-block-start:.35rem;font-size:.74rem;
  letter-spacing:.04em;padding:.22rem .6rem;border-radius:999px;
  color:#ffd8a8;background:rgba(255,176,64,.13);border:1px solid rgba(255,176,64,.30)}

/* ── the band under the hero ───────────────────────────────────────────────
   Full-bleed photograph, company line over it. Two things keep it honest and
   fast: the picture is a real <img> (responsive, prioritised, and it carries
   the archive caption as its alt), and the darkening is a pseudo-element
   gradient rather than a filter on the image — a filter would force the whole
   band onto its own raster pass every time it scrolls. */
.band{position:relative;isolation:isolate;overflow:hidden;
  min-block-size:clamp(420px,64vh,720px);display:grid;align-items:end;
  border-block:1px solid var(--line)}
.band-media{position:absolute;inset:0;z-index:-2}
.band-media img{inline-size:100%;block-size:100%;object-fit:cover;object-position:34% 46%;
  filter:saturate(.9) contrast(1.04)}
/* Two scrims, not one. The vertical one seats the band between the hero above
   and the section below; the horizontal one darkens the READING side — the
   right in Arabic, the left in English — because a facade shot has bright
   metal in it and white type over bright metal is not type, it is texture. */
.band::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(5,5,6,.74) 0%,rgba(5,5,6,.28) 32%,rgba(5,5,6,.88) 80%,var(--ink) 100%),
    linear-gradient(270deg,rgba(5,5,6,.80) 0%,rgba(5,5,6,.46) 34%,transparent 72%)}
html[dir="ltr"] .band::after{background:
  linear-gradient(180deg,rgba(5,5,6,.74) 0%,rgba(5,5,6,.28) 32%,rgba(5,5,6,.88) 80%,var(--ink) 100%),
  linear-gradient(90deg,rgba(5,5,6,.80) 0%,rgba(5,5,6,.46) 34%,transparent 72%)}
.band-in{position:relative;padding-block:clamp(2.2rem,6vw,4.2rem);max-inline-size:min(100% - 2.5rem,var(--maxw))}
.band-in h2{font-size:clamp(1.9rem,5.2vw,3.5rem);margin-block-end:.8rem;
  max-inline-size:19ch;text-shadow:0 2px 26px rgba(0,0,0,.65)}
.band-lead{max-inline-size:52ch;text-wrap:pretty;font-size:clamp(.98rem,1.5vw,1.14rem);line-height:1.85;
  color:var(--silver);text-shadow:0 1px 16px rgba(0,0,0,.75)}
.band .btn-row{margin-block-start:clamp(1.1rem,2.6vw,1.8rem)}
.band-cap{margin-block-start:1.15rem;font-size:.74rem;letter-spacing:.05em;color:var(--text-3);
  display:inline-flex;align-items:center;gap:.5rem}
.band-cap::before{content:"";inline-size:20px;block-size:1px;background:var(--ruby);flex:none}
@media (max-width:760px){
  .band{min-block-size:clamp(400px,72vh,620px)}
  .band-media img{object-position:44% 46%}
  /* the floating call/WhatsApp dock lives in the bottom corner on phones — the
     caption stops short of it rather than running underneath */
  .band-cap{max-inline-size:calc(100% - 4.6rem)}
}

/* ── reviews ──────────────────────────────────────────────────────────── */
.revwall{display:grid;gap:var(--s4);margin-block-start:var(--s5);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,270px),1fr))}
.revcard{position:relative;border-radius:var(--r3);padding:clamp(1.1rem,2.4vw,1.6rem);
  background:linear-gradient(158deg,rgba(255,255,255,.055),rgba(255,255,255,.014));
  border:1px solid rgba(255,255,255,.09);overflow:hidden;
  transition:transform .5s var(--ease),border-color .5s var(--ease)}
.revcard::before{content:"";position:absolute;inset-inline:0;inset-block-start:0;height:1px;
  background:linear-gradient(90deg,transparent,var(--ruby),transparent);opacity:.75}
.revcard:hover{transform:translateY(-4px);border-color:rgba(255,61,67,.34)}
.revtop{display:flex;gap:.85rem;align-items:center}
.revface{inline-size:62px;block-size:62px;border-radius:50%;object-fit:cover;object-position:50% 22%;
  border:1px solid rgba(255,255,255,.16);flex:0 0 auto}
.revcard h3{font-size:1rem;margin:0}
.revrole{font-size:.78rem;color:var(--muted);margin:.12rem 0 .18rem}
.revstars{color:#ffc44d;font-size:.9rem;letter-spacing:.09em;margin:0}
.revcard blockquote{margin:.95rem 0 0;font-size:.96rem;line-height:1.75;color:var(--text)}
.revsample{position:absolute;inset-block-start:.6rem;inset-inline-end:.6rem;font-size:.66rem;
  letter-spacing:.05em;padding:.16rem .5rem;border-radius:999px;color:#ffd8a8;
  background:rgba(255,176,64,.14);border:1px solid rgba(255,176,64,.32)}
.samplenote{margin-block-start:.9rem;font-size:.86rem;color:var(--muted);max-inline-size:62ch}

/* ── sector pages ─────────────────────────────────────────────────────── */
.ticks{list-style:none;padding:0;margin:.6rem 0 1.6rem;display:grid;gap:.55rem}
.ticks li{position:relative;padding-inline-start:1.7rem;color:var(--text);line-height:1.75}
.ticks li::before{content:"";position:absolute;inset-inline-start:0;inset-block-start:.62em;
  inline-size:.62rem;block-size:.62rem;border-radius:2px;
  background:linear-gradient(135deg,var(--ruby),#7d1016)}
.minicard{display:block;padding:1.05rem 1.15rem;border-radius:var(--r2);
  background:rgba(255,255,255,.035);border:1px solid rgba(255,255,255,.085);
  text-decoration:none;transition:transform .4s var(--ease),border-color .4s var(--ease),background .4s var(--ease)}
.minicard:hover{transform:translateY(-3px);border-color:rgba(255,61,67,.36);background:rgba(255,255,255,.06)}
.minicard h3{font-size:1rem;margin:0 0 .3rem}
.minicard p{font-size:.86rem;color:var(--muted);margin:0;line-height:1.65}
/* WhatsApp keeps its own colour: people scan for green, and a ghost button
   beside a red one loses the "message us" affordance entirely. */
.btn-wa{background:rgba(37,211,102,.13);border:1px solid rgba(37,211,102,.42);color:#7ff0aa}
.btn-wa:hover{background:rgba(37,211,102,.22);border-color:rgba(37,211,102,.66);color:#b6ffd0}

/* ── hero presenter (rigged) ──────────────────────────────────────────────
   Sits on the inline-END side so it never lands under the copy: in Arabic
   that is the left, in English the right. In English the whole RIG is mirrored
   rather than each image — mirroring the images individually would fight the
   arm's own rotate transform and the origin would land on the wrong shoulder.

   Entrance rises and settles instead of sliding in from the page edge: a
   figure that flies in sideways reads as a banner ad, not as a presenter who
   is already standing there. */
.hero-figure{position:absolute;inset-block-end:0;inset-inline-end:0;z-index:2;
  pointer-events:none;block-size:min(88%,760px);inline-size:min(40vw,470px);
  filter:drop-shadow(0 30px 60px rgba(0,0,0,.75));
  opacity:0;transform:translateY(26px) scale(.965);
  animation-name:figIn;animation-duration:1.5s;animation-delay:.45s;
  animation-timing-function:cubic-bezier(.16,.84,.28,1);animation-fill-mode:forwards}
@keyframes figIn{to{opacity:1;transform:translateY(0) scale(1)}}

.hf-rig{position:absolute;inset:0;display:block;
  transform:perspective(1100px) rotateY(var(--rigY,0deg)) translateY(var(--rigT,0px));
  transform-style:preserve-3d;will-change:transform}
.hf-body,.hf-arm{position:absolute;inset:0;inline-size:100%;block-size:100%;
  object-fit:contain;object-position:bottom;display:block}
.hf-flat{display:none;inline-size:100%;block-size:100%;object-fit:contain;object-position:bottom}

/* the body breathes; the arm swings from the elbow */
.hf-body{animation:botBreathe 6.4s ease-in-out infinite}
.hf-arm{transform-origin:26% 76%;animation:botArm 5.2s ease-in-out infinite}
@keyframes botBreathe{
  0%,100%{transform:translateY(0) rotate(0deg)}
  38%    {transform:translateY(-9px) rotate(-.5deg)}
  72%    {transform:translateY(-3px) rotate(.35deg)}}
@keyframes botArm{
  0%,100%{transform:rotate(0deg) translateY(0)}
  30%    {transform:rotate(-3.4deg) translateY(-9px)}
  55%    {transform:rotate(-1.2deg) translateY(-5px)}
  80%    {transform:rotate(1.9deg) translateY(-1px)}}

html[dir="ltr"] .hf-rig{transform:perspective(1100px) rotateY(calc(var(--rigY,0deg) * -1))
  translateY(var(--rigT,0px)) scaleX(-1)}

@media (prefers-reduced-motion:reduce){
  .hero-figure{animation:none;opacity:1;transform:none}
  .hf-body,.hf-arm{animation:none}
  .hf-rig{transform:none}
}
@media (max-width:1280px){ .hero-figure{block-size:min(76%,620px);inline-size:min(38vw,400px);opacity:.94} }
@media (max-width:1024px){ .hero-figure{block-size:min(60%,500px);inline-size:min(36vw,330px)} }
@media (max-width:760px){
  /* On the phone it is scenery behind the copy: one flat layer, small and low. */
  .hf-rig{display:none}
  .hf-flat{display:block}
  .hero-figure{block-size:min(38%,330px);inline-size:min(56vw,240px);
    inset-inline-end:-4%;opacity:.55;z-index:1;
    -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 34%,#000 100%);
            mask-image:linear-gradient(to bottom,transparent 0,#000 34%,#000 100%)}
}
@media (max-width:420px){ .hero-figure{block-size:min(32%,270px);opacity:.45} }
.hero-copy{position:relative;z-index:3}

/* ── sectors band (home) ──────────────────────────────────────────────────
   A photograph of the actual work does more for a vertical than an icon: a
   contractor recognises their own trade in a second. Tiles stay short so the
   band reads as a directory, not another card grid competing with services. */
.secband{display:grid;gap:var(--s3);margin-block-start:var(--s5);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,190px),1fr))}
.sbcard{position:relative;display:block;border-radius:var(--r2);overflow:hidden;
  text-decoration:none;border:1px solid rgba(255,255,255,.085);
  transition:transform .45s var(--ease),border-color .45s var(--ease)}
.sbcard:hover{transform:translateY(-4px);border-color:rgba(255,61,67,.42)}
.sb-media{display:block;aspect-ratio:4/3;overflow:hidden;background:#0b0c0e}
.sb-media img{inline-size:100%;block-size:100%;object-fit:cover;display:block;
  filter:saturate(.72) brightness(.8);transition:filter .5s var(--ease),transform .7s var(--ease)}
.sbcard:hover .sb-media img{filter:saturate(1) brightness(.95);transform:scale(1.05)}
.sb-body{position:absolute;inset-inline:0;inset-block-end:0;padding:.85rem .9rem;
  background:linear-gradient(to top,rgba(6,6,8,.94),rgba(6,6,8,.55) 55%,transparent)}
.sb-body b{display:block;font-size:.95rem;line-height:1.4;color:var(--chrome)}
.chip--logo{padding:.35rem .7rem;background:#f6f7f9;border-color:transparent}
.chip--logo img{block-size:34px;inline-size:auto;max-inline-size:130px;object-fit:contain;display:block;
  filter:saturate(.2);transition:filter .4s var(--ease)}
.chip--logo:hover img{filter:none}

/* Depth targets get their own compositing layer up front. Promoting them on
   first paint avoids the flicker you get when a layer is created mid-scroll. */
[data-d3]{will-change:transform,opacity;transform-style:preserve-3d;backface-visibility:hidden}

/* ── articles ─────────────────────────────────────────────────────────── */
.artmeta{display:flex;gap:.6rem;align-items:center;margin-block-end:.45rem;
  font-size:.74rem;letter-spacing:.04em;color:var(--muted)}
.artmeta b{color:var(--ruby-txt,#ff7176);font-weight:600}
.artmeta time{opacity:.75}
.artcard h3{font-size:1.06rem;line-height:1.5}
.artlead{max-inline-size:900px;margin-inline:auto}
.artbody{max-inline-size:74ch;margin-inline:auto;margin-block-start:var(--s5)}
.artbody p{font-size:1.02rem;line-height:1.95;margin-block-end:1.15rem}
.artbody strong{color:var(--chrome);font-weight:700}
.artdate{font-size:.76rem;color:var(--text-3);letter-spacing:.05em;margin-block-end:1.4rem}

/* ── the moving gallery ───────────────────────────────────────────────────
   Four rails of different card shapes drifting at different speeds. The
   shapes are set by aspect-ratio rather than fixed pixel heights so a rail
   keeps its rhythm at every breakpoint without a media query per size. */
.gwall{padding-block:var(--s7) var(--s6);overflow:hidden}
.grail{margin-block-start:var(--s3)}
.grail .rail{padding-inline:var(--s4);scrollbar-width:none}
.grail .rail::-webkit-scrollbar{display:none}
.gcard{position:relative;flex:0 0 auto;padding:0;border:1px solid rgba(255,255,255,.09);
  border-radius:var(--r2);overflow:hidden;background:#0b0c0e;cursor:zoom-in;
  transition:transform .5s var(--ease),border-color .5s var(--ease)}
.gcard img{inline-size:100%;block-size:100%;object-fit:cover;display:block;
  filter:saturate(.82) brightness(.86);transition:filter .55s var(--ease),transform .8s var(--ease)}
.gcard:hover{transform:translateY(-6px);border-color:rgba(255,61,67,.45);z-index:2}
.gcard:hover img{filter:saturate(1.04) brightness(1);transform:scale(1.06)}
.gcard:focus-visible{outline:2px solid var(--ruby);outline-offset:3px}
.g-tall{inline-size:clamp(180px,22vw,268px);aspect-ratio:3/4.2}
.g-wide{inline-size:clamp(250px,32vw,420px);aspect-ratio:16/9}
.g-sq  {inline-size:clamp(180px,21vw,258px);aspect-ratio:1/1}
.g-mix {inline-size:clamp(200px,25vw,320px);aspect-ratio:4/3}
.g-mix:nth-child(even){aspect-ratio:3/4.4;inline-size:clamp(160px,19vw,232px)}
.gcap{position:absolute;inset-inline:0;inset-block-end:0;padding:.8rem .85rem;text-align:start;
  background:linear-gradient(to top,rgba(5,5,7,.95),rgba(5,5,7,.5) 58%,transparent);
  opacity:0;transform:translateY(8px);transition:opacity .4s var(--ease),transform .4s var(--ease)}
.gcard:hover .gcap,.gcard:focus-visible .gcap{opacity:1;transform:translateY(0)}
.gcap b{display:block;font-size:.87rem;line-height:1.4;color:var(--chrome)}
.gcap i{display:block;font-style:normal;font-size:.72rem;color:var(--muted);margin-block-start:.15rem}
@media (max-width:760px){
  .g-tall{inline-size:52vw} .g-wide{inline-size:74vw} .g-sq{inline-size:52vw} .g-mix{inline-size:60vw}
  .g-mix:nth-child(even){inline-size:46vw}
  .gcap{opacity:1;transform:none}
}

/* ── scroll-driven film ───────────────────────────────────────────────────
   The section is tall and the stage inside it is sticky: that is the whole
   mechanism. Scroll distance through the section becomes the film's playhead,
   and the copy changes stage as the shot progresses. */
.scrubsec{position:relative;block-size:320vh;background:#050506}
.scrub-sticky{position:sticky;inset-block-start:0;block-size:100svh;overflow:hidden;
  display:grid;place-items:center}
.scrub-vid{position:absolute;inset:0;inline-size:100%;block-size:100%;object-fit:cover;
  z-index:0;background:#050506}
.scrub-veil{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(120% 85% at 78% 45%, transparent 0%, rgba(4,4,6,.62) 58%, rgba(4,4,6,.9) 100%),
    linear-gradient(to top, rgba(4,4,6,.92), transparent 42%)}
/* Stages share one grid cell instead of being absolutely positioned: an
   absolute child escapes the wrap's inline padding, which is how the Arabic
   line ran off the right edge on the first pass. */
/* No inline-size here: .wrap already computes min(100% - gutter, --maxw), and
   overriding it with 100% is exactly what pushed the Arabic line to the very
   edge of the screen. */
.scrub-copy{position:relative;z-index:2;display:grid;align-items:center;
  min-block-size:52svh;justify-self:center}
.scrub-stage{grid-area:1/1;inline-size:min(46ch,100%);opacity:0;transform:translateY(14px);
  transition:opacity .55s var(--ease),transform .55s var(--ease);pointer-events:none;text-align:start}
.scrub-stage.on{opacity:1;transform:translateY(0)}
.scrub-n{display:block;font-size:.8rem;letter-spacing:.22em;color:var(--ruby-txt,#ff7176);
  margin-block-end:.7rem}
.scrub-stage h2{font-size:clamp(1.9rem,5vw,3.5rem);line-height:1.15;margin:0 0 .7rem;text-wrap:balance}
.scrub-stage p{font-size:clamp(.98rem,1.6vw,1.18rem);color:var(--text);line-height:1.8;margin:0}
.scrub-hint{position:absolute;inset-block-end:clamp(1rem,4svh,2.4rem);inset-inline:0;
  z-index:2;font-size:.76rem;letter-spacing:.14em;color:var(--text-3);text-align:start}
@media (max-width:760px){
  .scrubsec{block-size:260vh}
  .scrub-veil{background:
    linear-gradient(to top, rgba(4,4,6,.95) 8%, rgba(4,4,6,.55) 55%, rgba(4,4,6,.75)),
    radial-gradient(120% 60% at 50% 30%, transparent 0%, rgba(4,4,6,.5) 100%)}
  .scrub-stage{max-inline-size:100%}
}
@media (prefers-reduced-motion:reduce){
  .scrubsec{block-size:auto}
  .scrub-sticky{position:relative;block-size:70svh}
  .scrub-stage{position:relative;inset-block-start:auto;transform:none;opacity:1;
    margin-block-end:var(--s4);max-inline-size:100%}
  .scrub-hint{display:none}
}

/* ── staircase ────────────────────────────────────────────────────────────
   Each step sits lower and on the opposite side. The transform is written by
   JS on scroll (see initStairs); everything here is the resting state and the
   things JS should not have to think about — size, radius, caption. */
.stairsec{overflow:hidden}
.stairs{margin-block-start:var(--s6);display:grid;gap:clamp(2.2rem,7vh,5rem);
  perspective:1500px;perspective-origin:50% 50%}
.stair{position:relative;padding:0;border:1px solid rgba(255,255,255,.10);
  border-radius:var(--r3);overflow:hidden;background:#0b0c0e;cursor:zoom-in;
  inline-size:min(52%,560px);aspect-ratio:16/10;
  transform-style:preserve-3d;will-change:transform;
  transition:border-color .5s var(--ease),box-shadow .5s var(--ease)}
.s-left{justify-self:start}
.s-right{justify-self:end}
.stair:hover{border-color:rgba(255,61,67,.5);box-shadow:0 30px 70px rgba(0,0,0,.6)}
.stair:focus-visible{outline:2px solid var(--ruby);outline-offset:4px}
.stair-media{position:absolute;inset:0;display:block}
.stair-media img{inline-size:100%;block-size:100%;object-fit:cover;display:block;
  filter:saturate(.82) brightness(.84);transition:filter .6s var(--ease),transform .9s var(--ease)}
.stair:hover .stair-media img{filter:saturate(1.05) brightness(1);transform:scale(1.05)}
.stair-n{position:absolute;inset-block-start:.9rem;inset-inline-start:1rem;z-index:2;
  font-size:.78rem;letter-spacing:.2em;color:var(--ruby-txt,#ff7176);
  background:rgba(6,6,8,.6);border:1px solid rgba(255,61,67,.3);border-radius:999px;
  padding:.22rem .6rem;backdrop-filter:blur(6px)}
.stair-body{position:absolute;inset-inline:0;inset-block-end:0;z-index:2;padding:1rem 1.1rem;
  text-align:start;background:linear-gradient(to top,rgba(5,5,7,.95),rgba(5,5,7,.45) 60%,transparent)}
.stair-body b{display:block;font-size:1rem;line-height:1.4;color:var(--chrome)}
.stair-body i{display:block;font-style:normal;font-size:.76rem;color:var(--muted);margin-block-start:.2rem}
@media (max-width:760px){
  .stairs{gap:1.6rem;perspective:900px}
  .stair{inline-size:88%;aspect-ratio:4/3}
}

/* ── bubble field ─────────────────────────────────────────────────────────
   Round cards on a free-flowing wrap. Each bubble's duration, delay and drift
   come from its index so no two share a beat — a field where everything
   floats in step reads as a screensaver, not a portfolio. */
.bubblesec{overflow:hidden}
/* Staggered top margins turn two tidy rows into a scattered field. Done with
   nth-child rather than a per-item inline style so the pattern survives any
   number of bubbles. */
.bubbles{position:relative;margin-block-start:var(--s6);display:flex;flex-wrap:wrap;
  justify-content:center;align-items:flex-start;gap:clamp(.7rem,2vw,1.6rem);
  padding-block-end:clamp(30px,7vw,86px)}
.bub:nth-child(4n+2){margin-block-start:clamp(18px,4vw,58px)}
.bub:nth-child(4n+3){margin-block-start:clamp(6px,1.8vw,26px)}
.bub:nth-child(4n)  {margin-block-start:clamp(30px,6.5vw,86px)}
.bub{position:relative;padding:0;border:0;background:none;cursor:zoom-in;
  inline-size:calc(clamp(84px,13vw,190px) * var(--s,1));aspect-ratio:1/1;border-radius:50%;
  overflow:hidden;box-shadow:0 0 0 1px rgba(255,255,255,.10), 0 18px 40px rgba(0,0,0,.5);
  animation:bubFloat var(--t,11s) ease-in-out var(--d,0s) infinite;
  /* Parallax rides the independent `translate` property so it composes with
     the keyframe animation instead of fighting it for `transform`. */
  translate:0 var(--par,0px);
  will-change:transform,translate;transition:box-shadow .45s var(--ease)}
.bub::after{content:"";position:absolute;inset:0;border-radius:50%;pointer-events:none;
  background:radial-gradient(120% 120% at 30% 22%, rgba(255,255,255,.16), transparent 46%),
             radial-gradient(90% 90% at 72% 82%, rgba(255,61,67,.20), transparent 58%)}
.bub img{inline-size:100%;block-size:100%;object-fit:cover;display:block;
  filter:saturate(.78) brightness(.82);transition:filter .5s var(--ease),transform .8s var(--ease)}
.bub:hover{box-shadow:0 0 0 1px rgba(255,61,67,.6), 0 26px 60px rgba(0,0,0,.62);z-index:3}
.bub:hover img{filter:saturate(1.06) brightness(1.02);transform:scale(1.08)}
.bub:focus-visible{outline:2px solid var(--ruby);outline-offset:4px}
.bub-cap{position:absolute;inset-inline:0;inset-block-end:0;padding:.5rem .4rem .7rem;
  font-size:.68rem;line-height:1.35;color:var(--chrome);text-align:center;
  background:linear-gradient(to top,rgba(5,5,7,.92),transparent);
  opacity:0;transition:opacity .35s var(--ease)}
.bub:hover .bub-cap,.bub:focus-visible .bub-cap{opacity:1}
@keyframes bubFloat{
  0%,100%{transform:translate3d(0,0,0) scale(1)}
  25%    {transform:translate3d(6px,-14px,0) scale(1.015)}
  50%    {transform:translate3d(-4px,-22px,0) scale(1.03)}
  75%    {transform:translate3d(-8px,-9px,0) scale(1.01)}}
@media (max-width:760px){ .bub-cap{opacity:1;font-size:.6rem} }
@media (prefers-reduced-motion:reduce){
  .bub{animation:none}
  .stair{transform:none !important}
}
