/* ==========================================================================
   Alsandara ICT Consulting | shared design system
   Palette (keyed to the logo): ink / indigo / cobalt / sky on paper.
   Type: IBM Plex Sans (+ Condensed for display).
   Single light theme on purpose (see docs/audit-uiux.md section 5).
   Layout uses logical properties (inline = left/right in LTR) so an
   Arabic RTL build only needs dir="rtl" plus the block at the end.
   ========================================================================== */

:root {
  color-scheme: light;

  /* ---- Brand palette ---- */
  --ink: #0b1033;          /* logo navy, deepest */
  --ink-2: #1a2150;
  --ink-rgb: 11 16 51;     /* for overlays: rgb(var(--ink-rgb) / .6) */
  --indigo: #1b2a8c;       /* logo indigo */
  --indigo-2: #2a3db0;
  --cobalt: #3456ff;       /* accent: buttons, rules, icons (white text 5.36:1) */
  --cobalt-text: #2440d8;  /* cobalt dark enough for text and button hover (white text 7.5:1) */
  --cobalt-soft: #e6ebff;
  --sky: #9db1ff;          /* accent on dark surfaces */
  --paper: #f5f6fa;
  --paper-rgb: 245 246 250;
  --white: #ffffff;
  --slate: #5a6078;
  --line: #dde1ee;
  --line-dark: rgba(255, 255, 255, 0.14);        /* hairlines on dark */
  --line-dark-strong: rgba(255, 255, 255, 0.35); /* control borders on dark */

  /* ---- Text on dark surfaces (replaces the scattered white alphas) ---- */
  --on-dark-strong: rgba(255, 255, 255, 0.88);   /* links, nav on video */
  --on-dark-muted: rgba(255, 255, 255, 0.8);     /* ledes, body copy on dark (11.9:1 ink, 8.0:1 indigo) */
  --on-dark-subtle: rgba(255, 255, 255, 0.7);    /* captions, meta, tags (9.3:1 ink, 6.6:1 indigo) */

  /* ---- Status / misc ---- */
  --danger: #b3261e;       /* errors (6.5:1 on white) */
  --field-border: #8a90a8; /* form control border (3.2:1 on white) */
  --wa-green: #1f9d55;

  /* ---- Semantic aliases ---- */
  --accent: var(--cobalt);
  --accent-text: var(--cobalt-text);
  --accent-soft: var(--cobalt-soft);
  --brand: var(--indigo);

  /* Focus ring colour. Cobalt on light surfaces; redefined to sky on dark
     surfaces further down (.section--dark, .cta-band, .vhero, ...). */
  --focus: var(--cobalt);

  /* ---- Legacy names (kept as aliases; page CSS still uses them) ---- */
  --petrol: var(--indigo);
  --petrol-2: var(--indigo-2);
  --sand: var(--cobalt);
  --sand-text: var(--cobalt-text);
  --sand-soft: var(--cobalt-soft);

  /* ---- Type ---- */
  --font-body: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-display: "IBM Plex Sans Condensed", "IBM Plex Sans", system-ui, sans-serif;

  /* modular scale ~1.25 */
  --step--2: 0.8rem;
  --step--1: 0.875rem;
  --step-0: 1rem;
  --step-1: 1.25rem;
  --step-2: 1.5625rem;
  --step-3: clamp(1.75rem, 1.4rem + 1.4vw, 2.4rem);
  --step-4: clamp(2.2rem, 1.6rem + 2.6vw, 3.4rem);
  --step-5: clamp(2.6rem, 1.7rem + 4vw, 4.6rem);

  /* ---- Layout ---- */
  --gutter: clamp(1rem, 4vw, 2.5rem);
  --max: 1200px;
  --section: clamp(4rem, 8vw, 7.5rem);
  --header-h: 72px;

  /* ---- Radius. The rule:
       6px   --radius-control  controls: buttons, inputs, selects, nav links, small panels
       12px  --radius-surface  surfaces and media: .photo, .panel, dark panels, figures, hero stats strip
       999px --radius-pill     ONLY tags, filter chips and floating pills (pause, WhatsApp)
       50%                     ONLY round counters, monograms and icon circles
     Nothing else. ---- */
  --radius-control: 6px;
  --radius-surface: 12px;
  --radius-pill: 999px;
  --radius: var(--radius-control); /* legacy alias */

  /* ---- Motion (docs/audit-motion.md) ---- */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);      /* enter, press, state change */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);  /* on-screen movement */
  --dur-press: 120ms;   /* :active scale */
  --dur-hover: 150ms;   /* hover colour */
  --dur-exit: 150ms;    /* things closing */
  --dur-state: 200ms;   /* state change, crossfades */
  --dur-enter: 220ms;   /* things opening */
}

/* ---- Phone scale (docs/audit-mobile.md S3, S7). Desktop tokens above stay unchanged.
     At 390px: h1 ~35 / h2 ~28.5 / h3 21 / service + value h3 24 / lede + h4 18 / body 16.
     --header-h drives the header row, the mobile menu sheet and any sticky offsets:
     page CSS should use top: var(--header-h) / scroll-margin-top: calc(var(--header-h) + ...). ---- */
@media (max-width: 600px) {
  :root {
    --step-1: 1.125rem;                                   /* 18px: ledes, h4, list heads */
    --step-2: 1.3125rem;                                  /* 21px: card/case/member h3 */
    --step-3: 1.5rem;                                     /* 24px: service rows, value h3, quote */
    --step-4: clamp(1.625rem, 1.1rem + 2.8vw, 2.125rem);  /* h2 ~28.5px at 390 */
    --step-5: clamp(2rem, 1.4rem + 3.2vw, 2.5rem);        /* page h1 ~35px at 390 */
    --section: 3.5rem;                                    /* 56px section padding */
    --header-h: 60px;
  }
}
/* Short landscape phones: the header takes less of the ~340px height */
@media (orientation: landscape) and (max-height: 500px) {
  :root { --header-h: 56px; }
}

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

html { -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
/* Same-page anchors glide; reduced motion (and anything unsupported) jumps */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

/* ---- Touch baseline (S1): no double-tap zoom delay on controls, no text selection or
     callout on long-press of controls. Press feedback comes from the :active rules below. ---- */
a, button, summary, label, [role="button"] { touch-action: manipulation; }
.btn, .nav-toggle, .nav__link, .case-filter__btn, .vhero__pause, .wa-float, summary {
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
/* Open mobile menu (class set on <html> by main.js): lock the page behind the sheet */
html.menu-open { overflow: hidden; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--cobalt-soft); color: var(--ink); }

img, svg { display: block; max-width: 100%; }
a { color: inherit; }
p { margin: 0 0 1em; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.015em;
  margin: 0 0 0.5em;
  text-wrap: balance;
}
h1 { font-size: var(--step-5); letter-spacing: -0.025em; }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-2); line-height: 1.2; }
h4 { font-size: var(--step-1); line-height: 1.25; }
@media (max-width: 600px) {
  h1, h2 { line-height: 1.1; }
}

/* ---------- Focus ---------- */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}
/* Dark surfaces: sky ring (8.95:1 on ink, 5.79:1 on indigo) */
.section--dark, .cta-band, .vhero, .page-hero--image, .site-footer, .quote-band, .svc--dark,
.site-header--overlay:not(.is-scrolled) { --focus: var(--sky); }

.skip-link {
  position: absolute; inset-inline-start: 1rem; top: -3rem; z-index: 100;
  background: var(--ink); color: var(--white);
  padding: 0.6rem 1rem; border-radius: var(--radius-control); text-decoration: none;
}
.skip-link:focus { top: 1rem; }

.container { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
/* Landscape phones with a notch (viewport-fit=cover): keep content clear of the cut-outs */
@supports (padding: max(0px)) {
  .container {
    padding-left: max(var(--gutter), env(safe-area-inset-left, 0px));
    padding-right: max(var(--gutter), env(safe-area-inset-right, 0px));
  }
}

.section { padding-block: var(--section); }
.section--white { background: var(--white); }
.section--dark { background: var(--ink); color: var(--white); }
.section--dark .lede, .section--dark .muted { color: var(--on-dark-subtle); }

.lede { font-size: var(--step-1); line-height: 1.5; color: var(--slate); max-width: 38em; }
.muted { color: var(--slate); }
.measure { max-width: 42em; }
.tabular { font-variant-numeric: tabular-nums; }

/* Section heads stack: headline, then lede. (.section-head--split is kept
   as a class name for the HTML but no longer makes a two-column split.) */
.section-head { display: grid; gap: 1rem; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.section-head h2 { max-width: 18em; margin: 0; }
.section-head .lede { margin: 0; max-width: 65ch; }
@media (max-width: 600px) {
  .lede { line-height: 1.55; text-wrap: pretty; }
  .section-head { margin-bottom: 2rem; }
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  font: 500 var(--step-0)/1 var(--font-body);
  padding: 0.95rem 1.4rem;
  border-radius: var(--radius-control);
  border: 1.5px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--dur-hover) ease,
    color var(--dur-hover) ease,
    border-color var(--dur-hover) ease,
    transform var(--dur-press) var(--ease-out);
}
.btn:active:not(:disabled) { transform: scale(0.97); }
.btn:disabled { opacity: 0.6; cursor: progress; }
.btn--primary { background: var(--ink); color: var(--white); }
.btn--ghost { border-color: var(--ink); color: var(--ink); background: transparent; }
.btn--sand { background: var(--cobalt); color: var(--white); }
.section--dark .btn--ghost { border-color: var(--on-dark-subtle); color: var(--white); }
/* CTA band: white button with ink text (cobalt on indigo reads at 2.2:1 as a shape) */
.cta-band .btn--sand { background: var(--white); color: var(--ink); }
.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; }

@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover { background: var(--indigo); }
  .btn--ghost:hover { background: var(--ink); color: var(--white); }
  .btn--sand:hover { background: var(--cobalt-text); }            /* darkens: white 7.5:1 */
  .section--dark .btn--ghost:hover { background: var(--white); color: var(--ink); }
  .cta-band .btn--sand:hover { background: var(--sky); color: var(--ink); }
}
/* Press feedback on touch (the grey tap flash is off): same colours as hover, only while pressed */
.btn--primary:active:not(:disabled) { background: var(--indigo); }
.btn--sand:active:not(:disabled) { background: var(--cobalt-text); }
.cta-band .btn--sand:active { background: var(--sky); color: var(--ink); }

/* Phones: hero and CTA-band buttons stack full width at equal size (S4) */
@media (max-width: 480px) {
  .vhero .btn-row, .cta-band .btn-row { display: grid; grid-template-columns: 1fr; gap: 0.625rem; }
  .vhero .btn-row .btn, .cta-band .btn-row .btn { width: 100%; padding-block: 0.9rem; }
}

.text-link {
  color: var(--cobalt-text); font-weight: 500; text-decoration: underline;
  text-underline-offset: 0.25em; text-decoration-thickness: 1px;
}
@media (hover: hover) and (pointer: fine) {
  .text-link:hover { text-decoration-thickness: 2px; }
}
.text-link:active { text-decoration-thickness: 2px; }
.section--dark .text-link { color: var(--sky); }

/* ---------- Header ---------- */
/* Sticks at 0 and pads the status-bar / notch area itself, so nothing scrolls visibly above it (S7) */
.site-header {
  top: 0; padding-top: env(safe-area-inset-top, 0px);
  position: sticky; z-index: 50;
  background: rgb(var(--paper-rgb) / 0.9);
  backdrop-filter: saturate(140%) blur(10px);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-state) ease;
}
.site-header.is-scrolled { border-bottom-color: var(--line); }
.site-header__inner { display: flex; align-items: center; justify-content: space-between; height: var(--header-h); gap: 1rem; }

/* Brand: the two header logos sit in one grid cell so they can crossfade */
.brand { display: inline-grid; align-items: center; text-decoration: none; color: var(--ink); }
.brand__logo { grid-area: 1 / 1; height: 34px; width: auto; display: block; transition: opacity var(--dur-state) ease; }
@media (min-width: 961px) { .brand__logo { height: 40px; } }
@media (max-width: 600px), (orientation: landscape) and (max-height: 500px) { .brand__logo { height: 28px; } }
.brand__logo--white { display: none; }

.nav { display: flex; align-items: center; gap: 0.25rem; }
.nav__list { display: flex; gap: 0.25rem; list-style: none; margin: 0; padding: 0; }
.nav__link {
  display: block; padding: 0.55rem 0.8rem; border-radius: var(--radius-control);
  text-decoration: none; font-size: 0.95rem; color: var(--ink-2);
  transition: color var(--dur-state) ease;
}
.nav__link[aria-current="page"] { color: var(--ink); font-weight: 600; box-shadow: inset 0 -2px 0 var(--cobalt); border-radius: 0; }
.nav__cta { margin-inline-start: 0.75rem; padding: 0.7rem 1.1rem; font-size: 0.95rem; min-height: 44px; white-space: nowrap; }
/* Narrow desktops (961-1120px): tighter link padding so logo, links, switcher and CTA keep one row */
@media (min-width: 961px) and (max-width: 1120px) { .nav__link { padding-inline: 0.65rem; } .nav__cta { margin-inline-start: 0.5rem; } }
@media (hover: hover) and (pointer: fine) {
  .nav__link:hover { background: rgb(var(--ink-rgb) / 0.06); }
}
.nav__link:active { background: rgb(var(--ink-rgb) / 0.06); }

.nav-toggle {
  display: none; background: none; border: 1.5px solid var(--ink); border-radius: var(--radius-control);
  width: 44px; height: 44px; padding: 0; cursor: pointer; color: var(--ink);
  transition:
    transform var(--dur-press) var(--ease-out),
    color var(--dur-state) ease,
    border-color var(--dur-state) ease;
}
.nav-toggle:active { transform: scale(0.95); }
.nav-toggle svg { width: 24px; height: 24px; margin: auto; }
.nav-toggle .nav-toggle__close { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__open { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__close { display: block; }

@media (max-width: 960px) {
  .nav-toggle { display: grid; place-items: center; }
  /* Full-height solid sheet under the header (S6): the page never shows through,
     so the hero's own "Book a consultation" is never seen stacked under the menu's.
     Height, not bottom: 0, because the header's backdrop-filter makes it the containing
     block for this fixed panel. */
  .nav {
    position: fixed; inset: calc(var(--header-h) + env(safe-area-inset-top, 0px)) 0 auto 0;
    height: calc(100vh - var(--header-h) - env(safe-area-inset-top, 0px));
    height: calc(100dvh - var(--header-h) - env(safe-area-inset-top, 0px));
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--paper); border-top: 1px solid var(--line);
    padding: 0.5rem var(--gutter) calc(1.5rem + env(safe-area-inset-bottom, 0px));
    overflow-y: auto; overscroll-behavior: contain;
    transform: translateY(-8px); opacity: 0; visibility: hidden;
    /* closing: fast, visibility flips after the fade */
    transition:
      opacity var(--dur-exit) ease-out,
      transform var(--dur-exit) ease-out,
      visibility 0s linear var(--dur-exit);
  }
  .nav.is-open {
    transform: none; opacity: 1; visibility: visible;
    transition:
      opacity var(--dur-enter) var(--ease-out),
      transform var(--dur-enter) var(--ease-out),
      visibility 0s;
  }
  .nav__list { flex-direction: column; }
  .nav__link { padding: 1rem 0.25rem; border-bottom: 1px solid var(--line); border-radius: 0; font: 500 1.25rem/1.2 var(--font-display); letter-spacing: 0; }
  .nav__link[aria-current="page"] { box-shadow: none; border-inline-start: 3px solid var(--cobalt); padding-inline-start: 0.75rem; font-weight: 600; }
  .nav__cta { margin: 1.5rem 0 0; flex: none; min-height: 48px; font-size: var(--step-0); }
}
@media (max-width: 960px) and (prefers-reduced-motion: reduce) {
  .nav, .nav.is-open { transform: none; }
}

/* ---------- Language switcher (English <-> Arabic) ----------
   .nav__lang sits in the main nav (desktop) and in the menu sheet (phones and tablets);
   .lang-switch is a compact copy in the header row, shown only while the nav is a sheet.
   The link text is always in the target language (lang="ar" / lang="en"). */
.lang-switch, .nav__lang {
  align-items: center; min-height: 44px; text-decoration: none; color: var(--ink-2);
  font-size: 0.95rem; font-weight: 500; line-height: 1.2; border-radius: var(--radius-control);
  transition: color var(--dur-state) ease, background-color var(--dur-hover) ease;
}
:root:not([lang="ar"]) [lang="ar"] { font-family: "IBM Plex Sans Arabic", system-ui, "Segoe UI", sans-serif; }
:root[lang="ar"] [lang="en"] { font-family: "IBM Plex Sans", system-ui, "Segoe UI", sans-serif; }
.lang-switch { display: none; }
.nav__lang { display: inline-flex; position: relative; padding: 0.55rem 0.8rem; margin-inline-start: 0.6rem; }
.nav__lang::before {
  content: ""; position: absolute; inset-inline-start: -0.35rem; top: 50%; height: 1.2em; margin-top: -0.6em;
  border-inline-start: 1px solid var(--line);
}
@media (hover: hover) and (pointer: fine) {
  .lang-switch:hover, .nav__lang:hover { background: rgb(var(--ink-rgb) / 0.06); color: var(--ink); }
}
.lang-switch:active, .nav__lang:active { background: rgb(var(--ink-rgb) / 0.06); }
@media (max-width: 960px) {
  .lang-switch { display: inline-flex; margin-inline-start: auto; margin-inline-end: -0.35rem; padding-inline: 0.65rem; }
  .nav__lang { margin: 0; padding: 1rem 0.25rem; border-bottom: 1px solid var(--line); border-radius: 0; font-size: 1.05rem; color: var(--slate); }
  .nav__lang::before { display: none; }
}
/* 320-359px phones: the header row has no room; the switcher stays in the menu sheet */
@media (max-width: 359px) { .lang-switch { display: none; } }

/* ---------- Header floating over the video hero (home only) ----------
   Two background layers crossfade with opacity (gradients can't transition). */
.site-header--overlay {
  position: fixed; inset-inline: 0;
  background: none; backdrop-filter: none; -webkit-backdrop-filter: none;
  isolation: isolate;
}
.site-header--overlay::before,
.site-header--overlay::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  transition: opacity var(--dur-state) ease;
}
.site-header--overlay::before { background: linear-gradient(180deg, rgb(var(--ink-rgb) / 0.6), rgb(var(--ink-rgb) / 0)); }
.site-header--overlay::after {
  background: rgb(var(--paper-rgb) / 0.92);
  backdrop-filter: saturate(140%) blur(10px);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  opacity: 0;
}
.site-header--overlay.is-scrolled::before { opacity: 0; }
.site-header--overlay.is-scrolled::after { opacity: 1; }
/* Menu open: header and sheet read as one solid paper surface */
html.menu-open .site-header { background: var(--paper); }
html.menu-open .site-header--overlay { background: none; }
html.menu-open .site-header--overlay::after { background: var(--paper); }

.site-header--overlay .brand__logo--white { display: block; opacity: 0; }
.site-header--overlay:not(.is-scrolled) .brand__logo--white { opacity: 1; }
.site-header--overlay:not(.is-scrolled) .brand__logo--color { opacity: 0; }
.site-header--overlay:not(.is-scrolled) .nav-toggle { color: var(--white); border-color: var(--on-dark-subtle); }
.site-header--overlay:not(.is-scrolled) .lang-switch { color: var(--white); }
@media (min-width: 961px) {
  .site-header--overlay:not(.is-scrolled) .nav__lang { color: var(--on-dark-strong); }
  .site-header--overlay:not(.is-scrolled) .nav__lang::before { border-color: var(--line-dark-strong); }
  .site-header--overlay:not(.is-scrolled) .nav__link { color: var(--on-dark-strong); }
  .site-header--overlay:not(.is-scrolled) .nav__link[aria-current="page"] { color: var(--white); }
  .site-header--overlay:not(.is-scrolled) .nav__cta { background: var(--white); color: var(--ink); }
}
@media (min-width: 961px) and (hover: hover) and (pointer: fine) {
  .site-header--overlay:not(.is-scrolled) .nav__link:hover { background: var(--line-dark); }
  .site-header--overlay:not(.is-scrolled) .nav__lang:hover { background: var(--line-dark); color: var(--white); }
  .site-header--overlay:not(.is-scrolled) .nav__cta:hover { background: var(--sky); color: var(--ink); }
}

/* ---------- Page hero (inner pages) ---------- */
.page-hero { padding-block: clamp(3.5rem, 7vw, 6rem) clamp(2.5rem, 5vw, 4rem); border-bottom: 1px solid var(--line); }
.page-hero h1 { font-size: var(--step-5); max-width: 14em; }
.page-hero .lede { margin-top: 1rem; }
.breadcrumb { font-size: var(--step--1); color: var(--slate); margin-bottom: 1.25rem; }
.breadcrumb a { color: var(--slate); }
.breadcrumb span[aria-hidden] { margin-inline: 0.4rem; }
/* Phones: tighter inner-page heroes (S10). The --image variant is re-set further down. */
@media (max-width: 600px) {
  .page-hero { padding-block: 2.25rem 2rem; }
  .breadcrumb { margin-bottom: 0.75rem; }
  .page-hero .lede { max-width: 34ch; }
}

/* ---------- Network map (home) ---------- */
.netmap { width: 100%; height: auto; }
.netmap figcaption { font-size: var(--step--1); color: var(--slate); margin-top: 0.75rem; }
.netmap .grid line { stroke: #e3e6f0; stroke-width: 1; }
.netmap .link { stroke: var(--indigo); stroke-width: 1.5; fill: none; opacity: .45; stroke-dasharray: 3 4; }
.netmap .trunk { stroke: var(--ink); stroke-width: 2.5; fill: none; }
.netmap .site { fill: var(--white); stroke: var(--indigo); stroke-width: 1.5; }
.netmap .hub-ring { fill: none; stroke: var(--cobalt); stroke-width: 1.5; }
.netmap .hub { fill: var(--ink); }
.netmap .packet { fill: var(--cobalt); }
.netmap .label { font: 600 23px var(--font-display); fill: var(--ink); letter-spacing: .01em; }
.netmap .label-sub { font: 400 16px var(--font-body); fill: var(--slate); }
.netmap .label-site { font: 400 16px var(--font-body); fill: var(--slate); }
/* Phones: the 708-unit map renders at about half scale. Enlarge the city and site labels
   (about 12px on screen) and drop the country sub-labels, which the office list above already gives.
   Baghdad is end-anchored near the left edge, so .label cannot grow past 25px without clipping. */
@media (max-width: 600px) {
  .netmap .label { font-size: 25px; }
  .netmap .label-site { font-size: 24px; }
  .netmap .label-sub { display: none; }
}
/* Pause/play control for the map traffic (button[data-map-toggle], wired in main.js) */
.netmap__toggle {
  font: 500 var(--step--1)/1.4 var(--font-body); color: var(--cobalt-text);
  background: none; border: 0; padding: 0.35rem 0; margin-inline-start: 0.5rem;
  text-decoration: underline; text-underline-offset: 0.2em; cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .netmap__toggle:hover { text-decoration-thickness: 2px; }
}
.netmap__toggle:active { text-decoration-thickness: 2px; }
/* Phones: the toggle wraps under the caption; sit it flush with the caption text */
@media (max-width: 600px) { .netmap__toggle { display: block; margin-inline-start: 0; } }

/* ---------- Partner strip ---------- */
.partners { border-block: 1px solid var(--line); background: var(--white); padding-block: 1.75rem; }
.partners__inner { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.75rem 1.75rem; }
.partners__label { font-size: var(--step--1); color: var(--slate); margin: 0; line-height: 1.4; white-space: nowrap; }
.partners__list { display: flex; flex-wrap: wrap; gap: 0.6rem 1.25rem; list-style: none; margin: 0; padding: 0; }
.partners__list li { font: 600 1.05rem/1.2 var(--font-display); color: #3a4166; letter-spacing: 0.01em; white-space: nowrap; }
.partners__more { font-size: var(--step--1); white-space: nowrap; }
@media (min-width: 1100px) { .partners__more { margin-inline-start: auto; } }
/* Phones: label, a tidy 2-column name grid, then the link (S10) */
@media (max-width: 600px) {
  .partners__inner { display: grid; gap: 0.75rem; }
  .partners__list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem 1rem; }
  .partners__list li { font-size: 0.95rem; white-space: normal; }
  .partners__more { justify-self: start; }
}

/* ---------- Service index (row list, not cards) ---------- */
.service-index { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line-dark); }
.service-row { border-bottom: 1px solid var(--line-dark); }
.service-row a {
  display: grid; gap: 0.5rem 2rem; padding: 1.75rem 0; text-decoration: none; color: inherit;
  grid-template-columns: 1fr auto;
}
.service-row h3 { margin: 0; font-size: var(--step-3); transition: color var(--dur-state) ease; }
.service-row p { margin: 0; color: var(--on-dark-subtle); grid-column: 1 / -1; max-width: 36em; }
.service-row .tags { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; }
.service-row .arrow {
  align-self: center; width: 44px; height: 44px; border: 1px solid var(--line-dark); border-radius: 50%;
  display: grid; place-items: center;
  transition: background-color var(--dur-state) ease, border-color var(--dur-state) ease, color var(--dur-state) ease;
}
.service-row a:focus-visible h3, .service-row a:active h3 { color: var(--sky); }
/* Below the 3-column layout: arrow top-right beside the heading, not on a row of its own (S10) */
@media (max-width: 899px) {
  .service-row a { padding-block: 1.5rem; }
  .service-row .arrow { grid-column: 2; grid-row: 1; align-self: start; width: 36px; height: 36px; }
}
@media (hover: hover) and (pointer: fine) {
  .service-row a:hover h3 { color: var(--sky); }
  .service-row a:hover .arrow { background-color: var(--cobalt); border-color: var(--cobalt); color: var(--white); }
}
@media (min-width: 900px) {
  .service-row a { grid-template-columns: minmax(16rem, 1fr) 1.4fr auto; align-items: start; }
  .service-row p { grid-column: 2; }
  .service-row .tags { grid-column: 2; }
  .service-row .arrow { grid-column: 3; grid-row: 1 / span 2; }
}
.tag { font-size: var(--step--2); padding: 0.25rem 0.6rem; border-radius: var(--radius-pill); border: 1px solid var(--line-dark); color: var(--on-dark-muted); }
.tag--light { border-color: var(--line); color: var(--slate); background: var(--white); }

/* ---------- Process (a real sequence, so numbered) ---------- */
.process { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; counter-reset: step; }
@media (min-width: 900px) { .process { grid-template-columns: repeat(4, 1fr); } }
.process li { counter-increment: step; padding-block: 1.75rem; padding-inline: 0 1.5rem; border-top: 2px solid var(--ink); position: relative; }
@media (min-width: 900px) { .process li + li { padding-inline-start: 1.5rem; border-inline-start: 1px solid var(--line); } }
.process li::before {
  content: counter(step); display: inline-grid; place-items: center;
  width: 2rem; height: 2rem; border-radius: 50%; margin-bottom: 1.25rem;
  background: var(--cobalt-soft); color: var(--cobalt-text); font: 600 0.95rem/1 var(--font-display);
  font-variant-numeric: tabular-nums;
}
.process h3 { font-size: var(--step-1); margin-bottom: 0.4rem; }
.process p { color: var(--slate); margin: 0; font-size: 0.97rem; }
/* Stacked (below 900px): number beside the heading, hairlines between steps (S10) */
@media (max-width: 899px) {
  .process li { display: grid; grid-template-columns: 2rem 1fr; column-gap: 1rem; align-items: start; padding-block: 1.25rem; padding-inline: 0; border-top-width: 1px; }
  .process li:first-child { border-top-width: 2px; }
  .process li::before { margin: 0; grid-row: 1 / span 2; }
  .process li > * { grid-column: 2; }
}

/* ---------- Leadership table ---------- */
.leaders { width: 100%; border-collapse: collapse; }
.leaders th, .leaders td { text-align: start; padding-block: 1.1rem; padding-inline: 0 1rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.leaders thead th { font-size: var(--step--1); font-weight: 500; color: var(--slate); border-bottom-color: var(--ink); }
.leaders td:first-child { font: 600 var(--step-1)/1.2 var(--font-display); }
.leaders .role { color: var(--slate); font-size: 0.95rem; }
.leaders .years { font: 600 var(--step-2)/1 var(--font-display); color: var(--indigo); white-space: nowrap; font-variant-numeric: tabular-nums; }
.leaders .years small { font: 400 0.8rem var(--font-body); color: var(--slate); margin-inline-start: 0.25rem; }
@media (max-width: 720px) {
  .leaders thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .leaders tr { display: grid; grid-template-columns: 1fr auto; gap: 0.2rem 1rem; padding: 1rem 0; border-bottom: 1px solid var(--line); }
  .leaders td { border: 0; padding: 0; }
  .leaders td.years { grid-row: 1 / span 2; grid-column: 2; }
  .leaders td.prev { grid-column: 1 / -1; font-size: 0.9rem; color: var(--slate); }
  /* H4: a clean ruled list, same top rule as the office and client lists */
  .leaders tbody tr:first-child { border-top: 1px solid var(--line); }
  .leaders tr { padding-block: 0.9rem; }
  .leaders td:first-child { font-size: var(--step-1); }
}
.leaders-foot { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 1rem; margin-top: 2rem; }
.leaders-total { font-size: var(--step-1); }
.leaders-total strong { font-family: var(--font-display); font-size: var(--step-3); color: var(--indigo); font-variant-numeric: tabular-nums; }

/* ---------- Quote ---------- */
.quote { display: grid; gap: 2rem; align-items: center; }
@media (min-width: 900px) { .quote { grid-template-columns: 1.6fr 1fr; gap: 4rem; } }
.quote blockquote { margin: 0; font: 500 var(--step-3)/1.3 var(--font-display); letter-spacing: -0.01em; }
.quote blockquote p { margin: 0; }
.quote figcaption { margin-top: 1.5rem; color: var(--slate); }
.quote figcaption strong { color: var(--ink); display: block; font-weight: 600; }
.quote__facts { display: grid; gap: 1.25rem; border-top: 1px solid var(--line); padding-top: 1.5rem; }
.quote__facts div { font-size: 0.95rem; color: var(--slate); }
.quote__facts strong { display: block; font: 600 var(--step-2)/1.1 var(--font-display); color: var(--ink); font-variant-numeric: tabular-nums; }

/* ---------- CTA band ---------- */
.cta-band { background: var(--indigo); color: var(--white); padding-block: clamp(3.5rem, 7vw, 5.5rem); position: relative; overflow: hidden; }
.cta-band__inner { display: grid; gap: 2rem; align-items: end; position: relative; }
@media (min-width: 900px) { .cta-band__inner { grid-template-columns: 1.4fr auto; } }
.cta-band h2 { margin: 0 0 0.75rem; max-width: 16em; }
.cta-band p { margin: 0; color: var(--on-dark-muted); max-width: 34em; }
.cta-band__pattern { position: absolute; inset-inline-end: -40px; top: 50%; transform: translateY(-50%); width: 460px; opacity: .14; pointer-events: none; }
/* Phones: the pattern moves to the bottom corner, clear of the headline (S9) */
@media (max-width: 700px) {
  .cta-band { padding-block: 3rem; }
  .cta-band__inner { gap: 1.5rem; }
  .cta-band__pattern { top: auto; bottom: -60px; transform: none; width: 300px; inset-inline-end: -80px; opacity: .07; }
}

/* ---------- Footer ---------- */
.site-footer { background: var(--ink); color: var(--on-dark-subtle); padding-block: 4rem 2rem; font-size: 0.95rem; }
.site-footer a { color: var(--on-dark-strong); text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
  .site-footer a:hover { color: var(--white); text-decoration: underline; text-underline-offset: .2em; }
}
.site-footer a:focus-visible, .site-footer a:active { color: var(--white); }
.footer-grid { display: grid; gap: 2.5rem; }
@media (min-width: 800px) { .footer-grid { grid-template-columns: 1.5fr 1fr 1fr 1.2fr; } }
.site-footer .brand { color: var(--white); }
.site-footer .brand__logo { height: 36px; }
.footer-about { margin-top: 1.25rem; max-width: 22em; }
.footer-col h2 { font: 600 1rem/1.3 var(--font-body); color: var(--white); margin-bottom: 1rem; letter-spacing: 0; }
.footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
.footer-contact li { display: flex; align-items: center; gap: 0.6rem; }
.footer-contact svg { width: 18px; height: 18px; flex: none; color: var(--sky); }
.footer-bottom { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 1rem; margin-top: 3.5rem; padding-top: 1.5rem; border-top: 1px solid var(--line-dark); font-size: var(--step--1); }
.footer-bottom p { margin: 0; }
.footer-bottom ul { display: flex; gap: 1.5rem; list-style: none; margin: 0; padding: 0; }
/* Touch: 44px-tall link targets in the footer */
@media (max-width: 800px) {
  .footer-col ul { gap: 0; }
  .footer-col a, .footer-bottom a { display: inline-block; padding-block: 0.65rem; }
  .footer-contact li { min-height: 44px; }
}
/* Keep the floating WhatsApp button (fixed, bottom right) from covering the footer's last line at any width */
.site-footer { padding-block-end: 6rem; }
/* Phones and small tablets: compact footer, Company and Services side by side (S8).
   The bottom padding still clears the 44px float (12px inset + 44px < 72px). */
@media (max-width: 799px) {
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 2rem 1.5rem; }
  .footer-grid > :first-child, .footer-grid > :last-child { grid-column: 1 / -1; }
  .site-footer { padding-block: 3rem calc(4.5rem + env(safe-area-inset-bottom, 0px)); }
  .site-footer .brand__logo { height: 30px; }
  .footer-about { margin-top: 1rem; }
  .footer-col h2 { margin-bottom: 0.5rem; }
  .footer-bottom { margin-top: 2rem; }
}

/* ---------- Floating WhatsApp ---------- */
.wa-float {
  position: fixed; inset-inline-end: 1.25rem; bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px)); z-index: 60;
  display: inline-flex; align-items: center; gap: 0.5rem; min-height: 44px;
  background: var(--white); color: var(--ink); text-decoration: none;
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  padding-block: 0.6rem; padding-inline: 0.65rem 1rem; font-size: 0.9rem; font-weight: 500;
  box-shadow: 0 8px 24px rgb(var(--ink-rgb) / 0.14);
  transition:
    border-color var(--dur-hover) ease,
    transform var(--dur-press) var(--ease-out),
    opacity var(--dur-exit) ease,
    visibility 0s linear 0s;
}
/* Hidden while the mobile menu sheet is open (html.menu-open from main.js) */
html.menu-open .wa-float {
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity var(--dur-exit) ease, visibility 0s linear var(--dur-exit);
}
/* Phones: the float (and the publish copy's draft note) steps aside while a full-width button row
   or the contact form passes under it, so it never covers a button, a field or the submit button.
   html.wa-yield is set by main.js; the WhatsApp number stays in the footer and on Contact. */
html.wa-yield .wa-float,
html.wa-yield .draft-note {
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity var(--dur-exit) ease, visibility 0s linear var(--dur-exit);
}
.site-footer .wa-float { color: var(--ink); }
.wa-float svg { width: 26px; height: 26px; flex: none; color: var(--wa-green); }
.wa-float:active { transform: scale(0.96); }
@media (hover: hover) and (pointer: fine) {
  .site-footer .wa-float:hover { border-color: var(--ink); color: var(--ink); text-decoration: none; }
}
.site-footer .wa-float:focus-visible { color: var(--ink); }
/* Phones (portrait) and short landscape phones: compact 44px icon-only circle, never the full
   pill over content (S5). The label stays as its accessible name. */
@media (max-width: 560px), (max-height: 500px) {
  .wa-float {
    inset-inline-end: max(0.75rem, env(safe-area-inset-right, 0px));
    bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
    width: 44px; height: 44px; padding: 0; justify-content: center;
    box-shadow: 0 4px 14px rgb(var(--ink-rgb) / 0.16);
  }
  .wa-float svg { width: 24px; height: 24px; }
  .wa-float span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
}
@media (prefers-reduced-motion: reduce) {
  .wa-float { transition: border-color var(--dur-hover) ease, opacity var(--dur-exit) ease, visibility 0s linear 0s; }
  .wa-float:active { transform: none; }
}

/* ---------- Generic content helpers for inner pages ---------- */
.split { display: grid; gap: 2.5rem; }
@media (min-width: 900px) { .split { grid-template-columns: 1fr 1fr; gap: 4rem; } .split--wide-left { grid-template-columns: 1.4fr 1fr; } }
.check-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.6rem; }
.check-list li { padding-inline-start: 1.75rem; position: relative; }
/* The tick is drawn with two borders; it is a glyph, so its left/bottom stay physical. */
.check-list li::before { content: ""; position: absolute; inset-inline-start: 0.1rem; top: 0.55em; width: 0.9rem; height: 0.5rem; border-left: 2px solid var(--indigo); border-bottom: 2px solid var(--indigo); transform: rotate(-45deg) translateY(-50%); }
.panel { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-surface); padding: clamp(1.5rem, 3vw, 2.25rem); }

.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- Page-load moment (home hero only; CSS-only so content never gets stuck hidden) ---------- */
@keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.vhero [data-reveal] { animation: rise 600ms var(--ease-out) both; }
.vhero [data-reveal="2"] { animation-delay: 60ms; }
.vhero [data-reveal="3"] { animation-delay: 120ms; }
.vhero [data-reveal="4"] { animation-delay: 180ms; }
@media (prefers-reduced-motion: reduce) {
  .vhero [data-reveal], .vhero [data-reveal="2"], .vhero [data-reveal="3"], .vhero [data-reveal="4"] { animation: fade 300ms ease both; }
}

/* ---------- Video hero ---------- */
.vhero { position: relative; min-height: min(100svh, 920px); display: flex; align-items: flex-end; color: var(--white); background: var(--ink); overflow: hidden; isolation: isolate; }
.vhero__media { position: absolute; inset: 0; z-index: -2; }
.vhero__media video, .vhero__media img { width: 100%; height: 100%; object-fit: cover; object-position: 70% 50%; }
.vhero::before { content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(90deg, rgb(var(--ink-rgb) / .92) 0%, rgb(var(--ink-rgb) / .7) 38%, rgb(var(--ink-rgb) / .15) 70%, rgb(var(--ink-rgb) / 0) 100%),
    linear-gradient(0deg, rgb(var(--ink-rgb) / .85) 0%, rgb(var(--ink-rgb) / 0) 40%); }
.vhero__content { padding-block: 9rem clamp(2.5rem, 6vw, 4.5rem); width: 100%; }
.vhero h1 { max-width: 12em; font-size: clamp(2.6rem, 1.6rem + 4.4vw, 5.2rem); letter-spacing: -0.03em; }
.vhero .lede { color: var(--on-dark-muted); margin-block: 1.5rem 2.25rem; }
.vhero .btn--ghost { border-color: var(--on-dark-subtle); color: var(--white); }
@media (hover: hover) and (pointer: fine) { .vhero .btn--ghost:hover { background: var(--white); color: var(--ink); } }
.vhero__pause { position: absolute; inset-inline-end: var(--gutter); top: calc(var(--header-h) + 24px); z-index: 2; display: inline-flex; align-items: center; gap: .5rem;
  min-height: 44px; padding: 0 1rem;
  background: rgb(var(--ink-rgb) / .45); color: var(--white); border: 1px solid var(--line-dark-strong); border-radius: var(--radius-pill);
  font: 500 .85rem/1 var(--font-body); cursor: pointer; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  transition: background-color var(--dur-hover) ease, transform var(--dur-press) var(--ease-out); }
.vhero__pause svg { width: 14px; height: 14px; flex: none; }
.vhero__pause:active { transform: scale(0.96); }
@media (hover: hover) and (pointer: fine) { .vhero__pause:hover { background: rgb(var(--ink-rgb) / .7); } }
@media (max-width: 700px) {
  /* H2: a quiet 40px round icon button under the menu toggle, not a labelled pill.
     The span stays in the DOM (visually hidden) as the accessible name; main.js swaps it Pause/Play. */
  .vhero__pause { top: calc(var(--header-h) + 0.75rem); inset-inline-end: 1rem;
    width: 40px; height: 40px; min-height: 40px; padding: 0; justify-content: center; border-radius: 50%;
    background: rgb(var(--ink-rgb) / .35); }
  .vhero__pause span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .vhero__media video, .vhero__media img { object-position: 78% 50%; }
  /* The lede spans the full width on phones and crosses the bright side of the
     video: add a flat base layer under the gradients for a contrast margin. */
  .vhero::before {
    background:
      linear-gradient(90deg, rgb(var(--ink-rgb) / .92) 0%, rgb(var(--ink-rgb) / .7) 38%, rgb(var(--ink-rgb) / .15) 70%, rgb(var(--ink-rgb) / 0) 100%),
      linear-gradient(0deg, rgb(var(--ink-rgb) / .85) 0%, rgb(var(--ink-rgb) / 0) 40%),
      rgb(var(--ink-rgb) / .35);
  }
}
/* H1: phone hero. h1 ~34-36px on 3 lines, 18px lede, both CTAs inside the first screen
   (320x568 included). Top padding clears the header plus the 40px pause button. */
@media (max-width: 600px) {
  .vhero__content { padding-block: calc(var(--header-h) + 4.25rem) 1.75rem; }
  /* Greedy wrap + the two no-wrap spans give "Networks and security / your business / can stand on."
     (balance split it as "Networks and / security your business / can stand on."). */
  .vhero h1 { font-size: clamp(2.125rem, 1.5rem + 3vw, 2.5rem); line-height: 1.05; max-width: 11em; text-wrap: wrap; }
  .vhero .lede { margin-block: 1rem 1.5rem; max-width: 34ch; }
  .vhero__keep { white-space: nowrap; }
  .vhero__media video, .vhero__media img { object-position: 70% 35%; }
}
/* 320-359px phones: 32px keeps "Networks and security" on one line, so still 3 lines */
@media (max-width: 359px) {
  .vhero h1 { font-size: 2rem; }
}
/* H3: tall phones. Stop the hero at ~88% of the screen so the content sits in the
   lit part of the skyline (not under an empty sky) and the next section peeks in. */
@media (max-width: 600px) and (min-height: 760px) {
  .vhero { min-height: 88svh; }
}
/* Tall phones: the landscape video is height-bound, so cover alone leaves the top ~40% as empty sky.
   A modest zoom anchored at the bottom lifts the lit towers up behind the headline. */
@media (max-width: 600px) and (min-height: 700px) {
  .vhero__media video, .vhero__media img { transform: scale(1.22); transform-origin: 70% 100%; }
}
/* Short landscape phones: headline, lede and CTAs in one screen, pause as an icon */
@media (orientation: landscape) and (max-height: 500px) {
  .vhero { min-height: auto; }
  .vhero__content { padding-block: calc(var(--header-h) + 1.5rem) 1.5rem; }
  .vhero h1 { font-size: 2rem; max-width: 18em; }
  .vhero .lede { max-width: 48ch; margin-block: 0.75rem 1.25rem; }
  .vhero__pause { top: calc(var(--header-h) + 0.75rem); width: 40px; height: 40px; min-height: 40px; padding: 0; justify-content: center; border-radius: 50%; }
  .vhero__pause span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}

/* ---------- Image page heroes (inner pages) ---------- */
.page-hero--image { position: relative; isolation: isolate; color: var(--white); border-bottom: 0; padding-block: clamp(4.5rem, 10vw, 8rem) clamp(3.5rem, 7vw, 5.5rem);
  background-color: var(--ink); background-size: cover; background-position: center; background-repeat: no-repeat; }
.page-hero--image::before { content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgb(var(--ink-rgb) / .95) 0%, rgb(var(--ink-rgb) / .82) 45%, rgb(var(--ink-rgb) / .35) 100%); }
@media (max-width: 700px) {
  .page-hero--image::before {
    background: linear-gradient(90deg, rgb(var(--ink-rgb) / .95) 0%, rgb(var(--ink-rgb) / .82) 45%, rgb(var(--ink-rgb) / .35) 100%), rgb(var(--ink-rgb) / .3);
  }
}
@media (max-width: 600px) {
  .page-hero--image { padding-block: 2.5rem 2.25rem; }
}
@media (orientation: landscape) and (max-height: 500px) {
  .page-hero--image { padding-block: 1.75rem; }
}
.page-hero--image .lede { color: var(--on-dark-muted); }
.page-hero--image .breadcrumb, .page-hero--image .breadcrumb a { color: var(--on-dark-subtle); }

/* ---------- Photography ---------- */
.photo { margin: 0; border-radius: var(--radius-surface); overflow: hidden; background: var(--ink); position: relative; }
.photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo--wide { aspect-ratio: 21 / 9; }
.photo--std { aspect-ratio: 4 / 3; }
@media (max-width: 700px) { .photo--wide { aspect-ratio: 16 / 10; } }
/* Photo set v2 (2026-10-03): focal points for cropped slots, so faces and helmets stay in frame */
.photo img[src$="network-engineer.webp"] { object-position: 50% 30%; }
.photo img[src$="security-operations.webp"] { object-position: 50% 25%; }
.photo img[src$="telecom-site.webp"] { object-position: 50% 30%; }
.photo img[src$="hospital-it.webp"] { object-position: 35% 50%; }

/* Regional network section */
.region { display: grid; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
@media (min-width: 1000px) { .region { grid-template-columns: 1fr 1.15fr; } }
.office-list { list-style: none; margin: 2rem 0 0; padding: 0; border-top: 1px solid var(--line); }
.office-list li { display: grid; grid-template-columns: 7.5rem 1fr; gap: 1rem; padding: 1rem 0; border-bottom: 1px solid var(--line); }
.office-list strong { font: 600 var(--step-1)/1.2 var(--font-display); }
.office-list span { color: var(--slate); font-size: .97rem; }
/* Phones: label above its text instead of a squeezed 7.5rem label column (S10) */
@media (max-width: 480px) {
  .office-list li { grid-template-columns: 1fr; gap: 0.15rem; padding-block: 0.9rem; }
  .office-list strong { font-size: var(--step-0); }
}

/* Industries split with photo stack */
.industry-split { display: grid; gap: clamp(2rem, 5vw, 4rem); }

.photo-stack { display: grid; gap: 1rem; grid-template-columns: 1fr 1fr; }
.photo-stack .photo:first-child { grid-column: 1 / -1; }
/* Go-live fix (2026-10-03): from 1000px the three photos stack in one column and stretch to the height of the
   sector list, so no blank column is left under the collage (contain: size keeps the photos from setting the row height). */
@media (min-width: 1000px) {
  .industry-split { grid-template-columns: .9fr 1.1fr; align-items: stretch; }
  .photo-stack { contain: size; grid-template-columns: 1fr; grid-template-rows: repeat(3, minmax(0, 1fr)); }
  .photo-stack .photo { aspect-ratio: auto; min-height: 0; }
  .photo-stack .photo:first-child { grid-column: auto; }
}
.industry-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.industry-list li { display: grid; grid-template-columns: 2.25rem 1fr; gap: 1rem; padding: 1.25rem 0; border-bottom: 1px solid var(--line); }
.industry-list svg { width: 26px; height: 26px; color: var(--cobalt); margin-top: .2rem; }
.industry-list h3 { font-size: var(--step-1); margin: 0 0 .25rem; }
.industry-list p { margin: 0; color: var(--slate); font-size: .97rem; }
/* H5: phones show the lead photo only; the two small 4:3 crops were ~170px wide and
   pushed the sector list a further ~150px down. */
@media (max-width: 600px) {
  .photo-stack { grid-template-columns: 1fr; }
  .photo-stack .photo:not(:first-child) { display: none; }
  .industry-list li { gap: 0.875rem; padding-block: 1.1rem; }
}

/* Leadership heading with photo */
.lead-head { display: grid; gap: 2rem; margin-bottom: clamp(2.5rem, 5vw, 3.5rem); align-items: end; }
@media (min-width: 900px) { .lead-head { grid-template-columns: 1fr 1.1fr; gap: 4rem; } }
.lead-head h2 { max-width: 12em; }

/* Quote over photography */
.quote-band { position: relative; color: var(--white); background: linear-gradient(90deg, rgb(var(--ink-rgb) / .96) 0%, rgb(var(--ink-rgb) / .85) 55%, rgb(var(--ink-rgb) / .55)), var(--ink); }
.quote-band .quote figcaption { color: var(--on-dark-subtle); }
.quote-band .quote figcaption strong { color: var(--white); }
.quote-band .quote__facts { border-top-color: var(--line-dark); }
.quote-band .quote__facts div { color: var(--on-dark-subtle); }
.quote-band .quote__facts strong { color: var(--white); }

/* Service section photos (services page) */
.svc-media { margin: 0 0 2rem; }

/* ==========================================================================
   Motion layer (v9): scroll reveals, hero parallax, scroll progress, map draw-in,
   anchor arrival, page transitions and hover polish.
   - Transform and opacity only (the map trunks use stroke-dashoffset, as a line drawing).
   - Hidden start states exist only under html.rv-on, which main.js sets when
     IntersectionObserver is available and motion is allowed. Without JS, without
     IntersectionObserver, in print and under reduced motion, everything is simply there.
   - Scroll-linked effects use CSS scroll-driven animations inside @supports; there are
     no scroll listeners. Everything sits behind prefers-reduced-motion: no-preference.
   - Vertical motion needs no mirroring; horizontal offsets flip under [dir="rtl"].
   Timings: reveal 600ms (--ease-out) rising 20px, cascade steps 70ms (6 max, set by main.js),
   map trunks 1300ms, arrival accent 900ms, page transition 180ms out / 280ms in,
   hover lift and photo zoom 200 / 700ms.
   ========================================================================== */

/* In-page anchors land below the sticky header. :where() keeps this at zero specificity,
   so page CSS that also clears a sticky sub-nav (.svc, .sol, ...) still wins. */
:where(main :is(section, article, div, h2, h3, li, figure)[id]) {
  scroll-margin-top: calc(var(--header-h) + env(safe-area-inset-top, 0px) + 1.25rem);
}

/* Scroll progress: a 2px cobalt rule under the header (element added by main.js). Hidden unless
   the browser has scroll-driven animations; grows from the reading start edge. */
.scroll-progress {
  display: none; position: absolute; inset-inline: 0; top: 100%; height: 2px;
  background: var(--cobalt); transform: scaleX(0); transform-origin: left center; pointer-events: none;
  transition: opacity var(--dur-exit) ease, visibility 0s linear 0s;
}
[dir="rtl"] .scroll-progress { transform-origin: right center; }
html.menu-open .scroll-progress {
  opacity: 0; visibility: hidden;
  transition: opacity var(--dur-exit) ease, visibility 0s linear var(--dur-exit);
}

/* Anchor arrival: a short accent sweeps under the target heading (class set by main.js) */
.is-arriving { position: relative; }

@keyframes rv-progress { to { transform: scaleX(1); } }
@keyframes rv-drift { to { translate: 0 8%; scale: 1.06; } }
@keyframes rv-arrive {
  0%   { transform: scaleX(0); opacity: 1; }
  40%  { transform: scaleX(1); opacity: 1; }
  70%  { transform: scaleX(1); opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}
@keyframes vt-out { to { opacity: 0; transform: translateX(-12px); } }
@keyframes vt-in { from { opacity: 0; transform: translateX(16px); } }
@keyframes vt-out-rtl { to { opacity: 0; transform: translateX(12px); } }
@keyframes vt-in-rtl { from { opacity: 0; transform: translateX(-16px); } }

@media (prefers-reduced-motion: no-preference) {
  /* 1. Scroll reveals: blocks rise into place once, as they enter the viewport */
  html.rv-on .rv:not(.is-in) { opacity: 0; transform: translateY(20px); }
  html.rv-on .rv.is-in {
    transition:
      opacity 600ms var(--ease-out) var(--rv-delay, 0ms),
      transform 600ms var(--ease-out) var(--rv-delay, 0ms);
  }

  /* 2. Network map: trunks draw in office to office, then traffic and access links fade up.
     --len (path length) and --d (stagger) are set per trunk by main.js. */
  html.rv-on .netmap .trunk { stroke-dasharray: var(--len) var(--len); }
  html.rv-on .netmap.rv:not(.is-in) .trunk { stroke-dashoffset: var(--len); }
  html.rv-on .netmap.rv:not(.is-in) :is(.packet, .link) { opacity: 0; }
  /* Transitions only on the way in, so the hidden start state applies instantly at load */
  html.rv-on .netmap.is-in .trunk { transition: stroke-dashoffset 1300ms var(--ease-in-out) var(--d, 0ms); }
  html.rv-on .netmap.is-in :is(.packet, .link) { transition: opacity 500ms ease 1100ms; }

  /* 3. Hero: the footage drifts slower than the page and eases in slightly as the hero leaves.
     Individual translate/scale compose with the RTL mirror (transform: scaleX(-1)). */
  @supports (animation-timeline: view()) {
    .vhero { view-timeline: --vhero block; }
    .vhero__media {
      animation: rv-drift linear both;
      animation-timeline: --vhero;
      animation-range: exit 0% exit 100%;
    }
  }

  /* 4. Scroll progress */
  @supports (animation-timeline: scroll()) {
    .scroll-progress {
      display: block;
      animation: rv-progress linear both;
      animation-timeline: scroll(root block);
    }
  }

  /* 5. Anchor arrival accent (sky on dark surfaces, via --focus) */
  .is-arriving::after {
    content: ""; position: absolute; inset-inline-start: 0; top: calc(100% + 0.3rem);
    width: 3.5rem; height: 3px; border-radius: 2px; background: var(--focus);
    transform-origin: left center; pointer-events: none;
    animation: rv-arrive 900ms var(--ease-out) both;
  }
  [dir="rtl"] .is-arriving::after { transform-origin: right center; }

  /* 6. Page-to-page: a quick cross-document view transition. The header and the WhatsApp
     float hold still; the page content fades and slides 12-16px in the reading direction. */
  @view-transition { navigation: auto; }
  .site-header { view-transition-name: site-header; }
  .wa-float { view-transition-name: wa-float; }
  ::view-transition-old(root) { animation: vt-out 180ms cubic-bezier(0.4, 0, 1, 1) both; }
  ::view-transition-new(root) { animation: vt-in 280ms var(--ease-out) both; }
  :root[dir="rtl"]::view-transition-old(root) { animation-name: vt-out-rtl; }
  :root[dir="rtl"]::view-transition-new(root) { animation-name: vt-in-rtl; }
  ::view-transition-group(site-header), ::view-transition-group(wa-float) { animation-duration: 200ms; }

  /* 7. Hover polish (mouse and trackpad only): photos ease in inside their rounded frames,
     project and office tiles lift 2px. Uses translate/scale so it never fights the reveal transform. */
  @media (hover: hover) and (pointer: fine) {
    .photo img { transition: scale 700ms var(--ease-out); }
    .photo:hover img { scale: 1.035; }
    .case, .office { transition: translate var(--dur-state) var(--ease-out); }
    .case:hover, .office:hover { translate: 0 -2px; }
  }
}

/* Print: never print a half-revealed page */
@media print {
  .rv { opacity: 1 !important; transform: none !important; }
  .scroll-progress { display: none !important; }
}

/* ==========================================================================
   Windows High Contrast / forced colours: keep shared components visible
   ========================================================================== */
@media (forced-colors: active) {
  .btn, .nav-toggle, .vhero__pause, .netmap__toggle, .wa-float { border: 1px solid ButtonText; }
  .wa-float svg { color: ButtonText; }
  .btn:disabled { border-color: GrayText; color: GrayText; }
  .site-header, .site-header.is-scrolled { border-bottom: 1px solid CanvasText; }
  .site-header--overlay::before, .site-header--overlay::after { display: none; }
  /* Logos are raster images: keep them on a fixed plate so they show on any theme */
  .brand { forced-color-adjust: none; }
  .site-header .brand { background: #fff; padding: 2px 6px; border-radius: var(--radius-control); }
  .site-header--overlay .brand__logo--white { display: none; }
  .site-header--overlay .brand__logo--color { opacity: 1; }
  .site-footer .brand { background: #0b1033; padding: 6px 8px; border-radius: var(--radius-control); justify-self: start; }
  /* Current page is drawn with box-shadow, which forced colours drop */
  .nav__link[aria-current="page"] { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 0.3em; }
  .process li::before { border: 1px solid CanvasText; }
  .service-row .arrow, .tag { border-color: CanvasText; }
  :focus-visible { outline-color: Highlight; }
}
/* The mobile menu panel needs an edge in forced colours; the desktop nav does not */
@media (forced-colors: active) and (max-width: 960px) {
  .nav { border: 1px solid CanvasText; }
}

/* ==========================================================================
   Arabic / RTL (site/ar/, <html lang="ar" dir="rtl">)
   Every rule below is scoped to :root[lang="ar"] or [dir="rtl"], so the English
   pages are untouched. Layout already uses logical properties; this block covers
   type, the physical leftovers (gradients, masks, background positions) and the
   directional icons.
   ========================================================================== */

/* ---- Type: IBM Plex Sans Arabic for body and headings (Plex Sans Condensed has no Arabic).
   IBM Plex Sans comes first so Latin runs (brands, acronyms, emails, phone numbers) keep
   the English face; Arabic letters fall through to Plex Sans Arabic. ---- */
:root[lang="ar"] {
  --font-body: "IBM Plex Sans", "IBM Plex Sans Arabic", system-ui, "Segoe UI", Tahoma, sans-serif;
  --font-display: "IBM Plex Sans", "IBM Plex Sans Arabic", system-ui, "Segoe UI", Tahoma, sans-serif;
  --step-0: 1.0625rem;
  --step-1: 1.1875rem;
  --step-3: clamp(1.625rem, 1.35rem + 1.2vw, 2.2rem);
  --step-4: clamp(2rem, 1.5rem + 2.2vw, 3rem);
  --step-5: clamp(2.3rem, 1.6rem + 3.2vw, 3.9rem);
}
@media (max-width: 600px) {
  :root[lang="ar"] {
    --step-1: 1.125rem;
    --step-3: 1.375rem;
    --step-4: clamp(1.5rem, 1.05rem + 2.4vw, 1.9rem);
    --step-5: clamp(1.8rem, 1.3rem + 2.8vw, 2.2rem);
  }
}
/* Arabic script must never be tracked (it breaks the joins) */
:root[lang="ar"] body, :root[lang="ar"] body * { letter-spacing: 0; }
:root[lang="ar"] body { line-height: 1.75; }
:root[lang="ar"] h1, :root[lang="ar"] h2, :root[lang="ar"] h3, :root[lang="ar"] h4 { line-height: 1.3; }
:root[lang="ar"] h1 { line-height: 1.25; }
:root[lang="ar"] .lede { line-height: 1.75; }
:root[lang="ar"] .btn { line-height: 1.25; padding-block: 0.8rem; }
:root[lang="ar"] .nav__cta { padding-block: 0.55rem; }
:root[lang="ar"] .nav__link { font-size: 1rem; }
@media (max-width: 960px) {
  :root[lang="ar"] .nav__link { font-size: 1.2rem; line-height: 1.4; padding-block: 0.85rem; }
  :root[lang="ar"] .nav__cta { padding-block: 0.7rem; }
}
:root[lang="ar"] .vhero h1 { font-size: clamp(2.3rem, 1.5rem + 3.6vw, 4.4rem); line-height: 1.25; max-width: 11em; }
@media (max-width: 600px) {
  :root[lang="ar"] .vhero h1 { font-size: clamp(1.875rem, 1.35rem + 2.6vw, 2.2rem); line-height: 1.3; }
}
@media (max-width: 359px) { :root[lang="ar"] .vhero h1 { font-size: 1.75rem; } }
@media (orientation: landscape) and (max-height: 500px) { :root[lang="ar"] .vhero h1 { font-size: 1.75rem; } }
:root[lang="ar"] .partners__list li { font-weight: 600; }
:root[lang="ar"] .quote blockquote { line-height: 1.5; }
:root[lang="ar"] .netmap .label { font-size: 24px; font-weight: 600; }
:root[lang="ar"] .netmap .label-sub, :root[lang="ar"] .netmap .label-site { font-size: 17px; }
@media (max-width: 600px) {
  :root[lang="ar"] .netmap .label { font-size: 26px; }
  :root[lang="ar"] .netmap .label-site { font-size: 25px; }
}
:root[lang="ar"] .tag { font-size: 0.8125rem; }

/* ---- Arabic logo (SVG, built by tools/arabic/build-ar.js). Each header logo sits in a <picture>
   that swaps in the «السندره»-only mark at <=420px and on narrow desktops from 961px (AR_MARK_MEDIA in the build);
   display: contents keeps both images in the .brand grid cell, so the colour/white crossfade works
   exactly as on the English pages. Heights follow the English logo (40 / 34 / 28px header,
   36 / 30px footer). The logo never shrinks (a squeezed SVG would distort). ---- */
:root[lang="ar"] .brand picture { display: contents; }
:root[lang="ar"] .site-header .brand { flex-shrink: 0; }

/* Left-to-right runs inside Arabic text: phone numbers, emails, WhatsApp number, URLs.
   (Inline runs in sentences use <bdi dir="ltr"> in the HTML.) */
[dir="rtl"] a[href^="tel:"], [dir="rtl"] a[href^="mailto:"], [dir="rtl"] .direct-list a,
[dir="rtl"] input[type="email"], [dir="rtl"] input[type="tel"] { direction: ltr; unicode-bidi: isolate; }
[dir="rtl"] input[type="email"], [dir="rtl"] input[type="tel"] { text-align: right; }

/* ---- Directional icons flip; play/pause, WhatsApp, checks and the down caret do not ---- */
[dir="rtl"] .service-row .arrow svg, [dir="rtl"] .text-link-arrow { transform: scaleX(-1); }

/* ---- Video hero: the headline sits on the right in RTL. The abstract skyline is mirrored
   so its bright towers move to the left, and the scrim is mirrored with it, giving the
   headline the same contrast as the English hero. ---- */
[dir="rtl"] .vhero__media { transform: scaleX(-1); }
[dir="rtl"] .vhero::before {
  background:
    linear-gradient(270deg, rgb(var(--ink-rgb) / .92) 0%, rgb(var(--ink-rgb) / .7) 38%, rgb(var(--ink-rgb) / .15) 70%, rgb(var(--ink-rgb) / 0) 100%),
    linear-gradient(0deg, rgb(var(--ink-rgb) / .85) 0%, rgb(var(--ink-rgb) / 0) 40%);
}
@media (max-width: 700px) {
  [dir="rtl"] .vhero::before {
    background:
      linear-gradient(270deg, rgb(var(--ink-rgb) / .92) 0%, rgb(var(--ink-rgb) / .7) 38%, rgb(var(--ink-rgb) / .15) 70%, rgb(var(--ink-rgb) / 0) 100%),
      linear-gradient(0deg, rgb(var(--ink-rgb) / .85) 0%, rgb(var(--ink-rgb) / 0) 40%),
      rgb(var(--ink-rgb) / .35);
  }
}

/* ---- Image page heroes: scrim dark on the right, under the text ---- */
[dir="rtl"] .page-hero--image::before {
  background: linear-gradient(270deg, rgb(var(--ink-rgb) / .95) 0%, rgb(var(--ink-rgb) / .82) 45%, rgb(var(--ink-rgb) / .35) 100%);
}
@media (max-width: 700px) {
  [dir="rtl"] .page-hero--image::before {
    background: linear-gradient(270deg, rgb(var(--ink-rgb) / .95) 0%, rgb(var(--ink-rgb) / .82) 45%, rgb(var(--ink-rgb) / .35) 100%), rgb(var(--ink-rgb) / .3);
  }
}
[dir="rtl"] .quote-band { background: linear-gradient(270deg, rgb(var(--ink-rgb) / .96) 0%, rgb(var(--ink-rgb) / .85) 55%, rgb(var(--ink-rgb) / .55)), var(--ink); }

/* ---- Diagrams and the network map are drawings, not text flow: they are never mirrored.
   Their SVG text keeps the English anchoring (start/end), and each Arabic label is a
   single right-to-left run, so it reads correctly. ---- */
[dir="rtl"] .netmap svg, [dir="rtl"] .svc-figure svg, [dir="rtl"] .insight-feature__figure svg { direction: ltr; }

/* ---- Horizontal scroll rows: the edge fades follow the reading direction. The scripts set
   is-start / is-end from the logical scroll position, so --fade-l is the start (right) edge. ---- */
@media (max-width: 999px) {
  [dir="rtl"] .svc-nav ul {
    -webkit-mask-image: linear-gradient(270deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
            mask-image: linear-gradient(270deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
  }
}
@media (max-width: 759px) {
  [dir="rtl"] .case-filter {
    -webkit-mask-image: linear-gradient(270deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
            mask-image: linear-gradient(270deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
  }
}
/* Isolated LTR runs (ISO 27001, phone examples, F801, Maple Woodz, and Latin client names with their
   parentheses inside the isolate: <bdi dir="ltr" lang="en">(Name)</bdi>) stay on one line, so the
   brackets can never split across lines and look reversed on phones */
[dir="rtl"] bdi[dir="ltr"] { white-space: nowrap; }
/* Fix round 2026-10-03 (review-arabic.md, RTL P2) */
:root[lang="ar"] .vhero__keep { white-space: nowrap; }   /* desktop too: "شبكات وأمن تبني عليهما / أعمالكم بثقة." */
:root[lang="ar"] .skip-link { top: -4rem; }              /* Arabic line height makes the link 49px tall: no sliver */
:root[lang="ar"] .ar-keep { white-space: nowrap; }       /* "جميع الحقوق محفوظة." in the footer */
@media (max-width: 600px) { :root[lang="ar"] .vhero .lede { line-height: 1.65; } }
/* Client names: Latin name as a quieter secondary line under the Arabic one (project tiles) */
:root[lang="ar"] .case__latin { margin: 0.1rem 0 0; font-size: var(--step--1); line-height: 1.4; color: var(--slate); }
/* Legal pages: "the English text prevails" note under the date */
:root[lang="ar"] .legal-langnote {
  margin: 1rem 0 0; padding: 0.75rem 1rem; max-width: 42em; font-size: var(--step--1); line-height: 1.7;
  background: var(--cobalt-soft); border-radius: var(--radius-surface); color: var(--ink);
}
/* Diagram labels: Arabic words run wider than the English ones inside the fixed boxes */
:root[lang="ar"] .svc-figure__label text { font-size: 14px; }
:root[lang="ar"] .svc-figure__label .svc-figure__sub { font-size: 11.5px; }
/* Arabic passages on English pages (the bilingual 404): Arabic face, no tracking */
:root:not([lang="ar"]) [lang="ar"] * { font-family: inherit; letter-spacing: 0; }
:root:not([lang="ar"]) section[lang="ar"] { line-height: 1.75; }
:root:not([lang="ar"]) section[lang="ar"] h2 { line-height: 1.3; }
