/* ==========================================================================
   The document system.

   Every directional property here is logical (inline-start / inline-end),
   never left / right, so switching to Arabic is a dir="rtl" flip rather than
   a second stylesheet. rtl.css holds only what must mirror explicitly.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html {
  color-scheme: light;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--charcoal);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.55;
  letter-spacing: -.006em;
  font-feature-settings: "tnum" 1;   /* tabular figures, so columns of numbers align */
  -webkit-font-smoothing: antialiased;
}

/* Arabic needs more leading and must never be tracked tighter than normal. */
html[lang="ar"] body {
  font-family: var(--font-arabic);
  letter-spacing: 0;
  line-height: 1.75;
}

img, svg { display: block; max-width: 100%; }

/* Arrow links. `svg { display: block }` above made the arrow a block, so it
   dropped onto a line of its own and "All 14 service lines" rendered as two
   lines at every viewport. `.btn` was never affected because it is already
   inline-flex; these are the plain prose links, and they get the same
   treatment rather than a different one. The label stays a single flex item,
   so it still wraps internally at narrow widths while the arrow holds its
   place beside it. */
a:has(> .arrow):not(.btn) {
  display: inline-flex;
  align-items: center;
  gap: .45em;
}
a > .arrow { flex: none; }

/* These inline link-CTAs are the only route into the four calculators and
   into a case record, and they measured 21px tall -- under the 24px WCAG
   2.5.8 floor, never mind the 44px a thumb wants. The site's real buttons
   were sized correctly and these were not, so they get the same minimum at
   touch widths. Padding, not leading, so the type is unchanged. */
@media (max-width: 900px) {
  a:has(> .arrow):not(.btn) {
    min-height: 44px;
    padding-block: 4px;
  }
}

a { color: var(--teal); text-decoration: none; }
a:hover { color: var(--teal-deep); }

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 650;
  letter-spacing: -.028em;
  line-height: 1.06;
}
html[lang="ar"] :is(h1, h2, h3, h4) { letter-spacing: 0; line-height: 1.35; }

p { margin: 0; }

/* The browser gives <figure> a 40px side margin and a 1em top and bottom.
   Nothing in this stylesheet was resetting it, so every framed figure on the
   site sat 40px inside the column its own text occupied -- on the home page
   that put the results figure 40px narrower than the table directly above
   it, which reads as two unrelated blocks rather than a table and its
   illustration. Blocks that want air above use .fig--gap, which says so. */
figure { margin: 0; }

/* Consecutive paragraphs get air. The reset above is deliberate -- almost
   every block on this site positions its own children -- but nothing then
   handled the plain case, so a `.lead` followed by an unclassed <p> rendered
   as one block set in two sizes, with the leading changing mid-flow. Only
   adjacent siblings are affected, so no block that already spaces its own
   paragraphs is touched. */
p + p { margin-block-start: .9em; }

:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 3px;
}

.skip-link {
  position: absolute;
  inset-inline-start: -9999px;
  top: 0;
  z-index: 100;
  background: var(--navy);
  color: #fff;
  padding: 12px 18px;
  font-size: var(--step--1);
  font-weight: 600;
}
.skip-link:focus { inset-inline-start: 0; color: #fff; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   Shell: the page carries visible document margins
   -------------------------------------------------------------------------- */

.shell {
  max-width: var(--shell);
  margin-inline: auto;
  border-inline: 1px solid var(--rule-soft);
}
.pad { padding-inline: var(--pad); }

/* --------------------------------------------------------------------------
   The micro-label. This is how the document speaks about itself.
   -------------------------------------------------------------------------- */

.lbl {
  font-size: var(--label);
  font-weight: 600;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--gray);
  line-height: 1.4;
}
/* --teal is 4.62:1 on --paper and 4.36:1 on --paper-2, so this label
   passes on the page ground and fails inside a recessed panel. The
   deeper teal clears both, and at this size the two are
   indistinguishable. */
.lbl--teal { color: var(--teal); }
:is(.fig--paper, .band-paper, .prov, .results__ft) .lbl--teal { color: var(--teal-deep); }
/* Arabic has no uppercase, and heavy tracking damages joined letterforms. */
html[lang="ar"] .lbl { letter-spacing: .04em; text-transform: none; }

/* --------------------------------------------------------------------------
   Meta bar and header
   -------------------------------------------------------------------------- */

.metabar {
  border-bottom: 1px solid var(--rule);
  background: var(--paper);
}
.metabar__in {
  display: flex;
  gap: 16px;
  justify-content: space-between;
  align-items: center;
  padding-block: 9px;
  flex-wrap: wrap;
}
.metabar .dot {
  width: 5px; height: 5px;
  background: var(--teal);
  display: inline-block;
  margin-inline-end: 8px;
  vertical-align: 1px;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(247, 246, 243, .93);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.head {
  display: flex;
  align-items: center;
  gap: clamp(12px, 2.5vw, 34px);
  padding-block: 14px;
  /* Pinned, so --header-h is a fact rather than an estimate. Anything that
     sticks below the header or scrolls to an anchor underneath it reads the
     same token, and the shape rail on /proof/ no longer sits 14px behind the
     header because a padding value changed somewhere else. */
  min-height: calc(var(--header-h) - 2px);
  box-sizing: border-box;
}

/* Crops the supplied raster lockup to its ink, so it sits on the baseline
   like type instead of floating in a box of built-in padding.
   The masters carry about 5.3% of dead margin either side and 24.4% top and
   bottom, so without this the lockup renders small in a mostly empty box.

   Every number below is derived from the ink bounding box measured out of the
   PNG, not estimated: lockup-light is 639x213 with ink at x 34-605, y 52-160,
   giving an ink aspect of 5.2477; lockup-dark has ink at x 35-604, y 52-156,
   aspect 5.4286. Re-measure if a lockup is ever regenerated -- an earlier
   version of this rule had the two variants' figures crossed, which clipped
   1.8px off the top of the ink and left 15px of empty box trailing right.

   max-width is mandatory. The global `img, svg { max-width: 100% }` rule
   above is not contested by `width`, so without this the scale-up is silently
   clamped back to 100% and the crop lands in the wrong place. */
.wordmark {
  display: block;
  height: 24px;
  aspect-ratio: 5.2477;
  position: relative;
  overflow: hidden;
  flex: none;
}
.wordmark img {
  position: absolute;
  max-width: none;
  /* height:auto is load-bearing. The <img> carries width/height attributes so
     the box is reserved before the raster loads; those attributes also act as
     presentational hints, and the height hint is not contested by the `width`
     below -- so without this the image rendered at its full 213px natural
     height inside a 24px crop window, and the header showed an empty slice. */
  height: auto;
  width: 111.71%;          /* 639 / 572 */
  inset-inline-start: -5.944%;  /* -34 / 572 */
  top: -47.72%;            /* -(52/213) * (639/572) * 5.2477 */
}
.wordmark--dark { aspect-ratio: 5.4286; }
.wordmark--dark img { width: 112.11%; inset-inline-start: -6.14%; top: -49.52%; }

.nav {
  margin-inline-start: auto;
  display: flex;
  gap: clamp(10px, 1.6vw, 22px);
  align-items: center;
}
.nav a {
  color: var(--charcoal);
  font-size: var(--step--1);
  font-weight: 500;
  padding-block: 3px;
  border-bottom: 1px solid transparent;
  white-space: nowrap;
}
.nav a:hover { color: var(--navy); border-bottom-color: var(--teal); }
.nav a[aria-current="page"] { border-bottom-color: var(--teal); color: var(--navy); }

/* The `a` is load-bearing, not decoration. This element sits inside .nav, so
   it also matches `.nav a` above -- which is one class plus one type and
   therefore beats a bare `.nav__cta`. Written the short way, `color: #fff`
   lost to `.nav a { color: var(--charcoal) }` and the site's primary header
   CTA rendered charcoal on navy at a contrast ratio of about 1.1:1. The
   background never showed the fault because nothing else declares one. */
.nav a.nav__cta {
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  background: var(--navy);
  padding: 9px 15px;
  border-bottom: 0;
}
.nav a.nav__cta:hover,
.nav a.nav__cta:focus-visible {
  background: var(--teal);
  color: #fff;
  border-bottom-color: transparent;
}

/* --------------------------------------------------------------------------
   Language switcher
   -------------------------------------------------------------------------- */

.lang {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--rule);
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 600;
  color: var(--charcoal);
  background: transparent;
  cursor: pointer;
  font-family: inherit;
  flex: none;
}
.lang:hover { border-color: var(--teal); color: var(--teal); }
.lang svg { flex: none; }

/* `align-items: center` centres each flex item's box, not the ink inside it.
   The globe is a 15px block and centres exactly; the glyph inherits
   line-height 1.55 from body, so its line box is 18.6px and centring that box
   pushes the baseline down. Collapsing the leading to 1 makes the two boxes
   the same height, which is the only way the two optical centres coincide. */
.lang,
.lang__code { line-height: 1; }

/* The glyph is Arabic and the UI font has no Arabic coverage, so it falls
   back to whatever the platform offers -- with different vertical metrics,
   which is what made the misalignment obvious rather than subtle. Every other
   Arabic rule in this stylesheet keys on the document language, so none of
   them fire here: on an English page the document is lang="en" while this one
   element is lang="ar". Hence the attribute selector. */
.lang[lang="ar"] .lang__code {
  font-family: var(--font-arabic);
  font-size: 14px;
}
.lang[lang="en"] .lang__code { letter-spacing: .06em; }

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -.012em;
  padding: 13px 20px;
  border: 1px solid var(--navy);
  background: var(--navy);
  color: #fff;
  transition: background .16s, border-color .16s, color .16s;
  cursor: pointer;
  font-family: inherit;
}
.btn:hover { background: var(--teal); border-color: var(--teal); color: #fff; }
.btn--ghost { background: transparent; color: var(--navy); border-color: var(--rule); }
.btn--ghost:hover { background: transparent; color: var(--teal); border-color: var(--teal); }
.btn svg { flex: none; }
html[lang="ar"] .btn { letter-spacing: 0; }

.ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin-block-start: clamp(20px, 2.2vw, 26px);
}

/* The response promise. Sits beside every CTA on the site. */
.promise {
  font-size: var(--step--1);
  color: var(--gray);
  margin-block-start: 16px;
  display: flex;
  gap: 9px;
  align-items: flex-start;
  max-width: 58ch;
}
.promise b { color: var(--charcoal); font-weight: 600; }
.promise svg { flex: none; margin-block-start: 3px; }

/* --------------------------------------------------------------------------
   Numbered sections. The spine of every page.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Page header. Every page but Home opens with one, which is where its <h1>
   lives. Kept deliberately quiet: it states which page this is and then gets
   out of the way of section 01, which is where the argument starts.
   -------------------------------------------------------------------------- */

.phead {
  border-bottom: 1px solid var(--rule);
  padding-block: clamp(26px, 3.2vw, 46px) clamp(20px, 2.4vw, 30px);
}
.phead__t {
  font-size: var(--step-3);
  letter-spacing: -.032em;
  line-height: 1.1;
  max-width: 20ch;
}
.phead__d {
  margin-block-start: 12px;
  font-size: clamp(14.5px, 1.2vw, 17px);
  color: var(--ink-soft);
  line-height: 1.5;
  max-width: 58ch;
}
html[lang="ar"] .phead__t { letter-spacing: 0; line-height: 1.35; max-width: 26ch; }
html[lang="ar"] .phead__d { max-width: 62ch; }

.sec {
  border-bottom: 1px solid var(--rule);
  padding-block: var(--sec-y);
}
.sec__grid {
  display: grid;
  grid-template-columns: minmax(0, var(--rail)) minmax(0, 1fr);
  gap: var(--gap-rail);
}
.sec__no {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .14em;
  color: var(--teal);
  display: block;
  margin-block-end: 9px;
}
/* Section titles were --step-2, which is 19px at phone width and 23px at
   1440 -- a ratio of 1.19 to 1.44 against 16px body. That is the flatness
   the commercial review named: "headings are only slightly larger than body
   text ... there is no visual rhythm telling the eye where a section starts".
   --step-3 is 24px to 36px, a ratio of 1.5 to 2.25, which is a hierarchy
   rather than a hint. Nothing else about the spine changes: the rail width,
   the grid and the numbers are untouched. */
.sec__ttl {
  font-size: var(--step-3);
  letter-spacing: -.032em;
  line-height: 1.1;
  max-width: 16ch;
  /* ⚠ Load-bearing. The rail is 190px and this type is 24px to 36px, so a
     title with a long single word is wider than its own column: measured,
     "Implementation" is 257px in a 190px box and drew 67px of itself over
     the body text beside it. Nine titles across the site were doing this.

     Invisible to the horizontal-overflow test, which measures the
     document's scrollWidth -- the word overruns its neighbouring column,
     not the page. Only a screenshot shows it.

     hyphens first so a long word breaks at a syllable; break-word as the
     floor for anything the hyphenation dictionary does not know. The
     document carries lang="en" or lang="ar", which is what hyphenation
     needs. */
  hyphens: auto;
  overflow-wrap: break-word;
}
.sec__note {
  font-size: 12.5px;
  color: var(--gray);
  line-height: 1.5;
  margin-block-start: 12px;
  max-width: 24ch;
}
html[lang="ar"] :is(.sec__ttl, .sec__note) { max-width: none; }

.lead {
  font-size: var(--step-1);
  line-height: 1.55;
  letter-spacing: -.016em;
  max-width: 62ch;
  color: var(--ink-mid);
}
.lead b { font-weight: 600; color: var(--charcoal); }
html[lang="ar"] .lead { letter-spacing: 0; }
/* A lead sitting directly on the prose that follows it had no gap at all,
   while the paragraphs inside that prose were 16px apart -- so the seam
   between two different kinds of sentence read tighter than the seam
   between two of the same kind. Affects the product page and each
   capability theme. */
.lead + .prose { margin-block-start: 18px; }

/* One canonical pain sentence, set as a recognition line. */
.recognise {
  border-inline-start: 3px solid var(--teal);
  padding-inline-start: 18px;
  padding-block: 4px;
  margin-block-end: 26px;
  font-size: clamp(16px, 1.55vw, 19px);
  line-height: 1.5;
  letter-spacing: -.02em;
  color: var(--charcoal);
  font-weight: 500;
  max-width: 52ch;
}
.recognise em { font-style: normal; color: var(--gray); }
html[lang="ar"] .recognise { letter-spacing: 0; max-width: none; }

/* An unsoftened statement of fact. Carries the stop-recommendation. */
.stopnote {
  margin-block-start: 22px;
  border-inline-start: 3px solid var(--teal);
  padding-inline-start: 16px;
  padding-block: 2px;
  font-size: 14.5px;
  line-height: 1.55;
  max-width: 66ch;
}
.stopnote b { font-weight: 650; }

/* Client quotes are the one place a serif appears in this system. */
.quote {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(16px, 1.5vw, 19px);
  line-height: 1.5;
  color: var(--charcoal);
  margin: 0;
  max-width: 54ch;
}
/* Was `.quote footer`. A <footer> inside a <blockquote> is still announced as
   a page-level contentinfo landmark, and /proof/ carries six quotes -- so the
   site's longest page offered six "footer" landmarks and the rotor was
   useless on it. <cite> is what this actually is. */
.quote__by {
  font-family: var(--font-sans);
  font-style: normal;
  font-size: 12.5px;
  color: var(--gray);
  margin-block-start: 12px;
  letter-spacing: .02em;
}
.quote__by cite { font-style: normal; }
/* A plain hyphen, not an em-dash: the house rule is that no dash other than a
   hyphen reaches a visitor, and generated content is still text a visitor
   reads. */
.quote__by::before { content: "-\00a0"; }
html[lang="ar"] .quote { font-family: var(--font-arabic); font-style: normal; }

/* --------------------------------------------------------------------------
   Dark bands and the closing CTA
   -------------------------------------------------------------------------- */

.band-navy { background: var(--navy); color: #fff; }
.band-navy .shell { border-inline-color: rgba(255, 255, 255, .12); }
.band-navy .lbl { color: rgba(255, 255, 255, .5); }
.band-navy h2 { color: #fff; }
.band-navy .btn { background: var(--teal); border-color: var(--teal); }
.band-navy .btn:hover { background: #fff; border-color: #fff; color: var(--navy); }
.band-navy .btn--ghost { background: transparent; color: #fff; border-color: rgba(255, 255, 255, .3); }
.band-navy .btn--ghost:hover { border-color: #fff; color: #fff; }
.band-navy .promise { color: rgba(255, 255, 255, .6); }
.band-navy .promise b { color: rgba(255, 255, 255, .9); }

.close { padding-block: clamp(40px, 5vw, 64px); }
.close__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 60px);
  align-items: start;
}
@media (max-width: 900px) {
  .close__grid { grid-template-columns: minmax(0, 1fr); }
}
.close h2 { font-size: var(--step-3); letter-spacing: -.032em; max-width: 24ch; }
.close__grid p:not(.promise) {
  color: rgba(255, 255, 255, .72);
  font-size: 15px;
  max-width: 56ch;
  margin-block-start: 16px;
  line-height: 1.6;
}
/* The CTAs already carry their own top margin for the stacked case; in the
   two-column case they head their own column and the margin is dead space. */
@media (min-width: 901px) {
  .close__act .ctas { margin-block-start: 4px; }
}
html[lang="ar"] .close h2 { letter-spacing: 0; max-width: none; }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
  background: var(--charcoal);
  color: rgba(247, 246, 243, .62);
  padding-block: 44px 34px;
  font-size: var(--step--1);
}
.site-footer .shell { border-inline-color: rgba(247, 246, 243, .1); }
/* Five columns: the identity block, then the offer, the evidence, the
   publications and the calculators. The publications column was added on
   18 September 2026 -- all three PDFs were being built and served and only
   two were linked from anywhere, so the whitepaper existed at a URL and
   nowhere else.

   The identity column is 1.4fr rather than 1.5fr now. With five columns at
   1.5 it was taking enough width that "Municipal, Rural Affairs" in the
   Arabic link lists wrapped to three lines. */
.foot {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(4, minmax(0, 1fr));
  gap: 30px;
}
.foot h2 {
  font-size: var(--label);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(247, 246, 243, .42);
  margin-block-end: 14px;
  font-weight: 600;
}
html[lang="ar"] .foot h2 { letter-spacing: .04em; text-transform: none; }
.foot ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.foot a { color: rgba(247, 246, 243, .78); }
.foot a:hover { color: var(--teal-lit); }
.foot .wordmark { margin-block-end: 16px; height: 22px; }
.foot p { line-height: 1.6; max-width: 42ch; font-size: 12.5px; }
.legal {
  margin-block-start: 34px;
  padding-block-start: 18px;
  border-top: 1px solid rgba(247, 246, 243, .13);
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 11.5px;
  color: rgba(247, 246, 243, .45);
}

/* --------------------------------------------------------------------------
   Responsive. The page body must never scroll sideways: wide tables and
   diagrams get their own .scroll-x wrapper instead.
   -------------------------------------------------------------------------- */

/* A table wider than its column scrolls sideways inside this. On a touch
   device the scrollbar is an overlay that appears only mid-gesture, so a
   clipped column reads as broken text rather than as more table -- hence a
   persistent thin bar rather than the platform default. The real answer for
   the widest table is to stop it needing a scroll at all, which .rt--stack
   does below. */
.scroll-x {
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
  /* Anchors the scroll position to a column edge rather than mid-cell. */
  scroll-snap-type: inline proximity;
}

/* A grid item's default min-width is auto, which is its content's max-content
   width -- so a wide table inside a one-column .sec__grid pushed its own
   track wider than the viewport, and .scroll-x never got a constrained parent
   to scroll inside. /frameworks/ rendered its body 712px wide at 390px and
   ran its sentences off the screen mid-word. This is the rule that lets
   .scroll-x do its job, and it has to sit outside the media query because the
   two-column layout has the same exposure. */
.sec__grid > * { min-width: 0; }

/* Anchor targets clear the sticky header, and on /proof/ the sticky shape
   rail under it too. Without this a jump link lands with its heading hidden
   behind the header, which reads as the link having gone to the wrong
   place. */
:target { scroll-margin-top: calc(var(--header-h) + 56px); }

/* The nav collapses here. It was 1060px, which hid the whole navigation on
   every 1024-wide tablet in landscape and on every part-width laptop window
   -- and the commercial review of 16 September 2026, reading at 1000px,
   concluded that ten of eleven pages were invisible to most visitors. The
   row is six shorter labels now where it was seven longer ones, so it fits
   comfortably down to here. */
@media (max-width: 900px) {
  /* The header grows here: the touch-size rules below give its controls a
     44px minimum. */
  :root { --header-h: 74px; }
  .sec__grid { grid-template-columns: 1fr; gap: 22px; }
  .sec__ttl, .sec__note { max-width: none; }
  .foot { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nav a:not(.nav__cta) { display: none; }

  /* Touch widths. The header's three surviving controls were 38, 37 and 29px
     tall, which is under the 44px a thumb needs and under even the 24px WCAG
     2.5.8 floor in one case. Height is added around the ink rather than to
     it, so nothing about the type changes. */
  .nav a.nav__cta,
  .navmob > summary,
  .lang {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
}

@media (max-width: 620px) {
  /* The header row does not wrap, and below about 620px wordmark + Menu +
     language + CTA no longer fit: the CTA was pushed past the right edge, so
     the site's primary conversion control was half off-screen and every page
     carried a horizontal scrollbar. The language switch is the item to drop,
     because it is duplicated inside the Menu disclosure and a reader who
     wants Arabic will find it there. */
  .nav .lang-form { display: none; }
  .head { gap: 10px; }
}

@media (max-width: 560px) {
  .foot { grid-template-columns: 1fr; }
  .metabar__in .lbl:last-child { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
  html { scroll-behavior: auto; }
}

@media print {
  .site-header, .metabar, .lang, .skip-link { display: none; }
  body { background: #fff; }
}
