@charset "UTF-8";
/* =====================================================================
   YAZAWAJ — FOUNDATION LAYER  (Phase 0)
   ---------------------------------------------------------------------
   Loaded LAST on every page (declared in application/php/core/config/
   header.code.json -> "stylesheets"), so it can define the design system
   and self-hosted fonts without being overridden by the page bundles.

   PHASE 0 CONTRACT — this file is intentionally VISUALLY NEUTRAL:
     • It SELF-HOSTS the fonts already in use (Vazirmatn = "yazawaj",
       Almarai), replacing the Google-CDN @font-face at runtime. Same
       glyphs, same names → identical rendering, zero external request.
     • It DEFINES design tokens (spacing, radii, shadows, colours,
       typography, per-language Arabic scale) for later phases to CONSUME.
     • It does NOT yet apply those tokens to any element. Nothing moves.

   Later phases (buttons, RTL logical props, spacing, …) build on these
   tokens. Do not add component overrides here without a phase note.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. SELF-HOSTED FONTS  (local — no fonts.gstatic.com dependency)
   Files live in ../fonts/ . Ranges mirror Google Fonts subsets so the
   browser only downloads the subset a page actually needs.
   --------------------------------------------------------------------- */

/* Vazirmatn — exposed under the legacy family name "yazawaj" that the
   existing CSS already references (variable weight 100–900).
   PHASE 0: Arabic subset only, mirroring the original CDN face, so Latin
   text in "yazawaj, sans-serif" stacks keeps falling through to sans-serif
   exactly as today. Latin/latin-ext files are on disk for the typo phase. */
@font-face {
  font-family: 'yazawaj';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(../fonts/vazirmatn-arabic.woff2) format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}

/* Almarai — PHASE 0: weight 800 only (Arabic + Latin), mirroring the single
   weight the site currently ships, so heading weight resolution is unchanged.
   400/700 files are on disk and get declared in the typography phase. */
@font-face {
  font-family: 'Almarai'; font-style: normal; font-weight: 800; font-display: swap;
  src: url(../fonts/almarai-800-arabic.woff2) format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'Almarai'; font-style: normal; font-weight: 800; font-display: swap;
  src: url(../fonts/almarai-800-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Almarai 400 / 700 — activated so the Arabic body can use the brand face at
   a true regular/bold weight (headings stay pinned to 800 in Phase 6). */
@font-face {
  font-family: 'Almarai'; font-style: normal; font-weight: 400; font-display: swap;
  src: url(../fonts/almarai-400-arabic.woff2) format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'Almarai'; font-style: normal; font-weight: 400; font-display: swap;
  src: url(../fonts/almarai-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Almarai'; font-style: normal; font-weight: 700; font-display: swap;
  src: url(../fonts/almarai-700-arabic.woff2) format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
@font-face {
  font-family: 'Almarai'; font-style: normal; font-weight: 700; font-display: swap;
  src: url(../fonts/almarai-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------------------------------------------------------------------
   2. DESIGN TOKENS  (definitions only — consumed by later phases)
   Values are derived from the existing Bootstrap build and current CSS,
   not invented. Colours mirror the live palette (rose / rouge / vert).
   --------------------------------------------------------------------- */
:root {
  /* Brand palette — same values already in the compiled --bs-* set */
  --brand-primary:  #FFB6D9;   /* rose  (--bs-primary)  */
  --brand-danger:   #F31559;   /* rouge (--bs-danger, theme-color) */
  --brand-success:  #39b900;   /* vert  (--bs-success)  */
  --brand-info:     #BAD7E9;
  --brand-dark:     #202327;
  --brand-light:    #f9fafd;   /* current body background */

  /* Font stacks */
  --font-latin:   system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif;
  --font-arabic:  "Almarai", "yazawaj", "Segoe UI", Tahoma, sans-serif;
  --font-display: "yazawaj", "Almarai", sans-serif;

  /* Type scale — base matches the current 1rem / 1.5 body rhythm */
  --fs-title:  1.25rem;
  --fs-body:   1rem;
  --fs-button: 1rem;
  --fs-label:  0.9375rem;
  --fs-small:  0.8125rem;
  --lh-body:   1.5;
  --lh-button: 1.2;
  --lh-title:  1.2;

  /* Per-language Arabic optical scale. 1 everywhere by default (neutral).
     Overridden below for Arabic; only takes effect once components read
     these tokens (Phase 1+). */
  --fs-ar-scale: 1;

  /* Spacing scale — aligned to the Bootstrap spacers already in use */
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 0.75rem;
  --space-lg: 1rem;
  --space-xl: 1.5rem;
  --space-xxl: 3rem;

  /* Radii — from the rounded cards/pills already present */
  --radius-sm: 0.375rem;
  --radius-md: 0.5rem;
  --radius-lg: 1rem;
  --radius-pill: 50rem;

  /* Elevation — Bootstrap default shadows, tokenised */
  --shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
  --shadow-md: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}

/* Arabic gets a small, controlled optical bump (~+6%), NOT a blanket
   enlargement. Neutral until a component consumes --fs-ar-scale. */
:root:lang(ar),
[lang="ar"],
[dir="rtl"] {
  --fs-ar-scale: 1.06;
}

/* =====================================================================
   APPLICATION LAYER
   ===================================================================== */

/* ---------------------------------------------------------------------
   PHASE 1a — ROBUST BUTTON SYSTEM
   ---------------------------------------------------------------------
   ROOT CAUSE: .btn-dating and .gender-option already declare
   align-items / justify-content / gap, but they were never `display:flex`,
   so every one of those properties was INERT — which is exactly why icon +
   text inside those buttons never aligned and why height wandered between
   languages. We give every .btn a real inline-flex box, which ACTIVATES the
   alignment those buttons already asked for. No per-button patching, no
   !important. Bootstrap's compact controls (.btn-close, .navbar-toggler)
   are separate classes and are deliberately left untouched.

   We intentionally do NOT set font-size/padding here so each variant keeps
   its own identity (e.g. .btn-dating stays 0.95rem). Only box + rhythm. */
.btn:not(select) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  line-height: var(--lh-button);
}

/* Primary CTAs — full robustness: one consistent height across ar/fr/en
   (kills the language-dependent height jump) and a single line that grows
   in width instead of overflowing or being cut. */
.btn-dating,
.gender-option {
  min-height: 2.5rem;            /* ~40px, comfortable touch target */
  white-space: nowrap;
}

/* Inline action buttons (profile/friends rows) — just forbid an ugly wrap
   or overflow; keep their existing compact size. */
.message-btn,
.friend-btn,
.friend-cancel-btn,
.friend-request-btn,
.like-btn,
.btn-confirm,
.btn-cancel {
  white-space: nowrap;
}

/* ---------------------------------------------------------------------
   PHASE 1b — DIRECTIONAL ICONS MIRROR WITH WRITING DIRECTION
   ---------------------------------------------------------------------
   Horizontal arrows / chevrons are inherently directional: a "back" affordance
   points ← in LTR (fr/en) and → in RTL (ar). The icons are inline SVGs that
   already carry Bootstrap-Icons classes, so we mirror ONLY the horizontal
   glyphs when dir=rtl. Vertical (up/down) and non-directional icons (heart,
   trash, user, check…) are never touched — no blind global flip. */
[dir="rtl"] svg.bi-arrow-left,
[dir="rtl"] svg.bi-arrow-right,
[dir="rtl"] svg.bi-arrow-left-short,
[dir="rtl"] svg.bi-arrow-right-short,
[dir="rtl"] svg.bi-chevron-left,
[dir="rtl"] svg.bi-chevron-right {
  transform: scaleX(-1);
}

/* ---------------------------------------------------------------------
   PHASE 2 — RTL/LTR: fix the genuinely direction-HOSTILE rules
   ---------------------------------------------------------------------
   This codebase is Arabic-FIRST, so most physical values were tuned to look
   right in RTL and happen to be symmetric enough in LTR (menu badges, list
   spacing) — those are deliberately LEFT ALONE. Only the rules that pin a
   component to one direction are corrected here. Arabic stays identical;
   fr/en (LTR) stops being mirrored the wrong way.
   .btn-my-profile's physical !important padding has since been converted to
   logical at source (all bundles). Remaining position-sensitive rules like
   .dropend offsets are handled in the dropdown pass, not fought with more
   !important here. */

/* The mobile header was hard-forced to `direction: rtl` + right-aligned text,
   so in French/English it rendered right-to-left. Follow <html dir> instead. */
.custom-header {
  direction: inherit;
  text-align: start;
}

/* Dropdown text was pinned to the right; follow the writing direction. */
.dropdown-menu {
  text-align: start;
}

/* .justify-content-start had been overridden with the PHYSICAL value
   `justify-content: left`, so in RTL it aligned to the wrong (end) side.
   Restore the direction-aware flex value the utility is supposed to have. */
.justify-content-start {
  justify-content: flex-start !important;
}

/* ---------------------------------------------------------------------
   PHASE 3 — CONSISTENT INTERACTIVE-CONTROL HEIGHT (vertical rhythm)
   ---------------------------------------------------------------------
   Measured on the live site, control heights were scattered across
   31 / 32 / 37 / 40 / 46 / 56 px with no system, which is what makes forms
   and toolbars look uneven and makes buttons "change height by language".
   A single height token snaps inputs, selects, addons and standard buttons
   to one baseline (40px, a comfortable touch target that matches the Phase 1
   CTA height), so a field and the button next to it line up. Compact
   (.btn-sm/.form-control-sm), the close glyph, the navbar toggler and
   padding-stripped icon buttons (.p-0) keep their own size. */
:root {
  --control-h: 2.5rem;
  --control-h-sm: 2rem;
  --control-h-lg: 3rem;
}

.form-control,
.form-select,
.input-group-text,
.btn {
  min-height: var(--control-h);
}
.form-control-sm,
.form-select-sm,
.btn-sm {
  min-height: var(--control-h-sm);
}
.form-control-lg,
.form-select-lg,
.btn-lg {
  min-height: var(--control-h-lg);
}
/* Compact / icon-only controls keep their intrinsic size (low specificity
   above so scoped rules like .yz-search .btn can win without a :not() war). */
.btn-close,
.navbar-toggler,
select.btn,
.btn.p-0 {
  min-height: 0;
}

/* ---------------------------------------------------------------------
   PHASE 4 — MULTILINGUAL TYPOGRAPHY (conservative, reversible)
   ---------------------------------------------------------------------
   Arabic needs a slightly larger optical size than Latin for equal
   legibility (your §3). We apply the controlled --fs-ar-scale (1.06, set in
   Phase 0) ONLY to inherited running text in RTL — not to headings, buttons
   or anything sized absolutely, and NOT by scaling the rem system — so the
   Arabic LAYOUT stays pixel-identical and only paragraph/label copy grows a
   touch. Dial the amount from the single --fs-ar-scale token.

   Latin (fr/en) is pinned to the system UI stack it already used → neutral.
   We deliberately do NOT swap the Arabic body to the Almarai brand face or
   touch heading weights here; those are visible identity changes best done
   with staging eyes, and the extra Almarai weights are staged on disk ready
   for that step. */
[dir="ltr"] body {
  font-family: var(--font-latin);
}
[dir="rtl"] body {
  font-size: calc(1rem * var(--fs-ar-scale));
}

/* ---------------------------------------------------------------------
   PHASE 5 — FORMS: coherent, visible focus + invalid state
   ---------------------------------------------------------------------
   ROOT CAUSE: the bundles set `.form-control:focus { box-shadow: 0 0 }`,
   i.e. inputs had NO visible focus ring (a keyboard-accessibility gap, §15),
   while `.form-select:focus` had a faint pink ring — inconsistent. We give
   every focusable control ONE brand-coloured ring, and a coherent invalid
   border. Buttons use :focus-visible so a ring shows for keyboard users
   without adding a halo on mouse click. */
:root {
  --focus-ring: 0 0 0 0.2rem rgba(243, 21, 89, 0.22); /* brand danger, subtle */
}

.form-control:focus,
.form-select:focus,
.form-check-input:focus {
  border-color: var(--brand-primary);
  outline: 0;
  box-shadow: var(--focus-ring);
}
.btn:focus-visible {
  outline: 0;
  box-shadow: var(--focus-ring);
}

.form-control.is-invalid,
.form-select.is-invalid,
.was-validated .form-control:invalid,
.was-validated .form-select:invalid {
  border-color: var(--brand-danger);
}
.form-control.is-invalid:focus,
.form-select.is-invalid:focus,
.was-validated .form-control:invalid:focus {
  box-shadow: 0 0 0 0.2rem rgba(243, 21, 89, 0.3);
}

/* ---------------------------------------------------------------------
   PHASE 6 — ARABIC BRAND FONT ON BODY COPY
   ---------------------------------------------------------------------
   The site already ships Almarai (loaded for headings). Here we extend the
   brand face to Arabic running text, which until now fell back to the
   system Arabic font — so Arabic copy finally reads in the site's own type.
   Scoped to RTL only; fr/en keep the Latin system stack untouched.

   IDENTITY GUARD: headings previously rendered at weight 800 (the only
   Almarai weight that existed). Now that 400/700 are available, an
   unqualified heading would drop to ~400 and look lighter. We pin all
   headings to 800 so their current bold appearance is preserved exactly;
   only body/label copy adopts the regular (400) brand weight. */
[dir="rtl"] body {
  font-family: var(--font-arabic);
}
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
  font-weight: 800;
}

/* ---------------------------------------------------------------------
   PHASE 7 — SEARCH PANEL + DROPEND (bidi robustness)
   ---------------------------------------------------------------------
   SEARCH PANEL: in the desktop search form the "look for" label was
   inline-block, so it shared its line with the gender buttons. In Arabic the
   words are short and it fit; in fr/en the longer words pushed the 2nd gender
   button onto a new line and the panel looked broken. Root cause = label on
   the same line as the toggle. We put the label on its own line, so the two
   gender buttons sit side by side below it in every language. */
/* Desktop search form — self-contained flex layout.
   The compiled bundle is a SUBSET Bootstrap (e.g. col-lg-2 isn't included),
   so the search row can't rely on the grid. This flex layout owns its own
   sizing: three fields that grow (location twice as wide) plus an auto-width
   action, wrapping cleanly and mirroring in RTL. */
.yz-search {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem;
}
.yz-search .yz-f {
  flex: 1 1 12rem;
}
.yz-search .yz-f--wide {
  flex: 2 1 16rem;
}
.yz-search .yz-f--action {
  flex: 0 0 auto;
}
.yz-search .form-label {
  display: block;
  margin-bottom: 0.25rem;
  font-weight: 600;
}
/* A label placed INSIDE an inline row (e.g. "Âge" before "de … à … an")
   stays on the same line instead of stacking above. */
.yz-search .yz-row .form-label {
  display: inline;
  margin-bottom: 0;
}
/* Inline rows inside a field (gender buttons; age selects + labels). */
.yz-search .yz-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: nowrap;
}
.yz-search .yz-row .gender-option {
  flex: 1 1 auto;
  white-space: nowrap;
}
.yz-search .yz-lbl {
  margin: 0;
  font-size: 0.85rem;
  white-space: nowrap;
}
.yz-search .btn-warning {
  white-space: nowrap;
}
/* Age pickers: compact inline selects (not full-width form-selects). */
.age-picker {
  width: auto;
  min-width: 4.75rem;
  display: inline-block;
}

/* --- ONE consistent, compact height for EVERY search control ---------
   Measured heights were all over the place (pill 40, gender 32, age 37,
   location/icon 46, button 40). Snap them to a single compact height in
   both directions (also reduces the Arabic ones, as asked). Inputs/selects
   centre their text natively at a fixed height; buttons via inline-flex. */
.yz-search .btn,
.yz-search .form-control,
.yz-search .form-select,
.yz-search .input-group-text,
.shadowed-container .btn-menu {
  height: 2.125rem;
  min-height: 2.125rem;
  padding-block: 0;
  font-size: 0.875rem;
  line-height: 1.2;
}

/* --- Input-group corners: fix the RTL-baked PHYSICAL radius -----------
   The bundle rounds/squares corners with border-*-left/right-radius, so in
   LTR the outer corners land on the wrong side. Re-derive with LOGICAL
   corner radii → correct outer rounding in both directions. Systemic:
   applies to every input-group (search, login, …). */
/* Square every child, then round the OUTER corners of the first/last child.
   NOTE: we use PHYSICAL radii scoped by the PAGE direction ([dir] on <html>),
   NOT logical radii — because inputs (esp. password fields) often carry their
   own `direction: ltr`, which makes logical corner radii resolve on the wrong
   side inside an RTL page. Scoping by the page's [dir] is direction-correct
   regardless of each child's own direction. */
.input-group > * {
  border-radius: 0 !important;
}
[dir="ltr"] .input-group > :first-child,
[dir="rtl"] .input-group > :last-child {
  border-top-left-radius: 1rem !important;
  border-bottom-left-radius: 1rem !important;
}
[dir="ltr"] .input-group > :last-child,
[dir="rtl"] .input-group > :first-child {
  border-top-right-radius: 1rem !important;
  border-bottom-right-radius: 1rem !important;
}

/* --- Select chevron follows the writing direction --------------------
   The bundle pins the arrow to the left (RTL). Put it on the trailing
   (inline-end) side: right in LTR, left in RTL. Padding is logical so the
   text never sits under the arrow. */
.form-select {
  padding-inline-end: 1.75rem;
  padding-inline-start: 0.6rem;
}
[dir="ltr"] .form-select {
  background-position: right 0.6rem center;
}
[dir="rtl"] .form-select {
  background-position: left 0.6rem center;
}

/* --- Discussion header: flag must not touch the country name --------- */
#discussion_country .flag-icon {
  margin-inline-end: 0.4rem;
}

/* Discussion header (Messages): the delete/block actions must sit at the END
   of the bar (right in LTR, left in RTL). The name/country middle block wasn't
   growing, so the actions stayed stuck next to the name. Let the middle block
   grow to fill, which pushes the actions to the end. Done in CSS (via :has, so
   it targets the exact block) — holds even if the template isn't re-rendered. */
.discussion_container > div:first-child > div:has(#discussion_pseudo) {
  flex: 1 1 auto;
  min-width: 0;
}

/* DROPEND submenu (discussions filter): the custom rule pinned it to a
   PHYSICAL `left: 100%`, so it always opened to the right — in RTL it should
   open to the left (end side) and could run off-screen. Logical version:
   opens on the end side in both directions. */
.dropend .dropdown-menu[data-bs-popper] {
  left: auto;
  inset-inline-start: 100%;
  margin-left: 0;
  margin-inline-start: 0.125rem;
}

/* =====================================================================
   PHASE 8 — RTL-BAKED BOOTSTRAP UTILITIES  (root cause of fr/en mirroring)
   ---------------------------------------------------------------------
   The bundle was compiled RTL, so Bootstrap's DIRECTION-AWARE utilities were
   frozen with Arabic values: .text-start=right, .text-end=left, .ms-*=
   margin-right, .me-*=margin-left, and the desktop header + password were
   pinned to rtl. Correct for Arabic, reversed for fr/en. We restore the
   direction-correct values for LTR pages only; RTL keeps the bundle values.
   This is what was really behind the mirrored login, the glued flag, and the
   wrong-side alignments in French/English.
   ===================================================================== */

/* Desktop header was pinned to rtl (like .custom-header was in Phase 2) → the
   login/menu rendered right-to-left in fr/en. Follow the page direction. */
.shadowed-header {
  direction: inherit;
  text-align: start;
}

/* Text-alignment utilities */
[dir="ltr"] .text-start { text-align: left !important; }
[dir="ltr"] .text-end   { text-align: right !important; }

/* Start-margin utilities (baked as margin-right) → margin-left in LTR */
[dir="ltr"] .ms-0    { margin-left: 0 !important;       margin-right: 0 !important; }
[dir="ltr"] .ms-1    { margin-left: 0.25rem !important; margin-right: 0 !important; }
[dir="ltr"] .ms-2    { margin-left: 0.5rem !important;  margin-right: 0 !important; }
[dir="ltr"] .ms-3    { margin-left: 1rem !important;    margin-right: 0 !important; }
[dir="ltr"] .ms-4    { margin-left: 1.5rem !important;  margin-right: 0 !important; }
[dir="ltr"] .ms-5    { margin-left: 3rem !important;    margin-right: 0 !important; }
[dir="ltr"] .ms-auto { margin-left: auto !important;    margin-right: 0 !important; }
[dir="rtl"] .ms-auto { margin-right: auto !important;   margin-left: 0 !important; }

/* End-margin utilities (baked as margin-left) → margin-right in LTR */
[dir="ltr"] .me-0    { margin-right: 0 !important;       margin-left: 0 !important; }
[dir="ltr"] .me-1    { margin-right: 0.25rem !important; margin-left: 0 !important; }
[dir="ltr"] .me-2    { margin-right: 0.5rem !important;  margin-left: 0 !important; }
[dir="ltr"] .me-3    { margin-right: 1rem !important;    margin-left: 0 !important; }
[dir="ltr"] .me-4    { margin-right: 1.5rem !important;  margin-left: 0 !important; }
[dir="ltr"] .me-5    { margin-right: 3rem !important;    margin-left: 0 !important; }
[dir="ltr"] .me-auto { margin-right: auto !important;    margin-left: 0 !important; }
[dir="rtl"] .me-auto { margin-left: auto !important;     margin-right: 0 !important; }

/* Password field was pinned text-align:right (with forced direction:ltr) →
   its content sat on the wrong side in fr/en. */
[dir="ltr"] .password { text-align: left !important; }

/* Profile-card "send message" row. The compiled bundle is a subset and does
   NOT ship .justify-content-end, so we push the button to the inline-end here.
   flex-end is direction-aware: RTL (ar) → left, LTR (fr/en) → right. */
.yz-msg-end { justify-content: flex-end; }

/* --- Connected top-menu "your profile" pill --------------------------------
   Self-contained pill: circular avatar and the profile name sit on ONE line,
   vertically centred; same 2.5rem height / 1rem radius / soft shadow as its
   four .gender-option siblings, so the row stays perfectly aligned. It is set
   apart only by a soft lavender fill + the avatar, not by a different size.
   (.btn and .gender-option are kept for the shared radius/shadow/font metrics;
   everything size-critical is pinned here.) */
.yz-profilepill{
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  height: 2.5rem;                          /* == siblings' min-height */
  padding-inline: .3rem 1rem !important;   /* hug avatar, room after the name */
  padding-block: 0 !important;
  background: #e6e6fa;                      /* lavender — its identity */
  color: #444 !important;
  border: 1px solid #d7d0f2 !important;
  white-space: nowrap;
}
.yz-profilepill:hover{ background: #dcd6f5; color: #333 !important; }
.yz-profilepill__avatar{
  width: 1.9rem;                           /* ~30px, fills the pill height */
  height: 1.9rem;
  border-radius: 50%;
  object-fit: cover;                       /* square-crops any source ratio */
  flex: 0 0 auto;
  display: block;
}
.yz-profilepill__name{ line-height: 1; }

/* --- Signup: validation-rule / checkmark blocks ---------------------------
   These lists sit under the assistant's avatar and were indented with a hard
   `margin-right:62px` (avatar is on the right in RTL). Use a logical margin so
   the checks stay on the speaker's side: right in RTL (ar), left in LTR (fr/en). */
.yz-signup-indent { margin-inline-start: 62px; }

/* ===========================================================================
   SIGNUP CHAT — RTL→LTR MIRRORING
   The whole assistant/user chat UI is built with physical, RTL-assumed values
   (baked `rounded-start/-end`, JS-set `border-bottom-left-radius`, a ::before
   tail pinned right). Arabic (RTL) is the reference and is left untouched; the
   rules below mirror only what is physically wrong under [dir=ltr].
   =========================================================================== */

/* 1. Assistant bubble tail (::before triangle). RTL: pinned right (avatar right).
      LTR: pin left with the left border coloured (points to the left avatar). */
[dir="ltr"] .question div p::before,
[dir="ltr"] .response div p::before {
  right: auto;
  left: 0;
  border-color: transparent transparent transparent #444;
}
/* The user's own answer bubbles (.archived) sit on the opposite side, so their
   tail mirrors the other way: pinned left in RTL → right in fr/en (LTR). */
[dir="ltr"] .archived div div::before,
[dir="ltr"] .archived div button::before {
  left: auto;
  right: 0;
  border-color: transparent #e9ecef transparent transparent;
}

/* 2. Assistant bubble bottom corners. `rounded-end` is baked as physical-left,
      so in LTR the squared corner (the tail base) ended up bottom-right. Square
      the tail side (bottom-left) and round the far side (bottom-right). When the
      JS strips `rounded-end` to group consecutive bubbles, this stops applying
      and both bottom corners go flat — same grouping behaviour as RTL. */
[dir="ltr"] .question div p.rounded-end,
[dir="ltr"] .response div p.rounded-end {
  border-bottom-left-radius: 0 !important;
  border-bottom-right-radius: 1rem !important;
}
/* The user's own answer bubbles use `rounded-start` (baked physical-right) and
   sit on the opposite side. Their tail is on the right in LTR, so square the
   bottom-right (tail base) and round the far bottom-left corner. */
[dir="ltr"] .archived .rounded-start,
[dir="ltr"] .bg-gray.rounded-start {
  border-bottom-right-radius: 0 !important;
  border-bottom-left-radius: 1rem !important;
}

/* 3. Success bubbles get an inline `border-bottom-left-radius:1rem` from the JS
      (physical left). Mirror to the right in LTR; !important beats the inline
      style the script writes. */
[dir="ltr"] .location-success p,
[dir="ltr"] .date-success p,
[dir="ltr"] .pseudo-success p,
[dir="ltr"] .mail-success p,
[dir="ltr"] .passwd-success p,
[dir="ltr"] .occupation-success p {
  border-bottom-left-radius: 0 !important;
  border-bottom-right-radius: 1rem !important;
}

/* 4. Date picker button group [day | month | year]. `rounded-start` (day) and
      `rounded-end` (year) are baked physical-RTL, so in LTR the pill was rounded
      on its inner edges. Round the OUTER edges: day on the left, year on the
      right (same fix pattern as the input-group radii). */
[dir="ltr"] .date-value.rounded-start {   /* day → leftmost: round the left edge */
  border-radius: 1rem .25rem .25rem 1rem !important;   /* TL TR BR BL */
}
[dir="ltr"] .date-value.rounded-end {     /* year → rightmost: round the right edge */
  border-radius: .25rem 1rem 1rem .25rem !important;
}

/* 5. Answer radio buttons. Built with `float-end`, so the radio floated to the
      trailing edge — right in LTR. Lay each option out as a normal flex row so
      the radio leads (left) with the label after it — the conventional fr/en
      form-check order. */
[dir="ltr"] .archived .form-check {
  display: flex;
  align-items: center;
  gap: .4rem;
}
[dir="ltr"] .archived .form-check-input.float-end {
  float: none;
  margin: 0;
}
[dir="ltr"] .archived .form-check-label {
  padding-inline-start: 0;
}

/* 6. Progress bar was pinned `flex-row-reverse` (fills from the right, RTL).
      In fr/en it must fill from the left. */
[dir="ltr"] .lover.progress {
  flex-direction: row !important;   /* beats the .flex-row-reverse utility */
}

/* 7. "Next" arrow. Its column leads the proposition row (right in RTL, left in
      LTR). The fr/en convention puts the advance control AFTER the fields, so
      move only that column to the end under [dir=ltr]. Arabic keeps it leading.
      Scoped to the column that actually holds a `.next` control, so the answer
      rows (which have no `.next`) are untouched. */
[dir="ltr"] .proposition .row > .col:has(> .next) {
  order: 2;
}

/* 8. Universal wizard navigation — the advance/back controls keep the SAME
      physical layout in every language (they are controls, not text):
        • "next"     → right, arrow pointing right
        • "previous" → left,  chevron pointing left
      Position: next already lands on the right (rule 7 in LTR; leading = right
      in RTL). The footer is [canvas][progress][prev]; RTL already renders it as
      [prev][progress][canvas] and works, so mirror the LTR footer to the same
      order (row-reverse) — this keeps the confetti canvas out of the way in
      both. Direction: the global RTL icon-mirroring (Phase 1b) must NOT flip
      these two nav glyphs — keep them fixed. */
[dir="ltr"] .modal-footer:has(.prev) {
  flex-direction: row-reverse;
}
[dir="rtl"] .next svg,
[dir="rtl"] .prev svg {
  transform: none !important;
}

/* 9. Date-picker modals were pinned to width:100px — too narrow for month
      names (Janvier/Septembre/Décembre) which overflowed and looked off-centre.
      Size the dialog to its content and never let an option wrap. Universal. */
#Modal-day-list .modal-dialog,
#Modal-month-list .modal-dialog,
#Modal-year-list .modal-dialog {
  width: 10rem !important;   /* fits the longest month, stays compact (not full-screen) */
  max-width: 90vw !important;
  margin-left: auto !important;
  margin-right: auto !important;
}
#Modal-day-list .date-prop,
#Modal-month-list .date-prop,
#Modal-year-list .date-prop {
  white-space: nowrap;
}

/* 10. Occupation / pseudo / password hint lists keep the browser-default 40px
       inline-start padding on the <ul> (the bundle's .list-group does not reset
       it here), over-indenting the hints. In fr/en drop it so they sit flush
       left; RTL keeps its right indent. */
[dir="ltr"] .yz-signup-indent ul {
  padding-left: 0 !important;
  list-style: none;
  text-align: left;
}

/* --- Mobile modal back/close arrow -----------------------------------------
   The sign-in modal header is [title, ← button] with space-between, so the
   dismiss arrow lands at the trailing corner: left in RTL (ar), right in LTR.
   For fr/en we want the back arrow at the leading corner (left), matching the
   Arabic placement and the usual LTR back-button position. Reverse the header
   only in LTR; Arabic is untouched. Scoped class → no other modal affected. */
[dir="ltr"] .yz-modal-back { flex-direction: row-reverse; }

/* --- Grid columns missing from the subset bundle ---------------------------
   The compiled bundle ships only col-md-1/4/6/7. The header (col-md-3 logo +
   col-md-8 menu) and the login form (col-md-3 button) need these two. */
@media (min-width: 768px) {
  .col-md-3 { flex: 0 0 auto; width: 25%; }
  .col-md-8 { flex: 0 0 auto; width: 66.666667%; }
}
/* .position-relative is also absent from the subset bundle. */
.position-relative { position: relative !important; }

/* --- Header language switcher ----------------------------------------------
   Two languages OTHER than the current one (the current one is stripped
   server-side via [{show-XX-lang}] visibility blocks).
   MOBILE (base): bare circular flags, side by side and touching — no pill,
   no white padding. LARGE header (--lg): labelled pills, pinned to the corner
   so they don't push the login form. */
.yz-langswitch {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
}
.yz-lang {
  display: inline-flex;
  align-items: center;
  padding: 0;                     /* no white padding around the flag */
  border-radius: 999px;
  border: 1px solid #f3d3e2;      /* keep the ring */
  box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
  text-decoration: none;
  line-height: 1;
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.yz-lang:hover { border-color: #f31559; box-shadow: 0 3px 8px rgba(243, 21, 89, .18); }
.yz-lang .flag-icon {
  width: 1.5rem;                   /* 24px on mobile */
  height: 1.5rem;
  border-radius: 50%;
  background-size: cover;          /* flag fills the circle */
  background-position: center;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .12);
  display: block;
}

/* Mobile header: the wordmark (yazawaj.com) is centred V/H; the menu sits at
   one edge, the avatar + flags grouped at the other (far from the wordmark). */
.custom-header .container-fluid { position: relative; }
.yz-mlogo {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  margin: 0 !important;
  white-space: nowrap;
  z-index: 1;
}
/* Avatar (home logo) = same 24px as the flags, and the same .35rem gap between
   it and the nearest flag as there is between the two flags. */
.custom-header .yz-langswitch {
  margin: 0 !important;
  margin-inline-end: .35rem !important;
}
/* fr/en desktop: the bold sub-title under the wordmark runs longer than in
   Arabic, so trim it from the default .875em to .8em. */
[dir="ltr"] .shadowed-header .h5 small { font-size: .8em; }

.custom-header .yz-langswitch ~ a img {
  width: 1.85rem !important;                  /* bigger than the flags to offset the
                                                logo's internal padding so it reads
                                                the same visual size */
  height: 1.85rem !important;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid #f3d3e2;                 /* same ring style as the flag pills */
  box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
  box-sizing: border-box;
}

/* Large header: labelled pill group, absolutely pinned to the top corner so it
   is out of the flow and the login form can be centred. */
.yz-langswitch--lg {
  position: absolute;
  top: .3rem;
  inset-inline-end: .6rem;        /* right in LTR, left in RTL */
  z-index: 5;
  display: flex;
  gap: .4rem;
}
.yz-langswitch--lg .yz-lang {
  gap: .35rem;
  padding: .2rem .45rem;
  border-radius: 999px;
  background: #fff;
  border: 1px solid #f3d3e2;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .08);
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.yz-langswitch--lg .yz-lang:hover {
  transform: translateY(-1px);
  border-color: #f31559;
  box-shadow: 0 3px 8px rgba(243, 21, 89, .18);
}
.yz-langswitch--lg .yz-lang .flag-icon {
  width: 1.3rem;
  height: 1.3rem;
}
.yz-lang__txt {
  font-size: .8rem;
  font-weight: 700;
  color: #444;
}
.yz-langswitch--lg .yz-lang:hover .yz-lang__txt { color: #f31559; }
