/* ===========================================================
   About — Screen 07, `07-about.md`.

   GROUND PAPER, E1 UNAMENDED (§2), and not as a preference:
   §1.5a bars a third-party mark from --color-surface-dark, and
   the wall is thirty-two of them. The closing band is the
   page's one dark surface and owns the switch (E1.2a); the
   footer continues that black behind it.

   Because the ground is paper, nothing here has to restate a
   colour the way Services does — base.css already colours
   headings --color-ink and body copy resolves correctly. The
   only rules below that state a colour are the ones stepping
   DOWN to --color-ink-secondary (7.00:1), which is the site's
   secondary on paper. #A6A6A6 never appears on paper.

   THE WALL IS R2'S ONE COLOURED SURFACE, and nothing in this
   file touches the colour of a mark. §1.5a reproduces a
   client's trademark as they own it: no filter, no
   mix-blend-mode, no opacity, no background plate behind it.
   Three marks fight the paper (Talal Holdings never reaches
   3:1; Aqaar and Star Cinemas carry their own near-black
   field) and the answer is the name beside them, not a
   treatment applied to them.

   NO FRAME ANYWHERE. §1.5a rule 5 permits a border on every
   cell or none, and Screen 04 already chose none: a border
   around three rows is what makes three facts look like a form
   with fields missing. The wall's rules are horizontal only.
   =========================================================== */

/* -----------------------------------------------------------
   1 · The story (§3)
   ----------------------------------------------------------- */

/* The top padding clears the chrome at every width — the same duty as
   Services' claim. The H1 starts in the top inline-start corner, which is
   the corner the menu trigger is fixed in. */
.ab-story {
  /* The arrival clearance is UNTOUCHED — it is a site rule, not this page's
     rhythm. Only the foot steps down with the rest of the stack. */
  padding-block: var(--arrival-clearance) var(--ab-stack);
}

/* The ≤1023 restatement that used to sit here is GONE — the value now lives in
   --arrival-clearance (tokens-layout.css), which restates itself at the gap
   tokens' own breakpoint. Seven files carried this identical block; the whole
   point of P3 is that there is one place to change it. */

/* ¶1's first sentence, at display scale. .t-editorial carries the register
   and the mobile collapse: --fs-h1 is 52px, 40px at 1023 and 34px at 767,
   which is §9's stated H1 value with no page-level override. */
.ab-story__line {
  margin: 0;
}

.ab-story__support {
  margin: var(--gap-block) 0 0;
}

/* The gap between the support line and ¶2 is the heading gap, not the block
   gap: the H1 and its support are one object, and ¶2 starts the argument. */
.ab-story__prose {
  margin: var(--gap-heading) 0 0;
}

.ab-story__prose + .ab-story__prose {
  margin-block-start: var(--gap-block);
}

/* The proof line — ¶3, the practice's one externally verified fact, sitting
   as the last beat before the only door on the first screen.

   IT TAKES THE SUPPORT LINE'S OWN MEASURE, not a chosen one. At an invented
   34ch the sentence set three lines with "2023." orphaned; --measure-body-lg
   is the token the support line above it already uses, so the rule ends
   where that column ends and the sentence sets in two.

   The rule is horizontal, which is the only kind this page has (§1.5a rule 5,
   and the wall's own register). It separates the proof from the invitation —
   which is work worth doing here, and would not have been higher up. */
.ab-story__route {
  margin: var(--gap-heading) 0 0;
}

/* The page's three routes share one register — the site's link grammar on
   paper, ruled underneath rather than coloured. */
.ab-link {
  display: inline-block;
  border-block-end: 1px solid currentcolor;
  padding-block-end: 2px;
  font-size: var(--fs-metadata);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-nav);
  text-transform: uppercase;
  color: var(--color-ink);
  transition: border-block-end-width var(--dur-fast) var(--ease-out);
}

.ab-link:hover,
.ab-link:focus-visible {
  border-block-end-width: 2px;
}

.ab-link:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 4px;
}

/* -----------------------------------------------------------
   0 · ABOUT'S OWN STACK RHYTHM (Session XXXI, 8 Aug)
   -----------------------------------------------------------

   🔴 MEASURED, NOT ADJUSTED BY EYE. Mahesh, reading the six-block page:
   "there is a lot of spacing issues". At 1440 the gaps between blocks came
   out 225 · 200 · 200 · 200 · 200 · 340 — **1,365px of white between blocks
   in a 5,518px page, a quarter of it** — while the same page at a true 375
   ran 121 · 96 · 96 · 96 · 96 · 168 and he had already said the narrow one
   read better.

   WHY IT ONLY SHOWS NOW. --gap-section is 200px at desktop and it was right
   when About had FOUR visible blocks, one of which was the 2,186px wall: a
   long block earns a long gap. The page has six now, four of them short, and
   a short block at a 200px remove reads adrift rather than airy. Nothing
   about the token changed; the page around it did.

   🔴 SCOPED TO THIS PAGE ON PURPOSE. --gap-section, --gap-heading and
   --gap-component are shared tokens; editing them moves all fifty-seven
   routes for a complaint made about one. These are page-local values that
   step at the same two breakpoints the tokens do, so About still breathes
   with the site rather than against it.

   MOBILE IS DELIBERATELY UNCHANGED AT 96px — it is the reading Mahesh
   preferred, so it is the target the desktop step moves toward, not a value
   to be re-tuned alongside it. */
/* 🔴 GROUPED, NOT UNIFORM — and the first attempt at this was WRONG.
   Session XXXI first answered "a lot of spacing issues" by taking every gap
   from 200px to 128px. Freya killed it on the render and the reason is a
   rule this project already carries: **when a design complaint recurs,
   re-read the complaint rather than tightening the threshold.** Five
   identical gaps of 128 are exactly as undifferentiated as five identical
   gaps of 200 — the complaint was never that the gaps were big, it was that
   six blocks in one column never say which of them belong together.

   So the gap now CARRIES THE GROUPING, and the grouping is the page's
   argument (Mahesh, 8 Aug, "grouped order now"):

     who we are                      story · mission/vision · leadership
     who trusts us                   the quotation (X9) · the client wall
     the foot                        join us · certifications

   Re-grouped 8 Aug (Session XXXII) for Mahesh's reorder; the seam
   photograph retired with it. 200 between groups, 96 within one. The
   ratio is 2.08:1, which reads as grouping; 1:1 cannot, at any value.

   🔴 EACH SECTION'S BOTTOM GAP DESCRIBES WHAT FOLLOWS IT, NOT WHAT IT IS.
   That is why .ab-purpose is 96 and .ab-lead is 200 when both are "a
   block": Mission & Vision is followed by its own group's third beat,
   Leadership is followed by a different group. Move a section and its
   value moves with the wrong block — so any reorder must revisit this
   list, and nothing on the board can see that. It is written down here
   because that is the only place it can be seen. */
.ab-story  { --ab-stack: 96px;  }   /* -> the quick view, same group */
.ab-purpose{ --ab-stack: 96px;  }   /* -> leadership, same group */
.ab-lead   { --ab-stack: 200px; }   /* -> the wall (the quotation, when X9 lands), group break */
.ab-wall   { --ab-stack: 200px; }   /* -> join us, group break */
.ab-join   { --ab-stack: 96px;  }   /* -> certifications, same group */
.ab-certs  { --ab-stack: 200px; }   /* -> the band, which owns the switch */
/* 🔴 THE QUICK VIEW MOVED TO THE TOP (Mahesh, 8 Aug, Session XXXIII:
   "this needs to come somewere towards the top .. not at the bottom"), and
   THIS LIST IS WHAT A REORDER COSTS. Every value below describes the section
   that FOLLOWS it, so moving one block re-aimed three of them: story now
   hands to the quick view (96), the quick view to mission/vision (96), and
   certifications goes back to 200 because the band is its neighbour again.
   Nothing here is a re-tuning — the numbers are unchanged, the neighbours
   are not.
   `.ab-facts` was absent from this list entirely until earlier today, which
   is why un-hiding it would have handed the dark band a ZERO gap. The board
   can see this now: sweep-about derives the section list from the rendered
   order and fails if any section is missing from the map, at any tier. */
.ab-facts  { --ab-stack: 96px;  }   /* -> mission/vision, same group */

/* 🔴 --ab-head IS MEASURED TO THE FIRST INK, AND A 1px RULE IS INK.
   Freya read this block's fault as "one token, three optical gaps" —
   Leadership and Certifications each open on a hairline with --gap-block
   beneath it, Join us opens straight onto its paragraph — and the first fix
   subtracted that structure so the gap to the CONTENT was constant. Two
   things killed it, both only visible in a render:

     · at =<767 the subtraction went NEGATIVE (--ab-head 24 minus
       --gap-block 24 minus the border), and the block's first hairline rode
       up level with its own heading;
     · clamped at 0 it still read wrong — the rule sat ON the heading.

   The premise was the error, not the arithmetic. **A hairline is not
   structure between the heading and the content; it is the first thing the
   eye lands on.** So every heading sits --ab-head above its first ink, and
   for a ruled block that ink is the rule. One token, one rule, no
   subtraction, nothing to go negative. */
.ab-story,
.ab-purpose,
.ab-lead,
.ab-certs,
.ab-join,
.ab-wall {
  --ab-head: 40px;
}

@media (max-width: 1119px) {
  .ab-story  { --ab-stack: 72px;  }
  .ab-purpose{ --ab-stack: 72px;  }
  .ab-lead   { --ab-stack: 144px; }
  .ab-wall   { --ab-stack: 144px; }
  .ab-join   { --ab-stack: 72px;  }
  .ab-certs  { --ab-stack: 144px; }
  .ab-facts  { --ab-stack: 72px;  }

  .ab-story,
  .ab-purpose,
  .ab-lead,
  .ab-certs,
  .ab-join,
  .ab-wall {
    --ab-head: 32px;
  }
}

@media (max-width: 767px) {
  .ab-story  { --ab-stack: 56px; }
  .ab-purpose{ --ab-stack: 56px; }
  .ab-lead   { --ab-stack: 96px; }
  .ab-wall   { --ab-stack: 96px; }
  .ab-join   { --ab-stack: 56px; }
  .ab-certs  { --ab-stack: 96px; }
  .ab-facts  { --ab-stack: 56px; }

  .ab-story,
  .ab-purpose,
  .ab-lead,
  .ab-certs,
  .ab-join,
  .ab-wall {
    --ab-head: 24px;
  }
}

/* -----------------------------------------------------------
   1b · Mission & Vision (Session XXXI, 8 Aug)
   -----------------------------------------------------------

   TWO ITEMS, TWO COLUMNS, ONE HAIRLINE EACH. The page's grammar is
   horizontal hairlines and no frames, so a mission "card" is out; the rule
   above each statement is the same device the proof line already uses, and
   it is what makes the pair read as two things rather than one paragraph.

   THE LABEL TAKES THE PAGE'S ONE HEADING REGISTER — --fs-h3 regular, ink,
   no uppercase, no letterspacing. That is exactly .ab-wall__clients and
   .ab-lead__head, and using a fourth size for a fourth block is how a page
   acquires a type system it did not have.

   THE STATEMENT TAKES --measure-body-lg, the support line's own column.
   Two 1fr columns at 1120+; the statements are short enough that neither
   reaches the measure cap, so the cap only bites if the copy grows. */
.ab-purpose {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  column-gap: var(--gap-component);
  padding-block-end: var(--ab-stack);
}

.ab-purpose__item {
  padding-block-start: var(--gap-block);
  border-block-start: 1px solid var(--color-hairline);
}

/* 🔴 TRACKING IS STATED ON EVERY HEAD, AND IT WAS NOT UNTIL 8 Aug (XXXIII).
   These are bare <h2> elements, and base.css sets `h2 { letter-spacing:
   var(--ls-h2) }` — the THIRTY-TWO pixel value, -0.02em. A page class wins
   only on the properties it DECLARES, so /about's six 24px heads were
   rendering at the 32px tracking while /services' 24px heads (via .t-h3) ran
   at --ls-h3's -0.015em. Measured, both pages, same width: -0.0200em against
   -0.0150em. /about was the ONLY page whose section headings carried no .t-*
   class, which is why it was the only page with this drift.
   This is CLAUDE.md's own rule — "a heading's REGISTER is stated by the page,
   never inherited" — and it had been half-obeyed: the size and weight were
   stated, the tracking was left to fall through.
   The WEIGHT difference against /services (400 here, 600 there) is NOT this
   fault. It is 07-about §5's deliberate one-register decision and it stays. */
.ab-purpose__head {
  /* A two-word label over its own sentence is INTRA-OBJECT, not a section
     head — the ≤767 render was the proof, not a mobile exception: the same
     block reads correctly there precisely because --gap-heading collapses
     to 24. So it takes --gap-block at every width. */
  margin: 0 0 var(--gap-block);
  font-size: var(--fs-h3);
  letter-spacing: var(--ls-h3);
  font-weight: var(--fw-regular);
  line-height: var(--lh-h3);
  color: var(--color-ink);
}

.ab-purpose__line {
  margin: 0;
  max-inline-size: var(--measure-body-lg);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  color: var(--color-ink);
}

/* -----------------------------------------------------------
   2 · The client wall (§5) — W-A, one stack
   ----------------------------------------------------------- */

/* Four tables in one stack, one alignment axis down the whole wall. The
   groups are separated by the component gap rather than a rule: the rules
   in this section mean "one client", and a rule between groups would mean
   the same thing at a different scale. */
.ab-wall {
  padding-block-end: var(--ab-stack);
}

/* table-layout: fixed, because auto layout treats a column's inline-size as
   a PREFERENCE and negotiates it against the content: the 200px mark column
   settled at 197.9px and the one width-limited mark rendered 2px short of
   the geometry §5's arithmetic chose. Fixed makes the column exactly 200px,
   which is the number the container decision was taken on. */
.ab-wall__group {
  inline-size: 100%;
  table-layout: fixed;
  border-collapse: collapse;
  text-align: start;
}

/* W-B's pacing. The groups sit further apart than W-A's single stack needed,
   because at two across each group is half as tall and four of them in a row
   at --gap-component read as one continuous list again. Derived from the
   token rather than typed as 96px. */
.ab-wall__group + .ab-wall__group {
  margin-block-start: calc(var(--gap-component) * 1.5);
}

/* 🔴 THE FIVE-STAR RATING'S RULE IS RETIRED WITH IT, 22 Aug 2026. It sat
   under the authorities group (Session XXXIII) until Mahesh's "remove this
   data" took that group entirely — see pages-src/about.html's own note at
   the point the <p> used to render, and build/lib/about.js's note beside
   PROOF_HEAD. Nothing in `.ab-wall__group + .ab-wall__group` above needed
   changing: that adjacent-sibling rule only ever had to be worked around
   because the proof paragraph broke the sibling relationship it depends
   on, and with the paragraph gone there is nothing left to work around. */

/* The group head is the table's own <caption> — 12px uppercase secondary,
   the site's small-label register. text-align is stated because a caption
   centres by default, and this wall has one alignment axis. */
/* W-B's RAISE, REVERSED 8 Aug (Session XXXII). The raise put the four
   heads at --fs-h3 so the wall read as four sets — and under Mahesh's
   reorder that became the fault: nine headings at one register in one
   column, the page's last stretch reading as four more sections. "Clients"
   (.ab-wall__clients, below) now does the naming, so the heads return to
   the site's small-label register — the caption letterform W-A originally
   gave them — and only subdivide the block the heading owns. This is the
   only 12px-uppercase on the wall, so it cannot be mistaken for content.

   text-align is still stated — a caption centres by default and this wall
   has one alignment axis per pair. */
.ab-wall__head {
  padding-block-end: var(--gap-block);
  font-size: var(--fs-caption);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-caption);
  line-height: var(--lh-caption);
  text-align: start;
  text-transform: uppercase;
  color: var(--color-ink-secondary);
}

/* The wall's one heading — Mahesh's word, his reversal, recorded in the
   source above the section. The page's ONE heading register; the heads
   beneath it are captions, not competitors. */
.ab-wall__clients {
  margin: 0 0 var(--ab-head);
  font-size: var(--fs-h3);
  letter-spacing: var(--ls-h3);
  font-weight: var(--fw-regular);
  line-height: var(--lh-h3);
  color: var(--color-ink);
}

/* Hairline between rows, and above the first row of every group so the head
   sits on its set. No vertical rule, no cell border, no outer frame. */
.ab-wall__markcell,
.ab-wall__namecell {
  padding-block: var(--pad-table-row);
  border-block-start: 1px solid var(--color-hairline);
  vertical-align: middle;
}

/* W-A's mark column. 200px was chosen on the arithmetic in §5, re-derived
   from the trimmed files: at the 32px cap the set runs 25.7px to 244.5px
   wide (9.5:1, median 70.7), so a 200px column width-limits exactly one
   mark — Al Zorah Development — and the shortest row still renders 26.2px
   tall. 120px was rejected: nine marks would be width-limited and a third
   of the wall would fall to 13-20px optical, which is the failure §6.3
   solved by naming every client in the first place. */
/* THE GUTTER BELONGS TO THE NAME, NOT THE MARK. Sizing the cell 200px and
   then padding it 24px leaves the mark 176px, so the one width-limited mark
   rendered 174.9px instead of 200 and the wall no longer matched the
   arithmetic that chose the container. Measured, not reasoned: the cell is
   200px and every pixel of it is the mark's. */
.ab-wall__markcell {
  inline-size: 200px;
  /* The UA stylesheet gives every td 1px of padding on all four sides. The
     rule above sets padding-block and leaves the inline pair standing, so
     the mark had 198px of a 200px column and the width-limited mark landed
     197.9px. Stated, not inherited. */
  padding-inline: 0;
}

/* THE NAME COLUMN IS STATED, because W-B's row is an exact fit and an
   unstated column would be whatever is left over.

     mark 200 + gap 24 + name 224  =  448 per client
     448 x 2 + a 64px gutter       =  960  — the row, exactly

   960 is NOT --container-max. The container is 1120 and the two 80px page
   gutters come off first; §5's W-B note priced the pair against 1120 and
   overran by 112px. The number is in build/lib/about.js too, so the reported
   arithmetic and the rendered wall cannot drift apart.

   🔴 THE STATED WIDTHS ARE OUTER WIDTHS, AND THEY MUST SUM TO 960 EXACTLY.
   Written first as 200/224/200/224 they summed to 848, and `table-layout:
   fixed` does not overflow on a shortfall — it distributes the missing 112px
   across the columns in proportion. The mark column rendered 226.4px while
   this file and the build log both said 200. It failed toward LOOKING FINE:
   a wider column width-limits fewer marks, so nothing was visibly wrong and
   the number the container decision rests on was simply not true. Measured,
   not reasoned — the same failure §5 records three other people making.

   The gutter and the gap are PADDING INSIDE the name cells, so they are part
   of those cells' stated widths:

     200  +  (24 + 224 + 64)  +  200  +  (24 + 224)  =  960 */
.ab-wall__namecell {
  inline-size: 248px;
  padding-inline: var(--gap-block) 0;
}

/* The gutter between the two pairs belongs to the first name, the same way
   the mark column's gutter belongs to the name and not the mark. */
.ab-wall__namecell--first {
  inline-size: 312px;
  padding-inline-end: var(--gap-component);
}

/* The wall's own door. --gap-section from the last row, so it reads as the
   section's foot rather than a thirty-third client. */
/* -----------------------------------------------------------
   3x · The mosaic (X24) — the work's index at the wall's foot
   -----------------------------------------------------------

   /projects' justified-row mechanics, borrowed whole: each tile carries
   its CHOSEN aspect as the --a datum, flex distributes the row in
   proportion, and the row's height falls out of the arithmetic. The 12px
   gap (--gap-inline) on BOTH axes is what makes it one picture rather
   than /projects-with-the-captions-deleted — at --gap-block the tiles
   separate back into a grid of things (Freya, rendered, 8 Aug).

   The strip and the route sit at the wall's own inter-group pacing
   (--gap-component * 1.5 — 96/60/60), so the mosaic reads as the wall's
   fifth movement and the link beneath reads as the index's door. */
.ab-index {
  display: flex;
  flex-direction: column;
  gap: var(--gap-inline);
  margin-block-start: calc(var(--gap-component) * 1.5);
}

.ab-index__row {
  display: flex;
  gap: var(--gap-inline);
}

.ab-index__tile {
  flex: var(--a) 1 0;
  min-inline-size: 0;
  aspect-ratio: var(--a);
  block-size: auto;
  object-fit: cover;
}

/* ≤767: each row becomes a two-column grid and the portrait tile — keyed
   on what it IS, never on where it sits — reorders to close the strip
   full-width, /projects' own mobile rule. Mid-row it tears a 134px hole
   in the grid (rendered and killed). */
@media (max-width: 767px) {
  .ab-index__row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }

  .ab-index__tile--tall {
    order: 9;
    grid-column: 1 / -1;
  }
}

.ab-wall__route {
  margin: calc(var(--gap-component) * 1.5) 0 0;
}

/* §1.5a rule 4 caps a mark at 32px optical height — a CAP, NOT A FLOOR, so
   a mark rendering under it conforms.

   max-* with auto dimensions, never height+max-width: the latter clamps the
   width of a wide mark while the height stays 32px and DISTORTS it, which
   on a trademark is not a layout bug. The intrinsic width/height attributes
   on the <img> give the browser the aspect ratio, so each row reserves its
   height before the mark loads — this page is thirty-two images. */
.ab-wall__mark {
  display: block;
  inline-size: auto;
  block-size: auto;
  max-inline-size: 100%;
  max-block-size: 32px;
}

.ab-wall__name {
  display: block;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--color-ink);
}

/* Four rows carry one. Shown only where it does not restate the client's
   own name — every other row is a client-equals-building echo (Screen 04's
   suppression rule, reused). It is a caption on the row, not a second name,
   so it steps down in size and colour. */
.ab-wall__relation {
  display: block;
  margin-block-start: 2px;
  font-size: var(--fs-metadata);
  line-height: var(--lh-body);
  color: var(--color-ink-secondary);
}

/* -----------------------------------------------------------
   2b · Leadership (X9) — SHIPPING WITH PLACEHOLDERS
   ----------------------------------------------------------- */

/* NO CARD, NO FRAME, NO ROUNDING. The page's grammar is horizontal
   hairlines — that is what a client row gets, so it is what a person gets.
   A rounded card with a shadow around four people would be the one device
   on /about that belongs to a different site.

   The columns are 1fr rather than a typed 216px: on the 960px row four of
   them at a 32px gap come out at 216 exactly, and stating the fraction means
   the block survives a container change that a typed pixel would not. */
.ab-lead {
  padding-block-end: var(--ab-stack);
}

.ab-lead__head {
  margin: 0 0 var(--ab-head);
  font-size: var(--fs-h3);
  letter-spacing: var(--ls-h3);
  font-weight: var(--fw-regular);
  line-height: var(--lh-h3);
  color: var(--color-ink);
}

.ab-lead__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: calc(var(--gap-tight) * 2);
}

.ab-lead__person {
  margin: 0;
  padding-block-start: var(--gap-block);
  border-block-start: 1px solid var(--color-hairline);
}

/* aspect-ratio, not a height: the frame keeps 4:5 at every column width, so
   a real photograph dropped in later crops to the same box the placeholder
   occupied and the page does not move. */
.ab-lead__frame {
  aspect-ratio: 4 / 5;
  /* Derived from the two tokens either side of it rather than typed, and
     deliberately soft: a placeholder should read as present-but-not-content.
     Both this rule and .ab-lead__placeholder leave with X9. */
  background: color-mix(in srgb, var(--color-hairline) 40%, var(--color-surface));
}

.ab-lead__placeholder {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  fill: var(--color-hairline);
}

.ab-lead__caption {
  margin-block-start: var(--gap-inline);
}

/* HARD RULE 8 BY CONSTRUCTION — the name is a block BENEATH the frame, never
   inside it. When the photographs arrive nothing about this moves. */
.ab-lead__name {
  display: block;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--color-ink);
}

.ab-lead__role {
  display: block;
  margin-block-start: 2px;
  font-size: var(--fs-metadata);
  line-height: var(--lh-body);
  color: var(--color-ink-secondary);
}

/* -----------------------------------------------------------
   3 · The facts (§6) — built, shipped hidden
   ----------------------------------------------------------- */

/* [hidden] is the switch; these rules are what it unhides onto. base.css
   may set display on section elements, so the attribute selector states it
   rather than trusting the cascade — a facts table that ships VISIBLE is a
   silent failure of the X6 gate, and the one below is a row already inside
   ¶1. */
.ab-facts[hidden] {
  display: none;
}

/* The gap it hands to the band. Every other section on this page spends its
   --ab-stack as padding-block-end; this one did not, which is the other half
   of the omission above. */
.ab-facts {
  padding-block-end: var(--ab-stack);
}

.ab-facts__table {
  inline-size: 100%;
  border-collapse: collapse;
}

.ab-facts__row + .ab-facts__row .ab-facts__label,
.ab-facts__row + .ab-facts__row .ab-facts__value {
  border-block-start: 1px solid var(--color-hairline);
}

.ab-facts__label,
.ab-facts__value {
  padding-block: var(--pad-table-row);
  vertical-align: baseline;
}

/* text-align stated, not inherited — the UA's `th { text-align: center }`
   matches the element and therefore beats the table's inherited start.
   Found on Contact, where the same table treatment shipped visible and the
   labels centred in their column. Nothing changes here today: this table
   is hidden behind X6, which is exactly why the fault could sit unseen and
   why it is fixed now rather than on the day the attribute comes off. */
.ab-facts__label {
  /* 28, not 40. Freya's render: at 40% a 384px gutter opened in front of a
     six-name list and the names wrapped early for no reason. */
  inline-size: 28%;
  padding-inline-end: var(--gap-tight);
  text-align: start;
  font-size: var(--fs-metadata);
  /* STATED, not inherited — /contact's .ct-facts__label states --lh-metadata
     and this rule inherited --lh-body. Same table idiom, one property apart.
     It is the second half of the fault already recorded against this exact
     pair of rules: the UA's `th { text-align: center }` was fixed on both,
     the leading on contact only. */
  line-height: var(--lh-metadata);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-nav);
  text-transform: uppercase;
  color: var(--color-ink-secondary);
}

.ab-facts__value {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--color-ink);
}

/* A DISCIPLINE NAME NEVER BREAKS, AND A SEPARATOR NEVER LEADS A LINE. The
   middot is bound to the name BEFORE it with &nbsp; (build/lib/about.js), so
   a wrap can only fall AFTER a separator. Freya rendered the plain-space
   version at 768 and it broke onto "· Interior design" — a separator opening
   a line reads as a bullet, i.e. as a list the row is not. */
.ab-facts__d {
  white-space: nowrap;
}

/* -----------------------------------------------------------
   3c · Certifications (X21) — real rows since 27 Aug 2026
   -----------------------------------------------------------

   RULED ROWS, NO FRAME. The same reason §6's facts table gives: a border
   around a short list of things makes it look like a form with fields
   missing. The hairline sits ABOVE each row so the list has a top edge and
   no bottom one, which is the wall's register.

   🔴 THE ROW TEXT STEPPED FROM SECONDARY TO --color-ink, 27 Aug 2026, exactly
   as this comment always said it would: "when X21 answers, the bracket goes
   and the colour steps up to --color-ink in the same rule." The SEAL below
   does NOT step with it — see pages-src/about.html's own note on why the
   ring stays a drawn hairline stand-in rather than a repurposed auditor
   logo. */
.ab-certs {
  padding-block-end: var(--ab-stack);
}

.ab-certs__head {
  margin: 0 0 var(--ab-head);
  font-size: var(--fs-h3);
  letter-spacing: var(--ls-h3);
  font-weight: var(--fw-regular);
  line-height: var(--lh-h3);
  color: var(--color-ink);
}

/* The measure is the body measure PLUS the seal column — at the bare
   measure the icon column steals 72px from the sentence and orphans the
   closing bracket onto its own line (Freya, render-caught, 8 Aug). */
.ab-certs__list {
  margin: 0;
  padding: 0;
  max-inline-size: calc(var(--measure-body-lg) + 48px + var(--gap-block));
  list-style: none;
}

.ab-certs__item {
  display: grid;
  grid-template-columns: 48px 1fr;
  column-gap: var(--gap-block);
  align-items: start;
  padding-block: var(--gap-block);
  border-block-start: 1px solid var(--color-hairline);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--color-ink);
}

/* Each row is a link to its own certificate PDF (27 Aug 2026). Underlined
   at rest, not just on hover: nothing else in this row differs from plain
   body text (E10's register bars a "Download" verb here), so the
   underline is the only signal the row is clickable at all — never colour
   alone (§9's own accessibility rule). */
.ab-certs__claim {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.ab-certs__claim:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 4px;
}

/* The dummy seal — a drawn hairline ring, the same pendingness grammar as
   Leadership's grey frames. Hairline, never ink or secondary: a ring in
   ink reads as a CHOSEN glyph, and a dummy must never look chosen. 32px is
   §1.5a rule 4's cap, so the placeholder occupies exactly the box a real
   certification mark will. The -3px start margin centres the 32px seal on
   the row's 25.6px first line box, and holds when the text wraps at 375. */
.ab-certs__seal {
  margin-block-start: -3px;
}

.ab-certs__seal circle {
  fill: none;
  stroke: var(--color-hairline);
  stroke-width: 3;
}

/* -----------------------------------------------------------
   4 · Join us (§8)
   ----------------------------------------------------------- */

.ab-join {
  padding-block-end: var(--ab-stack);
}

/* The heading §3's beat table always specified and the build never shipped.
   Same register as .ab-lead__head and .ab-wall__clients — the page has
   ONE heading size and this does not add a second. */
.ab-join__head {
  margin: 0 0 var(--ab-head);
  font-size: var(--fs-h3);
  letter-spacing: var(--ls-h3);
  font-weight: var(--fw-regular);
  line-height: var(--lh-h3);
  color: var(--color-ink);
}

.ab-join__prose {
  margin: 0;
}

.ab-join__route {
  margin: var(--gap-block) 0 0;
}

/* -----------------------------------------------------------
   5 · The closing band — E1.2 / E1.2a
   ----------------------------------------------------------- */

/* On a paper page the band is the inverse, so it is the dark surface and it
   owns the switch. The register is the site's, one on all fifty-four pages
   that carry it: 32px light, never an uppercase imperative. */
.ab-band {
  padding-block: calc(var(--gap-section-major) / 2);
}

.ab-band__line {
  margin: 0 0 var(--gap-block);
  max-inline-size: var(--measure-h2);
  font-size: var(--fs-h2);
  font-weight: var(--fw-light);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  color: var(--color-on-dark);
}

.ab-band__action {
  display: inline-block;
  padding-block: var(--gap-tight);
  padding-inline: var(--gap-heading);
  border: 1px solid var(--color-on-dark);
  font-size: var(--fs-metadata);
  font-weight: var(--fw-medium);
  letter-spacing: var(--ls-nav);
  text-transform: uppercase;
  color: var(--color-on-dark);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

.ab-band__action:hover,
.ab-band__action:focus-visible {
  background: var(--color-on-dark);
  color: var(--color-surface-dark);
}

/* -----------------------------------------------------------
   6 · Breakpoints (§9) — restack, never shrink
   ----------------------------------------------------------- */

/* BELOW 768 THE WALL RESTACKS: the mark on its own line, the name beneath
   it, still one ruled row per client.

   Found by rendering, not by reasoning. Carrying the desktop values down
   left 127px for the name at 375 and clipped every one of them — "General
   Authority of Islamic Affairs & Endowm…". Shrinking the mark column to fit
   is the wrong fix: at ~104px half the set falls below 20px optical, which
   is the exact failure naming every client was chosen to solve.

   The cells become blocks and the row carries the rule, so the ruled
   register survives the restack rather than being traded for it. A
   consequence worth having: the mark may now use the full column width, so
   Al Zorah renders WIDER at 375 than in the 200px desktop container. */
/* BELOW 1120 THE WALL GOES BACK TO ONE CLIENT ACROSS, and this breakpoint is
   not a taste — it is where the arithmetic stops being true. The row is the
   container less its two 80px page gutters, so it reaches 960px at exactly a
   1120px viewport. One pixel narrower and `table-layout: fixed` scales the
   stated columns down proportionally: the mark column leaves 200px, and the
   set falls toward the 13-20px optical failure that naming every client was
   chosen to solve in the first place. It compresses silently — no overflow,
   no warning — which is why the revert is stated rather than left to the
   table.

   The <tr> becomes a two-column grid, so its four cells flow mark / name,
   mark / name — one client per line, the W-A register, with no second
   markup path to maintain. The cells carry role="row"/"cell" in the template
   precisely because this rule changes their display: a table's implicit
   semantics do not survive it, and the wall is the page's argument. */
@media (max-width: 1119px) {
  .ab-wall__row {
    display: grid;
    grid-template-columns: 200px 1fr;
    align-items: center;
  }

  .ab-wall__markcell,
  .ab-wall__namecell {
    border-block-start: 0;
  }

  /* One rule per CLIENT, not per row — the row now holds two of them. */
  .ab-wall__markcell {
    border-block-start: 1px solid var(--color-hairline);
  }

  .ab-wall__namecell {
    border-block-start: 1px solid var(--color-hairline);
    inline-size: auto;
  }

  .ab-wall__namecell--first {
    inline-size: auto;
    padding-inline-end: 0;
  }

  /* The pair restacks rather than narrowing: at 1119 two 1fr columns put
     each statement in a ~460px measure, and the mission sets four lines
     against the vision's three, which reads as a mistake rather than as a
     pair. Stacked, each takes the support line's own measure. */
  .ab-purpose {
    display: block;
  }

  .ab-purpose__item + .ab-purpose__item {
    margin-block-start: var(--gap-component);
  }

  .ab-lead__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--gap-heading) calc(var(--gap-tight) * 2);
  }
}

@media (max-width: 767px) {
  .ab-wall__row {
    display: block;
  }

  .ab-wall__markcell,
  .ab-wall__namecell {
    display: block;
    border-block-start: 0;
  }

  /* The rule stays on the mark, which is where each client starts. */
  .ab-wall__markcell {
    inline-size: auto;
    padding-block-end: var(--gap-inline);
    border-block-start: 1px solid var(--color-hairline);
  }

  /* The name is under the mark now, not beside it, so the gutter that
     separated them horizontally would only indent the name. */
  .ab-wall__namecell {
    padding-block-start: 0;
    padding-inline: 0;
  }

  /* The facts table stacks label over value on the same clause. */
  .ab-facts__label,
  .ab-facts__value {
    display: block;
    inline-size: auto;
  }

  .ab-facts__label {
    padding-block-end: 0;
    padding-inline-end: 0;
  }

  .ab-facts__value {
    padding-block-start: 0;
  }

  .ab-facts__row + .ab-facts__row .ab-facts__value {
    border-block-start: 0;
  }
}
