/* Les primitives du verre (jetons, decor, images-cles) sont PARTAGEES avec la console :
   voir verre.css. L'@import doit rester la PREMIERE regle du fichier — place apres une
   autre regle, il est ignore en silence par le navigateur. */
@import url("/css/verre.css");

/* Les quatre variables --bg / --brand / --brand-ink / --accent sont REDEFINIES en attribut
   `style` sur <html> par l'apparence du domaine (BrandingTheme.getCssVariables). Les valeurs
   ci-dessous sont donc le defaut tashilat, et il n'existe aucune feuille de style par domaine :
   un domaine de plus ne coute pas un fichier de plus. */
:root {
    --bg: #f4f5f7;
    --card: #ffffff;
    --ink: #1c2733;
    /* FONCE LE 21/10/2026 (#5b6b7a avant). Ce gris portait tout le texte secondaire —
       sous-titres, indications, etiquettes de definition — et il etait calcule pour du
       blanc opaque. Sur le verre pose au-dessus d'une couleur de domaine il tombait a
       1,9:1. A #3e4b57 le pire cas mesure est 4,9:1. Voir verre.css. */
    --muted: #3e4b57;
    --brand: #0b6b5b;
    --brand-ink: #ffffff;
    --accent: #19a08a;
    --border: #d9dee3;
    --danger: #b3261e;
    --ok: #1b5e20;

    /* La description du domaine (18/10/2026) : son poids, sa taille et sa couleur sont
       REGLABLES ICI, en un seul endroit, parce que c'est le seul texte de la page dont le
       contenu vient de la base — sa longueur et son ton changent d'un domaine a l'autre, et
       c'est donc lui qu'on retouche. Le defaut la met en gras : en gris discret, sur le
       verre, elle se lisait mal. Une apparence de domaine ne peut PAS encore les redefinir
       (getCssVariables n'emet que les 4 couleurs) : ce serait une colonne de plus. */
    --desc-poids: 600;
    --desc-taille: 15px;
    --desc-couleur: var(--ink);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    /* La pile d'interface du systeme (voir verre.css) : Segoe UI Variable sur Windows 11,
       SF Pro sur Apple, Roboto sur Android — et Noto Sans Arabic pour l'arabe. Le repli
       couvre le cas ou `verre.css` ne se chargerait pas. */
    font-family: var(--police-ui, system-ui, "Segoe UI", Roboto, Arial, sans-serif);
    background: var(--bg);
    color: var(--ink);
    /* 1,55 : l'interligne fait autant pour la lisibilite d'un paragraphe que sa taille. */
    line-height: 1.55;
    overflow-x: hidden;
}

img, svg { max-width: 100%; height: auto; }

.shell {
    max-width: 440px;
    /* 6vh EN HAUT ET EN BAS faisaient 12 % de la hauteur de la fenetre perdus avant le
       premier pixel de contenu : c'est la premiere cause du defilement vertical de la page
       de connexion sur un portable. La borne haute garde l'air sur un grand ecran, la borne
       basse rend la page compacte sur un petit. */
    margin: clamp(16px, 4vh, 44px) auto;
    padding: 0 16px;
}

@media (max-width: 480px) {
    .shell { margin: 3vh auto; }
}

.brand {
    text-align: center;
    margin-bottom: 20px;
}

/* Logo du domaine (ou tashilat par defaut). `height` seul + `width:auto` : l'image garde ses
   proportions quelle que soit la taille de fichier deposee. max-width evite tout debordement
   sur telephone. */
.brand-logo {
    height: 52px;
    width: auto;
    max-width: 100%;
    display: block;
}

/* Nom et description du domaine, sous le logo. Ils viennent de l'apparence resolue, donc
   deja dans la bonne langue ; `balance` evite une derniere ligne d'un seul mot. */
.brand-name {
    font-size: 15px;
    font-weight: 700;
    margin-top: 10px;
    color: var(--ink);
}

.brand-desc {
    font-size: var(--desc-taille);
    font-weight: var(--desc-poids);
    color: var(--desc-couleur);
    margin: 4px auto 0;
    max-width: 34ch;
    text-wrap: balance;
}

.card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: clamp(20px, 6vw, 28px);
}

h1 { font-size: 19px; margin: 0 0 4px; }
.lead { color: var(--muted); font-size: 15px; margin: 0 0 20px; }

label { display: block; font-size: 13.5px; font-weight: 600; margin: 14px 0 4px; }
.hint { font-weight: 400; color: var(--muted); }

input[type=text], input[type=password], input[type=email], input[type=tel], input[type=number], select {
    width: 100%;
    padding: 11px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 16px; /* >=16px : évite le zoom automatique sur iOS */
    background: #fff;
    color: var(--ink);
}

input:focus { outline: 2px solid var(--brand); outline-offset: 1px; }

button {
    margin-top: 20px;
    width: 100%;
    padding: 11px 14px;
    border: 0;
    border-radius: 8px;
    background: var(--brand);
    color: var(--brand-ink);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
}

button:hover { filter: brightness(1.06); }

.alert {
    border-radius: 8px;
    padding: 10px 12px;
    font-size: 14px;
    margin-bottom: 16px;
}
.alert-error { background: #fde9e8; color: var(--danger); border: 1px solid #f4c7c3; }
.alert-ok { background: #e7f4e8; color: var(--ok); border: 1px solid #c3e0c5; }

.links { margin-top: 18px; font-size: 14px; text-align: center; }
.links a { color: var(--brand); text-decoration: none; }
.links a:hover { text-decoration: underline; }

/* Selecteur de langue FR/AR, en haut de chaque page publique. */
.lang-switch { display: flex; justify-content: center; gap: 6px; margin-bottom: 16px; }
.lang-switch a {
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    text-decoration: none;
    border: 1px solid var(--border);
}
.lang-switch a.on { color: var(--brand-ink); background: var(--brand); border-color: var(--brand); }

.meta { font-size: 13.5px; color: var(--muted); }
dl { display: grid; grid-template-columns: 40% 60%; gap: 6px 12px; font-size: 15px; }
dt { color: var(--muted); }
dd { margin: 0; overflow-wrap: break-word; min-width: 0; }

@media (max-width: 420px) {
    dl { grid-template-columns: 1fr; gap: 2px; }
    dl dt { margin-top: 8px; font-size: 13px; }
}

/* =====================================================================
   LES PAGES PUBLIQUES — « liquid glass »
   =====================================================================
   `auth-page` est porte par les DIX pages publiques d'identity (connexion, inscription,
   les quatre ecrans de MFA, les deux de mot de passe, le compte, l'accueil et l'erreur) —
   pas seulement par la connexion, malgre son nom, garde parce qu'il etait deja dans vingt
   selecteurs. La console d'administration a sa propre feuille (`admin.css`), qui importe
   les memes primitives.

   Les JETONS, le DECOR et les IMAGES-CLES vivent dans `verre.css`, importe ci-dessus :
   les deux familles de pages partagent le meme verre, et le recopier aurait garanti
   qu'elles divergent. Ce qui reste ici est l'APPLICATION de ce verre aux objets propres
   aux pages publiques.

   Aucune ligne de script : la CSP de ces pages est `script-src 'self'`, et surtout un
   formulaire de connexion doit fonctionner a l'identique quand JavaScript est
   indisponible. Toutes les animations sont donc en CSS.                                 */

.auth-page {
    position: relative;
    /* `100dvh` APRES `100vh`, ET C'EST UNE CAUSE REELLE DE DEFILEMENT. Sur iOS Safari et
       dans les navigateurs integres, `100vh` compte la hauteur AVEC la barre d'outils
       rabattue : la page mesure donc toujours un peu plus que ce qu'on voit, et elle
       defile de quelques dizaines de pixels sans qu'aucun contenu le justifie. `dvh` suit
       la hauteur reellement visible. Les navigateurs qui l'ignorent gardent `100vh`. */
    min-height: 100vh;
    min-height: 100dvh;

    /* Champs et liseres : la maquette les tire de son theme ; ici ils derivent de l'encre
       pour rester lisibles quelle que soit la couleur du domaine.

       `--champ` est monte de .62 a .74 : il ne sert pas que de fond de champ, il est aussi
       la gouttiere du selecteur de langue, qui est passe SOUS la carte le 18/10 et n'a donc
       plus le verre entre lui et le fond du domaine. A .62 le texte inactif y etait a
       4,3:1 ; a .74 il est a 5,4:1 au pire. */
    --champ: rgba(255, 255, 255, .86);
    --liseres: color-mix(in srgb, var(--ink) 24%, transparent);
    --accent-halo: color-mix(in srgb, var(--accent) 28%, transparent);
}

/* Le contenu passe devant le decor.

   FLEX + `order` POUR DESCENDRE LA LANGUE (18/10/2026), et non un deplacement de balise :
   les dix pages publiques portent `.lang-switch` avant `.card`, et les reecrire une par une
   aurait garanti qu'on en oublie. L'ordre VISUEL change, l'ordre du DOCUMENT ne bouge pas —
   ce qui est d'ailleurs preferable ici : au clavier, on atteint le formulaire avant le
   selecteur de langue, ce qui est le bon ordre pour qui vient se connecter. */
.auth-page .shell {
    position: relative;
    z-index: 1;
    max-width: 452px;
    display: flex;
    flex-direction: column;
}

.auth-page .card        { order: 1; }
.auth-page .lang-switch { order: 2; }

/* ---------------------------------------------------------------------
   LE VERRE
   ---------------------------------------------------------------------
   Trois couches superposees, exactement comme dans la maquette, et chacune porte son
   role :
     - le fond : un degrade blanc de 135deg sur une teinte, plus `backdrop-filter`
       (flou + saturation + luminosite) qui est ce qui fait le « verre » ;
     - `::before` : le LISERE, un degrade de 1.2px decoupe au masque
       (`mask-composite: exclude`) — un `border` uni ne peut pas etre degrade ;
     - `::after` : les CAUSTIQUES, deux halos radiaux (un en haut a gauche, un en bas a
       droite) qui imitent la lumiere traversant une matiere epaisse.
   `isolation: isolate` est necessaire : les pseudo-elements sont en `z-index: -1` et
   sortiraient derriere la carte sans contexte d'empilement propre.                    */

.auth-page .card {
    position: relative;
    isolation: isolate;
    border: 0;
    border-radius: var(--r-carte);
    padding: clamp(22px, 6vw, 32px);
    background:
        linear-gradient(135deg,
            rgba(255, 255, 255, var(--verre-haut)),
            rgba(255, 255, 255, var(--verre-bas)) 60%),
        var(--verre-teinte);
    -webkit-backdrop-filter: blur(var(--verre-flou)) saturate(var(--verre-sat)) brightness(var(--verre-lum));
    backdrop-filter: blur(var(--verre-flou)) saturate(var(--verre-sat)) brightness(var(--verre-lum));
    box-shadow:
        inset 0 1px 1px rgba(255, 255, 255, var(--verre-rim)),
        inset 0 -1px 1px rgba(255, 255, 255, var(--verre-rim2)),
        inset 0 0 0 1px rgba(255, 255, 255, var(--verre-rim3)),
        inset 0 -20px 40px -20px rgba(255, 255, 255, var(--verre-glow)),
        inset 0 0 28px rgba(255, 255, 255, .06),
        0 0 0 .5px var(--verre-arete),
        0 24px 60px var(--verre-ombre);
}

.auth-page .card::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1.2px;
    pointer-events: none;
    z-index: -1;
    background: linear-gradient(140deg,
        rgba(255, 255, 255, .9),
        rgba(255, 255, 255, .12) 30%,
        rgba(255, 255, 255, 0) 55%,
        rgba(255, 255, 255, .5));
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
}

.auth-page .card::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: -1;
    /* Les deux halos sont desormais a peine visibles (.24 -> .10). Poses A L'INTERIEUR de la
       carte, ils dessinaient des degrades de luminosite en travers des paragraphes : c'est
       joli sur une maquette sans texte, et c'est ce qui fatigue l'oeil sur un formulaire. */
    background:
        radial-gradient(120% 60% at 10% 0%, rgba(255, 255, 255, .10), rgba(255, 255, 255, 0) 50%),
        radial-gradient(70% 45% at 92% 100%, rgba(255, 255, 255, var(--verre-caustic)), rgba(255, 255, 255, 0) 60%);
}

/* REPLI SANS `backdrop-filter` : la carte doit rester LISIBLE, pas jolie. Un verre sans
   flou laisse voir les orbes a travers le texte. On passe donc a un blanc franc. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .auth-page .card { background: rgba(255, 255, 255, .94); }
}

/* ---------------------------------------------------------------------
   LA PLAQUE DU LOGO  (`.logo-plate` de la maquette)
   ---------------------------------------------------------------------
   Plaque blanche legerement bombee, avec une lueur teintee par l'accent dessous. Le logo
   d'un domaine est une image quelconque : la plaque lui donne un cadre constant, quelle
   que soit sa forme ou son fond.                                                       */

.brand-mark {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 14px;
    border-radius: var(--r-plaque);
    background: linear-gradient(180deg, rgba(255, 255, 255, .96), rgba(232, 238, 250, .9));
    box-shadow:
        inset 0 1px 0 #fff,
        0 0 0 1px rgba(11, 16, 38, .06),
        0 10px 26px var(--accent-halo);
    animation: respiration 6s ease-in-out infinite;
}

/* LA MARQUE EST DANS LA CARTE depuis le 18/10/2026, et cela a deux consequences.

   LE HALO DE TEXTE A ETE RETIRE. Il existait pour detacher le nom et la description d'un
   fond imprevisible — `--bg` est choisi par le domaine, et on ne peut rien supposer d'un
   bleu moyen comme #73A7CB. Sur le verre, le fond est connu et clair : le halo n'avait plus
   rien a detacher et ne faisait que troubler les lettres. Le garder « au cas ou » aurait
   ete du decor sans cause.

   LE LOGO PEUT ETRE PLUS GRAND, pour la meme raison : pose sur un fond constant, il porte
   la page sans risquer de se perdre dans une couleur quelconque. */
.brand {
    margin-bottom: 18px;
}

/* Un filet sous la marque : il separe l'identite du domaine du formulaire, sans ajouter de
   titre ni d'espace mort. */
.auth-page .brand::after {
    content: "";
    display: block;
    width: 56px;
    height: 2px;
    margin: 14px auto 0;
    border-radius: 2px;
    background: linear-gradient(90deg, transparent, var(--liseres), transparent);
}

.auth-page .brand-logo {
    height: 76px;               /* 52px avant le passage dans la carte */
}

.brand-name {
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -.02em;     /* le serrage des titres de la maquette */
    margin-top: 12px;
}

/* En gras, elle a besoin d'air : sans interligne ni marge, deux lignes serrees et grasses
   se lisent moins bien qu'une ligne grise. Le poids vient de --desc-poids (voir :root). */
.brand-desc { max-width: 36ch; line-height: 1.55; margin-top: 8px; }

/* ---------------------------------------------------------------------
   TITRES, CHAMPS, BOUTON
   --------------------------------------------------------------------- */

/* 24px et non 22 : c'est le titre qui dit OU l'on est, et sur un ecran de connexion ouvert
   depuis un lien, c'est la premiere chose qu'on cherche. */
.auth-page h1 {
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -.02em;
    margin: 0 0 6px;
}

.auth-page .lead { font-size: 16px; margin: 0 0 18px; }

.auth-page label {
    font-size: 14px;
    font-weight: 600;
    letter-spacing: .01em;
    margin: 14px 0 6px;
}

/* Champs : 50px de haut et 16px de rayon, comme `.lg-input`. L'ombre interieure remplace
   la bordure — c'est ce qui donne l'impression d'un creux dans la matiere. */
.auth-page input[type=text],
.auth-page input[type=password],
.auth-page input[type=email],
.auth-page input[type=tel],
.auth-page input[type=number],
.auth-page select,
.auth-page textarea {
    min-height: 52px;
    padding: 0 16px;
    border: 0;
    border-radius: var(--r-champ);
    background: var(--champ);
    box-shadow:
        inset 0 1px 2px rgba(0, 0, 0, .12),
        inset 0 0 0 1px var(--liseres);
    transition: box-shadow .25s ease, background .25s ease;
}

/* Un `textarea` ne peut pas etre centre verticalement par `min-height` seul : il garde
   son interligne, donc il lui faut un vrai rembourrage haut et bas. */
.auth-page textarea {
    padding: 14px 16px;
    min-height: 110px;
    resize: vertical;
}

/* Le champ en cours de saisie : fond franc, liseré d'accent, et un halo autour. Trois
   signaux plutot qu'un, parce que c'est le seul endroit de la page ou l'on doit savoir sans
   hesiter ou va ce qu'on tape. */
.auth-page input:focus,
.auth-page select:focus,
.auth-page textarea:focus {
    outline: 0;                 /* remplace par l'anneau ci-dessous, plus lisible ici */
    background: #fff;
    box-shadow:
        inset 0 1px 2px rgba(0, 0, 0, .08),
        inset 0 0 0 2px var(--accent),
        0 0 0 4px var(--accent-halo);
}

/* Le survol d'un champ, avant meme le clic : une interface d'aujourd'hui repond au
   passage de la souris, et cela indique aussi ce qui est cliquable. */
.auth-page input:hover:not(:focus),
.auth-page select:hover:not(:focus),
.auth-page textarea:hover:not(:focus) {
    background: #fff;
}

/* Bouton : pastille, degrade vertical, et le rebond de la maquette. `scale(.94, .9)` a
   l'enfoncement : la deformation inegale est ce qui fait « mou » plutot que « clique ». */
.auth-page button[type=submit] {
    margin-top: 20px;
    min-height: 50px;
    padding: 0 22px;
    border: 0;
    border-radius: var(--r-pastille);
    /* 19px/700 ET CE N'EST PAS UNE QUESTION DE GOUT : c'est le seuil « grand texte » de
       WCAG (18,67px en gras), dont le contraste exige 3,0 au lieu de 4,5. Mesure sur six
       paires accent/marque qu'un domaine peut poser, encre deduite comprise : a 15px aucun
       melange de degrade ne tient le seuil 4,5 partout (3,1 a 3,5 sur un or ou un bleu
       clair) ; a 19px gras, les six passent, la pire a 3,25. Agrandir l'etiquette est le
       SEUL levier qui ne depende pas de couleurs qu'on ne choisit pas. */
    font-size: 19px;
    font-weight: 700;
    letter-spacing: -.01em;

    /* LE BOUTON EST LE SEUL ENDROIT OU LA COULEUR DU DOMAINE DOIT RESTER (c'est l'action
       principale, elle lui appartient), DONC C'EST SON ENCRE QU'IL FAUT RENDRE SURE.
       Mesure : du blanc — ce que les apparences posent presque toujours en `--brand-ink` —
       donne 2,4:1 sur un or, 2,6:1 sur un bleu clair, 3,3:1 sur notre vert clair. C'est le
       domaine qui choisit la paire fond/encre, et il se trompe sans le savoir.

       L'encre du domaine reste ici ; c'est le bloc @supports ci-dessous qui la remplace,
       quand le navigateur sait deduire une couleur d'une autre.

       Le degrade ne part plus d'un accent ECLAIRCI AU BLANC mais d'un accent tire vers la
       couleur de marque : son haut et son bas ont desormais des clartes proches, donc
       l'encre deduite du bas vaut aussi pour le haut. */
    color: var(--brand-ink);
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--accent) 45%, var(--brand)),
        var(--brand));
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .55),
        inset 0 -3px 8px rgba(0, 0, 0, .18),
        0 10px 30px var(--accent-halo);
    transition: transform .35s var(--rebond), box-shadow .3s ease, filter .3s ease;
}

/* L'ENCRE DU BOUTON, DEDUITE DE LA CLARTE DE LA COULEUR DU DOMAINE : blanc sous 0,68 de
   clarte, noir au-dessus. C'est le domaine qui choisit la paire fond/encre et il se trompe
   sans le savoir — du blanc sur un or ne donne que 2,4:1.

   ET CE BLOC @supports N'EST PAS UNE PRECAUTION DE STYLE, IL EVITE UNE REGRESSION. Ecrite
   en seconde declaration dans la regle, `color: oklch(from var(--brand) ...)` contient un
   `var()` : elle est donc ACCEPTEE a l'analyse et ne peut echouer qu'au calcul. Or une
   propriete « invalide a la valeur calculee » ne retombe PAS sur la declaration precedente
   — elle vaut `inherit`. Le bouton aurait donc herite de l'encre de la carte, sombre, sur
   un fond sombre, et precisement sur les navigateurs qui connaissent `oklch()` mais pas
   encore la couleur relative : Chrome 111-118, Safari 15.4-16.3, Firefox 113-127. La
   condition est ecrite avec une couleur LITTERALE, sans `var()`, donc elle est tranchee a
   l'analyse et ces navigateurs n'entrent jamais dans le bloc. Le repli de `var()` couvre
   le dernier cas, celui d'une marque non definie. */
@supports (color: oklch(from white l 0 0)) {
    .auth-page button[type=submit] {
        color: oklch(from var(--brand, #0b6b5b) clamp(0, (.68 - l) * 100, 1) 0 0);
    }
}

.auth-page button[type=submit]:hover {
    transform: translateY(-2px) scale(1.03);
    filter: brightness(1.04);
}

.auth-page button[type=submit]:active {
    transform: scale(.94, .9);
    transition-duration: .12s;
}

.auth-page button[type=submit]:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
}

/* ---------------------------------------------------------------------
   SELECTEUR DE LANGUE, ALERTES, LIENS
   --------------------------------------------------------------------- */

/* Reprend `.seg` de la maquette : une gouttiere en creux, la langue active en pastille
   blanche posee dessus. */
/* Marge EN HAUT et non en bas : le selecteur est descendu sous la carte (`order: 2`). */
.auth-page .lang-switch {
    gap: 4px;
    padding: 4px;
    width: max-content;
    margin: 16px auto 0;
    border-radius: var(--r-pastille);
    background: var(--champ);
    box-shadow:
        inset 0 1px 3px rgba(0, 0, 0, .14),
        inset 0 0 0 1px var(--liseres);
}

/* PAS D'`opacity` SUR DU TEXTE (21/10/2026). Elle melangeait l'encre a son fond — c'est
   exactement ce qui delave : a .72 le texte inactif tombait a 4,3:1. Une couleur franche
   dit la meme chose (« ce n'est pas la langue active ») sans rien effacer, et c'est de
   toute facon la pastille blanche qui signale l'active, pas la paleur des autres. */
.auth-page .lang-switch a {
    border: 0;
    padding: 8px 17px;
    font-size: 14px;
    border-radius: var(--r-pastille);
    color: var(--muted);
    transition: all .35s var(--rebond);
}

.auth-page .lang-switch a:hover { color: var(--ink); }

.auth-page .lang-switch a.on {
    color: var(--ink);
    background: linear-gradient(180deg, #fff, #eef2ff);
    box-shadow:
        inset 0 1px 0 #fff,
        0 0 0 1px rgba(11, 16, 38, .06),
        0 4px 12px rgba(0, 0, 0, .12);
}

/* Alertes : memes rayons et meme liseré interieur que les champs, pour qu'elles
   appartiennent visiblement a la meme matiere.

   LE FILET DE COULEUR SUR LE BORD DE DEBUT (21/10/2026) : une alerte se repere a sa barre
   avant qu'on en lise un mot. `border-inline-start` et non `border-left` — en arabe la
   barre doit passer a droite, et un `border-left` en dur l'aurait laissee du mauvais cote
   sur la moitie des pages. */
.auth-page .alert {
    border: 0;
    border-inline-start: 4px solid currentColor;
    border-radius: var(--r-champ);
    padding: var(--esp-3) var(--esp-4);
    box-shadow: inset 0 0 0 1px var(--liseres);
}

/* Fonds OPAQUES, contrairement au reste de la page : une alerte dit pourquoi la connexion
   a echoue, c'est le texte le plus important de l'ecran. Avec un blanc translucide, son
   contraste dependait de ce qui passait dessous — donc de la couleur du domaine et de la
   position d'un orbe. Sur blanc franc il est de 5,4:1, toujours. */
.auth-page .alert-error {
    background: color-mix(in srgb, var(--danger) 12%, #fff);
    color: var(--danger);
}

.auth-page .alert-ok {
    background: color-mix(in srgb, var(--ok) 12%, #fff);
    color: var(--ok);
}

.auth-page .links { margin-top: 16px; font-size: 15px; }

/* UNE COULEUR DE LOGO N'EST PAS UNE COULEUR DE TEXTE (21/10/2026).
   Ces deux liens — « mot de passe oublie », « creer un compte » — portaient `--brand`, que
   le DOMAINE choisit pour son identite. Mesure sur des couleurs reelles, posees sur le bas
   d'une carte : 2,0:1 pour le bleu de Centre Admis, 1,9:1 pour un or, 2,5:1 pour notre
   propre vert clair. Et foncer la couleur ne sauve rien (3,4:1 au mieux a 72 %, mesure) :
   il faut cesser de teinter le TEXTE avec elle. L'encre porte donc le lien, et c'est son
   SOULIGNEMENT qui porte la couleur du domaine — un trait n'a pas a etre lisible, il a a
   etre vu. Souligner est de toute facon preferable : un lien reconnaissable a sa seule
   couleur n'existe pas pour qui ne distingue pas cette couleur. */
.auth-page .links a {
    padding: 8px 14px;
    border-radius: var(--r-pastille);
    color: var(--ink);
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, var(--brand) 70%, transparent);
    text-decoration-thickness: 2px;
    text-underline-offset: 3px;
    transition: background .25s ease;
}

/* Le survol ajoute un fond, il n'enleve PAS le souligne : c'est lui qui dit « lien ». */
.auth-page .links a {
    transition: background var(--duree-ui) var(--courbe-ui);
}

.auth-page .links a:hover {
    background: color-mix(in srgb, var(--ink) 9%, transparent);
}

/* ---------------------------------------------------------------------
   LES CODES DE SECOURS DE LA MFA
   ---------------------------------------------------------------------
   Ils se recopient a la main, souvent sur du papier : des chiffres de largeur egale et un
   interlettrage franc evitent de confondre 1 et l, 0 et O. C'est le seul endroit de
   l'application ou une police a chasse fixe est le bon choix.                           */
.auth-page code,
.auth-page .code {
    font-family: ui-monospace, "Cascadia Mono", "SF Mono", Consolas, "Liberation Mono", monospace;
    font-variant-numeric: tabular-nums;
    letter-spacing: .04em;
}

/* ---------------------------------------------------------------------
   ENTREE DE LA PAGE  (images-cles dans verre.css)
   --------------------------------------------------------------------- */

/* Les delais suivent l'ordre VISUEL, pas celui du document : la carte arrive d'abord,
   la langue ensuite — elle est maintenant dessous. Les prendre dans l'ordre du document
   ferait apparaitre le bas de la page avant le haut. */
.auth-page .card        { animation: pose .7s var(--rebond) both; }
.auth-page .brand       { animation: montee .6s ease-out .12s both; }
.auth-page .lang-switch { animation: montee .5s ease-out .22s both; }

@media (prefers-reduced-motion: reduce) {
    .auth-page .lang-switch,
    .auth-page .brand,
    .auth-page .card,
    .brand-mark {
        animation: none;
    }
    .auth-page button[type=submit]:hover { transform: none; }
    .auth-page button[type=submit]:active { transform: none; }
}

/* Telephone : le verre garde ses rayons mais le decor prend moins de place, pour ne pas
   pousser le formulaire sous la ligne de flottaison. */
@media (max-width: 480px) {
    .auth-page .card { border-radius: 24px; }
    .auth-page .brand-logo { height: 58px; }
    .brand-mark { padding: 11px; border-radius: var(--r-carte-petite); }
    .auth-page .brand { margin-bottom: 14px; }
    .auth-page .brand::after { margin-top: 12px; }
    .orbe-4, .orbe-5, .anneau { display: none; }
}

/* =====================================================================
   FENETRE BASSE : LA PAGE DOIT TENIR SANS DEFILEMENT (21/10/2026)
   =====================================================================
   Demande : « diminuer la marge verticale entre les elements afin que la page n'affiche pas
   un scroll vertical ».

   PAR LA HAUTEUR DE LA FENETRE, ET NON EN SERRANT TOUT PARTOUT. Le probleme n'existe que
   quand la fenetre est basse — un portable 1366x768, une fenetre pas en plein ecran, un
   telephone en paysage. Compresser le rythme sur tous les ecrans aurait resserre la page
   justement la ou la place ne manque pas. Deux paliers, et chacun ne retire que ce qui ne
   porte pas de sens : des marges, puis la taille de la plaque du logo, puis le filet
   decoratif sous la marque. AUCUN TEXTE N'EST MASQUE a aucun palier.

   `max-height` et non `max-width` : c'est une question de hauteur disponible. Les deux
   requetes se cumulent avec celle du telephone, qui porte, elle, la largeur.            */
@media (max-height: 820px) {
    .auth-page .shell { margin: clamp(10px, 2vh, 20px) auto; }
    .auth-page .card { padding: clamp(18px, 4vw, 26px); }
    .auth-page .brand-logo { height: 62px; }
    .brand-mark { padding: 11px; }
    .auth-page .brand { margin-bottom: 12px; }
    .auth-page .brand::after { margin-top: 10px; }
    .brand-name { margin-top: 8px; }
    .auth-page h1 { font-size: 22px; }
    .auth-page .lead { margin: 0 0 12px; }
    .auth-page label { margin: 10px 0 5px; }
    .auth-page input[type=text],
    .auth-page input[type=password],
    .auth-page input[type=email],
    .auth-page input[type=tel],
    .auth-page input[type=number],
    .auth-page select { min-height: 48px; }
    .auth-page button[type=submit] { margin-top: 14px; min-height: 48px; }
    .auth-page .links { margin-top: 12px; }
    .auth-page .lang-switch { margin: 12px auto 0; }
}

/* Tres bas : une fenetre de 600px de haut, ou un telephone couche. Le filet sous la marque
   disparait — il separe, il n'informe pas — et la plaque du logo se resserre encore. */
@media (max-height: 680px) {
    .auth-page .brand-logo { height: 52px; }
    .auth-page .brand::after { display: none; }
    .auth-page .brand { margin-bottom: 10px; }
    .auth-page .lead { margin: 0 0 10px; }
    .brand-desc { margin-top: 4px; }
}
