/* ==========================================================================
   Elite Plus — design system
   Inherits the V2 print identity: palette, signature devices, type scale.
   ========================================================================== */

/* Fonts are loaded in each page <head> via Google Fonts with preconnect.
   To self-host instead: drop woff2 files in assets/fonts/, uncomment the
   @font-face block below, and remove the <link> tags. See README. */
/*
@font-face{font-family:'Poppins';src:url('../fonts/Poppins-SemiBold.woff2') format('woff2');font-weight:600;font-display:swap}
@font-face{font-family:'Poppins';src:url('../fonts/Poppins-Bold.woff2') format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Poppins';src:url('../fonts/Poppins-ExtraBold.woff2') format('woff2');font-weight:800;font-display:swap}
@font-face{font-family:'Mulish';src:url('../fonts/Mulish-Regular.woff2') format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Mulish';src:url('../fonts/Mulish-SemiBold.woff2') format('woff2');font-weight:600;font-display:swap}
@font-face{font-family:'Cairo';src:url('../fonts/Cairo-Regular.woff2') format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Cairo';src:url('../fonts/Cairo-Bold.woff2') format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Cairo';src:url('../fonts/Cairo-Black.woff2') format('woff2');font-weight:900;font-display:swap}
*/

:root{
  /* palette — identical to the V2 print kit */
  --orange:#F26522; --orange-deep:#D9541A; --orange-tint:#FDE7DA;
  --navy:#1B2A52;   --navy-deep:#141F3D;
  --bone:#E9E3D8;   --bone-tint:#F7F4EE;
  --white:#fff;     --gray:#6A7079;          /* muted type on LIGHT grounds — AA: 4.99 on white, 4.55 on bone-tint */
  --gray-soft:#9AA1AB;  --ink:#2A2F36;
  /* Accent TEXT colour — the palette itself is unchanged.
     #F26522 stays the accent for fills, rules, markers and buttons, but as TEXT
     it measures 3.15:1 on white and 4.44:1 on navy, under the 4.5:1 that WCAG
     2.2 AA requires below 18.66px bold / 24px regular. Small accent labels use
     this token instead: navy on light grounds, white on dark ones.
     To restore the all-orange look and forgo AA on those labels, set
     --accent-text:var(--orange) here and delete the dark-ground override. */
  --accent-text:var(--navy);
  --wood:#5B3A22;   --wood-light:#8A6240;
  --char:#15181F;   --gold:#C9A24B;  --gold-light:#E3C98A;
  --line:#E4E0D6;

  --disp:'Poppins',system-ui,-apple-system,'Segoe UI',sans-serif;
  --body:'Mulish',system-ui,-apple-system,'Segoe UI',sans-serif;

  --wrap:1280px;
  --pad:clamp(20px,5vw,64px);
  --sec:clamp(64px,8vw,120px);
  --r:0px;                       /* brand uses square corners */
  --t:.28s cubic-bezier(.22,1,.36,1);
}
html[lang="ar"]{--disp:'Cairo',system-ui,sans-serif; --body:'Cairo',system-ui,sans-serif}

*,*::before,*::after{box-sizing:border-box}
*{margin:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
}
body{font-family:var(--body);font-size:clamp(15px,1.05vw,16px);line-height:1.58;color:var(--ink);
  background:var(--white);overflow-x:hidden;-webkit-font-smoothing:antialiased}
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;cursor:pointer;border:0;background:none;color:inherit}
:focus-visible{outline:3px solid var(--orange);outline-offset:3px}
::selection{background:var(--orange);color:#fff}

.wrap{max-width:var(--wrap);margin-inline:auto;padding-inline:var(--pad)}
.sec{padding-block:var(--sec)}
.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{position:absolute;inset-inline-start:0;top:-60px;background:var(--navy);color:#fff;
  padding:12px 20px;z-index:200;transition:top var(--t)}
.skip:focus{top:0}

/* ---------- type ---------- */
h1,h2,h3,h4{font-family:var(--disp);font-weight:800;line-height:1.05;
  letter-spacing:-.02em;color:var(--navy);text-wrap:balance}
html[lang="ar"] h1,html[lang="ar"] h2,html[lang="ar"] h3,html[lang="ar"] h4{
  font-weight:900;line-height:1.28;letter-spacing:0}
h1{font-size:clamp(30px,5.2vw,58px)}
h2{font-size:clamp(25px,3.6vw,40px)}
h3{font-size:clamp(18px,1.7vw,22px)}
p{text-wrap:pretty}
.lead{font-size:clamp(16px,1.35vw,19px);line-height:1.55;color:var(--ink)}
.muted{color:var(--gray)}
.eyebrow{font-family:var(--disp);font-weight:600;font-size:12px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--accent-text);display:block;margin-bottom:14px}
html[lang="ar"] .eyebrow{letter-spacing:.06em;font-size:12px}
.rule{width:clamp(60px,10%,120px);height:3px;background:var(--navy);margin-block:18px 26px}
.rule--orange{background:var(--orange)}
.tagline{font-family:var(--disp);font-weight:600;font-style:italic;text-transform:uppercase;
  letter-spacing:.22em;font-size:12px}
html[lang="ar"] .tagline{font-style:normal;letter-spacing:.04em;font-size:13px}

/* ---------- signature devices (§4) ---------- */
.marker{position:absolute;inset-block-start:0;inset-inline-end:0;width:46px;height:46px;
  background:var(--orange);color:#fff;font-family:var(--disp);font-weight:700;font-size:16px;
  display:grid;place-items:center;z-index:4}
.marker--start{inset-inline-end:auto;inset-inline-start:0}
.brk{position:absolute;width:44px;height:44px;z-index:4;pointer-events:none}
.brk--tl{inset-block-start:0;inset-inline-start:0;border-inline-start:2px solid var(--orange);border-block-start:2px solid var(--orange)}
.brk--br{inset-block-end:0;inset-inline-end:0;border-inline-end:2px solid var(--orange);border-block-end:2px solid var(--orange)}
.sq{position:absolute;width:26px;height:26px;background:var(--orange);z-index:4}
.sq--out{background:none;border:2px solid var(--orange)}
.rings{position:absolute;z-index:0;opacity:.9;pointer-events:none}
.block{position:absolute;background:var(--bone);z-index:0}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:10px;font-family:var(--disp);font-weight:600;
  font-size:14px;letter-spacing:.02em;padding:15px 30px;transition:background var(--t),color var(--t),transform var(--t);
  border:2px solid transparent}
.btn:hover{transform:translateY(-2px)}
/* Navy-deep on orange = 5.15:1 (AA). White on orange was 3.15:1 — the primary
   CTA failed AA on every page. Both colours are from the locked palette;
   the orange itself is unchanged. */
.btn--primary{background:var(--orange);color:var(--navy-deep)}
.btn--primary:hover{background:var(--orange-deep)}
.btn--ghost{border-color:currentColor}
.btn--ghost:hover{background:var(--navy);color:#fff;border-color:var(--navy)}
/* The resting colour must live in CSS, not an inline style: an inline
   style="color:#fff" outranks every selector, so on hover the background
   turned white while the text stayed white — the label vanished. */
.btn--on-dark.btn--ghost{color:#fff}
.btn--on-dark.btn--ghost:hover{background:#fff;color:var(--navy);border-color:#fff}
.btn__arrow{transition:transform var(--t)}
.btn:hover .btn__arrow{transform:translateX(4px)}
html[dir="rtl"] .btn:hover .btn__arrow{transform:translateX(-4px)}

/* ---------- header ---------- */
.hdr{position:sticky;top:0;z-index:100;background:#fff;border-bottom:1px solid var(--line);
  transition:box-shadow var(--t)}
.hdr.is-stuck{box-shadow:0 2px 20px rgba(20,31,61,.09)}
.hdr__in{display:flex;align-items:center;gap:24px;min-height:92px}
/* flex-shrink was squeezing the anchor, and the global img{max-width:100%} then
   squashed the mark to 116px while height stayed 56px — a 25% horizontal
   distortion on every desktop page. The logo must never shrink. */
.hdr__logo{flex:0 0 auto}
.hdr__logo img{height:56px;width:auto;max-width:none}
@media(max-width:1024px){.hdr__in{min-height:80px}.hdr__logo img{height:46px}}
.nav{display:flex;align-items:center;gap:4px;margin-inline-start:auto}
.nav a{font-family:var(--disp);font-weight:600;font-size:14px;padding:10px 13px;position:relative;
  color:var(--navy);transition:color var(--t)}
.nav a::after{content:"";position:absolute;inset-block-end:2px;inset-inline-start:13px;
  width:0;height:2px;background:var(--orange);transition:width var(--t)}
.nav a:hover::after,.nav a[aria-current="page"]::after{width:calc(100% - 26px)}
/* The orange 2px underline already marks the current page; orange TEXT here
   would be 3.15:1 on the white header. Navy + bold keeps it distinct and AA. */
.nav a[aria-current="page"]{color:var(--navy);font-weight:700}
.hdr__act{display:flex;align-items:center;gap:10px;margin-inline-start:12px}
.lang{font-family:var(--disp);font-weight:600;font-size:13px;padding:12px 14px;
  border:1px solid var(--line);transition:border-color var(--t),color var(--t)}
.lang:hover{border-color:var(--navy)}
/* Header CTA: measured to wrap to 2 lines under 560px and to 3 lines in Arabic
   under 414px, which pushes the sticky bar from 80px to 100px. Below 560px the
   hero CTA and the floating WhatsApp button already cover the same action, so the
   bar drops it instead of wrapping it. */
.hdr__act .btn{white-space:nowrap}
@media(max-width:559px){.hdr__act .btn{display:none}}
.burger{display:none;width:46px;height:46px;place-items:center;border:1px solid var(--line)}
.burger span{display:block;width:20px;height:2px;background:var(--navy);position:relative}
.burger span::before,.burger span::after{content:"";position:absolute;left:0;width:20px;height:2px;background:var(--navy)}
.burger span::before{top:-6px}.burger span::after{top:6px}

@media(max-width:1024px){
  .burger{display:grid}
  .nav{position:fixed;inset:80px 0 auto;background:#fff;flex-direction:column;align-items:stretch;
    gap:0;padding:12px var(--pad) 28px;border-bottom:1px solid var(--line);
    transform:translateY(-130%);transition:transform var(--t);max-height:calc(100dvh - 80px);overflow:auto}
  .nav.is-open{transform:translateY(0)}
  .nav a{padding:15px 0;font-size:17px;border-bottom:1px solid var(--line)}
  .nav a::after{display:none}
  .hdr__act{margin-inline-start:auto}
}

/* ---------- hero (split: copy panel + image panel) ----------
   Split rather than full-bleed so the source photography is displayed at
   roughly 1:1 instead of being upscaled across the whole viewport. */
.hero{position:relative;background:var(--navy-deep);overflow:hidden;isolation:isolate;
  display:grid;grid-template-columns:1.06fr .94fr;align-items:stretch;
  min-height:clamp(500px,72vh,700px)}
.hero__copy{display:flex;flex-direction:column;justify-content:center;position:relative;z-index:2;
  padding:clamp(40px,5.5vw,72px) 0 clamp(40px,5.5vw,72px) var(--pad)}
html[dir="rtl"] .hero__copy{padding:clamp(40px,5.5vw,72px) var(--pad) clamp(40px,5.5vw,72px) 0}
.hero__media{position:relative;overflow:hidden}
.hero__media img{width:100%;height:100%;object-fit:cover;display:block}
.hero__media::after{content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,var(--navy-deep) 0%,rgba(20,31,61,.35) 18%,rgba(20,31,61,0) 46%)}
html[dir="rtl"] .hero__media::after{
  background:linear-gradient(270deg,var(--navy-deep) 0%,rgba(20,31,61,.35) 18%,rgba(20,31,61,0) 46%)}
.hero__rings{position:absolute;inset-block-end:-12%;inset-inline-start:-8%;width:min(46%,420px);
  aspect-ratio:1;border-radius:50%;z-index:0;opacity:.5;
  background:repeating-radial-gradient(circle,transparent 0 13px,rgba(233,227,216,.16) 13px 15px)}
.hero h1{color:#fff;max-width:15ch}
.hero .lead{color:var(--bone);max-width:46ch;margin-top:20px}
.hero__eyebrow{display:flex;align-items:center;gap:12px;margin-bottom:20px}
.hero__eyebrow i{width:14px;height:14px;background:var(--orange);flex:none}
.hero__eyebrow span{font-family:var(--disp);font-weight:600;font-style:italic;
  text-transform:uppercase;letter-spacing:.2em;font-size:15px;color:var(--orange)}
html[lang="ar"] .hero__eyebrow span{font-style:normal;letter-spacing:.04em;font-size:17px;font-weight:700}
.hero__cta{display:flex;flex-wrap:wrap;gap:14px;margin-top:32px}
.hero__strip{display:flex;flex-wrap:wrap;gap:0;border-top:1px solid rgba(255,255,255,.18);margin-top:40px}
.hero__strip a{flex:1 1 180px;padding:18px 18px 18px 0;display:flex;align-items:center;gap:12px;
  font-family:var(--disp);font-weight:600;font-size:13.5px;color:#fff;transition:opacity var(--t)}
html[dir="rtl"] .hero__strip a{padding:18px 0 18px 18px}
.hero__strip a:hover{opacity:.72}
.hero__strip i{width:4px;height:30px;flex:none}
@media(max-width:900px){
  .hero{grid-template-columns:1fr;min-height:0}
  .hero__copy{order:2;padding-inline:var(--pad);padding-block:clamp(36px,7vw,56px)}
  .hero__media{order:1;aspect-ratio:16/10}
  .hero__media::after{background:linear-gradient(180deg,rgba(20,31,61,.15) 60%,var(--navy-deep) 100%)}
  html[dir="rtl"] .hero__media::after{background:linear-gradient(180deg,rgba(20,31,61,.15) 60%,var(--navy-deep) 100%)}
  .hero h1,.hero .lead{max-width:none}
}

/* ---------- page head ---------- */
.phead{position:relative;background:var(--bone-tint);padding-block:clamp(40px,6vw,72px);overflow:hidden}
.phead h1{max-width:20ch}
.phead .lead{max-width:62ch;margin-top:16px}
.crumbs{display:flex;gap:8px;font-size:13px;color:var(--gray);margin-bottom:20px;flex-wrap:wrap}
.crumbs a:hover{color:var(--orange)}
.crumbs span[aria-current]{color:var(--navy);font-weight:600}

/* ---------- grids & cards ---------- */
.grid{display:grid;gap:clamp(20px,2.4vw,32px)}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
@media(max-width:900px){.g3,.g4{grid-template-columns:repeat(2,1fr)}}
@media(max-width:600px){.g2,.g3,.g4{grid-template-columns:1fr}}

.dcard{position:relative;display:flex;flex-direction:column;background:#fff;
  border:1px solid var(--line);transition:transform var(--t),box-shadow var(--t)}
.dcard:hover{transform:translateY(-4px);box-shadow:0 16px 40px rgba(20,31,61,.10)}
.dcard__bar{height:8px;background:var(--navy)}
.dcard__img{aspect-ratio:4/3;overflow:hidden}
.dcard__img img{width:100%;height:100%;object-fit:cover;transition:transform .6s cubic-bezier(.22,1,.36,1)}
.dcard:hover .dcard__img img{transform:scale(1.04)}
.dcard__b{padding:26px 26px 30px;display:flex;flex-direction:column;gap:10px;flex:1}
.dcard__n{font-family:var(--disp);font-weight:600;font-size:12px;letter-spacing:.2em;color:var(--gray)}
.dcard__more{margin-top:auto;padding-top:14px;font-family:var(--disp);font-weight:600;font-size:13px;
  color:var(--accent-text);display:inline-flex;gap:8px;align-items:center}

.pcard{position:relative;display:block;background:#fff;border:1px solid var(--line);
  transition:transform var(--t),box-shadow var(--t)}
.pcard:hover{transform:translateY(-4px);box-shadow:0 16px 40px rgba(20,31,61,.10)}
.pcard__img{aspect-ratio:3/2;overflow:hidden;background:var(--bone-tint)}
.pcard__img img{width:100%;height:100%;object-fit:cover;transition:transform .6s cubic-bezier(.22,1,.36,1)}
.pcard:hover .pcard__img img{transform:scale(1.04)}
.pcard__b{padding:22px 24px 26px}
.pcard__meta{display:flex;gap:8px;align-items:center;font-family:var(--disp);font-weight:600;
  font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--gray);margin-bottom:10px}
.pcard__meta i{width:9px;height:9px;background:var(--orange);flex:none}
.pcard h3{font-size:19px}
.pcard p{font-size:14px;color:var(--gray);margin-top:8px}

/* ---------- dark band ---------- */
/* Dark containers need the LIGHTER muted grey; #6A7079 would sink into the navy.
   Custom properties cascade, so one re-binding covers every var(--gray) inside. */
.ftr,.band{--gray:var(--gray-soft);--accent-text:#fff}
.band{position:relative;background:var(--navy);color:#fff;overflow:hidden}
.band h2,.band h3{color:#fff}
.band .lead,.band p{color:var(--bone)}
.band--wood{background:var(--wood)}
.band--char{background:var(--char)}
.band--char .eyebrow{color:var(--gold)}
.band--char h2{color:#fff}

/* ---------- split ---------- */
.split{display:grid;grid-template-columns:1.02fr 1fr;gap:clamp(28px,5vw,72px);align-items:center}
.split--rev{grid-template-columns:1fr 1.02fr}
@media(max-width:900px){.split,.split--rev{grid-template-columns:1fr}}
.stack{position:relative}
.stack__block{position:absolute;inset-block-start:26px;inset-inline-start:-26px;
  width:62%;height:74%;background:var(--bone);z-index:0}
.stack img{position:relative;z-index:1;width:100%;aspect-ratio:4/5;object-fit:cover}
@media(max-width:900px){.stack__block{display:none}.stack img{aspect-ratio:4/3}}

/* ---------- list / services ---------- */
.slist{display:grid;gap:0;margin-top:8px}
.srow{display:grid;grid-template-columns:auto 1fr;gap:18px;padding:20px 0;border-bottom:1px solid var(--line)}
.band .srow{border-color:rgba(255,255,255,.16)}
.srow__n{font-family:var(--disp);font-weight:700;font-size:12px;color:var(--accent-text);padding-top:3px}
.srow h3{font-size:17px;margin-bottom:5px}
.srow p{font-size:14.5px;color:var(--gray)}
.band .srow p{color:var(--bone)}

/* ---------- stats ---------- */
.stats{display:grid;grid-template-columns:repeat(4,1fr);background:var(--navy)}
@media(max-width:700px){.stats{grid-template-columns:repeat(2,1fr)}}
.stat{padding:34px 20px;text-align:center;border-inline-end:1px solid rgba(255,255,255,.12)}
.stat:last-child{border:0}
.stat b{display:block;font-family:var(--disp);font-weight:800;font-size:clamp(24px,2.6vw,32px);color:var(--orange)}
.stat span{font-size:12.5px;color:var(--bone)}

/* ---------- clients ---------- */
.clients{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:clamp(28px,5vw,72px)}
.clients img{height:clamp(34px,3.4vw,46px);width:auto;opacity:.78;transition:opacity var(--t)}
.clients img:hover{opacity:1}

/* ---------- filters ---------- */
.filters{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:36px}
.filters button{font-family:var(--disp);font-weight:600;font-size:13px;padding:11px 20px;
  border:1px solid var(--line);color:var(--navy);transition:all var(--t)}
.filters button:hover{border-color:var(--navy)}
.filters button[aria-pressed="true"]{background:var(--navy);border-color:var(--navy);color:#fff}
.empty{padding:60px 0;text-align:center;color:var(--gray);display:none}
.empty.is-on{display:block}

/* ---------- gallery ---------- */
.gal{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
@media(max-width:900px){.gal{grid-template-columns:repeat(2,1fr)}}
.gal button{position:relative;overflow:hidden;aspect-ratio:1;background:var(--bone-tint);display:block;width:100%}
.gal img{width:100%;height:100%;object-fit:cover;transition:transform .6s cubic-bezier(.22,1,.36,1)}
/* portrait thumbs (doors) — show the whole leaf, don't crop it to a square */
.gal--tall button{aspect-ratio:2/3}
.gal--tall img{object-fit:contain;background:var(--bone-tint)}
.gal button:hover img{transform:scale(1.05)}
.gal button::after{content:"";position:absolute;inset:0;background:rgba(20,31,61,0);transition:background var(--t)}
.gal button:hover::after{background:rgba(20,31,61,.14)}

/* ---------- lightbox ---------- */
.lb{position:fixed;inset:0;z-index:300;background:rgba(10,14,26,.95);display:none;
  place-items:center;padding:clamp(16px,4vw,56px)}
.lb.is-open{display:grid}
.lb img{max-width:100%;max-height:82vh;object-fit:contain}
.lb__cap{color:var(--bone);font-size:13.5px;text-align:center;margin-top:16px;max-width:70ch}
.lb__x,.lb__p,.lb__n{position:absolute;width:52px;height:52px;display:grid;place-items:center;
  color:#fff;font-size:26px;background:rgba(255,255,255,.10);transition:background var(--t)}
.lb__x:hover,.lb__p:hover,.lb__n:hover{background:var(--orange)}
.lb__x{top:20px;inset-inline-end:20px}
.lb__p{inset-inline-start:16px;top:50%;transform:translateY(-50%)}
.lb__n{inset-inline-end:16px;top:50%;transform:translateY(-50%)}

/* ---------- spec table + accordion ---------- */
.acc{border:1px solid var(--line);margin-bottom:12px;background:#fff}
.acc__h{width:100%;display:flex;justify-content:space-between;align-items:center;gap:16px;
  padding:18px 22px;font-family:var(--disp);font-weight:600;font-size:15px;color:var(--navy);text-align:start}
.acc__h:hover{background:var(--bone-tint)}
.acc__i{font-size:20px;color:var(--orange);transition:transform var(--t);flex:none}
.acc__h[aria-expanded="true"] .acc__i{transform:rotate(45deg)}
.acc__p{display:none;padding:0 22px 22px}
.acc__p.is-open{display:block}
.spec{width:100%;border-collapse:collapse;font-size:14.5px}
.spec th,.spec td{text-align:start;padding:12px 14px;border-bottom:1px solid var(--line)}
.spec th{font-family:var(--disp);font-weight:600;color:var(--navy);width:52%}
.spec td{color:var(--gray)}
.spec tr:last-child th,.spec tr:last-child td{border-bottom:0}
.note{background:var(--orange-tint);border-inline-start:3px solid var(--orange);
  padding:16px 20px;font-size:14px;margin-top:18px}

/* ---------- product ---------- */
/* A WHITE product card sitting inside a dark .band was inheriting the band's
   white type: h3 rendered #fff on #fff (contrast 1.00 — the model names were
   invisible) and .muted rendered bone on white (1.28). A light card must always
   restate its own type colours. */
.band .prod{color:var(--ink);--gray:#6A7079}  /* white card: back to the dark grey */
.band .prod h3{color:var(--navy)}
.band .prod p,.band .prod .muted,.band .prod .lead{color:var(--gray)}
.prod{border:1px solid var(--line);background:#fff;display:flex;flex-direction:column}
/* Product frames letterbox the shot — a door or lock is never cropped.
   Absolute box + object-fit:contain instead of max-height:%, which is
   unreliable inside an overflow:hidden aspect-ratio container. */
.prod__img{position:relative;aspect-ratio:2/3;background:var(--bone-tint);overflow:hidden}
.prod__img img{position:absolute;inset:16px;width:calc(100% - 32px);height:calc(100% - 32px);
  object-fit:contain;object-position:center}
.prod__img--lock{aspect-ratio:3/4}
.prod__img--wide{aspect-ratio:4/5}
.prod__b{padding:24px;display:flex;flex-direction:column;gap:12px;flex:1}
.chips{display:flex;flex-wrap:wrap;gap:7px}
.chip{font-family:var(--disp);font-weight:600;font-size:12px;letter-spacing:.05em;
  padding:6px 12px;border:1px solid var(--line);color:var(--navy)}
.chip--gold{border-color:var(--gold);color:var(--wood)}
.ul{list-style:none;padding:0;display:grid;gap:9px;font-size:14.5px}
.ul li{display:grid;grid-template-columns:auto 1fr;gap:11px;align-items:start}
.ul li::before{content:"";width:8px;height:8px;background:var(--orange);margin-top:8px}

/* ---------- downloads ---------- */
.dl{display:flex;align-items:center;gap:18px;padding:22px 24px;border:1px solid var(--line);
  background:#fff;transition:border-color var(--t),transform var(--t)}
.dl:hover{border-color:var(--navy);transform:translateY(-2px)}
.dl__ic{width:46px;height:46px;background:var(--bone-tint);display:grid;place-items:center;
  font-family:var(--disp);font-weight:700;font-size:12px;color:var(--navy);flex:none}
.dl__t{font-family:var(--disp);font-weight:600;color:var(--navy);font-size:15px}
.dl__m{font-size:12.5px;color:#6A7079}   /* white card: never the soft grey — 4.99:1 */
.dl__a{margin-inline-start:auto;color:var(--orange);font-size:22px;flex:none}

/* ---------- forms ---------- */
.form{display:grid;gap:18px}
.field{display:grid;gap:7px}
.field label{font-family:var(--disp);font-weight:600;font-size:13px;color:var(--navy)}
.field .opt{color:var(--gray);font-weight:400}
.field input,.field select,.field textarea{font:inherit;font-size:15px;padding:13px 15px;
  border:1px solid var(--line);background:#fff;color:var(--ink);width:100%;transition:border-color var(--t)}
.field textarea{min-height:132px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--navy);outline:none}
.field.is-bad input,.field.is-bad select,.field.is-bad textarea{border-color:#B91C1C}
.err{font-size:12.5px;color:#B91C1C;display:none}
.field.is-bad .err{display:block}
.check{display:grid;grid-template-columns:auto 1fr;gap:11px;align-items:start;font-size:14px}
.check input{width:19px;height:19px;margin-top:2px;accent-color:var(--orange)}
.alert{padding:16px 20px;font-size:14.5px;display:none}
.alert.is-on{display:block}
.alert--ok{background:#E8F5EF;border-inline-start:3px solid #0A7A58;color:#0A5C43}
.alert--bad{background:#FDECEC;border-inline-start:3px solid #B91C1C;color:#8F1414}
@media(min-width:700px){.form__row{display:grid;grid-template-columns:1fr 1fr;gap:18px}}

/* ---------- footer ---------- */
.ftr{background:var(--navy-deep);color:var(--bone);padding-block:clamp(48px,6vw,76px) 0}
.ftr h2{color:#fff;font-size:13px;letter-spacing:.16em;text-transform:uppercase;margin-bottom:18px}
html[lang="ar"] .ftr h2{letter-spacing:.03em}
.ftr a{color:var(--bone);font-size:14.5px;transition:color var(--t)}
.ftr a:hover{color:var(--orange)}
.ftr__grid{display:grid;grid-template-columns:1.5fr 1fr 1fr 1.2fr;gap:clamp(24px,3vw,48px)}
@media(max-width:900px){.ftr__grid{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.ftr__grid{grid-template-columns:1fr}}
.ftr__logo img{height:44px;width:auto;margin-bottom:18px}
/* Touch targets: 44px minimum. Padding replaces the list gap so the visual
   rhythm is unchanged while the tappable area more than doubles. */
.ftr ul{list-style:none;padding:0;display:grid;gap:0}
.ftr ul a{display:block;padding-block:14px}
.ftr__bot a{display:inline-block;padding-block:14px}
.crumbs a{display:inline-block;padding-block:12px}
/* Hit area without layout shift: padding grows the tappable box, the equal
   negative margin cancels the space it would otherwise add. */
.dcard__more{padding-bottom:10px;margin-bottom:-10px}
.dcard__more .btn__arrow,.dcard__more span[aria-hidden]{color:var(--orange)}
.ul li a{display:block;padding-block:7px;margin-block:-7px}
.dcard__b a,.contact__b a{display:inline-block;padding-block:8px;margin-block:-8px}
.ftr__bot{margin-top:clamp(36px,5vw,60px);border-top:1px solid rgba(255,255,255,.14);
  padding-block:22px;display:flex;flex-wrap:wrap;gap:14px;justify-content:space-between;
  font-size:12.5px;color:var(--gray)}

/* ---------- floating actions ---------- */
.fab{position:fixed;inset-block-end:22px;inset-inline-end:22px;z-index:90;display:grid;gap:10px}
.fab a,.fab button{width:50px;height:50px;display:grid;place-items:center;background:var(--navy);
  color:#fff;font-size:20px;box-shadow:0 6px 20px rgba(20,31,61,.24);transition:background var(--t),opacity var(--t)}
.fab a:hover,.fab button:hover{background:var(--orange)}
.fab .totop{opacity:0;visibility:hidden;pointer-events:none}
.fab .totop.is-on{opacity:1;visibility:visible;pointer-events:auto}

/* ==========================================================================
   Cross-document navigation
   This is a classic multi-page site: every click is a real page load. Without
   these rules the browser paints white between pages, which reads as a hard
   reload. Native View Transitions cross-fade the two documents instead.
   Progressive enhancement — unsupported browsers behave exactly as before.
   Requires http(s); it does NOT run from file:// (opaque origin).
   ========================================================================== */
@view-transition{navigation:auto}

::view-transition-old(root){animation:vt-out .16s cubic-bezier(.4,0,1,1) both}
::view-transition-new(root){animation:vt-in  .26s cubic-bezier(0,0,.2,1) both}
@keyframes vt-out{to{opacity:0}}
@keyframes vt-in{from{opacity:0}}

/* Chrome/nav shell is identical on every page — name it so it stays put
   instead of cross-fading with the body. Stops the header flickering. */
.hdr{view-transition-name:hdr}
.ftr{view-transition-name:ftr}

@media (prefers-reduced-motion:reduce){
  @view-transition{navigation:none}
}

/* ---------- utilities & form chrome (added with the form work) ---------- */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.lb__fig{position:relative;max-width:min(1200px,92vw);max-height:86vh;text-align:center}
.lb__fig img{max-width:100%;max-height:78vh;object-fit:contain;margin-inline:auto}
body.nav-open{overflow:hidden}
.form__summary{border:2px solid #B3261E;background:#FDECEA;color:#7A1C15;padding:14px 18px;
  margin-bottom:18px;font-size:14.5px}
.form__summary ul{margin:8px 0 0;padding-inline-start:20px}
.form__summary a{color:#7A1C15;text-decoration:underline}
.form__summary:focus-visible{outline:3px solid var(--navy);outline-offset:2px}
.note--field{display:block;font-size:12.5px;color:var(--gray);margin-top:6px}
.field input[type=file]{padding:10px;border:1px dashed var(--line);background:#fff;width:100%}
.field input[aria-invalid=true],.field select[aria-invalid=true],.field textarea[aria-invalid=true]
  {border-color:#B3261E}
/* Direction-neutral: an off-canvas offset would add ~10000px of horizontal
   scroll to every Arabic (RTL) page carrying a form. */
.hp{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;border:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap;pointer-events:none}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
}

/* ==========================================================================
   v2.3 — unified brand mark · WhatsApp green · armored-door gallery
   ========================================================================== */

/* ---------- unified logo ----------
   The mark is a 4.7:1 wordmark, not the 2.8:1 divisional lockup it replaces,
   so the display heights are re-tuned: at the old 56px it ran 263px wide and
   crowded the nav. width:auto + max-width:none stay mandatory — the global
   img{max-width:100%} distorts any logo that carries a width attribute. */
.hdr__logo img{height:38px}
@media(max-width:1024px){.hdr__logo img{height:34px}}
@media(max-width:560px){.hdr__logo img{height:30px}}

/* Dark grounds get an ISOLATION PLATE, never a recoloured logo.
   "PLUS" is set in navy inside the orange block; on the navy footer it would
   measure 1.01:1 against it. Deriving a white version is forbidden (it
   flattens a two-colour mark), so the mark sits on warm bone instead — the
   same treatment the share card and the app icons bake in. */
.ftr__logo{display:inline-block;background:var(--bone);padding:12px 18px;margin-bottom:18px}
.ftr__logo img{height:34px;width:auto;max-width:none;margin-bottom:0;display:block}

/* ---------- WhatsApp ----------
   #25D366 is WhatsApp's own green and is used ONLY for the glyph. Backgrounds,
   buttons and type stay in the Elite Plus palette.
   Contrast, measured: 7.06:1 on --navy #1B2A52 and 8.19:1 on --navy-deep
   #141F3D — both clear of the 3:1 that WCAG 2.2 AA asks of a meaningful
   graphic, and of 4.5:1 as well. The floating button therefore keeps a navy
   ground and darkens on hover instead of turning orange: green on orange
   measures 1.59:1 and would have failed the moment a pointer touched it. */
.wa__i{color:#25D366;flex:none}
.fab__wa{color:#25D366}
.fab a.fab__wa:hover,.fab a.fab__wa:focus-visible{background:var(--navy-deep)}
.ftr a.wa{display:flex;align-items:center;gap:9px}
.ftr a.wa span{color:var(--bone);transition:color var(--t)}
.ftr a.wa:hover span{color:var(--orange)}
.ftr a.wa:hover .wa__i{color:#25D366}      /* the glyph never takes the hover colour */

/* ---------- armored-door gallery ----------
   Same visual language as .gal, plus a visible caption carrying the code that
   is printed on the artwork. The caption is aria-hidden: the button's own
   label already announces direction and code, and announcing both would read
   the code twice. Tiles are 2:3 because the masters are 1440x2160 exactly. */
.agal{display:grid;grid-template-columns:repeat(5,1fr);gap:14px;margin-top:18px}
.agal figure{margin:0}
.agal button{position:relative;overflow:hidden;aspect-ratio:2/3;background:var(--bone-tint);
  display:block;width:100%}
.agal img{width:100%;height:100%;object-fit:contain;background:var(--bone-tint);
  transition:transform .6s cubic-bezier(.22,1,.36,1)}
.agal button:hover img{transform:scale(1.04)}
.agal button::after{content:"";position:absolute;inset:0;background:rgba(20,31,61,0);
  transition:background var(--t)}
.agal button:hover::after{background:rgba(20,31,61,.12)}
.agal figcaption{font-family:var(--disp);font-weight:600;font-size:12.5px;color:var(--navy);
  text-align:center;padding-top:8px}
.agal__h{margin-top:40px;font-size:clamp(18px,2vw,22px);display:flex;align-items:baseline;
  gap:12px;flex-wrap:wrap}
.agal__n{font-family:var(--body);font-weight:600;font-size:12.5px;color:var(--gray);
  border:1px solid var(--line);padding:3px 9px}
@media(max-width:1100px){.agal{grid-template-columns:repeat(4,1fr)}}
@media(max-width:820px){.agal{grid-template-columns:repeat(3,1fr)}}
@media(max-width:540px){.agal{grid-template-columns:repeat(2,1fr);gap:10px}}

/* ==========================================================================
   v2.4 — product category tabs · footer mark without a plate · WhatsApp button
   ========================================================================== */

/* ---------- product tabs ----------
   The visual language deliberately matches the projects page filter row, so
   the two read as one system; the behaviour underneath is a real ARIA tablist
   because these panels differ in structure, unlike the identical project
   cards a filter switches.

   .has-tabs is set by tabs-boot.js in <head>. Without JavaScript the class
   never arrives, nothing is hidden, and the page stays the single scrolling
   document it was — and because the class lands BEFORE first paint, the five
   panels never flash open and collapse. */
.ptabs{position:sticky;top:80px;z-index:60;background:#fff;
  border-bottom:1px solid var(--line);padding-block:14px}
@media(max-width:1024px){.ptabs{top:80px}}
.ptabs .wrap{position:relative}
.ptabs__scroll{display:flex;gap:10px;overflow-x:auto;scrollbar-width:none;
  scroll-behavior:smooth;-webkit-overflow-scrolling:touch}
.ptabs__scroll::-webkit-scrollbar{display:none}
.ptab{flex:0 0 auto;font-family:var(--disp);font-weight:600;font-size:14px;
  color:var(--navy);background:#fff;border:1px solid var(--line);
  padding:12px 20px;cursor:pointer;transition:background var(--t),color var(--t),
  border-color var(--t)}
.ptab:hover{border-color:var(--navy)}
.ptab.is-on{background:var(--navy);color:#fff;border-color:var(--navy)}
.ptab:focus-visible{outline:3px solid var(--orange);outline-offset:2px}
/* the fade that says "there is more this way". Direction-neutral so it sits on
   the correct edge in Arabic without a second rule. */
/* The "there is more here" edge. Kept narrow and steep on purpose: at 52px
   with a soft stop it washed a pale gradient across the whole end of the
   ACTIVE tab, which is navy, and the prototype screenshot read as a rendering
   fault rather than as an affordance. 34px with the white reaching full
   opacity by 55% confines it to the edge, where it says the strip continues
   and nothing else. */
.ptabs__hint{position:absolute;inset-block:0;inset-inline-end:0;width:34px;
  pointer-events:none;opacity:0;transition:opacity var(--t);
  background:linear-gradient(to left,#fff 55%,rgba(255,255,255,0))}
html[dir=rtl] .ptabs__hint{background:linear-gradient(to right,#fff 55%,rgba(255,255,255,0))}
.ptabs__hint.is-on{opacity:1}
@media(min-width:900px){.ptabs__hint{display:none}}

/* Three rules, in this order, and the order is the whole trick.
   1. BEFORE tabs.js runs: only the first panel is displayed. This is what
      actually stops the 51 armored frames from being fetched — a lazy image
      inside a display:none subtree is never requested. Hiding them with the
      [hidden] attribute alone was not enough: tabs.js is deferred, so the
      browser had already parsed, painted and started fetching 48 of them
      before the attribute arrived. Measured, not assumed.
   2. AFTER tabs.js announces itself with .has-tabs-ready: every panel is
      closed by default...
   3. ...and the one without [hidden] is the open one. */
html.has-tabs .ppanel + .ppanel{display:none}
html.has-tabs-ready .ppanel{display:none}
html.has-tabs-ready .ppanel:not([hidden]){display:block}
.ppanel:focus{outline:none}
.ppanel:focus-visible{outline:3px solid var(--orange);outline-offset:-3px}

/* ---------- footer mark: no plate ----------
   The bone rectangle was added on a wrong reading of the artwork. "PLUS" is
   navy type inside an ORANGE block, so the block is its own isolation area and
   the word measures 4.44:1 against it on any ground. The plate was solving a
   problem that did not exist and read as a sticker on the footer.
   Clear space is kept as margin instead — the mark still needs air, it just
   does not need a background. */
.ftr__logo{display:inline-block;background:none;padding:0;margin-bottom:22px}
.ftr__logo img{height:34px;width:auto;max-width:none;margin-bottom:0;display:block}
@media(max-width:560px){.ftr__logo{margin-bottom:18px}.ftr__logo img{height:30px}}

/* ---------- WhatsApp: white glyph on the official green ----------
   The v2.3 build put a green glyph on the navy button so no large area turned
   green. The owner asked for WhatsApp's own lockup instead: white mark on
   #25D366. That IS the brand's asset, and WCAG exempts a logo from contrast —
   white on #25D366 measures 1.98:1 and would fail as ordinary UI, which is why
   it is confined to the glyph inside the brand's own green and never used for
   text. What matters for the CONTROL is that the button reads against the
   page: #25D366 on white is 1.98:1, so the button keeps a defined edge rather
   than floating, and darkens on hover for a visible state change. */
.fab a.fab__wa{background:#25D366;color:#fff;border:1px solid #1DA851}
.fab a.fab__wa .wa__i{color:#fff}
.fab a.fab__wa:hover,.fab a.fab__wa:focus-visible{background:#1DA851}
.fab a.fab__wa:hover .wa__i,.fab a.fab__wa:focus-visible .wa__i{color:#fff}
/* In the footer the glyph sits on the navy band, not on a green chip: there
   the official green is the readable choice at 7.06:1. */
.ftr a.wa .wa__i{color:#25D366}

/* ---- v2.4a — phone number direction -------------------------------------
   The Arabic footer showed "+20 10 3553 3899" as "3899 3553 10 20+": the
   digit groups are LTR runs but the spaces between them are neutral, so the
   bidi algorithm resolved them to the RTL paragraph direction and reversed
   the group order. The link target was never wrong — only what the reader
   saw, which in a phone number is indistinguishable from bad data.
   `direction` fixes the run; `isolate` keeps it out of the reordering of the
   Arabic text beside it. The markup carries dir="ltr" as well, so the fix
   survives a page that loads without this stylesheet. */
.tel{direction:ltr;unicode-bidi:isolate;display:inline-block}
