/* ═══════════════════════════════════════════════════════════════════════════
   ar.css — the Arabic locale sheet. Loaded ONLY by pages in the /ar/ tree,
   as the second stylesheet on line 1 of each ar content.html (after the
   page's own sheet, so these rules win ties).

   WHAT LIVES HERE and what deliberately does not:
     · Glyph coverage DOES live here: explicit families ('Cairo AB',
       'Kufi AB') + a Cairo-first blanket stack. (nav-lang.css keeps
       unicode-range helper faces for the menu's العربية label on EN/DE
       pages; on AR pages the explicit families below are authoritative.)
       The Arabic files are FULL fonts, deliberately not subset: subsetting
       was measured to break Cairo's mark composition (dot loss).
     · This sheet does three jobs: (1) typography corrections Arabic needs —
       letter-spacing zeroed, real font-weight where the site relied on
       variation settings, breathing room in line-heights that were tuned
       for Latin uppercase; (2) the RTL overlay for the SHARED shell
       (nav, fullscreen menu, footer) whose 183 KB Webflow sheet is physical
       and is never edited; (3) RTL re-aims for the few page mechanisms
       whose direction is data (the about beams, highlight wipes are
       already flipped in markup by the build's highDir).
     · Page sheets written logical-first (pricing.css, about.css) need
       almost nothing here. Reused page sheets (case, discipline, contact,
       projects…) get their fenced html[dir="rtl"] tails in their OWN files,
       not here — this sheet stays about the shell.

   The html element carries lang="ar" dir="rtl" (from the build), so every
   rule below is scoped to those attributes and is provably inert for EN/DE.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1 · typography ────────────────────────────────────────────────────── */

/* The faces, declared as their OWN families. (The unicode-range-under-the-
   site's-family-names route was tried first and measured: Chromium kept
   resolving Arabic runs through the full-range Quicksand faces and falling
   to the system naskh. Explicit families + Cairo-first stacks are the
   version that provably renders.) The subsets carry ONLY Arabic glyphs, so
   putting Cairo first costs Latin nothing — Latin falls through to
   Quicksand and the site's own identity holds for names and code. */
@font-face {
  font-family: 'Cairo AB';
  src: url('/assets/fonts/Cairo-Regular.ar.v2.woff2') format('woff2');
  font-weight: 100 500;
  font-display: swap;
}
@font-face {
  font-family: 'Cairo AB';
  src: url('/assets/fonts/Cairo-SemiBold.ar.v2.woff2') format('woff2');
  font-weight: 501 900;
  font-display: swap;
}
@font-face {
  font-family: 'Kufi AB';
  src: url('/assets/fonts/NotoKufiArabic-Bold.ar.v2.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
}

/* The blanket: (0,1,2) — outweighs every single-class font-family rule in
   the page sheets without !important, and loses on purpose to the display
   and mono promotions below. */
html[lang="ar"] body,
html[lang="ar"] body * {
  font-family: 'Cairo AB', Quicksand, Arial, sans-serif;
}

/* Display type: where the site reaches for Orbitron's engineered geometry,
   Arabic reaches for the squared Kufi. */
html[lang="ar"] :is(.text-title-lg-brier, .text-title-reg-brier,
  .text-impact-reg-brier, .text-impact-sm-brier, .font-brier) {
  font-family: 'Kufi AB', 'Cairo AB', Arial, sans-serif;
}

/* The "this is measured" mono signal keeps its mono for Latin/figures and
   borrows Cairo only for Arabic glyphs inside it. */
html[lang="ar"] :is(code, pre, .abt-code, .prc-v-n, .abt-run, .abt-rung,
  .abt-tag, .abt-duo-label, .wid-measure) {
  font-family: ui-monospace, SFMono-Regular, Menlo, 'Cairo AB', 'Courier New', monospace;
}

/* Arabic never letter-spaces: tracking breaks the joined script. The shared
   sheet sets em-tracking on eyebrows, buttons, nav links and display type,
   so this is the one justified blanket !important. */
html[lang="ar"] body,
html[lang="ar"] body * { letter-spacing: 0 !important; }

/* The site varies weight through font-variation-settings, which is a no-op
   on the static Arabic instances — promote real weights so display type
   actually selects the SemiBold/Kufi faces. */
html[lang="ar"] :is(h1, h2, h3, .text-nav-link, .btn-text, .text-eyebrow,
  .text-title-lg-mona, .text-title-reg-mona, .text-impact-reg-mona,
  .text-impact-sm-mona, .text-cta-short-intro) {
  font-weight: 600;
}
html[lang="ar"] :is(.text-title-lg-brier, .text-title-reg-brier,
  .text-impact-reg-brier, .text-impact-sm-brier) {
  font-weight: 700;
}

/* Latin display sizes assume uppercase ascent only; Arabic carries dots and
   marks above AND below — Cairo's final-yeh dots hang a full em under the
   baseline — so sub-1 line-heights collide. Open them up. */
html[lang="ar"] :is(h1, h2, h3, .text-nav-link, .text-title-lg-mona,
  .text-title-lg-brier, .text-title-reg-mona, .text-title-reg-brier,
  .text-impact-reg-mona, .text-impact-reg-brier, .text-impact-sm-mona,
  .text-impact-sm-brier) {
  line-height: 1.5;
}
html[lang="ar"] :is(p, li, .text-body-reg-mona) { line-height: 1.8; }

/* Labels and buttons ship at `line-height: 1`, and the footer/nav links are
   masked by `.text-clip-w { clip-path: polygon(0 -2%, 0 94%, …) }` — the
   window that hides the roll-up twin. At line-height 1 an Arabic descender
   sits BELOW 94% and the mask eats it, so the line box has to open.

   But the twin is a text-shadow at `0 var(--text-offset)`, and every
   --text-offset equals the FONT SIZE, i.e. the height of a line-height:1
   box. Open the box without moving the twin and the twin lands inside the
   window — the ghost row this pass measured. Both live on one number: set
   the offset in `em` so it tracks the same ratio the line box does. */
html[lang="ar"] :is(.btn-text, .text-eyebrow, .text-title-small-label) {
  --ar-label-lh: 1.55;
  line-height: var(--ar-label-lh);
}

/* AND THE MASK ITSELF, which the taller line box does not save. `.text-clip-w`
   cuts at 94% of the line box — the window that hides the roll-up twin. At
   line-height 1.55 the Arabic ink still runs to ~108% of that box, because the
   dots under a final ي hang below the descender line: measured on the footer's
   `راسلني`, ink ended 5px past the cut, and the word rendered as `راسلنى` —
   a different letter, and a misspelling of the owner's own words.
   Opening the window means the twin must move down to stay hidden, so the two
   numbers move together: window to 114%, twin to 2em (128% of the box). Any
   future change keeps that order — twin below window, window below ink. */
html[lang="ar"] .text-clip-w {
  clip-path: polygon(0 -2%, 0 114%, 100% 114%, 100% -2%);
}
html[lang="ar"] [split-text].btn-text {
  --text-offset: 2em;
}

/* THE FULLSCREEN MENU'S ROLL-UP TRICK, re-tuned. `.text-nav-link` paints a
   duplicate of itself exactly one line-height below via `text-shadow: 0
   5.25rem`, and `.nav-menu-link-w { overflow: clip }` hides it until hover
   rolls it up. The offset is hard-coded to the Latin line-height, so the
   moment Arabic opens the line box (above) the twin leaks into view and the
   descender dots clip. Both are one fix: keep the offset EQUAL to the line
   box, in em, so the two can never drift apart again. */
html[lang="ar"] .text-nav-link {
  --ar-nav-lh: 1.55;
  line-height: var(--ar-nav-lh);
  text-shadow: 0 calc(var(--ar-nav-lh) * 1em);
}

/* THE LOADER'S LATIN WORDMARK. The transition overlay's button is the one
   piece of char-split LATIN the AR tree inherits from the shared shell
   (`.transition-btn` in shell-standard.html — "Load Abbod"). Char-splitting
   wraps every letter in its own inline box, and inline boxes lay out in the
   CONTAINER's direction, so in RTL the word renders reversed: measured
   `dobbAdaoL` on /ar/, `LoadAbbod` on / and /de/. The bidi algorithm cannot
   save it — each letter is its own run. Same fix as the language switcher,
   but taken in CSS because the shell partial is shared with EN/DE: give the
   Latin run its own LTR inline context. Re-measure with the visual-order
   probe if the loader markup ever changes. */
html[dir="rtl"] .transition-btn .btn-text { direction: ltr; }

/* ── 2 · the shared shell, mirrored ────────────────────────────────────── */

/* The fullscreen menu's grid padding is physical in the shared sheet. */
html[dir="rtl"] .nav-menu-grid {
  padding-left: 8rem;
  padding-right: 2.25rem;
}

/* The home hero's corner HUD is pinned with a PHYSICAL `left: var(--gap)`
   in the shared sheet, so it stayed bottom-LEFT while the nav, the logo and
   every other shell element mirrored around it. Same token, other side. */
html[dir="rtl"] .home-hero-next-race-w { left: auto; right: var(--gap); }

/* Its caption is the standing Latin byline — it stays Latin in all three
   locales — and the engine splits it into per-line boxes, so the plaintext
   rule below (which lands on the parent) never reaches the line that holds
   the trailing comma: `creative developer — herne,` rendered with the comma
   jumped to the far side. Aim it at the lines themselves. */
html[dir="rtl"] .wfx-cap :is(.line, .word) { unicode-bidi: plaintext; }

/* ── ATOMIC LATIN TOKENS ───────────────────────────────────────────────────
   A counter, a hex colour, a phone number, a CSS selector, a handle: each is
   ONE token that must read exactly as authored, but Arabic pages set the
   paragraph direction to RTL and the bidi algorithm reorders their weak and
   neutral parts around it. Measured on the AR tree before these rules:
   `01 / 04` → `04 / 01`, `+49 155 67042737` → `6704273715549+`,
   `<section>` → `>section<`, `#C4552D` → `C4552D#`, `@alaaabbod` →
   `alaaabbod@`, `6 KB JS` → `KB JS 6`.

   TWO mechanisms, and the difference is not cosmetic — it was measured:

   1 · Token in ONE text node → `unicode-bidi: plaintext`. It derives the
       direction from the token's own first strong character, so a Latin
       token renders LTR and an Arabic one is untouched. That self-selection
       is why it can be aimed at shared classes that carry either language.
   2 · Token split across INLINE BOXES (`<span>01</span>/<span>10</span>`)
       → `direction: ltr`. plaintext cannot help there: boxes lay out in the
       container's direction, and a pure-digit token has no strong character
       to derive anything from. Verified — plaintext left `10 / 01` standing.

   Page sheets carry the same pair for their own tokens (projects.css,
   case.css, contact.css, whatido.css); these here are the shared-sheet
   classes and the generic elements, which no page sheet owns. */
html[dir="rtl"] :is(code, kbd, samp, b, .text-eyebrow, .text-title-small-label) {
  unicode-bidi: plaintext;
}
html[dir="rtl"] .jr-pill { direction: ltr; }

/* The Webflow sheet left-aligns a handful of text blocks explicitly. */
html[dir="rtl"] :is(.footer-links-w, .footer-links-col, .nav-menu-links-col) {
  text-align: right;
}

/* The nav-link roll-up trick uses a physical text-shadow offset — direction
   agnostic (vertical), left alone. The hamburger/brand order mirrors from
   flex direction automatically. */

/* ── 3 · page mechanisms whose direction is data ───────────────────────── */

/* The about beams: the split gradient and the tilt both encode
   design-on-the-start-side; in RTL the start side is the right. */
html[dir="rtl"] .abt-beam-bar {
  background: linear-gradient(-90deg,
    var(--abt-ink) 0 calc(var(--abt-l, .5) * 100%),
    var(--abt-grey-2) calc(var(--abt-l, .5) * 100%) 100%);
  transform: rotate(calc((var(--abt-l, .5) - var(--abt-r, .5)) * 18deg));
}
html[dir="rtl"] .abtjs .abt-pair:not(.is-cur) .abt-beam-bar { transform: rotate(0deg); }
@media (prefers-reduced-motion: reduce) {
  html[dir="rtl"] .abtjs .abt-pair:not(.is-cur) .abt-beam-bar {
    transform: rotate(calc((var(--abt-l, .5) - var(--abt-r, .5)) * 18deg));
  }
}

/* The role-weight meter's mint pointer sits on the logical end already
   (border-inline-end) — nothing to do. The process rail, nodes, carriage
   and stage grid are logical-native in pricing.css — nothing to do. */
