/* ==========================================================================
   Page components.

   Carried over from the approved design mockup, with every directional
   property rewritten as a logical one so Arabic is a dir="rtl" flip rather
   than a stylesheet fork.

   The mockup is _untracked/design-options/home-a2-dossier-interlock.html --
   kept on disk as the visual reference but out of the repo, because it
   carries 8MB of duplicated logo masters.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero {
  border-bottom: 1px solid var(--rule);
  padding-block: clamp(36px, 4.4vw, 68px) clamp(32px, 3.8vw, 52px);
  /* The geometry ground is absolutely positioned inside this, and the hero
     is the only full-bleed element on the page that has one.

     overflow: hidden is load-bearing, not tidiness. The ground is inset
     beyond the section on every side so it has room to parallax without
     revealing an edge, which makes it wider than its parent -- and an
     element that overhangs its parent still counts toward the document
     scrollWidth unless the parent clips it. Without this the home page
     carried a horizontal scrollbar at every width. */
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
.hero > .shell { position: relative; z-index: 1; }
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 58px);
  align-items: center;
}

/* The h1: the category, in one line, as the first thing on the page.

   It was the third element and the second-largest; it is now the first and
   the largest. Message House 2a records the reversal -- recognition needs a
   reader who has already placed the company, and the sentence that places us
   was the fifth element a visitor met.

   Capped below --step-4's 55px for the same reason the pain line was: at
   full size a two-clause category ran to three lines and pushed both buttons
   under the fold at 1440x900. */
.hero__h1 {
  font-size: clamp(31px, 4vw, 52px);
  font-weight: 700;
  letter-spacing: -.038em;
  line-height: 1.02;
  max-width: 20ch;
}
html[lang="ar"] .hero__h1 { letter-spacing: 0; line-height: 1.28; max-width: 22ch; }

/* One canonical pain line, as the subhead. Never four: four stacked read as
   a brochure, one reads as recognition.

   It is a <p> now rather than the h1, so it loses the heading weight and
   keeps the emphasis colour on its tail. Sized between the h1 and the body
   so it reads as the second thing rather than as a caption. */
.pain {
  margin-block-start: clamp(15px, 1.8vw, 22px);
  font-size: clamp(17px, 1.7vw, 22px);
  font-weight: 500;
  color: var(--ink-mid);
  letter-spacing: -.017em;
  line-height: 1.42;
  max-width: 40ch;
}
/* 3.42:1 on --paper at this size, and the emphasis is now the second half of
   the sentence rather than a different-coloured headline. Was #8A9199, which
   is 2.95:1 -- under the 3:1 floor. */
.pain em { font-style: normal; color: var(--charcoal); font-weight: 600; }
html[lang="ar"] .pain { letter-spacing: 0; line-height: 1.75; max-width: 46ch; }

/* --------------------------------------------------------------------------
   Figures in the hero: the mark drawn as a construction diagram
   -------------------------------------------------------------------------- */

.fig__hd {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-block-end: 12px;
}
.fig__legend {
  margin: 14px 0 0;
  padding-block-start: 11px;
  border-top: 1px solid var(--rule);
}
.fig__legend div {
  display: flex;
  gap: 12px;
  padding-block: 5px;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink-soft);
}
.fig__legend dt { font-weight: 700; color: var(--navy); flex: none; width: 19px; }
.fig__legend div:last-child dt { color: var(--teal); }
.fig__legend dd { margin: 0; }
.fig figcaption {
  margin-block-start: 11px;
  padding-block-start: 11px;
  border-top: 1px solid var(--rule-soft);
  font-size: 12px;
  color: var(--gray);
  line-height: 1.5;
}

/* The .prov strip is gone. It was a bordered aside in the hero carrying the
   year 2016 at 34px and two sentences of operating history -- the eighth
   element on a screen that now has four. The claim survives as one sentence
   inside section 02, where the lane is being established and where a reader
   has a reason to care that this practice grew out of an engineering
   business. The content brief still calls it the one industrial credential a
   software consultancy structurally cannot claim; it did not have to be a
   box to be that. */

/* --------------------------------------------------------------------------
   The document vocabulary index.

   Naming the documents is the whole differentiator and it costs nothing --
   not one of the 79 firms surveyed names a single one of these.
   -------------------------------------------------------------------------- */

.vocab {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
  gap: 0 clamp(20px, 3vw, 44px);
  margin-block-start: 26px;
}
.vocab div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: baseline;
  border-bottom: 1px solid var(--rule-soft);
  padding-block: 9px;
  font-size: 14px;
}
.vocab div:hover { border-bottom-color: var(--teal); }
.vocab span {
  font-size: var(--label);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gray);
  font-weight: 600;
  flex: none;
}
html[lang="ar"] .vocab span { letter-spacing: .02em; text-transform: none; }

.sys {
  margin-block-start: 26px;
  padding-block-start: 18px;
  border-top: 1px solid var(--rule);
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
}
.sys b { font-size: 13.5px; font-weight: 600; margin-inline-end: 4px; }
.sys code {
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--navy);
  border: 1px solid var(--rule);
  padding: 4px 9px;
  background: var(--card);
  /* Product names stay left-to-right inside an Arabic paragraph. */
  unicode-bidi: isolate;
  direction: ltr;
}

/* --------------------------------------------------------------------------
   Breadth: what the same practice ships that is not paper.

   Deliberately quieter than the document vocabulary above it. It answers a
   misreading -- that this is a document-processing shop -- and a block that
   shouted would turn a correction into a second pitch, which is the
   horizontal drift the positioning rules out. Rule above, no card, no fill.
   -------------------------------------------------------------------------- */

.breadth {
  margin-block-start: 30px;
  padding-block-start: 20px;
  border-top: 1px solid var(--rule);
}
.breadth__lead {
  font-size: 14.5px;
  color: var(--ink-soft);
  line-height: 1.6;
  margin-block-start: 8px;
  max-width: 62ch;
}
/* ⚠ The cell edges are the panels' own borders, not a container colour
   showing through a 1px gap.

   This grid was `gap: 1px` over `background: var(--rule)` with a card fill
   per cell, which draws hairlines beautifully while the item count is a
   multiple of the column count and draws an empty grey rectangle the moment
   it is not. With five items in two columns the sixth cell showed the
   container through and read as a dimmed sixth block -- the identical
   pathology the note on .featlist below records, in a grid 280 lines
   earlier in this same file.

   It matters more here than there: this is the grid that carries the
   computer-vision and data-science evidence, which is the one thing the
   review said could not be found anywhere on the site. The section that is
   the answer was the section that looked unfinished.

   A real gap and a border per panel means an odd count is just an odd
   count. */
.breadth__list {
  margin-block-start: 20px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.breadth__list > div {
  background: var(--card);
  border: 1px solid var(--rule);
  padding: 15px 16px 16px;
}
@media (max-width: 620px) {
  .breadth__list { grid-template-columns: minmax(0, 1fr); }
}
.breadth__list dt {
  font-size: 13px;
  font-weight: 600;
  color: var(--navy);
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  align-items: baseline;
}
/* The figure, not the label, is what the eye should land on. Teal is reserved
   for exactly this across the whole site. */
.breadth__list dt span {
  font-size: 15px;
  font-weight: 700;
  color: var(--teal);
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}
.breadth__list dd {
  margin: 8px 0 0;
  font-size: 12.5px;
  color: var(--ink-soft);
  line-height: 1.55;
}

@media (max-width: 620px) {
  .breadth__list { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   The stage table. Duration, never price.
   -------------------------------------------------------------------------- */

.tbl { width: 100%; border-collapse: collapse; margin-block-start: 8px; }
.tbl caption {
  text-align: start;
  font-size: 12.5px;
  color: var(--gray);
  padding-block-end: 14px;
  line-height: 1.5;
}
.tbl th {
  text-align: start;
  font-size: var(--label);
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--gray);
  padding: 0 14px 10px 0;
  padding-inline: 0 14px;
  border-bottom: 1px solid var(--navy);
}
html[lang="ar"] .tbl th { letter-spacing: .03em; text-transform: none; }
.tbl :is(th, td):last-child { padding-inline-end: 0; text-align: end; white-space: nowrap; }
.tbl td {
  padding-block: 16px;
  padding-inline: 0 14px;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: top;
  font-size: 14.5px;
  line-height: 1.5;
}
.tbl tr:hover td { background: rgba(14, 124, 123, .035); }
.tbl .st { font-weight: 650; letter-spacing: -.018em; font-size: 15px; min-width: 15ch; }
.tbl .st small {
  display: block;
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--teal);
  margin-block-end: 5px;
}
html[lang="ar"] .tbl .st { letter-spacing: 0; }
html[lang="ar"] .tbl .st small { letter-spacing: .02em; text-transform: none; }
.tbl .q { color: var(--ink-soft); max-width: 56ch; }
.tbl .dur { font-weight: 600; color: var(--navy); }

/* --------------------------------------------------------------------------
   The results motif, in its full boxed form. Identical on the site, the
   proposal PDF, the case-study PDF and the deck.
   -------------------------------------------------------------------------- */

.results { border: 1px solid var(--navy); background: var(--card); }
.results__hd {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  align-items: baseline;
  flex-wrap: wrap;
  padding: 13px 18px;
  background: var(--navy);
  color: #fff;
}
.results__hd .lbl { color: rgba(255, 255, 255, .72); }
.results__hd strong { font-size: 13.5px; font-weight: 600; letter-spacing: -.01em; }
.results table { width: 100%; border-collapse: collapse; }
.results th {
  text-align: start;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--gray);
  padding: 11px 18px;
  border-bottom: 1px solid var(--rule);
}
html[lang="ar"] .results th { letter-spacing: .03em; text-transform: none; }
.results td { padding: 14px 18px; border-bottom: 1px solid var(--rule-soft); font-size: 14.5px; }
.results tr:last-child td { border-bottom: 0; }
.results .m { color: var(--ink-mid); line-height: 1.45; }
.results .b { color: var(--gray); white-space: nowrap; text-align: end; width: 1%; }
.results .a {
  color: var(--teal);
  font-weight: 700;
  white-space: nowrap;
  text-align: end;
  width: 1%;
  font-size: 16px;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.results__ft {
  padding: 12px 18px;
  border-top: 1px solid var(--rule);
  font-size: 12px;
  color: var(--gray);
  line-height: 1.5;
  background: var(--paper-2);
}
.results th:nth-child(n+2) { text-align: end; }

.aside-note {
  font-size: 13px;
  color: var(--gray);
  margin-block-start: 20px;
  display: flex;
  gap: 9px;
  align-items: flex-start;
  max-width: 66ch;
  line-height: 1.55;
}
.aside-note svg { flex: none; margin-block-start: 4px; }

/* --------------------------------------------------------------------------
   Method strip
   -------------------------------------------------------------------------- */

.method {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  margin-block-start: 26px;
}
.method div { background: var(--paper); padding: 18px 16px 20px; }
.method b {
  display: block;
  font-size: 14.5px;
  font-weight: 650;
  letter-spacing: -.02em;
  margin-block: 9px 6px;
}
.method p { font-size: 12.5px; color: var(--gray); line-height: 1.5; }
.method .k { font-size: 11px; font-weight: 700; color: var(--teal); letter-spacing: .1em; }
html[lang="ar"] .method b { letter-spacing: 0; }

/* --------------------------------------------------------------------------
   The delivery record
   -------------------------------------------------------------------------- */

.plot {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: clamp(22px, 3vw, 40px);
  align-items: start;
  margin-block-start: 26px;
}
.plot__box { border: 1px solid var(--rule); background: var(--card); padding: 12px; }
/* The map's key. A reading list rather than a table: there is no longer a
   second column to align, because the per-country counts came off -- they
   read as a concentration rather than a footprint, and three of the seven
   rows had no case-file figure to print. The library/founder split is now
   carried by the two headings instead of by a blank cell. */
.ckey .lbl { color: var(--gray); }
.ckey .lbl + ol { margin: 9px 0 20px; }
.ckey ol:last-child { margin-block-end: 0; }
.ckey ol { list-style: none; padding: 0; }
.ckey li {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 13.5px;
  padding-block: 7px;
  border-bottom: 1px solid var(--rule-soft);
}
.ckey li:last-child { border-bottom: 0; }
.ckey li span {
  color: var(--teal);
  font-weight: 700;
  font-size: 11px;
  flex: none;
  width: 1.1em;
  font-variant-numeric: tabular-nums;
}

.plot__cap { font-size: 12.5px; color: var(--gray); line-height: 1.6; margin-block-start: 14px; }
.plot__cap b { color: var(--charcoal); font-weight: 600; }

/* .notfor is gone with the sections it styled -- Home 08 and Engagement 08,
   both "Who this is not for". Retired as a device in the content brief's six
   industrial-lean rules: it reads as specialised to a reader who is already
   engaged and as a list of reasons to leave to a stranger three seconds into
   a first visit. It survives as a live qualifying question in a
   conversation, which is where it always worked. */

/* --------------------------------------------------------------------------
   The product page.

   Two components, both added because the page had argued its case well and
   described nothing. A visitor could read it end to end without learning
   that it was a product rather than a service, or one thing it does.

   .orient is the home page's three routes: the engagement model, the service
   lines and the product. It sits directly under the hero, where a first-time
   visitor is being introduced to the practice. All three cards carry the
   same ground -- one of them shaded would read as the recommendation, and
   which route is right depends on the reader, not on us.

   .feat answers the second: four groups of concrete capabilities in the
   buyer's own words. Modelled on .breadth__list, but the emphasis is on the
   name rather than on a figure, so no teal number.
   -------------------------------------------------------------------------- */

.orient {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  margin-block-start: 24px;
}
/* Column, so the link and the "you are here" marker can be pushed to the
   foot of every card and line up across the row whatever the text runs to. */
.orient > div { background: var(--card); padding: 16px 18px 18px; display: flex; flex-direction: column; }
.orient b {
  display: block;
  font-size: 14px;
  font-weight: 650;
  letter-spacing: -.016em;
  color: var(--charcoal);
  margin-block: 0 6px;
}
.orient p { font-size: 13px; color: var(--ink-soft); line-height: 1.55; }
/* Pushed to the foot of the card, so the three links sit on one line
   whatever each card's text runs to. */
.orient a { margin-block-start: auto; padding-block-start: 12px; font-size: 12.5px; font-weight: 600; }
html[lang="ar"] .orient b { letter-spacing: 0; }

.featgrp { margin-block-start: 34px; padding-block-start: 24px; border-top: 1px solid var(--rule); }
.featgrp:first-of-type { margin-block-start: 26px; padding-block-start: 0; border-top: 0; }
.featgrp__ttl {
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -.022em;
  color: var(--navy);
  line-height: 1.35;
  max-width: 46ch;
}
.featgrp__lead {
  margin-block-start: 8px;
  font-size: 14px;
  color: var(--ink-soft);
  line-height: 1.6;
  max-width: 64ch;
}
/* ⚠ This was called .feat and so is the home page's featured-record grid,
   800 lines further down. Two rules, one name, and the later one wins -- so
   this list was being laid out by `repeat(auto-fit, minmax(210px, 1fr))`:
   four columns at this width, six items, and the container's own grey
   background showing through the two empty cells in the last row. The review
   reported it as "the last two blocks dimmed", which is exactly what it
   looked like and nothing to do with any intent.

   Three columns, so six items make two clean rows. */
.featlist {
  margin-block-start: 18px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
}
.featlist > div { background: var(--card); padding: 15px 16px 16px; }
.featlist dt { font-size: 13px; font-weight: 650; color: var(--navy); line-height: 1.4; }
.featlist dd { margin: 7px 0 0; font-size: 12.5px; color: var(--ink-soft); line-height: 1.55; }
@media (max-width: 900px) { .featlist { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .featlist { grid-template-columns: minmax(0, 1fr); } }

/* Four delivery steps, not the five the method strip is built for. The
   narrower breakpoints below still catch it, because they target .method. */
.method--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 620px) {
  .feat { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   Prose blocks used across the interior pages
   -------------------------------------------------------------------------- */

.prose { max-width: 68ch; }
.prose p { font-size: 15px; line-height: 1.66; color: var(--ink-soft); }
.prose p + p { margin-block-start: 16px; }
.prose p b { color: var(--charcoal); font-weight: 600; }
.prose h2 {
  font-size: 19px;
  letter-spacing: -.022em;
  line-height: 1.25;
  margin-block: 28px 9px;
}
.prose h2:first-child { margin-block-start: 0; }
html[lang="ar"] .prose h2 { letter-spacing: 0; }
.prose h3 {
  font-size: var(--step-1);
  letter-spacing: -.024em;
  margin-block: 30px 12px;
  line-height: 1.25;
}
.prose h4 {
  font-size: 14.5px;
  letter-spacing: -.014em;
  margin-block: 24px 8px;
}
.prose ul, .prose ol { margin: 14px 0 0; padding-inline-start: 20px; }
.prose li { font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); }
.prose li + li { margin-block-start: 8px; }
html[lang="ar"] .prose :is(h3, h4) { letter-spacing: 0; }

/* A theme heading with the teal rule beneath it, per the brand's section
   header convention. */
.theme { margin-block-start: clamp(30px, 3.4vw, 44px); }
.theme:first-child { margin-block-start: 0; }
/* The claim sentence and the prose under it had no space between them, so the
   two ran together as one paragraph set in two sizes. Every other block on
   the site puts air after a lead; this one only ever styled `.theme > p`,
   and the prose sits inside a wrapper of its own. */
.theme > :is(.prose, .fig, .deflist) { margin-block-start: 18px; }
.theme > h3 {
  font-size: var(--step-2);
  letter-spacing: -.028em;
  line-height: 1.2;
  padding-block-end: 12px;
  border-bottom: 2px solid var(--teal);
  display: inline-block;
  margin: 0;
}
html[lang="ar"] .theme > h3 { letter-spacing: 0; }
.theme > p { margin-block-start: 16px; }

/* A short definition list, used for scope, deliverables and glossary rows */
.deflist { margin: 20px 0 0; }
.deflist div {
  display: grid;
  grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
  gap: clamp(12px, 2vw, 26px);
  padding-block: 13px;
  border-bottom: 1px solid var(--rule-soft);
}
.deflist dt { font-size: 13.5px; font-weight: 600; color: var(--charcoal); line-height: 1.4; }
.deflist dd { margin: 0; font-size: 13.5px; color: var(--ink-soft); line-height: 1.55; }

/* --------------------------------------------------------------------------
   Service line cards
   -------------------------------------------------------------------------- */

.group { margin-block-start: clamp(28px, 3.2vw, 40px); }
.group:first-child { margin-block-start: 0; }
.group > h3 {
  font-size: 15px;
  letter-spacing: .01em;
  padding-block-end: 10px;
  border-bottom: 1px solid var(--navy);
  color: var(--navy);
}
.lines { display: grid; gap: 0; }
.line { padding-block: 20px; border-bottom: 1px solid var(--rule-soft); }
.line__hd { display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap; }
.line__n { font-size: 11px; font-weight: 700; color: var(--teal); letter-spacing: .1em; }
.line h4 { font-size: 15.5px; letter-spacing: -.02em; }
html[lang="ar"] .line h4 { letter-spacing: 0; }
.line__depth {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--teal);
  border: 1px solid var(--teal);
  padding: 2px 7px;
}
html[lang="ar"] .line__depth { letter-spacing: .02em; text-transform: none; }
.line__says {
  margin-block-start: 12px;
  border-inline-start: 3px solid var(--before);
  padding-inline-start: 14px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--charcoal);
  max-width: 62ch;
}
.line__promise { margin-block-start: 12px; font-size: 14px; line-height: 1.55; color: var(--ink-soft); max-width: 68ch; }
.line__docs { margin-block-start: 12px; display: flex; gap: 7px; flex-wrap: wrap; }
.line__docs span {
  font-size: 11.5px;
  color: var(--gray);
  border: 1px solid var(--rule-soft);
  padding: 3px 8px;
  background: var(--card);
}
/* .line__proof and .line__honest are gone. They styled the two prose
   paragraphs the catalogue printed under every service line -- the
   strongest delivered proof, and the internal honest note. Both moved:
   the numbers to /case-studies/, the per-line detail to the service
   catalogue PDF. What a catalogue entry carries now is the offer and
   the documents it touches. The surviving .line__scope is a scope line
   on a depth block, which is a specification rather than a caveat. */

/* --------------------------------------------------------------------------
   The contact form
   -------------------------------------------------------------------------- */

.form { max-width: 620px; margin-block-start: 8px; }
.form__req { font-size: 12.5px; color: var(--gray); margin-block-end: 18px; }
.field { margin-block-end: 20px; }
.field label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--charcoal);
  margin-block-end: 7px;
}
.field :is(input, textarea, select) {
  width: 100%;
  font-family: inherit;
  font-size: 15px;
  color: var(--charcoal);
  background: var(--card);
  border: 1px solid var(--rule);
  padding: 11px 13px;
  line-height: 1.5;
}
.field :is(input, textarea, select):focus-visible { border-color: var(--teal); }
.field textarea { resize: vertical; min-height: 132px; }
.field__help { font-size: 12px; color: var(--gray); margin-block-start: 7px; line-height: 1.5; }
.field__err { font-size: 12.5px; color: #9E2A2B; margin-block-start: 7px; font-weight: 500; }
.field--bad :is(input, textarea, select) { border-color: #9E2A2B; }
.formerr {
  border: 1px solid #9E2A2B;
  background: rgba(158, 42, 43, .05);
  padding: 13px 16px;
  font-size: 13.5px;
  line-height: 1.55;
  margin-block-end: 22px;
  max-width: 620px;
}
.formerr ul { margin: 8px 0 0; padding-inline-start: 18px; }
.formerr li + li { margin-block-start: 4px; }
.formerr a { color: #9E2A2B; text-decoration: underline; }
.sent {
  border: 1px solid var(--teal);
  background: rgba(14, 124, 123, .06);
  padding: 18px 20px;
  max-width: 620px;
}
.sent h3 { font-size: var(--step-1); letter-spacing: -.02em; margin-block-end: 10px; }
.sent p { font-size: 14px; color: var(--ink-soft); line-height: 1.6; }
html[lang="ar"] .sent h3 { letter-spacing: 0; }

/* --------------------------------------------------------------------------
   Calculators
   -------------------------------------------------------------------------- */

.calc {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
  gap: clamp(20px, 2.6vw, 36px);
  align-items: start;
  margin-block-start: 26px;
}
.calc__in { border: 1px solid var(--rule); background: var(--card); padding: clamp(16px, 2vw, 22px); }
.calc__out { border: 1px solid var(--navy); background: var(--card); }
.calc__outhd { background: var(--navy); color: #fff; padding: 12px 18px; }
.calc__outhd strong { font-size: 13.5px; font-weight: 600; }
.calc__body { padding: clamp(14px, 1.8vw, 20px); }
.calc__row { margin-block-end: 16px; }
.calc__row:last-child { margin-block-end: 0; }
.calc__row label { display: block; font-size: 13px; font-weight: 600; margin-block-end: 6px; }
.calc__row input {
  width: 100%;
  font-family: inherit;
  font-size: 15px;
  border: 1px solid var(--rule);
  padding: 10px 12px;
  background: var(--paper);
  color: var(--charcoal);
  font-variant-numeric: tabular-nums;
}
.calc__row input[type="range"] { padding: 0; border: 0; background: transparent; accent-color: var(--teal); }
.calc__note { font-size: 11.5px; color: var(--gray); margin-block-start: 5px; line-height: 1.45; }
.calc__big {
  font-size: clamp(26px, 3.4vw, 40px);
  font-weight: 700;
  letter-spacing: -.035em;
  color: var(--teal);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.calc__biglbl { font-size: 12px; color: var(--gray); margin-block-start: 8px; line-height: 1.45; }
html[lang="ar"] .calc__big { letter-spacing: 0; }
.calc__basis {
  margin-block-start: 20px;
  padding-block-start: 16px;
  border-top: 1px solid var(--rule);
  font-size: 12px;
  color: var(--gray);
  line-height: 1.55;
}
.calc__basis b { color: var(--ink-soft); font-weight: 600; }

/* Explicitly two columns, not auto-fit. There are four instruments and there
   will be four for a while, so the column count is a design decision rather
   than something to leave to the viewport. auto-fit resolved to three at the
   shell width, which put one card alone on a second row beside two empty
   grid cells showing through as rule colour -- reading as two tools we failed
   to think of. Four in a square reads as four on purpose. */
.toolcards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  margin-block-start: 26px;
}
.toolcard { background: var(--card); padding: 20px 20px 22px; display: flex; flex-direction: column; }
/* min-height reserves the label's line so the titles below it stay on one
   line across the row. Without it, a label that wraps in one card -- a longer
   Arabic translation, a narrower column -- drops that card's title alone and
   the row reads as misaligned. Same guard as .tile__lbl in viz.css. */
.toolcard .lbl { color: var(--teal); min-height: 1.4em; }
.toolcard h3 { font-size: 17px; letter-spacing: -.024em; margin-block: 10px 0; }
.toolcard p { font-size: 13px; color: var(--ink-soft); line-height: 1.55; margin-block-start: 10px; flex: 1; }
.toolcard a { font-size: 13.5px; font-weight: 600; margin-block-start: 16px; display: inline-flex; gap: 8px; align-items: center; }
html[lang="ar"] .toolcard h3 { letter-spacing: 0; }

/* --------------------------------------------------------------------------
   Proof entries
   -------------------------------------------------------------------------- */

.study { padding-block: clamp(22px, 2.6vw, 32px); border-bottom: 1px solid var(--rule); }
.study:last-child { border-bottom: 0; }
.study__hd { display: flex; gap: 12px; justify-content: space-between; align-items: baseline; flex-wrap: wrap; }
.study h3 { font-size: var(--step-1); letter-spacing: -.024em; line-height: 1.3; }
.study h3 a { color: var(--charcoal); }
.study h3 a:hover { color: var(--teal); }
.study__meta { font-size: 11.5px; color: var(--gray); letter-spacing: .01em; }
/* One column. This was a two-up grid, prose beside figure-and-table, which
   gave the results table half the shell to fit a three-column table with a
   sentence in the first column: measures wrapped to eight lines and long
   after-values pushed the table into a sideways scroll. The prose keeps a
   readable measure; the table takes the full column and now fits. */
.study__body { margin-block-start: 14px; display: grid; gap: 16px; }
.study__p { font-size: 14px; line-height: 1.6; color: var(--ink-soft); max-width: 74ch; }
.study__bridge {
  margin: 0;
  max-width: 74ch;
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink-mid);
  border-inline-start: 3px solid var(--teal);
  padding-inline-start: 14px;
}
.study__bridge b { color: var(--charcoal); font-weight: 600; }
.study__more { margin: 0; font-size: 13.5px; font-weight: 600; }

/* The rest of a shape's records. One row each: what it is, the sector it was
   built in, and its strongest figure -- enough to decide whether to open it,
   and no more. The full table is on the record's own page. */
.rest__h {
  font-size: var(--label);
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--gray);
  margin-block-start: clamp(26px, 3vw, 38px);
  padding-block-end: 10px;
  border-bottom: 1px solid var(--rule);
}
html[lang="ar"] .rest__h { letter-spacing: .03em; text-transform: none; }
.rest { margin: 0; padding: 0; list-style: none; }
.rest li {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 4px clamp(14px, 2vw, 28px);
  align-items: baseline;
  padding-block: 13px;
  border-bottom: 1px solid var(--rule-soft);
}
/* The title is the link, and it looks like one at rest. Styled as body text
   with the colour only appearing on hover, these 31 rows read as inert on a
   desktop and were invisible as links on a touch screen, where there is no
   hover -- so the largest part of the evidence library had nothing inviting
   a reader into it. */
.rest__t {
  grid-column: 1;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--teal-deep);
  line-height: 1.35;
  border-bottom: 1px solid var(--rule);
  padding-block-end: 1px;
}
.rest__t:hover { color: var(--teal); border-bottom-color: var(--teal); }
.rest li { position: relative; }
/* The whole row is the target, not just the words. */
.rest__t::after { content: ""; position: absolute; inset: 0; }
.rest__m {
  grid-column: 1;
  grid-row: 2;
  font-size: 11.5px;
  color: var(--gray);
  line-height: 1.4;
}
.rest__v {
  grid-column: 2;
  grid-row: 1 / span 2;
  font-size: 13.5px;
  color: var(--ink-soft);
  line-height: 1.4;
  font-variant-numeric: tabular-nums;
}
.rest__v b { color: var(--teal); font-weight: 650; }
.rest__v small { display: block; font-size: 11.5px; color: var(--gray); margin-block-start: 3px; }

@media (max-width: 620px) {
  .rest li { grid-template-columns: minmax(0, 1fr); }
  .rest__v { grid-column: 1; grid-row: auto; margin-block-start: 6px; }
}
html[lang="ar"] .study h3 { letter-spacing: 0; }

.asset-tag {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 2px 7px;
  border: 1px solid var(--rule);
  color: var(--gray);
  white-space: nowrap;
}
.asset-tag--own { border-color: var(--teal); color: var(--teal); }
html[lang="ar"] .asset-tag { letter-spacing: .02em; text-transform: none; }

/* --------------------------------------------------------------------------
   Glossary
   -------------------------------------------------------------------------- */

/* The gridlines are borders on the cells, not a background showing through
   1px gaps. With the background trick, 20 terms in a three-column grid left
   one cell unfilled and the rule colour painted through it as a 325x172
   block, which read as a card that had failed to load. Borders draw nothing
   where there is no cell. */
.terms {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  border: 1px solid var(--rule);
  border-width: 1px 0 0 1px;
  margin-block-start: 24px;
  background: var(--card);
}
.term {
  background: var(--card);
  padding: 17px 18px 19px;
  border: 1px solid var(--rule);
  border-width: 0 1px 1px 0;
}
.term h3 { font-size: 15px; letter-spacing: -.02em; line-height: 1.3; }
.term h3 a { color: var(--charcoal); }
.term h3 a:hover { color: var(--teal); }
.term p { font-size: 12.5px; color: var(--gray); line-height: 1.55; margin-block-start: 9px; }
html[lang="ar"] .term h3 { letter-spacing: 0; }

/* The .cmp* comparison cards went with /compare/. The page was "Four
   alternatives, honestly" plus "Why there is no price on this site", and
   both are the register the Message House now rules off every public
   surface. Its one real claim -- the content-layer survey across 79 firms,
   most of whose cells read zero or one -- moved to Services section 02 and
   still uses the .smalls grid in viz.css. */

/* --------------------------------------------------------------------------
   Mobile navigation.

   The desktop nav collapses below 900px. Without this it would simply
   disappear, which would leave a keyboard or phone reader with the CTA and
   nothing else -- so the same links come back as a disclosure. <details> is
   used deliberately: it needs no JavaScript and is keyboard-operable for
   free.
   -------------------------------------------------------------------------- */

.navmob { display: none; }
.navmob > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--charcoal);
  border: 1px solid var(--rule);
  padding: 8px 12px;
}
.navmob > summary::-webkit-details-marker { display: none; }
.navmob[open] > summary { border-color: var(--teal); color: var(--teal); }
.navmob__panel {
  position: absolute;
  inset-inline: 0;
  background: var(--paper);
  border-block: 1px solid var(--rule);
  padding: 6px var(--pad) 14px;
  display: grid;
  gap: 2px;
  z-index: 45;
}
.navmob__panel a {
  color: var(--charcoal);
  font-size: 14.5px;
  padding-block: 10px;
  border-bottom: 1px solid var(--rule-soft);
}
.navmob__panel a[aria-current="page"] { color: var(--teal); font-weight: 600; }
/* The language switch, which leaves the header row below 620px. It sits under
   the links rather than among them because it changes the page you are on
   rather than navigating to a new one. */
/* --------------------------------------------------------------------------
   The shape rail on /proof/. A 27-screen page needs somewhere to stand.
   -------------------------------------------------------------------------- */

.shapenav {
  position: sticky;
  /* Under the site header, which is itself sticky at top: 0. The token is
     pinned to the header's min-height, so this cannot drift out of register
     the way a hard-coded 53px did. */
  top: var(--header-h);
  z-index: 30;
  background: rgba(247, 246, 243, .95);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.shapenav__in {
  display: flex;
  align-items: baseline;
  gap: 10px clamp(14px, 2vw, 26px);
  flex-wrap: wrap;
  padding-block: 10px;
}
.shapenav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 6px clamp(12px, 2vw, 24px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.shapenav a {
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 500;
  border-bottom: 1px solid transparent;
  padding-block: 5px;
  display: inline-block;
}
.shapenav a:hover { color: var(--navy); border-bottom-color: var(--teal); }
/* Below the desktop nav breakpoint the label goes and the four links become
   one horizontally scrollable row. Wrapping instead cost 160px of an 844px
   phone screen, permanently, on the site's longest page. */
@media (max-width: 760px) {
  .shapenav .lbl { display: none; }
  .shapenav__in { padding-block: 4px; }
  .shapenav ul {
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 18px;
    /* Room for the scroll affordance, and the row keeps its own edge padding
       when it scrolls. */
    padding-inline-end: 18px;
    scrollbar-width: none;
  }
  .shapenav ul::-webkit-scrollbar { display: none; }
  .shapenav a { font-size: 12.5px; white-space: nowrap; min-height: 40px; }
}

/* The function index at the head of the capabilities catalogue. Same job as
   the shape rail on /proof/, not sticky: these are the page's own sections
   rather than a filter over a long list. */
.grouplist {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px clamp(14px, 2vw, 24px);
  padding-block: 14px;
  border-block: 1px solid var(--rule);
  margin-block-end: clamp(22px, 2.6vw, 32px);
}
.grouplist ul {
  display: flex;
  flex-wrap: wrap;
  gap: 6px clamp(12px, 2vw, 22px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.grouplist a {
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 500;
  border-bottom: 1px solid transparent;
  padding-block: 6px;
  display: inline-block;
}
.grouplist a:hover { color: var(--navy); border-bottom-color: var(--teal); }

.navmob__panel .lang-form { margin-block-start: 12px; }
.navmob__panel .lang { min-height: 44px; }
html[lang="ar"] .navmob > summary { letter-spacing: .02em; text-transform: none; }

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

/* The lead figure above a study's results table on the Proof page. Flat --
   no card, no border -- because it sits inside the study block, which
   already has its own frame, and a box inside a box reads as a mistake. */
.study__fig { margin: 0; }


@media (max-width: 900px) {
  .hero__grid { grid-template-columns: 1fr; }
  .hero .fig { max-width: 430px; }
  .plot, .calc { grid-template-columns: 1fr; }
  .method { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .navmob { display: block; margin-inline-start: auto; }
  .nav { margin-inline-start: 0; }
}

@media (max-width: 720px) {
  .deflist div { grid-template-columns: 1fr; gap: 4px; }
}

@media (max-width: 560px) {
  .method { grid-template-columns: 1fr; }
  /* Two columns of a four-card grid is right down to tablet width; on a
     phone the cards are narrower than their own titles. */
  .toolcards { grid-template-columns: minmax(0, 1fr); }
  .tbl :is(th, td):last-child { text-align: start; }
  .tbl, .tbl tbody, .tbl tr, .tbl td { display: block; width: 100%; }
  .tbl thead { display: none; }
  .tbl tr { border-bottom: 1px solid var(--rule); padding-block: 14px; }
  .tbl td { border: 0; padding-block: 2px; padding-inline: 0; }

  /* This rule used to read `.pain { font-size: clamp(27px, 8.4vw, 34px) }`,
     from when .pain WAS the h1 and wanted to be the largest thing on a phone.
     It survived the hero rebuild and made the subhead 31.5px against an h1 of
     31px -- two elements the same size, one of them seven lines long, which
     put both buttons 571px down a 812px screen. The h1 is the headline now
     and the subhead is a subhead at every width. */
  .hero__h1 { font-size: clamp(26px, 7.6vw, 31px); }
  .pain { font-size: 16.5px; line-height: 1.5; max-width: none; }
}


/* ==========================================================================
   Added 17 September 2026, in the marketing-surface rebuild.

   Everything below answers one of the seven findings in
   10-website/WEBSITE-REVIEW.md: the client band and the featured records
   answer "nothing proves the company exists", the product figures answer
   "there is no product", the purpose block and the index answer "services
   and case studies are not visible", and the reveal hooks answer "everything
   is the same size".
   ========================================================================== */

/* --------------------------------------------------------------------------
   Abstract geometry, as page ground.

   Charcoal and navy hairlines at 4-9% opacity. No teal: brand-guidelines.md
   reserves the accent for metrics, links, CTAs and highlighted numbers and
   forbids it as a dominant field, and the palette decision explicitly
   rejects a bold gradient treatment as the wrong signal for ministry and
   bank buyers. What the motion carries is depth, and it stops there.
   -------------------------------------------------------------------------- */

/* The field ground is parallaxed by motion.js, so it needs room to move
   without revealing an edge: it is inset beyond the section on every side. */
.geo--field { inset: -14% -4%; }
.geo {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.geo svg { width: 100%; height: 100%; display: block; }

/* ⚠ These opacities were 3.8% to 9% and were reviewed as "barely
   noticeable", which was accurate. A hairline at 5% on this paper ground is
   below the threshold at which a viewer registers a line at all, so the
   grounds were costing a request and delivering nothing.

   The range is now 6% to 16%. The ceiling is set by contrast rather than by
   taste: --ink-soft body copy over a 16% navy hairline still clears 4.5:1,
   and a stroke over that starts to read as content. Nothing here is teal and
   nothing is a gradient -- brand-guidelines.md rule 2 of the Motion section
   binds the palette, not the amplitude. */
.geo-hair { fill: none; stroke: var(--navy); stroke-width: 1; opacity: .15; }
.geo-hair--soft { opacity: .085; }
.geo-hair--lit { stroke: #fff; opacity: .17; }
.geo-ring { fill: none; stroke: var(--navy); stroke-width: 1; opacity: .13; }
.geo-ring--soft { opacity: .075; }
.geo-ring--lit { stroke: #fff; opacity: .15; }
.geo-box { fill: none; stroke: var(--charcoal); stroke-width: 1; opacity: .105; }
.geo-box--soft { opacity: .062; }
.geo-dot { fill: var(--navy); opacity: .13; }
.geo-dot--lit { fill: #fff; opacity: .16; }
/* A hairline that ends rather than crossing the whole plate. Used by the
   rays ground, where a line running edge to edge would fight the text. */
.geo-hair--cap { stroke-linecap: round; }

/* Grounds for the new plates. Each is positioned by the section that hosts
   it, and every host clips -- see the note on .hero above: a ground is inset
   past its section so it has room to drift, and an overhang its parent does
   not clip lands in the document scrollWidth. There is a guard test. */
.geo--rays { inset: -20% -6%; }
.geo--dots { inset: 0; }
.geo--arc { inset: -30% -18% -30% auto; width: min(560px, 58%); inset-inline-end: -8%; inset-inline-start: auto; }

/* The mesh ground sits inside a section rather than behind a full-bleed
   band, so it needs a containing block and a little inset. */
/* ⚠ .sec--purpose is retired. It was the clipping host for the mesh ground
   on Home's mission section; that section is on the dark plate now and the
   mesh moved to the privacy notice, where .sec--tint is the host. The class
   is also the pattern the plate system replaced -- it named a section rather
   than a treatment, so every ground needed its own selector and its own
   clipping rule. There are four plate rules now and any number of
   sections. */
.geo--mesh { inset: auto 0 0 0; height: 62%; }

/* The closing band's ground. Rings on navy, so the strokes are white at low
   opacity rather than dark. */
.close { position: relative; isolation: isolate; overflow: hidden; }
.close > .shell { position: relative; z-index: 1; }
.geo--orbit {
  inset: -40% -10% -40% auto;
  width: min(620px, 62%);
  inset-inline-end: -6%;
  inset-inline-start: auto;
}

/* --------------------------------------------------------------------------
   The client band.

   Named organisations, auto-scrolling, with a real pause control. WCAG 2.2.2
   requires anything moving for more than five seconds to be pausable, and a
   hover-only pause does not exist on a phone.

   The band renders nothing when the list is empty -- that is enforced in the
   template, not here, because an unpopulated credibility element is worse
   than its absence and CSS cannot make that decision.
   -------------------------------------------------------------------------- */

.clients {
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
  padding-block: clamp(20px, 2.2vw, 28px);
  overflow: hidden;
}
.clients__hd {
  display: flex;
  align-items: baseline;
  gap: 8px 18px;
  flex-wrap: wrap;
  margin-block-end: 16px;
}
.clients__hd h2 { font-size: var(--label); margin: 0; letter-spacing: .15em; font-weight: 600; text-transform: uppercase; color: var(--gray); }
html[lang="ar"] .clients__hd h2 { letter-spacing: .04em; text-transform: none; }
.clients__note { font-size: 12.5px; color: var(--gray); margin: 0; }
.clients__btn {
  margin-inline-start: auto;
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--gray);
  background: transparent;
  border: 1px solid var(--rule);
  padding: 6px 12px;
  cursor: pointer;
  /* 44px at touch widths is handled in the responsive block below rather
     than here, so the control stays small on a desktop where it is a
     secondary affordance. */
}
.clients__btn:hover,
.clients__btn:focus-visible { border-color: var(--teal); color: var(--teal-deep); }
html[lang="ar"] .clients__btn { letter-spacing: 0; text-transform: none; }

/* The viewport masks the track; the mask fades both edges so an entry
   entering or leaving does not appear to be cut in half by the shell. */
.clients__vp {
  position: relative;
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
}
/* The track lays out left to right in both languages, and the wrapper forces
   it. The entries are registered organisation names in Latin script, which
   read left to right whatever the page direction -- and in RTL the flex
   track was being laid out from the right edge while the -50% translate
   moved it further left, which put the whole strip about 11,600px off screen.
   The Arabic page rendered a band with a heading, a note, a pause button and
   no names in it.
 
   Only the layout is flipped back; the scroll direction still follows the
   reading direction, in motion.css. */
.clients__vp { direction: ltr; }
.clients__track { display: flex; width: max-content; }
/* Neither the first row nor the aria-hidden duplicate may shrink, or the two
   halves stop being the same width and the -50% loop visibly jumps. */
.clients__track > * { flex: none; }
.clients__row {
  display: flex;
  align-items: center;
  gap: clamp(28px, 4vw, 64px);
  margin: 0;
  padding: 0 clamp(14px, 2vw, 32px) 0 0;
  list-style: none;
}
/* Each entry is two rows: the mark, then the jurisdiction under it.

   A grid with a FIXED first row rather than a flex column, and that is the
   whole point. As a centred flex column each item sized itself to its own
   content, so a 30px wordmark, a 46px crest and a two-line lockup each
   centred inside a different height and the three jurisdiction lines under
   them landed at three different heights. A row of client names with its
   small print at three heights reads as untidy, which is the opposite of
   what a client band is for.

   46px is the tallest mark in the set, so the first row fits every one of
   them and every mark is optically centred in the same box. */
.clients__row li {
  display: grid;
  grid-template-rows: 46px auto;
  justify-items: start;
  align-items: center;
  gap: 4px;
  flex: none;
}
/* Grayscale at rest and colour on hover. Twenty-three marks in twenty-three
   palettes is a fruit salad, and the band is meant to read as one list of
   names rather than as a collection of brands. */
.clients__row img { height: 30px; width: auto; opacity: .62; filter: grayscale(1); }
.clients__row li:hover img { opacity: 1; filter: none; }

/* A stacked lockup or a crest, rather than a horizontal wordmark. At 30px a
   crest is a smudge and a two-line lockup is two smudges, so these get
   height instead -- which is why .clients__row li has a min-height that
   accommodates the taller one: the doubled marquee track must be exactly
   the same height in both halves or the -50% loop steps vertically. */
.cli--tall { height: 46px !important; }

/* The type fallback for an entry with no usable logo file. It has to sit at
   the same optical weight as the images beside it, or a mixed row reads as
   scavenged rather than as a design. */
.cli__t {
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: -.012em;
  color: var(--navy);
  opacity: .72;
  white-space: nowrap;
  display: block;
}
.clients__row li:hover .cli__t { opacity: 1; }

/* The jurisdiction. Small, quiet, and never absent: eight of these names
   exist in most countries and the band was asking a stranger to guess which
   Ministry of Commerce it meant. See the docstring in
   pages/copy/clients.py.

   nowrap because the band scrolls horizontally and a wrapped country name
   changes the height of one item, which changes the height of the track,
   which makes the loop jump at the halfway point. */
.cli__c {
  display: block;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: .045em;
  text-transform: uppercase;
  color: var(--gray);
  opacity: .78;
  white-space: nowrap;
}
html[lang="ar"] .cli__c { letter-spacing: 0; text-transform: none; font-size: 11px; }

/* --------------------------------------------------------------------------
   Mission and vision
   -------------------------------------------------------------------------- */

.purpose { margin: 0; display: grid; gap: clamp(18px, 2.4vw, 30px); }
.purpose > div { border-top: 2px solid var(--navy); padding-block-start: 14px; }
.purpose > div:last-child { border-top-color: var(--rule); }
.purpose dt { margin-block-end: 10px; }
.purpose dd {
  margin: 0;
  font-size: var(--step-2);
  font-weight: 500;
  line-height: 1.38;
  letter-spacing: -.02em;
  color: var(--charcoal);
  max-width: 34ch;
}
.purpose > div:last-child dd { color: var(--ink-mid); }
html[lang="ar"] .purpose dd { letter-spacing: 0; line-height: 1.7; max-width: 40ch; }

/* On About the two statements sit beside the interlock diagram. */
.purpose__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .82fr);
  gap: clamp(24px, 3.4vw, 48px);
  align-items: start;
}

/* --------------------------------------------------------------------------
   Featured records, on the home page
   -------------------------------------------------------------------------- */

.feat {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  margin-block-start: 24px;
}
.feat__c { background: var(--card); padding: 18px 18px 20px; display: flex; flex-direction: column; }
.feat__c .lbl { color: var(--teal-deep); min-height: 2.8em; }
.feat__c h3 { font-size: 16px; letter-spacing: -.022em; line-height: 1.28; margin-block: 10px 0; }
.feat__c h3 a { color: var(--charcoal); }
.feat__c h3 a:hover { color: var(--teal); }
.feat__sec { font-size: 12px; color: var(--gray); margin-block-start: 6px; flex: 1; }
.feat__m {
  margin-block-start: 14px;
  padding-block-start: 12px;
  border-top: 1px solid var(--rule-soft);
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}
.feat__m b { color: var(--teal-deep); font-weight: 700; }
.feat__m small { display: block; font-size: 11.5px; font-weight: 400; color: var(--gray); margin-block-start: 5px; line-height: 1.4; }

/* --------------------------------------------------------------------------
   Product figures.

   Drawings, never screenshots: the workspace is assembled from open-source
   parts and what those are is not a public fact, so a capture of the running
   system would identify them on sight. See templates/viz/product.html.
   -------------------------------------------------------------------------- */

.pf { margin: 0; }
.pf__svg { width: 100%; height: auto; }

/* The document. Paper against the card, with a turned corner so it reads as
   a sheet rather than a window. */
.pf-page { fill: var(--paper-2); stroke: var(--rule); stroke-width: 1; }
.pf-fold { fill: var(--paper); stroke: var(--rule); stroke-width: 1; }
.pf-ink { fill: var(--before); }
.pf-ink--h { fill: var(--navy); opacity: .5; }

/* The read fields. Grey for a resolved row, teal for the one that went to a
   person -- the same two-colour grammar as every chart on the site, where
   grey is the prior state and teal is the outcome. */
.pf-row rect { fill: var(--card); stroke: var(--rule); stroke-width: 1; }
.pf-row--flag rect { stroke: var(--teal); stroke-width: 1.4; }
.pf-k { font-family: var(--font-sans); font-size: 7px; font-weight: 600; fill: var(--charcoal); }
.pf-v { font-family: var(--font-sans); font-size: 6.4px; fill: var(--gray); }
.pf-row--flag .pf-v { fill: var(--teal-deep); font-weight: 600; }
.pf-flow { fill: none; stroke: var(--rule); stroke-width: 1.4; }
.pf-flow--flag { stroke: var(--teal); }
.pf-sys__top { fill: var(--paper-2); stroke: var(--navy); stroke-width: 1.2; opacity: .9; }
.pf-sys__body { fill: var(--card); stroke: var(--navy); stroke-width: 1.2; }
.pf-sys__rule { fill: none; stroke: var(--rule); stroke-width: 1; }
.pf-person { fill: none; stroke: var(--teal); stroke-width: 1.4; }

.pf__key {
  margin: 14px 0 0;
  padding-block-start: 12px;
  border-top: 1px solid var(--rule);
  display: grid;
  gap: 9px;
}
.pf__key div { display: flex; gap: 12px; font-size: 12.5px; line-height: 1.45; }
.pf__key dt { font-weight: 700; color: var(--navy); flex: none; width: 52px; }
.pf__key dd { margin: 0; color: var(--ink-soft); }
.pf__cap { margin-block-start: 12px; font-size: 12px; color: var(--gray); line-height: 1.55; }

/* The bilingual exchange. The direction switch inside one figure is the
   point being made, so the two paragraphs carry their own dir attributes in
   the markup and this only styles them. */
.pf-chat { border: 1px solid var(--rule); background: var(--card); padding: 16px 18px; display: grid; gap: 14px; }
.pf-chat p { margin: 0; font-size: 14.5px; line-height: 1.6; }
.pf-chat .lbl { display: block; margin-block-end: 6px; color: var(--gray); }
.pf-chat__q { color: var(--charcoal); font-weight: 500; }
.pf-chat__a {
  border-inline-start: 3px solid var(--teal);
  padding-inline-start: 14px;
  color: var(--ink-soft);
}
.pf-cite { margin: 0; padding: 0; list-style: none; display: grid; gap: 7px; }
.pf-cite li { display: flex; gap: 10px; align-items: baseline; font-size: 12.5px; color: var(--ink-soft); }
.pf-cite__n {
  flex: none;
  width: 17px; height: 17px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--teal);
  color: var(--teal-deep);
  font-size: 10.5px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* The workspace schematic. Real markup rather than SVG, because it is a
   layout and a layout drawn in SVG cannot reflow its own labels. */
.wsf { border: 1px solid var(--rule); background: var(--card); overflow: hidden; }
.wsf__bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 14px;
  background: var(--navy);
  color: #fff;
}
.wsf__dot { width: 8px; height: 8px; background: var(--teal-lit); flex: none; }
.wsf__ttl { font-size: 13px; font-weight: 600; }
.wsf__tag {
  margin-inline-start: auto;
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: rgba(255, 255, 255, .72);
  border: 1px solid rgba(255, 255, 255, .22);
  padding: 3px 8px;
}
.wsf__tag--lock { margin-inline-start: 0; color: var(--teal-lit); border-color: rgba(23, 163, 161, .4); }
html[lang="ar"] .wsf__tag { letter-spacing: 0; text-transform: none; }
.wsf__body { display: grid; grid-template-columns: minmax(0, 150px) minmax(0, 1fr); }
.wsf__rail { border-inline-end: 1px solid var(--rule); padding: 14px; background: var(--paper-2); }
.wsf__rail .lbl { display: block; margin-block-end: 8px; }
.wsf__rail ul { margin: 0 0 16px; padding: 0; list-style: none; display: grid; gap: 6px; }
.wsf__rail li { font-size: 12.5px; color: var(--ink-soft); padding: 4px 8px; }
.wsf__rail li.is-on { background: var(--card); color: var(--charcoal); font-weight: 600; box-shadow: inset 2px 0 0 var(--teal); }
html[dir="rtl"] .wsf__rail li.is-on { box-shadow: inset -2px 0 0 var(--teal); }
.wsf__who li { color: var(--gray); font-size: 12px; padding-inline: 8px; }
.wsf__main { padding: 16px; display: grid; gap: 10px; align-content: start; }
.wsf__msg { height: 11px; background: var(--paper-2); border-radius: 2px; width: 84%; }
.wsf__msg--them { background: rgba(14, 124, 123, .13); margin-inline-start: auto; width: 68%; }
.wsf__msg--short { width: 40%; }
.wsf__ask {
  margin-block-start: 8px;
  border: 1px dashed var(--rule);
  padding: 10px 12px;
  font-size: 12.5px;
  color: var(--gray);
}

/* --------------------------------------------------------------------------
   The case-study index table, and the PDF links
   -------------------------------------------------------------------------- */

.tbl--index th[scope="row"] { font-weight: 600; }
.tbl--index th[scope="row"] a { color: var(--charcoal); }
.tbl--index th[scope="row"] a:hover { color: var(--teal); }
.tbl--index td.after { font-variant-numeric: tabular-nums; color: var(--teal-deep); font-weight: 600; white-space: nowrap; }
.tbl--index td.after small { display: block; font-weight: 400; color: var(--gray); font-size: 11.5px; white-space: normal; margin-block-start: 3px; }

.study__more--pdf { margin-block-start: 26px; padding-block-start: 18px; border-top: 1px solid var(--rule); }

/* --------------------------------------------------------------------------
   Odds and ends
   -------------------------------------------------------------------------- */

/* The address, in the footer, on Contact, on About and on the privacy page.
   One of the eight verification checks a prospect runs, and the cheapest of
   them to answer truthfully. */
.foot__addr {
  margin-block-start: 14px;
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.6;
}
.foot__addr .lbl { display: block; margin-block-end: 3px; }
.site-footer .foot__addr { color: rgba(247, 246, 243, .72); }
.site-footer .foot__addr .lbl { color: rgba(247, 246, 243, .5); }

/* A scope line under a depth block: the sector the delivered systems ran in,
   which a reader needs in order to read the figures above correctly. Quieter
   than the prose and marked with a rule rather than a heading, because it is
   a specification and not a confession. */
.line__scope {
  margin-block-start: 16px;
  padding-inline-start: 14px;
  border-inline-start: 2px solid var(--rule);
  font-size: 13px;
  color: var(--gray);
  line-height: 1.6;
  max-width: 62ch;
}
.line__buys { margin-block-start: 10px; font-size: 12.5px; color: var(--gray); }

/* The documents strip inside a service line now carries a label, so the
   chips need to sit beside it rather than starting the row. */
.line__docs .lbl { display: block; width: 100%; margin-block-end: 7px; color: var(--gray); }

/* The privacy page's one permitted list of absences. A reader who arrived
   there came looking for exactly these, so naming them is a specification
   rather than a defence. */
.absent {
  margin-block-start: 24px;
  border: 1px solid var(--rule);
  background: var(--paper-2);
  padding: 18px 20px;
}
.absent .lbl { display: block; margin-block-end: 10px; }
.absent ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.absent li {
  font-size: 13.5px;
  color: var(--ink-soft);
  line-height: 1.5;
  padding-inline-start: 18px;
  position: relative;
}
.absent li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: .62em;
  width: 9px;
  height: 1px;
  background: var(--teal);
}

@media (max-width: 900px) {
  .purpose__grid { grid-template-columns: minmax(0, 1fr); }
  .wsf__body { grid-template-columns: minmax(0, 1fr); }
  .wsf__rail { border-inline-end: 0; border-bottom: 1px solid var(--rule); }
  /* The pause control is a touch target at these widths. */
  .clients__btn { min-height: 44px; display: inline-flex; align-items: center; }
}

@media (max-width: 620px) {
  .feat { grid-template-columns: minmax(0, 1fr); }
  .feat__c .lbl { min-height: 0; }
  .pf__key dt { width: 44px; }
}

/* ==========================================================================
   SECTION PLATES
   Added 18 September 2026.

   The defect. Every numbered section on every page rendered as the same
   object: a 190px left rail carrying a teal number, a title and a grey
   aside, with the content in one column beside it. Nine of them on Home,
   separated by an identical hairline rule. The director's words were "the
   home page feels like an article, not a modern home page ... all the
   sections look the same with no variation", and that is a fair reading of
   markup in which the only thing distinguishing section 07 from section 02
   is the text inside it.

   The spine was not wrong. A consistent numbered spine is what makes the
   site read as one document rather than a set of landing pages, and it is
   worth keeping. What was missing is a plate: the surface a section sits on.
   So the rail survives as the default and five variants change the plate
   under it.

     .sec--tint    a recessed paper panel, rules removed, full bleed
     .sec--dark    the navy band. Inverted, reuses .band-navy
     .sec--wide    no rail: the head runs across the top, content full width
     .sec--flip    the rail moves to the end of the line
     .sec--split   two equal columns rather than rail-plus-content

   Rules for using them, so this does not become nine variants by January:

   1. No two adjacent sections share a plate. That is the entire point.
   2. A plate is chosen for what the section CONTAINS, never for variety
      alone: --wide for a wide table or a row of more than three cards,
      --dark for a statement with no data in it, --tint for a block built
      around a figure.
   3. The section number and title keep their type, colour and order on
      every plate. A reader must still be able to count the sections.
   4. At most one --dark plate per page above the closing band, which is
      itself navy. Two dark bands and a navy footer is a striped page.
   ========================================================================== */

/* A tinted plate. Full bleed, so it reads as a change of ground rather than
   as a boxed panel, and the hairline rules come off -- a tint change is a
   stronger separator than a 1px rule, and keeping both makes a seam. */
.sec--tint {
  background: var(--paper-2);
  border-bottom: 0;
  border-top: 1px solid var(--rule-soft);
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
.sec--tint > .shell { position: relative; z-index: 1; }

/* The dark plate. Inverted type via .band-navy, which the closing band
   already defines, so there is one implementation of "white text on navy"
   rather than two that drift. */
.sec--dark {
  border-bottom: 0;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(52px, 6vw, 92px);
}
.sec--dark > .shell { position: relative; z-index: 1; }
.sec--dark .sec__no { color: var(--teal-lit); }
.sec--dark .sec__ttl { color: #fff; }
.sec--dark .sec__note { color: rgba(255, 255, 255, .58); }
.sec--dark .lead { color: rgba(255, 255, 255, .82); }

/* No rail. The head runs across the top of the plate and the content has
   the whole width under it -- for a table with four columns, or a row of
   more than three cards, both of which were being squeezed into the 1fr
   beside a 190px rail for no reason. */
.sec--wide .sec__grid {
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(22px, 2.6vw, 34px);
}
.sec--wide .sec__hd {
  /* The containing block for .sec__ghost. Without it `position: absolute`
     on the ghost resolves against the initial containing block and a 260px
     numeral lands somewhere relative to the page rather than to its own
     section -- off screen, in practice, which is why it read as missing
     rather than as misplaced. */
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 32ch);
  gap: clamp(16px, 3vw, 48px);
  align-items: end;
  padding-block-end: clamp(16px, 1.8vw, 24px);
  border-bottom: 1px solid var(--rule-soft);
}
.sec--wide .sec__ttl { max-width: 26ch; }
.sec--wide .sec__note { margin-block-start: 0; max-width: none; }
@media (max-width: 760px) {
  .sec--wide .sec__hd { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .sec--wide .sec__note { margin-block-start: 10px; }
}

/* The rail at the end of the line instead of the start. Logical properties,
   so this is a single rule and Arabic inherits it correctly: `row-reverse`
   would have needed an RTL counterpart. */
.sec--flip .sec__grid { grid-template-columns: minmax(0, 1fr) minmax(0, var(--rail)); }
.sec--flip .sec__grid > :first-child { order: 2; }

/* Two equal columns. For a section whose two halves are peers rather than
   a label and its content. */
.sec--split .sec__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 900px) {
  .sec--split .sec__grid,
  .sec--flip .sec__grid { grid-template-columns: minmax(0, 1fr); }
  .sec--flip .sec__grid > :first-child { order: 0; }
}

/* The ghost number. On a --wide plate the rail is gone, so the section
   number loses the column that used to give it presence; this puts it back
   as a very large outlined figure behind the title. Decorative only -- the
   real number is still in .sec__no and is what a reader and a screen reader
   both get. */
.sec__ghost {
  position: absolute;
  inset-block-start: -.24em;
  inset-inline-end: 2%;
  font-size: clamp(120px, 17vw, 260px);
  font-weight: 800;
  line-height: .78;
  letter-spacing: -.06em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(15, 36, 56, .075);
  pointer-events: none;
  user-select: none;
  z-index: 0;
}
.sec--dark .sec__ghost { -webkit-text-stroke-color: rgba(255, 255, 255, .11); }
/* Firefox before 137 has no -webkit-text-stroke. It is a decorative
   watermark, so the fallback is for it to be invisible rather than for a
   260px solid numeral to land on top of the heading. */
@supports not (-webkit-text-stroke: 1px black) {
  .sec__ghost { display: none; }
}
@media (max-width: 700px) { .sec__ghost { display: none; } }

/* Titles get a short rule under them that draws itself in when the section
   arrives. It is the cheapest possible marker of "a section starts here"
   and it is the one thing the flat page had none of. */
.sec__ttl { position: relative; }
.sec--wide .sec__hd .sec__ttl::after,
.sec__grid > :first-child .sec__ttl::after {
  content: "";
  display: block;
  width: 46px;
  height: 2px;
  background: var(--teal);
  margin-block-start: clamp(12px, 1.2vw, 18px);
}
.sec--dark .sec__ttl::after { background: var(--teal-lit); }


/* ==========================================================================
   THE DELIVERY RECORD -- the hero figure
   ========================================================================== */

.rec {
  background: var(--card);
  border: 1px solid var(--rule-soft);
  border-radius: 3px;
  padding: clamp(16px, 1.8vw, 24px);
}
.rec__nums {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(8px, 1.4vw, 20px);
  padding-block-end: clamp(14px, 1.6vw, 20px);
  border-bottom: 1px solid var(--rule-soft);
}
.rec__n {
  display: block;
  font-size: clamp(30px, 3.4vw, 46px);
  font-weight: 700;
  letter-spacing: -.04em;
  line-height: 1;
  color: var(--teal);
  font-variant-numeric: tabular-nums;
}
.rec__cap {
  display: block;
  margin-block-start: 6px;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--gray);
}
.rec__lbl { display: block; margin-block: clamp(14px, 1.6vw, 20px) 10px; }

.rec__mix { display: grid; gap: 9px; }
.rec__row {
  display: grid;
  /* 17ch, because at 15ch "Documents and knowledge" and "Prediction and
     optimisation" both wrapped and two of the five rows were double
     height. */
  grid-template-columns: minmax(0, 17ch) minmax(0, 1fr);
  gap: 6px 12px;
  align-items: center;
}
.rec__row dt {
  font-size: 12.5px;
  color: var(--ink-soft);
  line-height: 1.3;
}
.rec__row dd {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
}
/* preserveAspectRatio="none" on a 0-100 viewBox, so the bar's width
   attribute is read as a percentage of whatever the row is. */
.rec__bar { flex: 1 1 auto; height: 8px; min-width: 0; }
.rec__trk { fill: var(--paper-2); }
.rec__fill { fill: var(--teal); }
.rec__ct {
  flex: 0 0 auto;
  min-width: 2.2ch;
  text-align: end;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--charcoal);
  font-variant-numeric: tabular-nums;
}
@media (max-width: 620px) {
  .rec__row { grid-template-columns: minmax(0, 1fr); }
  .rec__row dt { font-size: 12px; }
}


/* ==========================================================================
   THE STEPPER -- the method, across the full width of a --wide plate

   Five steps in a row with a connecting line, rather than five stacked
   paragraphs in a 1fr column. The line is a border on the container so it
   cannot fall out of step with the number of items.
   ========================================================================== */

.step {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(14px, 1.8vw, 28px);
  counter-reset: step;
}
.step > div {
  position: relative;
  padding-block-start: 30px;
  border-top: 1px solid var(--rule);
}
.step > div::before {
  content: "";
  position: absolute;
  inset-block-start: -5px;
  inset-inline-start: 0;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--paper);
  border: 2px solid var(--teal);
}
.step .k {
  display: block;
  font-size: var(--label);
  font-weight: 600;
  letter-spacing: .14em;
  color: var(--teal);
  margin-block-end: 7px;
}
.step b { display: block; font-size: 14.5px; letter-spacing: -.01em; }
.step p {
  margin-block-start: 7px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-soft);
}
@media (max-width: 1000px) { .step { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .step { grid-template-columns: minmax(0, 1fr); } }


/* ==========================================================================
   SCROLL PROGRESS

   A 2px teal line at the very top of the viewport showing reading position.
   It is the one piece of chrome here that is purely navigational, and it
   earns its place on a site whose pages run to 1,300 words: it answers "how
   much of this is left", which is the question that makes a reader leave.

   Width is set by motion.js through the CSSOM (transform: scaleX), never as
   an attribute, so no inline style reaches the markup.
   ========================================================================== */

.prog {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  height: 2px;
  z-index: 60;
  background: transparent;
  pointer-events: none;
}
.prog__bar {
  height: 100%;
  background: var(--teal);
  transform: scaleX(0);
  transform-origin: left center;
  will-change: transform;
}
[dir="rtl"] .prog__bar { transform-origin: right center; }

/* ==========================================================================
   A SUB-BLOCK INSIDE A SECTION

   Section 01 on Home carries two subjects: the three things there are to
   buy, and the four stages of the one almost everyone buys first. They used
   to be sections 01 and 04, which put a document vocabulary and a mission
   statement between a route and how that route runs.

   A sub-block gets a heading and a top rule and no number. The number was
   the actual problem with the old arrangement: two numbered sections for one
   subject reads as two subjects.
   ========================================================================== */

.sub {
  margin-block-start: clamp(30px, 3.4vw, 48px);
  padding-block-start: clamp(22px, 2.4vw, 32px);
  border-top: 1px solid var(--rule-soft);
}
.sub__ttl {
  font-size: var(--step-2);
  font-weight: 600;
  letter-spacing: -.024em;
  line-height: 1.18;
  max-width: 28ch;
  margin-block-end: clamp(12px, 1.4vw, 18px);
}
html[lang="ar"] .sub__ttl { letter-spacing: 0; line-height: 1.45; max-width: 34ch; }


/* ==========================================================================
   THE DARK PLATE'S CONTENTS

   .purpose was written for the paper ground. On navy every one of its
   colours inverts, and the two statements want more size than they had --
   the whole reason for putting them on a dark plate is that they are the
   one block on the page a reader is meant to stop at rather than scan.
   ========================================================================== */

.sec--dark .purpose { gap: clamp(22px, 3vw, 38px); }
.sec--dark .purpose > div { border-top-color: var(--teal-lit); }
.sec--dark .purpose > div:last-child { border-top-color: var(--rule-dark); }
.sec--dark .purpose dd {
  color: #fff;
  font-size: var(--step-3);
  font-weight: 500;
  line-height: 1.26;
  max-width: 30ch;
}
.sec--dark .purpose > div:last-child dd { color: rgba(255, 255, 255, .78); }
html[lang="ar"] .sec--dark .purpose dd { line-height: 1.58; max-width: 36ch; }
.sec--dark .lbl { color: rgba(255, 255, 255, .55); }
.sec--dark .lbl--teal { color: var(--teal-lit); }

/* The dark plate is the one place the two statements are the whole content,
   so the rail is narrower than the default and the statements take the
   space. */
@media (min-width: 901px) {
  .sec--dark .sec__grid { grid-template-columns: minmax(0, 168px) minmax(0, 1fr); }
}


/* ==========================================================================
   A TINTED PLATE'S PANELS

   .results and .rec sit on --card white, which reads as lift on the paper
   ground and as a hole on the tint. On a tinted plate they get the paper
   ground instead, so the stack still goes ground-panel-figure rather than
   tint-white-tint.
   ========================================================================== */

.sec--tint .results,
.sec--tint .feat__c,
.sec--tint .rec { background: var(--paper); }
.sec--tint .tbl tbody tr:nth-child(odd) { background: transparent; }


/* ==========================================================================
   THE PUBLICATIONS COLUMN IN THE FOOTER

   Two lines per item: the title as the link, and what it is under it. The
   second line carries the format and the extent, because a reader deciding
   whether to open a 22-page PDF on a phone wants to know before the
   download starts.
   ========================================================================== */

.foot__dl li { margin-block-end: 9px; }
.foot__dl span {
  display: block;
  margin-block-start: 1px;
  font-size: 10.5px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .42);
}
html[lang="ar"] .foot__dl span { letter-spacing: 0; text-transform: none; font-size: 11px; }


/* ==========================================================================
   THE DARK PLATE: EVERYTHING THAT HAS TO INVERT

   .sec--dark is new, and every text colour in this stylesheet was written
   for the paper ground. The first casualty was the Cairo address on About:
   --ink-soft on --navy is about 1.4:1, so the address rendered and could
   not be read.

   The footer already had inverted variants of some of these, because the
   footer has always been navy. That is the pattern this block generalises:
   one place that lists what inverts, keyed on the plate rather than on the
   element, so a section moved onto a dark plate later needs no new CSS.

   ⚠ If you add a plate-level ground colour, add its text colours here in
   the same commit. A missing entry does not fail a test -- it renders dark
   text on a dark field, which reads as an element that did not load.
   ========================================================================== */

.sec--dark .foot__addr { color: rgba(255, 255, 255, .78); }
.sec--dark .foot__addr .lbl { color: rgba(255, 255, 255, .5); }
.sec--dark p,
.sec--dark dd,
.sec--dark li { color: rgba(255, 255, 255, .78); }
.sec--dark :is(h2, h3, h4, b, strong, dt) { color: #fff; }
.sec--dark a:not(.btn) { color: var(--teal-lit); }
.sec--dark a:not(.btn):hover { color: #fff; }
.sec--dark .stopnote,
.sec--dark .aside-note,
.sec--dark .sec__note { color: rgba(255, 255, 255, .6); }
.sec--dark .stopnote b { color: #fff; }
/* A hairline rule on navy has to be the light one, or it disappears. */
.sec--dark :is(.deflist > div, .breadth, .sub) { border-color: var(--rule-dark); }


/* ==========================================================================
   THE PAGE HEADER'S GROUND

   Clipping and stacking for the geometry behind every page's h1. Same two
   requirements as the hero: the ground is inset past the element so it has
   room, and an overhang the parent does not clip lands in the document
   scrollWidth -- which put a horizontal scrollbar on every page the first
   time a ground shipped without this.
   ========================================================================== */

.phead {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
.phead > .shell { position: relative; }
.phead__in { position: relative; z-index: 1; }
/* The header is short, so the ground is scaled down and pulled up: the
   hero's -14% inset on a 120px element leaves the lattice reading as three
   diagonal lines rather than as a field. */
.phead .geo--field { inset: -160% -4%; }


/* ==========================================================================
   FILLED BLOCKS ON A DARK PLATE

   `.method div` and `.orient > div` set a --paper background, and the dark
   plate sets the text inside them white. AI Workspace's four delivery steps
   rendered as white text on beige boxes, which is unreadable and was
   reported as exactly that.

   On a dark plate the boxes lose their fill and keep a light rule. The
   arrangement still reads as four steps; it just reads as four steps on
   navy instead of four holes in it.
   ========================================================================== */

.sec--dark :is(.method div, .orient > div, .featlist > div, .tiles > div) {
  background: transparent;
  border-top: 1px solid var(--rule-dark);
}
.sec--dark .featlist { background: transparent; border-color: var(--rule-dark); }
.sec--dark :is(.method b, .orient b, .featlist dt) { color: #fff; }
.sec--dark :is(.method p, .orient p, .featlist dd) { color: rgba(255, 255, 255, .74); }
.sec--dark :is(.method .k, .orient .k) { color: var(--teal-lit); }
.sec--dark .orient > div:hover,
.sec--dark .featlist > div:hover { background: rgba(255, 255, 255, .04); }


/* ==========================================================================
   FIG. 02, made legible

   It was three unlabelled blocks of text and the review could not read what
   it was. A caption strip names the figure, the question and the answer are
   visually distinct rather than only labelled, and the citation list says
   what it is a list of.
   ========================================================================== */

.pf-chat__hd {
  display: block;
  padding-block-end: 10px;
  margin-block-end: 12px;
  border-bottom: 1px solid var(--rule-soft);
}
.pf-chat__cl { display: block; margin-block-start: 14px; margin-block-end: 6px; }
/* The question sits in a recessed panel and the answer on the card, so the
   two read as a exchange rather than as two paragraphs. */
.pf-chat__q {
  background: var(--paper-2);
  border-inline-start: 2px solid var(--rule);
  padding: 10px 12px;
  margin-block-end: 10px;
}
.pf-chat__a { border-inline-start: 2px solid var(--teal); padding: 10px 12px; }
.pf-chat__a b { color: var(--charcoal); }


/* ==========================================================================
   LONG WORDS IN NARROW COLUMNS

   Every heading that can land in a 190px rail or a card, given the same
   treatment as .sec__ttl for the same reason: a word wider than its column
   draws outside it, and the horizontal-overflow test cannot see that
   because the page itself does not scroll.
   ========================================================================== */

.sub__ttl,
.featgrp__ttl,
.phead__t,
.feat__c h3,
.orient b,
.featlist dt {
  hyphens: auto;
  overflow-wrap: break-word;
}

/* The bold lead-in on a definition-style line. It was written as
   `<b>{{ head }}</b>{{ text }}` with nothing between the tags, so the dark
   plate on /engagement/ read "The audit stands alone.Its findings and
   recommendations are yours to act on". A margin rather than a literal
   space, so it survives the heading wrapping to its own line. */
.notfor > div > b { margin-inline-end: .4em; }
