
:root{
  --teal-950:#072B22; --teal-900:#0A3D30; --teal:#0F6E56; --teal-600:#158268;
  --amber:#BA7517;    --amber-bright:#D89234; --amber-pale:#E8C98F;
  /* Amber for SMALL TEXT on light grounds only. #BA7517 on cream measures
     3.19:1, under the 4.5:1 floor for body-size text; this tint measures
     4.97:1. The brand accent itself is unchanged - shapes, rules, marks and
     large display type all keep --amber. */
  --amber-text:#8F5A11;
  --cream:#F1EFE8;    --panel:#FAF8F2;    --panel-2:#EAE4D5;  --white:#FFFFFF;
  --ink:#232B26;      --muted:#5A665D;    --line:#DED8C8;
  --wa:#1FAF5E;       --alert:#A6431F;
  /* sampled from the hero footage's own background so the stage never seams */
  --taupe:#9F9683;
  /* cream at 62% — the readable tint for hairlines on dark grounds */
  --line-dark:rgba(241,239,232,.16);
  --display:'Marcellus',Georgia,'Times New Roman',serif;
  --sans:'IBM Plex Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --ease:cubic-bezier(.22,.7,.25,1);
}

.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--teal-950);color:var(--cream);
  padding:12px 20px;border-radius:0 0 8px 0;font-family:var(--mono);font-size:.85rem;text-decoration:none}
.skip:focus{left:0}

*{box-sizing:border-box}
/* clip, NOT hidden — overflow-x:hidden silently makes this a scroll container
   and position:sticky stops working on every page that uses it. */
html,body{overflow-x:clip}
html{scroll-behavior:smooth;font-size:17px;-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--cream);color:var(--ink);
  font-family:var(--sans);font-size:19px;line-height:1.7;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
img{max-width:100%;height:auto;display:block}
h1,h2,h3,h4{font-family:var(--display);font-weight:400;margin:0;text-wrap:balance;letter-spacing:-.005em}
p{margin:0 0 1.1em}
a{color:var(--teal);text-underline-offset:3px}
::selection{background:var(--amber-pale);color:var(--teal-950)}
:focus-visible{outline:2px solid var(--amber);outline-offset:3px;border-radius:3px}

/* ---------------------------------------------------------------- layout */
.wrap{width:min(1180px,92vw);margin-inline:auto}
.wrap-n{width:min(780px,92vw);margin-inline:auto}
section{position:relative;padding:clamp(74px,9vw,138px) 0}
.pad-s{padding:clamp(48px,6vw,84px) 0}

/* Paper grain. Two-octave fractal noise at 3.5% — visible as texture on a
   large cream field, invisible as pattern. Painted on a pseudo-element so it
   never intercepts a pointer event. */
.grain::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;opacity:.038;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='2'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}
.grain>*{position:relative;z-index:1}

/* ------------------------------------------------------------- surfaces */
.s-cream{background:var(--cream)}
.s-panel{background:var(--panel)}
.s-white{background:var(--white)}
.s-panel2{background:var(--panel-2)}
.s-dark{background:var(--teal-950);color:var(--cream)}
.s-teal{background:var(--teal-900);color:var(--cream)}
.s-dark h1,.s-dark h2,.s-dark h3,.s-teal h1,.s-teal h2,.s-teal h3{color:var(--cream)}
.s-dark .eyebrow,.s-teal .eyebrow{color:var(--amber-pale)}
.s-dark .lede,.s-teal .lede{color:rgba(241,239,232,.76)}
.s-dark a,.s-teal a{color:var(--amber-bright)}
.s-dark .rule,.s-teal .rule{background:var(--line-dark)}

/* ----------------------------------------------------------------- type */
.eyebrow{
  font-family:var(--mono);font-size:.85rem;font-weight:500;letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted);margin:0 0 18px;
  display:flex;align-items:center;gap:10px;
}
.eyebrow .star{color:var(--amber);font-size:1.05em;line-height:1}
.h1{font-size:clamp(2.7rem,6.2vw,5rem);line-height:1.02;color:var(--teal-950)}
.h2{font-size:clamp(2rem,4.4vw,3.4rem);line-height:1.08;color:var(--teal-950);margin:0 0 20px}
.h3{font-size:clamp(1.35rem,2.4vw,1.75rem);line-height:1.2;color:var(--teal-950)}
.lede{font-size:clamp(1.06rem,1.6vw,1.25rem);color:var(--muted);max-width:60ch;line-height:1.65}
.mono{font-family:var(--mono)}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums}
.rule{height:1px;background:var(--line);border:0;margin:0}
.star{color:var(--amber)}
.dot{width:.42em;height:.42em;border-radius:50%;background:var(--amber);display:inline-block;vertical-align:.12em}

/* A section divider that is a mark, not a line: hairline — asterism — hairline */
.asterism{display:flex;align-items:center;gap:18px;color:var(--amber);margin:0 0 clamp(34px,5vw,58px)}
.asterism::before,.asterism::after{content:"";flex:1;height:1px;background:var(--line)}
.s-dark .asterism::before,.s-dark .asterism::after,
.s-teal .asterism::before,.s-teal .asterism::after{background:var(--line-dark)}

/* -------------------------------------------------------------- buttons */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  font-family:var(--sans);font-size:1.02rem;font-weight:500;text-decoration:none;
  padding:15px 26px;border-radius:99px;border:1px solid transparent;cursor:pointer;
  position:relative;overflow:hidden;
  transition:transform .2s var(--ease),box-shadow .2s var(--ease),background .2s,border-color .2s,color .2s;
}
/* travelling sheen — a single pass on hover, not a loop */
.btn::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 38%,rgba(255,255,255,.28) 50%,transparent 62%);
  transform:translateX(-130%);transition:transform .65s var(--ease);
}
.btn:hover::after{transform:translateX(130%)}
.btn:hover{transform:translateY(-2px)}
.btn-teal{background:var(--teal);color:#fff;box-shadow:0 14px 30px -16px rgba(15,110,86,.9)}
.btn-teal:hover{background:var(--teal-600)}
.btn-wa{background:var(--wa);color:#fff;box-shadow:0 14px 30px -16px rgba(31,175,94,.9)}
.btn-amber{background:var(--amber);color:var(--teal-950);font-weight:600;box-shadow:0 14px 30px -16px rgba(186,117,23,.9)}
.btn-ghost{background:transparent;color:var(--teal-900);border-color:rgba(35,43,38,.28)}
.btn-ghost:hover{border-color:var(--teal);background:var(--white)}
.s-dark .btn-ghost,.s-teal .btn-ghost{color:var(--cream);border-color:var(--line-dark)}
.s-dark .btn-ghost:hover,.s-teal .btn-ghost:hover{background:rgba(241,239,232,.08);border-color:var(--amber-bright)}
/* Button text colour has to out-specify `.s-dark a` / `.s-teal a` (0,1,1),
   which otherwise repaints every button label on a dark section amber - and
   an amber label on an amber pill is invisible. A lone `.btn-amber` (0,1,0)
   loses that cascade, so the dark-section variants are restated here. */
.s-dark .btn-amber,.s-teal .btn-amber{color:var(--teal-950)}
.s-dark .btn-teal,.s-teal .btn-teal,
.s-dark .btn-wa,.s-teal .btn-wa{color:#fff}
.btn .wa-icon{width:19px;height:19px}
.wa-icon{width:17px;height:17px;fill:currentColor;flex:none}
.btn-row{display:flex;gap:12px;flex-wrap:wrap;align-items:center}

/* Inline text link that draws its own underline on hover */
.tlink{
  font-family:var(--mono);font-size:.9rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--teal);text-decoration:none;display:inline-flex;align-items:center;gap:9px;
  padding-bottom:3px;background-image:linear-gradient(var(--amber),var(--amber));
  background-size:0 1px;background-position:0 100%;background-repeat:no-repeat;
  transition:background-size .35s var(--ease),color .2s;
}
.tlink:hover{background-size:100% 1px;color:var(--amber-text)}
.tlink .arw{transition:transform .3s var(--ease)}
.tlink:hover .arw{transform:translateX(4px)}
.s-dark .tlink,.s-teal .tlink{color:var(--amber-pale)}

/* ---------------------------------------------------------------- cards */
.card{
  position:relative;background:var(--panel);border:1px solid var(--line);
  border-radius:16px;padding:clamp(24px,3vw,34px);overflow:hidden;
  transition:transform .35s var(--ease),box-shadow .35s var(--ease),border-color .35s;
}
.card::before{
  content:"";position:absolute;top:0;left:0;right:0;height:2px;
  background:linear-gradient(90deg,var(--amber),var(--amber-pale));
  transform:scaleX(0);transform-origin:0 50%;transition:transform .5s var(--ease);
}
.card:hover{transform:translateY(-4px);box-shadow:0 26px 50px -34px rgba(7,43,34,.55);border-color:var(--panel-2)}
.card:hover::before{transform:scaleX(1)}
.card .n{font-family:var(--mono);font-size:.9rem;letter-spacing:.14em;color:var(--amber-text);display:block;margin-bottom:14px}
.card h3{margin:0 0 10px}
.card p{color:var(--muted);font-size:1rem;margin:0}
.s-dark .card,.s-teal .card{background:rgba(241,239,232,.045);border-color:var(--line-dark)}
.s-dark .card p,.s-teal .card p{color:rgba(241,239,232,.72)}
.s-dark .card .n,.s-teal .card .n{color:var(--amber-bright)}

.grid{display:grid;gap:clamp(16px,2vw,24px)}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}

.chip{
  display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:.82rem;
  letter-spacing:.06em;text-transform:uppercase;color:var(--teal-900);
  background:var(--white);border:1px solid var(--line);border-radius:99px;padding:7px 14px;
}
.chip b{color:var(--amber-text);font-weight:500}
.s-dark .chip,.s-teal .chip{background:rgba(241,239,232,.07);border-color:var(--line-dark);color:var(--cream)}
.s-dark .chip b,.s-teal .chip b{color:var(--amber-bright)}

/* ---------------------------------------------------------------- faq
   One accordion skin for the whole site, extracted when the fifth copy
   appeared: contact, the e-invoicing tool and the invoice tool were already
   byte-identical, and two other pages had quietly drifted into their own
   markers. Pages wanting a different marker override this block afterwards -
   and must reset every property they do not want, because the chevron sets
   two borders, a rotation and a negative offset. See article_kit.py and
   page_tool_whatsapp.py for the two that do. */
.faq{border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{
  cursor:pointer;list-style:none;padding:22px 44px 22px 0;position:relative;
  font-family:var(--display);font-size:clamp(1.15rem,2vw,1.45rem);color:var(--teal-950);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:"";position:absolute;right:8px;top:50%;width:12px;height:12px;margin-top:-8px;
  border-right:1.5px solid var(--amber);border-bottom:1.5px solid var(--amber);
  transform:rotate(45deg);transition:transform .3s var(--ease);
}
.faq details[open] summary::after{transform:rotate(-135deg);margin-top:-3px}
.faq .ans{padding:0 0 24px;color:var(--muted);font-size:1.02rem;max-width:70ch;margin:0}
.faq .ans+.ans{padding-top:0;margin-top:-10px}
.faq summary:hover{color:var(--teal)}

/* ----------------------------------------------------------- mock cards
   A card that shows a screen rather than describing it - the scorecard on
   the process page, and the same scorecard on the services page. Second
   user is what moved it here. */
.mock{background:var(--white);border:1px solid var(--line);border-radius:14px;padding:20px 22px;box-shadow:0 30px 56px -44px rgba(7,43,34,.55)}
.mock .mh{display:flex;justify-content:space-between;align-items:baseline;border-bottom:1px solid var(--line);padding-bottom:11px;margin-bottom:14px}
.mock .mh b{font-family:var(--display);font-size:1.1rem;color:var(--teal-950);font-weight:400}
.mock .mh span{font-family:var(--mono);font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.scorerow{display:flex;justify-content:space-between;align-items:center;gap:14px;padding:9px 0;border-bottom:1px dotted var(--line);font-size:.92rem}
.scorerow:last-child{border-bottom:0}
.scorerow em{font-style:normal;color:var(--muted)}
.grade{font-family:var(--mono);font-size:.78rem;letter-spacing:.06em;padding:3px 10px;border-radius:99px;white-space:nowrap}
.grade.bad{background:rgba(166,67,31,.12);color:var(--alert)}
.grade.mid{background:rgba(186,117,23,.14);color:var(--amber)}
.grade.good{background:rgba(31,175,94,.14);color:#127A41}

/* ------------------------------------------------------------ page hero */
.phero{padding:clamp(150px,17vw,220px) 0 clamp(56px,7vw,90px);position:relative;overflow:hidden}
.phero .h1{margin:0 0 22px}
.phero .lede{font-size:clamp(1.12rem,1.9vw,1.4rem);color:var(--muted)}

/* ------------------------------------------------------------ marquee */
.facts{
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  background:var(--panel-2);overflow:hidden;padding:15px 0;
}
.facts .track{display:flex;width:max-content;animation:mq 42s linear infinite}
.facts .half{display:flex;gap:0;flex:none}
.facts span{
  font-family:var(--mono);font-size:.86rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--teal-900);white-space:nowrap;display:inline-flex;align-items:center;gap:12px;padding:0 26px;
}
.facts .star{opacity:.9}
@keyframes mq{to{transform:translateX(-50%)}}
.facts:hover .track{animation-play-state:paused}

/* ------------------------------------------------------------- header */
.top{
  position:fixed;inset:0 0 auto 0;z-index:80;display:flex;align-items:center;
  justify-content:space-between;gap:16px;padding:13px clamp(16px,3vw,30px);
  border-bottom:1px solid transparent;transition:background .3s,border-color .3s,padding .3s;
}
.top.solid{background:rgba(241,239,232,.93);backdrop-filter:blur(12px);border-bottom-color:var(--line);padding-top:9px;padding-bottom:9px}
.top .mark{display:block;width:clamp(128px,15vw,160px);height:auto}
.nav{display:flex;align-items:center;gap:clamp(12px,1.9vw,24px)}
.nav a.lnk{
  position:relative;font-family:var(--mono);font-size:.85rem;letter-spacing:.1em;
  text-transform:uppercase;text-decoration:none;color:var(--teal-900);white-space:nowrap;opacity:.86;
  transition:opacity .2s,color .2s;padding:4px 0;
}
.nav a.lnk::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--amber);
  transform:scaleX(0);transform-origin:0 50%;transition:transform .35s var(--ease);
}
.nav a.lnk:hover{opacity:1;color:var(--teal)}
.nav a.lnk:hover::after,.nav a.lnk[aria-current=page]::after{transform:scaleX(1)}
.nav a.lnk[aria-current=page]{opacity:1;color:var(--teal-950)}
/* The one and only WhatsApp entry point on the page. There used to be two -
   this pill in white up here plus a green float bottom-right - which meant one
   action wearing two different looks, and on a phone the float sat on top of
   the content. The pill is now the green one, the float is gone, and it stays
   on screen at every width, including where the nav links collapse into the
   burger. */
.top-wa{
  display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:.85rem;
  letter-spacing:.1em;text-transform:uppercase;text-decoration:none;color:#fff;white-space:nowrap;
  border:1px solid transparent;background:var(--wa);
  padding:10px 16px;border-radius:99px;
  box-shadow:0 12px 26px -16px rgba(31,175,94,.9);
  transition:background .2s,transform .2s,box-shadow .2s;
}
.top-wa:hover{background:#199B51;transform:translateY(-1px);box-shadow:0 16px 30px -16px rgba(31,175,94,1)}
.top-wa .wa-icon{width:18px;height:18px}

/* Mobile menu. The v3 header simply hid its links below 1100px, which on a
   phone left the site with no way to reach any other page — the exact
   opposite of what this set is for. */
.burger{
  display:none;width:44px;height:44px;border-radius:50%;border:1px solid rgba(35,43,38,.22);
  background:rgba(250,248,242,.82);cursor:pointer;padding:0;align-items:center;justify-content:center;
}
.burger i{display:block;width:18px;height:1.5px;background:var(--teal-900);position:relative;transition:background .2s}
.burger i::before,.burger i::after{content:"";position:absolute;left:0;width:18px;height:1.5px;background:var(--teal-900);transition:transform .3s var(--ease)}
.burger i::before{top:-6px}.burger i::after{top:6px}
.menu-open .burger i{background:transparent}
.menu-open .burger i::before{transform:translateY(6px) rotate(45deg)}
.menu-open .burger i::after{transform:translateY(-6px) rotate(-45deg)}
.mmenu{
  position:fixed;inset:0;z-index:75;background:var(--teal-950);color:var(--cream);
  display:flex;flex-direction:column;justify-content:center;gap:6px;padding:96px clamp(24px,7vw,64px) 40px;
  opacity:0;visibility:hidden;transform:translateY(-12px);
  transition:opacity .35s var(--ease),transform .35s var(--ease),visibility .35s;
}
.menu-open .mmenu{opacity:1;visibility:visible;transform:none}
.mmenu a{
  font-family:var(--display);font-size:clamp(2rem,8vw,3rem);color:var(--cream);text-decoration:none;
  padding:10px 0;border-bottom:1px solid var(--line-dark);display:flex;align-items:baseline;gap:16px;
}
.mmenu a:hover{color:var(--amber-bright)}
.mmenu a em{font-family:var(--mono);font-size:.8rem;font-style:normal;letter-spacing:.14em;color:var(--amber-bright);opacity:.8}
.mmenu .mfoot{margin-top:28px;font-family:var(--mono);font-size:.85rem;letter-spacing:.08em;color:rgba(241,239,232,.6)}

/* --------------------------------------------------------------- pager */
.pager{border-top:1px solid var(--line);background:var(--panel)}
.pager a{
  display:flex;align-items:center;justify-content:space-between;gap:24px;text-decoration:none;
  padding:clamp(34px,5vw,62px) 0;color:var(--teal-950);
}
.pager .pl{font-family:var(--mono);font-size:.85rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);display:block;margin-bottom:10px}
.pager .pt{font-family:var(--display);font-size:clamp(1.7rem,4.4vw,3rem);line-height:1.08;display:block;transition:color .25s}
.pager a:hover .pt{color:var(--teal)}
.pager .parw{font-size:clamp(1.8rem,4vw,2.6rem);color:var(--amber);transition:transform .35s var(--ease);flex:none}
.pager a:hover .parw{transform:translateX(10px)}

/* -------------------------------------------------------------- footer */
.foot{
  position:relative;background:var(--teal-950);color:rgba(241,239,232,.74);
  padding:clamp(58px,7vw,92px) 0 40px;font-size:1rem;
  /* Two soft lights instead of a flat slab: a teal wash rising from the top
     left, an amber one from the right, both well under the text contrast. */
  background-image:
    radial-gradient(980px 400px at 8% -14%, rgba(15,110,86,.50), transparent 62%),
    radial-gradient(720px 360px at 96% 6%, rgba(186,117,23,.13), transparent 66%);
}
/* hairline that fades in from both sides - reads as a seam, not a border */
.foot::before{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(186,117,23,.7) 26%,rgba(232,201,143,.35) 64%,transparent);
}
.foot .fmark{width:170px;margin-bottom:clamp(24px,2.6vw,30px)}

/* -------------------------------------------------------- footer signature
   The slogan used to be two flat paragraphs stacked under the wordmark, at
   roughly the weight of a caption - nothing about it said "this is the line
   the whole brand hangs on". It is set as a signature block instead: an amber
   rule in the inline-start gutter to anchor it, the payoff word lifted into
   amber over a brush stroke, and a short beat holding the two languages apart
   in place of 2px of dead margin. Built on logical properties (inset-inline-*,
   not left) so the whole frame mirrors on the Arabic pages, where .slogan
   carries the Arabic and .slogan-ar carries the English echo. */
.fsig{position:relative;margin:0}
/* The rule HANGS in the gutter rather than indenting the text, so the slogan,
   the wordmark above it and the socials below it all share one left edge and
   the mark reads as an annotation instead of a nested quote. Bright at the
   first line and gone by the second: a mark in the margin, not a full-height
   border, which would close the block into a box. */
.fsig::before{
  content:"";position:absolute;inset-block:.16em .5em;inset-inline-start:-18px;
  width:2px;border-radius:2px;
  background:linear-gradient(180deg,var(--amber-bright),rgba(186,117,23,.5) 48%,transparent);
}
.foot .slogan{
  font-family:var(--display);font-size:clamp(1.42rem,2.9vw,2.05rem);
  line-height:1.22;letter-spacing:-.01em;color:var(--cream);margin:0;
  text-wrap:balance;
}
/* The payoff word: amber plus a rule under it. inline-block keeps that rule
   the width of the word rather than of the whole line box, and font-weight
   stays 400 because Marcellus ships one weight - anything heavier is a
   synthesised bold that thickens the serifs unevenly. */
.foot .slogan .ins{
  display:inline-block;position:relative;font-weight:400;
  color:var(--amber-pale);white-space:nowrap;
}
.foot .slogan .ins::after{
  /* Thicker than a text-decoration and rounded at both ends, because at 2px
     square this landed as a link underline in a column full of links that do
     not carry one. It has to read as a brush mark. */
  content:"";position:absolute;left:-.04em;right:-.04em;bottom:-.12em;
  height:4px;border-radius:3px;
  background:linear-gradient(90deg,rgba(216,146,52,.85),rgba(216,146,52,.22));
  transition:background .45s var(--ease);
}
/* Deliberately NOT hung off the .rv reveal. Every other block on the page can
   afford to wait for IntersectionObserver; the one line the brand rests on
   cannot be invisible on any page where the motion script fails to run. The
   movement is on hover instead, where nothing depends on it firing. */
.fsig:hover .slogan .ins::after{background:linear-gradient(90deg,var(--amber-bright),var(--amber-bright))}
/* the beat between the two languages */
.fsig .sig-beat{
  display:block;width:44px;height:1px;
  margin:clamp(13px,1.4vw,17px) 0 clamp(11px,1.2vw,14px);
  background:linear-gradient(90deg,rgba(232,201,143,.6),rgba(232,201,143,0));
}
.foot .slogan-ar{
  /* Marcellus carries no Arabic glyphs, so this line ALWAYS falls back - naming
     the fallback is what makes its size predictable across platforms. Held a
     clear step under the English now rather than matching it, so the pair reads
     as statement and echo instead of two headlines competing; width:fit-content
     pulls the RTL box back to the column's inline-start edge instead of letting
     it drift out to the right of the whole column. */
  font-family:'Noto Naskh Arabic','Geeza Pro','Segoe UI',Tahoma,serif;
  font-size:clamp(1.02rem,2vw,1.3rem);line-height:1.8;color:rgba(232,201,143,.78);
  width:fit-content;margin:0;
}
/* The Arabic echo takes the colour but not the stroke: an underline crosses the
   descenders and the join, which is what makes the word hard to read. */
.foot .slogan-ar .ins{color:var(--amber-pale)}
.foot-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:clamp(26px,4vw,56px);align-items:stretch}
/* The brand column is the short one. Making it a flex column and pushing the
   socials down on auto margin lands the tiles on the same baseline as the
   longest link column instead of leaving a hole under them. */
.foot-brand{display:flex;flex-direction:column}
.soc-wrap{margin-top:auto;padding-top:34px}
.foot h4{font-family:var(--mono);font-size:.82rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--amber-pale);margin:0 0 16px}
.foot ul{list-style:none;margin:0;padding:0}
.foot li{margin-bottom:11px}
.foot a{color:rgba(241,239,232,.74);text-decoration:none;transition:color .2s}
.foot a:hover{color:var(--amber-bright)}

/* Column links: underline wipes in from the left. Drawn on a pseudo-element
   rather than text-decoration so it animates and costs no layout shift. */
.foot .fcol a{position:relative;display:inline-block}
.foot .fcol a::after{
  content:"";position:absolute;left:0;right:0;bottom:-2px;height:1px;background:currentColor;
  transform:scaleX(0);transform-origin:left;transition:transform .3s var(--ease);
}
.foot .fcol a:hover::after{transform:scaleX(1)}

/* The two direct lines are the ones actually worth a click, so they get size,
   an icon and full-cream contrast while the nav links stay quiet. */
.foot .direct{margin-bottom:20px}
.foot .fcol .direct a{display:inline-flex;align-items:center;gap:10px;color:var(--cream);font-size:1.06rem}
.foot .fcol .direct a:hover{color:var(--amber-bright)}
.foot .direct svg{width:17px;height:17px;flex:none;fill:currentColor;color:var(--amber-pale);transition:transform .25s var(--ease)}
.foot .fcol .direct a:hover svg{transform:translateX(2px)}

/* --------------------------------------------------------------- socials */
.foot .soc-h{margin:0 0 14px}
.socials{display:flex;flex-wrap:wrap;gap:10px}
.socials li{margin:0}
.socials a{
  --sc:var(--teal);
  width:46px;height:46px;border-radius:13px;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line-dark);background:rgba(241,239,232,.03);color:rgba(241,239,232,.82);
  transition:transform .28s var(--ease),background .28s,border-color .28s,color .28s,box-shadow .28s;
}
.socials svg{width:20px;height:20px;fill:currentColor}
.socials a:hover{
  transform:translateY(-4px);background:var(--sc);border-color:transparent;color:#fff;
  box-shadow:0 14px 26px -12px var(--sc);
}

/* ---------------------------------------------------- google review card */
.review{
  position:relative;overflow:hidden;display:flex;align-items:center;gap:clamp(16px,2.6vw,28px);
  margin-top:clamp(36px,5vw,58px);padding:clamp(20px,2.8vw,26px) clamp(20px,3vw,30px);
  border:1px solid rgba(232,201,143,.26);border-radius:20px;text-decoration:none;
  background:linear-gradient(115deg,rgba(186,117,23,.16),rgba(186,117,23,.05) 52%,rgba(241,239,232,.02));
  transition:transform .3s var(--ease),border-color .3s,box-shadow .3s;
}
/* sheen that sweeps across on hover */
.review::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 32%,rgba(241,239,232,.11) 46%,transparent 60%);
  transform:translateX(-110%);transition:transform 1s var(--ease);
}
.review:hover{transform:translateY(-3px);border-color:rgba(232,201,143,.55);box-shadow:0 26px 48px -28px rgba(0,0,0,.9)}
.review:hover::after{transform:translateX(110%)}
.review .gmark{flex:none;width:52px;height:52px;border-radius:50%;background:var(--white);display:flex;align-items:center;justify-content:center}
.review .gmark svg{width:26px;height:26px}
.review .rbody{flex:1 1 auto;min-width:0}
.review .stars{display:flex;gap:3px;margin-bottom:8px}
.review .stars svg{width:16px;height:16px;fill:var(--amber-pale);transition:fill .3s var(--ease),transform .3s var(--ease)}
.review:hover .stars svg{fill:var(--amber-bright);transform:scale(1.18)}
.review:hover .stars svg:nth-child(2){transition-delay:.05s}
.review:hover .stars svg:nth-child(3){transition-delay:.1s}
.review:hover .stars svg:nth-child(4){transition-delay:.15s}
.review:hover .stars svg:nth-child(5){transition-delay:.2s}
.review .rk{display:block;font-family:var(--mono);font-size:.76rem;letter-spacing:.14em;text-transform:uppercase;color:var(--amber-pale)}
.review .rt{display:block;font-family:var(--display);font-size:clamp(1.15rem,2.2vw,1.55rem);line-height:1.2;color:var(--cream);margin-top:5px}
.review .rarw{flex:none;font-size:1.7rem;line-height:1;color:var(--amber-bright);transition:transform .35s var(--ease)}
.review:hover .rarw{transform:translateX(9px)}

.foot .legal a{color:rgba(241,239,232,.82);text-decoration:underline;text-underline-offset:3px}
.foot .legal a:hover{color:var(--amber-bright)}
.foot .legal{
  margin-top:clamp(34px,5vw,58px);padding-top:26px;border-top:1px solid var(--line-dark);
  font-family:var(--mono);font-size:.79rem;letter-spacing:.05em;line-height:2;color:rgba(241,239,232,.5);
}

/* ----------------------------------------------------------- motion kit */
.js .rv{opacity:0;transform:translateY(24px);transition:opacity .8s var(--ease),transform .8s var(--ease);transition-delay:var(--d,0s)}
.js .rv.vis{opacity:1;transform:none}
/* Heading wipe. Done with overflow on the heading and a transform on an inner
   span that the motion script injects - NOT with clip-path:inset(), whose
   negative offsets are dropped by the parser, which left every h2 on the page
   permanently clipped to nothing. The padding-bottom gives descenders room so
   the hidden overflow does not shave a "g" once the wipe has finished. */
.js .rvw{display:block;overflow:hidden;padding-bottom:.14em}
.js .rvw .wi{display:block;transform:translateY(106%);transition:transform 1s var(--ease);transition-delay:var(--d,0s)}
.js .rvw.vis .wi{transform:none}
.js .drawn path,.js .drawn line,.js .drawn polyline,.js .drawn circle,.js .drawn rect.dr{
  stroke-dasharray:var(--len,1000);stroke-dashoffset:var(--len,1000);
  transition:stroke-dashoffset 1.5s var(--ease);transition-delay:var(--d,0s);
}
.js .drawn.vis path,.js .drawn.vis line,.js .drawn.vis polyline,.js .drawn.vis circle,.js .drawn.vis rect.dr{stroke-dashoffset:0}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  .js .rv{opacity:1;transform:none}
  .js .rvw .wi{transform:none}
  .facts .track{animation:none}
}

/* -------------------------------------------------------- breakpoints */
@media (max-width:1080px){
  .g4{grid-template-columns:repeat(2,1fr)}
  .g3{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:900px){
  .nav a.lnk{display:none}
  /* The WhatsApp button survives the collapse as an icon-only circle: it is
     the primary contact route, and the float that used to carry it here is
     gone. It sits above the open menu (header z-index 80 > mmenu 75), so it
     is reachable whether the menu is open or shut. */
  .top-wa{width:44px;height:44px;padding:0;gap:0;justify-content:center}
  .top-wa span{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  .top-wa .wa-icon{width:20px;height:20px}
  .burger{display:inline-flex}
  .foot-grid{grid-template-columns:1fr 1fr}
  /* brand block goes full width so the two link columns still sit side by side */
  .foot-brand{grid-column:1/-1;margin-bottom:10px}
}
@media (max-width:640px){
  body{font-size:18px}
  /* .wrap leaves ~4vw of gutter here - too little to hang a rule in - and
     indenting the block instead would cost the single left edge the column
     reads on. So the mark turns horizontal and sits above the line. Flat
     amber rather than a gradient: a horizontal fade would have to be flipped
     for Arabic, and at 34px there is nothing to fade. */
  .fsig{padding-inline-start:0;padding-top:15px}
  .fsig::before{
    inset-block:0 auto;inset-inline-start:0;width:34px;height:2px;
    background:var(--amber-bright);
  }
  .foot .slogan{font-size:1.36rem}
  .g2,.g3,.g4{grid-template-columns:1fr}
  .foot-grid{grid-template-columns:1fr}
  .pager .parw{display:none}
  .review .rarw{display:none}
  .review{gap:16px;padding-right:76px}
  .review .rt{font-size:1.12rem}
  .review .gmark{width:44px;height:44px}
  .review .gmark svg{width:22px;height:22px}
}

/* ------------------------------------------------------------------ hero */
.hhero .h1{margin:0 0 clamp(30px,3.6vw,42px)}

/* Visually hidden but read aloud: the search field and the filter group both
   need a name, and neither has room for a visible one. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* ---------------------------------------------------------------- search */
.search{position:relative;max-width:620px}
.search input{
  width:100%;font-family:var(--sans);font-size:1rem;color:var(--ink);
  background:var(--white);border:1px solid var(--line);border-radius:99px;
  padding:15px 52px 15px 52px;transition:border-color .2s,box-shadow .2s;
  -webkit-appearance:none;appearance:none;
}
.search input::placeholder{color:var(--taupe)}
.search input:focus{outline:none;border-color:var(--teal);box-shadow:0 0 0 4px rgba(15,110,86,.12)}
.search input::-webkit-search-cancel-button{-webkit-appearance:none}
.search .mag{
  position:absolute;top:50%;inset-inline-start:19px;transform:translateY(-50%);
  width:19px;height:19px;color:var(--muted);pointer-events:none;
}
.search .mag svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.search .clr{
  position:absolute;top:50%;inset-inline-end:9px;transform:translateY(-50%);
  width:34px;height:34px;border:0;border-radius:50%;background:var(--panel-2);
  color:var(--teal-900);cursor:pointer;font-size:1.15rem;line-height:1;
  display:none;align-items:center;justify-content:center;
}
.search .clr:hover{background:var(--line)}
.search.has-q .clr{display:flex}

/* ---------------------------------------------------------------- filter */
.filters{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-top:clamp(20px,2.4vw,26px)}
.filters button{
  font-family:var(--mono);font-size:.79rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--teal-900);background:var(--white);border:1px solid var(--line);border-radius:99px;
  padding:9px 17px;cursor:pointer;transition:border-color .2s,background .2s,color .2s,transform .2s;
}
.filters button:hover{border-color:var(--teal);transform:translateY(-1px)}
.filters button[aria-pressed=true]{background:var(--teal-950);border-color:var(--teal-950);color:var(--cream)}
.filters button i{font-style:normal;opacity:.55;margin-inline-start:7px}
.fcount{
  font-family:var(--mono);font-size:.79rem;letter-spacing:.08em;color:var(--muted);
  margin-inline-start:auto;white-space:nowrap;
}

/* -------------------------------------------------------------- featured */
.feat{
  display:grid;grid-template-columns:1.05fr .95fr;background:var(--white);
  border:1px solid var(--line);border-radius:18px;overflow:hidden;text-decoration:none;
  transition:transform .4s var(--ease),box-shadow .4s var(--ease);
}
.feat:hover{transform:translateY(-4px);box-shadow:0 30px 60px -40px rgba(7,43,34,.6)}
/* Every hero in /blog/images/ was drawn for the old navy skin: near-black
   fields of blue and cyan. Dropped straight onto cream they read as holes in
   the page. `article_kit`'s .afig already answered this - inset the art in a
   panel-toned frame so it presents as a mounted plate rather than as the page
   itself - and the hub matting is deliberately the same frame, so a card and
   the article it opens look like one system. */
.feat .shot{background:var(--panel-2);padding:clamp(12px,1.4vw,18px)}
.feat .shot img{display:block;width:100%;height:100%;aspect-ratio:16/10;
  object-fit:cover;border-radius:12px}
.feat .txt{padding:clamp(26px,3.4vw,44px);display:flex;flex-direction:column;justify-content:center}
.feat .tagline{
  font-family:var(--mono);font-size:.74rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--amber-text);margin:0 0 14px;display:flex;align-items:center;gap:9px;
}
.feat h2{font-size:clamp(1.4rem,2.6vw,2.05rem);line-height:1.14;color:var(--teal-950);margin:0 0 14px}
.feat p{color:var(--muted);font-size:1.02rem;margin:0 0 20px}
.feat .stamp{font-family:var(--mono);font-size:.76rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}

/* ------------------------------------------------------------------ grid */
.posts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(18px,2.4vw,28px)}
.post{
  display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--line);
  border-radius:16px;overflow:hidden;text-decoration:none;
  transition:transform .35s var(--ease),box-shadow .35s var(--ease),border-color .35s;
}
.post:hover{transform:translateY(-4px);box-shadow:0 26px 50px -34px rgba(7,43,34,.5);border-color:var(--panel-2)}
/* Same matte as .feat. The zoom-on-hover that a bleeding thumbnail can afford
   is gone with it: a scaled image inside a padded frame grows over its own
   mount. The card still answers the pointer by lifting. */
.post .shot{background:var(--panel-2);padding:clamp(9px,1vw,12px)}
.post .shot img{display:block;width:100%;aspect-ratio:16/9;object-fit:cover;border-radius:11px}
.post .txt{padding:clamp(20px,2.2vw,26px);display:flex;flex-direction:column;flex:1}
.post .kicker{font-family:var(--mono);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--amber-text);margin:0 0 11px}
.post h3{font-size:clamp(1.06rem,1.5vw,1.22rem);line-height:1.26;color:var(--teal-950);margin:0 0 10px}
.post p{color:var(--muted);font-size:.95rem;line-height:1.55;margin:0 0 18px}
.post .stamp{
  margin-top:auto;padding-top:14px;border-top:1px solid var(--line);
  font-family:var(--mono);font-size:.73rem;letter-spacing:.09em;text-transform:uppercase;
  color:var(--muted);display:flex;justify-content:space-between;gap:10px;
}
/* .post is display:flex, which beats the [hidden] UA rule, so the filter's
   hidden attribute needs saying again here or nothing ever disappears. */
.post[hidden]{display:none}

/* ------------------------------------------------------------ show more */
.more-row{display:flex;justify-content:center;margin-top:clamp(34px,4vw,52px)}
.more{
  font-family:var(--mono);font-size:.82rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--teal-950);background:transparent;border:1px solid var(--teal-950);
  border-radius:99px;padding:15px 34px;cursor:pointer;
  transition:background .25s,color .25s;
}
.more:hover{background:var(--teal-950);color:var(--cream)}
.more[hidden]{display:none}

.empty{border:1px dashed var(--line);border-radius:16px;padding:clamp(30px,5vw,60px);
  text-align:center;color:var(--muted);margin-top:24px}
.empty[hidden]{display:none}
.empty b{display:block;font-family:var(--display);font-size:1.3rem;color:var(--teal-950);
  font-weight:400;margin-bottom:8px}

/* --------------------------------------------------- no-JS / no-behaviour */
/* Nothing above is load-bearing for reading the archive. Without the script
   the page is 150 cards, newest first, and the three controls that would do
   nothing are not shown at all rather than shown broken. */
html:not(.js) .search,
html:not(.js) .filters,
html:not(.js) .more-row{display:none}
html:not(.js) .post[hidden]{display:flex}
/* …except the newest article's duplicate card, which only exists so the
   search can return it. The panel above is already showing that article, and
   with no script running the panel never goes away. Must follow the rule
   above: equal specificity, so source order decides. */
html:not(.js) .post[data-feat]{display:none}

@media (max-width:1080px){
  /* minmax(0,…) on every track: a card's <img> carries a width attribute, so
     the automatic minimum of a plain 1fr track is that image's own width and
     the grid quietly grows past a phone viewport. */
  .posts{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* Stacked, the shot has no row height to inherit, so height:100% goes
     indefinite and the img's own aspect-ratio takes over sizing it. That is
     why the ratio lives on the img and there is no min-height anywhere: the
     pair together would set an automatic minimum in the INLINE axis and push
     the card past the viewport. */
  .feat{grid-template-columns:minmax(0,1fr)}
}
@media (max-width:640px){
  .posts{grid-template-columns:minmax(0,1fr)}
  .fcount{width:100%;margin:4px 0 0}
}

/* ---------------------------------------------- Arabic fallback metrics --
   The Arabic pages shifted on font swap and the byte-identical English ones
   did not: same template, same images, CLS 0.160 against 0.002. The cause is
   `display=swap` plus a metric mismatch. Markazi Text has an x-height of
   36.4% of its em; Geeza Pro on Apple is 49.1% and Tahoma on Windows 54.5% -
   so every Arabic heading painted around a third too large in the fallback
   and then snapped down when the webfont arrived, dragging the hero figure
   and everything under it with it.

   One adjusted face per platform font, listed in stack order: a face whose
   only src is a local() the machine does not have simply fails to load and
   the next one is used. Every number below is read out of the actual font
   files - head.unitsPerEm, hhea ascender/descender, OS/2 sxHeight - not
   estimated: size-adjust is xHeight(web)/xHeight(fallback), and the
   ascent/descent overrides are the webfont's own metrics divided by it. */
@font-face{
  font-family:'Markazi Fallback';src:local('Geeza Pro');
  size-adjust:74.2%;ascent-override:113.1%;descent-override:48.7%;line-gap-override:0%;
}
@font-face{
  font-family:'Markazi Fallback 2';src:local('Tahoma'),local('Segoe UI');
  size-adjust:66.8%;ascent-override:125.6%;descent-override:54.1%;line-gap-override:0%;
}
@font-face{
  font-family:'Plex Arabic Fallback';src:local('Geeza Pro');
  size-adjust:105.1%;ascent-override:103.2%;descent-override:39.5%;line-gap-override:0%;
}
@font-face{
  font-family:'Plex Arabic Fallback 2';src:local('Tahoma'),local('Segoe UI');
  size-adjust:94.6%;ascent-override:114.7%;descent-override:43.9%;line-gap-override:0%;
}

/* --------------------------------------------------------------- Arabic */
[dir=rtl]{
  --display:'Markazi Text','Markazi Fallback','Markazi Fallback 2','Amiri',Georgia,serif;
  --sans:'IBM Plex Sans Arabic','Plex Arabic Fallback','Plex Arabic Fallback 2','IBM Plex Sans',-apple-system,'Segoe UI',sans-serif;
  --mono:'IBM Plex Mono','IBM Plex Sans Arabic','Plex Arabic Fallback',ui-monospace,SFMono-Regular,Menlo,monospace;
}
/* Naskh needs more leading than Latin at the same size: the descenders and the
   dots below the baseline collide at 1.7. */
[dir=rtl] body{line-height:1.85}
[dir=rtl] h1,[dir=rtl] h2,[dir=rtl] h3,[dir=rtl] h4{letter-spacing:0}
/* Markazi Text runs visibly small against IBM Plex Sans Arabic, so display
   type is bumped a step and given the leading Arabic ascenders need. */
[dir=rtl] .h1{font-size:clamp(2.3rem,5.4vw,4.2rem);line-height:1.24}
[dir=rtl] .h2{font-size:clamp(1.9rem,4.2vw,3.1rem);line-height:1.32}
[dir=rtl] .h3{line-height:1.4}
[dir=rtl] .lede{line-height:1.85}
[dir=rtl] .phero .h1{margin-bottom:26px}

/* Tracking and small-caps are Latin devices. On Arabic, letter-spacing breaks
   the join between letters and text-transform does nothing at all, so both
   come off everywhere the kit sets them. */
[dir=rtl] .eyebrow,[dir=rtl] .chip,[dir=rtl] .btn,[dir=rtl] .tlink,
[dir=rtl] .lnk,[dir=rtl] .top-wa,[dir=rtl] .facts span,[dir=rtl] .card .n,
[dir=rtl] .pager .pl,[dir=rtl] .foot h4,[dir=rtl] .soc-h,[dir=rtl] .rk,
[dir=rtl] .rt,[dir=rtl] .legal,[dir=rtl] .mfoot,[dir=rtl] .mmenu a,
[dir=rtl] .mmenu a em,[dir=rtl] .skip{
  letter-spacing:0;text-transform:none;
}

/* Figures, prices, phone numbers and times stay left-to-right inside Arabic
   running text. Without this, "OMR 1,023" comes out reversed and "9:47" reads
   as "47:9".

   isolate, NOT embed. Under `embed` the Latin run still takes part in the
   surrounding reorder, so a figure at the start of a line gets thrown to the
   far edge of its box and the Arabic closes up behind it - which is exactly
   what happened to the four stats cells on the services page. `isolate`
   treats the run as one neutral object sitting at its logical position. */
[dir=rtl] .num,[dir=rtl] [dir=ltr]{direction:ltr;unicode-bidi:isolate}
/* A figure that is the whole of a display value gets its own line box, so the
   isolation has nothing to fight with; the cell just reads right-to-left. */
[dir=rtl] .stats div b,[dir=rtl] .bignum,[dir=rtl] .hcount{unicode-bidi:isolate}

/* An Arabic page wraps every figure in `.num` so the bidi algorithm cannot
   reorder it. That wrapper is a <span>, and it lands INSIDE components whose
   caption rule is an unscoped descendant selector - `.pricetag span`,
   `.kpi span`, `.mock .mh span`, `.figs span`. Those are (0,1,1) and beat a
   bare `.num`, so a 2.3rem price was rendering its digits at 0.85rem in
   uppercase grey while the currency beside it stayed full size.
   `[dir=rtl] .num` is (0,2,0) and out-specifies all of them. Everything here
   is inherit-or-off: the figure takes the size and colour of whatever it sits
   in, and only keeps the tabular mono face the brand book gives to numerals.
   The English pages are untouched - they write their figures as plain text. */
[dir=rtl] .num{
  display:inline;margin:0;
  font-size:inherit;line-height:inherit;color:inherit;
  letter-spacing:0;text-transform:none;font-weight:inherit;
}

/* ------------------------------------------- article-specific RTL layer */
/* The tokens, the type scale and the tracking kill-list above come from
   tools/v4/rtl.py, which the core pages load too - one copy, so the article
   header and the services header cannot end up on different Arabic faces.
   What follows is only what an ARTICLE has and a core page does not. */
[dir=rtl] body{line-height:1.85}
[dir=rtl] h1,[dir=rtl] h2,[dir=rtl] h3,[dir=rtl] h4{letter-spacing:0}
[dir=rtl] .h1,[dir=rtl] .ahero .h1{font-size:clamp(2rem,4.3vw,3.2rem);line-height:1.3}
[dir=rtl] .h2,[dir=rtl] .prose h2{line-height:1.35}
[dir=rtl] .prose h2{font-size:clamp(1.7rem,3.1vw,2.4rem)}
[dir=rtl] .prose h3{font-size:clamp(1.3rem,2.1vw,1.55rem);line-height:1.4}
[dir=rtl] .prose p{line-height:1.9}
[dir=rtl] .prose blockquote p{line-height:1.6}
[dir=rtl] .faq summary{line-height:1.5}
[dir=rtl] .callout h3,[dir=rtl] .callout h4{line-height:1.45}

/* Tracking and small-caps are Latin devices; on Arabic they break the join
   between letters and leave a label unreadable. */
[dir=rtl] .eyebrow,[dir=rtl] .crumbs,[dir=rtl] .toc h2,[dir=rtl] .keybox h4,
[dir=rtl] .callout b,[dir=rtl] .refs h2,[dir=rtl] .tblcap,[dir=rtl] .tbl th,
[dir=rtl] .byline .who span,[dir=rtl] .byline .stamp,[dir=rtl] .steps b,
[dir=rtl] .related .card .rd,[dir=rtl] .related .card .n,[dir=rtl] .pfig figcaption,
[dir=rtl] .afig figcaption,[dir=rtl] .brandbox .rolelbl,[dir=rtl] .topics span:first-child,
[dir=rtl] .lnk,[dir=rtl] .top-wa,[dir=rtl] .btn,[dir=rtl] .chip,
[dir=rtl] .pager .pl,[dir=rtl] .foot h4,[dir=rtl] .soc-h,[dir=rtl] .rk,[dir=rtl] .rt,
[dir=rtl] .legal,[dir=rtl] .mfoot,[dir=rtl] .mmenu a{
  letter-spacing:0;text-transform:none;
}

/* ------------------------------------------------------------ mirroring */
[dir=rtl] .prog{left:auto;right:0}
[dir=rtl] .skip{left:auto;right:-9999px;border-radius:0 0 0 8px}
[dir=rtl] .skip:focus{left:auto;right:0}

[dir=rtl] .prose p.open::first-letter{float:right;padding:.06em 0 0 .12em}
[dir=rtl] .prose li{padding-left:0;padding-right:30px}
[dir=rtl] .prose ul>li::before{left:auto;right:6px}
[dir=rtl] .prose ol>li::before{left:auto;right:0}
[dir=rtl] .prose blockquote{padding:0 clamp(20px,3vw,30px) 0 0;border-left:0;border-right:2px solid var(--amber)}

[dir=rtl] .keybox{border-left:0;border-right:3px solid var(--amber);border-radius:14px 0 0 14px}
[dir=rtl] .keybox li{padding-left:0;padding-right:26px}
[dir=rtl] .keybox li::before{left:auto;right:0}

[dir=rtl] .toc a{padding:8px 15px 8px 0;border-left:0;border-right:1px solid var(--line)}
[dir=rtl] .toc a.on{border-left-color:transparent;border-right-color:var(--amber)}

[dir=rtl] .tbl th{text-align:right}
[dir=rtl] .tblcap,[dir=rtl] .pfig figcaption,[dir=rtl] .afig figcaption{
  padding-left:0;padding-right:16px;border-left:0;border-right:2px solid var(--amber);
}
[dir=rtl] .afig figcaption{padding-right:14px}

[dir=rtl] .refs li{padding-left:0;padding-right:32px}
[dir=rtl] .refs li::before{left:auto;right:0}

[dir=rtl] .faq summary{padding:20px 0 20px 44px}
[dir=rtl] .faq summary::after{right:auto;left:8px}
[dir=rtl] .faq summary::before{right:auto;left:14px}
[dir=rtl] .faq details p{padding-right:0;padding-left:44px}

[dir=rtl] .icta::after{right:auto;left:-40px}
[dir=rtl] .topics span:first-child{margin-right:0;margin-left:4px}

/* Figures, prices, phone numbers and code stay left-to-right inside Arabic
   running text; without this "OMR 1,023" comes out reversed. */
[dir=rtl] .num,[dir=rtl] .tbl td.n,[dir=rtl] .formula span,[dir=rtl] .prose code{
  direction:ltr;unicode-bidi:embed;text-align:right;
}

/* ---------------------------------------------- footer signature, mirrored */
/* On an Arabic page the two lines swap roles: .slogan carries the Arabic and
   .slogan-ar carries the English echo. The amber stroke follows the Latin word
   rather than staying on .slogan, because under Arabic it cuts through the
   descenders and the join. The frame itself needs no override - .fsig is built
   on logical properties and mirrors on its own. */
[dir=rtl] .foot .slogan .ins::after{content:none}
/* .slogan-ar carries Latin here, so it drops the Arabic fallback stack and
   takes Marcellus - which these pages already load for the wordmark - instead
   of rendering the English echo in a Naskh face. */
[dir=rtl] .foot .slogan-ar{font-family:'Marcellus',Georgia,'Times New Roman',serif}
[dir=rtl] .foot .slogan-ar .ins{display:inline-block;position:relative;white-space:nowrap}
[dir=rtl] .foot .slogan-ar .ins::after{
  content:"";position:absolute;left:-.04em;right:-.04em;bottom:-.12em;
  height:4px;border-radius:3px;
  background:linear-gradient(90deg,rgba(216,146,52,.85),rgba(216,146,52,.22));
  transition:background .45s var(--ease);
}
[dir=rtl] .fsig:hover .slogan-ar .ins::after{background:linear-gradient(90deg,var(--amber-bright),var(--amber-bright))}
/* the beat fades away from the inline-start edge, which is the right one here */
[dir=rtl] .fsig .sig-beat{background:linear-gradient(270deg,rgba(232,201,143,.6),rgba(232,201,143,0))}

/* --------------------------------------------------- Arabic hub overrides */
/* The hero heading is display type; Markazi Text sits smaller on the body than
   Marcellus does, so the Latin clamp leaves it undersized. */
[dir=rtl] .hhero .h1{font-size:clamp(2.2rem,4.6vw,3.4rem);line-height:1.28}
[dir=rtl] .feat h2{font-size:clamp(1.5rem,2.8vw,2.2rem);line-height:1.34}
[dir=rtl] .post h3{font-size:clamp(1.14rem,1.6vw,1.32rem);line-height:1.45}
/* Tracked, upper-cased small text is a Latin device: on Arabic it separates
   letters that must join and the label stops being a word. */
[dir=rtl] .filters button,[dir=rtl] .fcount,[dir=rtl] .more,
[dir=rtl] .feat .tagline,[dir=rtl] .feat .stamp,
[dir=rtl] .post .kicker,[dir=rtl] .post .stamp{letter-spacing:0;text-transform:none}
[dir=rtl] .search input{font-size:1.02rem}
/* Deliberately NO direction:ltr on the date. blog_chrome forces LTR on .num
   because a bare figure like "OMR 1,023" comes out reversed in Arabic, and
   the same rule applied here looks like it should help - the day and year are
   Western digits. It does the opposite. "18 أغسطس 2026" is not a number, it
   is an RTL phrase with digits in it, and forcing the run LTR strands the
   year between the day and the month: 18 2026 أغسطس. Left alone, the bidi
   algorithm puts the day on the right and the year on the left, which is the
   order an Arabic reader expects. */
