/* =========================================================================
   Sarrif: Design system stylesheet
   Written with CSS logical properties throughout so this single file
   serves both the English (ltr) and Arabic (rtl) pages without a
   duplicate RTL stylesheet. Uses the system font stack only (no
   external font requests) to keep first paint fast and layout stable.
   ========================================================================= */

/* ---------- Design tokens ---------- */
/* Sarrif runs a single, deliberate light theme on a flat page background
   (--color-bg), the same color on every page. Previously this was a
   blurred, animated blue gradient (see git history for body::before);
   that layer was removed at the client's request in favor of this flat
   fill. --color-surface / --color-surface-alt / --color-border are
   still translucent, a holdover from when UI chrome needed to read as
   frosted glass over a moving background; they still work fine as a
   soft, barely-there tint over the flat color. */
:root {
  color-scheme: light;

  --color-bg: #F5F4F0;
  --color-surface: rgba(255, 255, 255, 0.6);
  --color-surface-alt: rgba(255, 255, 255, 0.45);
  --color-text: #2b2018;
  --color-text-muted: #3f3226;
  --color-primary: #1d2f4e;
  --color-primary-strong: #131f33;
  --color-on-primary: #f7f1e8;
  --color-accent: #7a4f22;
  --color-accent-strong: #96632c;
  --color-on-accent: #fbf3e8;
  --color-border: rgba(43, 32, 24, 0.15);
  --color-focus: #1d2f4e;

  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, "Noto Sans", "Noto Kufi Arabic", sans-serif;

  --max-width: 72rem;
  --radius-sm: 6px;
  --radius-md: 12px;
  --radius-lg: 20px;

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4.5rem;

  --shadow-sm: 0 1px 2px rgba(43, 32, 24, 0.12);
  --shadow-md: 0 8px 24px rgba(43, 32, 24, 0.18);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

html { background: var(--color-bg); }

body {
  position: relative;
  margin: 0;
  background: transparent;
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.6;
  text-rendering: optimizeLegibility;
}

/* The page background is just the flat --color-bg fill set on html above
   (line 59), the same on every page. This used to be followed by an
   animated blurred blue gradient layer (body::before) plus its
   @keyframes bg-drift; both were removed here when the client asked for
   a flat background site-wide instead. See git history to restore it. */

/* ---------- Homepage showcase strip background ----------
   Homepage-only (markup lives in index.php / ar/index.php, not in the
   shared partials), so every other page keeps the plain body::before
   gradient above untouched. This wrapper used to host a looping video
   background (see git history), scoped to the strip of content between
   the two bg-primary bands (the hero above and the "Get in touch" band
   below). The video was removed at the client's request and replaced
   with this flat fill color instead; the wrapper div is kept (now with
   no special positioning needed) so the markup didn't have to be
   restructured again. */
.video-strip {
  background-color: #F5F4F0;
}

/* Homepage-only intro section (markup lives in index.php / ar/index.php),
   sitting between the header and the bg-primary band that used to start
   immediately below the nav. min-height fills roughly the rest of the
   viewport so only the header and this centered heading are visible on
   load; the bg-primary band now sits below the fold until the visitor
   scrolls. 89px approximates the site header's rendered height
   (.header-inner's padding-block + the 3.5rem logo + the 1px border);
   adjust that number here if the header's own height ever changes. */
.hero-intro {
  min-height: calc(100vh - 89px);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  background: var(--color-bg);
}
.hero-intro-heading {
  font-family: 'Montserrat', var(--font-sans);
  font-size: 55px;
  font-weight: 400;
  line-height: 1.3;
  color: #0A026E;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  /* Matches .container's own max-width (var(--max-width), 72rem) so this
     heading wraps at the same width as the centered text in the
     "Get in touch" band below (that band's .lede has no narrower cap of
     its own, so it fills .container up to the same 72rem). Was 54rem. */
  max-width: var(--max-width);
  margin-inline: auto;
}

/* ---------- Homepage-only typography + showcase-box recolor ----------
   Scoped to body.home (added on <body> in index.php only) rather than
   changed on the shared --color-primary token, since --color-primary and
   .showcase-box are also used/referenced on every other page. .bg-primary
   itself no longer needs a homepage-specific override: its own rule below
   was updated to the same #0B0384 -> #131F33 gradient sitewide (see that
   rule's comment). On this page only: every text element uses Montserrat
   at a uniform weight of 400 instead of the heavier weights baked into
   h1-h4/.btn/etc. elsewhere; the showcase boxes use the same
   #0B0384 -> #131F33 gradient as .bg-primary instead of a flat navy; and
   the off-white/light-blue text colors inside the bg-primary bands become
   a flat #FFFFFF. .showcase-box's own text was already #fff, so it
   needed no change. */
body.home,
body.home * {
  font-family: 'Montserrat', var(--font-sans);
  font-weight: 400;
}
body.home .showcase-box {
  background: linear-gradient(160deg, rgba(11, 3, 132, 0.94), rgba(19, 31, 51, 0.96));
}
body.home .bg-primary h1,
body.home .bg-primary h2,
body.home .bg-primary p,
body.home .bg-primary .lede {
  color: #FFFFFF;
}

/* Consulting box (home page only): background and logo removed per the
   client's request, so it no longer reads as a navy panel like the
   Sister Companies box beside it. Border and shadow are also removed
   (the client asked to drop "the box" entirely), so this is just the
   intro paragraph and the Explore Consulting button, centered, floating
   directly on the page with no card chrome at all. */
body.home .showcase-consulting {
  background: none;
  border: none;
  box-shadow: none;
  text-align: center;
  gap: 0;
}
body.home .showcase-consulting .consulting-intro {
  font-family: 'Montserrat', var(--font-sans);
  font-weight: 400;
  font-size: 28px;
  color: #0B0384;
  /* One blank line's worth of space before the button below: 1.6em at
     this element's own font-size, i.e. one full line-height at the
     site's default 1.6 line-height ratio. gap is zeroed above so this
     margin is the only spacing between the two, instead of stacking on
     top of it. */
  margin-block-end: 1.6em;
}
body.home .showcase-consulting a {
  color: #0B0384;
}
body.home .showcase-consulting a:hover {
  color: var(--color-accent);
}
/* Explore Consulting button: subtle lift on hover, so it still reads as
   clickable now that the box around it has no border or shadow of its
   own to hint at interactivity. */
body.home .showcase-consulting .btn {
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
body.home .showcase-consulting .btn:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.08);
}

/* Corporate Affiliates page: light text on the dark .bg-primary bands
   becomes a flat #FFFFFF, same approach as body.home above. Scoped to
   body.affiliates rather than the shared .bg-primary rule (used
   site-wide) so no other page's off-white/light-blue band text changes. */
body.affiliates .bg-primary h1,
body.affiliates .bg-primary h2,
body.affiliates .bg-primary p,
body.affiliates .bg-primary .lede {
  color: #FFFFFF;
}

/* Consulting page: same approach again, this time also setting every
   element's font to Montserrat 400. h1 is included in the color
   selector below for consistency, but "Trusted advice. Real impact."
   keeps its own gold color regardless: it has its own inline
   style="color:#FFD700" in consulting/index.php, and an inline style
   always wins over a class selector like this one, so that's the one
   dark-band heading this rule doesn't actually touch. */
body.consulting,
body.consulting * {
  font-family: 'Montserrat', var(--font-sans);
  font-weight: 400;
}
body.consulting .bg-primary h1,
body.consulting .bg-primary h2,
body.consulting .bg-primary p,
body.consulting .bg-primary .lede {
  color: #FFFFFF;
}

/* About ("Who We Are") page: same font treatment as Consulting above, plus
   a two-way text color split per the client's request: white on the dark
   .bg-primary bands, and a dark blue (#0B0384) everywhere else, since
   every other section on this page sits on the light page background or
   the translucent .bg-alt panel. The "Who We Are" heading itself is the
   one exception, styled gold via its own inline style in about/index.php
   (that always wins over this class rule, same approach as the "Trusted
   advice. Real impact." heading on /consulting/). Link hover keeps the
   sitewide accent color so links still read as interactive. */
body.about,
body.about * {
  font-family: 'Montserrat', var(--font-sans);
  font-weight: 400;
}
body.about .bg-primary h1,
body.about .bg-primary h2,
body.about .bg-primary p,
body.about .bg-primary .lede {
  color: #FFFFFF;
}
body.about section:not(.bg-primary) h2,
body.about section:not(.bg-primary) h3,
body.about section:not(.bg-primary) p,
body.about section:not(.bg-primary) .lede,
body.about section:not(.bg-primary) summary,
body.about section:not(.bg-primary) a {
  color: #0B0384;
}
body.about section:not(.bg-primary) a:hover {
  color: var(--color-accent);
}
/* The four "How we think and work" question headers: larger than the
   sitewide 1rem base per the client's request, matching the site's own
   h3 size so they read as a clear step up from the answer text below
   them. */
body.about .think-work-item summary {
  font-size: 1.25rem;
}

/* /profiles/mohammed/ page: same font + two-way color split as About
   above. White on the dark .bg-primary hero and closing CTA bands
   (including the eyebrow text and the "Available for consulting ·
   email · LinkedIn" line, which set their own inline color in
   profiles/mohammed/index.php since an inline style always wins over a
   class rule); #0B0384 everywhere else, i.e. the Background, Three
   areas of practice, and testimonials sections, all on the light page
   background or the translucent .bg-alt panel. Covers the numbered
   "01/02/03" practice markers and the testimonial attribution lines
   too, both of which have their own lower-specificity color rules
   elsewhere that this scoped one outweighs. */
body.mohammed,
body.mohammed * {
  font-family: 'Montserrat', var(--font-sans);
  font-weight: 400;
}
body.mohammed .bg-primary h1,
body.mohammed .bg-primary h2,
body.mohammed .bg-primary p,
body.mohammed .bg-primary .lede {
  color: #FFFFFF;
}
body.mohammed section:not(.bg-primary) h2,
body.mohammed section:not(.bg-primary) h3,
body.mohammed section:not(.bg-primary) p,
body.mohammed section:not(.bg-primary) .lede,
body.mohammed section:not(.bg-primary) a,
body.mohammed section:not(.bg-primary) .testimonial-signature,
body.mohammed section:not(.bg-primary) .practice-number {
  color: #0B0384;
}
body.mohammed section:not(.bg-primary) a:hover {
  color: var(--color-accent);
}

/* /profiles/adam/'s placeholder page: a single .bg-primary section, so
   every piece of text on it (including the "Back to Our People" link,
   whose .btn-outline border tracks the same color via currentColor) is
   in scope for the dark-background white-text rule; there is no
   light-background content on this page to need the second block that
   about/mohammed have above. */
body.adam,
body.adam * {
  font-family: 'Montserrat', var(--font-sans);
  font-weight: 400;
}
body.adam .bg-primary h1,
body.adam .bg-primary p,
body.adam .bg-primary .lede,
body.adam .bg-primary a {
  color: #FFFFFF;
}

/* /profiles/ (the "Our People" index, listing Mohammed and Adam's cards):
   same font + two-way color split as body.about/body.mohammed above,
   white on the dark .bg-primary hero, #0B0384 on the light-background
   card grid below it, including the card headings/body text and the
   "View profile" links. */
body.profiles,
body.profiles * {
  font-family: 'Montserrat', var(--font-sans);
  font-weight: 400;
}
body.profiles .bg-primary h1,
body.profiles .bg-primary h2,
body.profiles .bg-primary p,
body.profiles .bg-primary .lede {
  color: #FFFFFF;
}
body.profiles section:not(.bg-primary) h2,
body.profiles section:not(.bg-primary) h3,
body.profiles section:not(.bg-primary) p,
body.profiles section:not(.bg-primary) .lede,
body.profiles section:not(.bg-primary) a {
  color: #0B0384;
}
body.profiles section:not(.bg-primary) a:hover {
  color: var(--color-accent);
}

/* /faq/: same font + two-way color split as body.about/body.mohammed/
   body.profiles above. summary is included in the light-background
   selector since the Q&A list is a <details>/<summary> accordion, same
   as the "How we think and work" accordion on /about/. */
body.faq,
body.faq * {
  font-family: 'Montserrat', var(--font-sans);
  font-weight: 400;
}
body.faq .bg-primary h1,
body.faq .bg-primary h2,
body.faq .bg-primary p,
body.faq .bg-primary .lede {
  color: #FFFFFF;
}
body.faq section:not(.bg-primary) h2,
body.faq section:not(.bg-primary) p,
body.faq section:not(.bg-primary) .lede,
body.faq section:not(.bg-primary) summary,
body.faq section:not(.bg-primary) a {
  color: #0B0384;
}
body.faq section:not(.bg-primary) a:hover {
  color: var(--color-accent);
}

/* /contact/: same font + two-way color split as the pages above. address
   and label are added to the light-background selector since this page's
   "Direct contact" block and form labels aren't covered by h2/h3/p/.lede/a. */
body.contact,
body.contact * {
  font-family: 'Montserrat', var(--font-sans);
  font-weight: 400;
}
body.contact .bg-primary h1,
body.contact .bg-primary h2,
body.contact .bg-primary p,
body.contact .bg-primary .lede {
  color: #FFFFFF;
}
body.contact section:not(.bg-primary) h2,
body.contact section:not(.bg-primary) h3,
body.contact section:not(.bg-primary) p,
body.contact section:not(.bg-primary) .lede,
body.contact section:not(.bg-primary) address,
body.contact section:not(.bg-primary) label,
body.contact section:not(.bg-primary) a {
  color: #0B0384;
}
body.contact section:not(.bg-primary) a:hover {
  color: var(--color-accent);
}

/* Tightens just the 3-line postal address ("P.O. Box 5133 / Amman, 11183 /
   Jordan") to single-line spacing, separately from the rest of the
   <address> block, then a blank line before the email link restores a
   visible gap. See contact/index.php. */
.contact-address-lines {
  display: block;
  line-height: 1.2;
}

/* ---------- Consulting: "Countries we operate in" interactive map ----------
   Styled after the client's own reference map: the reference image is
   used as a plain background picture, occupying 64% of this component's
   own width; the remaining 14%/22% side margins (left/right) hold
   leader-line labels for the small Gulf states plus Lebanon and Jordan,
   the same layout the reference uses, while the three large countries
   with room to spare (Saudi Arabia, Syria, Oman) get their name set
   directly inside their own shape. See the $map_countries comment in
   consulting/index.php for how the box's 14%/64%/22% column split maps
   onto pixel coordinates.
   Three layers, in DOM/paint order:
     1. img                the reference map picture
     2. .ops-map-lines     a purely decorative SVG: one leader line +
                            anchor dot per margin-label country. Takes
                            no part in hover behavior.
     3. .map-country + .map-label pairs   the interactive layer: an
                            invisible hover hotspot (clip-path, not
                            hand-drawn -- see that same PHP comment)
                            immediately followed by its always-visible
                            name label. Hover/focus washes a light tint
                            over the hotspot and bolds its label via the
                            adjacent-sibling combinator below, so that
                            pairing must stay intact in the markup. */
.ops-map-wrap {
  max-width: 60rem;
  margin-inline: auto;
}
.ops-map {
  position: relative;
  /* Matches the 1875x1083 box the PHP-side coordinates (clip paths,
     label positions, the SVG viewBox) are all computed against: image
     width (1200) / 0.64 = 1875 wide, image height (1083) unchanged. */
  aspect-ratio: 1875 / 1083;
}
.ops-map img {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 14%;
  inline-size: 64%;
  block-size: 100%;
  object-fit: fill;
  border-radius: var(--radius-md);
}
.ops-map-lines {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  overflow: visible;
  pointer-events: none;
}
.map-leader {
  fill: none;
  stroke: #8a7f6a;
  stroke-width: 1.5;
  /* Keeps the line a constant visual thickness as the map scales with
     viewport width, instead of thickening on a wide screen. */
  vector-effect: non-scaling-stroke;
}
.map-dot {
  fill: var(--color-text);
}
.map-country {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  /* Not fully transparent: a near-zero alpha background keeps the
     hotspot reliably hit-testable (and hover/focus-tintable) across
     browsers, while reading as invisible at rest. */
  background: rgba(217, 242, 208, 0.001);
  cursor: pointer;
  transition: background 0.15s ease;
}
.map-country:hover,
.map-country:focus-visible {
  background: rgba(217, 242, 208, 0.75);
}
.map-country:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 1px;
}
.map-label {
  position: absolute;
  transform: translate(-50%, -50%);
  font-family: 'Montserrat', var(--font-sans);
  font-size: 1rem;
  font-weight: 400;
  color: var(--color-text);
  pointer-events: none;
  white-space: nowrap;
}
.map-country:hover + .map-label,
.map-country:focus-visible + .map-label {
  font-weight: 700;
}
/* Homepage-only: the map's country names use a different text color here
   than on /consulting/, per the client's request. Scoped to body.home so
   the Consulting page's copy of this same partial is unaffected. */
body.home .map-label {
  color: #0B0384;
}
/* Leader-line labels (the margin countries) sit in the narrower side
   columns, so they wrap rather than truncate (United Arab Emirates
   wraps to two lines, matching the reference), and grow away from
   their anchor point instead of being centered on it. Font size is
   intentionally NOT overridden here: every label on the map, inline or
   leader-line, uses the same Montserrat size as "Saudi Arabia" (set on
   .map-label above), per the client's request. */
.map-label--leader {
  white-space: normal;
  line-height: 1.2;
  max-inline-size: 9rem;
}
.map-label--start {
  text-align: start;
  transform: translate(0, -50%);
}
.map-label--end {
  text-align: end;
  transform: translate(-100%, -50%);
}
@media (max-width: 700px) {
  .map-label { font-size: 0.75rem; }
  .map-label--leader { max-inline-size: 7rem; }
}
@media (max-width: 480px) {
  .map-label { font-size: 0.65rem; }
  .map-label--leader { max-inline-size: 5.5rem; }
}

img, svg { max-width: 100%; display: block; }
h1, h2, h3, h4 { line-height: 1.2; margin: 0 0 var(--space-3); font-weight: 700; }
h1 { font-size: clamp(2rem, 1.5rem + 2vw, 3.25rem); }
h2 { font-size: clamp(1.5rem, 1.3rem + 1vw, 2.25rem); }
h3 { font-size: 1.25rem; }
p { margin: 0 0 var(--space-4); color: var(--color-text); }
.lede { font-size: 1.125rem; color: var(--color-text-muted); max-width: 107ch; }

/* Default link color uses --color-primary rather than the amber accent: several
   links (contact mailto, in-page cross-links) sit directly on the ambient
   gradient with no card/panel behind them, and the amber accent does not carry
   enough contrast against the more saturated blue gradient stops to pass WCAG
   AA there. --color-primary is dark enough to stay legible everywhere. The
   accent color remains in full use on protected surfaces (buttons, cards, the
   FAQ, the header/footer) where it is well clear of AA. */
a { color: var(--color-primary); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--color-accent); }

/* Visible, accessible focus state everywhere, required for keyboard and
   assistive-technology users, and satisfies "layout stability": outline
   does not shift layout because it sits outside the box (no border swap). */
:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* ---------- Skip link ---------- */
.skip-link {
  position: absolute;
  inset-inline-start: var(--space-3);
  top: -3rem;
  background: var(--color-primary);
  color: var(--color-on-primary);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  z-index: 100;
  transition: top 0.15s ease;
}
.skip-link:focus { top: var(--space-3); }

/* ---------- Layout ---------- */
.container {
  width: 100%;
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

section { padding-block: var(--space-8); background: transparent; }
section.tight { padding-block: var(--space-6); }
.bg-alt { background: var(--color-surface-alt); backdrop-filter: blur(3px); }
/* Sitewide dark band. Updated from the original #1D2F4E -> #131F33
   gradient to #0B0384 -> #131F33 per the client's request, rolled out
   first to the homepage and the consulting page individually (see git
   history for those now-removed body.home/body.consulting overrides),
   then applied here to every remaining page that uses .bg-primary
   (about, contact, faq, profiles, trading, and their Arabic mirrors). */
.bg-primary {
  background: linear-gradient(160deg, rgba(11, 3, 132, 0.94), rgba(19, 31, 51, 0.96));
  color: var(--color-on-primary);
}
.bg-primary h1, .bg-primary h2, .bg-primary p { color: var(--color-on-primary); }
.bg-primary .lede { color: #c9d6e8; }

/* ---------- Header / nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--color-bg);
  border-block-end: 1px solid var(--color-border);
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-4);
}
/* The wordmark is now the SARRIF logo image rather than text. Height is set to
   2.8x the previous text wordmark's font-size (1.25rem * 2.8 = 3.5rem) per the
   client's spec; width is automatic so the logo's aspect ratio is preserved.
   The surrounding flex row (.header-inner, align-items: center) centers it
   vertically without any extra rules needed here. */
.wordmark {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}
.wordmark img {
  display: block;
  height: 3.5rem;
  width: auto;
}

.primary-nav ul {
  list-style: none;
  display: flex;
  gap: var(--space-6);
  margin: 0;
  padding: 0;
}
.primary-nav a {
  color: var(--color-text);
  text-decoration: none;
  font-family: 'Montserrat', var(--font-sans);
  font-weight: 400;
  font-size: 12px;
  padding-block: var(--space-2);
  border-block-end: 2px solid transparent;
}
.primary-nav a:hover,
.primary-nav a[aria-current="page"] {
  color: var(--color-accent-strong);
  border-block-end-color: var(--color-accent-strong);
}

/* Mobile nav trigger: a plain hamburger icon (three horizontal lines)
   instead of a text "Menu" button, per the client's spec. Hidden above
   the 860px breakpoint below, where the full .primary-nav list shows
   inline instead. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  inline-size: 2.5rem;
  block-size: 2.5rem;
  padding: 0;
  font: inherit;
  cursor: pointer;
}
.nav-toggle-icon,
.nav-toggle-icon::before,
.nav-toggle-icon::after {
  display: block;
  inline-size: 22px;
  block-size: 2px;
  background: var(--color-text);
  border-radius: 2px;
}
.nav-toggle-icon {
  position: relative;
}
.nav-toggle-icon::before,
.nav-toggle-icon::after {
  content: "";
  position: absolute;
  inset-inline-start: 0;
}
.nav-toggle-icon::before { top: -7px; }
.nav-toggle-icon::after { top: 7px; }

.lang-switch {
  display: flex;
  gap: var(--space-2);
  font-size: 0.85rem;
}
.lang-switch a {
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-weight: 700;
}
.lang-switch a[aria-current="true"] {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border-color: var(--color-primary);
}

@media (max-width: 860px) {
  .nav-toggle { display: inline-flex; }
  .primary-nav {
    position: absolute;
    inset-inline: 0;
    top: 100%;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(16px) saturate(130%);
    border-block-end: 1px solid var(--color-border);
    box-shadow: var(--shadow-md);
  }
  .primary-nav[data-open="false"] { display: none; }
  .primary-nav ul { flex-direction: column; gap: 0; padding: var(--space-3) var(--space-5); }
  .primary-nav li { border-block-end: 1px solid var(--color-border); }
  .primary-nav li:last-child { border-block-end: none; }
  .primary-nav a { display: block; padding-block: var(--space-3); }
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font: inherit;
  font-weight: 700;
  font-size: 0.95rem;
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
  border: 2px solid transparent;
  cursor: pointer;
  text-decoration: none;
  line-height: 1.2;
}
.btn-primary {
  background: var(--color-accent-strong);
  color: var(--color-on-accent);
}
.btn-primary:hover { background: var(--color-accent); color: var(--color-on-accent); }
/* Gold button, applied per-button rather than as a sitewide .btn-primary
   recolor, since .btn-primary also styles the trading page's "Get in
   touch" button (and the Arabic-page equivalents), which stay the
   default color. Used on the "Contact us" CTAs and, per the client's
   request, the /contact/ form's "Send message" submit button. #FFD700 is
   a light gold, so text switches to the site's dark --color-text for
   contrast (11.3:1, well past AA) rather than the light --color-on-accent
   .btn-primary normally pairs it with. */
.btn-gold {
  background: #FFD700;
  color: var(--color-text);
}
.btn-gold:hover {
  background: #e6c200;
  color: var(--color-text);
}
.btn-outline {
  background: transparent;
  border-color: currentColor;
  color: inherit;
}
.btn-outline:hover { background: rgba(43, 32, 24, 0.08); }

/* Email/LinkedIn contact buttons on /profiles/mohammed/'s closing CTA.
   Solid gold fill per the client's request, same #FFD700/#e6c200-hover
   pair as the sitewide .btn-gold button (see that rule) rather than the
   multi-stop blue radial-gradient this used previously (see git history
   to restore it). Text stays the dark --color-text so it passes contrast
   against the light gold, same reasoning as .btn-gold; the SVG icons
   inherit that same color via currentColor. inline-size is fixed so both
   buttons render at the same width regardless of their very different
   label lengths ("mohammed@sarrif.com" vs "LinkedIn"), measured against
   the longer label's natural width, not guessed. */
.contact-btn {
  inline-size: 16.5rem;
  max-inline-size: 100%;
  justify-content: center;
  background: #FFD700;
  color: var(--color-text);
}
.contact-btn:hover {
  background: #e6c200;
  color: var(--color-text);
}
.btn-icon { inline-size: 1.125rem; block-size: 1.125rem; flex-shrink: 0; }

/* ---------- Cards / grid ---------- */
.grid-2 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-6);
}
.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-5);
}
@media (max-width: 780px) {
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
}

/* "Our People" team grid on /about/: sized to fit four profile-photo
   tiles across the same width the old two-box row used (.container
   itself is unchanged). A new class rather than reusing .grid-2, since
   that class is shared with /contact/ and /profiles/index/ and a
   4-column override there would break those pages' own 2-column
   layouts. Falls back to two columns on tablet widths and one on
   mobile, a tighter collapse than .grid-2/.grid-3 above since a photo
   tile still needs to read at a reasonable size at each step. */
.people-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-5);
  /* Without this, grid's default row-stretch would force the much
     shorter "Adam" .card to grow to the tall photo tile's height,
     leaving a large empty gap inside the card. Each item instead sizes
     to its own content. */
  align-items: start;
}
@media (max-width: 900px) {
  .people-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 480px) {
  .people-grid { grid-template-columns: 1fr; }
}

/* A team member's photo and name/title, both inside one link to their
   profile page per the client's request, so clicking either the photo
   or the caption opens it. Deliberately not a .card (no border,
   background, or padding): just the photo with its caption underneath.
   Base class has no underline and left-aligned (default) caption text;
   per-tile modifiers below opt into the underlined-link look (Mohammed)
   or centered caption text (Adam), since each tile in this row has its
   own explicit treatment rather than one shared default. Link color
   comes from the sitewide /about/ text-color rule
   (body.about section:not(.bg-primary) a), not repeated here. */
.person-tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  text-decoration: none;
}
/* The photo itself is never underlined regardless of this modifier,
   since browsers don't underline images; only the caption text is
   affected, which is the expected look for a typical underlined
   hyperlink. */
.person-tile--underline {
  text-decoration: underline;
}
.person-tile--center .person-caption {
  text-align: center;
}
.person-photo {
  width: 100%;
  /* height:auto overrides the img's width/height HTML attributes (which
     otherwise act as a fixed 817px default height, leaving aspect-ratio
     below with no "auto" dimension to compute and no visible effect). */
  height: auto;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius-lg);
  box-shadow: 10px 10px 24px rgba(43, 32, 24, 0.15);
}
.person-caption {
  line-height: 1.4;
}

/* Background section on /profiles/mohammed/: bio text with a photo to its
   right. Text column left over from the section's old single-column
   48rem reading width; giving it 1fr against a fixed 22rem photo column
   inside the standard 72rem .container lands it at almost that same
   ~720px reading width, so paragraph line length is effectively
   unchanged from before the photo was added. Below 780px (matching the
   .grid-2/.grid-3 stacking breakpoint above) it collapses to one column,
   photo above text, a visual reorder only; the underlying markup order
   (heading, then bio text, then photo) is unchanged, so screen readers
   still meet the text before the image at every width. */
.bio-layout {
  display: grid;
  grid-template-columns: 1fr 22rem;
  grid-template-areas: "text photo";
  gap: var(--space-6);
  align-items: center;
}
.bio-text { grid-area: text; }
.bio-photo {
  grid-area: photo;
  width: 100%;
  height: auto;
  object-fit: cover;
  border-radius: var(--radius-lg);
  box-shadow: 10px 10px 24px rgba(43, 32, 24, 0.15);
}
@media (max-width: 780px) {
  .bio-layout {
    grid-template-columns: 1fr;
    grid-template-areas: "photo" "text";
  }
}

.card {
  margin: 0;
  background: var(--color-surface);
  backdrop-filter: blur(16px) saturate(130%);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: 10px 10px 24px rgba(43, 32, 24, 0.15);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.card ul { margin: 0; padding-inline-start: 1.1em; color: var(--color-text-muted); }
.card ul li { margin-block-end: var(--space-1); }

/* Testimonial attribution lines ("- ICT Industry" etc.) on the What
   clients say cards, /profiles/mohammed/. margin-top: auto pushes each
   one to the bottom of its own card rather than sitting directly under
   its quote, since .card is a column flexbox and every card in a row is
   already stretched to the row's tallest card height, this lines every
   signature up at the same level across a row (matching where the
   longest quote's signature already naturally sits), regardless of how
   short the other quotes in that row are. */
.testimonial-signature {
  margin-top: auto;
  font-style: italic;
  color: var(--color-text-muted);
  font-size: .9rem;
}

/* Numbered practice-area cards on /profiles/mohammed/ ("01", "02", "03"
   ahead of each card's heading). Decorative only. The numbering is
   already conveyed by DOM/visual order, so it's aria-hidden and doesn't
   duplicate as accessible-name text for screen reader users. */
.practice-number {
  display: block;
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--color-primary);
  margin-block-end: calc(-1 * var(--space-2));
}

/* ---------- Homepage showcase boxes (Consulting / Sister Companies) ----------
   Fixed-proportion boxes per exact client spec: each is 29.5% of the page's
   full width, with the Consulting box's leading edge 0.5cm further toward
   the start edge than 18.5% of the page width, and the Sister Companies
   box's leading edge 0.5cm further toward the end edge than 48% (a visible
   1cm gap between the two boxes). Sized against the page width itself (not
   the .container max-width), so this section deliberately has no .container
   wrapper.

   Rebuilt as a CSS grid on 2026-09-13, replacing the previous absolute-
   positioning-plus-vw-formula approach. The old approach measured each
   box's content height by hand at one reference width (1440px) and baked
   that single measurement into a min-height formula, accurate at that one
   width, but real text doesn't reflow in exact proportion to viewport
   width, so at other widths (particularly the 1000-1200px range, where the
   narrower box pushes more text onto extra lines) the two boxes could grow
   unevenly and stop matching. A CSS grid row with the default item
   alignment (stretch) removes that guesswork entirely: the row's height is
   always exactly the taller box's actual content height at whatever width
   the browser is currently at, and the shorter box is automatically
   stretched to match it, at every width, not just the one that was
   measured. This makes genuine content overflow impossible (the row can
   never be shorter than either box needs) and keeps both boxes the same
   height at every width, not only the reference width.

   grid-template-columns lays out five tracks: a leading spacer sized to
   push the Consulting box to its 18.5%-minus-0.5cm start position, the
   Consulting box itself (29.5vw), a 1cm gap, the Sister Companies box
   (29.5vw), and a trailing 1fr spacer absorbing the remaining page width.
   Grid track numbering runs from the inline-start edge in whichever
   direction text flows, so this mirrors correctly on the Arabic (rtl)
   pages with no separate rule needed, the same way the previous
   inset-inline-start approach did.

   One residual, unavoidable effect worth knowing: if Consulting's and
   Sister Companies' own content need different heights (different amounts
   of text, different logos), stretching both to the same row height means
   whichever box needs less content height will show that small difference
   as empty space at its own bottom, since matching height and zero empty
   space in both boxes at once is only possible if their content happens to
   need exactly the same height. See docs/CONTENT-NOTES.md for the measured
   size of that difference at the reference width. */
/* Stacked layout, adopted 2026-09-13 (Consulting above Sister Companies,
   both full width up to 107ch), replacing the side-by-side grid described
   in the comment above. The client tried the grid version first. It
   solved logo alignment and overflow but couldn't also guarantee equal
   height with zero wasted space at every width (see docs/CONTENT-NOTES.md),
   and chose this stacked arrangement instead, since stacked boxes aren't
   compared against each other's height the way side-by-side ones are. */
.showcase-boxes {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-5);
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--space-5);
  padding-block-start: var(--space-8);
  /* Bottom padding reduced below the sitewide section default (var(--space-8))
     to tighten the gap before "Who We Are", per the client's request; see
     the matching override on the very next section, below. */
  padding-block-end: var(--space-5);
}
/* Targets whichever section immediately follows the showcase boxes ("Who We
   Are" on both the English and Arabic homepages) without needing an extra
   class in the markup. Its top padding is reduced to match the override
   above, so the two overrides together, not just one, are what closes the
   gap; changing only one half would leave the other section's own padding
   holding the gap open. */
.showcase-boxes + section {
  padding-block-start: var(--space-5);
}
/* Fixed 107-character-wide column for both boxes, per the client's request,
   rather than stretching to the full container width. align-items: center
   above centers each box horizontally in the stacked column, since a 107ch
   box is narrower than the container at most widths (it still fits within
   the container's own max-width, so max-inline-size: 100% below is a
   narrow-screen safety net, not something that kicks in on typical desktop
   widths; see the verification note in docs/CONTENT-NOTES.md). */
.showcase-consulting,
.showcase-sister { inline-size: 107ch; max-inline-size: 100%; }
.showcase-box {
  background: #1d2f4e;
  color: #fff;
  border-color: rgba(255, 255, 255, 0.15);
  backdrop-filter: none;
}
.showcase-box p,
.showcase-box ul,
.showcase-box li { color: #fff; }
.showcase-box a { color: #fff; }
.showcase-box a:hover { color: #ffd700; }
.showcase-box .btn-outline:hover { background: rgba(255, 255, 255, 0.12); }
/* Body text inside both boxes is sized to match the hero paragraph
   (.lede: 1.125rem / 1.6 line-height) per the client's spec. Padding and
   gaps stay tight, since this text size needs meaningfully more room than
   the site's normal small-print scale; see docs/CONTENT-NOTES.md for how
   much room is actually needed at this size versus what the fixed box
   height provides. */
.showcase-box.card { padding: 0.5cm; gap: var(--space-2); }
.showcase-box p { margin-block-end: 0; font-size: 1.125rem; line-height: 1.6; }
.showcase-box ul { padding-inline-start: 1.1em; margin: 0; }
.showcase-box li { margin-block-end: var(--space-1); font-size: 1.125rem; line-height: 1.6; }
.showcase-box .btn { font-size: 1.125rem; }
/* Both heading logos sit the same 0.5cm below the box's own padding edge,
   so the two logos line up on the same horizontal level across both boxes
   despite the logos themselves being different heights (see
   .showcase-logo vs .showcase-sister-logo below). This one shared rule
   replaced two separate per-box rules (0.5cm and 0.7cm) that had drifted
   out of sync with each other; see docs/CONTENT-NOTES.md. */
.showcase-box h3 { margin: 0; margin-block-start: 0.5cm; }
.showcase-logo { display: block; height: 3rem; width: auto; }
/* Sister Companies heading is this white-on-navy logo image, the same
   treatment as the Consulting box's logo. */
.showcase-sister-logo { display: block; height: 1.3rem; width: auto; max-width: 100%; }
/* Sister Companies grid: sqft and FC (FitCheck) as two matching white
   cards, stacked one over the other (sqft on top; markup order in
   corporate-affiliates/index.php controls that), inside the still-navy
   .showcase-sister outer box. Every color/typography rule here needs to
   out-specificity the generic .showcase-box a / .showcase-box p rules
   above (which turn text white for the navy box), so each selector below
   is deliberately qualified with .showcase-sister, not just
   .sister-card / .sister-card-logo on their own, even though that reads
   as slightly redundant. */
.sister-grid {
  display: grid;
  /* Single column: the two cards stack vertically instead of sitting
     side by side. Was "1fr 1fr". */
  grid-template-columns: 1fr;
  /* At least one blank line's worth of separation between the two cards,
     per the client's request; was var(--space-4) (1rem). */
  gap: var(--space-7);
}
.showcase-sister .sister-card {
  display: flex;
  /* Logo on the left, text to its right, both vertically centered on
     the row. Was "flex-direction: column" (logo above text, centered). */
  flex-direction: row;
  align-items: center;
  text-align: start;
  gap: var(--space-4);
  background: #fff;
  border: 1px solid #E2E8F0;
  border-radius: var(--radius-md);
  padding: var(--space-4);
  color: var(--color-text);
  text-decoration: none;
  box-shadow: 10px 10px 24px rgba(43, 32, 24, 0.15);
  transition: border-color 0.15s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.showcase-sister .sister-card:hover {
  border-color: #CBD5E1;
  /* Subtle lift on hover, same treatment as the homepage's Explore
     Consulting button, so these cards read as interactive too. */
  transform: translateY(-3px);
  box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.08);
}
.sister-card-logo {
  inline-size: 6.75rem;
  block-size: 6.75rem;
  object-fit: contain;
  border-radius: var(--radius-sm);
  /* Keeps the logo at full size instead of being squeezed by the text
     column now sitting beside it in the row layout. */
  flex-shrink: 0;
}
.showcase-sister .sister-card p {
  color: var(--color-text-muted);
  font-size: 0.95rem;
  line-height: 1.55;
  margin: 0;
}
@media (max-width: 480px) {
  /* Logo-left/text-right doesn't have room to breathe at phone widths,
     so each card's own contents drop back to a centered column stack
     there; the outer grid is already single-column at every size. */
  .showcase-sister .sister-card {
    flex-direction: column;
    text-align: center;
  }
}

/* /corporate-affiliates/: the sqft and FitCheck cards at half their
   normal width per the client's request. Scoped to body.affiliates so
   the same .sister-card markup in the "Sister Companies" box on
   ar/index.php keeps its full-width layout. The grid's single column
   still stretches its item to full width by default, so an explicit
   inline-size needs margin-inline: auto to stay centered rather than
   drift to the start edge. Reverts to full width under 480px, where a
   half-width card would leave too little room for the logo-above-text
   stack to read comfortably. */
body.affiliates .sister-card {
  inline-size: 50%;
  margin-inline: auto;
}
@media (max-width: 480px) {
  body.affiliates .sister-card {
    inline-size: 100%;
  }
}

/* ---------- Homepage "Who We Are" box ----------
   Same 107ch width and centering as the Consulting/Sister Companies boxes
   above, so all three homepage boxes read as one family. Background and
   border now match the FC/sqft sister-cards exactly (flat white,
   1px solid #E2E8F0) instead of the old blue radial-gradient card (see
   git history), per the client's request to make this box match those. */
.about-box {
  inline-size: 107ch;
  max-inline-size: 100%;
  margin-inline: auto;
  align-items: center;
  text-align: center;
  background: #fff;
  backdrop-filter: none;
  border: 1px solid #E2E8F0;
  box-shadow: 10px 10px 24px rgba(43, 32, 24, 0.15);
}
.about-box h2,
.about-box p { color: var(--color-text); }
.about-box .lede { color: var(--color-text-muted); margin-inline: auto; }

.pillar {
  border-inline-start: 4px solid var(--color-primary);
  padding-inline-start: var(--space-4);
}

/* ---------- Service list (numbered) ---------- */
.service {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: var(--space-4);
  padding-block: var(--space-5);
  border-block-end: 1px solid var(--color-border);
}
.service:last-child { border-block-end: none; }
.service .num {
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--color-primary);
}
@media (max-width: 600px) {
  .service { grid-template-columns: 1fr; }
}

/* A single service item can carry a photo to its left (e.g. item 01 on
   /consulting/). Uses the same grid-template-areas approach as .bio-layout
   above: the text stays first in markup (so screen readers meet it before
   the image), the photo is placed visually via its named grid area, not
   DOM order. Below 780px it stacks, photo above text, matching .bio-layout. */
.service-block {
  display: grid;
  grid-template-columns: 20rem 1fr;
  grid-template-areas: "photo text";
  gap: var(--space-6);
  align-items: center;
  padding-block: var(--space-5);
  border-block-end: 1px solid var(--color-border);
}
/* Modifier for a photo on the right instead of the left, same component,
   columns and named areas mirrored. Markup order is unchanged either way
   (text first, photo second) so reading order never depends on which side
   the photo is drawn on. */
.service-block--right {
  grid-template-columns: 1fr 20rem;
  grid-template-areas: "text photo";
}
.service-block .service {
  grid-area: text;
  padding-block: 0;
  border-block-end: none;
}
.service-block-photo {
  grid-area: photo;
  width: 100%;
  height: auto;
  object-fit: cover;
  border-radius: var(--radius-lg);
  box-shadow: 10px 10px 24px rgba(43, 32, 24, 0.15);
}
@media (max-width: 780px) {
  .service-block,
  .service-block--right {
    grid-template-columns: 1fr;
    grid-template-areas: "photo" "text";
  }
}

/* ---------- FAQ (native disclosure, no JS required, fully accessible) --- */
.faq-item {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-block-end: var(--space-3);
  background: var(--color-surface);
  backdrop-filter: blur(16px) saturate(130%);
  overflow: hidden;
}
.faq-item summary {
  cursor: pointer;
  font-weight: 700;
  padding: var(--space-4) var(--space-5);
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+";
  font-size: 1.25rem;
  color: var(--color-accent-strong);
  flex-shrink: 0;
}
.faq-item[open] summary::after { content: "\2212"; }
.faq-item .faq-answer { padding: 0 var(--space-5) var(--space-5); color: var(--color-text-muted); }

/* ---------- "How we think and work" (about page, same native
   disclosure pattern as .faq-item above, with a bold, large "+"/"−"
   marker per the client's spec rather than the FAQ's smaller accent-brown
   one). Marker color is #1D2F4E, set explicitly per the client's request.
   The first item ships with the native `open` attribute so its answer is
   expanded on page load; the disclosure toggle itself is native browser
   behavior, no JS involved. */
.think-work-item {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-block-end: var(--space-3);
  background: var(--color-surface);
  backdrop-filter: blur(16px) saturate(130%);
  overflow: hidden;
}
.think-work-item summary {
  cursor: pointer;
  font-weight: 700;
  padding: var(--space-4) var(--space-5);
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
}
.think-work-item summary::-webkit-details-marker { display: none; }
.think-work-item summary::after {
  content: "+";
  font-size: 2rem;
  font-weight: 800;
  line-height: 1;
  color: #1D2F4E;
  flex-shrink: 0;
}
.think-work-item[open] summary::after { content: "\2212"; }
.think-work-item .think-work-answer { padding: 0 var(--space-5) var(--space-5); color: var(--color-text-muted); }
.think-work-item .think-work-answer p:last-child { margin-bottom: 0; }

/* ---------- Forms ---------- */
.form-field { margin-block-end: var(--space-4); }
.form-field label {
  display: block;
  font-weight: 700;
  margin-block-end: var(--space-2);
}
.form-field input,
.form-field textarea,
.form-field select {
  width: 100%;
  font: inherit;
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.75);
  color: var(--color-text);
}
.form-field .hint { font-size: 0.85rem; color: var(--color-text-muted); margin-block-start: var(--space-1); }
.form-field.required label::after { content: " *"; color: var(--color-primary); }
.honeypot { position: absolute; inset-inline-start: -9999px; }

.form-status {
  padding: var(--space-4);
  border-radius: var(--radius-sm);
  margin-block-end: var(--space-5);
  font-weight: 600;
}
.form-status.success { background: #e4f3e6; color: #1e4620; border: 1px solid #bfe2c4; }
.form-status.error { background: #fbe7e7; color: #6b1d1d; border: 1px solid #f2bcbc; }

/* ---------- Footer ---------- */
.site-footer {
  border-block-start: 1px solid var(--color-border);
  padding-block: var(--space-7);
  background: var(--color-surface-alt);
  backdrop-filter: blur(6px);
}
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: var(--space-6);
}
@media (max-width: 780px) { .footer-grid { grid-template-columns: 1fr; } }
.footer-grid h3 { font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text-muted); }
.footer-grid ul { list-style: none; margin: 0; padding: 0; }
.footer-address-col { display: flex; flex-direction: column; justify-content: flex-end; padding-block-end: var(--space-2); }
.footer-grid li { margin-block-end: var(--space-2); }
.footer-grid a { color: var(--color-text); text-decoration: none; }
.footer-grid a:hover { color: var(--color-accent-strong); }
.footer-bottom {
  margin-block-start: var(--space-6);
  padding-block-start: var(--space-5);
  border-block-start: 1px solid var(--color-border);
  font-size: 0.85rem;
  color: var(--color-text-muted);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
}

/* ---------- Utility ---------- */
.text-center { text-align: center; }
.stack { display: flex; flex-direction: column; gap: var(--space-4); }
.cluster { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; }
.mt-6 { margin-block-start: var(--space-6); }
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
