/* ═══════════════════════════════════════════════════════════════════════════
   TOKENS - direction "انهار" : DARK CINEMATIC + HI-VIS LIME
   One hue owns the page. Lime is the only saturated colour, so it means
   "act here" everywhere it appears. The previous build ran green as brand and
   blue as accent, and neither owned anything.
   Lime is the logo's green pushed to safety-vest intensity, which is also the
   PPE colour of this trade. The logo's wave blue is dropped entirely.
   No raw hex below this block.
   ═══════════════════════════════════════════════════════════════════════════ */
:root{
  /* ground: four steps of ink, lightest = most raised */
  --color-deep:#070C0A;
  --color-ground:#0D1512;
  --color-raised:#141E19;
  --color-panel:#1A2620;
  --color-panel-2:#22302A;

  --color-brand:#B7E82E;
  --color-brand-dim:#94BE24;
  --color-on-brand:#0B120E;
  --color-whatsapp:#25D366;

  --color-text:#F2F5F0;
  --color-text-muted:#93A79A;
  --color-text-dim:#6E8175;
  --color-focus:#B7E82E;
  --border-hairline:1px solid hsl(150 14% 88% / .11);

  /* illustration palette, so the flat art is themed rather than hard-coded */
  --illus-deep:#24382C;
  --illus-mid:#31493A;
  --illus-light:#E7EFE3;
  --illus-lime:#B7E82E;
  --illus-ink:#0B120E;

  /* elevation. On an ink ground a shadow alone is invisible, so every step pairs
     a black shadow with a lighter surface and a hairline ring. */
  --shadow-xs:0 1px 2px hsl(150 30% 2% / .40);
  --shadow-sm:0 2px 4px hsl(150 30% 2% / .45), 0 4px 10px hsl(150 30% 2% / .30);
  --shadow-md:0 4px 8px hsl(150 30% 2% / .50), 0 12px 28px hsl(150 30% 2% / .38);
  --shadow-lg:0 8px 16px hsl(150 30% 2% / .55), 0 24px 56px hsl(150 30% 2% / .46);
  --shadow-xl:0 14px 28px hsl(150 30% 2% / .60), 0 40px 80px hsl(150 30% 2% / .55);
  --shadow-action:0 4px 10px hsl(76 70% 20% / .45), 0 14px 32px hsl(76 75% 30% / .35);
  --shadow-ring:inset 0 0 0 1px hsl(150 14% 88% / .09);
  --shadow-ring-strong:inset 0 0 0 1px hsl(150 14% 88% / .18);
  --shadow-ring-lime:inset 0 0 0 1px hsl(76 78% 55% / .38);

  /* scrim: every stop >= .55 alpha so text clears AA over ANY photograph */
  --scrim-strong:hsl(154 30% 3% / .90);
  --scrim-mid:hsl(154 30% 3% / .74);
  --scrim-floor:hsl(154 30% 3% / .62);
  --hero-scrim:linear-gradient(to bottom,var(--scrim-strong) 0%,var(--scrim-floor) 34%,var(--scrim-mid) 66%,var(--scrim-strong) 100%);
  /* A second, sideways veil weighted to the side the copy sits on. The vertical scrim
     alone left the headline crossing the operator's white hood, which is legible but
     reads as a collision. PHYSICAL by necessity: a gradient has no logical direction,
     so it is declared as a mirrored pair the way base.css handles --hero-texture. */
  --hero-side:linear-gradient(to left,var(--scrim-strong) 0%,hsl(154 30% 3% / .34) 54%,transparent 100%);
  --hero-side-ltr:linear-gradient(to right,var(--scrim-strong) 0%,hsl(154 30% 3% / .34) 54%,transparent 100%);
  --media-veil:linear-gradient(to top,hsl(154 30% 3% / .78) 0%,hsl(154 30% 3% / .14) 62%);

  /* type */
  --font-display:"Cairo",system-ui,sans-serif;
  --font-body:"Tajawal",system-ui,sans-serif;
  --step--1:clamp(.78rem,.75rem + .12vw,.86rem);
  --step-0:clamp(1rem,.96rem + .2vw,1.09rem);
  --step-1:clamp(1.15rem,1.08rem + .32vw,1.32rem);
  --step-2:clamp(1.32rem,1.2rem + .55vw,1.62rem);
  --step-3:clamp(1.55rem,1.32rem + .95vw,2.1rem);
  --step-4:clamp(1.95rem,1.5rem + 1.9vw,3.05rem);
  --step-5:clamp(2.3rem,1.6rem + 2.9vw,3.9rem);
  --step-6:clamp(2.55rem,1.6rem + 4.75vw,5rem);
  --leading-body:1.85; --leading-heading:1.4; --leading-display:1.28;
  --weight-display:900;

  /* space + shape */
  --space-2xs:.25rem; --space-xs:.5rem; --space-sm:.75rem; --space-md:1rem;
  --space-lg:1.5rem; --space-xl:2.25rem; --space-2xl:3.5rem;
  --section-space:clamp(3.5rem,2.2rem + 5vw,6.5rem);
  --section-space-tight:clamp(2rem,1.5rem + 1.8vw,2.75rem);
  --section-space-loose:clamp(4rem,2.5rem + 6vw,7.5rem);
  --radius-sm:8px; --radius-md:14px; --radius-lg:22px; --radius-pill:999px;
  --container:78rem;
  --media-ratio-card:4/3; --media-ratio-wide:16/10; --media-zoom:1.05;
  --lift-sm:-2px; --lift-md:-4px;
  --transition:160ms cubic-bezier(.22,.61,.36,1);
  --transition-slow:280ms cubic-bezier(.22,.61,.36,1);
  --focus-ring-width:3px; --focus-ring-offset:3px;
}
/* Arabic script metrics. :lang() prefix-matches, so this covers ar-SA/ar-KW/ar-AE. */
:root:lang(ar){ --leading-body:1.9; --leading-heading:1.45; --leading-display:1.3;
  --tracking-display:0; --label-transform:none; }
html:lang(ar){ font-size:106.25%; }
[dir="ltr"]{ --hero-side:var(--hero-side-ltr); }

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;overflow-x:clip;background:var(--color-ground);color:var(--color-text);
  font-family:var(--font-body);font-size:var(--step-0);line-height:var(--leading-body);
  -webkit-font-smoothing:antialiased}
img{max-width:100%;height:auto;display:block}
h1,h2,h3,h4{font-family:var(--font-display);line-height:var(--leading-heading);
  margin:0;font-weight:800;letter-spacing:var(--tracking-display,-.01em);text-wrap:balance}
p{margin:0}
a{color:inherit}
ul,ol{margin:0;padding:0;list-style:none}
:focus-visible{outline:var(--focus-ring-width) solid var(--color-focus);
  outline-offset:var(--focus-ring-offset);border-radius:var(--radius-sm)}
.container{width:min(100% - 2.5rem,var(--container));margin-inline:auto}
.icon{inline-size:1.15em;block-size:1.15em;fill:none;stroke:currentColor;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;flex:none}
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.bidi{unicode-bidi:isolate;direction:ltr;display:inline-block}

.skip{position:absolute;inset-inline-start:1rem;top:-6rem;z-index:200;
  background:var(--color-brand);color:var(--color-on-brand);padding:.75rem 1.25rem;
  border-radius:var(--radius-sm);box-shadow:var(--shadow-lg);font-weight:700;
  transition:top var(--transition)}
.skip:focus{top:1rem}

/* ═══ SECTION SHELL ═══ */
.section{padding-block:var(--section-space);background:var(--color-ground);position:relative}
.section--raised{background:var(--color-raised)}
.section--lime{background:var(--color-brand);color:var(--color-on-brand)}
.section--tight{padding-block:var(--section-space-tight)}
.section--loose{padding-block:var(--section-space-loose)}
/* Heading and standfirst NEVER sit side by side. Banned sitewide by the brief, and
   taste-skill §4.7 bans the same shape as a default. The head is one stacked column. */
.section__head{margin-block-end:var(--space-2xl);text-align:start;max-width:52rem}
.section__eyebrow{display:block;font-family:var(--font-display);font-weight:700;
  font-size:var(--step--1);color:var(--color-brand);margin-block-end:var(--space-sm);
  text-transform:var(--label-transform,none)}
.section__title{font-size:var(--step-4);font-weight:900;line-height:1.18;
  letter-spacing:-.015em}
.section__lead{margin-block-start:var(--space-md);font-size:var(--step-1);
  color:var(--color-text-muted);max-width:46ch}
.section--lime .section__title,.section--lime .section__lead{color:var(--color-on-brand)}

/* ═══ BUTTONS ═══ */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  font-family:var(--font-display);font-weight:800;font-size:var(--step-0);
  padding:.95rem 1.7rem;border-radius:var(--radius-pill);border:0;cursor:pointer;
  text-decoration:none;line-height:1.2;transition:transform var(--transition),
  box-shadow var(--transition),background-color var(--transition),color var(--transition)}
.btn__meta{unicode-bidi:isolate;direction:ltr;font-weight:700;opacity:.9}
.btn--primary{background:var(--color-brand);color:var(--color-on-brand);
  box-shadow:var(--shadow-action)}
.btn--wa{background:var(--color-whatsapp);color:var(--color-on-brand);
  box-shadow:var(--shadow-md)}
.btn--ink{background:var(--color-on-brand);color:var(--color-text);
  box-shadow:var(--shadow-md)}
.btn--ghost{background:hsl(150 14% 88% / .08);color:var(--color-text);
  box-shadow:var(--shadow-ring-strong)}
/* Secondary action ON the lime band. WhatsApp green sits at nearly the same lightness
   as the lime behind it, so the brand-coloured button disappears there. It keeps its
   real colour in the hero, where the ground is ink and the colour earns its keep. */
.btn--on-lime{background:transparent;color:var(--color-on-brand);
  box-shadow:inset 0 0 0 2px hsl(150 40% 8% / .55)}
.btn--lg{padding:1.1rem 2.1rem;font-size:var(--step-1)}
@media (hover:hover){
  .btn:hover{transform:translateY(var(--lift-sm))}
  .btn--primary:hover{background:var(--color-brand-dim);box-shadow:var(--shadow-lg)}
  .btn--wa:hover{filter:brightness(1.08);box-shadow:var(--shadow-lg)}
  .btn--ink:hover{box-shadow:var(--shadow-lg)}
  .btn--ghost:hover{background:hsl(150 14% 88% / .15)}
  .btn--on-lime:hover{background:hsl(150 40% 8% / .10);box-shadow:inset 0 0 0 2px var(--color-on-brand)}
}
.btn:active{transform:translateY(1px);box-shadow:var(--shadow-xs)}

/* ═══ HEADER ═══ */
.site-header{position:sticky;top:0;z-index:100;background:hsl(154 22% 5% / .82);
  backdrop-filter:blur(16px);transition:box-shadow var(--transition)}
.site-header[data-scrolled]{box-shadow:var(--shadow-md)}
.site-header__inner{display:flex;align-items:center;gap:var(--space-lg);
  min-height:4.5rem;padding-block:.6rem}
.brand{display:flex;align-items:center;gap:.7rem;text-decoration:none;flex:0 1 auto;min-width:0}
/* The logo carries the name and the descriptor already, so there is no text beside it.
   Height-driven with width:auto, because the Arabic and English lockups are different
   aspect ratios and pinning the width would squash one of them. */
.brand__logo{block-size:2.5rem;inline-size:auto;max-inline-size:100%;display:block}
@media (max-width:24rem){.brand__logo{block-size:2.1rem}}
.footer__brand .brand__logo{block-size:3rem}
.site-nav{margin-inline-start:auto;display:none}
.site-nav ul{display:flex;gap:var(--space-lg)}
.site-nav a{position:relative;text-decoration:none;font-weight:500;padding-block:.4rem;
  color:var(--color-text)}
.site-nav a::after{content:"";position:absolute;inset-inline:0;bottom:0;block-size:2px;
  background:var(--color-brand);transform:scaleX(0);transform-origin:inline-end;
  transition:transform var(--transition)}
@media (hover:hover){.site-nav a:hover::after{transform:scaleX(1);transform-origin:inline-start}}
.header__cta{display:none}
@media (min-width:64rem){.site-nav{display:block}.header__cta{display:inline-flex}}

/* ═══ MOBILE NAV ═══
   Below 64rem the desktop nav is display:none and there was nothing in its place, so a
   phone could only reach other pages through the footer. */
.nav-toggle{margin-inline-start:auto;inline-size:2.75rem;block-size:2.75rem;flex:none;
  display:grid;place-items:center;border:0;border-radius:var(--radius-md);
  background:hsl(150 14% 88% / .08);color:var(--color-text);cursor:pointer;
  transition:background var(--transition)}
.nav-toggle__bars{inline-size:1.15rem;block-size:.85rem;position:relative;display:block}
.nav-toggle__bars span{position:absolute;inset-inline:0;block-size:2px;border-radius:2px;
  background:currentColor;transition:transform var(--transition),opacity var(--transition)}
.nav-toggle__bars span:nth-child(1){top:0}
.nav-toggle__bars span:nth-child(2){top:calc(50% - 1px)}
.nav-toggle__bars span:nth-child(3){bottom:0}
/* burger morphs into the close cross, rather than swapping to a different glyph */
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1){transform:translateY(calc(.425rem - 1px)) rotate(45deg)}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2){opacity:0}
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3){transform:translateY(calc(-.425rem + 1px)) rotate(-45deg)}
@media (hover:hover){.nav-toggle:hover{background:hsl(150 14% 88% / .16)}}
.nav-toggle:active{transform:translateY(1px)}
@media (min-width:64rem){.nav-toggle{display:none}}

/* The sheet sits UNDER the header on purpose. Covering the header would hide the only
   control that closes it: the burger that just became a cross. The reader must be able
   to see the way out at all times. */
.nav-panel{position:fixed;inset:0;z-index:90;background:var(--color-deep);
  display:flex;flex-direction:column;justify-content:flex-end;
  padding:calc(5.5rem + var(--space-lg)) var(--space-lg) calc(var(--space-2xl) + env(safe-area-inset-bottom));
  overflow-y:auto;opacity:0;transition:opacity var(--transition)}
.nav-panel:focus{outline:none}
/* the panel carries its own language link, so the header's would be a second one */
body[data-nav-open] .lang-switch{opacity:0;pointer-events:none}
.nav-panel[data-open]{opacity:1}
.nav-panel[hidden]{display:none}
/* Content sits in the lower two thirds: that is the half of a phone a thumb reaches
   without the hand shifting grip. */
.nav-panel__inner{inline-size:100%}
.nav-panel__links{display:flex;flex-direction:column;gap:.15rem;
  margin-block-end:var(--space-xl)}
.nav-panel__links a{display:block;text-decoration:none;color:var(--color-text);
  font-family:var(--font-display);font-weight:800;font-size:var(--step-3);
  line-height:1.35;padding-block:.55rem;border-block-end:1px solid hsl(150 14% 88% / .09)}
.nav-panel__links li:last-child a{border-block-end:0}
@media (hover:hover){.nav-panel__links a:hover{color:var(--color-brand)}}
.nav-panel__actions{display:flex;flex-direction:column;gap:var(--space-sm)}
.nav-panel__actions .btn{inline-size:100%;justify-content:center}
.nav-panel__lang{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  padding-block:.75rem;text-decoration:none;color:var(--color-text-dim);
  font-weight:600;font-size:var(--step--1)}
.nav-panel__lang .icon{inline-size:1.05rem;block-size:1.05rem}

/* Each row rises as the sheet fades in. The delay is indexed off --i on the element, so
   adding a link needs no new CSS. Transform and opacity only: both are compositor
   properties, so this stays smooth on a cheap phone. */
.nav-panel__links li,.nav-panel__actions{opacity:0;transform:translateY(.85rem);
  transition:opacity .32s ease,transform .32s cubic-bezier(.22,1,.36,1)}
.nav-panel[data-open] .nav-panel__links li,
.nav-panel[data-open] .nav-panel__actions{opacity:1;transform:none;
  transition-delay:calc(60ms + var(--i) * 38ms)}

body[data-nav-open]{position:fixed;inline-size:100%;overflow:hidden}

/* ═══ HERO ═══ */
.hero{position:relative;isolation:isolate;padding-block:clamp(4.5rem,2rem + 10vw,9rem);
  background:var(--color-deep)}
.hero__media{position:absolute;inset:0;z-index:-2;overflow:hidden}
.hero__media img{inline-size:100%;block-size:100%;object-fit:cover;object-position:50% 48%}
.hero::after{content:"";position:absolute;inset:0;z-index:-1;background:var(--hero-scrim)}
.hero::before{content:"";position:absolute;inset:0;z-index:-1;background:var(--hero-side)}
.hero__inner{max-width:58rem}
.hero__badge{display:inline-flex;align-items:center;gap:.5rem;
  background:hsl(150 14% 88% / .08);box-shadow:var(--shadow-ring-lime);
  padding:.45rem 1rem;border-radius:var(--radius-pill);font-size:var(--step--1);
  font-weight:700;font-family:var(--font-display);margin-block-end:var(--space-lg);
  text-decoration:none;color:var(--color-text)}
.hero__badge .icon{inline-size:1.05em;block-size:1.05em;color:var(--color-brand)}
/* Five solid stars carry the score, so the words next to them only have to say where it
   came from. The star row never mirrors: a rating reads left to right in both locales. */
.hero__badge-stars{display:inline-flex;gap:.12rem;direction:ltr;color:var(--color-brand)}
.hero__badge-stars .icon{inline-size:1em;block-size:1em}
.fact__value--stars{display:flex;gap:.2rem;direction:ltr;color:var(--color-brand);
  justify-content:inherit}
.fact__value--stars .icon{inline-size:.5em;block-size:.5em}
.hero__title{font-size:var(--step-6);font-weight:var(--weight-display);
  line-height:var(--leading-display);letter-spacing:-.02em}
.hero__title em{font-style:normal;color:var(--color-brand)}
.hero__lead{margin-block-start:var(--space-lg);font-size:var(--step-2);
  line-height:1.75;color:hsl(150 10% 92% / .82);max-width:44ch}
.hero__actions{display:flex;flex-wrap:wrap;gap:var(--space-md);
  margin-block-start:var(--space-xl)}
.hero__facts{display:flex;flex-wrap:wrap;gap:var(--space-lg) var(--space-xl);
  margin-block-start:var(--space-xl);padding-block-start:var(--space-lg);
  border-block-start:var(--border-hairline)}
.hero__fact{display:flex;align-items:center;gap:.55rem;font-size:var(--step--1);
  color:hsl(150 10% 92% / .78);font-weight:500}
.hero__fact .icon{color:var(--color-brand);inline-size:1.2em;block-size:1.2em}
.hero__fact b{font-family:var(--font-display);font-weight:800;color:var(--color-text);
  font-size:var(--step-0)}

/* ═══ FLAT ILLUSTRATIONS ═══
   Custom branded art, NOT the icon sprite. Requested in place of the icon-tile strip.
   This is a recorded deviation from 00-design-law.md §9.E.2 (no hand-authored SVG):
   every shape is flat, uses only themed fills via var(), and lives in one marked block
   so the build can tell art from a hand-drawn icon pretending to be one. */
.illus{display:block;inline-size:100%;block-size:auto}
.pillars{display:grid;gap:var(--space-lg);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,15rem),1fr))}
.pillar{background:var(--color-panel);border-radius:var(--radius-lg);
  padding:var(--space-xl) var(--space-lg) var(--space-lg);
  box-shadow:var(--shadow-sm),var(--shadow-ring);
  display:flex;flex-direction:column;gap:var(--space-sm);
  transition:transform var(--transition),box-shadow var(--transition)}
@media (hover:hover){.pillar:hover{transform:translateY(var(--lift-sm));
  box-shadow:var(--shadow-md),var(--shadow-ring-strong)}}
.pillar__art{inline-size:5.5rem;block-size:5.5rem;margin-block-end:var(--space-sm)}
.pillar__title{font-family:var(--font-display);font-weight:800;font-size:var(--step-1);
  line-height:1.35}
.pillar__text{font-size:var(--step--1);color:var(--color-text-muted);line-height:1.8}

/* ═══ SERVICE CARDS ═══ */
.card-grid{display:grid;gap:var(--space-lg);
  grid-template-columns:repeat(auto-fill,minmax(min(100%,17rem),1fr))}
@media (min-width:64rem){
  .card-grid{grid-template-columns:repeat(4,1fr)}
  /* One card leads at double width. Composition variety without a uniform grid, and
     without the editorial 2x2 tile, whose cell-count rule 7 cards cannot satisfy.
     NOTE: this is a strong pattern and it should appear ONCE on a page. A pillar page has
     several grids, and with the lead-tile on every one of them the page read as the same
     asymmetric block four times over. Use .card-grid--even for the others. */
  .card-grid > li:first-child{grid-column:span 2}
  .card-grid > li:first-child .card__media{aspect-ratio:16/9}
  .card-grid--even > li:first-child{grid-column:span 1}
  .card-grid--even > li:first-child .card__media{aspect-ratio:var(--media-ratio-card)}
  .card-grid--even{grid-template-columns:repeat(3,1fr)}
}
.card{position:relative;display:flex;flex-direction:column;overflow:hidden;block-size:100%;
  border-radius:var(--radius-lg);background:var(--color-panel);
  box-shadow:var(--shadow-sm),var(--shadow-ring);text-decoration:none;
  transition:transform var(--transition),box-shadow var(--transition)}
@media (hover:hover){
  .card:hover{transform:translateY(var(--lift-md));box-shadow:var(--shadow-lg),var(--shadow-ring-lime)}
  .card:hover .card__media img{transform:scale(var(--media-zoom))}
}
.card:active{transform:translateY(1px);box-shadow:var(--shadow-xs),var(--shadow-ring)}
.card__media{aspect-ratio:var(--media-ratio-card);overflow:hidden;position:relative;
  background:var(--color-panel-2)}
.card__media::after{content:"";position:absolute;inset:0;background:var(--media-veil)}
/* Stock arrives at every exposure. Left alone, the bright warm frames (the cockroach
   macro, the fogging shot) punch holes in an ink page. One filter on every card image
   pulls the whole set into the same tonal register, which is what makes eight
   photographs from eight photographers read as one shoot. */
.card__media img{inline-size:100%;block-size:100%;object-fit:cover;
  filter:brightness(.84) saturate(.88) contrast(1.04);
  transition:transform var(--transition-slow),filter var(--transition)}
@media (hover:hover){.card:hover .card__media img{filter:brightness(.95) saturate(.95) contrast(1.04)}}
.card__body{padding:var(--space-lg);display:flex;flex-direction:column;gap:.45rem;flex:1}
.card__title{font-family:var(--font-display);font-weight:800;font-size:var(--step-1);
  line-height:1.35}
.card__text{font-size:var(--step--1);color:var(--color-text-muted);line-height:1.8}
.card__go{margin-block-start:auto;padding-block-start:var(--space-sm);
  font-family:var(--font-display);font-weight:800;font-size:var(--step--1);
  color:var(--color-brand);display:flex;align-items:center;gap:.4rem}
.card__go .icon{inline-size:1em;block-size:1em;transition:transform var(--transition)}
@media (hover:hover){.card:hover .card__go .icon{transform:translateX(-3px)}}

/* ═══ WHY US : image beside a short list, not a wall of text ═══ */
.why{display:grid;gap:var(--space-2xl);align-items:center}
@media (min-width:62rem){.why{grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr)}}
.why__frame{position:relative;border-radius:var(--radius-lg);overflow:hidden;
  aspect-ratio:4/5;box-shadow:var(--shadow-lg),var(--shadow-ring)}
.why__frame img{inline-size:100%;block-size:100%;object-fit:cover;
  filter:brightness(.82) saturate(.86) contrast(1.05)}
.why__frame::after{content:"";position:absolute;inset:0;background:var(--media-veil)}
.why__list{display:flex;flex-direction:column}
.why__item{display:grid;grid-template-columns:auto 1fr;gap:var(--space-md) var(--space-lg);
  padding-block:var(--space-lg);border-block-end:var(--border-hairline)}
.why__item:last-child{border-block-end:0;padding-block-end:0}
.why__item:first-child{padding-block-start:0}
.why__num{font-family:var(--font-display);font-weight:900;font-size:var(--step-2);
  color:var(--color-brand);line-height:1;unicode-bidi:isolate}
.why__title{font-family:var(--font-display);font-weight:800;font-size:var(--step-2);
  line-height:1.3;margin-block-end:.4rem}
.why__text{font-size:var(--step-0);color:var(--color-text-muted);line-height:1.8}

/* ═══ PROCESS ═══ */
.process{display:grid;gap:var(--space-xl);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,13rem),1fr))}
.process__step{position:relative;padding-inline-end:var(--space-md)}
.process__disc{inline-size:3rem;block-size:3rem;border-radius:var(--radius-pill);
  background:var(--color-brand);color:var(--color-on-brand);display:grid;
  place-items:center;font-family:var(--font-display);font-weight:900;
  font-size:var(--step-1);position:relative;z-index:1;
  box-shadow:0 0 0 7px var(--color-raised);margin-block-end:var(--space-md)}
.process__step::before{content:"";position:absolute;inset-block-start:1.5rem;
  inset-inline-start:3rem;inset-inline-end:0;block-size:2px;
  background:hsl(150 14% 88% / .13)}
.process__step:last-child::before{display:none}
@media (max-width:52rem){.process__step::before{display:none}}
.process__title{font-family:var(--font-display);font-weight:800;font-size:var(--step-1);
  line-height:1.35;margin-block-end:.4rem}
.process__text{font-size:var(--step--1);color:var(--color-text-muted);line-height:1.8}

/* ═══ OUR WORK : photographs only, no captions ═══ */
/* Three columns, not four. At four the six frames left a two-cell hole in the bottom
   corner: 2x2 lead + four singles + a wide sixth does not tile a 4-wide grid. At three
   it tiles exactly, with no filler frame invented to plug a gap. */
.work{display:grid;gap:var(--space-md);grid-template-columns:repeat(2,1fr)}
@media (min-width:62rem){
  .work{grid-template-columns:repeat(3,1fr);grid-auto-rows:13rem}
  .work__frame:nth-child(1){grid-column:span 2;grid-row:span 2}
}
.work__frame{position:relative;overflow:hidden;border-radius:var(--radius-md);
  box-shadow:var(--shadow-md),var(--shadow-ring);background:var(--color-panel-2);
  aspect-ratio:4/3}
@media (min-width:62rem){.work__frame{aspect-ratio:auto}}
.work__frame img{inline-size:100%;block-size:100%;object-fit:cover;
  transition:transform var(--transition-slow)}
@media (hover:hover){.work__frame:hover img{transform:scale(var(--media-zoom))}}

/* ═══ REVIEWS ═══ */
.reviews{display:grid;gap:var(--space-2xl)}
@media (min-width:64rem){.reviews{grid-template-columns:minmax(0,.75fr) minmax(0,1.25fr);
  align-items:start}}
.score{background:var(--color-panel);border-radius:var(--radius-lg);
  padding:var(--space-xl);box-shadow:var(--shadow-md),var(--shadow-ring);
  position:relative;overflow:hidden}
.score::after{content:"";position:absolute;inset-block-start:0;inset-inline:0;
  block-size:3px;background:var(--color-brand)}
.score__value{font-family:var(--font-display);font-weight:900;
  font-size:clamp(3.6rem,2rem + 7vw,5.6rem);line-height:.9;color:var(--color-brand);
  unicode-bidi:isolate;direction:ltr;letter-spacing:-.04em}
.score__stars{display:flex;gap:.3rem;color:var(--color-brand);
  margin-block-start:var(--space-md)}
.score__stars .icon{inline-size:1.7rem;block-size:1.7rem;stroke-width:1.6}
.score__meta{margin-block-start:var(--space-md);color:var(--color-text-muted);
  font-size:var(--step--1);line-height:1.8}
.score__link{display:inline-flex;align-items:center;gap:.4rem;margin-block-start:var(--space-md);
  color:var(--color-brand);font-family:var(--font-display);font-weight:800;
  font-size:var(--step--1);text-decoration:none}
.score__link .icon{inline-size:1em;block-size:1em}
@media (hover:hover){.score__link:hover{text-decoration:underline}}
/* Quotes are typography, not cards. Four boxed panels is what every competitor ships;
   a ruled column with the quote set large reads as an editorial page instead. */
.quotes{display:grid;gap:0}
@media (min-width:48rem){.quotes{grid-template-columns:repeat(2,1fr);
  column-gap:var(--space-2xl)}}
.quote{padding-block:var(--space-lg);border-block-end:var(--border-hairline);
  display:flex;flex-direction:column;gap:var(--space-md)}
.quote__text{font-family:var(--font-display);font-weight:700;font-size:var(--step-1);
  line-height:1.7;position:relative;padding-inline-start:var(--space-lg)}
.quote__text::before{content:"";position:absolute;inset-inline-start:0;inset-block:.35em .35em;
  inline-size:3px;border-radius:2px;background:var(--color-brand)}
.quote__foot{display:flex;align-items:center;gap:.6rem;font-size:var(--step--1);
  color:var(--color-text-dim);padding-inline-start:var(--space-lg)}
.quote__name{font-family:var(--font-display);font-weight:800;color:var(--color-text)}
.quote__src{margin-inline-start:auto;display:inline-flex;align-items:center;gap:.3rem;
  color:var(--color-text-muted);text-decoration:none}
.quote__src .icon{inline-size:1em;block-size:1em}
@media (hover:hover){.quote__src:hover{color:var(--color-brand)}}

/* ═══ BEATS : three short statements, no wall of text ═══
   The overview used to be three long paragraphs, which is the densest thing that can go
   on a page and the first thing a scanning reader skips. Same argument, three beats, each
   short enough to read without deciding to. Deliberately NOT a card and NOT a photo grid,
   because this page already carries both and repeating a component is what makes a long
   page feel like one repeated section. */
.beats{display:grid;gap:var(--space-xl);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,16rem),1fr))}
.beat{display:flex;flex-direction:column;gap:var(--space-sm);align-items:center;
  text-align:center;padding-block-start:var(--space-lg);
  border-block-start:3px solid var(--color-brand)}
.beat__label{font-family:var(--font-display);font-weight:800;font-size:var(--step--1);
  color:var(--color-brand);letter-spacing:.02em}
.beat__title{font-family:var(--font-display);font-weight:800;font-size:var(--step-2);
  line-height:1.3}
.beat__text{font-size:var(--step-0);color:var(--color-text-muted);line-height:1.8;
  max-width:32ch}

/* ═══ ID TILES : a photograph with a caption under it, and nothing else ═══
   Six of them, uniform. No panel, no shadow, no arrow: the card grid on this page already
   owns that treatment, so the identification set is deliberately plainer. */
/* Fixed column counts, not auto-fit. There are exactly six tiles, and auto-fit resolved
   to five at 1440px, which left one orphan on a second row. Six divides cleanly by three
   and by two, so the set always fills its rows. */
.idgrid{display:grid;gap:var(--space-lg);grid-template-columns:repeat(2,1fr)}
@media (min-width:56rem){.idgrid{grid-template-columns:repeat(3,1fr)}}
.idtile{display:flex;flex-direction:column;gap:var(--space-sm);text-align:center;
  align-items:center}
.idtile__media{inline-size:100%;aspect-ratio:1;overflow:hidden;
  border-radius:var(--radius-lg);box-shadow:var(--shadow-md),var(--shadow-ring);
  position:relative;background:var(--color-panel-2)}
.idtile__media img{inline-size:100%;block-size:100%;object-fit:cover;
  filter:brightness(.84) saturate(.88) contrast(1.04);
  transition:transform var(--transition-slow),filter var(--transition)}
@media (hover:hover){.idtile:hover .idtile__media img{
  transform:scale(var(--media-zoom));filter:brightness(.95) saturate(.95) contrast(1.04)}}
.idtile__name{font-family:var(--font-display);font-weight:800;font-size:var(--step-1);
  line-height:1.35}
.idtile__text{font-size:var(--step--1);color:var(--color-text-muted);line-height:1.75;
  max-width:34ch}

/* ═══ TESTIMONIALS : an actual card, not a bare line of text ═══
   The old .quote was a hairline rule and some type, which on a dark page reads as
   unstyled. A review is the highest-trust content on the site and it was the least
   designed thing on it. */
.testimonials{display:grid;gap:var(--space-lg);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,19rem),1fr))}
.testimonial{background:var(--color-panel);border-radius:var(--radius-lg);
  padding:var(--space-xl) var(--space-lg) var(--space-lg);
  box-shadow:var(--shadow-md),var(--shadow-ring);
  display:flex;flex-direction:column;gap:var(--space-md);align-items:center;
  text-align:center;position:relative;
  transition:transform var(--transition),box-shadow var(--transition)}
@media (hover:hover){.testimonial:hover{transform:translateY(var(--lift-sm));
  box-shadow:var(--shadow-lg),var(--shadow-ring-strong)}}
.testimonial__stars{display:flex;gap:.15rem;direction:ltr;color:var(--color-brand)}
.testimonial__stars .icon{inline-size:1.05rem;block-size:1.05rem}
.testimonial__text{font-family:var(--font-display);font-weight:700;font-size:var(--step-1);
  line-height:1.75;flex:1}
.testimonial__foot{display:flex;flex-direction:column;gap:.15rem;align-items:center;
  padding-block-start:var(--space-md);inline-size:100%;
  border-block-start:var(--border-hairline)}
.testimonial__name{font-family:var(--font-display);font-weight:800;font-size:var(--step--1)}
.testimonial__src{font-size:var(--step--1);color:var(--color-text-dim);
  display:inline-flex;align-items:center;gap:.3rem}
.testimonial__src .icon{inline-size:1em;block-size:1em}
.testimonial__note{font-size:var(--step--1);color:var(--color-text-dim);opacity:.8;
  font-style:italic}

/* ═══ AREA PILLS ═══
   Every entry becomes an <a> the moment the service-area pages exist. Until then they are
   plain <span> and there is nothing to orphan, which is the only condition under which
   combo permits an unlinked pill. */
/* ═══ AREA RAIL : all 107 districts, ONE ROW ═══
   The same shape the reference site uses for the same job, labelled in its own markup as
   "Areas Served: 1-row slider". This section exists for the LINK GRAPH, not for browsing:
   a visitor who wants their district clicks it, and a crawler gets 107 anchors for the
   vertical cost of a single row.

   No wrap, no disclosure, no truncation, nothing hidden behind a control. A "show more"
   button is a reading affordance, and nobody reads a list of 107 district names. */
.areas-rail{position:relative}
.areas-rail__track{display:flex;flex-wrap:nowrap;gap:.5rem;overflow-x:auto;
  scroll-behavior:smooth;padding:.35rem 3.25rem;
  scrollbar-width:none;-ms-overflow-style:none}
.areas-rail__track::-webkit-scrollbar{display:none}
.area-pill{display:inline-flex;align-items:center;gap:.35rem;flex:0 0 auto;
  white-space:nowrap;padding:.5rem .95rem;
  border-radius:var(--radius-pill);background:var(--color-panel);
  box-shadow:var(--shadow-xs),var(--shadow-ring);font-size:var(--step--1);
  font-family:var(--font-display);font-weight:700;color:var(--color-text-muted);
  text-decoration:none;transition:color var(--transition),box-shadow var(--transition)}
.area-pill .icon{inline-size:.9em;block-size:.9em;color:var(--color-brand);flex:none}
@media (hover:hover){a.area-pill:hover{color:var(--color-brand);
  box-shadow:var(--shadow-ring-lime)}}

/* The arrows sit ON the row's edges, so the strip reads as running past both sides rather
   than as a list that happens to be cut off. */
.areas-rail__btn{position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  inline-size:2.5rem;block-size:2.5rem;border:0;border-radius:var(--radius-pill);
  background:var(--color-panel-2);color:var(--color-text-muted);cursor:pointer;
  display:grid;place-items:center;box-shadow:var(--shadow-md),var(--shadow-ring);
  transition:color var(--transition),box-shadow var(--transition)}
.areas-rail__btn .icon{inline-size:1.15rem;block-size:1.15rem;stroke-width:2.2}
.areas-rail__btn--prev{inset-inline-start:0}
.areas-rail__btn--next{inset-inline-end:0}
@media (hover:hover){.areas-rail__btn:hover{color:var(--color-brand);
  box-shadow:var(--shadow-lg),var(--shadow-ring-lime)}}
.areas-rail__btn:active{transform:translateY(-50%) scale(.94)}

/* ═══ SERVICE LINK ROW : the related block, without another photo grid ═══
   The related section was a fourth card grid on the same page. It is a list of names, so
   it is now a list of names. */
.svc-links{display:grid;gap:.5rem;
  grid-template-columns:repeat(auto-fit,minmax(min(100%,17rem),1fr))}
.svc-link{display:flex;align-items:center;justify-content:center;gap:.6rem;
  padding:1rem 1.25rem;border-radius:var(--radius-md);background:var(--color-panel);
  box-shadow:var(--shadow-xs),var(--shadow-ring);text-decoration:none;
  font-family:var(--font-display);font-weight:800;font-size:var(--step-0);
  transition:transform var(--transition),box-shadow var(--transition),color var(--transition)}
.svc-link .icon{inline-size:1.05em;block-size:1.05em;color:var(--color-brand);
  transition:transform var(--transition)}
[dir="ltr"] .svc-link .icon{transform:scaleX(-1)}
@media (hover:hover){
  .svc-link:hover{transform:translateY(var(--lift-sm));box-shadow:var(--shadow-md),var(--shadow-ring-lime)}
  .svc-link:hover .icon{transform:translateX(-3px)}
  [dir="ltr"] .svc-link:hover .icon{transform:scaleX(-1) translateX(-3px)}
}

/* The one outbound citation. Small and quiet: it is there for the reader who wants the
   national guidance and for the crawler, not to pull attention off the page. */
.authority{margin-block-start:var(--space-lg);font-size:var(--step--1);
  color:var(--color-text-dim);line-height:1.8}
.authority a{color:var(--color-text-muted);text-decoration:underline;
  text-underline-offset:3px;transition:color var(--transition)}
@media (hover:hover){.authority a:hover{color:var(--color-brand)}}

/* ═══ FAQ ═══ */
.faq{max-width:54rem;display:flex;flex-direction:column;gap:var(--space-sm)}
.faq__item{border-radius:var(--radius-md);background:var(--color-panel);
  box-shadow:var(--shadow-xs),var(--shadow-ring);overflow:hidden;
  transition:box-shadow var(--transition)}
.faq__item[open]{box-shadow:var(--shadow-md),var(--shadow-ring-strong)}
.faq__summary{list-style:none;cursor:pointer;padding:var(--space-md) var(--space-lg);
  display:flex;align-items:center;gap:var(--space-md);font-family:var(--font-display);
  font-weight:800;font-size:var(--step-1);line-height:1.45}
.faq__summary::-webkit-details-marker{display:none}
.faq__summary .icon{margin-inline-start:auto;flex:none;color:var(--color-brand);
  transition:transform var(--transition)}
.faq__item[open] .faq__summary .icon{transform:rotate(180deg)}
@media (hover:hover){.faq__summary:hover{color:var(--color-brand)}}
.faq__answer{padding:0 var(--space-lg) var(--space-lg);color:var(--color-text-muted);
  line-height:1.9}

/* ═══ FINAL CTA ═══ */
.cta__inner{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-lg);
  max-width:46rem}
.cta__actions{display:flex;flex-wrap:wrap;gap:var(--space-md)}

/* ═══ FOOTER ═══ */
.site-footer{background:var(--color-deep);color:var(--color-text-muted);
  padding-block:var(--space-2xl) 0}
.site-footer__grid{display:grid;gap:var(--space-xl);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,15rem),1fr))}
/* A grid item's automatic minimum size is its min-content width, and an iframe carries an
   intrinsic width, so the footer map would otherwise widen the track it sits in. */
.site-footer__grid>*{min-inline-size:0}
.site-footer h2{font-size:var(--step-0);color:var(--color-text);
  margin-block-end:var(--space-md);font-weight:800;text-transform:var(--label-transform,none)}
.site-footer li{margin-block-end:.55rem;font-size:var(--step--1);line-height:1.7}
.site-footer a{text-decoration:none}
@media (hover:hover){.site-footer a:hover{color:var(--color-brand)}}
.footer__contact{display:flex;align-items:center;gap:.55rem}
.footer__contact .icon{color:var(--color-brand);inline-size:1.05rem;block-size:1.05rem;flex:none}
.footer__brand{display:flex;align-items:center;gap:.7rem;margin-block-end:var(--space-md)}
.footer__bottom{margin-block-start:var(--space-xl);padding-block:var(--space-md);
  border-block-start:var(--border-hairline);font-size:var(--step--1);
  display:flex;flex-wrap:wrap;gap:var(--space-sm) var(--space-lg);align-items:center}
body:has(.float-ctas) .footer__bottom{
  padding-block-end:calc(4.25rem + env(safe-area-inset-bottom,0px))}
@media (min-width:40rem){
  body:has(.float-ctas) .footer__bottom{padding-block-end:var(--space-md)}
}

/* ═══ FLOAT CTAs ═══
   Hidden while the hero is on screen: the hero already carries both actions, and the
   bar sat directly on top of them. It is a display toggle, never an animated entrance
   (10-visual-craft.md §8.5: a bar that arrives late gets tapped by accident).
   Default is VISIBLE, so with JS disabled the bar still works. */
.float-ctas{position:fixed;z-index:150;display:flex;
  inset-block-end:1.25rem;inset-inline-end:1.25rem;flex-direction:column;gap:.6rem}
.float-ctas[data-in-hero]{display:none}
.float-cta{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  inline-size:3.5rem;block-size:3.5rem;border-radius:var(--radius-pill);
  text-decoration:none;color:var(--color-on-brand);box-shadow:var(--shadow-xl);
  transition:transform var(--transition),box-shadow var(--transition)}
.float-cta--call{background:var(--color-brand)}
.float-cta--wa{background:var(--color-whatsapp)}
.float-cta .icon{inline-size:1.5rem;block-size:1.5rem;stroke-width:2}
.float-cta__label,.float-cta__meta{display:none}
@media (hover:hover){.float-cta:hover{transform:translateY(var(--lift-sm))}}
.float-cta:active{transform:translateY(1px);box-shadow:var(--shadow-md)}
@media (max-width:40rem){
  .float-ctas{inset-inline:0;inset-block-end:0;flex-direction:row;gap:0;
    padding-block-end:env(safe-area-inset-bottom,0px);box-shadow:var(--shadow-xl)}
  .float-cta{flex:1;inline-size:auto;block-size:auto;min-block-size:3.75rem;
    border-radius:0;flex-wrap:wrap;padding-block:.5rem;box-shadow:none;
    font-family:var(--font-display);font-weight:800;font-size:var(--step-0)}
  .float-cta__label{display:inline}
  .float-cta__meta{display:inline;unicode-bidi:isolate;direction:ltr;font-weight:700;
    font-size:.72rem;opacity:.9;flex-basis:100%;text-align:center;white-space:nowrap;
    line-height:1.2}
}

/* On a phone the hero actions go full width and the number stops wrapping. */
@media (max-width:40rem){
  .hero__actions,.cta__actions{flex-direction:column;align-items:stretch;width:100%}
  .hero__actions .btn,.cta__actions .btn{width:100%}
  .btn__meta{white-space:nowrap;font-size:var(--step--1)}
}



@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{transition-duration:.01ms !important;animation-duration:.01ms !important}
  .btn:hover,.card:hover,.float-cta:hover,.pillar:hover,
  .btn:active,.card:active,.float-cta:active{transform:none}
  .card:hover .card__media img,.work__frame:hover img,
  .card:hover .card__go .icon{transform:none}
  .site-nav a:hover::after{transform:scaleX(1)}
  /* The sheet still opens and closes, it just arrives whole. The staggered rise is the
     part that causes trouble, so the rows are placed rather than moved. The burger still
     morphs, since rotating a 2px bar is not vestibular motion. */
  .nav-panel__links li,.nav-panel__actions{opacity:1;transform:none;transition-delay:0s !important}
}

/* ═══════════════════════════════════════════════════════════════════════════
   INNER PAGES
   Added when the site went multi-page. Everything above this line is the
   approved landing page and is unchanged.

   NOTE: inner page headers use .page-head, never .hero. The float bar hides
   itself while a .hero is on screen, and an inner page has no hero, so the bar
   must be visible from the first pixel there.
   ═══════════════════════════════════════════════════════════════════════════ */

.page-head{position:relative;isolation:isolate;background:var(--color-deep);
  padding-block:clamp(2.75rem,1.6rem + 4.5vw,5rem) clamp(2.25rem,1.4rem + 3.5vw,4rem);
  overflow:hidden}
.page-head::after{content:"";position:absolute;inset:0;z-index:-1;
  background:radial-gradient(120% 140% at 88% 0%,hsl(76 78% 55% / .10),transparent 58%)}
.page-head__title{font-size:var(--step-5);font-weight:var(--weight-display);
  line-height:1.16;letter-spacing:-.02em;max-width:20ch}
.page-head__lead{margin-block-start:var(--space-md);font-size:var(--step-2);
  color:var(--color-text-muted);max-width:52ch;line-height:1.7}

/* breadcrumb: the separator is drawn in CSS so it is never read aloud and never
   needs translating */
.breadcrumb{margin-block-end:var(--space-lg);font-size:var(--step--1);
  color:var(--color-text-dim)}
.breadcrumb ol{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}
.breadcrumb li{display:flex;align-items:center;gap:.5rem}
.breadcrumb li+li::before{content:"/";color:var(--color-text-dim);opacity:.6}
.breadcrumb a{color:var(--color-text-muted);text-decoration:none}
@media (hover:hover){.breadcrumb a:hover{color:var(--color-brand)}}
.breadcrumb [aria-current]{color:var(--color-text)}

/* long-form copy */
/* A prose block that follows a grid in the same band. A class rather than an inline style
   because this page is the template for 25 more, and an inline style would be copied 25
   times; combo's document rules put inlineStyleAttributes at 0 for the same reason. */
.prose--after-grid{margin-block-start:var(--space-xl)}
.prose{max-width:38rem;font-size:var(--step-0);line-height:1.95;
  color:var(--color-text-muted)}
.prose > * + *{margin-block-start:var(--space-lg)}
.prose h2{font-size:var(--step-3);color:var(--color-text);line-height:1.3;
  margin-block-start:var(--space-2xl)}
.prose h3{font-size:var(--step-1);color:var(--color-text);line-height:1.4;
  margin-block-start:var(--space-xl)}
.prose strong{color:var(--color-text);font-weight:700}
.prose a{color:var(--color-brand);text-underline-offset:.25em}
.prose ul,.prose ol{display:flex;flex-direction:column;gap:var(--space-sm);
  padding-inline-start:var(--space-lg)}
.prose ul li{position:relative;padding-inline-start:var(--space-md)}
.prose ul li::before{content:"";position:absolute;inset-inline-start:0;inset-block-start:.72em;
  inline-size:.42rem;block-size:.42rem;border-radius:50%;background:var(--color-brand)}
.prose ol{counter-reset:n;list-style:none;padding-inline-start:0}
.prose ol li{counter-increment:n;position:relative;padding-inline-start:2.2rem}
.prose ol li::before{content:counter(n);position:absolute;inset-inline-start:0;
  inset-block-start:.1em;font-family:var(--font-display);font-weight:900;
  color:var(--color-brand);font-size:var(--step-0)}
.prose blockquote{margin:0;padding-inline-start:var(--space-lg);
  border-inline-start:3px solid var(--color-brand);color:var(--color-text);
  font-family:var(--font-display);font-weight:700;font-size:var(--step-1);line-height:1.7}

/* article layout: copy column beside a sticky aside */
.article{display:grid;gap:var(--space-2xl)}
@media (min-width:64rem){.article{grid-template-columns:minmax(0,1fr) 20rem;
  align-items:start}}
.article__figure{margin:0 0 var(--space-xl);border-radius:var(--radius-lg);
  overflow:hidden;aspect-ratio:16/9;box-shadow:var(--shadow-md),var(--shadow-ring)}
.article__figure img{inline-size:100%;block-size:100%;object-fit:cover;
  filter:brightness(.86) saturate(.9) contrast(1.04)}
.article__meta{display:flex;flex-wrap:wrap;gap:var(--space-md);font-size:var(--step--1);
  color:var(--color-text-dim);margin-block-end:var(--space-lg)}
@media (min-width:64rem){.aside{position:sticky;top:6rem}}
.aside__card{background:var(--color-panel);border-radius:var(--radius-lg);
  padding:var(--space-lg);box-shadow:var(--shadow-sm),var(--shadow-ring);
  display:flex;flex-direction:column;gap:var(--space-md)}
.aside__title{font-family:var(--font-display);font-weight:800;font-size:var(--step-1)}
.aside__text{font-size:var(--step--1);color:var(--color-text-muted);line-height:1.8}

/* blog index */
.posts{display:grid;gap:var(--space-lg);
  grid-template-columns:repeat(auto-fill,minmax(min(100%,19rem),1fr))}
.post{display:flex;flex-direction:column;block-size:100%;overflow:hidden;
  border-radius:var(--radius-lg);background:var(--color-panel);text-decoration:none;
  box-shadow:var(--shadow-sm),var(--shadow-ring);
  transition:transform var(--transition),box-shadow var(--transition)}
@media (hover:hover){
  .post:hover{transform:translateY(var(--lift-md));box-shadow:var(--shadow-lg),var(--shadow-ring-lime)}
  .post:hover .post__media img{transform:scale(var(--media-zoom))}
}
.post:active{transform:translateY(1px)}
.post__media{aspect-ratio:16/10;overflow:hidden;position:relative}
.post__media::after{content:"";position:absolute;inset:0;background:var(--media-veil)}
.post__media img{inline-size:100%;block-size:100%;object-fit:cover;
  filter:brightness(.84) saturate(.88) contrast(1.04);
  transition:transform var(--transition-slow)}
.post__body{padding:var(--space-lg);display:flex;flex-direction:column;gap:.5rem;flex:1}
.post__title{font-family:var(--font-display);font-weight:800;font-size:var(--step-1);
  line-height:1.4}
.post__text{font-size:var(--step--1);color:var(--color-text-muted);line-height:1.8}
.post__go{margin-block-start:auto;padding-block-start:var(--space-sm);
  font-family:var(--font-display);font-weight:800;font-size:var(--step--1);
  color:var(--color-brand);display:flex;align-items:center;gap:.4rem}
.post__go .icon{inline-size:1em;block-size:1em;transition:transform var(--transition)}
@media (hover:hover){.post:hover .post__go .icon{transform:translateX(-3px)}}

/* contact */
.contact{display:grid;gap:var(--space-2xl)}
@media (min-width:64rem){.contact{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr)}}
.channels{display:flex;flex-direction:column;gap:var(--space-md)}
.channel{display:flex;align-items:center;gap:var(--space-lg);text-decoration:none;
  padding:var(--space-lg);border-radius:var(--radius-lg);background:var(--color-panel);
  box-shadow:var(--shadow-sm),var(--shadow-ring);
  transition:transform var(--transition),box-shadow var(--transition)}
@media (hover:hover){.channel:hover{transform:translateY(var(--lift-sm));
  box-shadow:var(--shadow-md),var(--shadow-ring-lime)}}
.channel:active{transform:translateY(1px)}
.channel__tile{inline-size:3.25rem;block-size:3.25rem;flex:none;display:grid;
  place-items:center;border-radius:var(--radius-md);background:var(--color-panel-2);
  color:var(--color-brand);box-shadow:var(--shadow-ring)}
.channel--wa .channel__tile{color:var(--color-whatsapp)}
.channel__tile .icon{inline-size:1.5rem;block-size:1.5rem}
.channel__label{font-family:var(--font-display);font-weight:800;font-size:var(--step-1)}
.channel__value{font-size:var(--step--1);color:var(--color-text-muted);
  unicode-bidi:isolate;display:block;margin-block-start:.15rem}

/* The two actions that matter in this market. Call and WhatsApp are how a Saudi
   customer contacts a home service, so they are the page, not a row above a form. */
.channels-major{display:grid;gap:var(--space-lg);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,20rem),1fr));
  margin-block-end:var(--space-lg)}
.major{display:flex;flex-direction:column;align-items:flex-start;gap:.3rem;
  padding:var(--space-xl);border-radius:var(--radius-lg);text-decoration:none;
  background:var(--color-panel);box-shadow:var(--shadow-md),var(--shadow-ring);
  transition:transform var(--transition),box-shadow var(--transition)}
@media (hover:hover){.major:hover{transform:translateY(var(--lift-md));
  box-shadow:var(--shadow-lg),var(--shadow-ring-lime)}}
.major:active{transform:translateY(1px);box-shadow:var(--shadow-sm)}
.major__tile{inline-size:3.75rem;block-size:3.75rem;display:grid;place-items:center;
  border-radius:var(--radius-md);margin-block-end:var(--space-md);
  background:var(--color-brand);color:var(--color-on-brand)}
.major--wa .major__tile{background:var(--color-whatsapp)}
.major__tile .icon{inline-size:1.8rem;block-size:1.8rem;stroke-width:2}
.major__label{font-family:var(--font-display);font-weight:900;font-size:var(--step-2);
  line-height:1.2}
.major__value{font-family:var(--font-display);font-weight:800;font-size:var(--step-1);
  color:var(--color-brand);unicode-bidi:isolate;direction:ltr}
.major--wa .major__value{color:var(--color-whatsapp)}
.major__note{font-size:var(--step--1);color:var(--color-text-muted);line-height:1.7;
  margin-block-start:.35rem}
/* a plain two-column fact list, used on About */
.facts{display:grid;gap:var(--space-lg);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,15rem),1fr))}
.fact{padding-block:var(--space-md);border-block-start:2px solid var(--color-brand)}
.fact__value{font-family:var(--font-display);font-weight:900;font-size:var(--step-3);
  line-height:1.1;unicode-bidi:isolate}
.fact__label{font-size:var(--step--1);color:var(--color-text-muted);
  margin-block-start:.35rem;line-height:1.7}

/* ═══════════════════════════════════════════════════════════════════════════
   BILINGUAL
   The layout itself needed no changes: every rule uses logical properties, so
   it mirrors from the dir attribute alone. Only the four things below are
   genuinely direction-dependent.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1. Language switch */
.lang-switch{display:inline-flex;align-items:center;gap:.4rem;text-decoration:none;
  font-family:var(--font-display);font-weight:700;font-size:var(--step--1);
  color:var(--color-text-muted);padding:.5rem .85rem;border-radius:var(--radius-pill);
  box-shadow:var(--shadow-ring);transition:color var(--transition),box-shadow var(--transition)}
.lang-switch .icon{inline-size:1.05em;block-size:1.05em}
@media (hover:hover){.lang-switch:hover{color:var(--color-brand);box-shadow:var(--shadow-ring-lime)}}
@media (max-width:64rem){.lang-switch{margin-inline-start:auto}}

/* 2. The forward arrow. icon-arrow-left points the reading direction in RTL; in LTR
   forward is the other way, so the glyph is flipped. The hover nudge is written once
   and comes out correct in both, because translateX inside a flipped coordinate system
   already runs the other way. */
[dir="ltr"] .card__go .icon,[dir="ltr"] .post__go .icon{transform:scaleX(-1)}
@media (hover:hover){
  [dir="ltr"] .card:hover .card__go .icon,
  [dir="ltr"] .post:hover .post__go .icon{transform:scaleX(-1) translateX(-3px)}
}

/* 3. Latin script metrics. The Arabic block raises the root size and kills tracking,
   both of which are wrong for Latin, so English gets the defaults back explicitly
   rather than inheriting an Arabic-tuned page. */
:root:lang(en){--leading-body:1.7;--leading-heading:1.25;--leading-display:1.05;
  --tracking-display:-.02em}
html:lang(en){font-size:100%}

/* 4. English headlines want the tighter display tracking that Arabic must not have. */
[dir="ltr"] .hero__title,[dir="ltr"] .page-head__title{letter-spacing:-.03em}
[dir="ltr"] .section__title{letter-spacing:-.02em}

/* Translation provenance on a quote. Small, muted, and never omitted: a translated
   review presented as if it were written in English quietly reattributes the
   reviewer's words. */
.quote__note{font-size:var(--step--1);color:var(--color-text-dim);opacity:.85;
  font-style:italic}
.quote__note::before{content:"";display:inline-block;inline-size:.9rem;block-size:1px;
  background:currentColor;vertical-align:middle;margin-inline-end:.45rem;opacity:.6}

/* ── Header overflow fix ──────────────────────────────────────────────────
   The Arabic brand line is «شركة انهار / لمكافحة الحشرات والمبيدات». At flex:none it
   could not compress, so below about 390px the header demanded 352px of content in a
   320px viewport and the page scrolled sideways. English never showed it, because
   "Pest Control" is short. Three changes, smallest first:
     1. the brand may shrink (above)
     2. both brand lines truncate rather than push
     3. under 24rem the tagline steps out entirely, and the language switch tightens
   body{overflow-x:clip} stays as a backstop, but a backstop is not a fix: it hides the
   symptom while the header still lays out too wide. */
.brand > span:last-child{min-width:0}
.brand__name,.brand__tag{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  display:block;max-width:100%}
@media (max-width:24rem){
  .brand__tag{display:none}
  .lang-switch{padding-inline:.55rem}
  .site-header__inner{gap:var(--space-sm)}
}
/* ═══════════════════════════════════════════════════════════════════════════
   SERVICE RAIL (home) and SERVICE HUB (services page)
   Both are generated from _services.json by the build. Twenty six pillars
   hand-written into two pages in two languages is 104 entries that drift the
   first time a service changes.

   The rail is horizontal on purpose: house rule is that vertical space is the
   scarcest thing on the page, and a grid of 26 cards would own the whole
   viewport for a block whose job is internal linking.
   ═══════════════════════════════════════════════════════════════════════════ */

.rail__head{display:flex;align-items:flex-end;gap:var(--space-lg);
  margin-block-end:var(--space-xl);flex-wrap:wrap}
.rail__head .section__head{margin-block-end:0;flex:1 1 20rem}
.rail__ctrls{display:flex;gap:.5rem;flex:none}
.rail__btn{inline-size:2.75rem;block-size:2.75rem;border-radius:var(--radius-pill);
  border:0;cursor:pointer;display:grid;place-items:center;background:var(--color-panel);
  color:var(--color-text);box-shadow:var(--shadow-sm),var(--shadow-ring);
  transition:transform var(--transition),box-shadow var(--transition),color var(--transition)}
.rail__btn .icon{inline-size:1.25rem;block-size:1.25rem;stroke-width:2.2}
@media (hover:hover){.rail__btn:hover{color:var(--color-brand);
  box-shadow:var(--shadow-md),var(--shadow-ring-lime)}}
.rail__btn:active{transform:translateY(1px)}

/* One row, scrolls sideways, snaps. scrollbar hidden because the arrows and the
   partially visible next card already say "there is more". */
.rail__track{display:flex;gap:var(--space-md);overflow-x:auto;scroll-snap-type:x mandatory;
  scrollbar-width:none;padding-block-end:.35rem;
  /* bleed to the container edge so the row reads as continuing off-screen */
  margin-inline:calc(var(--space-md) * -1);padding-inline:var(--space-md)}
.rail__track::-webkit-scrollbar{display:none}
.rail__track > li{flex:0 0 auto;scroll-snap-align:start}

.svc{display:flex;flex-direction:column;gap:.4rem;inline-size:15.5rem;block-size:100%;
  padding:var(--space-lg);border-radius:var(--radius-lg);background:var(--color-panel);
  box-shadow:var(--shadow-sm),var(--shadow-ring);text-decoration:none;position:relative;
  overflow:hidden;transition:transform var(--transition),box-shadow var(--transition)}
/* the one accent: a lime rule on the leading edge, drawn on hover */
.svc::before{content:"";position:absolute;inset-block:0;inset-inline-start:0;
  inline-size:3px;background:var(--color-brand);transform:scaleY(0);transform-origin:top;
  transition:transform var(--transition)}
@media (hover:hover){
  .svc:hover{transform:translateY(var(--lift-sm));box-shadow:var(--shadow-lg),var(--shadow-ring-lime)}
  .svc:hover::before{transform:scaleY(1)}
  .svc:hover .svc__go{transform:translateX(-3px)}
}
.svc:active{transform:translateY(1px)}
.svc__seg{font-size:var(--step--1);color:var(--color-text-dim);font-weight:500}
.svc__name{font-family:var(--font-display);font-weight:800;font-size:var(--step-1);
  line-height:1.3;color:var(--color-text)}
.svc__tag{font-size:var(--step--1);color:var(--color-text-muted);line-height:1.7;flex:1}
.svc__go{color:var(--color-brand);margin-block-start:var(--space-xs);
  transition:transform var(--transition)}
.svc__go .icon{inline-size:1.1rem;block-size:1.1rem}
[dir="ltr"] .svc__go .icon{transform:scaleX(-1)}
@media (hover:hover){[dir="ltr"] .svc:hover .svc__go .icon{transform:scaleX(-1) translateX(-3px)}}
.rail__all{margin-block-start:var(--space-lg)}

/* ── hub (services page) ── */
.filter-tabs{display:flex;flex-wrap:wrap;gap:.5rem;margin-block-end:var(--space-xl)}
.filter-tab{font-family:var(--font-display);font-weight:800;font-size:var(--step--1);
  padding:.6rem 1.15rem;border-radius:var(--radius-pill);border:0;cursor:pointer;
  background:var(--color-panel);color:var(--color-text-muted);
  box-shadow:var(--shadow-ring);transition:color var(--transition),
  background-color var(--transition),box-shadow var(--transition)}
@media (hover:hover){.filter-tab:hover{color:var(--color-text)}}
.filter-tab[aria-pressed="true"]{background:var(--color-brand);color:var(--color-on-brand);
  box-shadow:var(--shadow-action)}
.hub-grid{display:grid;gap:var(--space-md);
  grid-template-columns:repeat(auto-fill,minmax(min(100%,17rem),1fr))}
.hub-grid > li[hidden]{display:none}
.hub-sep{grid-column:1/-1;margin-block-start:var(--space-lg);
  font-family:var(--font-display);font-weight:800;font-size:var(--step-1);
  color:var(--color-brand);padding-block-end:var(--space-xs);
  border-block-end:var(--border-hairline)}
.hub-sep:first-child{margin-block-start:0}

/* LTR flips the rail chevrons: DOM order stays prev-then-next so prev sits on the
   correct side in both directions, but the glyphs must point the way they travel. */
[dir="ltr"] .rail__btn .icon{transform:scaleX(-1)}

/* service card gains a picture: media on top, body below. The rail and the hub share
   the .svc component so a change to one is a change to both by construction. */
.svc{padding:0}
.svc__media{display:block;aspect-ratio:4/3;overflow:hidden;position:relative;
  background:var(--color-panel-2)}
.svc__media::after{content:"";position:absolute;inset:0;background:var(--media-veil)}
.svc__media img{inline-size:100%;block-size:100%;object-fit:cover;
  filter:brightness(.84) saturate(.88) contrast(1.04);
  transition:transform var(--transition-slow),filter var(--transition)}
@media (hover:hover){.svc:hover .svc__media img{transform:scale(var(--media-zoom));
  filter:brightness(.95) saturate(.95) contrast(1.04)}}
.svc__body{display:flex;flex-direction:column;gap:.35rem;padding:var(--space-md) var(--space-lg) var(--space-lg);flex:1}

/* arrow pinned to the card foot so a two-line service name does not leave a ragged
   row of arrows at different heights */
.svc__go{margin-block-start:auto;padding-block-start:var(--space-sm)}

/* Footer map. Muted and desaturated so a bright Google tile does not become the
   loudest thing on an ink page, and lifted back to full colour on hover.

   It sits inside the brand column and is sized BY that column: inline-size:100% with no
   rem max, so it can only ever be as wide as the track it is in. The iframe's own
   width attribute never participates. */
.footer__map{margin-block-start:var(--space-lg);display:flex;flex-direction:column;
  gap:var(--space-sm)}
.footer__map iframe{inline-size:100%;max-inline-size:100%;aspect-ratio:16/9;block-size:auto;
  max-block-size:11rem;border:0;display:block;
  border-radius:var(--radius-md);box-shadow:var(--shadow-md),var(--shadow-ring);
  filter:grayscale(.55) brightness(.82) contrast(1.05);
  transition:filter var(--transition)}
@media (hover:hover){.footer__map:hover iframe{filter:grayscale(0) brightness(.95) contrast(1)}}
.footer__map-link{display:inline-flex;align-items:center;gap:.45rem;align-self:flex-start;
  font-family:var(--font-display);font-weight:800;font-size:var(--step--1);
  color:var(--color-brand);text-decoration:none}
.footer__map-link .icon{inline-size:1em;block-size:1em}
@media (hover:hover){.footer__map-link:hover{text-decoration:underline}}

/* ═══════════════════════════════════════════════════════════════════════════
   LAST IN THE FILE ON PURPOSE. A media query carries no extra specificity, so this
   block can only beat the rail, hub and bilingual rules above by coming after them.
   Moving it up will silently stop parts of it working.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ═══ EVERYTHING CENTRED, AT EVERY WIDTH ═══
   This was scoped to phones. It is now the whole site at every width, because an
   edge-aligned layout reads as lopsided here and centred reads as composed.

   Long-form ARTICLE prose is still the one exception, set at the end: centring a
   multi-line paragraph destroys the left edge the eye returns to on every line. That is a
   reading-speed cost, not a taste question, and it only applies to blog articles, where
   paragraphs actually run long. Everywhere else the copy is short enough to centre.

   Section heads carry max-width, so they also need margin-inline:auto or a centred
   heading sits in a box still pinned to the start edge. */
.section__head{margin-inline:auto}
@media (min-width:48.0625rem){
  .section__head,.section__title,.section__lead,.section__eyebrow,
  .hero__inner,.hero__title,.hero__lead,
  .card,.card__title,.card__body,
  .fact,.pillar,.process__step,
  .page-head,.page-head__title,.page-head__lead,
  .post__title,.svc__title,.prose{text-align:center}
  .card__go,.hero__actions,.cta__actions,.hero__badge,.hero__facts,
  .score__stars,.process__step{justify-content:center}
  /* justify-content on an INLINE-flex centres its children, not the element itself. These
     need to become block-level with a fit-content width before auto margins can move
     them, which is why they are listed apart from the group above. */
  .score__link,.hero__badge,.rail__all,.btn.rail__all{
    display:flex;width:fit-content;margin-inline:auto}
  /* The rail head is a row with the controls pinned to the far edge, which is the one
     thing left looking bolted to the side once the heading above it centres. Same change
     the mobile block makes, now at every width. flex-basis is measured on the MAIN axis,
     so section__head's `flex:1 1 20rem` has to be reset or 20rem becomes a min HEIGHT. */
  .rail__head{flex-direction:column;align-items:center}
  .rail__head .section__head{flex:0 0 auto}
  .rail__ctrls{justify-content:center}
  .hero__facts{align-items:center}
  /* A max-width box does NOT centre itself just because its text is centred, and the
     result reads as a paragraph that is subtly off rather than as a layout bug. Every
     element here carries a max-width: prose 38rem, faq 54rem, hero__lead 44ch,
     section__lead 46ch. Measured: hero__lead sat 317px from one edge and 0 from the other
     at 1440px while the title and buttons above and below it were centred. */
  .prose,.faq,.hero__lead,.section__lead,.page-head__lead,.beat__text,.idtile__text{
    margin-inline:auto}
  /* the breadcrumb is a flex row, so it needs justify-content rather than text-align */
  .breadcrumb ol{justify-content:center}
  /* block-level art does not answer to text-align */
  .pillar__art,.pillar .illus,.process__disc,.fact__value{margin-inline:auto}
  .pillar__art,.pillar .illus{display:block}
  .process__step{padding-inline-end:0}
  /* the blog article keeps its natural edge; nothing else does */
  .article .prose,.article .prose p,.article .prose li,.article .prose blockquote{
    text-align:start}
}
@media (max-width:48rem){
  .section__head,.section__title,.section__lead,.section__eyebrow,
  .hero__inner,.hero__title,.hero__lead,
  .card,.card__title,.card__body,.card__go,
  .fact,.facts,.pillar,.process__step,.why,.why__list li,
  .score,.quote,.reviews,.areas,.faq__item,.cta,
  .page-head,.page-head__title,.page-head__lead,
  .post,.post__title,.post__meta,.svc,.svc__title,
  .site-footer__grid>*,.footer__brand,.footer__bottom{text-align:center}

  /* anything laid out as a row has to re-centre too, or the text centres inside a box
     that is still pinned to one edge */
  .hero__badge,.hero__actions,.cta__actions,.score__stars,.footer__brand,
  .footer__map,.footer__map-link,.hero__facts,.why__list li,.footer__bottom,
  .fact__value--stars,.score__link,.post__meta{justify-content:center}
  .hero__facts{align-items:center}
  .footer__contact{justify-content:center}
  .footer__map-link{align-self:center}
  .brand{justify-content:center}
  .why__list li{flex-direction:column;align-items:center}
  /* Block-level art does not answer to text-align, so it stays pinned to the start edge
     while the words around it centre. These are the elements that has to be moved by
     margin instead. */
  .card__media,.svc__media,.pillar__art,.pillar .illus,.process__step .illus,
  .fact__value,.quote__mark,.work__frame,.score__value,.process__disc{margin-inline:auto}
  .pillar__art,.pillar .illus{display:block}
  /* the step number is its own box above the words, not a bullet beside them */
  .process__step{padding-inline-end:0}
  /* the rail's controls and its "all services" link both sit on one edge by default,
     which is the last thing left looking bolted to the side once everything else has
     moved to the middle */
  .rail__head{flex-direction:column;align-items:center}
  /* flex-basis is measured on the MAIN axis. .rail__head .section__head carries
     flex:1 1 20rem for the desktop row, where 20rem is a width; turning the row into a
     column silently turned it into a 20rem MINIMUM HEIGHT, which opened a large empty
     gap between the standfirst and the cards. Reset it to content height. */
  .rail__head .section__head{flex:0 0 auto}
  .rail__ctrls,.rail__all,.filter-tabs{justify-content:center;display:flex;flex-wrap:wrap}

  /* .svc carries a fixed inline-size:15.5rem because the HOME RAIL needs every card the
     same width in a scrolling row. In the hub it is a grid cell instead, so the fixed
     width left each card narrower than its cell and parked against the start edge, which
     is what read as "aligned right" in RTL. */
  .hub-grid .svc{inline-size:100%}
  .hub-sep{text-align:center}

  /* Contact cards, article meta and the in-article aside. These are laid out as rows or
     start-aligned columns of their own, so the sitewide text-align never reached them. */
  .major,.channel,.aside__card,.article__meta,
  .major__label,.major__value,.major__note,
  .channel__label,.channel__value,.aside__title,.aside__text{text-align:center}
  .major{align-items:center}
  .channel{flex-direction:column;align-items:center;gap:var(--space-sm)}
  .article__meta{justify-content:center}
  .aside__card .btn{inline-size:100%}

  /* Article headings centre with everything else; the body copy underneath does not.
     A centred heading reads as composition, a centred paragraph just loses the left edge
     the eye needs to find the next line. */
  .prose h2,.prose h3{text-align:center}
  .site-footer__grid>* ul{list-style:none;padding:0}
  /* a centred block still needs its measure, or the ragged edges get very far apart */
  .section__lead,.hero__lead,.page-head__lead,.score__meta{margin-inline:auto}

  /* THE EXCEPTION. Article body copy keeps its natural edge. */
  .prose,.prose p,.prose li,.prose blockquote{text-align:start}
}
