/* ============================================================
   MAFORGEX POS — auth screens (login, sign-up, OTP, password reset)

   Split layout: the form sits on a white panel on the LEFT, the
   illustration fills the RIGHT half edge-to-edge. Below lg the
   illustration drops away and the form takes the full width.

   The markup order is illustration-then-form (.left-content then
   .right-content), so flex `order` does the swap rather than the
   Blade being rewritten in six files.

   Requires maforgex-pos-tokens.css to be linked first.
   ============================================================ */

body {
    font-family: var(--q-font) !important;
    color: var(--q-text);
    background: var(--q-bg) !important;
    -webkit-font-smoothing: antialiased;
    min-height: 100vh;
}

/* ---- split layout ---- */

.authentications {
    display: flex !important;
    align-items: stretch !important;
    justify-content: flex-start !important;
    flex-direction: row !important;
    /* min-height, NOT height: the sign-up form is taller than the viewport and
       must be able to grow (and scroll). The illustration cannot stretch the row
       because it is absolutely positioned, so no fixed height is needed here. */
    min-height: 100vh;
    /* `dvh` suit la barre d'URL mobile qui se rétracte au défilement. `100vh`
       vaut la fenêtre barre REPLIÉE : sur un téléphone où tout tenait déjà,
       il créait une soixantaine de pixels de défilement fantôme. Déclarée
       après, l'unité est simplement ignorée par les moteurs qui l'ignorent. */
    min-height: 100dvh;
    width: 100%;
    padding: 0 !important;
    margin: 0 !important;
}

/* FORM — left half */
.authentications .right-content {
    order: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 46% !important;
    max-width: 46%;
    width: 46% !important;
    background: var(--q-surface);
    padding: 56px 48px !important;
    margin: 0 !important;
    position: relative;
}

/* ILLUSTRATION — right half, edge to edge.

   The image is positioned ABSOLUTELY inside the panel. That is deliberate and
   load-bearing: an in-flow <img> contributes its own scaled height to the flex
   row, so a tall source (e.g. 2026x3600) stretches the page and pushes the form
   below the fold. Out of flow, the panel's height comes from the form column /
   100vh only, and object-fit crops the photo to whatever that turns out to be.
   The layout is therefore independent of the image's dimensions and aspect.

   assets/css/style.min.css also styles this panel as an inset light-blue card
   (`.left-content{padding:2.5rem 1.25rem;border-radius:.5rem;background:#ecf4ff}`)
   and caps the image (`.left-content figure img{max-width:100%;height:auto}`).
   Those are overridden by selector, not out-specified, hence !important. */
.authentications .left-content,
.left-content {
    order: 2;
    display: block !important;
    flex: 1 1 54% !important;
    max-width: 54% !important;
    width: 54% !important;
    position: relative !important;
    overflow: hidden !important;
    padding: 0 !important;
    border-radius: 0 !important;
    /* the only child is absolutely positioned, so there is nothing in flow to
       give this height — stretch handles the tall case, min-height the rest */
    align-self: stretch !important;
    min-height: 100vh !important;
    height: auto !important;
    /* brand gradient shows while the image loads, and behind transparent art */
    background: var(--q-primary-grad) !important;
}
.authentications figure,
.left-content figure {
    position: absolute !important;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    display: block !important;
    margin: 0 !important;
    padding: 0 !important;
    height: auto !important;
    width: auto !important;
    overflow: hidden;
}
.authentications .left-content img,
.left-content figure img {
    position: absolute !important;
    top: 0;
    left: 0;
    display: block !important;
    width: 100% !important;
    height: 100% !important;
    max-width: none !important;
    max-height: none !important;
    /* fills the panel and crops the overflow — switch to `contain` if your art
       must not be cropped (it will then letterbox onto the gradient) */
    object-fit: cover !important;
    /* shift this if your photo's subject sits off-centre, e.g. `70% center` */
    object-position: center;
}

/* ---- the form itself: a plain panel, not a floating card ---- */

.authentication-form {
    background: transparent !important;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0 !important;
    width: 100%;
    max-width: 400px;
    margin: 0 !important;
    /* style.min.css fait de ce <form> une colonne flex avec `gap:3.75rem`
       (60px), ce qui creusait l'écart entre l'accroche et le premier champ.
       Un `gap` de flexbox ne se règle pas par les marges des enfants : il faut
       le redéfinir ici. Les seuls enfants directs sont l'en-tête, le contenu
       et — sur quatre écrans — le pied, qui porte déjà sa propre marge et son
       filet de séparation ; le réduire ne décolle donc rien d'autre. */
    gap: 3px;
}
.authentication-form.px-lg-5 { padding-left: 0 !important; padding-right: 0 !important; }

/* Logo sits at the top of the form itself, directly above the heading —
   in flow, not pinned to the panel corner. */
/* Aucune marge basse : l'écart avec le premier champ est porté par le `gap`
   de .authentication-form, pour n'avoir qu'un seul réglage à toucher. */
/* `start` et non `left` : le mot-clé logique suit la direction du document,
   donc l'en-tête (logo, titre, sous-titre) se cale du même côté que les
   libellés des champs — à gauche en français, à droite en arabe. Avec `left`
   le titre restait collé à gauche pendant que « البريد الإلكتروني » partait à
   droite, et le bloc paraissait désaligné du formulaire. */
.authentication-form-header { text-align: start; margin-bottom: 0; }
.authentication-form-header .logo {
    position: static;
    display: block;
    margin: 0 0 1.5rem;
}
/* Constrain by HEIGHT, not width: site_logo may be square, and a 150px-wide
   square mark is 150px tall — it collided with the vertically-centred form. */
.authentication-form-header .logo img {
    max-height: 44px;
    max-width: 190px;
    width: auto;
    height: auto;
    object-fit: contain;
}

.form-title {
    color: var(--q-text) !important;
    font-weight: var(--q-fw-bold);
    font-size: var(--q-fs-h1);
    line-height: var(--q-lh-heading);
    margin-bottom: .4rem;
}
.form-des { color: var(--q-text-soft) !important; font-size: var(--q-fs-body); margin-bottom: 0; }

/* ---- fields ---- */

.authentication-form .form-label {
    /* Même cas que .form-control : style.min.css pose « Titillium Web » sur
       `.form-group .form-label`. Les libellés arabes sortaient donc dans une
       fonte système alors que le titre juste au-dessus, lui, n'a pas de règle
       vendor et rendait bien en IBM Plex Sans Arabic — d'où deux fontes
       arabes visiblement différentes sur le même écran. */
    font-family: var(--q-font);
    color: var(--q-text) !important;
    font-weight: var(--q-fw-regular);
    font-size: var(--q-fs-body);
    margin-bottom: 8px;
}

.authentication-form .form-control {
    /* style.min.css impose « Titillium Web » sur .form-control. La fonte est
       latine : en arabe la valeur saisie et le placeholder retombaient sur une
       fonte système, visiblement différente des libellés au-dessus. Le token
       ramène IBM Plex Sans — dont la variante arabe est auto-hébergée et
       greffée sur la même famille par unicode-range (cf. tokens). Corrige
       aussi le français, où les champs sortaient en Titillium Web alors que
       tout le reste de la page est en Plex. maforgex-pos-theme.css:922 pose
       déjà la même règle côté admin. */
    font-family: var(--q-font);
    background: var(--q-surface-2) !important;
    border: 1px solid transparent !important;
    border-radius: var(--q-r-pill) !important;
    color: var(--q-text) !important;
    height: 48px;
    padding: 0 20px;
    font-size: var(--q-fs-body);
    box-shadow: none;
    transition: border-color .16s ease, box-shadow .16s ease, background .16s ease;
}
/* `::placeholder` hérite de l'input, mais style.min.css redéclare la fonte
   explicitement sur `.form-group .form-control::placeholder` — une valeur
   déclarée bat l'héritage, il faut donc la reposer ici aussi. */
.authentication-form .form-control::placeholder {
    font-family: var(--q-font);
    color: var(--q-text-soft) !important;
    opacity: 1;
}
.authentication-form .form-control:focus {
    background: var(--q-surface-2) !important;
    border-color: transparent !important;
    box-shadow: var(--q-ring) !important;
    outline: none;
}

/* stack the two half-width columns into one column */
.authentication-form-content .col-sm-6,
.authentication-form-content .col-lg-12,
.authentication-form-content .col-xl-6 {
    flex: 0 0 100% !important;
    max-width: 100% !important;
}

.form-group { position: relative; margin-bottom: .25rem; }

/* show/hide password eye */
/* L'oeil doit se placer au bout du champ, donc à DROITE en français et à
   GAUCHE en arabe. `right` est une propriété physique : elle laissait l'icône
   du côté droit en RTL, par-dessus le texte saisi.

   `right: auto` est indispensable avant la propriété logique : style.min.css
   pose `.show-hide{right:0.25rem}`, et un élément qui aurait à la fois `right`
   et `left` définis s'étirerait d'un bord à l'autre au lieu de se caler.
   Déclaré ensuite, `inset-inline-end` gagne en LTR et vaut `left` en RTL. */
.show-hide.toggle-password {
    position: absolute;
    right: auto;
    inset-inline-end: .9rem;
    top: 2.4rem;
    cursor: pointer;
    line-height: 1;
    color: var(--q-text-soft);
}

/* Réserve la place de l'icône pour que la saisie ne passe pas dessous.
   Ciblé par :has() afin de n'affecter que les champs qui portent un oeil ;
   sur un moteur sans :has() la règle est simplement ignorée et l'on retrouve
   le comportement actuel. */
.authentication-form .form-group:has(.toggle-password) .form-control {
    padding-inline-end: 46px;
}

/* Piège : deux directions différentes sur deux éléments imbriqués.
   L'oeil se résout contre .form-group, qui est en rtl -> il part à GAUCHE.
   L'input, lui, est forcé en `direction: ltr` par maforgex-pos-rtl.css (un
   e-mail ou un mot de passe est du contenu latin, il se lit de gauche à
   droite) -> son `padding-inline-end` ci-dessus retombe sur la DROITE.
   La réserve se créait donc à l'opposé de l'icône : 46px de vide à droite, et
   la saisie qui passait sous l'oeil à gauche. Les propriétés logiques n'ont
   pas de repère commun ici, seul le physique en a un. */
[dir="rtl"] .authentication-form .form-group:has(.toggle-password) .form-control {
    padding-left: 46px;
    padding-right: 20px;
}
.show-hide svg path { stroke: currentColor !important; }

/* ---- OTP boxes (7.4) ---- */

.otp-container {
    display: flex;
    gap: 10px;
    justify-content: center;
}
.otp-container input[type="text"] {
    width: 52px;
    height: 56px;
    text-align: center;
    font-size: var(--q-fs-h3);
    font-weight: var(--q-fw-bold);
    color: var(--q-text);
    background: var(--q-surface-2);
    border: 1px solid transparent;
    border-radius: var(--q-r-tile);
    outline: 0;
    transition: box-shadow .16s ease;
}
.otp-container input[type="text"]:focus {
    box-shadow: var(--q-ring);
    border-color: transparent;
}

/* ---- remember / links ---- */

/* style.min.css pose la case en physique — `padding-left:1.875rem` sur le
   libellé et `left:0` sur les deux pseudo-éléments qui dessinent la boîte et
   la coche. En arabe la case restait donc à GAUCHE du texte, du mauvais côté
   du sens de lecture. Les propriétés logiques la font passer au début de la
   ligne dans les deux sens.

   Le `padding-left:0` / `left:auto` préalable est nécessaire : sans lui la
   valeur physique de la vendor survivrait en RTL et l'élément se retrouverait
   calé des deux bords à la fois. Déclarée après, la propriété logique gagne en
   LTR et bascule côté droit en RTL. */
.customcheck-label {
    color: var(--q-text-soft) !important;
    /* style.min.css impose « Titillium Web » sur ce libellé ; la déclaration
       portée par l'élément l'emporte sur le `font-family` hérité du body. La
       fonte ne couvre pas l'arabe, « تذكّرني » basculait donc sur une fonte
       système étrangère au reste de la page. */
    font-family: var(--q-font);
    font-size: .89rem;
    cursor: pointer;
    padding-left: 0;
    padding-inline-start: 1.875rem;
}
.customcheck-label::before,
.customcheck-label::after {
    left: auto;
    inset-inline-start: 0;
}
/* La coche est un chevron en bordure, symétrique dans sa boîte de 1.25rem :
   0.4375rem depuis le début la centre à l'identique des deux côtés. Elle n'est
   pas mise en miroir — une coche de validation ne s'inverse pas en RTL. */
.customcheck-label::after { inset-inline-start: .4375rem; }
.forget, .authentication-form-footer a {
    color: var(--q-primary-ink) !important;
    font-weight: var(--q-fw-medium);
    font-size: var(--q-fs-body);
    text-decoration: none;
}
.forget:hover, .authentication-form-footer a:hover { color: var(--q-primary-ink) !important; text-decoration: underline; }

.authentication-form-footer {
    text-align: center;
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--q-border);
}
.authentication-form-footer p { color: var(--q-text-soft) !important; margin-bottom: 0; font-size: .91rem; }

/* ---- buttons ---- */

.create-account-btn {
    background: var(--q-primary) !important;
    border: 0 !important;
    border-radius: var(--q-r-pill) !important;
    color: var(--q-text-invert) !important;
    font-weight: var(--q-fw-medium);
    min-height: 48px;
    padding: 0 24px;
    font-size: var(--q-fs-body);
    width: 100%;
    box-shadow: none;
    transition: background .16s ease, box-shadow .16s ease;
}
.create-account-btn:hover { background: var(--q-primary-2) !important; }
.create-account-btn:focus { outline: none; box-shadow: var(--q-ring) !important; }

.google-btn {
    background: var(--q-surface-2) !important;
    border: 1px solid var(--q-border) !important;
    border-radius: var(--q-r-pill) !important;
    color: var(--q-text) !important;
    font-weight: var(--q-fw-medium);
    min-height: 48px;
    padding: 0 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    text-decoration: none;
}
.google-btn:hover { border-color: var(--q-primary) !important; }

/* ---- helper paragraphs inside the form ("Back to log in", resend link) ----
   This also styled the demo-credentials block that sat under the Sign In button;
   that block was removed 2026-08-13 — it published live admin credentials. */

.authentication-form-content .form-group p {
    color: var(--q-text-soft);
    font-size: .85rem;
    margin-bottom: .15rem;
}
.authentication-form-content p b { color: var(--q-text-soft); }

/* ---- validation ---- */

.invalid-feedback { color: var(--q-danger) !important; font-size: .81rem; }
.was-validated .form-control:invalid, .form-control.is-invalid { border-color: var(--q-danger) !important; }
.was-validated .form-control:valid, .form-control.is-valid { border-color: var(--q-success) !important; }

/* ---- alerts from <x-simple-alert /> ---- */

.alert { border: 0; border-radius: var(--q-r-pill); font-weight: 500; }
.alert-success { background: var(--q-success-soft) !important; color: var(--q-success) !important; }
.alert-danger { background: var(--q-danger-soft) !important; color: var(--q-danger) !important; }

@media (prefers-reduced-motion: reduce) {
    * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}


/* ---- sélecteur de langue (contrôle segmenté) ---------------------------

   Un <select> natif ouvrait une liste dessinée par l'OS, hors d'atteinte du
   CSS. Avec deux langues, on les affiche toutes : plus de panneau à ouvrir,
   donc plus rien qui échappe au système de design.

   Ancré sur .authentications (et non dans un des panneaux) pour survivre au
   display:none de l'illustration sous 992px.

   `inset-inline-end` suit le côté de l'illustration dans les deux sens de
   lecture : en LTR l'image est à droite (order:2), en RTL le flux s'inverse
   et elle passe à gauche — la puce l'accompagne sans règle [dir] dédiée.

   Contrastes vérifiés (clair / sombre) :
     actif   blanc sur --q-primary ............ 5.99:1  (min 4.5)
     inactif --q-text-soft sur la puce ........ 5.48:1 / 8.76:1
     survol  --q-text-soft sur --q-surface-2 .. 4.73:1 / 6.40:1
     pastille active vs fond de puce .......... 5.99:1 / 3.05:1  (min 3.0)

   Le dernier point impose le fond sombre de la puce : sur --q-surface
   (#122232) le remplissage --q-primary ne rend que 2.70:1, et l'on ne
   distinguerait plus la langue sélectionnée. --q-bg (#0A1622) rétablit 3.05:1.
   ---------------------------------------------------------------------- */

.authentications {
    /* référentiel du positionnement absolu ci-dessous */
    position: relative !important;
}

.q-auth-lang {
    position: absolute;
    top: 20px;
    inset-inline-end: 20px;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 5px 9px 5px 12px;
    border: 1px solid var(--q-border);
    border-radius: var(--q-r-pill);
    /* fond opaque : la lisibilité ne dépend pas de la photo derrière */
    background: var(--q-surface);
    box-shadow: var(--q-shadow);
}

[dir="rtl"] .q-auth-lang { padding: 5px 12px 5px 9px; }

[data-theme="dark"] .q-auth-lang {
    background: var(--q-bg);
}

.q-auth-lang-icon {
    flex: 0 0 auto;
    color: var(--q-primary-ink);
}

.q-auth-lang-group {
    display: inline-flex;
    align-items: center;
    gap: 2px;
}

.q-auth-lang-item {
    display: inline-block;
    padding: 5px 11px;
    border-radius: var(--q-r-pill);
    font-family: var(--q-font);
    font-size: var(--q-fs-body-sm);
    font-weight: var(--q-fw-medium);
    line-height: 1.2;
    letter-spacing: .04em;
    color: var(--q-text-soft);
    text-decoration: none !important;
    transition: background .16s ease, color .16s ease;
}

a.q-auth-lang-item:hover,
a.q-auth-lang-item:focus {
    background: var(--q-surface-2);
    color: var(--q-text-soft);
}

.q-auth-lang-item:focus-visible {
    outline: none;
    box-shadow: var(--q-ring);
}

.q-auth-lang-item.is-active {
    background: var(--q-primary);
    /* --q-primary est identique dans les deux thèmes : l'étiquette reste blanche */
    color: var(--q-text-invert);
    font-weight: var(--q-fw-bold);
    cursor: default;
}

/* libellé complet réservé aux lecteurs d'écran : « FR » seul est ambigu à l'oral */
.q-auth-lang-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

@media (max-width: 575.98px) {
    .q-auth-lang {
        top: 12px;
        inset-inline-end: 12px;
        gap: 7px;
        padding: 4px 7px 4px 10px;
    }
    [dir="rtl"] .q-auth-lang { padding: 4px 10px 4px 7px; }
    .q-auth-lang-item { padding: 4px 9px; }
}


/* ===========================================================================
   RESPONSIVE — écrans d'authentification

   Placé en FIN de fichier volontairement. Une media query ne change pas la
   spécificité : à spécificité égale, une règle de base déclarée plus bas
   l'emporte. La section vivait au milieu du fichier, et toute valeur mobile
   posée sur un champ y aurait été écrasée sans bruit par les règles de la
   section « fields » qui la suivaient.

   Quatre paliers, calés sur ceux du Bootstrap 5.3 déjà chargé :

     >= 1200px    bureau             panneau 46 % + illustration 54 %
     992-1199px   tablette paysage   illustration retirée, formulaire pleine largeur
     576-991px    tablette portrait  idem, gouttières réduites
     < 576px      mobile             idem, gouttières minimales

   L'illustration tombe désormais à 1200px et non à 992px : une tablette en
   paysage fait 1024 à 1180px de large, elle passait donc du côté « bureau » et
   se retrouvait avec une colonne de formulaire d'environ 470px pendant que la
   photo mangeait plus de la moitié de la dalle. Au-delà de 1200px on est sur un
   portable, la photo reprend sa place.

   Rien ici n'est directionnel — uniquement des largeurs et des paddings
   symétriques. Les quatre paliers se comportent à l'identique en français et en
   arabe ; seul le sélecteur de langue a sa variante RTL, déjà déclarée plus
   haut avec le composant.
   =========================================================================== */

/* ---- tablette (paysage ET portrait) + mobile : plus d'illustration -------- */

@media (max-width: 1199.98px) {
    .authentications .left-content,
    .left-content { display: none !important; }

    .authentications .right-content {
        flex: 1 1 100% !important;
        max-width: 100% !important;
        width: 100% !important;
        /* Réserve en haut plus large qu'en bas : le sélecteur de langue est en
           position absolue et ne pousse donc rien devant lui. Sans elle, le
           logo du formulaire passait dessous dès que le contenu approchait la
           hauteur de la fenêtre. Le décentrage vertical qui en résulte est de
           8px, invisible à l'oeil. */
        padding: 72px 32px 56px !important;
    }

    .authentication-form { max-width: 420px; }

    /* iOS Safari zoome la page à la mise au point dès qu'un champ descend sous
       16px, et ne dézoome jamais ensuite : le sélecteur de langue et le bouton
       de connexion sortaient de l'écran. --q-fs-body vaut 14px, d'où ce 16px
       forcé sur les seuls champs de saisie.

       Posé sur CE palier et non sur celui du portrait : la borne tactile est la
       même que celle de l'illustration. Un iPad en paysage fait 1024 à 1180px,
       il serait resté à 14px et aurait zoomé alors que c'est justement la
       posture la plus courante pour une caisse. */
    .authentication-form .form-control { font-size: 16px; }
}

/* ---- tablette portrait et en dessous ------------------------------------- */

@media (max-width: 991.98px) {
    .authentications .right-content { padding: 72px 24px 48px !important; }
}

/* ---- mobile -------------------------------------------------------------- */

@media (max-width: 575.98px) {
    .authentications .right-content { padding: 64px 20px 40px !important; }
    .form-title { font-size: var(--q-fs-h2); }
    .authentication-form-header .logo { margin-bottom: 1.15rem; }
}

/* ---- fenêtre courte (téléphone tenu en paysage) --------------------------
   Le conteneur est en `min-height` et non `height` : il grandit, la page
   défile, le formulaire n'est jamais rogné — rien à réparer de ce côté. On
   récupère seulement la hauteur perdue en marges pour éviter un défilement
   qui n'a pas lieu d'être. */

@media (max-height: 560px) and (orientation: landscape) {
    .authentications .right-content {
        padding-top: 60px !important;
        padding-bottom: 28px !important;
    }
}
