/* Generated by scripts/fonts_estedad.py — self-hosted Estedad (OFL-1.1), do not edit by hand. */
/* Estedad — arabic */
@font-face {font-family: 'Estedad';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/assets/fonts/estedad-arabic.woff2) format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* Estedad — latin */
@font-face {font-family: 'Estedad';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/assets/fonts/estedad-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ─── metric-compatible fallbacks, DESIGN §4.4 method, re-derived for Estedad ───
   Measured 2026-09-11 from wiki/polish2/fonts/fonts/estedad-var.woff2 with fontTools:
   unitsPerEm 1000; hhea ascent 1025, descent -500, lineGap 0 (OS/2 fsSelection has
   USE_TYPO_METRICS set and sTypoAscender/Descender/LineGap are identical, so hhea
   and typo agree here — either source gives the same numbers). Raw ascent/UPM =
   102.50%, descent/UPM = 50.00%, lineGap/UPM = 0%. hmtx advances read at the fvar
   default instance (wght=400).

   size-adjust is the geometric mean of real ÷ fallback advance widths, overrides are
   the raw metrics above divided back by that factor (the fontaine/next-font
   convention, same as the Plex derivation this replaces).

   Arabic — §4.4's own isolated-glyph method (Estedad ÷ Geeza Pro, fontNumber 0 of
   GeezaPro.ttc, for أ/م/س/ن/ل: 2.051, 1.598, 1.362, 1.125, 1.471 → geo mean 1.4916 →
   size-adjust 149%) FAILED §4.4's own acceptance test: applied live, the hero
   headline rendered 53% wider in the fallback than in Estedad (measured via
   offsetWidth, real page, both fonts loaded). Isolated أ is a thin medial stroke in
   real Arabic text; measuring it alone as a lone tall glyph overweighted the geo
   mean. Per §4.4 ("whichever pair gives the smaller measured shift is correct; do
   not argue it from the spec"), replaced with the ratio measured directly on shaped
   running text at production sizes/weights — Estedad ÷ Geeza Pro (both real,
   unmodified fonts) on 5 live strings: hero h1 (60px/600) 1.069, lede (20px/400)
   1.168, body (17px/400) 1.127, eyebrow (14px/600) 0.925, fact label (16px/400)
   1.204 → geo mean 1.0941 → size-adjust 109.4%. Re-verified with the shipped face:
   the hero headline's offsetWidth ratio against "Estedad Arabic Fallback" landed
   within ~2% (matches the 99.67%/98.3% Latin check below in order of magnitude).
   ascent-override = 102.50% / 1.0941 = 93.69%; descent-override = 50.00% / 1.0941 =
   45.70%; line-gap-override = 0%. */
@font-face{
  font-family:"Estedad Arabic Fallback";
  /* G-TYPE2: "GeezaPro" (no space) is the family's actual PostScript/lookup name on some
     engines that don't resolve the display name "Geeza Pro" via local() — listed as an
     alternate so the intended system face still resolves there instead of falling through
     to Noto Sans Arabic / Tahoma. Same physical font either name resolves it, so the
     measured metrics below are unchanged. */
  src:local("Geeza Pro"),local("GeezaPro"),local("Noto Sans Arabic"),local("Tahoma"),local("Arial");
  ascent-override:93.69%; descent-override:45.70%; line-gap-override:0%; size-adjust:109.4%;
}
/* Latin — Estedad ÷ Arial (UPM 2048) for n / H / o / x: 1.030, 0.985, 0.973, 1.000 →
   geo mean 0.9967 → size-adjust 99.67%. ascent-override = 102.50% / 0.9967 = 102.84%;
   descent-override = 50.00% / 0.9967 = 50.17%; line-gap-override = 0%. */
@font-face{
  font-family:"Estedad Latin Fallback";
  src:local("Helvetica Neue"),local("Arial");
  ascent-override:102.84%; descent-override:50.17%; line-gap-override:0%; size-adjust:99.67%;
}

/* ══════════════════════════════════════════════════════════════
   EPIC v3 — Light Glossy.  Ported from wiki/proto/light/style.css,
   extended per the STAMPED wiki/DESIGN.md.  Arabic RTL primary,
   English LTR mirror.  Charcoal ink on near-white; violet/coral as light.

   File order:  fonts.css (generated, pasted in above — @font-face faces
   and metric fallbacks together) → this sheet.
   ══════════════════════════════════════════════════════════════ */

/* ══════════ 1 · tokens (DESIGN §2) ══════════ */
:root{
  --ink:#1F1F2E;          /* 16.2:1 on white  */
  --ink-2:#55556A;        /*  7.3:1 on white  */
  --ink-3:#6B6B80;        /* decorative only  */
  --violet:#7B61FF;       /* shapes only      */
  --violet-ink:#5A44D8;   /*  6.5:1 on white  */
  --violet-deep:#4B34C4;  /*  8.1:1 — focus ring */
  --coral:#FF7A59;        /* shapes only      */
  --coral-ink:#8A3E28;    /*  7.5:1 on white — same coral-family ink already used by .fallback-note */

  --bg:#FFFFFF;
  --bg-soft:#F7F7FA;
  --bg-tint:#F5F5F7;
  --line:rgba(31,31,46,.10);
  --line-soft:rgba(31,31,46,.07);

  --glass:rgba(255,255,255,.82);
  --glass-strong:rgba(255,255,255,.92);

  /* the contact card only (§2.3) */
  --dark-ground:#1F1F2E;
  --on-dark:#FFFFFF;
  --on-dark-2:#D8D8E2;
  --on-dark-violet:#E4DDFF;
  --on-dark-coral:#FFD3C6;
  --on-dark-line:rgba(255,255,255,.55);
  --on-dark-fill:rgba(31,31,46,.55);
  --on-dark-fill-hi:rgba(31,31,46,.40);

  /* the graft (§2.4) */
  --graft-v:rgba(123,97,255,.34);
  --graft-d:rgba(75,52,196,.26);
  --graft-c:rgba(255,122,89,.20);

  --shadow-s:0 2px 8px rgba(31,31,46,.05), 0 12px 28px -12px rgba(31,31,46,.10);
  --shadow-m:0 1px 2px rgba(31,31,46,.05), 0 18px 44px -18px rgba(31,31,46,.16);
  --shadow-l:0 2px 4px rgba(31,31,46,.04), 0 40px 80px -32px rgba(31,31,46,.24);
  --shadow-dark:0 4px 8px rgba(31,31,46,.12), 0 60px 100px -40px rgba(31,31,46,.55);

  --r-xs:8px; --r-s:14px; --r-m:20px; --r-l:28px; --r-xl:36px; --r-pill:999px;

  /* spacing scale (§2.8) */
  --s-1:6px; --s-2:10px; --s-3:14px; --s-4:20px; --s-5:26px;
  --s-6:34px; --s-7:46px; --s-8:60px; --s-9:80px; --s-10:104px;
  --sec-y:clamp(84px,11vw,148px);
  --sec-y-tight:clamp(72px,9vw,120px);
  --gap-inner:clamp(64px,8vw,104px);
  --gap-wide:clamp(72px,9vw,120px);

  /* containers and z-layers (§2.9) */
  --wrap:1180px;
  --wrap-doc:760px;
  --head-h:76px;
  --pad-x:24px;
  --z-wash:0; --z-render:1; --z-copy:2;
  --z-mast:60; --z-menu:70; --z-skip:120;

  /* F22 (polish r1, defect A): site.js measures .masthead's real rendered height on
     load/resize and writes it here — every scroll-margin below reads THIS number, so the
     Lenis path (site.js reads scroll-margin back off the target) and the native/reduced-
     motion path (the browser applies it directly) always land on the same pixel. This
     value is only the pre-JS fallback. */
  --masthead-h:96px;

  /* STAMP 2: the measured height of the .viz-about figure at the widths where it reorders
     above .about-text (§18's 1000px breakpoint) — #about's scroll-margin subtracts it.
     Unlike the square slab it replaced, this figure's height is not a function of its
     width, so it is measured rather than derived: 263px from 431-1000px, and the stacked
     chain's height below 430px (the Arabic and English figures differ there). */
  --viz-about-h:373px;

  interpolate-size:allow-keywords;   /* §9.4 — <details> height animation */
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; scroll-behavior:smooth; overflow-x:clip}
/* F22: generic fallback for ids with no section top-padding to compensate for
   (#voice/#advisory/#digital cards, #contact, #main…). The five nav-landed sections
   override this immediately below, precisely, via .sec[id]. */
[id]{scroll-margin-block-start:calc(var(--masthead-h) + 24px)}
/* The five sections a[href="#…"] in the masthead actually points at share one .sec
   ancestor whose own top padding is --sec-y — subtract it back out so what lands 40px
   below the masthead is the section's FIRST CONTENT LINE (the eyebrow/heading inside
   .wrap), not its padded top edge. */
.sec[id]{scroll-margin-block-start:calc(var(--masthead-h) + 40px - var(--sec-y))}
#contact{scroll-margin-block-start:calc(var(--masthead-h) + 40px - var(--sec-y-tight))}
body{
  margin:0; background:var(--bg); color:var(--ink);
  font-family:"Estedad","Estedad Arabic Fallback",system-ui,-apple-system,"Segoe UI",Tahoma,sans-serif;
  font-size:17px; line-height:1.75; letter-spacing:0;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  /* NO overflow on <body>: it would turn body into a scroll container and
     break position:sticky on the masthead. html{overflow-x:clip} does the job. */
}
img{max-width:100%; height:auto; display:block}
h1,h2,h3,h4{margin:0; font-weight:600; line-height:1.32; letter-spacing:0}
p,ul{margin:0}
ul{list-style:none; padding:0}
a{color:inherit; text-decoration:none}
button{font:inherit; color:inherit}

::selection{background:rgba(123,97,255,.22); color:var(--ink)}
.contact-card ::selection{background:rgba(255,211,198,.30); color:#fff}
input,select,textarea{caret-color:var(--violet-deep)}

/* Lenis */
html.lenis,html.lenis body{height:auto}
/* F22 (defect A): Lenis only wears the `lenis-smooth` class WHILE an animated scroll is
   actually in flight — idle, it is still plain `.lenis`. html's own scroll-behavior:smooth
   stayed live the rest of the time, so any programmatic scroll (Lenis's own per-frame
   window.scrollTo among them) was smoothed a second time by the browser on top of Lenis's
   own easing: two scroll owners fighting, which reads as the page overshooting and
   settling on the wrong section. `.lenis` (present for Lenis's whole lifetime once
   instantiated) is the correct, permanent kill switch. */
.lenis{scroll-behavior:auto!important}
.lenis.lenis-stopped{overflow:hidden}

/* pre-reveal state — only when JS confirms motion is on (§8.1).
   Nothing in the masthead or the hero ever carries these attributes. */
html.js-motion [data-reveal]{opacity:0}
html.js-motion [data-render]{opacity:0}

.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip:focus{position:fixed!important;inset-block-start:12px;inset-inline-start:12px;width:auto;height:auto;clip:auto;margin:0;
  padding:14px 22px;background:var(--ink);color:#fff;border-radius:var(--r-pill);z-index:var(--z-skip);box-shadow:var(--shadow-m)}

:focus-visible{outline:2px solid var(--violet-deep); outline-offset:3px; border-radius:6px}
.contact-card :focus-visible{outline-color:var(--on-dark-coral)}

.wrap{max-width:var(--wrap); margin-inline:auto; padding-inline:var(--pad-x)}

/* ══════════ 2 · type scale (DESIGN §4.5) ══════════ */
.eyebrow{
  font-size:.875rem; font-weight:600; color:var(--violet-ink);
  margin-block-end:20px; line-height:1.6;
}
/* G-L6 (DESIGN STAMP 3 §4.5): Arabic line-height 1.26 → 1.45 — harakat of line 2 were
   colliding with the dots of line 1 at 60px. English is overridden separately below (§17). */
.h-hero{font-size:clamp(2.1rem,5.4vw,3.75rem); line-height:1.45; font-weight:600;
  min-block-size:calc(2 * 1.45em); hyphens:none}
.h-hero em{font-style:normal; color:var(--violet-ink)}
.h2{font-size:clamp(1.7rem,3.6vw,2.7rem); line-height:1.3}
.h2 em{font-style:normal; color:var(--on-dark-coral)}
.h3{font-size:1.2rem; line-height:1.45}
.h4{font-size:1.06rem; line-height:1.5}
.lede{font-size:clamp(1.06rem,1.7vw,1.3rem); line-height:1.75; color:var(--ink-2); max-width:37ch; margin-inline:auto}
.body{font-size:1.0625rem; line-height:1.85; color:var(--ink-2)}
.mono{font-size:.78rem; font-weight:600; letter-spacing:.14em; color:var(--violet-ink)}

/* ══════════ 3 · buttons (§9.1) ══════════ */
.btn{
  display:inline-flex; align-items:center; justify-content:center; text-align:center;
  min-height:52px; padding:0 30px; border-radius:var(--r-pill);
  font-size:1rem; font-weight:600; font-family:inherit; border:1px solid transparent;
  cursor:pointer; transition:transform .35s cubic-bezier(.2,.7,.3,1), box-shadow .35s, background-color .35s;
}
/* F20(d): only a device with a real hover state animates the button on hover, so only that
   device pays for the layer promotion. */
@media (hover:hover){ .btn{will-change:transform} }
.btn-sm{min-height:44px; padding:0 22px; font-size:.94rem}
.btn-dark{background:var(--ink); color:#fff; box-shadow:0 1px 2px rgba(31,31,46,.2), 0 14px 30px -14px rgba(31,31,46,.55)}
@media (hover:hover){ .btn-dark:hover{background:#2C2C44; transform:translateY(-2px); box-shadow:0 2px 4px rgba(31,31,46,.2), 0 20px 38px -14px rgba(31,31,46,.5)} }
.btn-ghost{background:var(--glass-strong); color:var(--ink); border-color:var(--line); box-shadow:var(--shadow-s)}
@media (hover:hover){ .btn-ghost:hover{transform:translateY(-2px); box-shadow:var(--shadow-m)} }
.btn-coral{background:var(--coral); color:var(--ink); box-shadow:0 1px 2px rgba(255,122,89,.35), 0 16px 34px -14px rgba(255,122,89,.75)}
@media (hover:hover){ .btn-coral:hover{transform:translateY(-2px); background:#FF8A6D} }
/* on the dark card only */
.btn-light{background:#FFFFFF; color:var(--ink); box-shadow:0 1px 2px rgba(0,0,0,.2), 0 18px 38px -16px rgba(0,0,0,.55)}
@media (hover:hover){ .btn-light:hover{transform:translateY(-2px); background:var(--bg-tint)} }
/* G-P13: a pressed state on every interactive element (guarded so touch never gets a stuck hover) */
.btn:active{transform:translateY(0); box-shadow:var(--shadow-s)}
.cta-row{display:flex; flex-wrap:wrap; gap:14px; margin-block-start:34px}
.cta-center{justify-content:center}
.full-button{width:100%; margin-block-start:24px}
.text-link{display:inline-flex; align-items:center; min-height:44px; padding:0; border:0; background:none;
  font-size:.97rem; font-weight:600; color:var(--violet-ink); cursor:pointer; transition:color .25s, background-color .25s}
@media (hover:hover){ .text-link:hover{text-decoration:underline; text-underline-offset:3px} }
.text-link:active{background:rgba(31,31,46,.08)}

/* ══════════ 4 · masthead (§5.2) ══════════ */
.masthead{
  position:sticky; inset-block-start:0; z-index:var(--z-mast);
  background:rgba(255,255,255,.72);
  -webkit-backdrop-filter:saturate(180%) blur(20px); backdrop-filter:saturate(180%) blur(20px);
  border-block-end:1px solid var(--line-soft);
  transition:background-color .35s ease, box-shadow .35s ease;
}
.masthead.is-fixed{background:rgba(255,255,255,.88); box-shadow:var(--shadow-s)}
.masthead-in{
  max-width:var(--wrap); margin-inline:auto; padding-inline:var(--pad-x);
  min-height:var(--head-h); display:flex; align-items:center; gap:24px;
}
/* G-L9-P5: padding-block:5px + the 66px wordmark = 76px, exactly --head-h */
.brand{display:flex; align-items:center; padding:5px 10px; margin-inline-start:-10px; flex:none}
.brand img{width:140px; height:66px; object-fit:contain}
.desktop-nav{display:flex; gap:2px; margin-inline:auto}
.desktop-nav a{
  display:inline-flex; align-items:center; min-height:44px; padding:0 14px; border-radius:var(--r-pill);
  font-size:.97rem; font-weight:500; color:var(--ink-2); transition:color .25s, background-color .25s;
  white-space:nowrap;
}
.desktop-nav a:hover,.desktop-nav a:focus-visible{color:var(--ink); background:rgba(31,31,46,.05)}
.desktop-nav a[aria-current]{color:var(--ink)}
.language{
  flex:none; display:inline-flex; align-items:center; justify-content:center;
  min-height:44px; min-width:44px; padding:0 16px; border-radius:var(--r-pill);
  border:1px solid var(--line); background:var(--glass-strong); cursor:pointer;
  transition:background-color .25s, border-color .25s;
}
.language:hover{border-color:rgba(31,31,46,.2)}
.language .mono{color:var(--violet-ink)}
.masthead-cta{flex:none}

/* mobile menu trigger (§5.3) */
.menu-toggle{
  display:none; flex:none; width:44px; height:44px; padding:0; border:0; background:none; cursor:pointer;
  place-items:center; align-content:center; justify-items:center;
}
.menu-toggle span{
  display:block; width:20px; height:2px; border-radius:2px; background:var(--ink);
  transition:transform .28s cubic-bezier(.2,.7,.3,1);
}
.menu-toggle span + span{margin-block-start:8px}
.menu-toggle[aria-expanded="true"] span:first-child{transform:translateY(5px) rotate(45deg)}
.menu-toggle[aria-expanded="true"] span:last-child{transform:translateY(-5px) rotate(-45deg)}

.mobile-nav{
  /* G-L9-P5: anchor to the JS-measured live height, not the pre-JS token — the two
     can differ by a few px band to band (see .brand above), and only the measured
     value guarantees the sheet starts exactly under the masthead's hairline. */
  position:fixed; inset-block-start:var(--masthead-h); inset-inline:0; z-index:var(--z-menu);
  padding:14px 20px 26px;
  background:var(--glass-strong);
  -webkit-backdrop-filter:blur(20px) saturate(180%); backdrop-filter:blur(20px) saturate(180%);
  border-block-end:1px solid var(--line);
  box-shadow:var(--shadow-m);
  display:grid; gap:4px;
  animation:menu-in .32s cubic-bezier(.2,.7,.3,1) both;
}
.mobile-nav[hidden]{display:none}
.mobile-nav a{display:flex; align-items:center; min-height:52px; padding:0 14px;
  border-radius:var(--r-s); font-size:1.05rem; font-weight:500; color:var(--ink)}
@media (hover:hover){ .mobile-nav a:hover{background:rgba(31,31,46,.05)} }
.mobile-nav a:focus-visible{background:rgba(31,31,46,.05)}
.mobile-nav a:active{background:rgba(31,31,46,.08)}
@keyframes menu-in{from{opacity:0; transform:translateY(-10px)} to{opacity:1; transform:none}}
.mobile-nav a{animation:menu-item-in .32s cubic-bezier(.2,.7,.3,1) both}
.mobile-nav a:nth-child(1){animation-delay:.04s}
.mobile-nav a:nth-child(2){animation-delay:.08s}
.mobile-nav a:nth-child(3){animation-delay:.12s}
.mobile-nav a:nth-child(4){animation-delay:.16s}
.mobile-nav a:nth-child(5){animation-delay:.20s}
@keyframes menu-item-in{from{opacity:0; transform:translateY(-6px)} to{opacity:1; transform:none}}

/* ══════════ 5 · washes / blobs (no filter: cheap on phones) ══════════ */
.wash{position:absolute; inset:0; overflow:hidden; pointer-events:none; z-index:var(--z-wash)}
.blob{position:absolute; display:block; border-radius:50%}
.blob-v{
  width:min(1060px,126vw); aspect-ratio:1; inset-block-start:-34%; inset-inline-end:-24%;
  background:radial-gradient(closest-side,rgba(123,97,255,.22),rgba(123,97,255,.07) 56%,transparent 74%);
}
.blob-c{
  width:min(820px,104vw); aspect-ratio:1; inset-block-start:30%; inset-inline-start:-28%;
  background:radial-gradient(closest-side,rgba(255,122,89,.18),rgba(255,122,89,.05) 56%,transparent 74%);
}
/* industries: wash only, dialled down (§6.5) */
/* the wash is positioned (z:0) and would paint over the static .wrap — lift the copy, as .hero-copy does */
.sec-ind > .wrap{position:relative; z-index:var(--z-copy)}
/* G-L3: the same §5.4 ramp as .sec-zaki/.sec-about, so #alozaki's own #fff 100% stop
   meets #industries at the same white instead of a hard 1px seam. */
.sec-ind{background:linear-gradient(180deg,#fff 0%,var(--bg-tint) 12%,var(--bg-tint) 88%,#fff 100%)}
.wash-ind .blob-v{background:radial-gradient(closest-side,rgba(123,97,255,.14),rgba(123,97,255,.05) 56%,transparent 74%)}
.wash-ind .blob-c{background:radial-gradient(closest-side,rgba(255,122,89,.11),rgba(255,122,89,.04) 56%,transparent 74%)}

/* ══════════ 6 · hero (§6.1) ══════════ */
/* F22 (polish r1, defect B): the stage (figure + caption, one rigid layer per
   §8.4) drifts down by scroll-linked yPercent:10 as the reader scrolls through the hero —
   at 0 bottom padding that lag carried the caption straight across .hero's own
   overflow:hidden edge and clipped it mid-word. The fix is headroom, not a different
   clip: padding-block-end is sized comfortably above the stage's worst-case travel
   (≈10% of stage height, ≈54px desktop / ≈40px phone) so the whole layer's excursion
   stays inside .hero's own box at every scroll position, and overflow:hidden stays on
   — so once #about has landed the stage is fully behind it, never visible under the
   masthead. .wash clips itself (line ~327) so dropping overflow was never necessary here.  */
.hero{position:relative; padding-block:56px 96px; overflow:hidden}
.hero-copy{position:relative; z-index:var(--z-copy); text-align:center; padding-block-end:8px}
.hero-copy .h-hero{max-width:16ch; margin-inline:auto}
.hero-copy .lede{margin-block-start:22px}

.hero-stage{position:relative; z-index:var(--z-render); margin:20px auto 0; width:min(520px,82vw); text-align:center}
.hero-cap{margin-block-start:-8px; font-size:.9rem; color:var(--ink-2)}

/* ══════════ 7 · generic section ══════════ */
.sec{position:relative; overflow:hidden; padding-block:var(--sec-y)}
.sec-head{text-align:center; margin-inline:auto}
.sec-sub{margin-block-start:20px}
.h2-mid{text-align:center; max-width:20ch; margin-inline:auto}
.sec-head + *{margin-block-start:clamp(48px,6vw,72px)}
/* G-L1 (DESIGN STAMP 3 §2.9): the measure moves off the .sec-head/.zaki-head wrapper
   onto the text nodes themselves, so no section headline ever breaks into a
   one-word last line. */
.sec-head,.zaki-head,html[lang=en] .sec-head,html[lang=en] .zaki-head{max-width:none}
.sec-head>.h2,.zaki-head>.h-zaki{max-width:20ch; margin-inline:auto}
html[lang=en] .sec-head>.h2,html[lang=en] .zaki-head>.h-zaki{max-width:26ch}
.sec-head>.eyebrow,.sec-head>.sec-sub,.zaki-head>.zaki-sub{max-width:52ch; margin-inline:auto}

/* ══════════ 8 · about ══════════ */
.sec-about{background:linear-gradient(180deg,#fff 0%,var(--bg-soft) 40%,#fff 100%)}
.about-grid{display:grid; grid-template-columns:1fr 1fr; gap:clamp(40px,6vw,88px); align-items:center}
.about-text .body{max-width:52ch}
.about-text .body + .body{margin-block-start:18px}
/* F22 (polish r1, defect D): was a row of pill-shaped .chip buttons ("anything floating
   like this may be thought of as clickable") with a separate .ticks checklist below it.
   Each value name is now merged with its one-line application into a single calm entry —
   a small heading over a body line, no border, no shadow, no hover, no pointer cursor —
   laid out 2×2 (1 column on phones, see §18). Pill styling stays reserved for things that
   are actually interactive (tabs, the language switch, buttons). */
.values{
  display:grid; grid-template-columns:1fr 1fr; column-gap:28px; row-gap:22px;
  margin-block-start:34px;
}
.value-name{font-size:1rem; font-weight:600; color:var(--ink); line-height:1.4}
.value-line{margin-block-start:6px; font-size:.94rem; line-height:1.65; color:var(--ink-2)}

/* ══════════ 10 · cards (§9.5) ══════════ */
.cards-3{display:grid; grid-template-columns:repeat(3,1fr); gap:22px}
.cards-4{display:grid; grid-template-columns:repeat(2,1fr); gap:22px}
.cards-3-stagger{display:grid; grid-template-columns:repeat(3,1fr); gap:22px}
/* G-L5: the plain wrapper around the middle card (site.js/GSAP never touches it, only the
   [data-reveal] .card inside does) — display:grid so the stretched grid-cell height still
   reaches the card itself, keeping all three cards equal height. */
.stage-mid{display:grid}
/* F12: closed cards stretch to one row height (prototype); an opened accordion must not stretch
   its two closed siblings into empty space, so align-items:start returns only while one is open. */
.cards-3:has(details[open]){align-items:start}
.card{
  position:relative; padding:34px 30px 30px; border-radius:var(--r-l);
  background:var(--glass-strong); border:1px solid var(--line);
  box-shadow:var(--shadow-m);
  transition:transform .45s cubic-bezier(.2,.7,.3,1), box-shadow .45s;
}
.card:hover{transform:translateY(-4px); box-shadow:var(--shadow-l)}
.card-sm{padding:30px 26px}
.card-mark{
  display:block; width:46px; height:46px; border-radius:15px; margin-block-end:22px;
  box-shadow:0 10px 22px -10px rgba(31,31,46,.5), inset 0 1px 0 rgba(255,255,255,.6);
  position:relative; overflow:hidden;
}
.card-mark::after{content:""; position:absolute; inset:0;
  background:linear-gradient(150deg,rgba(255,255,255,.55),transparent 52%)}
.mark-voice   {background:linear-gradient(150deg,#9D8AFF,#7B61FF 60%,#6B4FE8)}
.mark-auto    {background:linear-gradient(150deg,#AC9CFF,#7B61FF 70%,#FF9276)}
.mark-insight {background:linear-gradient(150deg,#9D8AFF,#6B4FE8)}
.mark-secure  {background:linear-gradient(150deg,#FF9F84,#FF7A59 45%,#7B61FF)}
.mark-assess  {background:linear-gradient(150deg,#9D8AFF,#7B61FF 60%,#6B4FE8)}
.mark-design  {background:linear-gradient(150deg,#8E79FF,#8C6BE8 45%,#FF8A6B)}
.mark-build   {background:linear-gradient(150deg,#FFA98F,#FF7A59 60%,#E8603F)}
.card-tag{margin-block-start:8px; font-size:.9rem; font-weight:500; line-height:1.6; color:var(--violet-ink)}
.card-body{margin-block-start:16px; font-size:1rem; line-height:1.8; color:var(--ink-2)}
.card-note{margin-block-start:14px; padding-block-start:14px; border-block-start:1px solid var(--line-soft);
  font-size:.9rem; line-height:1.7; color:var(--ink-2)}
.ticks{margin-block-start:20px; display:grid; gap:11px}
.ticks li{position:relative; padding-inline-start:22px; font-size:.97rem; line-height:1.6; color:var(--ink)}
.ticks li::before{
  content:""; position:absolute; inset-inline-start:0; inset-block-start:.55em;
  width:8px; height:8px; border-radius:50%;
  background:linear-gradient(140deg,var(--violet),var(--coral));
}
.card-link{
  display:inline-flex; align-items:center; gap:8px; min-height:44px; margin-block-start:22px;
  font-size:.97rem; font-weight:600; color:var(--violet-ink); transition:color .25s, background-color .25s;
}
.card-link::after{content:"←"; transition:transform .3s}
@media (hover:hover){ .card-link:hover::after{transform:translateX(-4px)} }
.card-link:active{background:rgba(31,31,46,.08)}

/* the capabilities accordion (§9.4) */
/* G-L7-P6: summary is a flex column filling the (stretched) card's full height, so the
   chevron row can pin itself to the bottom with margin-block-start:auto and all three
   cards' chevrons land on one line even when their body copy differs in length. */
.expertise-item > summary{list-style:none; cursor:pointer; display:flex; flex-direction:column;
  block-size:100%; border-radius:var(--r-m); transition:color .25s, background-color .25s}
.expertise-item > summary::-webkit-details-marker{display:none}
/* PHYSICAL borders — a disclosure chevron points DOWN in both reading directions.
   Logical `border-inline-end` would flip it to a "<" on the RTL page. */
.expertise-item > summary::after{
  content:""; display:block; width:12px; height:12px; margin-block-start:auto;
  border-right:2px solid var(--violet-ink); border-bottom:2px solid var(--violet-ink);
  transform:rotate(45deg); transition:transform .42s cubic-bezier(.2,.7,.3,1);
}
.expertise-item[open] > summary::after{transform:rotate(-135deg)}
.expertise-item::details-content{
  block-size:0; overflow:hidden;
  transition:block-size .42s cubic-bezier(.2,.7,.3,1), content-visibility .42s allow-discrete;
  transition-behavior:allow-discrete;
}
.expertise-item[open]::details-content{block-size:auto}
/* G-P11: room for the in-body CTA's focus ring, which ::details-content's own overflow:hidden
   would otherwise clip flush against the card's bottom edge. */
.service-body{padding-block-start:4px; padding-block-end:6px}
.swap-in{animation:swap-in .5s cubic-bezier(.2,.7,.3,1) both}
@keyframes swap-in{from{opacity:0; transform:translateY(10px)} to{opacity:1; transform:none}}

/* advisory services list */
.svc{margin-block-start:20px; display:grid; gap:16px}
.svc > div{padding-inline-start:16px; border-inline-start:2px solid rgba(123,97,255,.22)}
.svc b{display:block; font-size:1rem; font-weight:600; line-height:1.5; color:var(--ink)}
.svc span{display:block; margin-block-start:4px; font-size:.95rem; line-height:1.65; color:var(--ink-2)}

/* approach stage cards (§9.5) */
/* G-L2/G-P7: unicode-bidi:isolate lets the "01"/"02"/"03" numerals keep LTR digit shaping
   while the element itself inherits the page's own direction, so it sits on the same edge
   as the mark/h3 in RTL — the removed dir="ltr" was pinning it to the wrong edge in Arabic. */
.stage .stage-n{display:block; margin-block-end:10px; unicode-bidi:isolate}
.stage .card-note{display:grid; gap:4px}
.note-label{font-size:.78rem; font-weight:600; letter-spacing:0; color:var(--violet-ink)}
.note-text{font-size:.95rem; line-height:1.7; color:var(--ink)}

/* ══════════ 11 · Alo Zaki ══════════ */
.sec-zaki{background:linear-gradient(180deg,#fff 0%,var(--bg-tint) 12%,var(--bg-tint) 88%,#fff 100%)}
.zaki-head{text-align:center; margin-inline:auto}
.h-zaki{font-size:clamp(2.4rem,5.9vw,3.75rem); line-height:1.2; font-weight:700}
.zaki-sub{margin-block-start:14px; font-size:clamp(1.05rem,2vw,1.35rem); line-height:1.5; font-weight:500; color:var(--violet-ink)}
.zaki-lede{margin-block-start:22px}

.facts{display:grid; grid-template-columns:repeat(3,1fr); gap:18px; max-width:820px; margin-inline:auto}
.fact{
  text-align:center; padding:30px 16px; border-radius:var(--r-l);
  background:var(--glass-strong); border:1px solid var(--line); box-shadow:var(--shadow-m);
}
.fact-n{
  display:block; font-size:clamp(2.4rem,5vw,3.4rem); font-weight:600; line-height:1.15;
  color:var(--violet-ink); white-space:nowrap;
}
.fact-l{display:block; margin-block-start:6px; font-size:.98rem; line-height:1.6; color:var(--ink-2)}

.channels{margin-block-start:var(--gap-wide)}

/* ══════════ 12 · the switcher — channels and sectors (§9.3) ══════════ */
.switch{
  margin-block-start:40px; padding:16px; border-radius:var(--r-xl);
  background:var(--glass); border:1px solid rgba(255,255,255,.9);
  -webkit-backdrop-filter:blur(18px) saturate(150%); backdrop-filter:blur(18px) saturate(150%);
  box-shadow:var(--shadow-l);
}
/* G-L4: the #industries instance (preceded by .sec-head) gets the full §5.1 gap;
   #alozaki's .switch (not preceded by .sec-head) keeps its 40px above. */
.sec-head + .switch{margin-block-start:clamp(48px,6vw,72px)}
.tabs{
  display:flex; gap:6px; padding:6px; border-radius:var(--r-pill);
  background:rgba(31,31,46,.05); max-width:440px; margin-inline:auto;
}
.tab{
  flex:1; min-height:46px; padding:0 18px; border:0; border-radius:var(--r-pill); cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  font-family:inherit; font-size:.98rem; font-weight:600; color:var(--ink-2); background:transparent;
  transition:color .3s, background-color .3s, box-shadow .3s;
}
.tab svg{width:18px; height:18px; flex:none}
@media (hover:hover){ .tab:hover{color:var(--ink)} }
.tab:active{background:rgba(31,31,46,.08)}
.tab[aria-selected="true"]{background:#fff; color:var(--ink); box-shadow:0 1px 2px rgba(31,31,46,.1), 0 6px 16px -8px rgba(31,31,46,.3)}
.industry-tabs{max-width:560px}
.industry-tabs .tab{padding:0 14px}
.panels{margin-block-start:24px}
.panel{padding:34px 30px 30px; border-radius:var(--r-l); background:#fff; border:1px solid var(--line-soft); box-shadow:var(--shadow-s)}
.panel-head{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.panel-icon{display:inline-flex; color:var(--violet-ink)}
.panel-icon svg{width:20px; height:20px}
.panel-tag{font-size:.78rem; font-weight:600; letter-spacing:.14em; line-height:1.6; color:var(--violet-ink)}
.panel-usecase{font-size:.78rem; font-weight:600; letter-spacing:0; line-height:1.6; color:var(--ink-2)}
.panel-usecase::before{content:"·"; margin-inline-end:8px}
.panel-title{margin-block-start:14px; font-size:clamp(1.35rem,2.6vw,1.85rem); line-height:1.38; font-weight:600}
.panel-text{margin-block-start:16px; font-size:1.0625rem; line-height:1.85; color:var(--ink-2); max-width:52ch}
.panel-entry{
  margin-block-start:22px; display:inline-flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:10px 18px; border-radius:var(--r-pill); background:var(--bg-tint); border:1px solid var(--line-soft);
  font-size:.95rem; font-weight:500; color:var(--ink);
}
.panel-entry span{font-size:.82rem; font-weight:600; color:var(--ink-2)}
.panel-entry b{font-weight:500}
#channel-points{margin-block-start:22px; display:grid; gap:11px}
#channel-points > span{display:flex; align-items:flex-start; gap:10px; font-size:.97rem; line-height:1.6; color:var(--ink)}
#channel-points svg{width:18px; height:18px; flex:none; margin-block-start:.25em; stroke:var(--violet-ink)}
#industry-steps{margin-block-start:24px; display:grid; gap:14px}
#industry-steps > div{display:flex; align-items:baseline; gap:12px; font-size:.97rem; line-height:1.6; color:var(--ink)}
#industry-steps .mono{color:var(--violet-ink); flex:none}
.panel-cta{margin-block-start:26px}

.plat{margin-block-start:var(--gap-inner)}
.zaki-close{
  margin-block-start:clamp(48px,6vw,72px); text-align:center;
  font-size:clamp(1.25rem,2.6vw,1.75rem); font-weight:600; line-height:1.5;
  max-width:34ch; margin-inline:auto;
}

/* ══════════ 13 · contact — the one dark card, with the graft (§7) ══════════ */
.sec-contact{padding-block:var(--sec-y-tight)}
.contact-card{
  position:relative; overflow:hidden; border-radius:var(--r-xl);
  background-color:var(--dark-ground);
  box-shadow:var(--shadow-dark);
  padding:clamp(48px,7vw,88px) clamp(28px,5vw,72px);
}
/* THE GRAFT — three static radial layers, alphas measured in DESIGN §7.4 */
.contact-wash{
  position:absolute; inset:0; display:block; pointer-events:none;
  background:
    radial-gradient(70% 90% at 78%  6%, var(--graft-v) 0%, rgba(123,97,255,0) 64%),
    radial-gradient(64% 84% at 22% 22%, var(--graft-d) 0%, rgba(75,52,196,0) 68%),
    radial-gradient(58% 76% at 10% 96%, var(--graft-c) 0%, rgba(255,122,89,0) 62%);
}
.contact-in{position:relative; z-index:1; text-align:center}
/* F13: the measure limit lives on the text nodes, not the container, so .mails can size itself
   as a two-tile row at ≥640px instead of inheriting a ~36ch container width that forces a stack. */
.contact-in > .eyebrow,.contact-in > .h2,.contact-in > .body{max-width:36ch; margin-inline:auto}
.contact-mark{width:176px; height:85px; object-fit:contain; margin:0 auto 30px}
.eyebrow-on-dark{color:var(--on-dark-violet)}
.h2-on-dark{color:var(--on-dark)}
.body-on-dark{color:var(--on-dark-2); margin-block-start:20px}
.mails{display:flex; flex-wrap:wrap; gap:14px; justify-content:center; margin-block-start:38px}
/* G-L11: equalises the two mailbox tiles' widths in the row; ≤760 reverts to a full-width stack. */
.mail{
  display:flex; flex-direction:column; gap:2px; align-items:center; justify-content:center;
  flex:1 1 0; max-width:280px;
  min-height:64px; padding:12px 26px; border-radius:var(--r-m);
  background:var(--on-dark-fill);          /* DARKENS — a lightening fill fails AA on the wash */
  border:1px solid var(--on-dark-line);
  transition:background-color .3s, transform .3s;
}
@media (hover:hover){ .mail:hover{background:var(--on-dark-fill-hi); transform:translateY(-2px)} }
.mail:active{background:rgba(31,31,46,.08)}
.mail-l{font-size:.84rem; line-height:1.5; color:var(--on-dark-2)}
.mail-a{font-size:1rem; font-weight:600; color:var(--on-dark); letter-spacing:.01em}

/* ══════════ 14 · footer (§5.5) ══════════ */
.foot{border-block-start:1px solid var(--line-soft); background:var(--bg-soft)}
.foot-in{display:flex; flex-wrap:wrap; gap:32px; align-items:flex-start; justify-content:space-between;
  padding-block:52px}
.foot-brand{display:flex; align-items:flex-start; gap:22px; max-width:38ch}
.foot-brand img{width:160px; height:75px; object-fit:contain; flex:none}
.foot-name{font-size:.95rem; line-height:1.6; color:var(--ink-2)}
.foot-nav{display:grid; grid-template-columns:repeat(2,auto); gap:2px 24px; align-content:start}
.foot-nav a{display:inline-flex; align-items:center; min-height:44px; padding-inline:12px; margin-inline-start:-12px;
  border-radius:var(--r-s); font-size:.95rem; font-weight:500; color:var(--ink-2); transition:color .25s, background-color .25s}
@media (hover:hover){ .foot-nav a:hover{color:var(--ink); background:rgba(31,31,46,.05)} }
.foot-nav a:focus-visible{color:var(--ink); background:rgba(31,31,46,.05)}
.foot-nav a:active{background:rgba(31,31,46,.08)}
.foot-nav .foot-privacy{display:contents}
.foot-end{display:flex; flex-direction:column; align-items:flex-start; gap:4px}
.foot-top{display:inline-flex; align-items:center; min-height:44px; padding:0 16px; margin-inline-start:-16px;
  border-radius:var(--r-pill); font-size:.95rem; font-weight:500; color:var(--violet-ink); transition:color .25s, background-color .25s}
.foot-top:hover{background:rgba(123,97,255,.08)}
.foot-rights{font-size:.85rem; line-height:1.6; color:var(--ink-2)}
.foot-tag{flex-basis:100%; text-align:center; font-size:.8rem; font-weight:600; letter-spacing:.16em;
  line-height:1.6; color:var(--ink-2); padding-block-start:8px}

/* ══════════ 15 · forms (§9.7) ══════════ */
.form-grid{display:grid; grid-template-columns:1fr 1fr; gap:16px}
.form-grid .full{grid-column:1 / -1}
.form-grid label{display:grid; gap:8px}
.form-grid label > span{font-size:.9rem; font-weight:500; color:var(--ink-2)}
input,select,textarea{
  font-family:inherit; font-size:1rem; line-height:1.5; color:var(--ink); width:100%;
  min-height:52px; padding:14px 16px;
  background:var(--bg-soft); border:1px solid var(--line); border-radius:var(--r-s);
  transition:border-color .25s, background-color .25s, box-shadow .25s;
}
textarea{min-height:104px; resize:vertical}
select{
  appearance:none; padding-inline-end:44px; cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2355556A' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-size:18px 18px; background-position:left 16px center;
}
input:hover,select:hover,textarea:hover{border-color:rgba(31,31,46,.20)}
input:focus-visible,select:focus-visible,textarea:focus-visible{
  background:#fff; border-color:var(--violet-deep);
  outline:2px solid var(--violet-deep); outline-offset:1px;
}
input:user-invalid,textarea:user-invalid,
input[aria-invalid="true"],textarea[aria-invalid="true"]{border-color:#A93226; background:#FDF4F3}
::placeholder{color:var(--ink-3); opacity:1}
/* Own validation messages (no browser bubbles — the form carries novalidate; see site.js). */
/* .form-grid label's own grid gap is 8px; -2px brings the input→error gap to the
   spec's 6px without changing the span→input gap above it. */
.field-error{display:block; margin-block-start:-2px; font-size:.85rem; line-height:1.5; color:var(--coral-ink)}
.field-error:empty{display:none}
/* The optional group: sector / size / area of interest. Plain reset — a fieldset/legend
   pair carries its own UA border and padding by default; this one should read as a
   section of .form-grid, not as a boxed sub-form. */
.form-optional{grid-column:1 / -1; border:0; padding:0; margin:0; min-width:0}
.form-optional > legend{padding:0; margin-block-end:8px; font-size:.9rem; color:var(--ink-2)}
/* Sector + size side by side (the form's own 2-column measure — 3 columns clipped the
   longest size label, «من 250 إلى 1000 موظف» / "250 to 1,000 employees"); interest full width below. */
.form-optional-grid{display:grid; grid-template-columns:1fr 1fr; gap:16px}
.form-optional-grid .full{grid-column:1 / -1}
/* Same size and colour as .form-notice; the mailto link reads like any other in-dialog link. */
.form-alt{margin-block-start:14px; font-size:.88rem; line-height:1.7; color:var(--ink-2)}
.form-alt a{color:var(--violet-ink); text-decoration:underline; text-underline-offset:3px}

/* ══════════ 16 · the contact dialog (§9.8) ══════════ */
/* F22 (polish r1, defect C): #contact-dialog used to be the scroll container itself, so its
   native scrollbar drew at the element's own outer edge — outside the rounded corners the
   border-radius was supposed to clip to — and anything animated inside it could render past
   that same edge. #contact-dialog now only clips (overflow:hidden, the rounded panel, the
   surface that scales/moves on open); .dialog-scroll — a plain block inside it, never
   transformed — is the only thing that scrolls, so its scrollbar sits inside the rounded
   box and nothing painted inside .dialog-scroll can ever cross the panel's border. */
#contact-dialog{
  --dialog-max-h:min(88svh,860px);
  width:min(660px, calc(100vw - 32px)); max-height:var(--dialog-max-h);
  padding:0; border:0; border-radius:var(--r-xl);
  background:var(--glass-strong);
  -webkit-backdrop-filter:blur(20px) saturate(160%); backdrop-filter:blur(20px) saturate(160%);
  box-shadow:var(--shadow-l); color:var(--ink); overflow:hidden;
  margin:auto;
}
#contact-dialog:not([open]){display:none}
#contact-dialog::backdrop{background:rgba(31,31,46,.44)}
/* B6: a thin brand band across the top edge. `<dialog>` is UA-styled position:fixed while
   open (not static), so it is already a positioning context for this absolutely-positioned
   pseudo-element — no explicit position:relative needed here. */
#contact-dialog::before{
  content:""; position:absolute; inset-inline:0; inset-block-start:0; height:4px;
  background:linear-gradient(90deg, var(--violet), var(--coral));
}
.dialog-scroll{
  max-height:var(--dialog-max-h); overflow:auto; overscroll-behavior:contain;
  padding:clamp(28px,4vw,44px); scrollbar-gutter:stable;
  scrollbar-width:thin; scrollbar-color:rgba(31,31,46,.28) transparent;
}
.dialog-scroll::-webkit-scrollbar{width:8px}
.dialog-scroll::-webkit-scrollbar-track{background:transparent}
.dialog-scroll::-webkit-scrollbar-thumb{background:rgba(31,31,46,.24); border-radius:var(--r-pill)}
.dialog-scroll::-webkit-scrollbar-thumb:hover{background:rgba(31,31,46,.38)}
#contact-dialog h2{font-size:clamp(1.5rem,3vw,2rem); line-height:1.3; margin-block-end:10px}
.dialog-intro{font-size:1rem; line-height:1.7; color:var(--ink-2); margin-block-end:28px}
/* G-P4: at rest this wrapper takes no part in layout — .dialog-close still positions
   against #contact-dialog exactly as before. The ≤760 band below turns it into the
   72px header strip. */
.dialog-head{display:contents}
.dialog-close{
  position:absolute; inset-block-start:14px; inset-inline-end:14px;
  width:44px; height:44px; display:grid; place-items:center; border:0; border-radius:50%;
  background:rgba(31,31,46,.05); color:var(--ink-2); cursor:pointer;
  transition:background-color .25s, color .25s;
}
.dialog-close:hover{background:rgba(31,31,46,.10); color:var(--ink)}
.form-notice{margin-block-start:18px; font-size:.88rem; line-height:1.7; color:var(--ink-2)}
.form-notice a{color:var(--violet-ink); text-decoration:underline; text-underline-offset:3px}
.fallback-note{margin-block-end:20px; padding:14px 18px; border-radius:var(--r-s);
  background:#FFF3EF; border:1px solid rgba(255,122,89,.35);
  font-size:.95rem; line-height:1.7; color:#8A3E28}
.fallback-note[hidden]{display:none}
.recipient{display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:12px 16px; border-radius:var(--r-s); background:var(--bg-tint); margin-block-end:14px}
.recipient span{font-size:.85rem; color:var(--ink-2)}
.recipient b{font-size:1rem; font-weight:600; color:var(--ink)}
.message-preview{font-family:inherit; line-height:1.8; background:var(--bg-tint)}
.review-actions{display:flex; gap:12px; flex-wrap:wrap; margin-block-start:20px}
.review-bottom{display:flex; align-items:center; gap:16px; flex-wrap:wrap; margin-block-start:16px}
#copy-status{font-size:.88rem; color:var(--ink-2)}
.sent-mark{width:56px; height:56px; border-radius:50%; display:grid; place-items:center;
  background:linear-gradient(150deg,#9D8AFF,#7B61FF 60%,#6B4FE8); color:#fff;
  box-shadow:0 12px 26px -12px rgba(123,97,255,.9); margin:0 auto 22px}
#sent-view{text-align:center}
body.dialog-open{overflow:hidden}

.no-js-note{max-width:var(--wrap); margin-inline:auto; padding:16px var(--pad-x);
  font-size:.95rem; line-height:1.7; color:var(--ink-2); background:var(--bg-soft);
  border-block-start:1px solid var(--line-soft)}

/* ══════════ 17 · English mirror (§4.7) ══════════ */
html[lang=en] body{
  font-family:"Estedad","Estedad Latin Fallback",system-ui,-apple-system,"Segoe UI",Helvetica,Arial,sans-serif;
  line-height:1.65;
}
html[lang=en] :lang(ar){font-family:"Estedad","Estedad Arabic Fallback",Tahoma,sans-serif}
html[lang=en] h1,html[lang=en] h2,html[lang=en] h3,html[lang=en] h4{line-height:1.15}
html[lang=en] .h-hero{font-size:clamp(2.15rem,5.2vw,3.75rem); line-height:1.08; letter-spacing:-.022em;
  min-block-size:calc(2 * 1.08em); max-width:18ch}
html[lang=en] .h-zaki{font-size:clamp(2.5rem,5.8vw,3.75rem); line-height:1.05; letter-spacing:-.028em; font-weight:600}
html[lang=en] .h2{font-size:clamp(1.75rem,3.4vw,2.6rem); line-height:1.12; letter-spacing:-.018em}
html[lang=en] .h3{line-height:1.30; letter-spacing:-.012em}
html[lang=en] .h4{line-height:1.35; letter-spacing:-.010em}
html[lang=en] .panel-title{font-size:clamp(1.3rem,2.5vw,1.8rem); line-height:1.22; letter-spacing:-.014em}
html[lang=en] .lede{font-size:clamp(1.06rem,1.7vw,1.28rem); line-height:1.60; letter-spacing:-.006em; max-width:42ch}
html[lang=en] .body,
html[lang=en] .panel-text{line-height:1.70; max-width:62ch}
html[lang=en] .card-body{line-height:1.65}
html[lang=en] .eyebrow{font-size:.82rem; line-height:1.55; letter-spacing:.10em; text-transform:none}
html[lang=en] .zaki-sub{font-size:clamp(1.02rem,1.9vw,1.3rem); line-height:1.45; letter-spacing:-.004em}
html[lang=en] .fact-n{line-height:1.05; letter-spacing:-.02em}
html[lang=en] .mono,html[lang=en] .panel-tag,html[lang=en] .foot-tag{line-height:1.5}
html[lang=en] .note-label,html[lang=en] .panel-usecase{letter-spacing:.14em}
html[lang=en] .h2-mid{max-width:24ch}
html[lang=en] .contact-in > .eyebrow,html[lang=en] .contact-in > .h2,html[lang=en] .contact-in > .body{max-width:40ch}
/* LTR mirroring fixes (§6.1, §6.4, G21) */
html[lang=en] .doc-back .arrow,html[lang=en] .notfound .btn .arrow{transform:none}
html[lang=en] .card-link::after{content:"→"}
@media (hover:hover){ html[lang=en] .card-link:hover::after{transform:translateX(4px)} }
html[lang=en] select{background-position:right 16px center}
/* the three English channel labels are longer than the Arabic ones; 440px wraps them */
html[lang=en] .channel-tabs{max-width:560px}

/* ══════════ 18 · responsive ══════════ */
@media (max-width:1000px){
  .about-grid{grid-template-columns:1fr; gap:52px}
  .about-grid .viz-about{width:min(560px,100%); margin-inline:auto; order:-1}
  /* G-L8: keep the §5.1 22px gap at every width — the 18px override here only ever
     applied to the single-column stack, so cards-3/-4 disagreed with each other. */
  .cards-3,.cards-3-stagger{grid-template-columns:1fr}
  /* F22 (defect A): below 1000px the .viz-about figure above reorders to sit ABOVE
     .about-text (order:-1), so #about's first content line is no longer --sec-y below the
     section's own top — it's --sec-y + that reordered figure's own height + the grid's 52px
     row gap. Unlike the square slab it replaced, the figure's height is not a function of
     its width: it is measured, per layout, and carried as --viz-about-h (§1).
     #about's id-specificity wins over .sec[id] above without needing !important. */
  #about{scroll-margin-block-start:calc(var(--masthead-h) + 40px - var(--sec-y) - var(--viz-about-h) - 52px)}
}
@media (max-width:430px){
  /* .va-chain stacks here (§22), so the figure is taller — and the English labels wrap
     one line further than the Arabic ones. Measured at 390px, the audit width. */
  :root{--viz-about-h:264px}
  /* G-P2-P8: one row of tabs at phone widths. The icon is already cloned into the panel
     header, so hiding it here loses nothing. min-width:0 + nowrap lets flex actually shrink
     the tabs instead of wrapping them into a second ragged row; .tabs.channel-tabs (3 tabs,
     the DOM carries both classes on one element, not nested) is the one row this must hold —
     .industry-tabs (4 tabs) keeps its own deliberate 2×2 wrap below. */
  .tab svg{display:none}
  .tab{min-width:0; white-space:nowrap}
  .tabs.channel-tabs{flex-wrap:nowrap}
}
@media (max-width:339px){
  /* if a label still can't fit at the very narrowest phones, allow it to wrap rather than overflow */
  .tab{white-space:normal}
}
@media (min-width:1001px){
  /* G-L5: transform, not margin, so the offset survives the GSAP reveal tween — which
     writes its own inline transform on [data-reveal] and would erase a CSS one there.
     The offset lives on the plain wrapper (.stage-mid in the markup); the tweened .card
     inside it is untouched. */
  .cards-3-stagger > :nth-child(2){transform:translateY(18px)}
}
@media (max-width:960px){
  .desktop-nav{display:none}
  .menu-toggle{display:grid}
  .masthead-cta{margin-inline-start:auto}
}
@media (max-width:760px){
  /* G-L9-P5: 59px wordmark + 4px top/bottom padding = 67px, the measured masthead box —
     --head-h now matches it exactly instead of guessing 64px. */
  :root{--head-h:67px; --pad-x:20px}
  body{font-size:16px}
  .brand img{width:126px; height:59px}
  .brand{padding-block:4px}
  .hero{padding-block:52px 72px}
  .values{grid-template-columns:1fr}
  .hero-stage{width:min(400px,86vw); margin-block-start:22px}
  /* G-P9: stacked hero CTAs get one shared width so their edges line up. */
  .hero-copy .cta-row{flex-direction:column; align-items:center}
  .hero-copy .cta-row .btn{width:min(300px,100%); min-width:0}
  .cards-4{grid-template-columns:1fr}
  /* G-P15: §9.6's 18px gap, restored (was 14px), and a shared min-height so the English
     tiles (longer labels) don't sit at an uneven height next to the Arabic ones. */
  .facts{grid-template-columns:1fr; gap:18px}
  .fact{padding:24px 16px; display:flex; align-items:baseline; justify-content:center; gap:14px; min-height:96px}
  .fact-n{font-size:2.4rem}
  .fact-l{margin-block-start:0}
  .switch{padding:10px; border-radius:var(--r-l)}
  .tabs{max-width:none; flex-wrap:wrap}
  .tab{padding:0 10px; font-size:.94rem}
  .industry-tabs .tab{flex:1 1 calc(50% - 6px)}
  .panel{padding:26px 22px}
  .card{padding:28px 24px}
  .foot-in{flex-direction:column; align-items:flex-start; gap:26px; padding-block:44px}
  .foot-brand{gap:16px}
  .foot-nav{grid-template-columns:1fr}
  .foot-tag{text-align:start; padding-block-start:0}
  .mails{flex-direction:column; align-items:stretch}
  .mail{align-items:center; flex:none; max-width:none}
  .form-grid{grid-template-columns:1fr}
  .form-optional-grid{grid-template-columns:1fr}
  /* G-P1/G-P4: a flex column sheet — a fixed 72px header strip (.dialog-head, holding the
     close button on an opaque ground) plus a flex:1 scroll area — so EVERY view (form,
     review, sent) fills the full 100svh sheet, not just whichever view happens to be tall. */
  #contact-dialog{width:100vw; max-width:100vw; --dialog-max-h:100svh; height:100svh; border-radius:0; padding:0;
    display:flex; flex-direction:column}
  .dialog-head{display:flex; align-items:center; justify-content:flex-end; flex:none; block-size:72px;
    padding-inline:20px; background:#FFFFFF}
  .dialog-close{position:static}
  .dialog-scroll{padding:24px 20px 32px; flex:1}
}
/* phones: drop decorative backdrop-filters (kept only on the masthead — and .doc-header, its
   masthead-equivalent on the doc pages, which was never in this strip list).
   On a near-white ground a high-alpha fill reads the same and costs nothing.
   F18: keyed to 960px so this shares one breakpoint with the mobile-UI switch above, instead of
   760px — at 760–960px (a phone in landscape) every blur was coming back. */
@media (max-width:960px){
  .switch,.mail,.mobile-nav,#contact-dialog{-webkit-backdrop-filter:none; backdrop-filter:none}
  .switch{background:rgba(255,255,255,.90)}
  .mobile-nav{background:rgba(255,255,255,.98)}
  #contact-dialog{background:#FFFFFF}
}
/* Post-launch fix (2026-09-12, operator's iPhone 14 Pro Max / 430px): the compact masthead
   rules used to start at ≤400px, but the 401–520px band still carried the desktop gap (24px)
   and paddings — brand 136 + 3×24 + language 56 + CTA 119 + trigger 44 + gutters 40 = 467px,
   wider than a 430px phone, so the trigger fell off the edge and the page scrolled sideways.
   The compact rules now apply from 520px down; ≤400px tightens the gap one more notch. */
@media (max-width:520px){
  .brand{padding-inline-end:0}
  .masthead-in{gap:8px}
  .language{padding:0 6px}
  .masthead-cta{padding:0 10px; font-size:.86rem}
}
@media (max-width:400px){
  /* G-L9-P5: 56px wordmark + the same 4px top/bottom padding (inherited from the ≤760
     band above) = 64px — --head-h follows it down a second notch. */
  :root{--head-h:64px}
  .brand img{width:120px; height:56px}
  .tab{padding:0 6px; font-size:.9rem}
  .masthead-in{gap:4px} /* one notch tighter than the ≤520px block above; order matters */
}
/* G-P3-P10 (DESIGN STAMP 3 §2.9/§5.6): the 10px gutter band applies only below 344px —
   345-760px keeps the standard 20px. Moved out of the old ≤400px block, which was halving
   every gutter on ordinary 390/360 phones. Footer link boxes carry an optical negative
   margin (§5.5) that only fits where the 20px gutter can absorb it; below 344px it pushed
   them (and their focus rings) past the viewport edge, so it is nulled in the same band. */
@media (max-width:344px){
  :root{--pad-x:10px}
  .foot-nav a,.foot-top{margin-inline-start:0; padding-inline:0}
}

/* ══════════ 19 · reduced motion — a complete static site (§8.7) ══════════ */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important; animation-iteration-count:1!important; transition-duration:.001ms!important}
  html.js-motion [data-reveal],html.js-motion [data-render]{opacity:1}
  .mobile-nav,.mobile-nav a{animation:none}
}

/* ══════════ 20 · print ══════════ */
@media print{
  .masthead,.mobile-nav,.menu-toggle,.language,#contact-dialog,.skip,.no-js-note,
  .wash,.foot-top{display:none!important}
  html.js-motion [data-reveal],html.js-motion [data-render]{opacity:1!important}
  body{background:#fff; color:#000; font-size:11pt}
  .sec{padding-block:18pt; overflow:visible}
  .card,.panel,.fact,.switch{box-shadow:none; border:1px solid #bbb; background:#fff;
    -webkit-backdrop-filter:none; backdrop-filter:none; break-inside:avoid}
  .contact-card{background:#fff!important; color:#000; box-shadow:none; border:1px solid #bbb}
  .eyebrow-on-dark,.h2-on-dark,.body-on-dark,.mail-l,.mail-a{color:#000}
  .mail{background:#fff; border-color:#bbb}
  .expertise-item::details-content{block-size:auto}
  a[href^="http"]::after,a[href^="mailto"]::after{content:" (" attr(href) ")"; font-size:9pt; color:#555}
}

/* ══════════ 21 · standalone doc pages — privacy, 404 (§ shell) ══════════ */
.doc-header{
  position:sticky; inset-block-start:0; z-index:var(--z-mast);
  background:rgba(255,255,255,.72);
  -webkit-backdrop-filter:saturate(180%) blur(20px); backdrop-filter:saturate(180%) blur(20px);
  border-block-end:1px solid var(--line-soft);
}
.doc-header .wrap{min-height:var(--head-h); display:flex; align-items:center; gap:16px}
/* G-P12: reuses the masthead's own .brand — same padding, same responsive wordmark
   ladder (140×66 → 126×59 → 120×56) — so the doc-page header measures identically to
   the site masthead at every width instead of maintaining a second, drifted copy. */
.doc-back{
  display:inline-flex; align-items:center; gap:8px; min-height:44px; padding:0 16px;
  margin-inline-start:auto; margin-inline-end:-16px; border-radius:var(--r-pill);
  font-size:.95rem; font-weight:600; color:var(--ink-2); transition:color .25s, background-color .25s;
}
.doc-back:hover,.doc-back:focus-visible{color:var(--ink); background:rgba(31,31,46,.05)}
.doc-back .arrow{width:18px; height:18px; flex:none}
/* the shared ARROW glyph is drawn LTR; mirror it for the RTL doc pages and un-mirror under English (F7) */
.doc-back .arrow,.notfound .btn .arrow{transform:scaleX(-1)}
/* R2-2: the optical -16px pull only fits where .wrap-doc's own padding can absorb it; below 760px
   it pushed the link 6px past the viewport edge (396/390 overflow on all four doc pages). */
@media (max-width:759px){
  .doc-back{margin-inline-end:0}
}

.wrap-doc{max-width:var(--wrap-doc); margin-inline:auto; padding-inline:var(--pad-x)}

.doc-main{padding-block:var(--sec-y-tight)}
.doc-main h1{font-size:clamp(1.9rem,4.2vw,2.6rem); line-height:1.28; font-weight:600; margin-block-end:18px}
.doc-lead{font-size:1.1rem; line-height:1.7; color:var(--ink-2); max-width:56ch}
.doc-main h2{font-size:1.22rem; line-height:1.4; font-weight:600; margin-block:44px 14px}
.doc-main h2:first-of-type{margin-block-start:52px}
.doc-main p{font-size:1.0625rem; line-height:1.85; color:var(--ink-2); margin-block-end:14px}
.doc-main p:last-child{margin-block-end:0}
.doc-main ul{list-style:disc; padding-inline-start:1.3em; color:var(--ink-2); font-size:1.0625rem; line-height:1.85; margin-block-end:14px}
.doc-main li{margin-block-end:4px}
.doc-main a:not(.btn){color:var(--violet-ink); text-decoration:underline; text-underline-offset:3px}
.doc-main a:not(.btn):hover{color:var(--violet-deep)}
.doc-main strong{color:var(--ink); font-weight:600}
.doc-meta{
  margin-block-start:52px; padding-block-start:22px; border-block-start:1px solid var(--line-soft);
  font-size:.88rem; line-height:1.7; color:var(--ink-3);
}

.notfound{
  padding-block:clamp(48px,8vw,96px); text-align:center; max-width:52ch; margin-inline:auto;
}
.notfound .mono{display:block; margin-block-end:22px}
.notfound h1{font-size:clamp(2.1rem,5vw,2.9rem); line-height:1.24; font-weight:600; margin-block-end:16px}
.notfound .doc-lead{margin-inline:auto; text-align:center; margin-block-end:34px}
.notfound .btn .arrow{width:18px; height:18px; margin-inline-start:10px}

.doc-footer{border-block-start:1px solid var(--line-soft); background:var(--bg-soft)}
.doc-footer .footer-bottom{
  display:flex; flex-wrap:wrap; gap:8px 20px; align-items:center; justify-content:space-between;
  padding-block:28px; font-size:.85rem; line-height:1.6; color:var(--ink-2);
}
.doc-footer .mono{color:var(--ink-2); letter-spacing:.16em}

@media (max-width:640px){
  .doc-footer .footer-bottom{justify-content:center; text-align:center}
}


/* ══════════ 22 · the five product visuals (DESIGN STAMP 2 · wiki/polish2/visuals) ══════════
   Appended verbatim from wiki/polish2/visuals/visuals.css — five self-contained figures that
   replace the four abstract renders and the three gradient capability squares. Ink, accent,
   surfaces, lines, radii and shadows are the §2 tokens above; four new tokens are declared
   below. (--viz-about-h, the measured .viz-about height #about's scroll-margin in §18 reads,
   sits with the layout tokens in §1 instead, so §18's breakpoint overrides still win.) Identity gradients, washes, glass alphas, icon fills and art
   strokes stay rgba/hex literals, none of them used for text. Text is px-sized so the 12px
   floor holds at the 16px phone body. Motion: <=1 idle animation per component,
   transform/opacity only, nothing starts hidden, reduced-motion guarded. Internal source
   order matters (.viz{margin:0} must precede .viz-alozaki/.viz-approach's own margins). */

/* ─── new tokens (4) ─── */
:root{
  --viz-tint:rgba(123,97,255,.10);        /* violet fill under a highlighted node */
  --viz-tint-line:rgba(123,97,255,.26);   /* its hairline */
  --viz-wire:rgba(90,68,216,.42);         /* connector strokes */
  --viz-orb:radial-gradient(circle at 33% 25%,#D3C8FF 0%,#9A85FF 20%,#7B61FF 45%,#FF7A59 100%); /* the Alo Zaki node */
}

/* ─── shared frame ─── */
.viz{position:relative; margin:0; isolation:isolate; text-align:start}
/* G-VIZ1: :where() keeps this reset at 0 specificity so it never out-specifies a
   component rule beneath it (the blanket .viz p,.viz ul version was welding pills
   together and erasing authored margins). */
.viz :where(p,ul){margin:0}
.viz :where(ul){padding:0; list-style:none}
.viz svg{display:block}
.vz-wash{position:absolute; inset:-12% -8%; z-index:0; display:block; pointer-events:none}
html[dir=ltr] .vz-wash{transform:scaleX(-1)} /* the wash is composition, it mirrors with the cards (DESIGN §6.4 audit) */
.vz-wash-hero{background:
  radial-gradient(closest-side at 78% 12%,rgba(123,97,255,.34),rgba(123,97,255,.09) 58%,transparent 76%),
  radial-gradient(closest-side at 20% 88%,rgba(255,122,89,.28),rgba(255,122,89,.07) 58%,transparent 76%)}
.vz-wash-about{background:
  radial-gradient(closest-side at 70% 20%,rgba(123,97,255,.34),rgba(123,97,255,.09) 58%,transparent 76%),
  radial-gradient(closest-side at 26% 84%,rgba(255,122,89,.26),rgba(255,122,89,.06) 58%,transparent 76%)}
.vz-wash-zaki{background:
  radial-gradient(closest-side at 50% 46%,rgba(123,97,255,.34),rgba(123,97,255,.09) 56%,transparent 74%),
  radial-gradient(closest-side at 16% 90%,rgba(255,122,89,.24),rgba(255,122,89,.06) 58%,transparent 76%)}
.vz-wash-approach{background:
  radial-gradient(closest-side at 76% 18%,rgba(123,97,255,.30),rgba(123,97,255,.08) 58%,transparent 76%),
  radial-gradient(closest-side at 24% 88%,rgba(255,122,89,.26),rgba(255,122,89,.06) 58%,transparent 76%)}
/* the one arrow glyph: drawn pointing to inline-end of the flow on the RTL page (left) */
.vz-arr{flex:none; align-self:center; width:20px}
.vz-arr svg{width:20px; height:9px; fill:none; stroke:rgba(31,31,46,.34); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round}
html[dir=ltr] .vz-arr svg{transform:scaleX(-1)}
/* the two shared keyframes */
@keyframes vz-wave{from{transform:scaleY(var(--lo))} to{transform:scaleY(var(--hi))}}
@keyframes vz-breathe{0%,100%{transform:scale(1)} 50%{transform:scale(1.10)}}

/* ══════════ 3 · viz-caps — replaces the 46×46 .card-mark inside each #capabilities card:
   a full-width 88px art strip, margin-block-end:22px kept. Art only, no text.
   Idle animation: the voice waveform (one @keyframes, shared). ══════════ */
.viz-caps{display:grid; place-items:center; width:100%; height:88px; margin-block-end:22px; overflow:hidden;
  border-radius:var(--r-m); border:1px solid var(--line-soft);
  background:linear-gradient(160deg,rgba(123,97,255,.10),rgba(255,122,89,.08))}
.vc-line{position:absolute; inset-inline:14px; inset-block-end:18px; height:1px; background:rgba(31,31,46,.18)}
.vc-wave{display:flex; align-items:center; justify-content:space-between; gap:3px; height:38px; width:64%; max-width:170px; margin-block-end:10px}
.vc-doc{position:relative; width:58%; max-width:150px; display:grid; gap:5px; padding:9px 10px; border-radius:var(--r-xs);
  background-color:var(--glass-strong); border:1px solid var(--line); box-shadow:0 10px 20px -14px rgba(31,31,46,.5)}
.vc-doc-row{display:flex; gap:4px}
.vc-doc-row i{flex:1; height:11px; border-radius:4px; border:1px solid rgba(31,31,46,.22); background:rgba(31,31,46,.05)}
.vc-rule{display:block; height:4px; border-radius:99px; background:rgba(31,31,46,.14)}
.vc-rule.w70{width:70%}
.vc-rule.w45{width:45%}
.vc-stamp{position:absolute; inset-block-end:-7px; inset-inline-start:-7px; width:20px; height:20px; border-radius:50%;
  background:linear-gradient(150deg,#9D8AFF,var(--violet) 55%,#FF9276); box-shadow:0 8px 16px -8px rgba(123,97,255,.9)}
.vc-app{width:78%; max-width:176px; height:auto; fill:none; stroke-linecap:round; stroke-linejoin:round}
html[dir=ltr] .vc-app{transform:scaleX(-1)}
.vc-win{fill:rgba(255,255,255,.95); stroke:rgba(31,31,46,.24); stroke-width:1.3}
.vc-str{stroke:rgba(31,31,46,.24); stroke-width:1.3}
.vc-soft{stroke:rgba(31,31,46,.16); stroke-width:2.6}
.vc-acc{stroke:var(--violet-ink); stroke-width:1.6}
.vc-db{fill:var(--viz-tint); stroke:var(--viz-wire); stroke-width:1.3}
.vc-dbl{stroke:var(--viz-wire); stroke-width:1.3}

/* ══════════ 5 · viz-approach — the #approach alt-slab slot (margins kept; width min(400px,82vw))
   Three deliverables on a shelf: number · stage · what the client receives. No animation. ══════════ */
.viz-approach{width:min(400px,82vw); margin:clamp(48px,6vw,72px) auto clamp(52px,6vw,80px)}
.vp-shelf{position:relative; z-index:1; display:grid; gap:10px; padding-inline-start:16px}
.vp-item{display:grid; grid-template-columns:auto 1fr; column-gap:12px; align-items:baseline; justify-self:start; width:100%;
  padding:14px 16px; border-radius:var(--r-m); background-color:var(--glass-strong); border:1px solid var(--line); box-shadow:var(--shadow-m)}
.vp-item:nth-child(1){width:86%}
.vp-item:nth-child(2){width:93%}
.vp-n{grid-row:1 / span 2; align-self:start; font-size:12px; font-weight:600; letter-spacing:.14em; line-height:1.6; color:var(--violet-ink)}
.vp-stage{font-size:12px; line-height:1.6; color:var(--ink-2)}
.vp-out{margin-block-start:1px; font-size:15px; font-weight:600; line-height:1.5; color:var(--ink); text-wrap:pretty; text-wrap:balance}
.vp-item.is-hi{border-color:var(--viz-tint-line); background-image:linear-gradient(var(--viz-tint),var(--viz-tint))}
.vp-rail{position:absolute; inset-block:14px; inset-inline-start:0; width:3px; border-radius:99px;
  background:linear-gradient(180deg,rgba(123,97,255,.55),rgba(255,122,89,.55))}

/* ══════════ responsive ══════════ */
@media (max-width:960px){
  /* DESIGN §8.8 / site.css §18: no decorative backdrop-filter below 960px */
  .va-slab,.vz-diag{-webkit-backdrop-filter:none; backdrop-filter:none; background-color:rgba(255,255,255,.96)}
}
@media (max-width:760px){
  .vh-sheet{grid-template-rows:auto 40px auto; padding:10px}
  .vh-call,.vh-doc{width:94%}
  .vh-top{padding:12px 14px 8px}
  .vh-wave{padding-inline:14px}
  .vh-row,.vh-foot{padding-inline:14px}
  .vh-act{margin-inline:14px}
  .vh-doc{padding:14px 14px 16px}
  .vz-wash{inset:-10% -4%}
  .viz-caps{height:84px}
  .vz-diag{grid-template-columns:1fr; grid-template-rows:auto 40px auto 40px auto; padding:16px 14px}
  .vz-wires{height:40px; align-self:center}
  .vz-wires svg{display:none}
  .vz-wires::before{content:""; position:absolute; inset-block:5px; inset-inline-start:50%; width:2px; margin-inline-start:-1px; border-radius:99px;
    background:linear-gradient(180deg,var(--viz-wire),rgba(90,68,216,.14))}
  .vp-item:nth-child(1),.vp-item:nth-child(2){width:100%}
}
@media (max-width:430px){
  .va-chain{flex-direction:column; gap:8px}
  .va-chain .vz-arr svg{transform:rotate(-90deg)}          /* the flow now runs downward… */
  html[dir=ltr] .va-chain .vz-arr svg{transform:rotate(-90deg)} /* …in both reading directions */
  .va-out{gap:4px 16px}
  .va-drop path:nth-child(2){display:none}                 /* stacked chain: keep only the centre drop */
}

/* ══════════ reduced motion — the base transforms already draw the static picture ══════════ */
@media (prefers-reduced-motion:reduce){
  .vh-wave i,.vc-wave i,.va-orb,.vz-orb{animation:none}
}


/* ══════════ 23 · round-3 illustrations + icon set (wiki/polish3/visuals, STAMP 3) ══════════ */
:root{
  --ill-stroke:rgba(31,31,46,.34);   /* charcoal structure lines */
  --ill-soft:rgba(31,31,46,.16);     /* secondary rules / text-as-lines */
  --ill-wire:rgba(90,68,216,.48);    /* violet connectors */
}

/* ─── the panel (identical recipe to the approved .viz-caps tile, larger) ─── */
.ill{position:relative; margin:0; width:100%; overflow:hidden; isolation:isolate; text-align:start;
  border-radius:var(--r-l); border:1px solid var(--line-soft);
  background:linear-gradient(160deg,rgba(123,97,255,.10),rgba(255,122,89,.08))}
.ill-art{display:block; width:100%; height:auto}
html[dir=ltr] .ill-art{transform:scaleX(-1)}   /* the drawing flows with the reading direction */

/* stroke vocabulary — vector-effect keeps 1.5px at every panel width */
.ill svg *{vector-effect:non-scaling-stroke}
.il-s   {fill:none; stroke:var(--ill-stroke); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round}
.il-f   {fill:rgba(255,255,255,.94); stroke:var(--ill-stroke); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round}
.il-soft{fill:none; stroke:var(--ill-soft); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round}
.il-rule{fill:none; stroke:var(--ill-soft); stroke-width:3; stroke-linecap:round}
.il-v   {fill:none; stroke:var(--violet-ink); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round}
.il-vf  {fill:rgba(123,97,255,.12); stroke:var(--violet-ink); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round}
.il-w   {fill:none; stroke:var(--ill-wire); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round}
.il-wd  {fill:none; stroke:var(--ill-wire); stroke-width:1.5; stroke-linecap:round; stroke-dasharray:3 5}
.il-c   {fill:none; stroke:var(--coral); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round}
.il-cd  {fill:var(--coral); stroke:none}
.il-grid{fill:none; stroke:rgba(31,31,46,.07); stroke-width:1}
.il-dot {fill:var(--ill-stroke); stroke:none}
/* the waveform: rects that breathe on scaleY (transform-box makes SVG rects scale about their own centre) */
.il-bar{fill:var(--violet-ink); stroke:none; transform-box:fill-box; transform-origin:center;
  --lo:.45; --hi:1; transform:scaleY(var(--lo)); animation:ill-wave 1.6s ease-in-out infinite alternate}
.il-bar:nth-child(5n+1){--lo:.35; --hi:1;   animation-duration:1.45s}
.il-bar:nth-child(5n+2){--lo:.55; --hi:.85; animation-duration:1.90s}
.il-bar:nth-child(5n+3){--lo:.30; --hi:.95; animation-duration:1.62s}
.il-bar:nth-child(5n+4){--lo:.50; --hi:.80; animation-duration:2.15s}
.il-bar:nth-child(3n){animation-delay:-.55s}
.il-bar:nth-child(4n){animation-delay:-1.1s}
.il-bar.is-c{fill:var(--coral)}
.il-orb{stroke:none; transform-box:fill-box; transform-origin:center; animation:ill-breathe 4.4s ease-in-out infinite}
@keyframes ill-wave{from{transform:scaleY(var(--lo))} to{transform:scaleY(var(--hi))}}
@keyframes ill-breathe{0%,100%{transform:scale(1)} 50%{transform:scale(1.08)}}

/* ─── labels: HTML, ≥12px, positioned with logical insets so they follow the mirrored art ───
   --x / --y are the anchor point as a % of the panel, measured from inline-start / top.
   .c centres the label on its anchor; .s hangs it from inline-start; .e from inline-end. */
.ill-lbl{position:absolute; z-index:2; margin:0; white-space:nowrap; font-size:13px; font-weight:600; line-height:1.4;
  color:var(--ink-2); inset-inline-start:var(--x); inset-block-start:var(--y)}
.ill-lbl.c{transform:translate(50%,-50%)}
html[dir=ltr] .ill-lbl.c{transform:translate(-50%,-50%)}
.ill-lbl.e{inset-inline-start:auto; inset-inline-end:var(--x)}
.ill-lbl.hi{color:var(--violet-ink)}
.ill-lbl.halo{padding:1px 6px; border-radius:6px; background:rgba(255,255,255,.72)}
.ill-lbl[lang=en]{letter-spacing:.02em}

/* ══════════ HERO A / B — one panel in .hero-stage (width min(520px,82vw) → min(400px,86vw)) ══════════ */
.ill-hero{margin:0; padding-block:6px 24px}          /* 24px clears .hero-cap's -8px pull, as the old figure did */
.ill-hero .ill{aspect-ratio:520/360}

/* ══════════ ABOUT A / B — the .about-grid figure cell ══════════ */
.ill-about{margin:0; width:100%}
@media (max-width:1000px){.about-grid .ill-about{width:min(560px,100%); margin-inline:auto; order:-1}} /* mirrors site.css §18 for .viz-about */
.ill-about-a .ill{aspect-ratio:420/340}
.ill-about-b .ill{aspect-ratio:420/300}

/* ══════════ ALO ZAKI A — one drawn SVG (org phone · ring of four · CRM + WhatsApp text) ══════════ */
.ill-zaki{width:min(560px,88vw); margin:clamp(48px,6vw,72px) auto clamp(52px,6vw,80px)}
.ill-zaki-a .ill{aspect-ratio:560/300}
.ill-zaki-a .ill-lbl{font-size:12.5px}

/* ══════════ ALO ZAKI B — HTML flow (wraps on phones) of drawn parts ══════════ */
.ill-zaki-b .ill{display:grid; grid-template-columns:auto 1fr auto; align-items:center; gap:0; padding:26px 22px}
.zb-phone{width:96px; height:96px}
.zb-phone svg,.zb-out svg,.zb-st svg{display:block; width:100%; height:100%}
.zb-link{position:relative; width:34px; height:2px; align-self:center; background:var(--ill-wire); border-radius:99px}
.zb-link::after{content:""; position:absolute; inset-block-start:-4px; inset-inline-end:-1px; width:8px; height:8px;
  border-inline-start:1.5px solid var(--ill-wire); border-block-end:1.5px solid var(--ill-wire); transform:rotate(45deg)}
html[dir=ltr] .zb-link::after{transform:rotate(-135deg)}
.zb-band{display:grid; grid-template-columns:auto 1fr auto; align-items:center}
.zb-core{position:relative; display:flex; align-items:flex-start; justify-content:space-between; gap:6px; padding:18px 14px 12px;
  border-radius:var(--r-m); border:1px solid rgba(123,97,255,.30); background:rgba(255,255,255,.55)}
.zb-core::before{content:""; position:absolute; inset-inline:38px; inset-block-start:46px; height:1.5px; background:var(--ill-wire); z-index:0}
.zb-st{position:relative; z-index:1; display:grid; justify-items:center; gap:8px; min-width:0}
.zb-st svg{width:56px; height:56px}
.zb-st p{margin:0; font-size:12.5px; font-weight:600; line-height:1.4; color:var(--ink-2); white-space:nowrap}
.zb-out{display:grid; gap:14px}
.zb-o{display:grid; justify-items:center; gap:6px}
.zb-o svg{width:72px; height:60px}
.zb-o p{margin:0; font-size:12.5px; font-weight:600; line-height:1.4; color:var(--ink-2); white-space:nowrap}

/* ══════════ THE ICON SET — 46px tile exactly like .viz-caps at small scale (no shadow, no sheen) ══════════ */
.ico-mark{display:grid; place-items:center; width:46px; height:46px; margin-block-end:22px; border-radius:15px;
  border:1px solid var(--line-soft); background:linear-gradient(160deg,rgba(123,97,255,.12),rgba(255,122,89,.10)); color:var(--violet-ink)}
.ico-mark svg{display:block; width:24px; height:24px; fill:none; stroke:currentColor; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round}

/* ══════════ responsive ══════════ */
@media (max-width:760px){
  .ill-lbl{font-size:12px}
  .ill-zaki-a .ill-lbl{font-size:12px}
  .ill-zaki-b .ill{grid-template-columns:1fr; justify-items:center; padding:22px 16px; row-gap:0}
  .ill-zaki-b .zb-link{width:2px; height:30px}
  .ill-zaki-b .zb-link::after{inset-inline-end:-3px; inset-block-start:auto; inset-block-end:0; transform:rotate(-45deg)}
  html[dir=ltr] .ill-zaki-b .zb-link::after{transform:rotate(-45deg)}
  .zb-band{grid-template-columns:1fr; justify-items:center}
  .zb-core{gap:4px; padding:14px 8px 10px}
  .zb-core::before{inset-inline:30px; inset-block-start:38px}
  .zb-st svg{width:48px; height:48px}
  .zb-st p,.zb-o p{font-size:12px}
  .zb-out{grid-template-columns:1fr 1fr; gap:22px}
}
@media (prefers-reduced-motion:reduce){
  .il-bar,.il-orb{animation:none}
  .il-bar{transform:scaleY(.7)}
}

/* label anchors (were inline styles; CSP style-src self) */
.lh-l1{--x:5%; --y:5%}
.lh-l2{--x:5%; --y:91%}
.la-l1{--x:26%; --y:80%}
.la-l2{--x:73%; --y:80%}
.lz-l1{--x:36.4%; --y:24%}
.lz-l2{--x:63.6%; --y:24%}
.lz-l3{--x:63.6%; --y:76%}
.lz-l4{--x:36.4%; --y:76%}
.lz-l5{--x:82.1%; --y:47%}
.lz-l6{--x:82.1%; --y:82%}
