/* Language selector.

   Sits beside the theme toggle and borrows the same restraint: a small control
   that names the current state, opening a menu only when asked. Tokens come
   from css/main.css; the fallbacks let the control look right on the standalone
   pages that do not load the full stylesheet. */

.locale-switcher {
  position: relative;
  display: flex;
  align-items: stretch;
  flex-shrink: 0;
}

.locale-switcher__trigger {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  font: inherit;
  font-size: clamp(11px, 0.72vw, 13px);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* Wide enough for the two-letter codes and the single CJK glyph alike, so the
     header does not reflow when the language changes. */
  min-width: 44px;
  min-height: 44px;
  padding: 0 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-primary, #EEEADE);
  transition: color .24s ease, background-color .24s ease;
}

.locale-switcher__trigger:hover,
.locale-switcher__trigger:focus-visible {
  color: var(--color-accent-soft, #C7B9FF);
  background-color: rgba(var(--color-text-rgb, 238, 234, 222), 0.06);
}

.locale-switcher__menu {
  position: absolute;
  top: 100%;
  /* Anchored to the trigger's trailing edge, which flips with the document in
     Arabic without a separate rule. */
  inset-inline-end: 0;
  z-index: 80;
  min-width: 190px;
  display: none;
  flex-direction: column;
  padding: 6px 0;
  background: var(--color-canvas, #1E1E1E);
  border: 1px solid rgba(var(--color-rule-rgb, 238, 234, 222), 0.3);
}

.locale-switcher.is-open .locale-switcher__menu { display: flex; }

.locale-switcher__item,
.locale-switcher__reset {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  font: inherit;
  font-size: clamp(12px, 0.8vw, 14px);
  /* Language names are set in their own script, so no uppercasing: it mangles
     several of them and means nothing in CJK or Arabic. */
  text-transform: none;
  letter-spacing: 0;
  text-align: start;
  min-height: 44px;
  padding: 0 16px;
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--color-text-primary, #EEEADE);
  transition: color .2s ease, background-color .2s ease;
}

.locale-switcher__item:hover,
.locale-switcher__item:focus-visible,
.locale-switcher__reset:hover,
.locale-switcher__reset:focus-visible {
  background-color: rgba(var(--color-text-rgb, 238, 234, 222), 0.08);
  color: var(--color-accent-soft, #C7B9FF);
}

/* The current language is marked with a rule rather than a tick, so the cue
   survives a font that has no check glyph. */
.locale-switcher__item[aria-selected="true"] {
  color: var(--color-accent-soft, #C7B9FF);
  box-shadow: inset 2px 0 0 var(--color-accent-soft, #C7B9FF);
}

/* Discreet by design: an escape hatch for a wrong guess, not a peer of the
   languages above it. */
.locale-switcher__reset {
  font-size: clamp(10px, 0.68vw, 12px);
  /* The display rule above beats the user-agent's [hidden] { display: none },
     so hiding has to be restated at this specificity or the control shows even
     when there is no manual choice to reset. */
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-muted, rgba(238, 234, 222, 0.6));
  margin-top: 6px;
  padding-top: 10px;
  border-top: 1px solid rgba(var(--color-rule-rgb, 238, 234, 222), 0.25);
}

.locale-switcher__reset[hidden] { display: none; }

@media (max-width: 768px) {
  .locale-switcher__menu { min-width: 170px; }
}

@media (prefers-reduced-motion: reduce) {
  .locale-switcher__trigger,
  .locale-switcher__item,
  .locale-switcher__reset { transition: none; }
}

/* ── Right-to-left ──────────────────────────────────────────────────────────
   Arabic sets dir="rtl" on <html>. That is correct, and the standalone
   documents — privacy, access, request-access, the case study — mirror cleanly
   from it because they are ordinary vertical pages.

   The homepage is deliberately excluded, and it is worth being precise about
   why rather than treating this as a temporary hack.

   Its seven sections are one pinned composition that a GSAP controller drives
   along the X axis, using distances measured from element geometry. Much of the
   layout is absolutely positioned in viewport units against a left-hand origin.
   Flipping the document's inline axis underneath that does two things at once:
   it invalidates every measured section boundary, and it right-aligns text
   inside boxes whose position assumes the opposite, which clips the headline
   against its own container.

   So the homepage shell stays LTR under dir="rtl". Nothing about that is
   right for Arabic prose — but the homepage has no Arabic prose yet, and
   rendering English right-aligned and clipped would be worse than rendering it
   as designed. Mirroring the rail properly, so sections advance right-to-left
   and the index rail moves to the opposite edge, is real layout work that
   belongs with the Arabic translation, not ahead of it. See DESIGN_SYSTEM.md. */
[dir="rtl"] .header,
[dir="rtl"] .scroll,
[dir="rtl"] .scroll * {
  direction: ltr;
}

/* …with one correction now that Arabic copy actually exists.

   The rule above keeps the LAYOUT axis left-to-right, which is what the GSAP
   geometry depends on. But `direction` governs text as well as boxes, and
   forcing it on Arabic prose puts sentence-final punctuation at the wrong end
   — a full stop rendering at the start of the line.

   So direction is handed back to the text itself on the elements that carry
   prose, while their containers stay LTR. The box positions are untouched; only
   the characters inside them run right-to-left, which is the correct reading
   order and the correct place for the punctuation. */
[dir="rtl"] .scroll :is(h1, h2, h3, h4, p, li, dt, dd, blockquote, figcaption,
                        label, .hero-h1__line, .hero-stat__label span) {
  direction: rtl;
  text-align: right;
  unicode-bidi: isolate;
}

/* Latin runs inside Arabic prose — product names, "SaaS", "AI", URLs and email
   addresses — are isolated so they keep their own left-to-right order instead
   of being reordered by the surrounding paragraph. */
[dir="rtl"] .scroll [lang="en"],
[dir="rtl"] [dir="ltr"] {
  unicode-bidi: isolate;
  direction: ltr;
}

/* The language menu is the exception inside that shell: it is chrome, it is the
   control being used to choose Arabic in the first place, and its own items are
   tagged with their language so each name shapes correctly on its own. */
[dir="rtl"] .locale-switcher__menu { direction: rtl; }
[dir="rtl"] .locale-switcher__item[lang="ar"] { direction: rtl; }

/* ── Script-aware typography ────────────────────────────────────────────────
   Font coverage is deliberate per script.

   Latin (en, fr, de) and Cyrillic (ru) stay on HelveticaNeueCyr, the existing
   typeface — the "Cyr" cut carries Cyrillic, verified by measurement rather
   than by the name.

   Arabic and CJK fall to platform stacks rather than webfonts. The Content
   Security Policy set in netlify/edge-functions/auth-guard.ts allows
   font-src 'self' only, so Google-hosted Noto would be blocked; widening the
   CSP a second time to fetch fonts is a worse trade than using the high-quality
   faces every target platform already ships. Those stacks include Noto Sans
   Arabic / JP / SC where present (Linux, Android, ChromeOS) and the platform
   equivalent elsewhere. No network request, no swap period, no layout shift.

   Self-hosting subset Noto files under /fonts is the upgrade path if identical
   rendering across platforms is ever needed. */
:root[data-locale="ar"] {
  --font-script: "Noto Sans Arabic", "Geeza Pro", "Segoe UI Arabic",
                 "Arabic Typesetting", "Tahoma", sans-serif;
}
:root[data-locale="ja"] {
  --font-script: "Noto Sans JP", "Hiragino Sans", "Hiragino Kaku Gothic ProN",
                 "Yu Gothic", "Meiryo", sans-serif;
}
:root[data-locale="zh-Hans"] {
  --font-script: "Noto Sans SC", "PingFang SC", "Hiragino Sans GB",
                 "Microsoft YaHei", "Source Han Sans SC", sans-serif;
}

/* The script face is added AFTER the Latin one, so Latin glyphs inside
   translated copy — product names, "SaaS", "AI" — keep the portfolio's
   typeface, and only the characters the Latin font lacks fall through. */
:root[data-locale="ar"] body,
:root[data-locale="ja"] body,
:root[data-locale="zh-Hans"] body {
  font-family: 'HelveticaNeueCyr', var(--font-script);
}

/* Scripts without letter case.

   Latin uppercasing is meaningless in Arabic, Japanese and Chinese, and Latin
   tracking actively breaks Arabic by pulling apart glyphs that must join. Both
   are switched off wholesale for those locales rather than per component, so a
   section added later cannot forget. */
:root.i18n-caseless .header__menu a,
:root.i18n-caseless .hero-h1,
:root.i18n-caseless .hero-stat__label,
:root.i18n-caseless .hero-caps,
:root.i18n-caseless .locale-switcher__reset,
:root.i18n-caseless h1,
:root.i18n-caseless h2,
:root.i18n-caseless h3 {
  text-transform: none;
  letter-spacing: normal;
}

/* Cyrillic is cased, so uppercase stays — but Latin tracking set for short
   English words crowds longer Cyrillic ones. */
:root[data-locale="ru"] .hero-stat__label,
:root[data-locale="ru"] .header__menu a {
  letter-spacing: 0.03em;
}

/* CJK and Arabic need more leading than the tight Latin display settings. */
:root.i18n-caseless .hero-h1 { line-height: 1.18; }
:root.i18n-caseless .hero-stat__label { line-height: 1.45; }

/* ── Room for longer translations ───────────────────────────────────────────
   The hero headline is sized so English's longest line ("production-ready",
   10.25em) just fits its column. German and Russian run longer, so the ceiling
   comes down for those locales rather than letting the text collide with the
   right-hand panel. Still well above an accessible size — the clamp floor is
   untouched. */
:root[data-locale="de"] .hero-h1,
:root[data-locale="ru"] .hero-h1 { font-size: min(8.1cqi, 3.4rem); }
:root[data-locale="fr"] .hero-h1 { font-size: min(8.6cqi, 3.6rem); }

/* Statistic labels: two lines built from an array, one element per line, so
   each language picks its own break instead of inheriting an English <br>. */
.hero-stat__label span { display: block; }

/* The longest German and Russian labels need a little more headroom than the
   English tuning allows. */
:root[data-locale="de"] .hero-stat__label,
:root[data-locale="ru"] .hero-stat__label,
:root[data-locale="fr"] .hero-stat__label { font-size: min(9.4cqi, 0.74rem); }

/* Nothing may collide with the utility controls, whatever the language. */
.header__menu { min-width: 0; }
.header__menu a { overflow-wrap: break-word; }

/* Live region for the completed-change announcement: available to screen
   readers, never shown, and never affecting layout. */
.locale-switcher__status {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The hero actions sit side by side in English with a 48px gap. Longer labels
   (French, German, Russian) wrap them onto two rows, where that same gap is
   applied vertically and reads as a layout break rather than a stack. The
   column gap is unchanged, so English is untouched; only the wrapped case
   tightens. */
.hero-actions { row-gap: clamp(10px, 1.2vw, 16px); }

/* Headings whose lines were authored as <br> now render one element per line,
   so each language chooses its own break points instead of inheriting
   English's. They must stack like the line breaks they replace. */
.h1 > span { display: block; }
