/* =====================================================================
   FLASH SERVICE - systeme de design
   Palette : celle recommandee par la base UI/UX Pro Max pour le domaine
   « Fintech/Crypto » (refonte 27/09) — « Gold trust + purple tech » :
   bleu #0B2E55 (marque), bleu clair #2F5C93 (accents), fond sombre #0F172A,
   texte #F8FAFC. Le violet sert aux ACTIONS (boutons, liens, onglets actifs),
   l'or aux accents et aux mises en avant. Typographie recommandee pour le
   domaine finance : IBM Plex Sans.
   Les nuances sont ajustees pour tenir le contraste 4.5:1 demande par la base :
   bleu 600 #0B2E55 sous du texte blanc ; l'ambre ne sert plus qu'aux etats
   ===================================================================== */
:root {
  /* 10/11/2026 — DESIGN SYSTEM « FLASH PAY » (prompt du client) : le bleu de la
     marque passe au bleu nuit profond #0B2E55 (il etait #0B2E55, presque le meme :
     la nuance est plus froide et plus dense), le fond de page au gris-bleu
     #F2F6FA. Tous les ecrans suivent d'un coup, aucun a repeindre a la main. */
  /* 13/11/2026 — DESIGN SYSTEM « 1xBet » (prompt du client) : le bleu sportif
     #0E3867 remplace l'emeraude. La rampe est froide et franche, du tres clair
     (#EAF3FC, fonds de badge) au tres fonce (#0F3A66, encre sur fond clair). */
  /* 13/11/2026 : le client impose le BLEU NAVY du backoffice (#0E3867) a tout
     l'espace client — la rampe est resserree autour de cette teinte. */
  --brand-50: #E8EEF6;  --brand-100: #CFDDEE; --brand-200: #A6C0DE; --brand-300: #6E93C2;
  --brand-400: #2F5C93; --brand-500: #0E3867; --brand-600: #0B2E55; --brand-700: #0A2A4E;
  --brand-800: #08223F; --brand-900: #061A31;
  /* Le VERT D'ACTION (#68B647) : reserve aux boutons principaux — Deposer,
     Recharger, Valider. Un seul jeton, pour qu'aucun ecran n'invente sa teinte. */
  --cta: #68B647; --cta-hover: #5AA33B; --cta-ink: #FFFFFF;
  /* CHARTE DE L'ACCUEIL (12/11/2026, prompt du client) : BLEU MARINE #0A4232 et
     BLEU ROI #0E3867. Deux jetons seulement, poses ici avec le reste de la
     palette : la carte du portefeuille prend le bleu roi, la pilule active de la
     barre du bas le bleu marine. Les nuances servent au degrade de la carte. */
  --navy: #0A2A4E; --roi: #0E3867; --roi-700: #0A2A4E; --roi-500: #24599C;
  /* PANNEAU « PASSERELLE » ET CARRE DE LA MARQUE (13/11/2026) : ces teintes sont
     FIXES — la carte reste sombre et la tuile « Retrait » reste blanche dans les
     deux themes, comme sur la maquette. Posees ici (avant le bloc « socle ») parce
     que le socle n'accepte que des var(). */
  /* 13/11/2026 : le client veut LE BLEU DU PANNEAU DEPOT/RETRAIT DE FLASH PAY —
     le degrade navy de sa marque (#0A2A4E -> #0E3867 -> #24599C), repris tel quel. */
  --pass-fond: linear-gradient(155deg, #0A2A4E, #0E3867 58%, #24599C 100%);
  --pass-encre: #FFFFFF; --pass-sous: rgba(255, 255, 255, .82);
  --pass-tuile: #FFFFFF; --pass-tuile-encre: #14263C; --pass-tuile-sous: #64748B;
  /* 13/11/2026 : le carre de la marque prend LE MEME BLEU que le panneau
     « Passerelle » (degrade navy de Flash Pay), pour que les deux se repondent. */
  --logo-fond: linear-gradient(155deg, #0A2A4E, #0E3867 58%, #24599C 100%);
  /* ECRAN DEPOT « BENTO FINTECH » (13/11/2026, maquette « Recharger 1xBet ») :
     fond gris perle, cartes blanches, encre anthracite, cobalt d'action. */
  --dp-fond: #F5F6F8; --dp-carte: #FFFFFF; --dp-encre: #18181B; --dp-cobalt: #0E3867;
  --dp-bord: #E4E4E7; --dp-gris: #71717A; --dp-champ: #F5F6F8;
  --dp-cobalt-pale: #E8EEF6;
  /* 13/11/2026 : seul le BOUTON DEPOT garde l'ancien bleu vif ; le reste
     de l'espace client est passe au navy #0E3867. */
  --bleu-depot: #2B82D9;
  --vert-action: #68B647;
  --logo-point: #7FB3E6;

  /* Echelle neutre FROIDE du systeme : le canvas gris-bleu #F0F4F8, les bordures
     #E2E8F0, l'encre bleu marine #14263C (jamais de noir pur), le texte secondaire
     #64748B. */
  --slate-50: #F0F4F8; --slate-100: #F1F5F9; --slate-200: #E2E8F0; --slate-300: #CBD5E1;
  --slate-400: #94A3B8; --slate-500: #64748B; --slate-600: #475569; --slate-700: #334155;
  --slate-800: #1E293B; --slate-900: #14263C; --slate-950: #0F1D2E;

  /* 10/11/2026 — orange de l'OPERATEUR (Flooz / Moov Africa) : la seule teinte
     neuve de l'ecran « Recharger 1xBet », demandee au prompt. Ce n'est pas une
     couleur de la maison : elle vient du logo, elle ne sert donc qu'a la tuile
     ACTIVE du reseau et a son ombre. */
  --flooz-500: #F97316;
  /* 11/11/2026 — l'indigo de la fin du degrade du bouton principal (« Nouvelle
     operation », prompt du design system) : c'est la seule teinte demandee qui
     manquait a la palette. */
  --indigo-900: #063329;
  /* 11/11/2026 — encres du VERRE de la fenetre de paiement. Elles ne doivent PAS
     basculer avec le theme (le verre est sombre la nuit, clair le jour) : on les
     declare ici, en valeur fixe, au lieu de les ecrire dans le bloc de la peau. */
  --glass-ink: #E6EEF9; --glass-ink-doux: #A9B4C4; --glass-accent: #8BE0CC;
  --glass-ink-clair: #C7D2E1; --glass-titre: #F1F5F9;
  --amber-50: #FFFBEB; --amber-100: #FBF1DC; --amber-200: #F7E3B8; --amber-500: #E5A93C;
  --amber-600: #D97706; --amber-700: #B45309; --amber-800: #92400E;
  --violet-50: #F5F3FF; --violet-200: #DDD6FE; --violet-500: #8B5CF6; --violet-700: #6D28D9;
  --sky-50: #F0F9FF; --sky-500: #0EA5E9; --sky-600: #0284C7; --sky-700: #0369A1;
  /* le vert du RETRAIT / des gains : #0F8A4B (design system), un peu plus franc
     que l'ancien #059669 et plus lisible avec du blanc dessus (4,4:1 au lieu de 3,8:1). */
  --emerald-50: #ECFDF5; --emerald-200: #A7F3D0; --emerald-500: #10B981; --emerald-600: #0F8A4B;
  --emerald-700: #0B6E3C; --emerald-800: #065F46;
  --rose-50: #FFF1F2; --rose-200: #FECDD3; --rose-500: #F43F5E; --rose-600: #E11D48; --rose-700: #BE123C;

  /* Couleurs des DEUX CARTES D'ACTION de l'accueil. Quatre demandes du client le
     30/09/2026 : « couleur vert pour le bouton depot et couleur rouge pour le bouton
     retrait », puis « couleur bleu clair pour le depot et vert clair pour le bouton
     retrait », puis « un peu plus clair et transparent », enfin « maintenant rend le
     transparent comme du verre ». Puis le 13/10/2026 : « changer la couleur du depot
     et du retrait en bleu clair et en vert clair un citron », et, capture d'un rond
     vert a la cle a l'appui (« se verte ») : « et trouve egalement un bleu du depot
     qui sera marier a se vert ». Etat retenu : le VERT ENVOYE PAR LE CLIENT (mesure
     au pixel sur sa capture : #35C036, soit HSL(120, 57 %, 48 %)) au retrait, et au
     depot un bleu APPARIE — meme saturation (56 %) que son vert, teinte 212 degres
     (le bleu qui s'accorde avec un vert franc), plus CLAIR (68 % de clarte) parce que
     sa consigne de depart etait « bleu clair » : c'est l'ACCORD de poids entre les
     deux teintes qui les marie, pas leur voisinage.

     EN VERRE, et c'est le seul reglage qui bouge : la teinte translucide (le fond de
     page compose la couleur) et le flou (`body.client-app .cx-act`) sont conserves,
     mais l'OPACITE passe de 45 % a 72 %. Motif : a 45 %, le vert du client devenait un
     lavis pale — le compose restait a 55 % du fond de page, donc au mieux #83D38A,
     tres loin de son #35C036. Les jetons sont FIGES (declares ici, nulle part dans le
     bloc de nuit) : la TEINTE ne bascule pas, c'est l'ENCRE qui bascule (voir la regle
     de la carte). Le contraste se mesure sur la COULEUR COMPOSEE sur le fond de page
     (--brand-50 le jour, le fond de nuit la nuit) et non sur le jeton ecrit a la
     main : 7,3:1 et 5,4:1 au depot, 5,8:1 et 5,2:1 au retrait le jour ; 6,0:1 a 8,7:1
     (depot) et 5,0:1 a 5,8:1 (retrait) la nuit. Ce que le client VOIT en clair :
     depot #7FAADB -> #5E90CB, retrait #43C646 -> #43BB46. ui_check 9quinquies mesure
     ces rapports sur les deux themes. */
  --act-dep-1: rgba(18, 161, 131, .72); --act-dep-2: rgba(10, 124, 102, .72);
  --act-wd-1: rgba(0, 180, 0, .72); --act-wd-2: rgba(0, 165, 0, .72);
  /* APLATS DES DEUX CARTES D'ACTION (10/11/2026, forme de FRANCKO RECHARGE) :
     le bleu de la maison au depot, le vert de la reference au retrait. Declares
     ici (LE PREMIER :root) parce que les controles de contraste de ui_check
     lisent ce bloc-la : un jeton pose plus loin dans la feuille leur echappe. */
  /* 10/11/2026 — design system : Dépôt = bleu nuit primaire, Retrait = vert
     émeraude. Les jetons renvoient aux couleurs de la palette, plus a une valeur
     ecrite en dur (une seule source pour le bleu de la marque). */
  /* le vert du design system (#0F8A4B) mesure 4,41:1 avec du blanc dessus : un
     cran plus sombre il passe a 4,88:1, et l'oeil ne voit pas la difference. */
  --cx-dep-fond: var(--cta); --cx-wd-fond: var(--brand-600);
  /* Encre de la vitre « retrait » le jour : un vert tres fonce de la MEME famille que
     la vitre (un vert clair ou un citron s'y noierait). Le bleu, lui, prend
     --brand-900. La nuit, les deux vitres prennent --on-brand. */
  --act-encre-vert: #063A06;

  --radius: 16px; --radius-lg: 24px; --radius-sm: 12px;
  /* surfaces (le mode sombre les redefinit : voir :root[data-theme="dark"]) */
  --surface: #FFFFFF; --surface-2: #F8FAFC;
  /* fond des barres collees (barre du bas de l'admin) : blanc a 97 % en clair,
     bleu nuit a 97 % la nuit (voir :root[data-theme="dark"]) */
  --surface-glass: rgba(255, 255, 255, .97);
  /* geste « tirer pour actualiser » (core.js) : le rond qui suit le doigt. Le JS
     ne pose que des var(), donc le rond suit le theme ; en clair il prend la
     surface (blanc) et le bleu de marque pour l'aiguille, et la NUIT il bascule
     tout seul (--surface devient sombre, l'aiguille passe au bleu 400 : voir le
     bloc du theme sombre). Le cerne donne un bord au rond quand les deux fonds
     se ressemblent. */
  --ptr-fond: var(--surface); --ptr-bord: var(--slate-200);
  --ptr-trait: var(--brand-600); --ptr-pret: var(--brand-600);
  --ptr-pret-trait: var(--on-brand);
  /* ombres : teintees de la marque (bleu de la plateforme de reference) */
  --shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 8px 24px -12px rgba(31, 111, 191, .22);
  --shadow-lg: 0 24px 60px -24px rgba(15, 47, 92, .35);
  --shadow-hover: 0 4px 20px rgba(31, 111, 191, .12);
  --shadow-cta: 0 8px 24px rgba(31, 111, 191, .32);
  --ring: 0 0 0 1px var(--slate-200);
  /* typographie recommandee pour le domaine finance : IBM Plex Sans, titres et
     texte. Auto-hebergee (voir static/css/fonts.css) : le CSP interdit un
     domaine de polices externe. */
  --font: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* HABILLAGE DES DEUX ECRANS D'ENTREE (06/11/2026) : la page et la carte sont
     BLANCHES dans les deux themes (demande du client, « meme fond blanc »).
     Ces quatre jetons ne basculent donc PAS la nuit — sinon le texte de la carte
     blanche s'ecrirait en clair sur du blanc. Ils sont declares une seule fois,
     ici, et seulement consommes par le bloc d'habillage en fin de feuille. */
  --ah-ink: #0F172A;      /* encre des titres et des libelles */
  --ah-muted: #64748B;    /* sous-titres, aides, pieds de carte */
  --ah-line: #E2E8F0;     /* bordures de la carte et des ronds */
  --ah-field: #F1F5F9;    /* aplat des champs au repos */
  --ah-card: #FFFFFF;     /* la carte (blanche le jour, bleu nuit la nuit) */
  --ah-brand: #0B2E55;    /* le bleu de la maison, FIGE (--brand-600 s'eclaircit la nuit) */
  --ah-brand-500: #0E3867;
  --ah-link: #0B2E55;     /* liens du pied de carte */
  --ah-page: #FFFFFF;     /* le fond de page (la nuit, il passe au bleu nuit) */
  --ah-gold-ink: #3D2A00; /* encre posee sur la pastille or */
  --ah-onbrand: #FFFFFF;  /* encre posee sur le bleu (bouton, pastille, colonne) */
  --font-titre: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* degrades : or -> violet pour le titre (la signature de la palette),
     violet pour les boutons. Le violet 600 tient le contraste sous du blanc. */
  --grad: linear-gradient(90deg, #0F3A66, #2F5C93);                 /* titre du hero : bleu -> bleu clair */
  --grad-cta: linear-gradient(135deg, #0E3867, #2F5C93);
  /* texte pose SUR la marque (bouton plein, onglet actif) : blanc dans les
     deux themes, puisque le fond est toujours fonce. Nomme une fois pour
     toutes plutot que d'ecrire #fff dans les regles (la zone d'animations de
     la feuille interdit toute couleur litterale, cf. tests/ui_check.py). */
  --on-brand: #FFFFFF;
  /* Verre (glassmorphism) : style recommande pour le domaine fintech par la
     base UI/UX Pro Max, et signature visuelle de la plateforme de reference
     (son .glass-card : flou 20 px, fond translucide, cerne 1 px, ombre teintee
     au survol). Valeurs transcrites de sa feuille de style. */
  --glass-bg: rgba(255, 255, 255, .86);      /* clair : blanc a 86 % */
  --glass-bg-2: rgba(255, 255, 255, .96);    /* au survol */
  --glass-border: rgba(229, 231, 235, .8);
  --glass-blur: blur(20px);
  /* barres qui restent sombres dans les deux themes (barre laterale du
     panneau, bandeau de l'accueil) : indigo nuit */
  --night: #0F172A;   /* fond sombre recommande (Dark Mode OLED) */

  /* theme clair de la page publique */
  --dark-bg: #FFFFFF; --dark-1: #F8FAFC; --dark-2: #FFFFFF; --dark-3: #E2E8F0;
  --dark-text: #0F172A; --dark-muted: #475569;
  --landing-red: #0B2E55; --landing-red-dark: #0F3A66; --landing-red-light: #0E3867;
}

/* =====================================================================
   MODE SOMBRE / NOCTURNE (12/10/2026) — active par data-theme="dark" sur
   <html> et <body> (bascule presente dans l'en-tete de chaque espace, choix
   garde dans localStorage sous la cle 'cd_theme').
   Le theme sombre etait celui de la maquette bleu nuit : fond #0F172A,
   cartes et bordures bleutees. Demande du client (12/10/2026) : le theme
   « NOCTURNE » de sa capture — plus AUCUN bleu dans les FONDS, l'echelle
   neutre (noir -> blanc) : tout composant qui utilise var(--slate-*) bascule
   sans etre retouche.
   28/10/2026 — le NOIR PUR a son tour est abandonne : « l'ancien etait trop
   sombre et ca fait mal aux yeux », puis « c'est un peu bleu c'est pas noir »
   sur une premiere version gris-bleu. Etat final : le nocturne de l'application
   MobCash — fond NOIR RELEVE #101010, surfaces #1C1C1C, echelle sans aucune
   teinte (r == g == b), texte secondaire #A6A6A6. Ce qui reste teinte : les ACCENTS (le bleu de marque des
   boutons, de l'onglet actif et des icones, l'or des mises en avant) et les
   couleurs d'ETAT (vert du retrait, rouge d'alerte, ambre de l'attente).
   ===================================================================== */
:root[data-theme="dark"] {
  color-scheme: dark;
  /* ECRAN DE SAISIE (depot / retrait / suivi) la nuit : meme structure Bento,
     encre claire sur cartes anthracite. Le cobalt reste l'action ; l'or de
     l'operateur et le vert de la coche ne bougent pas. */
  --dp-fond: #0B0B0F; --dp-carte: #15151A; --dp-champ: #1E1E24;
  --dp-encre: #F4F4F5; --dp-gris: #A1A1AA; --dp-bord: #26262C;
  --dp-cobalt: #2B82D9; --dp-cobalt-pale: rgba(127, 179, 230, .18);
  /* memes aplats la nuit ; le vert descend d'un cran (#047857) pour tenir le
     blanc au-dela de 4,5:1 sur le fond noir. */
  --cx-dep-fond: var(--brand-600); --cx-wd-fond: #0B6E3C;

  /* echelle NYGMA (28/10/2026) : gris pur, jetons releves dans sa feuille. */
  /* 28/10/2026 — le nocturne est celui de NYGMA EXCHANGE
     (`https://nygmaexchange.com`), releve dans sa feuille : bloc `.dark`.
     Leurs jetons sont en HSL a teinte NULLE (0 0%), c'est-a-dire une echelle
     de GRIS PUR sans aucune derive bleue :
       --background 0 0% 7%   -> #121212  (fond de page)
       --card       0 0% 11%  -> #1C1C1C  (cartes, barres)
       --secondary  0 0% 16%  -> #292929  (champs, surfaces secondaires)
       --border     0 0% 20%  -> #333333  (bordures)
       --muted-fg   0 0% 64%  -> #A3A3A3  (texte secondaire)
       --foreground 0 0% 96%  -> #F5F5F5  (texte)
     Notre echelle reprend ces valeurs (correspondance en commentaire). Seuls
     les ACCENTS gardent le bleu de la maison : leur `--primary` est un VERT
     (142 71% 45%), on ne prend pas leur couleur de marque. */
  /* 04/11/2026 — « utilise le theme sombre du backoffice pour l'espace client ».
     L'echelle est celle du panneau (--ink-* de panneau-v2.css / CSS : fond
     #0C0C0E, carte #18181B, secondaire #27272A, bordure #27272A, texte
     secondaire #9D9DA6, texte blanc), au lieu du gris NYGMA (#121212/#1C1C1C).
     Les ACCENTS gardent les bleus du nocturne : le bleu de marque du panneau
     (#0B2E55) porte du texte BLANC sur ses boutons la-bas ; employe comme encre
     sur un fond presque noir, il ne se lirait pas (1,9:1). Meme marque, nuance
     lisible. */
  --slate-50: #0B0E0D;   /* --ink-900 : fond de page du panneau */
  --slate-100: #141917;  /* entre le fond et la carte */
  --slate-200: #252E2A;  /* --ink-700 : bordure / champ */
  --slate-300: #35403B;
  --slate-400: #64736D;  /* --ink-400 : placeholder */
  --slate-500: #94A39D;  /* --ink-300 : texte secondaire */
  --slate-600: #B9C5C0;
  --slate-700: #D7E0DC;
  --slate-800: #E9EFEC;
  --slate-900: #F5F8F7;  /* texte du panneau : blanc franc */
  --slate-950: #FFFFFF;

  /* surfaces */
  --surface: #141917;      /* --ink-800 : cartes, barres */
  --surface-2: #1B221F;    /* --ink-700 : champs, pastilles, barre du haut */
  --surface-glass: rgba(12, 12, 14, .97);

  /* geste « tirer pour actualiser » : le rond prend la surface (sombre, par la
     chaine de var() du theme clair) mais l'aiguille en bleu 600 (#2F5C93) ne
     donnait que 2,9:1 sur ce rond — le client ne voyait presque rien au moment
     de tirer. On monte au bleu 400 : 5,2:1. */
  --ptr-trait: var(--brand-400);

  /* marque : le BLEU DE MARQUE reste le seul accent du nocturne (fond des
     boutons, onglet actif, traits et icones sur fond noir). Ses trois
     premieres nuances servent de FONDS teintes (vignettes, pastilles,
     survols) : elles passent au gris NEUTRE, sinon le fond de l'application
     et chaque vignette redeviendraient bleus — c'est exactement le bleu que
     la demande fait disparaitre. Les nuances 300 a 900 gardent leur teinte. */
  /* La nuit, le navy #0E3867 serait illisible sur le fond noir : la rampe
     s'eclaircit d'un cran (bleus 300-500) tout en restant la meme famille. */
  --brand-50: #0E1A2A; --brand-100: #12243A; --brand-200: #1A3352; --brand-300: #4E7DB5;
  --brand-400: #7FB3E6; --brand-500: #4E97DD; --brand-600: #3B82C7; --brand-700: #2F5C93;
  --brand-800: #1B5FA6; --brand-900: #134A80;

  /* teintes semantiques : fonds sombres, accents eclaircis */
  --amber-50: #41300F;   --amber-100: #3A2C0C; --amber-200: #6B4E12; --amber-500: #E5A93C;
  --amber-600: #F0C36A;  --amber-700: #F5D08E; --amber-800: #F7E3B8;
  --violet-50: #1E1836;  --violet-200: #4C3E86; --violet-500: #A78BFA; --violet-700: #C4B5FD;
  --sky-50: #0C2233;     --sky-500: #38BDF8;    --sky-600: #7DD3FC; --sky-700: #BAE6FD;
  --emerald-50: #1D301D;   /* --gt-positive-secondary */ --emerald-200: #1E5C46; --emerald-500: #34D399; --emerald-600: #4ADE80;
  --emerald-700: #6EE7B7; --emerald-800: #A7F3D0;
  /* aplats d'ETAT des bandeaux (toasts) : la famille emerald/rose/amber sert
     d'ENCRE la nuit (ses tons 600/700 y sont PASTEL), elle ne peut donc pas
     servir de FOND. Ces six jetons existent pour ca — voir .toast plus bas
     (28/10/2026 : « la couleur du message d'alerte est trop pale »). */
  --etat-ok: #0B5F45; --etat-ok-encre: #EAFBF3;
  --etat-ko: #8E1230; --etat-ko-encre: #FFE4E6;
  --etat-att: #6B3F04; --etat-att-encre: #FFF1CC;
  --rose-50: #38211E;      /* --gt-negative-secondary */    --rose-200: #6B2233;   --rose-500: #FB7185; --rose-600: #F43F5E;

  /* HABILLAGE DES DEUX ECRANS D'ENTREE — variantes de NUIT (06/11/2026, demande :
     « appliquer le mode sombre a la page de connexion quand le mode sombre est
     active », puis « le theme noir qui est dans le systeme »). Les jetons du jour
     sont donc remplaces par CEUX DU THEME SOMBRE DE LA MAISON — pas une teinte
     inventee : fond de page --slate-50 (#0C0C0E), carte --surface (#18181B),
     champs et bordures --surface-2 (#27272A), texte --slate-900 (#FFFFFF),
     secondaire --slate-500 (#9D9DA6). Seuls les accents restent les bleus du
     nocturne (--brand-600 pour le bouton, --brand-400 pour les liens). Chaine de
     var() : si l'echelle de nuit change dans la palette, ces ecrans suivent. */
  --ah-page: var(--slate-50);
  --ah-card: var(--surface);
  --ah-ink: var(--slate-900);
  --ah-muted: var(--slate-500);
  --ah-line: var(--surface-2);
  --ah-field: var(--surface-2);
  --ah-brand: var(--brand-600);
  --ah-brand-500: var(--brand-500);
  --ah-link: var(--brand-400);
  --ah-gold-ink: #2B1E00;
  --rose-700: #FDA4AF;

  /* page publique : style nocturne (fond noir, cartes et bordures neutres) */
  --dark-bg: #121212; --dark-1: #181818; --dark-2: #1C1C1C; --dark-3: #292929;
  --dark-text: #F5F5F5; --dark-muted: #A3A3A3;
  --landing-red: #0E3867; --landing-red-dark: #0B2E55; --landing-red-light: #2F5C93;

  --ring: 0 0 0 1px var(--slate-200);
  --shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 10px 30px -14px rgba(0, 0, 0, .7);
  --shadow-lg: 0 30px 70px -30px rgba(0, 0, 0, .85);
  /* refonte 27/09 : ombres et degrades revus pour la nuit. Un degrade de
     marque fonce disparaitrait sur fond nuit, on part donc des tons clairs. */
  --shadow-hover: 0 4px 20px rgba(0, 0, 0, .48);
  --shadow-cta: 0 8px 24px rgba(0, 0, 0, .55);
  --grad: linear-gradient(90deg, #6FD0B8, #B3C8E5);                 /* nuit : bleu clair -> bleu pale */
  --grad-cta: linear-gradient(135deg, #0E3867, #2F5C93);
  /* teinte des barres toujours sombres (barre laterale du panneau, bandeau
     de l'accueil) : NOIR du nocturne (l'indigo nuit reste celui du clair) */
  --night: #040405;   /* --ink-950 du panneau (barres, onglets du bas) */
  /* verre, version nuit : un voile blanc tres leger sur le fond profond */
  --glass-bg: rgba(255, 255, 255, .07);
  --glass-bg-2: rgba(255, 255, 255, .13);
  --glass-border: rgba(255, 255, 255, .12);
}

:root[data-theme="dark"] body { background: var(--slate-50); color: var(--slate-900); }
/* meme famille que le panneau : sans serif neutre, chiffres lisibles */
:root[data-theme="dark"] body,
:root[data-theme="dark"] body.client-app { font-family: Inter, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
/* Barres et panneaux translucides : version nocturne (noir translucide).
   Le fond de l'APPLICATION cliente prend la teinte --brand-50 en clair ; la
   nuit, cette teinte etant devenue NEUTRE, le fond de page se repose sur
   l'echelle (le NOIR du nocturne) et les vignettes gardent --brand-50. */
:root[data-theme="dark"] body.client-app { background: var(--slate-50); }
/* Barres arrondies et voiles : eux aussi passent du noir pur a la surface du
   PDV (28/10/2026). Un voile de dialogue reste plus sombre que la page, sinon
   la fenetre ne se detache plus. */
:root[data-theme="dark"] .bottomnav { background: rgba(28, 28, 28, .96); }
:root[data-theme="dark"] .landing-nav { background: rgba(28, 28, 28, .94); }
:root[data-theme="dark"] .modal,
:root[data-theme="dark"] .sheet { background: rgba(9, 9, 9, .82); }
/* la barre laterale de l'admin est sombre dans les deux themes (bleu nuit
   var(--night)) : le mode sombre du PANNEAU suit le
   mode sombre general, section « admin » plus bas. */
/* les separateurs internes (historiques, listes) etaient invisibles sur fond nuit */
:root[data-theme="dark"] .divide > * + * { border-top-color: var(--slate-200); }
:root[data-theme="dark"] .phone-mock { background: linear-gradient(160deg, var(--surface), var(--night)); }
/* icones sur pastille : trop sombres sinon */
:root[data-theme="dark"] .tile .t-ico,
:root[data-theme="dark"] .feat .fi { color: var(--brand-400); }
/* champs de saisie : garder le texte clair et le placeholder lisible */
:root[data-theme="dark"] .input::placeholder,
:root[data-theme="dark"] .textarea::placeholder { color: var(--slate-400); }
:root[data-theme="dark"] .select option { background: var(--surface); color: var(--slate-900); }

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font);
  background: var(--slate-50);
  color: var(--slate-900);
  /* Rendu du texte sur iOS/iPadOS. « antialiased » rend les lettres plus
     FINES et plus delavees sur iPad (constate le 25/09/2026 : l'en-tete de
     l'appli semblait flou a cote de la carte sombre). On laisse le reglage
     par defaut du systeme, qui donne des lettres plus franches. Sur Android
     cette propriete n'a aucun effet : rien ne change pour les telephones. */
  -webkit-font-smoothing: auto;
  font-size: 15px;
  line-height: 1.5;
}
a { color: inherit; text-decoration: none; }
button { font-family: inherit; font-size: inherit; }
img { max-width: 100%; display: block; }

/* ---------- utilitaires de mise en page ---------- */
.container { width: 100%; max-width: 1120px; margin: 0 auto; padding: 0 16px; }
.narrow { max-width: 640px; }
.flex { display: flex; } .iflex { display: inline-flex; }
.col { display: flex; flex-direction: column; }
.grid { display: grid; }
.wrap { flex-wrap: wrap; }
.items-center { align-items: center; } .items-start { align-items: flex-start; } .items-end { align-items: flex-end; }
.justify-between { justify-content: space-between; } .justify-center { justify-content: center; }
.justify-end { justify-content: flex-end; }
.grow { flex: 1 1 auto; } .shrink-0 { flex: 0 0 auto; } .min0 { min-width: 0; }
.gap1 { gap: 4px; } .gap2 { gap: 8px; } .gap3 { gap: 12px; } .gap4 { gap: 16px; } .gap6 { gap: 24px; }
.pad { padding: 16px; }   /* conteneur de page (/medias, rubrique fermee) : aucune regle n'existait */
.mt1 { margin-top: 4px; } .mt2 { margin-top: 8px; } .mt3 { margin-top: 12px; }
.mt4 { margin-top: 16px; } .mt5 { margin-top: 20px; } .mt6 { margin-top: 24px; } .mt8 { margin-top: 32px; }
.mb1 { margin-bottom: 4px; } .mb2 { margin-bottom: 8px; } .mb3 { margin-bottom: 12px; }
.mb4 { margin-bottom: 16px; } .mb6 { margin-bottom: 24px; } .mb0 { margin-bottom: 0; }
.ml-auto { margin-left: auto; } .mr-auto { margin-right: auto; }
.p2 { padding: 8px; } .p3 { padding: 12px; } .p4 { padding: 16px; } .p5 { padding: 20px; } .p6 { padding: 24px; }
.px4 { padding-left: 16px; padding-right: 16px; } .py2 { padding-top: 8px; padding-bottom: 8px; }
.py3 { padding-top: 12px; padding-bottom: 12px; } .py6 { padding-top: 24px; padding-bottom: 24px; }
.w-full { width: 100%; } .h-full { height: 100%; }
.relative { position: relative; } .absolute { position: absolute; } .fixed { position: fixed; }
.hidden { display: none !important; }
.text-center { text-align: center; } .text-right { text-align: right; } .text-left { text-align: left; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nowrap { white-space: nowrap; }
.mono { font-family: var(--mono); }
.caps { text-transform: uppercase; letter-spacing: .06em; }
.muted { color: var(--slate-500); }
.small { font-size: 13px; } .xs { font-size: 12px; } .lg { font-size: 17px; }
.strong { font-weight: 600; } .bold { font-weight: 700; }
.mw-md { max-width: 480px; } .mw-lg { max-width: 720px; }
.text-brand { color: var(--brand-600); } .text-emerald { color: var(--emerald-700); }
.text-rose { color: var(--rose-700); } .text-amber { color: var(--amber-700); }
.text-warning { color: var(--amber-700); }   /* alias utilise par le panneau (note du retrait) */
.text-sky { color: var(--sky-600); } .text-slate4 { color: var(--slate-400); }
.pt2 { padding-top: 8px; } .pt3 { padding-top: 12px; } .pt4 { padding-top: 16px; }
.pb2 { padding-bottom: 8px; } .pb4 { padding-bottom: 16px; }
.logo { display: flex; align-items: center; justify-content: center; border-radius: 10px;
  color: #fff; font-weight: 800; font-size: 15px; overflow: hidden; }
/* logo en IMAGE (bookmakers, 01/10/2026) : le fichier livre est carre et porte
   son propre fond, il remplit donc la vignette ; « contain » evite de rogner un
   logo plus large venu du panneau (`logo_url`). */
.logo-img { object-fit: contain; }
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

h1, h2, h3, h4 { margin: 0; line-height: 1.2; font-weight: 700; }
.h1 { font-size: 26px; } .h2 { font-size: 21px; } .h3 { font-size: 17px; } .h4 { font-size: 15px; }

/* ---------- cartes / surfaces ---------- */
.card {
  background: var(--surface); border-radius: var(--radius); box-shadow: var(--ring);
  overflow: hidden;
}
.card.p4 { padding: 16px; }
.card-hd { padding: 14px 16px; border-bottom: 1px solid var(--slate-100); display: flex;
  align-items: center; justify-content: space-between; gap: 8px; }
.card-bd { padding: 16px; }
.card-ft { padding: 12px 16px; border-top: 1px solid var(--slate-100); background: var(--slate-50); }
.elevated { box-shadow: var(--shadow); }
.soft { background: var(--slate-50); border-radius: var(--radius-sm); padding: 12px; }
.hairline { border: 1px solid var(--slate-200); }
.divide > * + * { border-top: 1px solid var(--slate-100); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* ---------- boutons ---------- */
/* PASTILLE (30/09/2026, demande du client : « arrondit bien les boutons de
   l'interface ») : tous les boutons de la maison sont des pastilles — le rayon
   suit la hauteur, donc aucune taille de bouton ne peut redevenir rectangulaire.
   Les rayons par taille (.btn-sm / .btn-xs) ont ete retires le meme jour : ils
   cassaient cette regle. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 16px; border-radius: 999px; border: 1px solid transparent;
  background: var(--slate-100); color: var(--slate-800); font-weight: 600; cursor: pointer;
  transition: filter .15s ease, background .15s ease; line-height: 1.1;
}
.btn:active { transform: scale(.96); }   /* reference : active:scale-95 */
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-primary { background: var(--brand-600); color: #fff; }
.btn-primary:hover { filter: brightness(1.06); }
.btn-dark { background: var(--brand-700); color: #fff; }
.btn-ok { background: var(--emerald-600); color: #fff; }
.btn-warn { background: var(--amber-500); color: #3b2506; }
.btn-danger { background: var(--rose-600); color: #fff; }
.btn-ghost { background: transparent; border-color: var(--slate-200); color: var(--slate-700); }
.btn-ghost.white { border-color: rgba(255,255,255,.3); color: #fff; }
/* ---------- bascule clair / sombre ---------- */
.btn-theme {
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 12px; border-radius: 999px;
  border: 1px solid var(--slate-200); background: var(--surface); color: var(--slate-700);
  font-size: 13px; font-weight: 600; cursor: pointer; line-height: 1;
}
.btn-theme:hover { border-color: var(--brand-300); color: var(--brand-700); }
.btn-theme [data-theme-icon] { display: inline-flex; }
.btn-theme.white { background: rgba(255,255,255,.10); border-color: rgba(255,255,255,.3); color: #fff; }
.btn-theme.white:hover { background: rgba(255,255,255,.2); border-color: rgba(255,255,255,.5); color: #fff; }
@media (max-width: 700px) { .btn-theme .btn-theme-label { display: none; } }
.btn-sm { padding: 7px 11px; font-size: 13px; }
.btn-xs { padding: 4px 9px; font-size: 12px; }
.btn-block { width: 100%; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------- formulaires ---------- */
.label { display: block; font-size: 12px; font-weight: 600; color: var(--slate-600);
  text-transform: uppercase; letter-spacing: .05em; margin-bottom: 6px; }
.input, .select, .textarea {
  width: 100%; padding: 11px 13px; border: 1px solid var(--slate-200); border-radius: 12px;
  background: var(--surface); color: var(--slate-900); font-size: 15px; outline: none;
}
.input:focus, .select:focus, .textarea:focus { border-color: var(--brand-500);
  box-shadow: 0 0 0 3px var(--brand-100); }
.input.mono { font-family: var(--mono); letter-spacing: .14em; }
/* Champ du bookmaker du depot (01/10/2026, dessin de la reference) : FERME comme
   un select, il s'ouvre au toucher. Tant que rien n'est choisi : tuile grise,
   icone de boutique et texte gris ; une fois choisi, la vignette du bookmaker et
   son nom en encre normale. Le chevron reste a droite. */
.bm-champ { display: flex; align-items: center; gap: 10px; text-align: left; cursor: pointer; }
.bm-champ .bm-tuile { flex: none; width: 34px; height: 34px; border-radius: 10px;
  background: var(--slate-100); color: var(--slate-500); display: flex; align-items: center;
  justify-content: center; }
.bm-champ .bm-nom { color: var(--slate-400); }
.bm-champ.choisi .bm-nom { color: var(--slate-900); }
.bm-champ .bm-chev { flex: none; margin-left: auto; color: var(--slate-400); }
.textarea { min-height: 90px; resize: vertical; }
.field { margin-bottom: 14px; }
.hint { font-size: 12px; color: var(--slate-500); margin-top: 6px; }
.err-text { font-size: 13px; color: var(--rose-600); margin-top: 6px; }
.switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }

/* ---------- badges / pastilles ---------- */
.badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px; border-radius: 999px;
  font-size: 12px; font-weight: 600; background: var(--slate-100); color: var(--slate-700); white-space: nowrap; }
.badge-pending { background: var(--amber-100); color: var(--amber-800); }
.badge-awaiting_admin { background: var(--violet-50); color: var(--violet-700); }
.badge-paid, .badge-success { background: var(--emerald-50); color: var(--emerald-700); }
.badge-rejected { background: var(--rose-50); color: var(--rose-700); }
.badge-cancelled { background: var(--slate-100); color: var(--slate-600); }
.badge-expired { background: var(--slate-200); color: var(--slate-700); }
.badge-review { background: var(--amber-100); color: var(--amber-800); }
.badge-info { background: var(--sky-50); color: var(--sky-700); }
.badge-deposit { background: var(--brand-50); color: var(--brand-700); }
.badge-payout { background: var(--sky-50); color: var(--sky-700); }
.badge-admin { background: var(--brand-700); color: #fff; }
.badge-super { background: var(--brand-600); color: #fff; }
/* Credit manuel sur preuve (ajout a nous) : un depot credite SANS SMS marchand.
   Deux marques distinctes pour l'audit : « credit manuel » (qui l'a fait) et
   « sans SMS » (comment on l'a prouve). */
.badge-manual { background: var(--violet-50); color: var(--violet-700); }
.badge-nosms { background: var(--amber-100); color: var(--amber-800); }
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--slate-400); display: inline-block; }
.dot.ok { background: var(--emerald-500); } .dot.warn { background: var(--amber-500); }
.dot.err { background: var(--rose-500); } .dot.brand { background: var(--brand-600); }
.dot.sky { background: var(--sky-500); }   /* seconde serie de la tendance (retraits) */

/* ---------- tableau ---------- */
.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th { text-align: left; font-size: 12px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--slate-500); padding: 10px 12px; background: var(--slate-50); border-bottom: 1px solid var(--slate-200); }
.table td { padding: 11px 12px; border-bottom: 1px solid var(--slate-100); vertical-align: middle; }
.table tr:hover td { background: var(--slate-50); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* ---------- tableaux en cartes sur telephone (classe mob-cards) ----------
   Sur un ecran etroit, une ligne de tableau se lit de haut en bas : chaque
   cellule devient une ligne « NOM DE COLONNE -> valeur ». L'en-tete disparait
   (le nom est repris cellule par cellule par le noyau : data-label), donc plus
   aucun defilement horizontal et les colonnes de droite (statut, actions) ne
   sont plus hors de vue. Les cellules d'etat vide (colspan) restent telles quelles. */
@media (max-width: 700px) {
  .mob-cards { min-width: 0 !important; border-collapse: separate; border-spacing: 0; }
  .mob-cards thead { display: none; }
  .mob-cards tbody, .mob-cards tr, .mob-cards td { display: block; width: auto; }
  .mob-cards tr { border: 1px solid var(--slate-200); border-radius: var(--radius-sm);
    background: var(--surface); padding: 10px 12px; margin-bottom: 10px; }
  .mob-cards tr:hover td { background: transparent; }
  .mob-cards td { border: 0; padding: 3px 0; text-align: left; }
  .mob-cards td[data-label]:not([data-label=""]) { display: flex; flex-wrap: wrap;
    align-items: baseline; gap: 2px 12px; }
  .mob-cards td[data-label]:not([data-label=""])::before { content: attr(data-label);
    flex: 0 0 40%; font-size: 12px; text-transform: uppercase; letter-spacing: .06em;
    color: var(--slate-500); }
  .mob-cards td[data-label]:not([data-label=""]) > * { flex: 1 1 calc(60% - 12px); min-width: 0; }
  .mob-cards td[colspan] { padding: 0; }
  .mob-cards .num { text-align: left; }
  /* boutons d'action : toute la largeur de la carte, alignes a droite */
  .mob-cards td .tx-actions { flex: 1 1 100%; justify-content: flex-end; }
  .mob-cards td .btn { white-space: nowrap; }
  /* ---- listes de transactions : les champs separes, le cadre arrondi -------
     « separe-les et arrondis les bornes » (04/10/2026) : un trait entre deux
     champs et un rayon plus large. Pose sur la classe du tableau (liste-champs)
     pour ne pas modifier les autres listes, qui n'ont pas ete demandees. */
  .mob-cards.liste-champs tr { border-radius: 14px; padding: 12px 14px; }
  .mob-cards.liste-champs td { padding: 8px 0; }
  .mob-cards.liste-champs tbody tr > td + td { border-top: 1px solid var(--slate-100); }
}

/* ---------- LISTE DES TRANSACTIONS SUR TELEPHONE (04/10/2026) --------------
   « affiche les details comme avant, separe-les et arrondis les bornes », puis
   « comme ca c'est mieux ». Sur le telephone, la ligne de tableau retrouve donc
   ses champs — reference, date, client, type, montant, statut, ceux de la liste
   de l'accueil (voir .mob-cards.liste-champs) — un par ligne, libelle a gauche
   et valeur dans la colonne suivante, separes par un trait et reunis dans un
   cadre arrondi : `.dt-liste` / `.dt-row` / `.dt-l` / `.dt-v` (poses dans
   admin.html, remplis par `dtRow` dans admin.js). Tout le reste — bookmaker et
   ID joueur, moyen et numero de paiement, frais, chaque horodatage, journal,
   note — vit dans « Details », qui lit la MEME ligne : rien n'est perdu.

   Rien n'est masque par une classe de tableau ici : le telephone recoit des
   cartes (.tx-mob, rendu par txCardMob dans admin.js) et le grand ecran garde
   le tableau complet (.tx-desk). Un seul des deux est affiche a la fois, donc
   aucun contenu n'est rendu deux fois a l'ecran. Couleurs prises aux variables
   du theme : les deux themes suivent tout seuls. */
.tx-mob { display: none; }
.tx-card { padding: 10px; }
.tx-card + .tx-card { margin-top: 8px; }
.tx-card .tx-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
@media (max-width: 700px) {
  .tx-desk { display: none; }
  .tx-mob { display: block; }
}

/* ---------- KPI ---------- */
.kpi { background: var(--surface); border-radius: var(--radius); box-shadow: var(--ring); padding: 14px; }
.kpi .k-label { font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--slate-500); }
.kpi .k-value { font-size: 22px; font-weight: 700; margin-top: 4px; font-variant-numeric: tabular-nums; }
.kpi .k-sub { font-size: 12px; color: var(--slate-500); margin-top: 2px; }
.kpi.highlight { box-shadow: 0 0 0 2px var(--brand-500); }
/* ---- Tableau de bord : variation, courbe miniature, echelle -----------------
   Trois ajouts seulement, tous en jetons du projet (aucune couleur nouvelle) :
   la pastille de variation, la courbe de 7 points des tuiles, et l'echelle
   graduee de la tendance. La fleche de la pastille est un triangle CSS : pas de
   police d'icones, pas d'image, rien a charger. */
.delta { display: inline-flex; align-items: center; gap: 4px; padding: 1px 7px;
  border-radius: 999px; font-size: 11.5px; font-weight: 700;
  font-variant-numeric: tabular-nums; }
.delta-up { background: var(--emerald-50); color: var(--emerald-700); }
.delta-down { background: var(--rose-50); color: var(--rose-700); }
.delta-new { background: var(--slate-100); color: var(--slate-600); font-weight: 600; }
.tri-haut, .tri-bas { width: 0; height: 0; border-left: 4px solid transparent;
  border-right: 4px solid transparent; }
.tri-haut { border-bottom: 5px solid currentColor; }
.tri-bas { border-top: 5px solid currentColor; }
.kpi .spark { display: block; width: 100%; height: 28px; margin-top: 8px; color: var(--brand-500); }
.kpi .spark polyline { fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
/* File d'attente : tuiles compactes, deux colonnes des que la place le permet
   (sur telephone, six tuiles pleine largeur feraient deux ecrans de defilement). */
.qa-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 10px; }
.qa-card-live { box-shadow: 0 0 0 1px var(--brand-300), var(--shadow); }
/* Tendance : grille horizontale graduee, echelle ecrite a gauche. */
.chart-wrap { display: flex; align-items: stretch; gap: 10px; }
.chart-y { display: flex; flex-direction: column; justify-content: space-between;
  font-size: 10.5px; color: var(--slate-500); text-align: right; min-width: 52px;
  font-variant-numeric: tabular-nums; }
.chart-plot { flex: 1 1 auto; min-width: 0; position: relative; }
.chart-grid { position: absolute; inset: 0; border-bottom: 1px solid var(--slate-200);
  border-radius: 6px 6px 0 0;
  background-image: repeating-linear-gradient(to top, var(--slate-100) 0 1px, transparent 1px 50%); }
.chart-x { display: flex; justify-content: space-between; gap: 8px; margin-top: 6px;
  font-size: 10.5px; color: var(--slate-500); }
/* Pied de la carte « Tendance » : quatre reperes separes par un simple espace. */
.dash-strip { display: flex; flex-wrap: wrap; gap: 4px 22px; }
.dash-stat { display: flex; flex-direction: column; min-width: 92px; }
.dash-stat .strong { font-variant-numeric: tabular-nums; }
@media (max-width: 700px) {
  .chart-y { min-width: 38px; font-size: 9.5px; }
  .chart-x { font-size: 9.5px; }
  .qa-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .dash-strip { gap: 4px 16px; }
  .dash-stat { min-width: 78px; }
}

/* ---------- application cliente ---------- */
/* En-tete repris de la capture de reference : fond blanc bleute (pas de
   degrade sombre), logo dans une vignette carree arrondie, nom de marque,
   puis les actions (menu, theme, cloche + pastille, initiale du pseudo). */
/* 112 px : la barre du bas (barre + rond du support) PLUS la silhouette
   « vallees et montagnes » qui monte de ~20 px au-dessus d'elle depuis le
   28/09/2026 — sinon la derniere carte passait sous les collines.
   LA ZONE DE GESTES DU TELEPHONE S'AJOUTE (03/10/2026) : la barre flotte a
   `10 px + env(safe-area-inset-bottom)` du bord bas, donc la reserve doit
   grandir avec elle — sinon la derniere ligne d'une page longue passe sous la
   barre sur un telephone en navigation a trois boutons (zone de gestes ~48 px). */
.app-shell { max-width: 720px; margin: 0 auto; padding-bottom: calc(112px + env(safe-area-inset-bottom)); }
.topbar {
  position: sticky; top: 0; z-index: 20; background: var(--brand-50); color: var(--slate-900);
  padding: 10px 16px;
}
.topbar .brand { font-weight: 800; letter-spacing: -.02em; }
.topbar .who { font-size: 12px; opacity: .85; }
:root[data-theme="dark"] .topbar { background: var(--surface-2); }
.balance-hero {
  background: linear-gradient(140deg, var(--brand-600), var(--brand-800));
  color: #fff; border-radius: var(--radius-lg); padding: 20px;
}
.balance-hero .amt { font-size: 30px; font-weight: 800; font-variant-numeric: tabular-nums; }
.bottomnav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; background: rgba(255,255,255,.98);
  /* BORD HAUT ARRONDI (30/09/2026, demande du client : « arrondit bien les boutons de
     l'interface et la barre de navigation »). La silhouette « vagues et montagnes »
     (navWave) qui dessinait le bord haut est partie le meme jour : elle est posee
     AU-DESSUS de la barre, donc elle depasserait dans les coins arrondis — les deux
     ne peuvent pas cohabiter. La barre du telephone suit desormais la barre BORNEE
     de l'ordinateur : meme rayon (--radius-lg) et meme trait fin de 1 px, qui remplace
     ce que dessinait la silhouette. */
  /* 10/11/2026 — QUATRE entrees a parts egales (Accueil / Historique / Chat /
     Profil), comme la capture : plus de place vide qui poussait la derniere
     entree au bord droit, plus d'entree « hors du flux » au milieu. */
  display: flex; justify-content: space-around; align-items: center; gap: 0;
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  border-top: 1px solid var(--slate-200);
  backdrop-filter: blur(8px);
}
:root[data-theme="dark"] .bottomnav { border-top-color: rgba(255, 255, 255, .10); }
/* Les entrees de la barre. Depuis le 30/09/2026 (2e demande du client : « colle
   exactement a leur barre : Accueil a GAUCHE en pilule, puis les autres entrees en
   icones a droite ») : l'ACCUEIL vient en PREMIER, a GAUCHE, et c'est LUI qui porte
   son libelle DANS une pilule quand on est dessus ; « Coupon » est AU MILIEU (hors
   du flux, `.nav-milieu`) et « Historique » reste a DROITE, en icone seule. Le
   support n'est plus un rond flottant (retire le 30/09/2026) : seule l'entree ACTIVE
   montre son libelle. Le `nav-vide` est ce qui pousse « Historique » au bord droit. */
.bottomnav .item {
  /* ICONE AU-DESSUS, LIBELLE DESSOUS (10/11/2026, capture de la reference) : les
     quatre entrees portent leur nom en permanence, plus de pilule sur l'active. */
  position: relative; flex: 1 1 0; display: flex; flex-direction: column; align-items: center;
  gap: 3px; padding: 6px 2px; border-radius: 0; color: var(--slate-500);
  font-size: 11px; font-weight: 700; background: none; border: 0; cursor: pointer;
}
/* L'ENTREE ACTIVE : la pilule (icone + libelle), la signature de leur barre. Ses
   marges sont un peu plus larges pour que le libelle respire. */
/* 01/10/2026 (habillage retenu par l'agent, le client ayant laisse la main :
   « c'est pas joli, tu peux faire a ta guise ») : la pilule active est PLEINE, a la
   couleur de la maison, icone et libelle en blanc — elle se detache nettement du
   fond clair de la barre, comme la pastille d'une barre de navigation moderne. */
/* L'ENTREE ACTIVE : plus de pilule pleine — icone ET libelle a la couleur de la
   maison (le bleu de la capture est rouge, le notre est bleu). */
.bottomnav .item.active { background: none; color: var(--brand-600); padding: 6px 2px; }
:root[data-theme="dark"] .bottomnav .item.active { color: var(--brand-400); }
/* Les libelles des entrees NON actives restent dans le document — le nom lisible
   vient de l'`aria-label` pose par navItem — mais ne s'affichent pas. */
/* Le libelle est TOUJOURS visible (c'etait l'inverse depuis le 30/09/2026) ;
   l'`aria-label` pose par navItem reste, pour les lecteurs d'ecran. */
.bottomnav .item span { display: block; font-size: 11px; font-weight: 700; line-height: 1.1;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bottomnav .item svg { width: 24px; height: 24px; }
/* PASTILLE DES NON-LUS SUR L'ENTREE « MESSAGES » (10/11/2026, le support est
   entre dans la barre du bas a la place de Coupons). Elle se pose en haut a
   droite de l'icone. Deux pieges : `.bottomnav .item span { display: none }`
   masque les libelles des entrees non actives (donc la pastille avec), et une
   regle qui pose `display` fait reapparaitre un element `[hidden]` — d'ou la
   seconde ligne, ecrite sur le meme selecteur. */
.bottomnav .item .cx-nb,
.bottomnav .item.active .cx-nb {
  display: block; position: absolute; top: 0; left: 50%; margin: 0;
  transform: translateX(6px);
  min-width: 16px; height: 16px; padding: 0 4px; font-size: 10px; line-height: 16px;
  border-radius: 999px;
}
.bottomnav .item .cx-nb[hidden] { display: none; }
/* La place laissee entre les deux entrees : c'est elle qui ecarte « Historique »
   du bord gauche et le pose au bord droit. */
.nav-vide { flex: 1 1 0; }
/* L'ENTREE DU MILIEU (30/09/2026, demande du client : « met le au milieu »). Elle
   est prise HORS du flux et posee a 50 % de la barre : elle tombe donc au CENTRE
   de l'ecran quelle que soit la largeur de l'accueil (qui est une PILULE quand on
   est dessus) et de l'historique (icone seule). Dans le flux, elle serait collee a
   l'accueil : c'est justement ce que le client a fait corriger. Sans `top`, le
   navigateur la place comme si elle etait seule dans la barre (align-items center),
   donc exactement a la hauteur des deux autres entrees — ne pas ajouter de `top`,
   la barre a un rembourrage bas qui inclut la zone de gestes du telephone. */
.nav-milieu { position: absolute; left: 50%; transform: translateX(-50%); }
/* Depuis le 30/09/2026 l'entree active est une PILULE (fond teinte + libelle) :
   plus de pastille derriere l'icone, donc plus besoin de reserver 5 px autour de
   chaque icone. Les entrees gardent la meme hauteur, la pilule seule marque
   l'entree active (voir `.bottomnav .item.active` plus haut). */
.sheet {
  position: fixed; inset: 0; z-index: 40; background: rgba(10, 8, 24, .55);
  display: flex; align-items: flex-end; justify-content: center;
}
.sheet-card { background: var(--surface); width: 100%; max-width: 720px; border-radius: 22px 22px 0 0;
  max-height: 92vh; overflow: auto; padding: 18px; }
.modal { position: fixed; inset: 0; z-index: 50; background: rgba(10, 8, 24, .55);
  display: flex; align-items: flex-start; justify-content: center; padding: 16px;
  overflow-y: auto; overscroll-behavior: contain; }
/* margin:auto centre la fenetre quand elle tient a l'ecran ET laisse le
   defilement partir du HAUT quand elle est plus grande (avec align-items:center,
   le haut devenait inatteignable : la fenetre « se figeait »). */
.modal-card { background: var(--surface); width: 100%; max-width: 440px; border-radius: var(--radius-lg);
  padding: 20px; box-shadow: var(--shadow-lg); margin: auto; position: relative; }
.modal-card h3 { margin-bottom: 8px; padding-right: 40px; }
/* Fermeture toujours a portee de pouce, meme sur une fenetre tres longue. */
.modal-x { position: absolute; top: 10px; right: 10px; width: 34px; height: 34px; border: 0;
  border-radius: 999px; background: var(--slate-100); color: var(--slate-600); cursor: pointer;
  display: flex; align-items: center; justify-content: center; }
.modal-x:hover { background: var(--slate-200); color: var(--slate-800); }
/* La barre d'actions de la fenetre reste visible pendant le defilement. */
.modal-card > .btn-row:last-child { position: sticky; bottom: 0; background: var(--surface);
  padding-top: 10px; }
.stepper { display: flex; align-items: center; gap: 6px; margin: 4px 2px 0; }
.stepper .bar { height: 4px; border-radius: 999px; background: var(--slate-200); flex: 1; }
.stepper .bar.on { background: var(--brand-600); }
.choice {
  display: flex; align-items: center; gap: 12px; padding: 12px; border: 1px solid var(--slate-200);
  border-radius: 14px; background: var(--surface); cursor: pointer; width: 100%; text-align: left;
}
.choice.active { border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-50); }
.choice .logo { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center;
  justify-content: center; color: #fff; font-weight: 800; font-size: 15px; }
/* Logos des reseaux Mobile Money (Flooz = Moov Money, Mixx by Yas = Togocom).
   Les deux fichiers ont leur PROPRE fond opaque : la vignette est un CARRE de
   40 px, rempli de la couleur de fond du logo lui-meme, et l'image y tient en
   entier (contain) — un carre plein, sans liseré, identique pour les deux. */
/* =====================================================================
   ECRAN DE CONNEXION / INSCRIPTION, calque sur la reference : pleine page
   sombre, logo, nom de marque (deuxieme mot en couleur), formulaire, « ou »,
   bouton Google, lien vers l'autre ecran. Aucun en-tete ni barre du bas.
   ===================================================================== */
/* Le fond de la page de connexion doit GAGNER sur celui de l'espace client
   (`body.client-app`, plus bas dans la feuille, meme specificite (0,1,1)) : sinon
   c'est le bleu clair #EEF3FA qui peint le fond de page, et il se voyait AUTOUR
   de l'ecran sombre — une bande d'environ 14 px a gauche, a droite et en haut
   (mesure sur la capture du 28/09/2026, 15:40 : #EDF2F9 au bord, l'ecran sombre
   ne commencant qu'au 48e pixel d'image). Une classe de plus (0,2,1) : l'ordre
   des feuilles ne compte plus. Le mode sombre n'echappait pas au defaut — mais
   comme son fond d'espace client est deja sombre, la bande ne s'y voyait pas. */
body.auth-page,
body.auth-page.client-app,
body.auth-page.admin-app { background: #0B1220; }
/* Habillage 2 (30/09/2026) : l'ecriture de la reference (Inter) est abandonnee.
   Les deux ecrans de connexion prennent la police de la maison, IBM Plex Sans
   (--font), comme tout le reste du site : c'etait le dernier morceau de la
   reference qui restait visible chez nous. La fonte Inter reste sur le disque et
   son @font-face a ete retire de css/fonts.css (et de la liste du service
   worker) : pour revenir en arriere, le redeclarer et remettre la famille ici. */
body.auth-page, body.auth-page h1, body.auth-page h2, body.auth-page h3,
body.auth-page .auth-brand, body.auth-page .btn, body.auth-page input,
body.auth-page select, body.auth-page textarea {
  font-family: var(--font); }
/* Sur les deux ecrans de connexion, la coquille disparait ENTIEREMENT : en-tete et
   barre du bas. Le rond du support n'est plus a cacher ici : depuis le 30/09/2026
   il est flottant et n'apparait que sur l'accueil (syncShell pose `hidden`). */
body.auth-page .topbar, body.auth-page .bottomnav { display: none; }
body.auth-page .app-shell { padding-bottom: 0; }
/* Fond sombre constelle, comme la maquette : halo de la couleur de marque en
   haut, puis un reseau de points relies. */
/* L'IMAGE NE DOIT PAS BOUGER (02/10/2026). Le client : « l'image bouge quand on
   appuie sur Se connecter ». Le bloc etait CENTRE verticalement : plus la carte
   est haute (l'inscription a six champs), plus l'en-tete remonte — le logo sautait
   de 110 px entre les deux ecrans (mesure : 102 px en inscription, 211 en
   connexion). Il est desormais ancre a une distance FIXE du haut, et seule la
   carte s'allonge vers le bas. `overflow-x: hidden` (et non `overflow: hidden`)
   laisse defiler quand l'ecran est trop court : avant, le bas de l'inscription
   etait rogne. */
.auth-shell { position: relative; min-height: 100svh; display: flex; align-items: flex-start;
  justify-content: center; padding: 76px 16px 24px; overflow-x: hidden;
  background: radial-gradient(125% 58% at 50% -6%, rgba(43, 130, 217, .62), transparent 68%), #0B1220; }
.auth-shell::before { content: ''; position: absolute; inset: 0; pointer-events: none; opacity: .62;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='220'%20height='220'%3E%3Cg%20stroke='rgba(255,255,255,0.16)'%20stroke-width='1'%3E%3Cpath%20d='M18 34L74 62L126 24L176 74L204 44'/%3E%3Cpath%20d='M28 122L82 154L142 112L196 164'/%3E%3Cpath%20d='M62 62L82 154M126 24L142 112M176 74L196 164M18 34L28 122'/%3E%3C/g%3E%3Cg%20fill='rgba(255,255,255,0.34)'%3E%3Ccircle%20cx='18'%20cy='34'%20r='3'/%3E%3Ccircle%20cx='74'%20cy='62'%20r='3'/%3E%3Ccircle%20cx='126'%20cy='24'%20r='3'/%3E%3Ccircle%20cx='176'%20cy='74'%20r='3'/%3E%3Ccircle%20cx='204'%20cy='44'%20r='3'/%3E%3Ccircle%20cx='28'%20cy='122'%20r='3'/%3E%3Ccircle%20cx='82'%20cy='154'%20r='3'/%3E%3Ccircle%20cx='142'%20cy='112'%20r='3'/%3E%3Ccircle%20cx='196'%20cy='164'%20r='3'/%3E%3C/g%3E%3C/svg%3E"); background-size: 220px 220px; }
.auth-wrap { position: relative; z-index: 1; width: 100%; max-width: 384px; }
/* Habillage 2 (30/09/2026) : rayon 16 au lieu des 24 px de la reference, et la
   coche de marque posee en haut de la carte (voir l'habillage, plus bas). */
.auth-card { position: relative; overflow: hidden; width: 100%; background: #fff;
  border-radius: 16px; padding: 20px; margin-top: 14px;
  box-shadow: 0 18px 40px -24px rgba(0, 0, 0, .8); }
/* LE BLANC DE LA CARTE EST OPAQUE PLEIN, ET SANS CERNE. La regle « VERRE » plus
   bas l'englobait : son fond translucide (blanc a 86 %) l'emportait sur le blanc
   pose ci-dessus — la carte s'affichait donc GRISE (mesure 220, 222, 223 sur la
   capture du 28/09) avec un lisere clair tout autour. `.auth-card` a ete retiree
   de la liste du verre (voir la section VERRE) ; ce bloc-ci remet la carte a
   plat, au cas ou une regle voisine la reprendrait : fond blanc, aucun flou,
   aucun bord. Sur une page sombre, une carte blanche n'a pas besoin de cerne.
   Les champs gardent leur propre bord gris (--slate-300) pour rester lisibles
   dessus. Ce bloc est ecrit AVANT la section des mouvements de la feuille :
   tout ce qui suit n'accepte plus aucune couleur en dur (controle « aucune
   couleur nouvelle »). */
.auth-card {
  background: #fff;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border: 0;
}
.auth-card-t { text-align: center; font-size: 20px; font-weight: 600; letter-spacing: -.025em;
  /* L'ENCRE DE CE TITRE EST FIGEE (03/10/2026, meme defaut que la banniere de
     telechargement, releve sur la meme capture du client) : la carte est blanche
     DANS LES DEUX THEMES (voir `.auth-card`), alors que `--slate-900` devient
     #F8FAFC la nuit — « Connexion », « Creer un compte » et « Connexion Google »
     s'ecrivaient donc en blanc sur leur propre carte blanche. Valeur du theme
     clair ecrite EN DUR, comme pour les champs (`.fx-in`) : 17,9:1 sur le blanc.
     La section 12-5 de tests/ui_check.py mesure ce rapport dans les deux themes. */
  color: #0F172A; margin: 0 0 16px; }
.auth-head { display: flex; flex-direction: column; align-items: center; text-align: center; }
/* vignette du logo, comme la maquette (elle avait ete retiree le 27/09 au matin) */
.auth-logo { width: 46px; height: 46px; border-radius: 13px; overflow: hidden; margin-bottom: 10px;
  box-shadow: 0 14px 32px -12px rgba(0, 0, 0, .85); }
.auth-logo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.auth-title { font-size: 20px; font-weight: 600; color: #fff; letter-spacing: -.025em; margin: 0; }
.auth-title .auth-brand { color: var(--brand-300); }
.auth-sub { color: rgba(255, 255, 255, .62); font-size: 14px; margin-top: 4px; }
/* ---------- champs a libelle dans la bordure (maquette du 27/09/2026) ----------
   « L'instruction » (le libelle) est posee SUR le fond blanc du champ et bascule
   vers le haut, dans la bordure, des qu'on saisit — ou quand le champ contient
   deja du texte. Le fond blanc derriere le libelle « coupe » la bordure, comme
   sur la capture. */
.fx { position: relative; margin-bottom: 10px; }
.fx-in { width: 100%; height: 44px; border: 1px solid var(--slate-300); border-radius: 20px;
  padding: 0 16px; background: #fff; font: inherit; font-size: 14px; color: #0F172A;
  caret-color: #0B2E55; color-scheme: light;
  -webkit-appearance: none; appearance: none; }
.fx.has-ico .fx-in { padding-left: 48px; }
.fx-in:focus { outline: none; border-color: var(--brand-600);
  box-shadow: 0 0 0 3px rgba(31, 111, 191, .12); }
.fx-ico { position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  color: var(--slate-400); display: flex; pointer-events: none; }
.fx-lb { position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  padding: 0 5px; background: #fff; color: var(--slate-500); font-size: 14px; font-weight: 500;
  pointer-events: none; white-space: nowrap;
  transition: top .15s ease, left .15s ease, font-size .15s ease, color .15s ease; }
.fx.has-ico .fx-lb { left: 43px; }
/* CHAMP DONT LE LIBELLE RESTE DANS LA BORDURE : l'indice gris (« +228 … ») occupe
   le fond du champ — la facon de faire d'EMB Money, releve du 27/09/2026 : leur
   champ telephone porte `placeholder={"+228 …"}` et son libelle est deja pose en
   haut. Sans cette classe, le libelle « Telephone » resterait au milieu du champ
   et se superposerait a l'indice. */
.fx.fx-haut .fx-lb { top: 0; left: 11px; font-size: 12px; color: #64748B; }
.fx.has-ico.fx-haut .fx-lb { top: 0; left: 11px; font-size: 12px; color: #64748B; }
/* le libelle monte : champ rempli (au repos) puis champ actif (couleur de marque) */
.fx-in:not(:placeholder-shown) + .fx-lb { top: 0; left: 11px; font-size: 12px; color: var(--slate-500); }
.fx-in:focus + .fx-lb { top: 0; left: 11px; font-size: 12px; color: var(--brand-600); }
/* select : un select a toujours une valeur, son libelle reste en haut */
.fx-fixe .fx-lb { top: 0; left: 11px; font-size: 12px; color: var(--slate-500); }
.fx-fixe select.fx-in { padding-right: 40px; }
.fx-fixe::after { content: ''; position: absolute; right: 18px; top: 50%; width: 8px; height: 8px;
  border-right: 2px solid var(--slate-400); border-bottom: 2px solid var(--slate-400);
  transform: translateY(-70%) rotate(45deg); pointer-events: none; }
/* ---------- champ a libelle dans la bordure, DANS L'APPLI (maquette du 28/09/2026) --
   Capture de la reference : le champ « Numero mobile money » du depot porte son
   libelle DANS le champ — il monte dans la bordure des qu'on saisit —, une icone de
   telephone a gauche, et l'exemple du numero (« 90123456 ou 22890123456 ») qui ne se
   montre QU'UNE FOIS le champ actif. Memes mesures que les champs de l'appli
   (`.input` : bord 1 px `--slate-200`, rayon 12, 44 px, texte 15 px, fond
   `--surface`) : c'est exactement le gabarit de la capture, et l'ecran reste
   d'aplomb avec les autres champs — nuit comprise, ou `--surface` et les gris
   s'inversent. C'est ce qui la distingue des champs de connexion (`.fx`, rayon 20,
   fond blanc dans les deux themes puisque la carte de connexion est blanche). */
.fxn { position: relative; margin-bottom: 14px; }
.fxn-in { width: 100%; height: 44px; border: 1px solid var(--slate-200); border-radius: 12px;
  padding: 0 13px; background: var(--surface); color: var(--slate-900);
  caret-color: var(--brand-600);
  font: inherit; font-size: 15px; outline: none;
  -webkit-appearance: none; appearance: none; }
.fxn.has-ico .fxn-in { padding-left: 42px; }
.fxn-in:focus { border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--brand-100); }
.fxn-ico { position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
  color: var(--slate-400); display: flex; pointer-events: none; }
.fxn-lb { position: absolute; left: 9px; top: 50%; transform: translateY(-50%);
  padding: 0 4px; background: var(--surface); color: var(--slate-500); font-size: 15px;
  pointer-events: none; white-space: nowrap;
  transition: top .15s ease, left .15s ease, font-size .15s ease, color .15s ease; }
.fxn.has-ico .fxn-lb { left: 38px; }
/* le libelle monte : champ rempli (au repos), puis champ actif (couleur de marque) —
   l'ordre compte, le focus est ecrit apres */
.fxn-in:not(:placeholder-shown) + .fxn-lb { top: 0; left: 9px; font-size: 12px; color: var(--slate-500); }
.fxn-in:focus + .fxn-lb { top: 0; left: 9px; font-size: 12px; color: var(--brand-600); }
/* L'EXEMPLE NE SE MONTRE QUE SUR LE CHAMP ACTIF (capture de la reference) : au
   repos, le champ ne porte que son libelle, comme une phrase d'instruction. */
.fxn-in::placeholder { color: transparent; }
.fxn-in:focus::placeholder { color: var(--slate-400); }
/* ---------- LE TEXTE DES CHAMPS DE CONNEXION RESTE SOMBRE LA NUIT ---------------
   Les champs de connexion sont BLANCS dans les deux themes (`.fx-in` porte
   `background: #fff`). Or leur texte, leurs libelles et leurs icones suivaient
   les variables `--slate-*`, qui s'INVERSENT en mode sombre : on tapait donc du
   BLANC sur du BLANC — champ Email illisible (capture iOS du 27/09/2026 au soir).
   Les valeurs du theme clair sont donc ecrites EN DUR ici : des variables
   suivraient la nuit. `color-scheme: light` (pose sur `.fx` et rappele sur les
   champs) empeche en plus iOS d'appliquer son rendu sombre aux champs, qui
   forcait le texte en blanc par `-webkit-text-fill-color`.
   Contrastes sur le fond blanc du champ : texte #0F172A 17,9:1 ; libelle
   #64748B 4,8:1 ; icone #94A3B8 2,8:1 (decorative) ; libelle actif #0B2E55
   10,9:1. */
.fx { color-scheme: light; }
.fx-in, .auth-form .input, .auth-form .select {
  -webkit-text-fill-color: #0F172A; }
.fx-in::placeholder, .auth-form .input::placeholder {
  color: #94A3B8; -webkit-text-fill-color: #94A3B8; }
.fx-ico { color: #94A3B8; }
.fx-lb { color: #64748B; }
.fx-in:not(:placeholder-shown) + .fx-lb { color: #64748B; }
.fx-in:focus + .fx-lb { color: #0B2E55; }
.fx-fixe .fx-lb { color: #64748B; }
.fx-fixe::after { border-right-color: #94A3B8; border-bottom-color: #94A3B8; }
.pw-eye { color: #64748B; }
.pw-eye:hover { color: #0F172A; }
.auth-form .label { color: #475569; }
.auth-form .input, .auth-form .select {
  background: #fff; border-color: #CBD5E1; color: #0F172A; color-scheme: light; }
.auth-shell .gsi-off { border-color: #CBD5E1; background: #F8FAFC; color: #475569; }
/* (Le bouton Google maison a ete SUPPRIME le 02/10/2026, sur la demande du client :
   la connexion se fait maintenant avec le bouton de Google lui-meme, dessine dans
   l'application. Ses deux regles « .auth-shell .gsi-app » sont parties avec lui.) */
.auth-shell .gsi-ghost { border-color: #CBD5E1; background: #fff; color: #0F172A; }
/* LE BOUTON DE LA FENETRE GOOGLE DU TELEPHONE (02/10/2026) : le dessin de celui
   de Google (logo a quatre couleurs) — c'est la meme action pour le client, mais
   elle ouvre la liste de SES comptes du telephone.
   02/10/2026 (soir) : BLANC, sur sa demande (« change le bouton de connexion de
   google en blanc »). C'est le dessin du bouton BLANC de Google : fond blanc,
   trait fin gris, encre grise — et plus de pastille blanche derriere le logo
   (invisible sur fond blanc, elle ne faisait que rapetisser le G). */
.auth-shell .gsi-natif { width: 100%; font-family: inherit; font-size: 14px;
  font-weight: 600; cursor: pointer; display: flex; align-items: center;
  justify-content: center; gap: 10px; height: 46px; padding: 0 14px;
  border: 1px solid #DADCE0; border-radius: 23px; background: #fff; color: #3C4043; }
.auth-shell .gsi-natif svg { width: 18px; height: 18px; flex: 0 0 18px; }
.auth-shell .gsi-natif:active { background: #F1F3F4; }
/* LE BOUTON DES COMPTES DU TELEPHONE (03/10/2026) : quand l'application porte la
   fenetre des comptes d'Android, elle dessine CE bouton-la (meme dessin que celui de
   Google, pleine largeur) — un seul bouton Google a l'ecran, jamais deux. */
.gsi-comptes .gsi-natif { width: 100%; }

/* ---------------------- LA FENETRE FLOTTANTE DES COMPTES (03/10/2026, la nuit)
   Deux demandes du client, chacune avec sa capture :
   1. « c'est le rendu de emb money je veux c'est plus moderne l'affichage des email »
      -> la liste grise du systeme ne se redessine pas : la liste est la NOTRE.
   2. « ca doit etre une fentre flottant et s'afficher comme tel » (capture de la page
      Google : comptes separes par un FILET, sans cadre) -> plus une feuille collee en
      bas, mais une CARTE CENTREE : marges tout autour, fond assombri, coins arrondis,
      ombre, croix de fermeture, et une ligne par adresse separee par un filet.
   L'ENCRE SUIT LE THEME (--slate-*), elle n'est PAS figee : la carte porte la surface
   du theme (--surface), qui s'inverse la nuit. La regle du bandeau de telechargement
   (« figer l'ENCRE ») vaut pour une surface BLANCHE dans les deux themes ;
   l'appliquer ici donnerait de l'encre sombre sur fond sombre. */
.ctb-fenetre { position: fixed; inset: 0; z-index: 60; display: flex;
  align-items: center; justify-content: center; padding: 18px;
  background: rgba(10, 8, 24, .58); animation: ctb-fade .16s ease both; }
/* Le fond cliquable couvre TOUTE la surface (l'appui a cote de la carte la ferme) ;
   il sort du flux pour ne pas deplacer la carte. */
.ctb-fond { position: absolute; inset: 0; }
.ctb-card { position: relative; z-index: 1; width: 100%; max-width: 360px;
  max-height: 82vh; overflow: auto; background: var(--surface); border-radius: 22px;
  padding: 20px 16px 16px; box-shadow: var(--shadow-lg); animation: ctb-pop .2s ease both; }
@keyframes ctb-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes ctb-pop { from { opacity: 0; transform: translateY(10px) scale(.97); }
  to { opacity: 1; transform: none; } }
.ctb-x { position: absolute; top: 10px; right: 10px; width: 32px; height: 32px;
  border: 0; border-radius: 999px; background: var(--slate-100); color: var(--slate-600);
  cursor: pointer; display: flex; align-items: center; justify-content: center; }
.ctb-titre { font-size: 1.15rem; font-weight: 800; color: var(--slate-900);
  text-align: center; margin: 0 0 4px; padding: 0 30px; }
.ctb-sous { text-align: center; color: var(--slate-500); font-size: .84rem;
  margin: 0 0 12px; }
.ctb-sous b { color: var(--slate-700); font-weight: 700; }
.ctb-liste { display: flex; flex-direction: column; }
/* Les lignes sont SEPAREES PAR UN FILET, pas encadrees : c'est le dessin de la page
   de Google que le client a montree (« s'afficher comme tel »). */
.ctb-ligne { display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 11px 4px; border: 0; border-bottom: 1px solid var(--slate-200);
  border-radius: 0; background: transparent; text-align: left; cursor: pointer;
  font-family: inherit; transition: background .15s ease; }
.ctb-ligne:active { background: var(--slate-100); }
.ctb-avatar { position: relative; overflow: hidden;
  width: 40px; height: 40px; flex: 0 0 40px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center; color: #fff;
  font-weight: 800; font-size: 1rem;
  background: linear-gradient(135deg, #0B2E55 0%, #0E3867 55%, #E5A93C 140%); }
/* LA VRAIE PHOTO SE POSE PAR-DESSUS L'INITIALE (03/10/2026, la nuit) : « la photo du
   profil de l'email doit se faire voir ». Elle couvre la pastille ronde ; si le lien
   ne se charge pas, elle se retire toute seule et l'initiale reste — jamais de case
   vide, jamais d'image cassee dans la liste des comptes. */
.ctb-photo { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; border-radius: 999px; }
.ctb-plus { background: var(--slate-100); color: #0B2E55; font-size: 1.35rem;
  font-weight: 700; }
.ctb-texte { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.ctb-nom { color: var(--slate-900); font-weight: 700; font-size: .97rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctb-mail { color: var(--slate-500); font-size: .84rem; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.ctb-chev { color: var(--slate-400); flex: 0 0 auto; display: flex; align-items: center; }
/* « Ajouter un compte » ferme la liste : le filet du haut le separe des adresses. */
.ctb-ajout { border-top: 1px solid var(--slate-200); border-bottom: 0; }
.ctb-note { color: var(--slate-500); font-size: .76rem; line-height: 1.45;
  margin: 12px 2px 0; }
/* l'anneau de focus : la seule regle de cette famille qui garde un role ici (le
   fond, la bordure et l'encre sont poses plus haut, en valeurs fixes). */
.auth-form .input:focus { border-color: #2F5C93; box-shadow: 0 0 0 3px rgba(78, 123, 184, .25); }
/* Bouton d'envoi : mesures relevees sur la reference (42 px de haut, rayon 16,
   libelle 12 px, 14 px au-dessus — l'ecart qui separe le dernier champ). */
.auth-form .btn { height: 42px; padding: 0 16px; border-radius: 20px; font-size: 14px;
  margin-top: 14px; }
.auth-pw { position: relative; }
.auth-pw .input { padding-right: 46px; }
.pw-eye { position: absolute; right: 0; top: 0; height: 100%; padding: 0 12px; background: none;
  border: 0; color: #64748B; cursor: pointer; display: flex; align-items: center; }
.pw-eye:hover { color: #0F172A; }
.auth-row { display: flex; align-items: center; gap: 12px; }
.auth-link { background: none; border: 0; padding: 0; color: var(--brand-700); font-size: 14px; font-weight: 500;
  text-decoration: underline; cursor: pointer; }
.auth-sep { display: flex; align-items: center; gap: 12px; }
.auth-sep span { height: 1px; flex: 1; background: var(--slate-200); }
.auth-sep b { color: var(--slate-400); font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: .1em; }
.auth-foot { text-align: center; color: rgba(255, 255, 255, .66); font-size: 14px; margin-top: 16px; }
.auth-foot a { color: #7FB2F0; font-weight: 700; }
/* reseaux sociaux, sous la carte (maquette) : des ronds cercles sur le fond sombre */
.auth-soc { margin-top: 18px; text-align: center; }
.auth-soc-t { color: rgba(255, 255, 255, .6); font-size: 13.5px; }
.auth-soc-row { display: flex; justify-content: center; gap: 18px; margin-top: 12px; }
.auth-soc-row a { width: 52px; height: 52px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; color: #fff; background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .18); }
.auth-soc-row a:active { transform: scale(.94); }
.auth-foot.xs { font-size: 12px; margin-top: 10px; color: var(--slate-400); }

/* ---------- BANNIERE DE TELECHARGEMENT DE L'APPLICATION (page de connexion) --
   Demande du client (02/10/2026, capture de sa page de connexion de reference) :
   « afficher le bouton de telechargement de l'application sur la page de
   connexion exactement comme ca ». La banniere de la reference, reprise ici
   telle quelle dans sa FORME — pastille de la marque a gauche, deux lignes de
   texte, bouton rond de telechargement, croix de fermeture — avec NOS couleurs
   et NOS phrases. Elle FLOTTE en bas de l'ecran (hors du flux) : la page de
   connexion est sombre, la banniere est donc BLANCHE, comme la carte du
   formulaire juste au-dessus (meme famille, meme raison : une page sombre).
   Elle n'est posee que si le telechargement est ouvert (voir app.js) : sans
   fichier, rien ne s'affiche, et l'URL ne sort jamais du serveur. */
.dl-banner { position: fixed; left: 10px; right: 10px; z-index: 5;
  bottom: calc(10px + env(safe-area-inset-bottom));
  /* 03/10/2026, client : « rendre l'affichage moins long un peu rectangle » (capture
     du bandeau a l'appui), puis « reduis encore » dans la meme minute. Mesures du
     rendu REEL avant de toucher (424 px de page, echelle 3) : la reference faisait
     404 x 64 px, rayon 26 (= presque une barre), titre de 172 px dans 235 px de place.
     Etat retenu maintenant : max-width 404 -> 312, rayon 26 -> 16 (il avait demande
     « arrondit les bornes » le 02/10 : CETTE DEMANDE-LA EST PERIMEE), rembourrage
     10 -> 9 px, ecarts 11 -> 9, pastille 44 -> 36, bouton 42 -> 34, croix 26 -> 22,
     titre 14 -> 13 px, phrase 12 -> 11,5 px. La police descend parce que le titre est
     en nowrap + ellipse : retrecir sans baisser la police le COUPE (c'est la plainte
     du 02/10). Plancher a ne pas franchir : 22 (rembourrage) + pastille + TITRE
     NATUREL + bouton + croix + 3 ecarts. Mesure apres coup, titre non coupe :
     312 x 54 px, soit 74 % de la largeur.
     PUIS « augmente la taille vers le haut » (toujours le 03/10/2026) : la LARGEUR ne
     bouge pas (312 px, c'est la demande precedente), c'est la HAUTEUR qui monte — le
     bandeau est ancre en bas, il grandit donc vers le haut. Rembourrage vertical
     9 -> 15 px : 54 -> 66 px de haut, soit un vrai bloc (proportion 4,7:1 au lieu de
     6,3:1 au depart), et le contenu reste centre (align-items: center). La largeur est
     INCHANGEE : agrandir la pastille ou le bouton mangerait le creneau du titre. */
  max-width: 312px; margin: 0 auto; padding: 15px 11px;
  display: flex; align-items: center; gap: 9px;
  background: #fff; border-radius: 16px;
  box-shadow: 0 18px 40px -22px rgba(0, 0, 0, .9); }
.dl-banner[hidden] { display: none; }
/* ---------- LE TEXTE DE LA BANNIERE RESTE SOMBRE LA NUIT (03/10/2026) ----------
   Plainte du client : « le bouton de telechargement de l'application n'affiche pas
   les ecritures en mode sombre » (capture de sa page de connexion, les deux lignes
   blanches dans la banniere blanche). La banniere est BLANCHE dans les DEUX themes
   (voir le bloc du dessus : la page de connexion est sombre), or son titre et sa
   phrase suivaient les variables --slate-*, qui S'INVERSENT la nuit : --slate-900
   passe a #F8FAFC et --slate-500 a #94A3B8 — du presque-blanc sur du blanc, les
   deux lignes disparaissaient. Meme correctif que les champs de connexion
   (`.fx-in` et `.auth-form .input`, plus haut) : sur une surface blanche DANS LES
   DEUX THEMES, l'ENCRE est ecrite EN DUR sur les valeurs du theme clair — une
   variable suivrait la nuit. Contrastes sur le blanc de la banniere : titre
   #0F172A 17,9:1 ; phrase #64748B 4,8:1. La section 12-5 de tests/ui_check.py
   mesure ces deux rapports dans les deux themes : remettre var(--slate-*) ici
   fait rougir le controle. */
.dl-ico { flex: 0 0 auto; width: 36px; height: 36px; border-radius: 50%;
  background: var(--brand-600); color: #fff;
  display: flex; align-items: center; justify-content: center; }
.dl-txt { flex: 1 1 auto; min-width: 0; }
.dl-t { font-size: 13px; font-weight: 600; color: #0F172A;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dl-s { margin-top: 1px; font-size: 12px; line-height: 1.25; color: #64748B;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.dl-go { flex: 0 0 auto; width: 34px; height: 34px; border: 0; border-radius: 50%;
  background: var(--brand-600); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 10px 22px -12px rgba(31, 111, 191, .95); }
.dl-go:active { transform: scale(.94); }
.dl-x { flex: 0 0 auto; width: 22px; height: 22px; padding: 0; border: 0;
  background: none; color: var(--slate-400); cursor: pointer;
  display: flex; align-items: center; justify-content: center; }
/* ---------- LA PLACE DE LA BANNIERE EST RESERVEE DANS LE FLUX (03/10/2026) ------
   Client : « impossible de defiler l'interface de connexion vers le haut et le
   bas », capture de l'ecran d'inscription a l'appui. La banniere est `position:
   fixed` : elle ne pousse rien, et le document faisait EXACTEMENT la hauteur de
   l'ecran (`min-height: 100svh` sur `.auth-shell`). Sur un ecran court, le bas du
   formulaire passait donc SOUS elle sans qu'on puisse le ramener — mesure a
   840 px de haut : « Deja un compte ? Se connecter » 32 px sous le haut de la
   banniere, et `scrollHeight == clientHeight`, molette sans effet. Ce bloc, pose
   par `banniereApp` juste apres la banniere, rend au document la hauteur que la
   banniere occupe : 66 px + ses 10 px de marge basse. Il disparait avec elle
   (croix). Verifie par ui_check (12-5) et par le parcours de front_smoke. */
.dl-reserve { height: calc(76px + env(safe-area-inset-bottom)); }
.dl-reserve[hidden] { display: none; }

/* =====================================================================
   PANNEAU LATERAL DU BURGER (modele de la reference) : panneau blanc, liste
   verticale, entree active en pastille de la couleur de marque, carte du bas
   (bienvenue pour un visiteur, compte + deconnexion pour un client).
   ===================================================================== */
body.no-scroll { overflow: hidden; }
.sidedrawer { position: fixed; inset: 0; z-index: 70; }
.sd-back { position: absolute; inset: 0; background: rgba(10, 8, 24, .5); }
.sd-panel { position: absolute; top: 0; left: 0; bottom: 0; width: min(87%, 340px);
  display: flex; flex-direction: column; background: var(--surface); color: var(--slate-900);
  box-shadow: 22px 0 60px -30px rgba(0, 0, 0, .45); animation: sd-in .22s ease-out;
  /* La barre d'etat du systeme est dessinee PAR-DESSUS la page (iPad en mode
     application) : sans cette reserve, la marque du panneau et la croix de
     fermeture passaient dessous et paraissaient lavees/floues. Vu sur capture
     le 25/09/2026. L'inset vaut 0 sur Android dans un onglet : rien ne change. */
  padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); }
@keyframes sd-in { from { transform: translateX(-16px); opacity: .6; } to { transform: none; opacity: 1; } }
.sd-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px;
  padding: 18px 18px 14px; }
.sd-brand { line-height: 1.15; }
.sd-brand .sd-b1 { font-size: 20px; font-weight: 800; letter-spacing: -.01em; color: var(--slate-900); }
.sd-brand .sd-b2 { font-size: 20px; font-weight: 800; letter-spacing: -.01em; color: var(--brand-600); }
.sd-brand small { display: block; margin-top: 2px; font-size: 12px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--slate-500); }
.sd-x { background: none; border: 0; color: var(--slate-600); padding: 6px; cursor: pointer; }
.sd-list { flex: 1; overflow-y: auto; padding: 4px 12px 12px; }
.sd-item { display: flex; align-items: center; gap: 14px; padding: 13px 14px; margin-bottom: 2px;
  border-radius: 14px; color: var(--slate-700); font-size: 16px; font-weight: 600; text-decoration: none; }
.sd-item:hover { background: var(--slate-50); }
.sd-item .sd-ico { flex: 0 0 auto; opacity: .95; }
.sd-item.on { background: var(--brand-600); color: #fff; }
.sd-foot { padding: 14px; border-top: 1px solid var(--slate-200); }
.sd-user { margin-bottom: 10px; }
.sd-user b { display: block; font-size: 15px; color: var(--slate-900); }
.sd-user small { color: var(--slate-500); font-size: 12px; }
.sd-welcome { background: var(--slate-50); border: 1px solid var(--slate-200);
  border-radius: 18px; padding: 14px; }
.sd-welcome b { display: block; font-size: 15px; color: var(--slate-900); margin-bottom: 4px; }
.sd-welcome small { display: block; color: var(--slate-500); font-size: 12px; margin-bottom: 12px; line-height: 1.35; }
.sd-welcome .btn { margin-bottom: 8px; }
.sd-welcome .btn:last-child { margin-bottom: 0; }
.sd-white { background: #fff; color: var(--brand-700); border: 1px solid var(--slate-300); font-weight: 700; }
.sd-foot .btn-block { width: 100%; justify-content: center; }

/* Bandeau « Nouvelle version disponible » : fixe en bas, au-dessus de la barre. */
.maj-banner { position: fixed; left: 50%; transform: translateX(-50%); bottom: 84px; z-index: 60;
  display: flex; align-items: center; gap: 10px; padding: 10px 10px 10px 13px; border-radius: 18px;
  background: var(--slate-900); color: #fff; font-size: 13px; font-weight: 600;
  box-shadow: 0 12px 30px -12px rgba(15, 23, 42, .5); max-width: calc(100% - 24px); }
.maj-banner .btn { border-radius: 999px; }
/* Demande du client (28/09/2026) : « le bouton de mise a jour en mode sombre ».
   Le bandeau est un fond SOMBRE en clair (--slate-900), mais la nuit cette
   variable devient PRESQUE BLANCHE (#F8FAFC) alors que l'encre reste #fff figee :
   du blanc sur du blanc, libelle invisible, et un bloc qui eclatait la nuit.
   Version nuit explicite : surface du theme + encre claire (13,9:1). */
:root[data-theme="dark"] .maj-banner {
  background: var(--surface); color: var(--slate-900);
  border: 1px solid var(--slate-200);
  box-shadow: 0 12px 30px -12px rgba(0, 0, 0, .7);
}

/* Tournois : banniere de l'ecran (format 2:1 comme la reference, fond degrade
   avec le trophee quand aucune image n'est fournie) et carte de l'accueil. */
.banner { position: relative; aspect-ratio: 2 / 1; width: 100%; overflow: hidden; border-radius: 16px;
  display: flex; align-items: center; gap: 14px; padding: 18px; color: #fff;
  background: linear-gradient(135deg, var(--brand-800), var(--brand-600) 60%, var(--brand-400)); }
.banner img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.banner .bn-ico { flex: 0 0 auto; opacity: .95; }
.banner .bn-txt { position: relative; min-width: 0; }
.banner .bn-txt .strong { font-size: 18px; }
.banner .bn-txt .xs { opacity: .85; }
/* Carte promotionnelle (tournoi), sur le modele de la reference : grande image
   en haut, puis un bandeau blanc avec le titre, le texte et le bouton d'action. */
.cx-tournoi { display: block; margin-top: 16px; border: 1px solid var(--slate-200);
  border-radius: 20px; overflow: hidden; background: var(--surface); text-decoration: none;
  color: inherit; box-shadow: var(--shadow); }
.cx-tournoi .ct-img { display: block; width: 100%; aspect-ratio: 2 / 1; overflow: hidden; }
.cx-tournoi .ct-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cx-tournoi .ct-ico { display: flex; align-items: center; justify-content: center; width: 100%;
  aspect-ratio: 2 / 1; color: #fff;
  background: linear-gradient(135deg, var(--brand-800), var(--brand-500)); }
.cx-tournoi .ct-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; }
.cx-tournoi .ct-txt { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
.cx-tournoi .ct-txt b { font-size: 15px; }
.cx-tournoi .ct-txt small { color: var(--slate-500); font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cx-tournoi .ct-go { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px;
  background: var(--brand-600); color: #fff; font-size: 13px; font-weight: 700;
  padding: 10px 14px; border-radius: 999px; }

/* ---------------------------------------------------- bloc « Code promo »
   Reference du 06/10/2026 : la VIGNETTE de la marque, son nom, le libelle
   « Code promo » et le CODE dans une puce a pointilles qui se COPIE d'un appui.
   Le bloc vit sous les deux cartes Depot / Retrait, sur les DEUX accueils
   (client et visiteur) — c'est une publicite, la reference la montre a un
   visiteur. Le contenu vient des REGLAGES (voir `codePromoCard` dans app.js) :
   un code vide et le bloc n'existe pas.
   Couleurs de la maison : bleu de la marque pour la vignette, OR (--amber-*)
   pour la puce. Ces jetons S'INVERSENT la nuit, donc aucune regle de nuit a
   doubler ici. Fenetre OPAQUE (socle de l'espace client) : ni flou ni verre. */
.cx-promo { margin-top: 14px; padding: 12px 13px; border: 1px solid var(--slate-200);
  border-radius: 18px; background: var(--surface); box-shadow: var(--shadow); }
.cx-promo-row { display: flex; align-items: center; gap: 12px; }
.cx-promo-logo { flex: 0 0 auto; width: 46px; height: 46px; border-radius: 14px;
  display: flex; align-items: center; justify-content: center; color: #fff;
  background: linear-gradient(135deg, var(--brand-700), var(--brand-500));
  animation: cxPromoFlotte 3.6s ease-in-out infinite; }
@keyframes cxPromoFlotte { 0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3px); } }
.cx-promo-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.cx-promo-t { font-size: 15px; font-weight: 700; color: var(--slate-900);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cx-promo-s { font-size: 12px; color: var(--slate-500); }
.cx-promo-chip { position: relative; overflow: hidden; flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 7px; padding: 9px 12px;
  border: 1px dashed var(--amber-600); border-radius: 12px;
  background: var(--amber-50); color: var(--amber-800); font: inherit;
  font-weight: 700; cursor: pointer; animation: cxPromoRespire 2.6s ease-in-out infinite; }
@keyframes cxPromoRespire { 0%, 100% { transform: scale(1); }
  50% { transform: scale(1.03); } }
.cx-promo-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 15px; font-weight: 700; letter-spacing: 2px; }
.cx-promo-ico { display: inline-flex; opacity: .75; }
/* Le BALAYAGE : une bande claire traverse la puce toutes les 3,4 s et ramene
   l'oeil sur le code. Purement decoratif (aucun evenement, aucun clic). */
.cx-promo-brille { position: absolute; top: 0; bottom: 0; width: 38%; left: -60%;
  pointer-events: none; background: linear-gradient(90deg, transparent,
  rgba(255, 255, 255, .65), transparent);
  animation: cxPromoBrille 3.4s ease-in-out infinite; }
@keyframes cxPromoBrille { 0% { left: -60%; } 45%, 100% { left: 125%; } }
/* Le code vient de partir : la puce se remplit et se coche 1,4 s (classe posee
   par le gestionnaire `promo-copy` d'app.js). L'encre est FIGEE : elle vit sur
   l'or, qui ne bascule pas. */
.cx-promo-copie { background: var(--amber-500); border-style: solid;
  border-color: var(--amber-500); color: #3A2C0C; animation: cxPromoPop .5s ease; }
.cx-promo-copie .cx-promo-brille { display: none; }
.cx-promo-copie .cx-promo-ico svg { display: none; }
.cx-promo-copie .cx-promo-ico::after { content: '\2713'; font-size: 15px; font-weight: 700; }
@keyframes cxPromoPop { 0% { transform: scale(1); } 35% { transform: scale(1.12); }
  100% { transform: scale(1); } }
/* Le bouton d'inscription, quand le reglage `promo_url` est rempli : pleine
   largeur sous la ligne (vide = aucun bouton, le bloc reste celui de la
   reference). */
.cx-promo-cta { display: flex; align-items: center; justify-content: center; gap: 6px;
  margin-top: 11px; padding: 12px; border-radius: 14px; background: var(--brand-600);
  color: #fff; font-size: 14px; font-weight: 700; text-decoration: none; }
@media (prefers-reduced-motion: reduce) {
  .cx-promo-logo, .cx-promo-chip, .cx-promo-copie { animation: none; }
  .cx-promo-brille { display: none; }
}

/* Carte de bienvenue d'un visiteur : meme carte sombre que le client connecte,
   avec la pastille CASHDESK et les deux boutons. */
.cx-hero-guest .cx-pill { display: inline-flex; align-items: center; gap: 6px; }
.cx-hero-guest .cx-spark { display: inline-flex; }
.cx-hero-guest .cx-hello { margin-top: 12px; font-size: 22px; font-weight: 700; line-height: 1.25; }
/* Le mot de marque du titre porte le bleu clair de la maquette du client, sur la
   carte visiteuse COMME sur la carte d'un connecte (02/10/2026). */
.cx-hero .cx-hello b, .cx-hero-guest .auth-brand { color: #9DC0F0; font-weight: 800; }
.cx-hero .btn-white { background: #fff; color: var(--brand-800); border: 0; font-weight: 700; }
.cx-hero .btn-white:hover { background: #EDF3FC; }

/* Bouton « Continuer avec Google » (rendu par Google Identity Services) et ses
   etats d'attente. Le bouton officiel est en theme sombre, forme pilule, comme
   dans la reference. */
/* Le cadre du bouton de Google. EN COLONNE depuis le 02/10/2026 : quand notre
   bouton de secours se montre (Google trop lent a venir), il doit se placer SOUS
   celui de Google. En ligne, les deux se serraient cote a cote et le texte du
   second etait coupe — vu sur la capture du client. */
.gsi-wrap { position: relative; display: flex; flex-direction: column; width: 100%;
  justify-content: center; align-items: stretch; min-height: 40px; }
.gsi-wrap > div { width: 100%; display: flex; justify-content: center; }
/* Le secours ne colle pas au bouton de Google quand les deux sont a l'ecran. */
.gsi-wrap > #gsi-repli { margin-top: 10px; }
/* ECRAN INTERMEDIAIRE SUPPRIME (02/10/2026) : sur la page de connexion Google, le
   bouton est appuye par la page elle-meme, donc il n'a pas a se voir — mais il doit
   rester DANS la page (une case de taille nulle ne se dessine pas, et un element en
   display:none ne se laisse pas appuyer). On le rend donc invisible sans le retirer :
   la transparence ne change pas la mise en page, et « pointer-events: none » empeche
   seulement le doigt du client de le toucher. */
.gsi-wrap.gsi-auto { opacity: 0; pointer-events: none; }
.gsi-ghost { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--slate-200); border-radius: 999px; background: var(--slate-50);
  color: var(--slate-500); font-size: 12px; font-weight: 600; }
/* Etat « Google pas encore configure » : SURTOUT pas en position absolue — la
   classe de chargement ci-dessus s'etale sinon sur toute la page et recouvre le
   formulaire d'inscription. */
.gsi-off { display: block; padding: 12px 14px; text-align: center; border: 1px dashed var(--slate-300);
  border-radius: 999px; background: var(--slate-50); color: var(--slate-500);
  font-size: 12px; font-weight: 600; }
.gsi-sep { display: flex; align-items: center; gap: 10px; color: var(--slate-400); font-size: 12px; }
.gsi-sep::before, .gsi-sep::after { content: ''; height: 1px; flex: 1; background: var(--slate-200); }

/* Illustration de l'attente du SMS dans la modale de paiement (comme la reference). */
.pay-wait { display: flex; align-items: center; justify-content: center; color: var(--brand-600); }
.pay-wait svg { opacity: .85; }
/* Page de suivi du depot (reference : panneau du depot, pastille d'etat en haut).
   Meme forme pour les trois etats finaux, seule la couleur change. */
.dep-suivi .suivi-pastille { width: 64px; height: 64px; margin: 0 auto 16px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; }
.dep-suivi .suivi-pastille.confirme { background: var(--emerald-50); color: var(--emerald-600); }
.dep-suivi .suivi-pastille.non-trouve { background: var(--amber-100); color: var(--amber-600); }
.dep-suivi .suivi-pastille.clos { background: var(--slate-100); color: var(--slate-500); }
.dep-suivi .suivi-pastille.bookmaker { background: var(--brand-100); color: var(--brand-600); }
/* Succes du depot (22/10/2026) : montant en grand, puis le recapitulatif.
   Vert = etat « credite » uniquement. Les trois etapes ont ete retirees le
   22/10/2026 (demande du client) : plus de .suivi-etapes ni de .coche. */
.dep-suivi .suivi-pastille { margin-bottom: 12px; }
.dep-suivi .suivi-montant { font-size: 30px; font-weight: 800; letter-spacing: -.5px;
  line-height: 1.15; margin: 6px 0 8px; color: var(--emerald-600); }
.dep-suivi .suivi-montant + p { max-width: 34ch; margin: 0 auto; }
.paylogo { width: 40px; height: 40px; flex: 0 0 auto; border-radius: 10px; overflow: hidden;
  display: flex; align-items: center; justify-content: center; }
.paylogo img { display: block; width: 100%; height: 100%; object-fit: contain; }
.paylogo.flooz { background: #ffffff; }  /* fond du fichier flooz.png */
.paylogo.mixx { background: #003170; }   /* bleu exact de mixxbyyas.png */

/* Cartes de reseau Mobile Money, disposees comme dans la reference : logo
   au-dessus, nom du reseau et operateur en dessous, sur toute la largeur.
   Le reseau choisi prend la teinte de sa marque (jaune Flooz, bleu ciel Mixx)
   et porte une pastille verte, exactement comme la reference. */
.choice.net { flex-direction: column; align-items: center; text-align: center; gap: 8px;
  padding: 14px 10px; position: relative; }
.choice.net .paylogo { width: 48px; height: 48px; }
.choice.net .pick { position: absolute; right: 8px; top: 8px; width: 20px; height: 20px;
  border-radius: 999px; background: var(--emerald-500); color: #fff; display: flex;
  align-items: center; justify-content: center; }
.choice.net.on-flooz { border-color: transparent; background: var(--amber-50);
  box-shadow: 0 0 0 2px var(--amber-500); }
.choice.net.on-mixx { border-color: transparent; background: var(--sky-50);
  box-shadow: 0 0 0 2px var(--sky-500); }
.choice.net.off { opacity: .55; border-style: dashed; }
.choice.net.off .paylogo { filter: grayscale(.55); }
:root[data-theme="dark"] .choice.net.on-flooz { background: rgba(229, 169, 60, .16); }
:root[data-theme="dark"] .choice.net.on-mixx { background: rgba(14, 165, 233, .16); }
.list-item { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 14px; background: var(--surface); border-bottom: 1px solid var(--slate-100); }
.list-item:last-child { border-bottom: 0; }

/* ---------- historique : une carte PAR operation (01/10/2026) ----------
   Demande du client : « separrer comme tel », capture de la reference a
   l'appui — chaque operation dans SA carte, au lieu d'une seule carte a
   hachures. Squelette de la reference (badges en haut, titre en gras, montant
   a droite, message en rouge), mais nos variables : aucune teinte en dur, donc
   les deux themes suivent tout seuls.

   04/11/2026 — RETOUR A CET HABILLAGE, sur capture du proprietaire (« on
   utilise ca, l'ancien ») : tuile d'icone, bookmaker en titre, « ID joueur :
   ... », « #ref · date », montant a droite. Ont donc ete RETIREES avec les
   variantes qu'elles habillaient : `.hist-pill`, `.hp-*`, `.hist-ref`,
   `.hist-sous`, `.hist-corps`, `.hist-2`, `.hist-recu`, `.hist-recu-lb`,
   `.hist-in`, `.hist-out`. La bande de recu n'existe plus dans la carte ; le
   recu s'ouvre par la fenetre « Details ». Ne PAS remettre ces regles (ni les
   constantes PILL_ETAT / PILL_ICONE d'app.js) sans une demande NEUVE : le
   client a vu les deux etats et a choisi celui-ci. */
.hist-list { display: flex; flex-direction: column; gap: 10px; }
.hist-card { display: flex; align-items: center; gap: 10px; padding: 12px 14px; }
.hist-card[data-act] { cursor: pointer; }
.hist-tete { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.hist-titre { margin-top: 4px; font-size: 15px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hist-ligne { margin-top: 2px; }
.hist-msg { margin-top: 2px; color: var(--rose-600); }
.hist-date { margin-top: 4px; display: flex; align-items: center; gap: 5px; }
.hist-amt { font-variant-numeric: tabular-nums; }
.hist-code { margin-top: 2px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; font-weight: 500; color: var(--slate-500); }
.hist-q { display: flex; align-items: center; gap: 6px; }
.hist-q .input { flex: 1 1 auto; min-width: 0; }

/* ---------- aperçu du reçu : le PAPIER suit le theme ----------
   Le PDF (`recu.py`) reste BLANC : c'est le document qu'on telecharge. L'aperçu
   à l'ecran, lui, prend maintenant la surface et l'encre du theme (05/11/2026 :
   « l'apercu du recu est toujours blanc en mode sombre »). En theme CLAIR le
   rendu est identique au papier d'avant — chaque jeton employe vaut exactement
   la teinte qui etait ecrite en dur (#FFFFFF, #E2E8F0, #0F172A, #64748B,
   #F1F5F9, #94A3B8) ; la nuit, la carte devient sombre au lieu d'un pave blanc
   qui eclaire l'ecran. Aucune couleur litterale ici : tout passe par les jetons,
   sinon le theme ne suivrait pas. */
.recu { background: var(--surface); color: var(--slate-900); border: 1px solid var(--slate-200);
  border-radius: 16px; padding: 18px; margin-top: 10px; text-align: left; }
.recu-hd { text-align: center; border-bottom: 2px solid var(--slate-900); padding-bottom: 12px;
  margin-bottom: 14px; }
.recu-logo { display: block; margin: 0 auto 8px; border-radius: 12px; }
.recu-mq { font-size: 13px; font-weight: 700; letter-spacing: .06em; }
.recu-tt { font-size: 10px; letter-spacing: .18em; color: var(--slate-500); margin-top: 2px; }
.recu-k { font-size: 20px; font-weight: 700; margin-top: 6px; }
.recu-d { font-size: 11px; color: var(--slate-500); margin-top: 3px; }
.recu-amt { background: var(--surface-2); border-radius: 12px; padding: 12px; text-align: center;
  margin-bottom: 12px; }
.recu-amt-lb { font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--slate-500); }
.recu-amt-v { font-size: 26px; font-weight: 700; font-variant-numeric: tabular-nums; margin-top: 2px; }
.recu-st { margin-top: 6px; }
/* Pastille du recu : jetons d'ETAT (la nuit, l'emerald 50 est un fond sombre et
   l'emerald 700 une encre pastel — le couple reste lisible dans les deux). */
.recu-pill { display: inline-block; padding: 3px 10px; border-radius: 999px;
  background: var(--emerald-50); color: var(--emerald-700); font-size: 11px; font-weight: 600; }
.recu-l { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 7px 0; border-bottom: 1px solid var(--slate-100); }
.recu-lb { font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--slate-500); }
.recu-v { font-size: 12px; font-weight: 500; text-align: right; max-width: 60%; word-break: break-word; }
.recu-pied { margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--slate-200);
  text-align: center; font-size: 10px; color: var(--slate-400); }
.tile { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; padding: 14px;
  border-radius: 14px; background: var(--surface); box-shadow: var(--ring); cursor: pointer; border: 0; text-align: left; }
.tile .t-ico { width: 34px; height: 34px; border-radius: 10px; display: flex; align-items: center;
  justify-content: center; background: var(--brand-50); color: var(--brand-600); }
.progress { height: 8px; border-radius: 999px; background: var(--slate-200); overflow: hidden; }
.progress > i { display: block; height: 100%; background: var(--brand-600); border-radius: 999px; }
.empty { text-align: center; padding: 34px 16px; color: var(--slate-500); }
.empty svg { width: 34px; height: 34px; margin-bottom: 8px; color: var(--slate-300); }
.tabs { display: flex; gap: 6px; overflow-x: auto; padding-bottom: 2px; }
.tab { padding: 7px 12px; border-radius: 999px; background: var(--slate-100); color: var(--slate-600);
  font-size: 13px; font-weight: 600; border: 0; cursor: pointer; white-space: nowrap; }
.tab.active { background: var(--brand-600); color: #fff; }
.notice { border-radius: 14px; padding: 12px 14px; display: flex; gap: 10px; align-items: flex-start;
  border: 1px solid var(--slate-200); background: var(--surface); }
.notice.success { background: var(--emerald-50); border-color: var(--emerald-200); }
.notice.warning { background: var(--amber-50); border-color: var(--amber-200); }
.notice.error { background: var(--rose-50); border-color: var(--rose-200); }
.notice.info { background: var(--sky-50); border-color: #BAE6FD; }

/* Bandeau de signalement des credits manuels repetes (AJOUT A NOUS) : alerte
   INTERNE de l'equipe (un meme administrateur credite plusieurs depots sans
   SMS). Rouge, en haut du tableau de bord et en petit dans Depot manuel. Couleurs
   prises aux variables du theme (clair et sombre), jamais en dur. Le bouton
   « Vu » reutilise .btn/.btn-danger. */
.alert-manual { display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap;
  border: 1px solid var(--rose-200); background: var(--rose-50); color: var(--rose-700);
  border-radius: 14px; padding: 14px 16px; margin-bottom: 16px; }
.alert-manual .alert-manual-txt { flex: 1 1 260px; min-width: 0; }
.alert-manual .alert-manual-title { font-weight: 800; letter-spacing: .01em; }
.alert-manual .alert-manual-sub { color: var(--rose-600); font-size: 14px; margin-top: 2px; }
.alert-manual-sm { padding: 10px 12px; margin-bottom: 12px; gap: 10px; }
.alert-manual-sm .alert-manual-title { font-size: 13px; }
.alert-manual-sm .alert-manual-sub { font-size: 13px; }

/* Verification d'identite du joueur : encadre vert avec le nom du compte, comme
   la reference (icone + nom en capitales + ID du joueur, puis la mention). */
.idcheck { display: flex; gap: 12px; align-items: center; border: 1px solid var(--emerald-200);
  background: var(--emerald-50); border-radius: 16px; padding: 14px 16px; }
.idcheck .idc-ico { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 50%; background: rgba(16, 185, 129, .16);
  color: var(--emerald-700); }
.idcheck .idc-name { font-weight: 700; letter-spacing: .02em; color: var(--emerald-800); }
.idcheck .idc-id { color: var(--emerald-700); opacity: .85; }
.ussd { font-family: var(--mono); font-size: 18px; letter-spacing: .08em; background: var(--brand-800);
  color: #fff; padding: 12px 14px; border-radius: 12px; word-break: break-all; }
.code-box { font-family: var(--mono); font-size: 22px; letter-spacing: .3em; text-align: center;
  padding: 14px; border: 2px dashed var(--slate-300); border-radius: 14px; }
.spinner { width: 22px; height: 22px; border-radius: 50%; border: 3px solid var(--slate-200);
  border-top-color: var(--brand-600); animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.center-screen { min-height: 70vh; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 12px; }

/* ---------- toasts ---------- */
#toasts { position: fixed; z-index: 90; left: 0; right: 0; bottom: 96px; display: flex;
  flex-direction: column; align-items: center; gap: 8px; pointer-events: none; padding: 0 12px; }
.toast { background: var(--brand-800); color: #fff; padding: 11px 15px; border-radius: 12px;
  font-size: 14px; font-weight: 500; box-shadow: var(--shadow-lg); max-width: 520px; animation: pop .18s ease; }
.toast.success { background: var(--emerald-700); } .toast.error { background: var(--rose-700); }
.toast.warning { background: var(--amber-600); }
/* NUIT — les bandeaux d'etat prennent un aplat SOMBRE ET SATURE + une encre
   claire. Demande du client (28/10/2026, capture de l'annulation d'un depot) :
   « la couleur du message d'alerte a annulation est trop pale et ca fait mal
   aux yeux ». Cause : la nuit, la famille emerald/rose/amber sert d'ENCRE aux
   badges et aux textes et ses tons 600/700 y sont donc PASTEL (#6EE7B7 vert
   pastel, #FDA4AF, #F0C36A) ; comme .toast.success en fait un FOND avec une
   encre blanche, on obtenait un pave vert clair de deux lignes ou le texte
   tombait a 1,7:1 — illisible et agressif. Les trois aplats d'etat ont donc
   leur propre valeur nocturne, saturee, avec une encre claire a 7:1 mesure.
   Le theme clair et le panneau ne bougent pas : les regles sont bornees a
   data-theme="dark" et ne visent que les toasts. */
:root[data-theme="dark"] .toast.success { background: var(--etat-ok); color: var(--etat-ok-encre); }
:root[data-theme="dark"] .toast.error { background: var(--etat-ko); color: var(--etat-ko-encre); }
:root[data-theme="dark"] .toast.warning { background: var(--etat-att); color: var(--etat-att-encre); }
@keyframes pop { from { transform: translateY(8px); opacity: 0; } }

/* ---------- veille de l'administration : pop-up en HAUT de l'ecran ---------- */
/* Un message client ou une demande de depot/retrait qui arrive s'annonce ici,
   au-dessus de tout, et reste visible une quinzaine de secondes. Le fond suit le
   theme (var(--surface-glass)) : la nuit le pop-up est bleu nuit, pas blanc. */
#alertes { position: fixed; z-index: 96; left: 0; right: 0; display: flex;
  flex-direction: column; align-items: center; gap: 8px; pointer-events: none;
  padding: 0 12px; top: 10px; }
.alerte { pointer-events: auto; width: 100%; max-width: 460px; display: flex; gap: 11px;
  align-items: flex-start; padding: 11px 13px; border-radius: 14px;
  background: var(--surface-glass); backdrop-filter: blur(14px) saturate(1.3);
  border: 1px solid var(--slate-200); border-left: 4px solid var(--brand-600);
  box-shadow: 0 18px 40px -18px rgba(15, 23, 42, .45); animation: fx-alerte .3s var(--fx-ease) both; }
.alerte.sms { border-left-color: var(--sky-500); }
.alerte.dep { border-left-color: var(--emerald-700); }
.alerte.ret { border-left-color: var(--amber-500); }
.alerte .a-ico { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: var(--brand-50); color: var(--brand-600); }
.alerte.sms .a-ico { background: var(--sky-50); color: var(--sky-700); }
.alerte.dep .a-ico { background: var(--emerald-50); color: var(--emerald-700); }
.alerte.ret .a-ico { background: var(--amber-50); color: var(--amber-700); }
.alerte .a-titre { font-size: 13.5px; font-weight: 650; line-height: 1.25; color: var(--slate-900); }
.alerte .a-texte { font-size: 12.5px; color: var(--slate-600); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.alerte .a-quand { font-size: 11px; color: var(--slate-400); margin-top: 3px; }
@keyframes fx-alerte { from { opacity: 0; transform: translateY(-14px) scale(.98); } to { opacity: 1; transform: none; } }

/* Bande « autorise les notifications » du PANNEAU (25/10/2026). Elle paraît UNE
   fois, sous la barre du telephone, et disparait des que le client a tranche.
   Sans cet accord, le navigateur refuse tout bandeau de barre d'etat : c'est la
   seule chose qui manquait pour que le backoffice previenne d'une demande. */
body.admin-app .notif-bandeau {
  position: fixed; z-index: 95; left: 8px; right: 8px;
  top: calc(env(safe-area-inset-top) + 54px);
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border-radius: 14px; background: var(--surface);
  border: 1px solid var(--slate-200); border-left: 4px solid var(--brand-600);
  box-shadow: 0 14px 32px -16px rgba(15, 23, 42, .4);
  animation: fx-alerte .3s var(--fx-ease) both;
}
body.admin-app .notif-bandeau .nb-ico { flex: none; display: inline-flex; color: var(--brand-600); }
body.admin-app .notif-bandeau .nb-t { font-size: 13.5px; font-weight: 700; color: var(--slate-900); }
body.admin-app .notif-bandeau .nb-s { font-size: 12px; color: var(--slate-600); margin-top: 1px; }

/* ---------- admin ---------- */
/* Coquille reprise de la reference (embmoney) : barre laterale de 256 px a
   gauche (marque en haut, menu au milieu, carte de compte + bascule
   clair/sombre en bas), zone de contenu ou vit l'en-tete de page (titre 24 px
   + sous-titre gris 14 px, poses par mountPageHead), et barre du haut reservee
   au TELEPHONE (hamburger, marque, cloche, rond d'initiale).
   L'entree active prend le plein de --brand-600, comme la reference.

   =====================================================================
   COULEURS DU PANNEAU : CELLES DE LA MAISON, ET DEPENDANTES DU THEME
   =====================================================================
   La coquille est celle de la reference, la PALETTE est celle de la maison.
   La coquille SUIT LE THEME, comme le reste du panneau (25/09/2026 : le
   patron travaillait en clair et voyait une barre laterale noire) :
     - MODE CLAIR (defaut, pas de data-theme="dark" sur <html>) : barre
       laterale BLANCHE (var(--surface)) detachee du contenu par une bordure
       droite var(--slate-200) — le contenu est blanc lui aussi ; libelles du
       menu var(--slate-700), icones de la meme couleur, survol
       var(--slate-100), entree ACTIVE = plein de --brand-600, texte blanc,
       avec son ombre propre (0 8px 18px -10px rgba(0,0,0,.9)) ; sous-titre de
       la marque var(--slate-500) ; carte de compte var(--slate-50) bordee
       var(--slate-200), pseudo var(--slate-900), role var(--slate-500) ;
       bouton Deconnexion var(--surface) borde var(--slate-200), texte
       var(--slate-700) ; liens du pied var(--slate-600) sur un filet
       var(--slate-200) ; barre du haut mobile var(--surface), filet bas
       var(--slate-200), icones var(--slate-700) ; barre du bas
       var(--surface-glass) (blanc a 97 %), filet haut var(--slate-200),
       libelles var(--slate-600), trait et icone active var(--brand-600) ;
     - MODE SOMBRE : rendu INCHANGE (barre laterale indigo nuit, textes
       blancs translucides, barre du haut indigo nuit, barre du bas indigo nuit a
       97 %). Tout est regroupe dans le bloc « coquille de l'admin : mode
       sombre » plus bas : il ne reste donc AUCUNE couleur sombre en dur dans
       les regles claires, et la bascule de theme suffit a tout changer.
     - accent : celui de :root, rien a redefinir ici — clair --brand-500
       #0E3867 / --brand-600 #0B2E55, nuit --brand-400 #2F5C93.
   Aucune variable de palette n'est posee sur body.admin-app : le panneau suit
   donc exactement l'accent de l'espace client et de la page d'accueil, en
   clair comme en sombre (mode sombre du panneau = celui de
   :root[data-theme="dark"], nos bleus nocturnes).
   Le FOND DU CONTENU en mode clair est BLANC pur (#fff) et non gris : les
   cartes s'y detachent par leur bordure (--ring, 1 px de --slate-200) et leur
   ombre, qui restent en place ; la nuit, le fond general reprend la main. */
body.admin-app { background: #fff; }
:root[data-theme="dark"] body.admin-app { background: var(--slate-50); }
/* Une fenetre du panneau doit passer AU-DESSUS du tiroir mobile : sur
   telephone la barre laterale est en z-index 60 et son voile en 55, alors que
   les fenetres du projet sont en 50. La confirmation « Fermer la session
   administrateur ? » s'affichait donc DERRIERE le menu ouvert (capture du
   27/09/2026) : on appuyait sur Deconnexion et le menu restait la, ouvert,
   sans qu'aucune fenetre ne se voie. Les toasts (90) et les alertes (96)
   restent au-dessus. */
body.admin-app .modal { z-index: 80; }
.admin-shell { display: flex; min-height: 100vh; }
.admin-side { width: 256px; flex: 0 0 256px; background: var(--surface); color: var(--slate-900);
  border-right: 1px solid var(--slate-200); padding: 16px; position: sticky; top: 0;
  height: 100vh; overflow-y: auto; display: flex; flex-direction: column; }
/* a. marque : logo + nom + « Administration » en petites majuscules espacees */
.admin-side-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px;
  margin-bottom: 32px; }
.admin-side .cx-name { font-size: 17px; color: var(--slate-900); }
.admin-side-sub { font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; color: var(--slate-500); }
/* b. le menu occupe le milieu (le pied, pousse par margin-top:auto, reste en bas) */
.admin-nav { display: flex; flex-direction: column; gap: 4px; }
.admin-side a { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 12px;
  color: var(--slate-700); font-size: 14px; font-weight: 500; }
.admin-side a:hover { background: var(--slate-100); color: var(--slate-900); }
.admin-side a.active { background: var(--brand-600); color: #fff; font-weight: 600;
  box-shadow: 0 8px 18px -10px rgba(0,0,0,.9); }
/* la marque n'est pas une entree de menu : pas de rembourrage ni de survol */
.admin-side a.cx-brand { padding: 0; border-radius: 0; color: var(--slate-900); }
.admin-side a.cx-brand:hover { background: none; }
/* pastille de compteur a droite d'une entree (rond, fond marque, texte blanc) */
.admin-nav-count[hidden] { display: none; }
.admin-nav-count { margin-left: auto; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  background: var(--brand-500); color: #fff; font-size: 11px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center; }
/* demarcation entre les FAMILLES du menu (5 familles, voir `group` dans
   static/js/admin.js) : un trait fin de 1 px, encadre d'un espace de 13 px
   (9 px de marge + les 4 px d'ecart normal des entrees), la ou deux entrees
   voisines ne sont separees que par 4 px. Le trait suit la couleur des
   bordures du projet : --slate-200 en clair, --slate-300 la nuit (la barre
   laterale passe alors sur --night). */
.admin-nav-sep { display: block; height: 1px; flex: 0 0 auto;
  background: var(--slate-200); margin: 9px 6px; }
:root[data-theme="dark"] .admin-nav-sep { background: var(--slate-300); }
/* c. pied de la barre : carte de compte, puis bascule et retour au site */
.admin-foot { margin-top: auto; padding-top: 16px; display: flex; flex-direction: column; gap: 12px; }
.admin-acc { background: var(--slate-50); border: 1px solid var(--slate-200);
  border-radius: 12px; padding: 12px; }
.admin-acc-top { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; min-width: 0; }
.admin-acc-avatar { width: 32px; height: 32px; border-radius: 50%; flex: 0 0 auto; background: var(--brand-600);
  color: #fff; font-weight: 800; font-size: 14px; display: inline-flex; align-items: center;
  justify-content: center; }
.admin-acc-name { font-size: 14px; font-weight: 700; color: var(--slate-900); }
.admin-acc-role { font-size: 11px; color: var(--slate-500); text-transform: uppercase;
  letter-spacing: .06em; }
.admin-acc-out { width: 100%; justify-content: center; background: var(--surface);
  color: var(--slate-700); border: 1px solid var(--slate-200); }
.admin-foot-links { display: flex; flex-direction: column; gap: 2px;
  border-top: 1px solid var(--slate-200); padding-top: 10px; }
/* liens du pied (Mode sombre / Notifications / Retour au site) : plus discrets
   que les entrees du menu ; leur version nuit est dans le bloc sombre plus bas */
.admin-foot-links a { color: var(--slate-600); }
/* PLUS DE BARRE DE NAVIGATION EN BAS (retiree le 28/09/2026, demande du client).
   Sur telephone, la navigation passe par le hamburger de la barre du haut, qui
   ouvre la barre laterale complete : une seule liste d'entrees a tenir a jour,
   et plus de 84 px reserves en bas de chaque ecran. */
/* voile de la barre laterale : mobile uniquement. Fond noir translucide a
   70 % + flou de 4 px (corrige un vrai bug : la regle de base pose
   « display: none » et la media query ne le relevait pas, le contenu restait
   donc eclatant derriere le tiroir ouvert) ; un appui dessus le referme. */
.admin-back { display: none; }
.admin-back[hidden] { display: none; }
.admin-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
/* l'en-tete de page vit DANS le contenu (titre 24 px, sous-titre gris 14 px) */
.page-head { margin-bottom: 24px; }
.page-head-title { font-size: 24px; font-weight: 600; letter-spacing: -.02em; color: var(--slate-900);
  margin: 0 0 4px; }
.page-head-sub { font-size: 14px; color: var(--slate-500); margin: 0; }
.admin-body { padding: 32px; }
/* barre du haut : TELEPHONE uniquement (voir la media query plus bas) */
.admin-topbar { display: none; }
.admin-topbar-name { font-size: 17px; font-weight: 800; color: var(--slate-900); }
.admin-topbar .cx-logo { width: 34px; height: 34px; border-radius: 10px; }
.admin-topbar .cx-ico { color: var(--slate-700); }
.admin-topbar .cx-ico:hover { background: var(--slate-100); color: var(--slate-900); }
/* =====================================================================
   COQUILLE DE L'ADMIN : MODE SOMBRE (rendu INCHANGE)
   Tout ce qui etait pose en dur (barre laterale indigo nuit, textes
   blancs translucides, barre du haut indigo nuit, barre du bas indigo nuit a
   97 %) est regroupe ICI. Les regles claires ci-dessus n'en gardent aucune
   trace : il suffit de poser data-theme="dark" sur <html> pour repasser
   toute la coquille en bleu nuit. La disposition (256 px, media queries)
   n'est pas touchee.
   ===================================================================== */
:root[data-theme="dark"] .admin-side { background: var(--night); color: #fff;
  border-right-color: rgba(255,255,255,.08); }
:root[data-theme="dark"] .admin-side .cx-name,
:root[data-theme="dark"] .admin-side a.cx-brand { color: #fff; }
:root[data-theme="dark"] .admin-side-sub { color: rgba(255,255,255,.55); }
:root[data-theme="dark"] .admin-side a { color: rgba(255,255,255,.72); }
:root[data-theme="dark"] .admin-side a:hover { background: rgba(255,255,255,.08); color: #fff; }
/* l'entree active garde son texte BLANC plein (plus clair que le repos) */
:root[data-theme="dark"] .admin-side a.active { color: #fff; }
/* la marque n'a jamais de pave de survol, en clair comme la nuit */
:root[data-theme="dark"] .admin-side a.cx-brand:hover { background: none; }
:root[data-theme="dark"] .admin-acc { background: rgba(255,255,255,.06);
  border-color: rgba(255,255,255,.10); }
:root[data-theme="dark"] .admin-acc-name { color: #fff; }
:root[data-theme="dark"] .admin-acc-role { color: rgba(255,255,255,.55); }
:root[data-theme="dark"] .admin-acc-out { background: rgba(255,255,255,.10); color: #fff; border: 0; }
:root[data-theme="dark"] .admin-foot-links { border-top-color: rgba(255,255,255,.10); }
:root[data-theme="dark"] .admin-foot-links a { color: rgba(255,255,255,.72); }
:root[data-theme="dark"] .admin-topbar { background: var(--night); color: #fff;
  border-bottom-color: rgba(255,255,255,.08); }
:root[data-theme="dark"] .admin-topbar-name { color: #fff; }
:root[data-theme="dark"] .admin-topbar .cx-ico { color: rgba(255,255,255,.82); }
:root[data-theme="dark"] .admin-topbar .cx-ico:hover { background: rgba(255,255,255,.10); color: #fff; }
.mobile-only { display: none; }
.bars { display: flex; align-items: flex-end; gap: 3px; height: 120px; }
.bars .b { flex: 1 1 0; background: var(--brand-500); border-radius: 4px 4px 0 0; min-height: 2px; opacity: .9; }
.chart-legend { display: flex; gap: 14px; font-size: 12px; color: var(--slate-600); }

/* ---------- landing (theme clair, accents bleu fonce) ---------- */
body.landing { background: var(--dark-bg); color: var(--dark-text); }
.landing-nav { position: sticky; top: 0; z-index: 30; background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(10px); border-bottom: 1px solid var(--dark-3); }
.landing-nav .container { display: flex; align-items: center; justify-content: space-between;
  height: 64px; gap: 16px; }
.landing-nav a { color: var(--dark-muted); font-size: 14px; font-weight: 500; }
.landing-nav a:hover { color: var(--brand-700); }
.landing-links { display: flex; gap: 22px; }
.badge-pill { display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: 999px;
  background: var(--brand-50); border: 1px solid var(--brand-200); color: var(--brand-700);
  font-size: 12px; font-weight: 600; }
.hero { padding: 56px 0 48px;
  background: radial-gradient(1000px 420px at 78% -10%, rgba(31, 111, 191, .10), transparent 70%); }
.hero h1 { font-size: clamp(30px, 6vw, 52px); font-weight: 800; letter-spacing: -.03em; color: var(--dark-text); }
.hero h1 em { font-style: normal; color: var(--brand-600); }
.hero p.lead { color: var(--dark-muted); font-size: 17px; max-width: 560px; margin: 18px 0 24px; }
.btn-landing { display: inline-flex; align-items: center; gap: 10px; padding: 14px 22px; border-radius: 12px;
  background: linear-gradient(135deg, var(--brand-600), var(--brand-700)); color: #fff;
  font-weight: 700; box-shadow: 0 16px 40px -18px rgba(31, 111, 191, .75); border: 0; cursor: pointer; }
.stats-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px;
  margin-top: 40px; max-width: 560px; }
.stats-row .s { border-left: 2px solid var(--brand-600); padding-left: 12px; }
.stats-row .s b { display: block; font-size: 24px; font-weight: 800; color: var(--brand-700); }
.stats-row .s span { color: var(--dark-muted); font-size: 12px; }
.phone-mock { width: 100%; max-width: 320px; margin-left: auto; background: linear-gradient(160deg, var(--brand-700), var(--brand-900));
  border: 1px solid var(--brand-700); border-radius: 30px; padding: 14px; box-shadow: var(--shadow-lg); }
.phone-mock .screen { background: var(--surface); border-radius: 22px; padding: 14px; color: var(--slate-900); }
.phone-mock .bal { font-size: 26px; font-weight: 800; color: var(--brand-700); }
.pm-row { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 12px; border-radius: 12px; background: var(--slate-50); border: 1px solid var(--slate-200);
  margin-top: 8px; font-size: 13px; }
.pm-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 12px; }
.pm-actions .b { text-align: center; padding: 12px; border-radius: 12px; font-weight: 700; }
.pm-actions .b.r { background: linear-gradient(135deg, var(--brand-600), var(--brand-700)); color: #fff; }
.pm-actions .b.g { border: 1px solid var(--slate-300); color: var(--brand-700); }
.section { padding: 64px 0; border-top: 1px solid var(--dark-3); }
.section-head { text-align: center; max-width: 640px; margin: 0 auto 40px; }
.section-head .eyebrow { color: var(--brand-600); font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; }
.section-head h2 { font-size: clamp(24px, 4vw, 34px); margin: 12px 0 10px; letter-spacing: -.02em; color: var(--dark-text); }
.section-head p { color: var(--dark-muted); }
.feat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; }
.feat { background: var(--surface); border: 1px solid var(--dark-3); border-radius: var(--radius);
  padding: 22px; transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease; }
.feat:hover { border-color: var(--brand-300); transform: translateY(-2px); box-shadow: var(--shadow); }
.feat .fi { width: 42px; height: 42px; border-radius: 12px; background: var(--brand-50);
  color: var(--brand-600); display: flex; align-items: center; justify-content: center; margin-bottom: 14px; }
.feat h3 { font-size: 17px; margin-bottom: 8px; color: var(--dark-text); }
.feat p { color: var(--dark-muted); font-size: 14px; margin: 0; }
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 18px; }
.step { background: var(--dark-1); border: 1px solid var(--dark-3); border-radius: var(--radius); padding: 20px; }
.step .n { width: 34px; height: 34px; border-radius: 50%; background: linear-gradient(135deg, var(--brand-600),
  var(--brand-700)); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 800; margin-bottom: 12px; }
.step h3 { color: var(--dark-text); }
.step p { color: var(--dark-muted); font-size: 14px; }
.quote { background: var(--surface); border: 1px solid var(--dark-3); border-radius: var(--radius); padding: 22px; }
.quote .stars { color: #F2A20C; letter-spacing: 2px; margin-bottom: 10px; }
.quote p { font-style: italic; color: var(--slate-700); }
.quote .who { margin-top: 14px; font-size: 13px; color: var(--dark-muted); }
.faq-item { border: 1px solid var(--dark-3); border-radius: 14px; background: var(--surface);
  margin-bottom: 12px; overflow: hidden; }
.faq-q { width: 100%; text-align: left; background: none; border: 0; color: var(--dark-text); padding: 18px;
  font-weight: 600; font-size: 15px; display: flex; justify-content: space-between; gap: 12px; cursor: pointer; }
.faq-a { padding: 0 18px; max-height: 0; overflow: hidden; color: var(--dark-muted);
  transition: max-height .25s ease, padding .25s ease; font-size: 14px; }
.faq-item.open .faq-a { max-height: 420px; padding: 0 18px 18px; }
.dl-band { background: linear-gradient(135deg, var(--brand-50), var(--surface));
  border: 1px solid var(--brand-200); border-radius: var(--radius-lg); padding: 34px; text-align: center; }
.dl-band h2 { color: var(--dark-text); }
.landing-footer { border-top: 1px solid var(--dark-3); padding: 34px 0; color: var(--dark-muted); font-size: 13px; }
.landing-footer a { color: var(--dark-muted); } .landing-footer a:hover { color: var(--brand-700); }

/* ---------- responsive ---------- */
@media (max-width: 900px) {
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .admin-side { position: fixed; left: 0; top: 0; z-index: 60; transform: translateX(-104%);
    transition: transform .22s ease; box-shadow: var(--shadow-lg); }
  .admin-side.open { transform: none; }
  /* voile : fond noir translucide a 70 % + flou de 4 px ; un appui en dehors
     de la barre la referme. Il n'etait jamais affiche : la regle de base pose
     « display: none » et la media query ne le relevait pas, donc le contenu
     restait eclatant derriere le tiroir ouvert. */
  .admin-back { display: block; position: fixed; inset: 0; z-index: 55;
    background: rgba(4, 4, 5, .7);
    backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); }
  .admin-back[hidden] { display: none; }
  /* sur telephone, la barre du haut reprend son role : fond du theme
     (blanc en clair, indigo nuit la nuit — voir le bloc sombre plus
     haut) ; hamburger + marque + cloche + rond d'initiale */
  .admin-topbar { display: flex; align-items: center; justify-content: space-between; gap: 10px;
    position: sticky; top: 0; z-index: 40; background: var(--surface); color: var(--slate-900);
    border-bottom: 1px solid var(--slate-200);
    padding: calc(10px + env(safe-area-inset-top)) 14px 10px; }
  /* La barre du bas n'existe plus : le contenu descend jusqu'au bord, avec
     seulement de quoi ne pas passer SOUS la barre de gestes du telephone. */
  .admin-body { padding: 16px; padding-bottom: calc(16px + env(safe-area-inset-bottom)); }
  .page-head { margin-bottom: 20px; }
  .mobile-only { display: inline-flex; }
  .desk-only { display: none; }
}
@media (max-width: 640px) {
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hide-sm { display: none; }
  .hero { padding: 34px 0; }
  .section { padding: 44px 0; }
}

/* ---------- iPad et grands ecrans : aligner la coquille cliente -------------
   Sur un iPad, la barre du bas etait fixe de bord a bord : les six entrees
   partaient dans les coins, tres loin du contenu qui, lui, reste dans une
   colonne de 720 px. L'en-tete passait sous la barre d'etat (heure et batterie
   affichees par-dessus la page) et debordait de 16 px de chaque cote par rapport
   aux cartes (colonne de 720 px, padding a l'exterieur).
   Trois corrections, et rien qui change sur telephone (<= 720 px) :
     1. barre du bas, en-tete et cartes partagent EXACTEMENT les memes bords
        (688 px = 720 - 2 x 16) ;
     2. panneau du compte ancre sur le bord droit des cartes, pas du telephone ;
     3. en-tete et colonne reservent la barre d'etat (env(safe-area-inset-*)).
   Sur telephone, aucun changement : la barre reste pleine largeur. */
@media (min-width: 721px) {
  /* .colonne : 720 px moins 16 px de chaque cote = les cartes de .app-shell */
  /* +40 px : sur iPad, la bande translucide du systeme descend plus bas que la
     barre d'etat (mesure du 25/09/2026 : un texte a 27 px du haut sort a
     191/255 de gris — lave — alors qu'un bord net a 74 px est intact ; l'inset
     ne vaut que ~36 px). On place donc le contenu a ~76 px du haut. */
  .topbar {
    padding-left: 0; padding-right: 0;
    padding-top: calc(40px + env(safe-area-inset-top));
  }
  .cx-top {
    padding-left: calc(16px + env(safe-area-inset-left));
    padding-right: calc(16px + env(safe-area-inset-right));
  }
  .app-shell {
    padding-left: calc(16px + env(safe-area-inset-left));
    padding-right: calc(16px + env(safe-area-inset-right));
  }
  .bottomnav {
    left: 50%; right: auto; margin-left: -344px; width: 688px;
    max-width: calc(100% - 32px); border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    /* sur ordinateur la barre est bornee : elle garde son bord haut arrondi et son
       trait fin — le telephone fait desormais pareil (30/09/2026). */
    border-top: 1px solid var(--slate-200);
    padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right);
  }
  /* panneau du compte : bord droit aligne sur celui des cartes (420 px de large,
     donc bord gauche a 420 - 344 = 76 px a gauche du centre). Le haut suit
     l'en-tete : inset + 40 px de marge + 60 px de haut d'en-tete + 2 px. */
  .cx-acc { top: calc(102px + env(safe-area-inset-top)); left: 50%; right: auto;
    width: 420px; max-width: 100%; margin-left: -76px; }
  /* panneau lateral : sa marque descend au meme niveau que celle de l'en-tete
     de l'appli (40 px sous la barre d'etat), au lieu de coller au bord. */
  .sd-head { padding-top: 40px; }
}

/* ---------- tableau de bord sur telephone : des cartes separees --------------
   Chaque chiffre devient une petite carte ARRONDIE, bordee, avec un petit espace
   entre elles : les champs sont separes et se lisent un par un (la version bureau
   garde ses gros paves). Rien ne change sur ordinateur. */
@media (max-width: 700px) {
  .kpi-grid { display: block; }
  /* Chaque champ : carte arrondie, fond legerement teinte (pour la detacher du
     fond de page), bordure franche et un peu plus d'air entre elles. */
  .kpi-grid .kpi { background: var(--brand-50); box-shadow: 0 0 0 1px var(--slate-300);
    border-radius: 14px; padding: 12px 14px; margin-bottom: 13px; display: grid;
    grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; column-gap: 12px; }
  .kpi-grid .kpi:last-child { margin-bottom: 0; }
  .kpi-grid .kpi .k-label { grid-column: 1; font-size: 12px; line-height: 1.3; }
  .kpi-grid .kpi .k-value { grid-column: 2; text-align: right; font-size: 19px; margin-top: 0;
    white-space: nowrap; }
  .kpi-grid .kpi .k-sub { grid-column: 1 / -1; font-size: 12px; margin-top: 4px; }
  /* la carte mise en avant : meme forme, bordure de marque */
  .kpi-grid .kpi.highlight { box-shadow: 0 0 0 2px var(--brand-500); }
  .tabs.dash-tabs { overflow-x: auto; -webkit-overflow-scrolling: touch; flex-wrap: nowrap; }
  /* En-tete du tableau de bord : les filtres et le bouton sur UNE ligne (le
     bouton passait a la ligne, la periode en dessous : trois lignes avant le
     premier chiffre). Les filtres defilent, le bouton reste au bout. */
  .dash-head { flex-wrap: nowrap; gap: 8px; }
  .dash-head .dash-tabs { flex: 1 1 auto; min-width: 0; }
  .dash-head .btn { flex: 0 0 auto; padding: 8px 10px; }
  .dash-head .tab { padding: 7px 11px; font-size: 12.5px; white-space: nowrap; }
  /* En-tete de l'admin sur telephone : la barre sombre reste compacte (icones
     plus serrees) et le titre de page, dans le contenu, redescend un peu, pour
     que les titres longs ne poussent rien hors de l'ecran. */
  .admin-topbar { padding: calc(8px + env(safe-area-inset-top)) 12px 8px; }
  .admin-topbar .cx-actions { gap: 2px; }
  .admin-topbar .cx-ico { width: 34px; height: 34px; border-radius: 10px; }
  .admin-topbar .cx-avatar { width: 34px; height: 34px; font-size: 15px; }
  .admin-topbar-name { font-size: 16px; }
  .page-head-title { font-size: 21px; }
}

/* =====================================================================
   ESPACE CLIENT — alignement sur la reference (ref-client-emb.md) :
   carte sombre (fond bleu nuit) de l'accueil et du portefeuille, et
   badges de statut colores (bleu, indigo, ambre, gris, orange, violet,
   rose, emeraude, marque) utilises par l'historique.
   ===================================================================== */
.hero-dark { background: linear-gradient(150deg, var(--brand-900), var(--night) 62%); }
.badge-sky { background: var(--sky-50); color: var(--sky-700); }
.badge-indigo { background: var(--violet-50); color: var(--violet-700); }
.badge-amber { background: var(--amber-100); color: var(--amber-800); }
.badge-slate { background: var(--slate-100); color: var(--slate-600); }
.badge-orange { background: var(--amber-50); color: var(--amber-700); }
.badge-violet { background: var(--violet-50); color: var(--violet-700); }
.badge-rose { background: var(--rose-50); color: var(--rose-700); }
.badge-emerald { background: var(--emerald-50); color: var(--emerald-700); }
.badge-brand { background: var(--brand-50); color: var(--brand-700); }

/* =====================================================================
   CIRCUITS DEPOT / RETRAIT — barre d'etapes et blocs repliables
   (reference : « Pays & bookmaker … Confirmation », « Comment faire ? »).
   ===================================================================== */
/* Adresse du point de vente (etape « Bookmaker » du retrait) : c'est ce que le
   joueur recopie dans SON application bookmaker pour generer son code. Bloc de
   la reference — titre en petites majuscules precedees d'une punaise, puis les
   lignes Rue / Ville — dans nos couleurs (le fond et la bordure viennent de
   .soft et .hairline, deja utilises par le panneau). */
.pdv { display: grid; gap: 6px; }
.pdv-t { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--slate-600); }
.pdv-t svg { flex: 0 0 auto; }
.pdv-l { font-size: 13px; color: var(--slate-900); }
.pdv-k { color: var(--slate-600); }
.pdv-v { font-weight: 700; }
/* Barre des etapes, presentee EXACTEMENT comme la reference : cercles relies par
   un trait, libelle SOUS chaque cercle. L'etape faite est une pastille pleine
   avec une coche blanche ; l'etape en cours est un cercle blanc avec un anneau
   de la couleur de la marque et un halo doux, son libelle en gras. Reparties
   equitablement, les cinq tiennent sur un ecran etroit. */
.stepbar { display: flex; align-items: flex-start; padding: 6px 0 14px; }
.stepbar .s { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center;
  gap: 6px; position: relative; color: var(--slate-400); font-size: 12px; font-weight: 600; }
.stepbar .s::before { content: ''; position: absolute; top: 13px; left: -50%; width: 100%;
  height: 3px; border-radius: 2px; background: var(--slate-200); }
.stepbar .s:first-child::before { display: none; }
.stepbar .s .n { width: 28px; height: 28px; border-radius: 50%; background: var(--surface);
  color: var(--slate-400); border: 2px solid var(--slate-200); display: inline-flex;
  align-items: center; justify-content: center; font-size: 12px; font-weight: 700;
  position: relative; z-index: 1; }
.stepbar .s .lb { font-size: 12px; line-height: 1.15; text-align: center; }
.stepbar .s.done .n { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }
.stepbar .s.done::before { background: var(--brand-600); }
.stepbar .s.on .n { border-color: var(--brand-600); color: var(--brand-700);
  box-shadow: 0 0 0 4px var(--brand-50); }
.stepbar .s.on .lb { color: var(--slate-900); font-weight: 700; }
.stepbar .s.on { color: var(--brand-700); }
.stepbar .s.on .n { background: var(--brand-600); color: #fff; }
.stepbar .s.done { color: var(--emerald-700); }
.stepbar .s.done .n { background: var(--emerald-600); color: #fff; }
.fold { border: 1px solid var(--slate-200); border-radius: 14px; background: var(--surface); }
.fold > summary { cursor: pointer; padding: 12px 14px; font-weight: 600; font-size: 14px; display: flex;
  align-items: center; justify-content: space-between; gap: 10px; list-style: none; }
.fold > summary::-webkit-details-marker { display: none; }
.fold[open] > summary { border-bottom: 1px solid var(--slate-100); }
.fold-bd { padding: 12px 14px; }
/* pastille cliquable (IDs joueurs enregistres) */
.pill { border: 0; cursor: pointer; font: inherit; }

/* =====================================================================
   ACCUEIL CLIENT — reproduction de la capture de reference (EMB Money)
   avec nos couleurs : l'indigo de la marque remplace leur rouge.
   Fond blanc bleute, en-tete clair, carte hero sombre, deux gros ronds
   Depot / Retrait, bloc reseaux sociaux, barre du bas a 6 entrees avec un
   bouton WhatsApp rond flottant au centre.
   ===================================================================== */
:root { --hero-id: #A6E3D1; }              /* pseudo affiche sur la carte sombre */
:root[data-theme="dark"] { --hero-id: #55C4A1; }

/* fond de page de l'espace client : blanc bleute tres clair (pas de blanc pur) */
body.client-app { background: var(--brand-50); }
:root[data-theme="dark"] body.client-app { background: var(--slate-50); }

/* ---------- en-tete : logo, marque, cloche + pastille, initiale ---------- */
.cx-top { max-width: 720px; margin: 0 auto; display: flex; align-items: center;
  justify-content: space-between; gap: 10px; }
/* EN-TETE DE L'ESPACE CLIENT (12/11/2026, prompt : « menu hamburger a gauche »
   puis logo + titre + sous-titre). Trois zones : le menu, la marque au MILIEU,
   les commandes a droite. En grille pour que la marque reste centree quelle que
   soit la largeur des deux autres (en flex, elle glissait vers la droite).
   La barre du VISITEUR garde la disposition souple : elle n'a pas de menu. */
/* 12/11/2026 — sans le rond du menu a gauche, la marque reprend la place : deux
   colonnes (marque a gauche, commandes a droite) au lieu de trois. */
body.client-app .cx-top { display: grid; grid-template-columns: minmax(0, 1fr) auto; }
body.client-app .cx-brand { justify-self: start; }
body.client-app .cx-brand { justify-self: center; min-width: 0; }
/* 12/11/2026 — MAQUETTE : un ROND GRIS a gauche (menu) et un ROND BLANC a droite
   (reglages), la marque au centre. Les deux font 46 px : c'est la cible tactile
   de la maquette, et les deux ronds s'alignent exactement sur la marque. */
/* .cx-burger RETIRE de l'en-tete le 12/11/2026 (« enleve les 3 traits en haut »).
   La regle reste ecrite, dormante : la remettre = rappeler le bouton. */
body.client-app .cx-gear {
  width: 46px; height: 46px; border-radius: 50%; flex: 0 0 auto;
  display: grid; place-items: center; cursor: pointer;
  background: var(--surface); color: var(--slate-700);
  border: 1px solid var(--cx-cerne); box-shadow: var(--cx-flat);
}
body.client-app .cx-gear:active { background: var(--slate-100); }
.cx-brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.cx-logo { width: 40px; height: 40px; border-radius: 12px; flex: 0 0 auto; overflow: hidden;
  background: var(--brand-800); display: flex; align-items: center; justify-content: center; }
.cx-logo img { width: 100%; height: 100%; object-fit: cover; }
.cx-name { font-size: 19px; font-weight: 800; letter-spacing: -.02em; color: var(--slate-900);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cx-actions { display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }
.cx-ico { position: relative; width: 36px; height: 36px; border-radius: 999px; border: 0; cursor: pointer;
  background: transparent; color: var(--slate-700); display: inline-flex; align-items: center;
  justify-content: center; }
.cx-ico:hover { background: var(--brand-100); }
/* pastille rouge du nombre de notifications non lues (masquee si vide) */
.cx-count { position: absolute; top: -1px; right: -1px; min-width: 19px; height: 19px; padding: 0 5px;
  border-radius: 999px; background: var(--rose-600); color: #fff; font-size: 12px; font-weight: 700;
  line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
.cx-count:empty { display: none; }
/* rond plein avec l'initiale du pseudo, cliquable vers « Mon compte » */
.cx-avatar { width: 38px; height: 38px; border-radius: 50%; background: var(--brand-600); color: #fff;
  font-weight: 800; font-size: 17px; display: inline-flex; align-items: center; justify-content: center;
  /* 10/11/2026 : le bouton d'avatar n'avait JAMAIS perdu son cerne 3D natif —
     visible sur la capture du client comme un arc sombre a droite du rond bleu. */
  border: 0; padding: 0; flex: 0 0 auto; }

/* ---------- carte hero sombre ---------- */
.cx-hero { position: relative; overflow: hidden; border-radius: var(--radius-lg); padding: 18px;
  color: #fff; background: linear-gradient(150deg, var(--brand-900), var(--night) 62%);
  box-shadow: 0 22px 50px -26px rgba(15, 23, 42, .8); }
/* halo de lumiere colore derriere la carte (comme la reference) */
.cx-hero::after { content: ''; position: absolute; top: -45%; right: -18%; width: 250px; height: 250px;
  border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(78, 123, 184, .5), transparent 68%); }
:root[data-theme="dark"] .cx-hero { background: linear-gradient(150deg, #1B2E4E, #101B31 66%);
  box-shadow: 0 22px 50px -30px #000, 0 0 0 1px var(--slate-200); }
:root[data-theme="dark"] .cx-hero::after {
  background: radial-gradient(circle, rgba(147, 197, 253, .38), transparent 68%); }
/* pastille arrondie bordee : nom de la marque */
.cx-pill { position: relative; z-index: 1; display: inline-flex; align-items: center; padding: 5px 14px;
  border-radius: 999px; border: 1px solid rgba(255, 255, 255, .3); background: rgba(255, 255, 255, .07);
  font-size: 13px; font-weight: 600; }
.cx-hello-row { position: relative; z-index: 1; display: flex; align-items: center;
  justify-content: space-between; gap: 12px; margin-top: 14px; }
.cx-hello { font-size: 22px; font-weight: 800; letter-spacing: -.02em; min-width: 0; overflow-wrap: anywhere; }
.cx-hello b { color: var(--hero-id); }
/* bouton carre blanc arrondi : copier le nom d'utilisateur */
.cx-copy { flex: 0 0 auto; width: 46px; height: 46px; border-radius: 14px; border: 0; cursor: pointer;
  background: #fff; color: var(--slate-900); display: inline-flex; align-items: center;
  justify-content: center; }
.cx-copy:hover { filter: brightness(.95); }
/* La nuit, ce carre blanc devenait la source la plus lumineuse de l'ecran, et son
   icone disparaissait : `--slate-900` passe au blanc casse en mode sombre, donc le
   dessin se noyait dans le fond blanc. Meme forme, meme taille, meme place — on le
   pose en verre translucide, comme la pastille de la marque juste au-dessus. */
:root[data-theme="dark"] .cx-copy { background: rgba(255, 255, 255, .12); color: #E8F1FF;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .28); }
:root[data-theme="dark"] .cx-copy:hover { background: rgba(255, 255, 255, .2);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .4); filter: none; }
/* grand bouton vert WhatsApp (couleur officielle #25D366) */

/* ---------- (les deux ANCIENNES tuiles Depot / Retrait ont disparu le
   30/09/2026 : elles sont devenues les deux cartes `.cx-acts` / `.cx-act` plus
   bas. Les regles `.cx-rounds` / `.cx-round` / `.cx-round-cir` / `.cx-round-lb`
   ont ete retirees le meme jour, pour ne pas laisser deux dispositions
   concurrentes dans la feuille.) ---------- */

/* ---------- accueil : la question et les deux cartes d'action (30/09/2026) ----
   Squelette repris de l'interface envoyee par le client ce jour-la : la carte du
   haut pose la question (« Que voulez-vous faire ? »), puis Depot et Retrait sont
   deux CARTES cote a cote, entierement teintees, avec leur pastille d'icone
   ronde, leur libelle et leur sous-titre ; la ligne « Messages » vient juste
   dessous. Les COULEURS sont celles de la maison, mais BLEU CLAIR / VERT CLAIR
   depuis le 30/09/2026 (demande du client : « couleur bleu clair pour le depot et
   vert clair pour le bouton retrait », apres un premier passage VERT / ROUGE) : le
   depot prend un bleu clair, le retrait le VERT que le client a envoye le 13/10/2026
   (mesure #35C036) — et le bleu est choisi pour S'ACCORDER a ce vert. Les jetons
   --act-dep-* / --act-wd-* sont declares dans :root
   et FIGES (jamais redefinis la nuit) : en clair les deux cartes portent leur
   teinte pleine et une encre blanche, mesures par ui_check 9quinquies. */
.cx-ask { position: relative; z-index: 1; margin-top: 14px; font-size: 26px; font-weight: 800;
  letter-spacing: -.03em; line-height: 1.12; }
.cx-ask-sub { position: relative; z-index: 1; margin-top: 8px; font-size: 13.5px; opacity: .8; }

.cx-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 20px; }
.cx-act { position: relative; display: flex; flex-direction: column; gap: 4px;
  padding: 14px 14px 16px; border-radius: var(--radius-lg); overflow: hidden;
  color: #fff; text-decoration: none; box-shadow: var(--shadow);
  transition: transform .18s var(--fx-ease, ease), box-shadow .18s var(--fx-ease, ease); }
.cx-act-ico { width: 42px; height: 42px; border-radius: 999px; margin-bottom: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .18); }
.cx-act-t { font-size: 19px; font-weight: 800; letter-spacing: -.02em; }
.cx-act-s { font-size: 12.5px; opacity: .88; }
.cx-act-dep { background: linear-gradient(160deg, var(--act-dep-1), var(--act-dep-2)); }
.cx-act-wd { background: linear-gradient(160deg, var(--act-wd-1), var(--act-wd-2)); }
.cx-act-dep .cx-act-s, .cx-act-wd .cx-act-s { opacity: .9; }
.cx-act:hover { box-shadow: var(--shadow-lg); }
.cx-act:active { transform: scale(.98); }

/* la ligne « Messages » : pastille sombre, titre, sous-titre, chevron */
.cx-msg { display: flex; align-items: center; gap: 13px; margin-top: 12px; padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--slate-200); border-radius: var(--radius);
  box-shadow: var(--shadow); color: inherit; text-decoration: none; }
/* La pastille de la ligne « Messages » de l'accueil : ICONE DE LA MARQUE (bleu),
   et non plus l'or des etats (demande du client, 30/09/2026 : « changer l icone de
   la messagerie de depot en bleu »). Teinte claire + encre bleue en clair (9,8:1),
   teinte nuit + bleu clair la nuit (5,1:1) : les deux sont mesurees par ui_check
   9quinquies, donc remettre l'or fait rougir. */
.cx-msg-ico { flex: 0 0 auto; width: 42px; height: 42px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--brand-50); color: var(--brand-600); }
.cx-msg-txt { display: flex; flex-direction: column; min-width: 0; }
.cx-msg-t { font-size: 15.5px; font-weight: 700; }
.cx-msg-s { font-size: 12.5px; color: var(--slate-500); }
.cx-msg-go { margin-left: auto; display: inline-flex; color: var(--slate-400); }
:root[data-theme="dark"] .cx-msg { border-color: var(--slate-200); }
:root[data-theme="dark"] .cx-msg-ico { background: var(--brand-50); color: var(--brand-400); }

/* ---------- accueil : le suivi en direct (30/09/2026) ------------------------
   Repris du bloc « suivi en direct » de la reference : le type et le montant de
   l'operation, sa reference, son badge d'etat, les trois temps Envoyee / Prise en
   charge / Terminee et le mot du moment (recherche d'un caissier, nom du caissier
   qui traite, ou resultat). Palette de la maison uniquement. */
.cx-suivi { position: relative; margin-top: 14px; padding: 14px; background: var(--surface);
  border: 1px solid var(--slate-200); border-radius: var(--radius-lg); box-shadow: var(--shadow); }
.cx-suivi-hd { display: flex; align-items: center; gap: 11px; }
.cx-suivi-ico { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 12px; display: inline-flex;
  align-items: center; justify-content: center; background: var(--brand-50); color: var(--brand-600); }
.cx-suivi-t { display: block; font-size: 15.5px; font-weight: 700; }
.cx-suivi-ref { display: block; font-size: 12px; color: var(--slate-500); }
.cx-steps { display: flex; align-items: flex-start; margin-top: 14px; }
.cx-step { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.cx-step-rond { width: 26px; height: 26px; border-radius: 999px; display: inline-flex; align-items: center;
  justify-content: center; font-size: 12px; font-weight: 700; background: var(--slate-100);
  color: var(--slate-500); box-shadow: inset 0 0 0 1px var(--slate-200); }
.cx-step.fait .cx-step-rond { background: var(--brand-600); color: #fff; box-shadow: none; }
.cx-step.encours .cx-step-rond { background: var(--surface); color: var(--brand-600);
  box-shadow: inset 0 0 0 2px var(--brand-500); }
.cx-step.ko .cx-step-rond { background: var(--rose-50); color: var(--rose-600);
  box-shadow: inset 0 0 0 1px var(--rose-200); }
.cx-step-lb { font-size: 12px; color: var(--slate-500); text-align: center; }
.cx-step.fait .cx-step-lb, .cx-step.encours .cx-step-lb { color: var(--slate-900); font-weight: 600; }
/* le trait entre deux pastilles : pose a hauteur du CENTRE de la pastille (13 px
   moins la demi-epaisseur du trait) */
.cx-step-lien { flex: 1 1 auto; height: 2px; margin: 12px 6px 0; background: var(--slate-200); }
.cx-step-lien.fait { background: var(--brand-500); }
.cx-suivi-msg { display: flex; align-items: center; gap: 8px; margin-top: 12px;
  font-size: 12.5px; color: var(--slate-600); }
.cx-suivi.ok .cx-suivi-msg { color: var(--emerald-700); }
.cx-suivi.ko .cx-suivi-msg { color: var(--rose-700); }
.cx-suivi-go { display: inline-flex; align-items: center; gap: 6px; margin-top: 12px; padding: 9px 14px;
  border-radius: 999px; font-size: 13px; font-weight: 600; text-decoration: none;
  color: var(--brand-600); background: var(--brand-50); }
:root[data-theme="dark"] .cx-suivi-go { color: var(--brand-300); }
/* Le bouton qui FERME la demande de suivi (30/09/2026, demande du client) : meme
   famille visuelle que le bouton de copie de la carte du haut (gris clair en clair,
   voile blanc la nuit), en plus petit. */
.cx-suivi-x { flex: 0 0 auto; width: 30px; height: 30px; padding: 0; border: 0; cursor: pointer;
  border-radius: 999px; background: var(--slate-100); color: var(--slate-500);
  display: inline-flex; align-items: center; justify-content: center; }
.cx-suivi-x:hover { background: var(--slate-200); color: var(--slate-900); }
.cx-suivi-x:active { transform: scale(.94); }
:root[data-theme="dark"] .cx-suivi-x { background: rgba(255, 255, 255, .12); color: #E8F1FF; }
:root[data-theme="dark"] .cx-suivi-x:hover { background: rgba(255, 255, 255, .2); }
body.client-app .cx-suivi-x { border-radius: var(--cx-r-sm); }

/* ---------- raccourcis de l'accueil (28/09/2026) -----------------------------
   « Mes IDs » et « Historique » ENCADRENT la paire de tuiles Depot/Retrait :
   une pilule au-dessus, une pilule en dessous, chacune centree. Elles sont
   posees sur les memes fondations que les cartes (verre : fond translucide,
   flou, cerne 1 px, ombre teintee de la marque) pour ne pas jurer avec elles.
   Le lien pointe sur la MEME route que la barre du bas (#/players, #/history) :
   deux chemins vers le meme ecran, pas deux ecrans. */
.cx-racc { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.cx-racc-haut { margin-top: 20px; }
.cx-racc-bas { margin-top: 22px; }
.cx-racc-a { display: inline-flex; align-items: center; gap: 8px; padding: 9px 16px;
  border-radius: 999px; font: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--slate-700); background-color: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border); box-shadow: var(--shadow); }
.cx-racc-a svg { color: var(--brand-600); }
.cx-racc-a:active { transform: scale(.96); }

/* ---------- reseaux sociaux ---------- */
.cx-social { margin-top: 28px; text-align: center; }
.cx-social-t { font-size: 14px; color: var(--slate-500); }
.cx-social-row { display: flex; justify-content: center; gap: 20px; margin-top: 14px; }
/* Ronds des reseaux SANS logo (WhatsApp, Telegram, Facebook, Instagram) :
   la lettre prend la couleur de la marque sur le fond du rond. Le TikTok garde
   son SVG. */
.cx-soc-l { font-weight: 700; font-size: 20px; color: var(--brand-600, #0B2E55); }
/* Bandeau « Telechargez l'application » de l'accueil. */
.cx-app { display: flex; align-items: center; gap: 12px; margin: 0 0 12px;
  padding: 12px 14px; border-radius: 16px; background: var(--surface);
  box-shadow: var(--shadow-1, 0 2px 10px rgba(15, 30, 60, .08)); }
.cx-app-ico { width: 40px; height: 40px; flex: 0 0 40px; border-radius: 12px;
  display: grid; place-items: center; background: var(--brand-50, #eaf0f9);
  color: var(--brand-600, #0B2E55); }
.cx-app-txt { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.cx-app-txt b { font-size: 14px; }
.cx-app-txt small { font-size: 12px; color: var(--slate-500); }
.cx-app-btn { flex: 0 0 auto; padding: 9px 14px; border-radius: 12px;
  background: var(--brand-600, #0B2E55); color: #fff; font-size: 13px;
  font-weight: 600; text-decoration: none; }
/* Phrase du bloc code promo (reglage promo_text). */
.cx-promo-txt2 { font-size: 12px; color: var(--slate-500); padding: 2px 2px 0; }
.cx-soc { width: 54px; height: 54px; border-radius: 50%; background: var(--surface);
  border: 1px solid var(--slate-200); display: flex; align-items: center; justify-content: center;
  color: var(--slate-900); box-shadow: var(--shadow); }

/* Le libelle de la PILULE (30/09/2026) : une seule ligne, jamais coupee. Sa
   taille suit celle de l'entree (13,5 px, posee plus haut). Le petit trait de la
   marque au-dessus de l'entree active a disparu : la pilule teintee suffit. */
.bottomnav .item span { letter-spacing: -.02em; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --------------------------------------------- panneau du compte (avatar)
   Feuille ancree en haut a droite, ouverte par le rond d'initiale : infos du
   compte, entrees secondaires, puis « Deconnexion » — comme la reference. */
.cx-acc-back { position: fixed; inset: 0; background: rgba(30, 64, 175, .34); z-index: 70; }
.cx-acc-back[hidden] { display: none; }
/* Panneau du compte, REDUIT et ancre au cote droit (maquette du 27/09/2026) : il
   ne couvre plus toute la largeur, l'ecran reste visible derriere a gauche.
   `left: auto` + une largeur en pourcentage le collent au bord droit. */
.cx-acc { position: fixed; z-index: 71; top: 68px; right: 10px; left: auto;
  width: min(58%, 330px);
  background: var(--surface); color: inherit; border-radius: var(--radius-lg);
  box-shadow: 0 22px 55px -18px rgba(30, 64, 175, .55); overflow: hidden;
  animation: cxAccIn .16s ease-out; }
.cx-acc[hidden] { display: none; }
@keyframes cxAccIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }
.cx-acc-head { padding: 12px 15px 11px; border-bottom: 1px solid var(--slate-100); }
.cx-acc-row { display: flex; align-items: center; gap: 10px; width: 100%; padding: 13px 15px;
  background: none; border: 0; text-align: left; cursor: pointer;
  font: inherit; font-size: 14px; color: inherit; }
/* un libelle long (« Conditions d'utilisation ») ne doit pas deborder du panneau
   etroit : il se coupe proprement. */
.cx-acc-row span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cx-acc-row svg { flex: none; }
.cx-acc-row + .cx-acc-row { border-top: 1px solid var(--slate-100); }
.cx-acc-row:active { background: var(--brand-50); }
.cx-acc-row.danger { color: var(--rose-600); }
.cx-acc-sep { height: 8px; background: var(--slate-50); border-top: 1px solid var(--slate-100); }
/* Mode sombre : --slate-50 vaut #000 ; le separateur devenait une bande noire
   au-dessus de « Deconnexion ». On prend la couleur du panneau (ecart invisible). */
:root[data-theme="dark"] .cx-acc-sep { background: var(--slate-100); }
/* Mode sombre : le voile bleu (prevu pour le jour) teintait l'ecran de bleu nuit.
   Un voile noir garde la meme lisibilite et s'accorde avec le fond sombre. */
:root[data-theme="dark"] .cx-acc-back { background: rgba(0, 0, 0, .62); }

/* ==========================================================================
   Tchat (modele Telegram, 26/09/2026)
   La carte sombre du haut de l'accueil est l'entree du chat (nom du service,
   « En ligne » + point vert, apercu du dernier message, compteur de non lus).
   L'ecran de discussion suit Telegram : en-tete en pastille (fleche retour,
   avatar, nom, statut), pastille de jour, messages recus en blanc a gauche,
   messages envoyes en vert pale a droite avec l'heure et les deux coches,
   barre du bas en pastille (smiley, « Message », trombone) et rond bleu qui
   enregistre un message vocal. Les couleurs vivent dans des variables pour que
   le mode sombre les reprenne (fond sombre, bulles sombres).
   ========================================================================== */
.cx-chat { display: block; color: #fff; }
.cx-chat-top { position: relative; z-index: 1; display: flex; align-items: center; gap: 10px; }
.cx-chat-nom { font-size: 17px; font-weight: 800; letter-spacing: -.01em; }
.cx-chat-nb { margin-left: auto; min-width: 22px; height: 22px; padding: 0 7px; border-radius: 999px;
  background: #fff; color: var(--brand-900); font-size: 12px; font-weight: 800;
  display: inline-flex; align-items: center; justify-content: center; }
.cx-chat-statut { position: relative; z-index: 1; display: flex; align-items: center; gap: 6px;
  margin-top: 5px; font-size: 12.5px; color: #9AA9C0; }
.cx-chat-bas { position: relative; z-index: 1; display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.cx-chat-apercu { flex: 1; min-width: 0; font-size: 13.5px; color: #C9D6E8;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cx-chat-heure { flex: none; font-size: 11.5px; color: #8296B2; }

/* pastille verte « En ligne » : carte de l'accueil et en-tete du tchat */
.tg-point { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--emerald-500);
  box-shadow: 0 0 0 3px rgba(16, 185, 129, .18); }

.tg { position: fixed; inset: 0; z-index: 60; display: flex; flex-direction: column;
  color: var(--tg-encre); background: var(--tg-fond);
  /* palette Telegram : vert clair (le theme de Serge) et, en mode sombre, la
     palette Telegram sombre. Les motifs du papier peint sont dessines ici
     (le dessin d'origine de Telegram n'est pas copie). */
  /* Fond BLANC du chat du support (demande du 27/09/2026). Le degrade vert du
     papier peint Telegram est retire ; les teintes ci-dessous sont recalees pour
     se detacher sur blanc (une bulle blanche sur fond blanc disparaitrait). */
  --tg-fond: #FFFFFF;
  --tg-pastille: rgba(15, 23, 42, .05);
  --tg-encre: #16261F;
  --tg-recu: #F2F4F7;
  --tg-envoi: #E9FBC9;
  --tg-meta: #5B6B66;   /* assombri : sur fond blanc, le gris precedent ne tenait pas 4.5:1 */
  /* L'accent du tchat est celui de la MARQUE : l'ancien bleu de la messagerie
     jurait avec le reste du site. `--tg-accent-bg` est son aplat pale. */
  --tg-accent: var(--brand-600);
  --tg-accent-bg: rgba(31, 111, 191, .12);
  --tg-saisie: #F2F4F7;
  --tg-clavier: #F1F5F4;
  --tg-valide: #4FC15F; }
:root[data-theme="dark"] .tg {
  /* 28/10/2026 — « couleur du chat different en mode sombre » : le chat gardait
     sa palette BLEU NUIT a lui (fond #101924 mesure sur la capture du client)
     alors que le reste de l'application etait passe au noir neutre. Il suit
     maintenant le meme noir releve, sans teinte : fond #101010 -> #161616 ->
     #101010, bulle recue #242424, encre #ECECEC, secondaires #A6A6A6. Seule la
     bulle ENVOYEE reste bleue : c'est l'accent de la marque, comme les boutons. */
  --tg-fond: linear-gradient(168deg, #121212, #181818 55%, #121212);
  --tg-pastille: rgba(255,255,255,.09);
  --tg-encre: #F5F5F5;
  --tg-recu: #1C1C1C;
  --tg-envoi: #2B5278;
  --tg-meta: #A3A3A3;
  --tg-accent: var(--brand-400);
  --tg-accent-bg: rgba(111, 163, 232, .16);
  --tg-saisie: rgba(255,255,255,.07);
  --tg-clavier: #131E29; }
/* Le fond de la discussion est UNI, comme la maquette du 27/09/2026 : le papier
   peint a motifs de Telegram (data-URL ci-dessous, conserve juste apres) est
   simplement desactive en supprimant la regle qui suit. */
.tg::before { display: none; }

/* ---- en-tete : bande de la marque, rond du retour, titre en blanc, menu ---- */
/* Demande du 27/09/2026 : la barre du haut passe en BLEU et « Support » s'ecrit
   en BLANC. La bande est pleine largeur. La barre d'etat du telephone, elle, est
   portee par la reserve claire decrite ci-dessus (correction du 27/09/2026) : la
   couleur de l'en-tete ne monte donc plus jusqu'en haut de l'ecran. */
/* ---- bande de la barre d'etat, AU-DESSUS de l'en-tete ---------------------
   La bande du haut (heure, batterie) est peinte avec le FOND DU TCHAT (blanc en
   clair), et non avec le bleu de l'en-tete. Raison (capture de Serge du
   27/09/2026, « le haut du tchat est flou et blanc ») : sur iPad en mode
   application, la barre d'etat du systeme est une bande translucide qui FLoute
   et eclaircit ce qu'elle recouvre ; peinte sur le bleu, elle le lavait et le
   haut du tchat paraissait blanchi, avec une transition floue. Sous un fond
   clair, une bande claire ne se voit plus : le bleu commence donc SOUS la bande.
   La reserve de 40 px sur grand ecran reprend la mesure du 25/09/2026 (la bande
   du systeme descend jusqu'a ~76 px du haut de l'ecran alors que l'inset ne vaut
   que ~36 px). Sur telephone (<= 720 px, inset a 0 dans un onglet) : rien ne
   change, la barre bleue reste collee en haut. */
.tg { padding-top: env(safe-area-inset-top); }
@media (min-width: 721px) { .tg { padding-top: calc(env(safe-area-inset-top) + 40px); } }

.tg-head { flex: none; display: flex; align-items: center; gap: 8px;
  padding: 8px 10px 10px;
  background: var(--brand-600); color: #fff; }
/* Ronds de l'en-tete : BLANC FRANC et bords nets (demande du 27/09/2026 : ils
   paraissaient flous et laiteux). Le verre depoli (backdrop-filter) et l'ombre
   large sont retires : un rond opaque sur le bleu, avec une ombre courte, se
   detache nettement. Le blanc vient de --on-brand (le blanc pose sur la marque),
   donc aucune couleur en dur. */
.tg-back, .tg-rond-blanc { flex: none; width: 46px; height: 46px; border: 0; border-radius: 50%;
  cursor: pointer; display: grid; place-items: center; background: var(--tg-pastille);
  color: var(--tg-encre); box-shadow: 0 1px 3px rgba(8,24,47,.3); }
.tg-back { background: var(--on-brand); color: #16261F; }
.tg-back svg { transform: rotate(180deg); }
:root[data-theme="dark"] .tg-back { background: rgba(255,255,255,.14); color: var(--tg-encre); }
.tg-back:active, .tg-rond-blanc:active { transform: scale(.94); }
.tg-pill { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; height: 46px;
  padding: 0 14px 0 4px; border-radius: 999px; background: var(--tg-pastille);
  backdrop-filter: blur(12px); box-shadow: 0 6px 20px rgba(12,40,30,.16); }
.tg-avatar { flex: none; width: 38px; height: 38px; border-radius: 50%; overflow: hidden;
  background: var(--brand-600); display: grid; place-items: center; }
.tg-avatar img { width: 100%; height: 100%; object-fit: cover; }
.tg-qui { min-width: 0; display: flex; flex-direction: column; }
.tg-nom { font-size: 16px; font-weight: 700; line-height: 1.15;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tg-statut { display: flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--tg-encre);
  opacity: .7; }

/* ---- ecran de support : en-tete fleche + titre + menu ---------------------
   Maquette du 27/09/2026 : l'en-tete ne porte plus la pastille Telegram mais le
   seul titre de l'ecran. La bande bleue de marque (« Support / L'equipe repond
   ici des que possible. ») a ete supprimee le 27/09/2026 : son bouton de menu
   est remonte dans l'en-tete, a droite du titre, sur la meme pastille ronde que
   la fleche de retour. */
.tg-titre { flex: 1; min-width: 0; font-size: 19px; font-weight: 800; color: #fff;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Meme traitement que la fleche de retour : blanc franc, ombre courte, sans
   verre depoli — les deux ronds doivent avoir exactement le meme aspect. */
.tg-head-plus { flex: none; width: 46px; height: 46px; border: 0; border-radius: 50%;
  cursor: pointer; display: grid; place-items: center;
  background: var(--on-brand); color: #16261F;
  box-shadow: 0 1px 3px rgba(8,24,47,.3); }
:root[data-theme="dark"] .tg-head-plus { background: rgba(255,255,255,.14); color: var(--tg-encre); }
.tg-head-plus:active { transform: scale(.94); }

/* min-height: 0 est INDISPENSABLE : sans lui, un enfant de colonne flex refuse de
   se reduire sous la taille de son contenu. Quand le clavier monte, le fil poussait
   alors la barre hors de l'ecran au lieu de se reduire et de rester sur le dernier
   message (bug constate le 26/09). */
.tg-fil { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 6px; padding: 2px 10px 10px; }
.tg-jour { display: flex; justify-content: center; margin: 6px 0 2px; }
.tg-jour span { background: var(--slate-100); color: var(--slate-600); font-size: 12px;
  font-weight: 600; padding: 4px 11px; border-radius: 999px; }
:root[data-theme="dark"] .tg-jour span { background: rgba(255,255,255,.1); color: var(--tg-encre); }

.tg-ligne { display: flex; }
.tg-ligne.them { justify-content: flex-start; }
.tg-ligne.me { justify-content: flex-end; }
.tg-ligne.tg-suite { margin-top: -3px; }
.tg-bulle { position: relative; max-width: 82%; padding: 6px 10px 5px; border-radius: 14px;
  background: var(--tg-recu); color: var(--tg-encre); box-shadow: 0 1px 2px rgba(12,40,30,.14); }
.tg-ligne.me .tg-bulle { background: var(--tg-envoi); }
.tg-ligne.them .tg-bulle { border-top-left-radius: 6px; }
.tg-ligne.me .tg-bulle { border-top-right-radius: 6px; }
.tg-texte { font-size: 14.5px; line-height: 1.35; overflow-wrap: anywhere; white-space: pre-wrap; }
.tg-meta { float: right; display: inline-flex; align-items: center; gap: 2px;
  margin: 6px 0 0 10px; font-size: 12px; color: var(--tg-meta); }
.tg-meta svg { width: 14px; height: 14px; }
.tg-meta svg { color: var(--tg-meta); }
.tg-meta.tg-lu svg { color: var(--tg-valide); }
.tg-modif { font-style: italic; opacity: .8; margin-right: 3px; }

/* emoji seul : en grand, sans bulle, l'heure en dessous a droite (Telegram) */
.tg-emoji-seul { display: flex; flex-direction: column; align-items: flex-end;
  max-width: 78%; font-size: 42px; line-height: 1.08; overflow-wrap: anywhere; }
.tg-emoji-seul .tg-meta { float: none; margin: 2px 0 0; }
.tg-emoji-seul .tg-meta svg { color: var(--tg-valide); }

/* RANGEE D'ACTIONS VISIBLE sous un message (09/10/2026, reference client de
   Serge) : les memes actions que la feuille d'appui long, mais sous les yeux —
   repondre partout, modifier et supprimer sur mes messages. Possee du COTE DU
   MILIEU comme la reference : a DROITE d'un message recu, a GAUCHE d'un message
   envoye (le JS pose la rangee avant ou apres la bulle selon l'auteur). Petits
   ronds gris, la corbeille en rouge : des variables du theme, donc lisibles en
   mode nuit. */
.tg-ligne { align-items: flex-end; gap: 3px; }
.tg-acts { display: flex; align-items: center; gap: 1px; padding-bottom: 1px; }
.tg-act { width: 27px; height: 27px; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: var(--slate-400); cursor: pointer;
  display: grid; place-items: center; }
.tg-act:hover { background: var(--slate-100); color: var(--slate-600); }
.tg-act:active { transform: scale(.92); }
.tg-act.danger { color: var(--rose-500); }
.tg-act.danger:hover { background: rgba(244, 63, 94, .10); color: var(--rose-600); }
:root[data-theme="dark"] .tg-act { color: var(--slate-500); }
:root[data-theme="dark"] .tg-act:hover { background: rgba(255, 255, 255, .10); color: var(--tg-encre); }
:root[data-theme="dark"] .tg-act.danger { color: var(--rose-500); }

/* citation (« Repondre ») : barre coloree + nom + texte, comme Telegram.
   Demande du 27/09/2026 : la BANDE LATERALE (le trait a gauche du message cite)
   etait verte dans les messages envoyes — elle passe au bleu de la marque, comme
   celle des messages recus : l'identite du site est bleue. */
.tg-cite { display: flex; flex-direction: column; gap: 1px; margin-bottom: 5px; padding: 4px 9px;
  border-left: 3px solid var(--tg-accent); border-radius: 5px; background: var(--tg-accent-bg); }
.tg-cite b { font-size: 12.5px; font-weight: 700; }
.tg-cite span { font-size: 13px; opacity: .86; max-width: 230px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tg-ligne.them .tg-cite { border-left-color: var(--brand-500); background: rgba(23,136,103,.12); }
.tg-ligne.them .tg-cite b { color: var(--brand-600); }
.tg-ligne.me .tg-cite { border-left-color: var(--brand-500); background: rgba(23,136,103,.12); }
.tg-ligne.me .tg-cite b { color: var(--brand-600); }
:root[data-theme="dark"] .tg-ligne.them .tg-cite b { color: #9EC5F5; }
:root[data-theme="dark"] .tg-ligne.me .tg-cite b { color: #9EC5F5; }
:root[data-theme="dark"] .tg-ligne.them .tg-cite,
:root[data-theme="dark"] .tg-ligne.me .tg-cite { border-left-color: var(--brand-400);
  background: rgba(111,163,232,.16); }

.tg-copier { margin-top: 6px; display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  border: 0; border-radius: 8px; padding: 5px 9px; font: inherit; font-size: 12.5px; font-weight: 600;
  background: var(--tg-accent-bg); color: #1D6FA5; }
:root[data-theme="dark"] .tg-copier { color: #7CC4F5; }
.tg-valeur { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-weight: 700; }

/* message vocal : bouton d'ecoute, avancement, duree */
.tg-audio { display: flex; align-items: center; gap: 9px; min-width: 186px; }
.tg-play { flex: none; width: 40px; height: 40px; border: 0; border-radius: 50%; cursor: pointer;
  background: var(--tg-saisie); color: var(--tg-accent); display: grid; place-items: center; }
.tg-ligne.me .tg-play { background: rgba(255,255,255,.55); }
.tg-ligne.them .tg-play { background: var(--tg-accent-bg); }
/* forme d'onde : des barres plutot qu'un trait (comme Telegram) */
.tg-piste { flex: 1; display: flex; align-items: center; gap: 2px; height: 22px; }
.tg-barre { width: 2px; border-radius: 2px; background: currentColor; opacity: .28; }
.tg-barre.on { opacity: .85; }
.tg-duree { flex: none; font-size: 12px; color: var(--tg-meta); font-variant-numeric: tabular-nums; }
.tg-bulle-audio { padding-top: 8px; padding-bottom: 8px; }

.tg-vide { flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 24px 26px; text-align: center; font-size: 15px; color: var(--slate-500); }

/* pastille « aller au dernier message », au-dessus de la barre (Telegram) */
.tg-descendre { position: absolute; right: 12px; bottom: calc(78px + env(safe-area-inset-bottom));
  z-index: 2; width: 44px; height: 44px; border: 0; border-radius: 50%; cursor: pointer;
  background: var(--tg-saisie); color: var(--tg-encre); display: grid; place-items: center;
  box-shadow: 0 4px 16px rgba(12,40,30,.22); }

/* panneau d'emojis : onglets en icones, recherche, pave, onglets du bas et
   touche effacer (modele : le panneau de Telegram montre par Serge) */
/* Le panneau d'emojis se deploie a la place du clavier : colle au bas de
   l'ecran, toute la largeur, coins arrondis en haut (comme sur la capture de
   Telegram montree par Serge). Il est place APRES la barre dans le gabarit. */
.tg-emoji { position: relative; z-index: 4; flex: none; margin: 0;
  padding: 6px 10px calc(6px + env(safe-area-inset-bottom));
  border-radius: 16px 16px 0 0; background: var(--tg-clavier);
  box-shadow: 0 -6px 22px rgba(12,40,30,.22); }
/* panneau ouvert : la barre se recolle dessus et perd ses ombres */
.tg-panneau .tg-bar { padding-bottom: 6px; }
.tg-panneau .tg-saisie, .tg-panneau .tg-rond { box-shadow: none; }
.tg-cats { display: flex; gap: 2px; overflow-x: auto; padding: 2px 0 6px;
  border-bottom: 1px solid rgba(127,127,127,.18); }
.tg-cat { flex: none; width: 38px; height: 30px; border: 0; border-radius: 9px; cursor: pointer;
  background: transparent; color: var(--tg-meta); display: grid; place-items: center; }
.tg-cat.on { color: var(--tg-accent); background: var(--tg-accent-bg); }
.tg-cherche { display: flex; align-items: center; gap: 8px; margin: 8px 0 6px; padding: 0 12px;
  height: 38px; border-radius: 999px; background: rgba(127,127,127,.12); color: var(--tg-meta); }
.tg-cherche input { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--tg-encre);
  font: inherit; font-size: 14.5px; outline: none; }
.tg-emos { display: flex; flex-wrap: wrap; gap: 1px; max-height: 212px; overflow-y: auto; padding: 2px 0; }
.tg-emo { border: 0; background: transparent; font-size: 25px; line-height: 1.15; padding: 3px 6px;
  cursor: pointer; border-radius: 10px; }
.tg-emo:active { background: rgba(127,127,127,.18); }
.tg-emo-grand { font-size: 34px; padding: 2px 5px; }
.tg-emo-vide { padding: 14px 8px; font-size: 13.5px; color: var(--tg-meta); text-align: center; }
.tg-onglets { display: flex; align-items: center; gap: 4px; padding: 4px 0 2px;
  border-top: 1px solid rgba(127,127,127,.18); }
.tg-onglet { flex: 1; height: 34px; border: 0; border-radius: 10px; cursor: pointer;
  background: transparent; color: var(--tg-meta); font: inherit; font-size: 13.5px; font-weight: 600; }
.tg-onglet.on { color: var(--tg-accent); background: var(--tg-accent-bg); }
.tg-effacer { flex: none; width: 42px; height: 34px; border: 0; border-radius: 10px; cursor: pointer;
  background: transparent; color: var(--tg-meta); display: grid; place-items: center; }

/* citation en cours de redaction, au-dessus du champ */
.tg-citation { display: flex; align-items: center; gap: 8px; margin: 0 10px 6px;
  padding: 6px 8px 6px 10px; border-radius: 12px; background: var(--tg-saisie); }
.tg-citation .tg-cite { flex: 1; min-width: 0; margin: 0; }

.tg-bar { flex: none; display: flex; align-items: center;
  padding: 7px 10px calc(9px + env(safe-area-inset-bottom)); }
/* Un element marque hidden doit RESTER cache : une regle comme
   « .tg-rec { display: flex } » ecrase le [hidden] du navigateur (bug vu le
   26/09 : la barre d'enregistrement s'affichait en permanence). */
.tg [hidden] { display: none !important; }
.tg-saisie { flex: 1; min-width: 0; height: 54px; border-radius: 999px; display: flex;
  align-items: center; gap: 4px; padding: 0 6px 0 18px; background: var(--tg-saisie);
  box-shadow: 0 3px 14px rgba(12,40,30,.18); }
/* barre d'enregistrement : une ligne d'aide, puis corbeille, forme d'onde en
   direct, chrono et Pause — la disposition de WhatsApp, montree par Serge */
.tg-rec { position: relative; flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px;
  padding: 5px 10px 6px; border-radius: 20px; background: var(--tg-saisie);
  box-shadow: 0 3px 14px rgba(12,40,30,.18); }
/* repere du glissement : la fleche et le cadenas montent avec le doigt */
/* Il flotte AU-DESSUS de la barre : place a l'interieur, il passait sous le
   bouton Pause et ne se voyait pas (constate le 26/09). */
.tg-rec-glisse { position: absolute; right: 18px; bottom: calc(100% + 5px); display: flex;
  flex-direction: column; align-items: center; gap: 0; padding: 4px 7px 5px; border-radius: 14px;
  background: var(--tg-clavier); box-shadow: 0 4px 14px rgba(12,40,30,.26);
  color: var(--tg-accent); opacity: 0; pointer-events: none; transition: opacity .12s linear; }
/* barre en message d'explication (micro refuse par exemple) */
.tg-rec-blocage { background: rgba(225,29,72,.16); }
.tg-rec-blocage .tg-rec-aide { color: var(--tg-encre); white-space: normal; }
.tg-rec-glisse svg { display: block; }
.tg-rec-glisse .tg-glisse-chev svg { transform: rotate(180deg); }
.tg-glisse-cad { display: block; }   /* cadenas du panneau de glissement */
.tg-rec-poubelle { transition: transform .1s ease-out, color .1s linear; }
.tg-rec-ligne { display: flex; align-items: center; gap: 10px; height: 34px; }
.tg-ico { flex: none; width: 38px; height: 38px; border: 0; border-radius: 50%; cursor: pointer;
  background: transparent; color: #6E7C8C; display: grid; place-items: center; }
:root[data-theme="dark"] .tg-ico { color: #93A3B3; }
.tg-champ { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--tg-encre);
  font: inherit; font-size: 15.5px; outline: none; }
.tg-champ::placeholder { color: var(--tg-meta); }
/* le rond bleu est PLUS GROS que la barre et chevauche la pastille (capture) */
.tg-rond { flex: none; width: 56px; height: 56px; margin-left: 8px; border: 0; border-radius: 50%;
  cursor: pointer; background: var(--brand-600); color: #fff; display: grid; place-items: center;
  box-shadow: 0 10px 22px -8px rgba(31, 111, 191, .65); }
.tg-rond:active { transform: scale(.95); }
.tg-rec-onde { flex: 1; min-width: 0; display: flex; align-items: center; gap: 2px; height: 28px;
  overflow: hidden; color: var(--rose-600); }
.tg-rec-onde i { flex: none; width: 3px; height: 3px; border-radius: 2px; background: currentColor;
  opacity: .8; transition: height .09s linear; }
.tg-rec-pause { flex: none; display: flex; align-items: center; gap: 5px; height: 30px; padding: 0 10px;
  border: 0; border-radius: 999px; cursor: pointer; background: rgba(127,127,127,.16);
  color: var(--tg-encre); font: inherit; font-size: 12.5px; font-weight: 600; }
.tg-rec-pause-on { background: var(--tg-accent-bg); color: var(--tg-accent); }
/* appui long : le rond passe au rouge, et l'aide annonce l'annulation */
.tg-rond-rec { background: var(--rose-600); box-shadow: 0 5px 16px rgba(225,29,72,.45); }
.tg-rec-aide { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--tg-meta);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tg-rec.tg-annule { background: rgba(225,29,72,.16); }
.tg-rec.tg-annule .tg-rec-poubelle { color: var(--rose-600); transform: scale(1.45); }
.tg-rec.tg-annule .tg-rec-time { opacity: .45; }
.tg-rec-poubelle { transition: transform .12s ease-out, color .12s linear; }
.tg-rec.tg-verrou { background: var(--tg-accent-bg); }
.tg-rec-cadenas { flex: none; color: var(--tg-accent); display: grid; place-items: center;
  animation: tgCadenas .26s ease-out; }

/* ---- appareil photo integre (apercu en direct, comme WhatsApp) ------------ */
.tg-appareil { position: absolute; inset: 0; z-index: 6; display: flex; flex-direction: column;
  background: #0B0F14; }
.tg-appareil[hidden] { display: none; }
.tg-ap-haut { position: absolute; top: calc(10px + env(safe-area-inset-top)); left: 12px; right: 12px;
  display: flex; justify-content: space-between; z-index: 2; }
.tg-ap-rond { width: 44px; height: 44px; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(20,26,34,.62); color: #fff; display: grid; place-items: center; }
.tg-ap-rond.on { background: #F0C64A; color: #1A1A1A; }
/* L'apercu REMPLIT l'ecran (26/09 : Serge ne veut pas des bandes noires). Le
   recadrage reste modere parce que le flux est demande en vraie resolution. */
.tg-ap-video { flex: 1; min-height: 0; width: 100%; object-fit: cover; background: #000; }
.tg-ap-prises { flex: none; display: flex; align-items: center; justify-content: space-between;
  padding: 14px 22px 6px; background: #0B0F14; }
.tg-ap-mini { width: 48px; height: 48px; border: 0; border-radius: 14px; cursor: pointer;
  background: rgba(255,255,255,.12); color: #fff; display: grid; place-items: center; }
.tg-ap-prise { width: 74px; height: 74px; border: 4px solid #fff; border-radius: 50%; cursor: pointer;
  background: transparent; display: grid; place-items: center; }
.tg-ap-prise span { display: block; width: 56px; height: 56px; border-radius: 50%; background: #fff; }
.tg-ap-prise-rec span { border-radius: 12px; background: var(--rose-600); }
.tg-ap-onglets { flex: none; display: flex; justify-content: center; gap: 10px;
  padding: 6px 0 calc(12px + env(safe-area-inset-bottom)); background: #0B0F14; }
.tg-ap-onglet { border: 0; border-radius: 999px; cursor: pointer; background: transparent;
  color: #C6D2DE; font: inherit; font-size: 14px; font-weight: 600; padding: 7px 16px; }
.tg-ap-onglet.on { background: rgba(255,255,255,.16); color: #fff; }
.tg-ap-chrono { position: absolute; top: calc(16px + env(safe-area-inset-top)); left: 50%;
  transform: translateX(-50%); color: #fff; font-size: 14px; font-variant-numeric: tabular-nums;
  background: rgba(20,26,34,.62); padding: 4px 12px; border-radius: 999px; z-index: 2; }
.tg-ap-chrono[hidden] { display: none; }
/* bulle d'une note video dans le fil */
.tg-video { display: flex; align-items: center; gap: 10px; border: 0; cursor: pointer;
  background: var(--tg-accent-bg); color: var(--tg-accent); border-radius: 12px; padding: 12px 18px; }
.tg-video span { font-size: 13px; font-variant-numeric: tabular-nums; color: var(--tg-encre); }
.tg-vue video { max-width: 96%; max-height: 84%; border-radius: 10px; background: #000; }

/* ---- gestes de l'appui long : mouvements (places avant la section dediee) ---- */
@keyframes tgPulse { 0% { transform: scale(1); } 45% { transform: scale(1.13); } 100% { transform: scale(1); } }
@keyframes tgOnde { 0% { box-shadow: 0 0 0 0 rgba(225,29,72,.5); }
  100% { box-shadow: 0 0 0 15px rgba(225,29,72,0); } }
@keyframes tgPoint { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .3; transform: scale(.75); } }
@keyframes tgCadenas { 0% { transform: translateY(9px) scale(.7); opacity: 0; }
  100% { transform: translateY(0) scale(1); opacity: 1; } }
@keyframes tgCran { 0% { transform: scale(1); } 45% { transform: scale(1.3); } 100% { transform: scale(1); } }
/* au franchissement du seuil, le cadenas marque le coup */
.tg-rec.tg-verrou .tg-rec-cadenas svg { animation: tgCran .34s ease-out; }
/* l'appui fait pulser le rond et rayonner une onde rouge, le point clignote */
.tg-rond-rec { background: var(--rose-600); animation: tgPulse .42s ease-out, tgOnde 1.5s ease-out infinite; }
.tg-rond-envoi { background: var(--tg-accent); animation: tgPulse .35s ease-out; }
.tg-rond-rec .tg-rec-dot, .tg-rec-dot { animation: tgPoint 1.1s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .tg-rond-rec, .tg-rond-envoi, .tg-rec-dot, .tg-rec-cadenas { animation: none; }
}
.tg-rec-time { font-size: 14.5px; font-variant-numeric: tabular-nums; color: var(--tg-encre); }

/* feuille « Repondre / Copier », ouverte par un appui long sur un message */
.tg-sheet { position: absolute; inset: 0; z-index: 4; display: flex; align-items: flex-end; }
.tg-sheet[hidden] { display: none; }
.tg-sheet-fond { position: absolute; inset: 0; background: rgba(8,20,16,.38); }
.tg-sheet-card { position: relative; width: 100%; display: flex; flex-direction: column; gap: 4px;
  padding: 12px 12px calc(14px + env(safe-area-inset-bottom)); border-radius: 18px 18px 0 0;
  background: var(--tg-recu); color: var(--tg-encre); box-shadow: 0 -8px 30px rgba(0,0,0,.28); }
.tg-sheet-row { display: flex; align-items: center; gap: 10px; border: 0; border-radius: 12px;
  background: transparent; color: inherit; font: inherit; font-size: 15px; font-weight: 600;
  padding: 13px 10px; text-align: left; cursor: pointer; }
.tg-sheet-row:active { background: rgba(127,127,127,.14); }

/* photo jointe : vignette dans la bulle, ouverte en grand sur un appui */
.tg-bulle-media { padding: 4px 6px 5px; }
.tg-bulle-media .tg-meta { margin-right: 6px; }
.tg-photo { display: block; border: 0; padding: 0; background: transparent; cursor: pointer;
  border-radius: 12px; overflow: hidden; max-width: 260px; }
.tg-photo img { display: block; width: 100%; height: auto; max-height: 320px; object-fit: cover;
  border-radius: 12px; background: rgba(127,127,127,.18); min-height: 90px; }
.tg-vue { position: absolute; inset: 0; z-index: 5; display: flex; align-items: center;
  justify-content: center; background: rgba(6,12,20,.92); }
.tg-vue[hidden] { display: none; }
.tg-vue img { max-width: 96%; max-height: 84%; border-radius: 10px; }
.tg-vue-x { position: absolute; top: calc(10px + env(safe-area-inset-top)); right: 12px;
  width: 44px; height: 44px; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255,255,255,.16); color: #fff; display: grid; place-items: center; }
.tg-sheet-row.danger { color: #D93A3A; }
:root[data-theme="dark"] .tg-sheet-row.danger { color: #F87171; }

/* =====================================================================
   SELECTEUR DE LANGUE (01/10/2026) - la pastille « FR / EN » de la reference
   (site.ldmservice.com), posee dans l'en-tete de l'espace client, dans celui
   du visiteur et en haut a droite des ecrans de connexion. Aucune teinte
   figee : jetons et rgba seulement, donc la pastille suit le theme comme le
   reste de la coquille. L'entree ACTIVE se marque par la classe `on` ET par
   `aria-pressed` (l'etat se lit sans la couleur).
   ===================================================================== */
.cx-lang { display: inline-flex; align-items: center; gap: 2px; height: 30px; padding: 0 2px 0 7px;
  border-radius: 999px; border: 1px solid var(--cx-cerne); background: var(--surface);
  color: var(--slate-500); flex: 0 0 auto; }
.cx-lang-b { border: 0; background: transparent; color: inherit; font: inherit; font-size: 12px;
  font-weight: 700; letter-spacing: .02em; padding: 0 7px; height: 24px; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 999px;
  cursor: pointer; line-height: 1; }
.cx-lang-b.on { background: var(--brand-600); color: var(--on-brand); }
/* Page GOOGLE ouverte dans le NAVIGATEUR du telephone (elle porte encore la
   pastille de langue) : la page est SOMBRE, la pastille prend donc le meme verre
   translucide que le bouton de recopie de l'accueil. Les ecrans de connexion et
   d'inscription de l'application, eux, ne portent plus QUE le bouton de retour
   (la pastille y a ete retiree le 01/10/2026, le retour ajoute le 03/10/2026 —
   voir `.auth-back` juste apres). */
.auth-lang { position: fixed; top: calc(10px + env(safe-area-inset-top)); right: 12px; z-index: 30; }
.auth-lang .cx-lang { background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .30);
  color: rgba(255, 255, 255, .82); }
.auth-lang .cx-lang-b.on { background: var(--on-brand); color: var(--brand-700); }
/* BOUTON DE RETOUR des ecrans d'entree (03/10/2026, demande du client :
   « ajoute un bouton de retour en arriere sur l'interface de connexion et
   d'inscription »). Meme habillage que la pastille ci-dessus — la page est sombre
   par choix, donc un verre blanc translucide sans aucune teinte figee — mais pose
   en HAUT A GAUCHE, la ou l'oeil cherche un retour, et AVANT le logo dans le flux
   (il est fixe : il ne pousse donc rien). La fleche est le chevron de la maison
   tourne d'un demi-tour, comme celle du tchat (`.tg-back svg`). */
.auth-back { position: fixed; top: calc(10px + env(safe-area-inset-top)); left: 12px; z-index: 30;
  width: 38px; height: 38px; padding: 0; display: inline-flex; align-items: center;
  justify-content: center; border-radius: 50%; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, .30); background: rgba(255, 255, 255, .12);
  color: #fff; -webkit-appearance: none; appearance: none; }
.auth-back svg { transform: rotate(180deg); }
.auth-back:active { transform: scale(.94); }

/* ---------------------------------------------------------------------------
   ICONE FLOTTANTE DE LANGUE (02/10/2026 — demande du client : « change le bouton
   de langue en icone flottante sur l'ecran, touche le bouton pour changer la
   langue et vice-versa »). Un SEUL bouton rond remplace la pastille FR / EN de
   l'en-tete ; il FLOTTE au-dessus du contenu, a l'endroit exact qu'occupait le
   rond de messagerie (retire le 30/09/2026), donc juste au-dessus de la barre du
   bas et sur le bord droit. Il est pose DANS l'en-tete (comme la pastille qu'il
   remplace) : la ou l'en-tete disparait — les deux ecrans de connexion, la
   discussion en pleine page — l'icone disparait donc aussi.
   Le fond est plein a la couleur de la maison (l'appui EST une action), et la
   nuit elle suit la meme regle que la pilule active de la barre.
   Aucune teinte figee : jetons seulement. --------------------------------- */
.cx-lang-fab {
  position: fixed; right: 12px; bottom: calc(74px + env(safe-area-inset-bottom));
  z-index: 25; width: 52px; height: 52px; padding: 0; border: 0; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--brand-600); color: var(--on-brand); cursor: pointer;
  box-shadow: 0 14px 26px -16px rgba(31, 111, 191, .95);
  transition: transform .12s ease;
  /* Le bouton SE DEPLACE au doigt (02/10/2026) : sans cela le navigateur prend le
     geste pour un defilement et le bouton reste cloue a sa place. */
  touch-action: none;
}
.cx-lang-fab:active { transform: scale(.95); }
.cx-lang-fab svg { display: block; }
/* Le code de la langue CIBLE, sous le globe (l'appui y bascule). */
.cx-lang-fab-t { font-size: 12px; font-weight: 800; letter-spacing: .04em; line-height: 1;
  margin-top: 1px; }
:root[data-theme="dark"] .cx-lang-fab { background: var(--brand-500); }
/* Pendant une saisie, la barre du bas s'efface (`data-clavier`) : l'icone suit le
   meme sort, sinon elle flotterait par-dessus le clavier. */
body.client-app[data-clavier="1"] .cx-lang-fab { display: none; }

/* =====================================================================
   « MON COMPTE » ET REGLAGES — habillage modernise (30/09/2026)
   Demande du client : « moderniser la partie mon compte et les boutons de
   mise a jour et theme ». Meme palette que le reste du site : bleu de la
   marque, or pour les etats, un seul rouge (deconnexion). Aucune couleur
   nouvelle : uniquement les variables existantes, donc les deux themes
   suivent tout seuls. Les lignes font au moins 56 px de haut (cible
   tactile), et l'interrupteur du theme se peint sur aria-pressed, pose
   par le noyau (voir paintThemeIcons) : rien a cabler ici.
   ===================================================================== */

/* ---- bandeau d'identite : degrade de la marque, texte blanc ---- */
.pf-hero { position: relative; overflow: hidden; border-radius: var(--radius-lg);
  /* 12/11/2026 — MAQUETTE « Profil » : la carte d'identite est BLANCHE, a cerne
     fin, comme les autres cartes. L'ancien bandeau bleu degrade est parti avec
     elle (l'avatar porte desormais la couleur de la maison). */
  padding: 16px; color: var(--slate-900);
  background: var(--surface);
  border: 1px solid var(--cx-cerne);
  box-shadow: var(--cx-flat); }
/* titre de page de l'ecran (la maquette n'a pas de gros cartouche : deux lignes) */
.pf-head { margin: 2px 2px 14px; }
.pf-head-t { font-size: 26px; font-weight: 800; letter-spacing: -.02em; color: var(--slate-900); line-height: 1.1; }
.pf-head-s { margin-top: 3px; font-size: 13.5px; color: var(--slate-500); }
.pf-hero-top { position: relative; display: flex; align-items: center; gap: 14px; }
.pf-ava { flex: 0 0 auto; width: 62px; height: 62px; border-radius: 50%; display: grid; place-items: center;
  background: var(--navy); color: var(--on-brand);
  font-weight: 800; font-size: 20px; letter-spacing: .02em; }
.pf-nom { font-size: 18px; font-weight: 800; letter-spacing: -.01em; line-height: 1.2; color: var(--slate-900); }
.pf-meta { font-size: 12.5px; color: var(--slate-500); margin-top: 4px; }
/* les deux pastilles sous l'identite : etat du compte (verte) et anciennete */
.pf-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 14px; }
.pf-chip { position: relative; display: inline-flex; align-items: center; gap: 5px; margin-top: 0;
  padding: 5px 10px; border-radius: 999px; background: var(--slate-100);
  font-size: 11.5px; font-weight: 700; color: var(--slate-600); }
.pf-chip.ok { background: var(--emerald-50); color: var(--emerald-600); }
.pf-chip.stop { background: var(--rose-50); color: var(--rose-700); }
.pf-chip.ghost { background: transparent; border: 1px solid var(--cx-cerne); color: var(--slate-500); font-weight: 600; }

/* ---- trois compteurs : cagnotte, depots, retraits ----
   Budget mesure (viewport 363 px du client, police Inter du site) : 331 px
   utiles pour trois tuiles, soit 79 px de texte par tuile en 3 colonnes. Or
   « 1 234 567 F » en gras 700 mesure 83 px a 15 px et 88 px a 16 px : en trois
   colonnes, un solde a sept chiffres serait coupe. Donc SUR TELEPHONE, les
   trois compteurs passent en PLEINE LARGEUR (libelle a gauche, montant a
   droite, 259 px disponibles) — c'est la forme deja retenue pour le tableau de
   bord sur telephone, et le montant reste en 16 px. */
.pf-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin-top: 12px; }
.pf-stat { background: var(--surface); border-radius: var(--radius); box-shadow: var(--ring); padding: 12px; }
.pf-stat .k-label { font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--slate-500); }
.pf-stat .k-value { font-size: 15px; font-weight: 700; margin-top: 3px; font-variant-numeric: tabular-nums; }
.pf-stat.lead { box-shadow: 0 0 0 2px var(--brand-500); }
.pf-stat.lead .k-value { color: var(--brand-600); }
@media (max-width: 480px) {
  .pf-stats { grid-template-columns: 1fr; gap: 8px; }
  .pf-stat { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto;
    align-items: center; gap: 11px; padding: 12px 14px; }
  .pf-stat .pf-ico { margin-bottom: 0; }
  .pf-stat .k-label { font-size: 12px; }
  .pf-stat .k-value { font-size: 16px; margin-top: 0; text-align: right; white-space: nowrap; }
}

/* ---- tuile d'icone : titres de section et lignes ---- */
.pf-ico { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 10px; display: grid; place-items: center;
  background: none; color: var(--brand-600); }
.pf-ico.sm { width: 32px; height: 32px; border-radius: 10px; }
.pf-stat .pf-ico { margin-bottom: 8px; }
/* 12/11/2026 : les icones des lignes n'ont plus de tuile (maquette) — la nuit
   elles gardent seulement leur trait bleu clair, sans fond. */
:root[data-theme="dark"] .pf-ico { background: none; color: var(--brand-400); }

/* ---- titre de section : tuile + libelle + sous-titre ---- */
.pf-hd { display: flex; align-items: center; gap: 11px; min-width: 0; }
.pf-hd .pf-txt { display: grid; gap: 1px; min-width: 0; }
.pf-hd .pf-t { display: block; font-weight: 700; font-size: 14.5px; }
.pf-hd .pf-s { display: block; font-size: 12px; color: var(--slate-500); margin-top: 1px; }

/* ---- ligne de navigation / de reglage ---- */
.pf-row { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 56px;
  padding: 11px 14px; background: var(--surface); border: 0; border-bottom: 1px solid var(--slate-100);
  color: inherit; font: inherit; text-align: left; text-decoration: none; cursor: pointer;
  transition: background .15s ease; }
.pf-row:last-child { border-bottom: 0; }
.pf-row:hover, .pf-row:active { background: var(--slate-50); }
.pf-row:focus-visible { outline: 2px solid var(--brand-500); outline-offset: -2px; }
.pf-row .pf-lib { flex: 1 1 auto; min-width: 0; }
.pf-row .pf-lib .pf-t { display: block; font-weight: 600; font-size: 15px; color: var(--slate-900); }
.pf-row .pf-lib .pf-s { display: block; font-size: 12px; color: var(--slate-500); margin-top: 2px; }
.pf-row .pf-end { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; color: var(--slate-400); }

/* ---- 12/11/2026 : intitule de section, carte de lignes, deconnexion ----
   La maquette ne pose pas d'en-tete de carte : un INTITULE court au-dessus d'une
   carte arrondie qui contient les lignes, puis un bouton rose pleine largeur. */
.pf-grp { margin: 20px 2px 8px; font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .12em; color: var(--slate-500); }
.pf-card { border-radius: 18px; overflow: hidden; }
.pf-card .pf-row { background: transparent; }
.pf-out {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; min-height: 52px; margin-top: 20px; padding: 0 16px;
  border: 1px solid transparent; border-radius: 18px;
  background: var(--rose-50); color: var(--rose-700);
  font: inherit; font-size: 15px; font-weight: 700; cursor: pointer;
}
.pf-out:active { background: var(--rose-200); }

/* ---- interrupteur du theme ----
   Le bouton est BLANC FIGE (comme .sd-white et .zg-bulle deja whitelistes) : il
   doit rester le plus CLAIR, toujours. La piste, elle, prend --slate-300, qui
   bascule tout seul : gris clair (#CBD5E1) sur la carte blanche, gris moyen
   (#475569) sur la carte sombre. Une seule regle, donc — et le bouton ne doit
   JAMAIS suivre la piste (un bouton var(--surface) passerait SOUS la piste la
   nuit : interrupteur invisible, meme piege que la section 9novo). */
.pf-sw { flex: 0 0 auto; width: 48px; height: 28px; border-radius: 999px; background: var(--slate-300);
  position: relative; transition: background .2s ease; }
.pf-sw::after { content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 4px rgba(15, 23, 42, .32);
  transition: transform .2s ease; }
[data-theme-toggle][aria-pressed="true"] .pf-sw { background: var(--brand-500); }
[data-theme-toggle][aria-pressed="true"] .pf-sw::after { transform: translateX(20px); }

/* ---- bandeau « nouvelle version disponible » : tuile + texte + action ---- */
.maj-banner .mb-ico { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 10px; display: grid;
  place-items: center; background: rgba(255, 255, 255, .16); }
:root[data-theme="dark"] .maj-banner .mb-ico { background: rgba(31, 111, 191, .14); color: var(--brand-500); }
.maj-banner .mb-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.maj-banner .mb-t { font-size: 12.5px; font-weight: 700; line-height: 1.25; }
.maj-banner .mb-s { font-size: 12px; font-weight: 500; opacity: .74; line-height: 1.25; }

/* ==========================================================================
   LE MARCHE (30/09/2026) : rayons, cartes d'articles, panier, commande.
   Meme palette que le reste : bleu maison #0B2E55, or #E5A93C, plus le vert et
   le rouge deja utilises par les cartes de l'accueil. Aucune teinte etrangere.
   ========================================================================== */
.sh-tete { display: flex; align-items: center; gap: 12px; margin-top: 4px; }
.sh-caddie { position: relative; flex: 0 0 auto; display: inline-flex; align-items: center;
  justify-content: center; width: 46px; height: 46px; border-radius: 999px; cursor: pointer;
  background: var(--brand-50); color: var(--brand-600); border: 0; }
.sh-nb { position: absolute; top: -4px; right: -4px; min-width: 20px; height: 20px; padding: 0 5px;
  border-radius: 999px; background: var(--amber-500); color: var(--slate-900);
  font-size: 12px; font-weight: 800; line-height: 20px; text-align: center; }
.sh-nb.vide { display: none; }
.sh-rech { display: flex; align-items: center; gap: 8px; margin-top: 14px; padding: 4px 4px 4px 12px;
  background: var(--surface); border: 1px solid var(--slate-200); border-radius: 999px;
  color: var(--slate-500); }
.sh-rech input { flex: 1 1 auto; min-width: 0; border: 0; background: none; font: inherit;
  font-size: 14px; color: var(--slate-900); padding: 8px 0; }
.sh-rech input:focus { outline: none; }
.sh-rech-b { flex: 0 0 auto; border: 0; cursor: pointer; border-radius: 999px; padding: 8px 14px;
  background: var(--brand-600); color: #fff; font: inherit; font-size: 13px; font-weight: 600; }
.sh-rayons { display: flex; gap: 8px; overflow-x: auto; margin-top: 12px; padding-bottom: 4px;
  scrollbar-width: none; }
.sh-rayons::-webkit-scrollbar { display: none; }
.sh-rayon { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 8px 14px; border-radius: 999px; border: 1px solid var(--slate-200);
  background: var(--surface); color: var(--slate-600); font: inherit; font-size: 13px; font-weight: 600; }
.sh-rayon.on { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }
.sh-rayon-n { font-size: 12px; opacity: .75; }
.sh-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px; }
.sh-card { display: flex; flex-direction: column; gap: 6px; padding: 10px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--slate-200); border-radius: 16px; }
.sh-photo { display: flex; align-items: center; justify-content: center; height: 104px;
  border-radius: 12px; background: var(--brand-50); color: var(--brand-500); overflow: hidden; }
.sh-photo img { width: 100%; height: 100%; object-fit: cover; }
.sh-nom { font-size: 13.5px; font-weight: 700; color: var(--slate-900); line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.sh-prix { display: flex; align-items: baseline; gap: 6px; font-size: 15px; font-weight: 800;
  color: var(--brand-700); }
.sh-prix.big { font-size: 20px; }
.sh-old { font-size: 12px; font-weight: 600; color: var(--slate-400); text-decoration: line-through; }
.sh-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.sh-tag { display: inline-flex; align-items: center; gap: 3px; padding: 2px 8px; border-radius: 999px;
  background: var(--slate-100); color: var(--slate-600); font-size: 12px; font-weight: 700; }
.sh-tag-num { background: var(--brand-50); color: var(--brand-600); }
.sh-tag-18 { background: var(--rose-50); color: var(--rose-700); }
.sh-tag-vide { background: var(--slate-200); color: var(--slate-600); }
.sh-tag-peu { background: var(--amber-100); color: var(--amber-700); }
.sh-fiche { display: flex; gap: 12px; padding: 12px; }
.sh-fiche .sh-photo { flex: 0 0 96px; height: 96px; }
.sh-vide { padding: 12px; border-radius: 12px; background: var(--slate-50);
  color: var(--slate-600); font-size: 13px; }
.sh-qte { display: flex; align-items: center; gap: 10px; }
.sh-pm { display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  width: 34px; height: 34px; border-radius: 10px; border: 1px solid var(--slate-200);
  background: var(--surface); color: var(--brand-600); }
.sh-pm:active { transform: scale(.94); }
.sh-q { min-width: 28px; text-align: center; font-weight: 800; font-size: 15px; }
.sh-ligne { display: flex; align-items: center; gap: 10px; padding: 10px 0; }
.sh-ligne + .sh-ligne { border-top: 1px solid var(--slate-100); }
.sh-vign { position: relative; flex: 0 0 auto; display: inline-flex; align-items: center;
  justify-content: center; width: 44px; height: 44px; border-radius: 12px; overflow: hidden;
  background: var(--brand-50); color: var(--brand-500); }
.sh-vign img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.sh-x { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 999px; border: 0; cursor: pointer;
  background: var(--rose-50); color: var(--rose-600); display: inline-flex;
  align-items: center; justify-content: center; }
.sh-tot { display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 7px 0; font-size: 13.5px; color: var(--slate-700); }
.sh-tot.big { font-size: 16px; color: var(--slate-900); }
.sh-tot.muted { color: var(--slate-500); font-size: 12.5px; }
.sh-cmd { display: flex; align-items: center; gap: 10px; padding: 12px 0; cursor: pointer; }
.sh-cmd + .sh-cmd { border-top: 1px solid var(--slate-100); }
.sh-cmd-t { font-size: 14px; font-weight: 800; color: var(--slate-900); }
.sh-note { padding: 11px 13px; border-radius: 12px; background: var(--brand-50);
  color: var(--brand-800); font-size: 13px; line-height: 1.45; }
.sh-ev { display: flex; gap: 10px; padding: 6px 0; }
.sh-ev .xs { flex: 0 0 128px; }
:root[data-theme="dark"] .sh-photo, :root[data-theme="dark"] .sh-vign { background: var(--brand-50); }
:root[data-theme="dark"] .sh-note { background: rgba(255, 255, 255, .07); color: var(--slate-700); }
/* dans l'habillage de l'espace client : meme cerne, memes angles que le reste */
body.client-app .sh-card, body.client-app .sh-rech { border-color: var(--cx-cerne); box-shadow: var(--cx-flat); }
body.client-app .sh-card, body.client-app .sh-photo, body.client-app .sh-vign { border-radius: var(--cx-r); }

/* ==========================================================================
   AVIS DE L'ESPACE CLIENT (03/10/2026) — « le support t'a repondu », un
   depot valide, un retrait paye ou refuse.
   Le BANDEAU D'INTERFACE (la pastille sombre posee au-dessus de la barre du bas)
   a ete RETIRE le meme jour, le soir : « ne pas afficher le message du support en
   bas de l'ecran avec le bouton Ouvrir ; faire afficher les messages dans la barre
   de notification du telephone ». Seule la NOTIFICATION DU TELEPHONE annonce
   desormais (pont FSNotif / service worker) : ne rien remettre ici sans demande.
   Reste la pastille des messages non lus, en --rose-600, comme le compteur de
   la cloche (.cx-count).
   ========================================================================== */
/* La pastille des messages du support non lus : sur la ligne « Messages » de
   l'accueil (a cote du titre) et sur l'entree « Support » du panneau du compte
   (repoussee a droite). Elle disparait quand il n'y a rien a lire. */
.cx-nb { flex: 0 0 auto; margin-left: 6px; min-width: 19px; height: 19px; padding: 0 6px;
  border-radius: 999px; background: var(--rose-600); color: #fff; font-size: 12px;
  font-weight: 700; line-height: 1; display: inline-flex; align-items: center;
  justify-content: center; vertical-align: middle; }
.cx-nb[hidden] { display: none; }
.cx-acc-row .cx-nb { margin-left: auto; }

/* =====================================================================
   ANIMATIONS — mouvement discret, au service de la lecture.
   Trois principes : AUCUNE couleur nouvelle (on ne rejoue que la palette
   et des alphas), des durees courtes (0,26 a 0,5 s), et l'arret TOTAL
   quand le systeme demande moins de mouvement (prefers-reduced-motion).
   Le conteneur #view recoit la classe « no-anim » quand le meme ecran se
   redessine TOUT SEUL (suivi d un depot toutes les 6 s) : sans ce garde-fou
   la page clignoterait a chaque rafraichissement.
   ===================================================================== */
:root {
  --fx-ease: cubic-bezier(.22, .61, .36, 1);
  --fx-step: 32ms;                       /* ecart entre deux blocs d un ecran */
  --fx-glow: rgba(31, 111, 191, .45);     /* halo = bleu de la marque, en alpha */
}
:root[data-theme="dark"] { --fx-glow: rgba(147, 197, 253, .45); }

@keyframes fx-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes fx-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes fx-pop { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
@keyframes fx-sheet { from { opacity: 0; transform: translateY(26px) scale(.99); } to { opacity: 1; transform: none; } }
@keyframes fx-toast { from { opacity: 0; transform: translateY(14px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes fx-ping { 0% { opacity: 0; transform: scale(.55); } 60% { opacity: 1; transform: scale(1.14); } 100% { opacity: 1; transform: none; } }
/* halo de l'etape en cours : ne bouge que transform + opacity (pas de box-shadow
   anime a chaque image). Au repos, opacite 0 : le reglage « moins de mouvement »
   ne laisse donc aucun anneau fixe. */
@keyframes fx-halo { 0% { transform: scale(1); opacity: .55; } 100% { transform: scale(2.1); opacity: 0; } }
@keyframes fx-dot { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
@keyframes fx-ballon { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes fx-bar { from { transform: scaleY(.04); } to { transform: none; } }
@keyframes fx-toast-c { from { opacity: 0; transform: translateX(-50%) translateY(14px); }
  to { opacity: 1; transform: translateX(-50%); } }

/* ---- 1. entree d un ecran : chaque bloc monte et apparait, en cascade ---- */
#view > * { animation: fx-rise .34s var(--fx-ease) backwards; }
#view > *:nth-child(1) { animation-delay: 0ms; }
#view > *:nth-child(2) { animation-delay: 32ms; }
#view > *:nth-child(3) { animation-delay: 64ms; }
#view > *:nth-child(4) { animation-delay: 96ms; }
#view > *:nth-child(5) { animation-delay: 128ms; }
#view > *:nth-child(6) { animation-delay: 160ms; }
#view > *:nth-child(7) { animation-delay: 192ms; }
#view > *:nth-child(8) { animation-delay: 224ms; }
#view > *:nth-child(9) { animation-delay: 256ms; }
#view > *:nth-child(n+10) { animation-delay: 288ms; }
/* grilles (raccourcis, cartes, formulaires) et listes : meme cascade, plus fine */
#view .grid-2 > *, #view .grid-3 > *, #view .grid-4 > * {
  animation: fx-rise .30s var(--fx-ease) backwards; }
#view .grid-2 > *:nth-child(2), #view .grid-3 > *:nth-child(2), #view .grid-4 > *:nth-child(2) { animation-delay: 40ms; }
#view .grid-2 > *:nth-child(3), #view .grid-3 > *:nth-child(3), #view .grid-4 > *:nth-child(3) { animation-delay: 80ms; }
#view .grid-2 > *:nth-child(4), #view .grid-3 > *:nth-child(4), #view .grid-4 > *:nth-child(4) { animation-delay: 120ms; }
#view .grid-2 > *:nth-child(5), #view .grid-3 > *:nth-child(5), #view .grid-4 > *:nth-child(5) { animation-delay: 160ms; }
#view .grid-2 > *:nth-child(n+6), #view .grid-3 > *:nth-child(n+6), #view .grid-4 > *:nth-child(n+6) { animation-delay: 200ms; }
#view .cx-acts > * { animation: fx-pop .34s var(--fx-ease) backwards; }
#view .cx-acts > *:nth-child(2) { animation-delay: 70ms; }
#view .cx-racc > * { animation: fx-pop .34s var(--fx-ease) backwards; }
#view .cx-social-row > * { animation: fx-pop .34s var(--fx-ease) backwards; }
#view .cx-social-row > *:nth-child(2) { animation-delay: 60ms; }
#view .table tbody tr { animation: fx-fade .26s var(--fx-ease) backwards; }
#view .table tbody tr:nth-child(2) { animation-delay: 30ms; }
#view .table tbody tr:nth-child(3) { animation-delay: 60ms; }
#view .table tbody tr:nth-child(4) { animation-delay: 90ms; }
#view .table tbody tr:nth-child(n+5) { animation-delay: 120ms; }
/* Verification d identite du joueur : elle apparait pendant la frappe, sa
   petite apparition annonce que la reponse du bookmaker est arrivee. */
#view:not(.no-anim) .idcheck { animation: fx-pop .30s var(--fx-ease) backwards; }

/* Ouverture du DEPOT (24/10/2026) : MEME animation que l'ecran de retrait —
   la cascade fx-rise de 0,34 s, ecart 32 ms — appliquee aux SECTIONS du
   formulaire. Le retrait a trois blocs a la racine (carte, aide, encart) et se
   voit donc arriver ; le depot est UN seul bloc, il apparaissait d'un coup.
   On lui donne les memes sections en cascade : meme langage, meme duree.
   La garde `.no-anim` reste indispensable : le depot se redessine a chaque
   frappe au clavier, et l'animation ne doit PAS rejouer la. */
body:not(.admin-app) #view:not(.no-anim) .dp-form > * { animation: fx-rise .34s var(--fx-ease) backwards; }
body:not(.admin-app) #view:not(.no-anim) .dp-form > *:nth-child(1) { animation-delay: 0ms; }
body:not(.admin-app) #view:not(.no-anim) .dp-form > *:nth-child(2) { animation-delay: 32ms; }
body:not(.admin-app) #view:not(.no-anim) .dp-form > *:nth-child(3) { animation-delay: 64ms; }
body:not(.admin-app) #view:not(.no-anim) .dp-form > *:nth-child(4) { animation-delay: 96ms; }
body:not(.admin-app) #view:not(.no-anim) .dp-form > *:nth-child(5) { animation-delay: 128ms; }
body:not(.admin-app) #view:not(.no-anim) .dp-form > *:nth-child(n+6) { animation-delay: 160ms; }
/* Le geste : la carte « Depot » s'enfonce legerement sous le doigt, pour que
   l'appui se voie AVANT que la page arrive (retour tactile, pas decoratif). */
@media (hover: none) {
  body:not(.admin-app) #view .cx-act:active { transform: scale(.975); }
}

/* ---- 2. redessin automatique du MEME ecran : aucune animation d entree ---- */
#view.no-anim > *, #view.no-anim .grid-2 > *, #view.no-anim .grid-3 > *,
#view.no-anim .grid-4 > *, #view.no-anim .cx-acts > *, #view.no-anim .cx-racc > *,
#view.no-anim .cx-social-row > *,
#view.no-anim .dp-form, #view.no-anim .dp-form > *,
#view.no-anim .table tbody tr, #view.no-anim .idcheck { animation: none; }

/* ---- 3. le geste : boutons, cartes, champs, onglets du bas ---- */
.btn { transition: filter .15s ease, background .15s ease, transform .12s var(--fx-ease); }
.btn:active { transform: translateY(1px) scale(.97); }
.tile, .choice { transition: transform .16s var(--fx-ease), box-shadow .16s var(--fx-ease), border-color .16s ease; }
.tile:active, .choice:active { transform: scale(.985); }
.cx-act-ico { transition: transform .18s var(--fx-ease), box-shadow .18s var(--fx-ease); }
.cx-act:active .cx-act-ico { transform: scale(.94); }
.cx-soc { transition: transform .18s var(--fx-ease); }
.cx-soc:active { transform: scale(.92); }
.cx-copy { transition: transform .16s var(--fx-ease), filter .16s ease; }
.cx-copy:active { transform: scale(.94); }
.cx-ico, .sd-item, .cx-acc-row, .tab { transition: background .15s ease, color .15s ease; }
.input, .select, .textarea { transition: border-color .15s ease, box-shadow .18s var(--fx-ease); }
.bottomnav .item svg { transition: transform .18s var(--fx-ease); }
.bottomnav .item.active svg { transform: translateY(-1px) scale(1.08); }
.bottomnav .item:active svg { transform: scale(.88); }
.list-item { transition: background .15s ease; }

/* ---- 4. panneaux, modales, feuilles et messages ---- */
.modal { animation: fx-fade .16s ease both; }
.modal-card { animation: fx-sheet .26s var(--fx-ease) both; }
.sheet { animation: fx-fade .16s ease both; }
.sheet-card { animation: fx-sheet .30s var(--fx-ease) both; }
.sd-back { animation: fx-fade .20s ease both; }
.toast { animation: fx-toast .22s var(--fx-ease) both; }
.maj-banner { animation: fx-toast-c .30s var(--fx-ease) both; }

/* ---- 5. signaux « ca travaille » et « ca attend » ---- */
.stepbar .s.on .n { position: relative; isolation: isolate; }
.stepbar .s.on .n::after { content: ""; position: absolute; inset: 0; border-radius: 50%; z-index: -1;
  background: var(--fx-glow); opacity: 0; pointer-events: none;
  animation: fx-halo 1.9s var(--fx-ease) infinite; }
.stepbar .s.done .n { animation: fx-ping .30s var(--fx-ease) both; }
/* Le ballon de football qui tourne sur lui-meme — illustration de l'attente du
   SMS depuis le 27/09/2026 (remplace la silhouette qui marchait, fx-walk).
   `transform-box: view-box` + origine au CENTRE sont indispensables : sans elles
   la rotation d'un SVG part du coin haut-gauche du viewBox et le ballon decrit
   une ORBITE au lieu de tourner sur place. */
.pay-wait svg { animation: fx-ballon 2.6s linear infinite;
  transform-box: view-box; transform-origin: center; }
.cx-count { animation: fx-ping .26s var(--fx-ease) both; }
.dot.warn, .dot.brand { animation: fx-dot 1.7s ease-in-out infinite; }
.bars .b { transform-origin: bottom; animation: fx-bar .50s var(--fx-ease) backwards; }
.bars .b:nth-child(2n) { animation-delay: 60ms; }
.bars .b:nth-child(3n) { animation-delay: 110ms; }
.progress > i { transition: width .50s var(--fx-ease); }

/* ---- 6. respect du reglage systeme « moins de mouvement » ---- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* =====================================================================
   CONCOURS (promotion) — contenu de la page publique /concours
   Repris de l'ecran /admin/promotion de la reference. On ne cree aucune
   couleur : uniquement les variables de la palette existante.
   ===================================================================== */
.flex-col { flex-direction: column; }
.w-sm { width: 84px; }

/* une section du formulaire de contenu (En-tête, Lots, Classement...) */
.promo-sec { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--slate-200); }
.promo-sec:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

/* un lot / une étape dans la liste editable */
.promo-item { padding: 12px; border: 1px solid var(--slate-200); border-radius: var(--radius-sm);
  background: var(--surface-2); }

/* aperçu du logo du concours */
.promo-logo { display: flex; align-items: center; justify-content: center; width: 76px; height: 76px;
  overflow: hidden; border: 1px solid var(--slate-200); border-radius: var(--radius-sm);
  background: var(--surface-2); color: var(--slate-400); }
.promo-logo img { width: 100%; height: 100%; object-fit: contain; }

/* valeur deja cumulee d'une action (non saisissable) */
.promo-cumul { width: 84px; padding: 6px 8px; text-align: right; font-weight: 600;
  border-radius: var(--radius-sm); background: var(--slate-100); color: var(--slate-700); }

/* saisie des points d'un participant */
.promo-pt { width: 84px; text-align: right; }

/* capture de partage affichee dans la fenetre */
.promo-shot { display: block; width: 100%; max-height: 60vh; margin-top: 12px; object-fit: contain;
  border: 1px solid var(--slate-200); border-radius: var(--radius-sm); }

/* PIECE JOINTE D'UN CLIENT (photo ou video) affichee en grand dans le panneau
   (03/10/2026, client : « impossible d'ouvrir le fichier photo recu dans
   l'interface admin conversation »). Meme cadre que la capture de partage
   ci-dessus : la piece jointe occupe la fenetre, entiere et sans deformation. */
.chat-vue { display: block; width: 100%; max-height: 60vh; margin-top: 12px; object-fit: contain;
  border: 1px solid var(--slate-200); border-radius: var(--radius-sm);
  /* le fond derriere la piece jointe : un aplat sombre FIXE (rgba, donc insensible
     a la bascule de theme) — la ou l'image ne remplit pas le cadre, un fond blanc
     ferait croire a une image vide. */
  background: rgba(15, 23, 42, .92); }

/* --------- page publique du concours (espace client) --------- */
.promo-hero { padding: 18px; text-align: center; border: 1px solid var(--slate-200);
  border-radius: var(--radius); background: var(--surface-2); }
.promo-hero .promo-logo { margin: 0 auto 10px; }
.promo-pastille { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 700; background: var(--brand-50); color: var(--brand-700); }
.promo-sous-titre { margin-top: 8px; font-size: 13px; font-weight: 600; color: var(--brand-600); }

/* compte a rebours : quatre cases (jours, heures, minutes, secondes) */
.promo-compteur { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 10px;
  text-align: center; }
.promo-compteur > div { display: flex; flex-direction: column; gap: 2px; padding: 8px 4px;
  border-radius: var(--radius-sm); background: var(--slate-100); }
.promo-num { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--slate-900); }

/* podium, lots et etapes */
.promo-podium { display: grid; gap: 8px; }
.promo-podium-item, .promo-lot, .promo-etape { display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border: 1px solid var(--slate-200); border-radius: var(--radius-sm);
  background: var(--surface-2); }
.promo-lot-emoji, .promo-etape-emoji { font-size: 24px; line-height: 1; }

/* =====================================================================
   EFFETS D'ANIMATION DE LA REFERENCE (embmoney) sur nos composants.
   Memes effets : survol qui souleve, appui qui retrecit, filet de lumiere
   qui balaie, changement de fond en douceur. Nos apparitions (fx-*) et nos
   signaux (fx-halo / fx-dot) couvrent deja fade-up / pulse / pulse-glow.
   ===================================================================== */

/* 1. ronds de l'accueil client : souleves au survol, ecrases a l'appui
      (reference : transition-transform duration-200 + hover:-translate-y-1
      + hover:scale-110 + active:scale-95) */
.cx-round-c { transition: transform .20s var(--fx-ease), box-shadow .20s var(--fx-ease); }
.cx-round:hover .cx-round-c { transform: translateY(-4px) scale(1.08);
  box-shadow: 0 14px 26px -14px var(--brand-600); }
.cx-round:active .cx-round-c { transform: translateY(0) scale(.95); }

/* 2. cartes de l'espace client : elles se soulevent au survol (l'admin reste
      fixe, comme la reference) */
body:not(.admin-app) #view .card { transition: transform .25s var(--fx-ease), box-shadow .25s var(--fx-ease); }
body:not(.admin-app) #view .card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }

/* 3. lignes et entrees de menu : changement de fond en douceur
      (reference : transition-colors partout) */
tbody tr, .admin-nav a, .bottomnav .item, .list-row, .cx-link {
  transition: background .18s ease, color .18s ease, border-color .18s ease; }

/* 4. boutons : appui qui retrecit (reference : active:scale-95) et lumiere */
.btn { transition: transform .15s var(--fx-ease), filter .15s var(--fx-ease),
  box-shadow .15s var(--fx-ease), background .15s ease; }
.btn:active { transform: scale(.96); }
body:not(.admin-app) .btn-primary { position: relative; overflow: hidden; }
body:not(.admin-app) .btn-primary:hover { box-shadow: 0 10px 24px -12px var(--brand-600); }
body:not(.admin-app) .btn-primary::after { content: ''; position: absolute; top: 0; bottom: 0; width: 42%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.32), transparent);
  opacity: 0; pointer-events: none; transform: translateX(-160%) skewX(-12deg); }
body:not(.admin-app) .btn-primary:hover::after { opacity: 1; animation: fx-shine 1.1s ease-in-out; }

/* 5. filet lumineux en haut des cartes survolees (reference : ::after scaleX) */
@keyframes fx-shine { 0% { transform: translateX(-160%) skewX(-12deg); }
                      55%, 100% { transform: translateX(160%) skewX(-12deg); } }
body:not(.admin-app) #view .card { position: relative; }
body:not(.admin-app) #view .card::after { content: ''; position: absolute; top: 0; left: 0; right: 0;
  height: 2px; background: linear-gradient(90deg, transparent, var(--brand-400), transparent);
  transform: scaleX(0); transition: transform .35s var(--fx-ease); pointer-events: none; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
body:not(.admin-app) #view .card:hover::after { transform: scaleX(1); }

/* =====================================================================
   REFONTE DU 27/09 — habillage repris de la maquette de reference
   (uupm.cc/demo/ai-chatbot-platform), transpose sur NOTRE palette bleue.
   Seul l'habillage est touche : aucune classe, aucun ecran, aucune logique
   ne change. Ce qui suit vient apres tout le reste : a specificite egale,
   ces regles gagnent.
   ===================================================================== */

/* 1. typographie : les titres passent en Space Grotesk (texte deja en
      DM Sans via --font). On ne touche NI aux montants NI aux tableaux,
      qui gardent des chiffres tabulaires en DM Sans. */
h1, h2, h3, h4, .h1, .h2, .h3,
.cx-name, .admin-topbar-name, .auth-brand, .logo, .user-name,
.hero h1, .section-head h2, .stats-row .s b, .sd-welcome h2 {
  font-family: var(--font-titre);
}
h1, h2, .h1, .hero h1, .section-head h2 { letter-spacing: -.028em; }
h3, h4, .h3 { letter-spacing: -.012em; }

/* 2. boutons pleins : degrade de la marque au lieu de l'aplat, et leger
      soulevement au survol (reference : .btn-primary / hover translateY).
      ATTENTION : les boutons semantiques gardent LEUR couleur — « ok » reste
      vert et « danger » reste rouge, sinon le sens du bouton disparait. */
.btn-primary, .btn-dark, .btn-landing { background-image: var(--grad-cta); }
.btn-primary:hover, .btn-dark:hover, .btn-landing:hover {
  transform: translateY(-2px); filter: none; box-shadow: var(--shadow-cta); }
.btn-ok:hover, .btn-danger:hover, .btn-warn:hover { transform: translateY(-2px); filter: brightness(1.06); }
.btn-ghost:hover { border-color: var(--brand-300); color: var(--brand-700); }

/* 3. cartes : au survol, cerne de la marque + ombre teintee (reference :
      .card-hover { border-color: primary; box-shadow 0 4px 20px primary/10 }),
      a la place de la grande ombre noire qui ecrasait la page */
body:not(.admin-app) #view .card:hover {
  transform: translateY(-2px);
  box-shadow: 0 0 0 1px var(--brand-300), var(--shadow-hover); }
#view .kpi, .card, .promo-hero, .auth-card, .sd-panel { transition: box-shadow .2s var(--fx-ease), transform .2s var(--fx-ease); }
#view .kpi:hover { box-shadow: 0 0 0 1px var(--brand-300), var(--shadow-hover); }

/* 4. titres : un mot en degrade, comme le titre du hero de la reference.
      @supports evite d'effacer le texte si background-clip n'existe pas. */
.hero h1 em { color: var(--brand-600); }
@supports (-webkit-background-clip: text) or (background-clip: text) {
  .hero h1 em {
    background-image: var(--grad);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent; color: transparent;
  }
}

/* 5. elements actifs (onglets, pastilles de statut, chiffres cles) : meme
      traitement en degrade, en gardant la lisibilite sur les deux themes */
.tab.active, .dash-tabs .tab.active { background-image: var(--grad-cta); color: var(--on-brand); border-color: transparent; }
.stats-row .s { border-left-color: var(--brand-600); }
/* ATTENTION : ne PAS reposer ici la couleur du libelle de l'entree active du
   menu lateral. La regle « .admin-nav a.active { color: var(--brand-600) } »
   avait la MEME specificite que « .admin-side a.active » (ci-dessus) mais
   venait plus bas dans le fichier : en mode clair elle ecrasait donc le blanc
   et le libelle comme l'icone (currentColor) se peignaient du bleu de la
   pastille SUR la pastille bleue -> bande bleue vide dans le menu, sur
   telephone comme sur ordinateur. Les couleurs de l'entree active sont posees
   une seule fois, avec sa pastille (.admin-side a.active : texte blanc). */
.cx-round:hover .cx-round-c { box-shadow: 0 14px 26px -14px var(--brand-500); }

/* 6. champs de saisie : cerne de focus un peu plus large, dans l'esprit de
      la reference (ring teinte) */
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--brand-500); box-shadow: 0 0 0 3px rgba(31, 111, 191, .16); }
:root[data-theme="dark"] .input:focus,
:root[data-theme="dark"] .select:focus,
:root[data-theme="dark"] .textarea:focus { box-shadow: 0 0 0 3px rgba(147, 197, 253, .22); }

/* 7. page publique : les sections respirent comme dans la reference */
.hero { padding: 48px 0 40px; }
.section-head h2 { font-weight: 700; }
.btn-landing { font-weight: 600; border-radius: var(--radius-sm); }

/* 8. focus clavier : la plateforme impose un anneau de focus VISIBLE. Le halo
      par defaut du navigateur jure avec la palette, on le remplace par le bleu
      de la marque, en gardant un decalage pour qu'il ne colle pas au bord. */
a:focus-visible, button:focus-visible, .btn:focus-visible, .tab:focus-visible,
.bottomnav .item:focus-visible, .admin-nav a:focus-visible,
.list-row:focus-visible,
.cx-round:focus-visible, .card-hd [role="button"]:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--brand-600); outline-offset: 2px;
}
:root[data-theme="dark"] a:focus-visible, :root[data-theme="dark"] button:focus-visible,
:root[data-theme="dark"] .btn:focus-visible, :root[data-theme="dark"] .tab:focus-visible,
:root[data-theme="dark"] .bottomnav .item:focus-visible,
:root[data-theme="dark"] .admin-nav a:focus-visible,
:root[data-theme="dark"] .list-row:focus-visible, :root[data-theme="dark"] .cx-round:focus-visible,
:root[data-theme="dark"] input:focus-visible, :root[data-theme="dark"] select:focus-visible,
:root[data-theme="dark"] textarea:focus-visible, :root[data-theme="dark"] [tabindex]:focus-visible {
  outline-color: var(--brand-400);
}

/* 9. cibles tactiles : la plateforme demande 44 px minimum. On ne l'impose
      que sur les ecrans TACTILES (pointer: coarse) : a la souris, la densite
      des tableaux du panneau reste celle d'avant. */
@media (pointer: coarse) {
  .btn-xs, .btn-sm, .tab { min-height: 44px; }
  .bottomnav .item { min-height: 52px; }
}

/* =====================================================================
   VERRE (glassmorphism) — style recommande pour le domaine fintech
   (« Glassmorphism + Dark Mode (OLED) ») et signature de la plateforme de
   reference. Fond translucide + flou de 20 px + cerne de 1 px : l'effet se
   voit parce que les halos de la page passent dessous.
   Valeurs transcrites de sa feuille de style (.glass-card) ; l'ombre du
   survol prend notre violet au lieu de son bleu.
   Performance : la base classe le verre en « bon » et non « excellent » — il
   reste donc limite aux cartes, jamais sur les tableaux ni les listes.
   ===================================================================== */
/* `.auth-card` (l'ecran de connexion) a ete RETIREE de cette liste le 28/09 :
   sa charte est « page sombre, carte blanche », et le fond translucide la
   rendait grise avec un lisere clair. Elle reprend son blanc opaque juste
   en dessous. */
.card, .kpi, .net-card, .feat,
.tile, .promo-hero, .sd-panel, .stats-row .s {
  background-color: var(--glass-bg);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border);
}
/* Les FENETRES (modale, feuille) sont OPAQUES : posees sur un voile sombre, un
   fond translucide laissait passer ce voile et la fenetre paraissait grise au
   milieu d'un site clair. C'etait le cas du suivi de depot. */
.modal-card, .sheet-card {
  background: var(--surface);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border: 1px solid var(--glass-border);
}
.card:hover, .net-card:hover, .kpi:hover { background-color: var(--glass-bg-2); }
body:not(.admin-app) #view .card:hover {
  border-color: var(--brand-300);
  background-color: var(--glass-bg-2);
}
/* ombre du survol : valeur de la maquette (0 20px 25px -5px primary/15) */
.net-card:hover, .card:hover {
  box-shadow: 0 20px 25px -5px rgba(31, 111, 191, .15), 0 8px 10px -6px rgba(31, 111, 191, .10);
}
:root[data-theme="dark"] .net-card:hover, :root[data-theme="dark"] .card:hover {
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, .45);
}
/* le contenu du panneau garde son fond : pas de flou sur la coquille */
body.admin-app .admin-body { backdrop-filter: none; }

/* =====================================================================
   GALERIE DE STYLES (/galerie) — page de consultation du catalogue de design
   repris de la plateforme de reference. Le rendu est fait par
   static/js/galerie.js ; ces regles vivent ici, avec le reste du systeme de
   design, pour qu'il n'y ait qu'une seule feuille.
   ===================================================================== */
/* =====================================================================
     GALERIE DE STYLES — la base de donnees de design de la plateforme de
     reference, reproduite telle quelle. Page de consultation : elle ne fait
     aucun appel a l'API et reste hors de l'application.
     ===================================================================== */
  body.galerie { background: var(--slate-50); color: var(--slate-900); }
  body.galerie::before {
    content: ''; position: fixed; inset: -20% -10% auto -10%; height: 70vh; pointer-events: none;
    background:
      radial-gradient(520px 320px at 18% 12%, rgba(43, 130, 217, .28), transparent 70%),
      radial-gradient(460px 300px at 82% 4%, rgba(31, 111, 191, .22), transparent 70%);
    filter: blur(60px); z-index: 0;
  }
  .g-head {
    position: sticky; top: 0; z-index: 20;
    background: var(--glass-bg); -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
    border-bottom: 1px solid var(--glass-border);
  }
  .g-head .container { display: flex; align-items: center; justify-content: space-between; gap: 12px;
    min-height: 60px; padding-top: 8px; padding-bottom: 8px; flex-wrap: wrap; }
  .g-head .brand { display: inline-flex; align-items: center; gap: 10px; color: var(--slate-900); }
  .g-head .brand .brand-mark { width: 30px; height: 30px; border-radius: 9px; }
  .g-head .brand b { font-family: var(--font-titre); font-size: 16px; }
  .g-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
  main.container { position: relative; z-index: 1; padding-top: 28px; padding-bottom: 40px; }
  .g-bar { display: flex; flex-direction: column; gap: 12px; margin: 18px 0 22px; }
  .g-onglets { flex-wrap: wrap; }
  .g-onglets .tab { display: inline-flex; align-items: center; gap: 6px; }
  .g-n { font-size: 11px; opacity: .8; }
  .g-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 16px; }
  .g-card { padding: 16px; display: flex; flex-direction: column; gap: 8px; }
  .g-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
  .g-top .h3 { margin: 0; }
  .g-tags { display: flex; flex-wrap: wrap; gap: 6px; }
  .g-card { align-items: stretch; }
  .g-card > .g-tags, .g-card > .g-swatches, .g-card > .g-meta { align-self: flex-start; max-width: 100%; }
  .g-card .badge { margin: 2px 4px 2px 0; }
  .g-col { font-size: 13px; color: var(--slate-600); }
  .g-swatches { display: flex; gap: 5px; flex-wrap: wrap; }
  .g-sw { width: 20px; height: 20px; border-radius: 6px; box-shadow: var(--ring); display: inline-block; }
  .g-champ { display: flex; gap: 8px; font-size: 12.5px; }
  .g-lb { color: var(--slate-500); text-transform: uppercase; font-size: 10.5px; letter-spacing: .06em;
    font-weight: 700; flex: 0 0 74px; padding-top: 2px; }
  .g-vl { color: var(--slate-700); flex: 1 1 auto; }
  .g-meta { display: flex; flex-wrap: wrap; gap: 6px; }
  .g-chip { font-size: 11.5px; background: var(--slate-100); color: var(--slate-600);
    border-radius: 999px; padding: 3px 9px; }
  .g-chip b { color: var(--slate-800); }
  .g-det { font-size: 12.5px; }
  .g-det summary { cursor: pointer; color: var(--brand-700); font-weight: 600; }
  .g-det p { margin: 6px 0 0; color: var(--slate-600); }
  .g-rows { display: flex; flex-direction: column; gap: 5px; margin: 4px 0; }
  .g-row { display: flex; align-items: center; gap: 8px; font-size: 12.5px; }
  .g-row .g-lb { flex: 0 0 76px; }
  .g-prev { display: flex; align-items: center; justify-content: space-between; gap: 10px;
    border: 1px solid var(--slate-200); border-radius: 12px; padding: 12px 14px; font-size: 13px; }
  .g-btn { padding: 6px 12px; border-radius: 10px; color: var(--on-brand); font-weight: 600; font-size: 12.5px;
    font-family: var(--font-titre); }
  .g-duo { display: flex; gap: 14px; flex-wrap: wrap; }
  .g-duo .g-lb { display: block; flex: none; }
  .g-do { font-size: 12.5px; color: var(--emerald-700); }
  .g-dont { font-size: 12.5px; color: var(--rose-700); }
  .g-do b, .g-dont b { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; }
  /* Bandeau de l'apercu live : on essaie une palette de la galerie sans rien
     enregistrer. Il reste colle en haut pour qu'on puisse toujours revenir. */
  .g-apercu { position: sticky; top: 60px; z-index: 19; display: flex; align-items: center;
    justify-content: center; gap: 12px; flex-wrap: wrap; padding: 10px 16px;
    background: var(--brand-600); color: var(--on-brand); font-size: 13px; }
  .g-apercu[hidden] { display: none; }
  .g-apercu b { font-family: var(--font-titre); }
  .g-ap-note { opacity: .85; }
  .g-apercu .btn-ghost { border-color: currentColor; color: var(--on-brand); }
  .g-apercu .btn-ghost:hover { background: rgba(255, 255, 255, .16); color: var(--on-brand); }
  .g-essai { margin-top: 6px; align-self: flex-start; }
  .g-essai.actif { background: var(--brand-600); color: var(--on-brand); border-color: transparent; }
  /* Deux axes de l'apercu de style qui ne passent pas par une variable CSS :
     la respiration (styles « spacious ») et la lueur (styles neon / glow). */
  html[data-espace="1"] .g-grille { gap: 24px; }
  html[data-espace="1"] .g-card { padding: 26px; }
  html[data-espace="1"] .g-bar { margin: 26px 0 30px; }
  html[data-lueur="1"] .g-card .h3,
  html[data-lueur="1"] .g-head .brand b { text-shadow: 0 0 10px currentColor; }
  .g-foot { padding: 22px 16px 34px; }
  .g-foot p { max-width: 720px; margin: 0 auto; text-align: center; }
  .g-foot .tab.active { border: 0; }
  @media (max-width: 620px) {
    .g-grille { grid-template-columns: 1fr; }
    .g-head .container { justify-content: center; }
  }

/* ==========================================================================
   HABILLAGE 2 — 30/09/2026
   L'interface cliente reprenait le SQUELETTE de la plateforme de reference
   (EMB Money) : carte hero sombre avec son halo de lumiere, deux gros carres
   Depot / Retrait, pilules arrondies, silhouette « vallees et montagnes » sur
   la barre du bas, rond du support a halo. Une autre application tourne
   aujourd'hui avec exactement cette interface : on garde NOS ecrans et NOS
   couleurs, on change la FORME.
     - angles francs (12 / 16 px) la ou la reference etait toute en rondeurs ;
     - surfaces OPAQUES a cerne de 1 px, sans verre, sans flou, sans halo ;
       l'ombre est reservee a ce qui FLOTTE (barre du bas, bouton du support) ;
     - le bandeau d'identite remplace la carte hero : clair, sobre, avec une
       coche de marque sur son bord gauche ;
     - les deux tuiles Depot / Retrait deviennent deux LIGNES pleine largeur,
       icone carree et chevron : un tableau de bord, pas deux gros carres ;
     - la barre du bas perd sa silhouette : barre droite a cerne, bouton
       d'accueil CARRE arrondi, plus aucun rond a halo.
   Tout est porte par `body.client-app` : le PANNEAU D'ADMINISTRATION et les
   ecrans de connexion gardent leur habillage (regles plus haut dans la
   feuille). Les noms de classes ne changent pas : les tests du projet
   verrouillent la STRUCTURE (classes, ordre, liens), cet habillage ne joue que
   sur la forme.
   ========================================================================== */
body.client-app {
  --cx-r: 12px;            /* rayon courant : cartes de liste, boutons */
  --cx-r-lg: 16px;         /* rayon des grandes surfaces (bandeau, fenetres) */
  --cx-r-sm: 9px;          /* rayon des vignettes (icones d'en-tete, pastilles) */
  --cx-cerne: var(--slate-200);   /* le cerne de 1 px qui remplace les ombres */
  --cx-flat: 0 1px 2px rgba(15, 23, 42, .04);
}

/* ---------- surfaces : plates, a cerne, sans relief ---------- */
body.client-app .card,
body.client-app .panel {
  border-radius: var(--cx-r-lg); border: 1px solid var(--cx-cerne);
  box-shadow: var(--cx-flat);
}
body.client-app .modal-card { border-radius: var(--cx-r-lg); }
body.client-app .sheet-card { border-radius: var(--cx-r-lg) var(--cx-r-lg) 0 0; }
body.client-app .btn { border-radius: 999px; box-shadow: none; }
body.client-app .input, body.client-app .select, body.client-app textarea {
  border-radius: var(--cx-r);
}
body.client-app .sheet { background: rgba(8, 20, 40, .55); }
body.client-app .modal { background: rgba(8, 20, 40, .55); }

/* ---------- en-tete : pastille flottante, comme la barre du bas ----------
   Demande du client (13/10/2026, capture de l'en-tete) : « tu peux arrondir cette
   entete », puis devant le premier essai : « c'est pas joli, fais tes ajustements ».
   L'en-tete reprend donc l'habillage RETENU de la barre du bas (01/10/2026) : une
   capsule detachee des bords, fond `--surface`, cerne de 1 px, ombre douce — les
   deux barres de l'application se repondent. Ce qui bouge :
     - rayon `--radius-lg` (24 px) + `margin: 10px 10px 0` : la barre se detache des
       bords et ses QUATRE coins sont arrondis (le haut etait au ras de l'ecran, un
       rayon y serait invisible). PAS de rayon 999 px comme la barre du bas : la
       hauteur de cette barre VARIE (rembourrage porte par la reserve de la bande
       d'etat, 40 px sur grand ecran ou dans une application web installee) ; une
       capsule a bouts ronds sur une barre de 100 px mangerait le coin du logo, qui
       glisse alors dans la courbe. 24 px donne le meme dessin que les bouts de la
       barre du bas sans ce risque ;
     - le cerne fait le TOUR (il n'etait qu'en bas) : sur une barre arrondie, un trait
       pose au bas depasserait dans les coins ;
     - le trait de marque de 2 px (`::after`) est retire : il suivait un bord droit
       pleine largeur, il ne peut pas suivre une courbe. L'accent de la maison reste
       porte par la vignette du logo et le rond du compte ;
     - rembourrage LATERAL ramene de 14 a 8 px : la barre coute 20 px de largeur (ses
       marges) et l'ecran est etroit — 8 px laissent l'en-tete PLEIN sans couper le
       nom de la marque (voir la note de largeur du 01/10/2026) ;
     - `top: 10px` sur la barre COLLANTE : elle garde son jeu en haut quand on fait
       defiler, sinon elle se recolle au bord et l'arrondi parait rogne.
   Le panneau du compte suit la barre (10 px sous elle : top 73 -> 84 px). */
body.client-app .topbar {
  background: var(--surface); border: 1px solid var(--cx-cerne); border-radius: var(--radius-lg);
  margin: 10px 10px 0; padding: 12px 8px;
  box-shadow: 0 16px 32px -22px rgba(31, 111, 191, .50);
  top: 10px;
}
/* BANDE DE LA BARRE D'ETAT (symptome client « le haut est flou », capture du
   30/09/2026) : dans une APPLICATION WEB installee, le systeme dessine sa barre
   d'etat PAR-DESSUS la page (mode autonome + `viewport-fit=cover`) et lave ce
   qu'elle recouvre — le pseudo et la pastille passaient sous l'heure et la
   batterie. La reserve est donc portee par l'EN-TETE, dont le fond est clair
   (`--surface`) : sous un fond clair, un voile clair ne se voit plus. Meme
   traitement que le tchat (`.tg`). L'inset vaut 0 dans un onglet de navigateur ET
   dans notre application Android (sa barre d'etat est OPAQUE, bleu de marque : le
   WebView commence dessous) : rien ne change dans ces deux cas. */
body.client-app .topbar { padding-top: calc(12px + env(safe-area-inset-top)); }
/* Sur ecran large, la reserve du bloc grand ecran (`calc(40px + env(safe-area-inset-top))`)
   etait elle aussi ECRASEE par le `padding: 9px 14px` du client — meme piege de
   specificite que la barre du bas (0,2,1 contre 0,1,0) : le pseudo et la pastille
   restaient sous l'heure et la batterie. On la repose ici, apres la regle du
   telephone (a specificite egale, la plus BASSE gagne). */
@media (min-width: 721px) {
  body.client-app .topbar { padding-top: calc(40px + env(safe-area-inset-top)); }
}
/* GRAND ECRAN : la barre garde sa geometrie pleine largeur — elle porte la reserve
   de la bande translucide du systeme (40 px). Une capsule de 92 px avec 40 px de
   vide au-dessus serait plus laide que la barre d'origine : on ne garde donc que
   le BAS arrondi, comme les cartes de la page, et le cerne suit la courbe. Les
   bords lateraux restent a 0 : c'est `.cx-top` qui porte l'ecart de la colonne
   (16 px + zone sure), sinon le logo s'enfoncerait de deux rembourrages. */
@media (min-width: 721px) {
  body.client-app .topbar {
    margin: 0; top: 0; padding-left: 0; padding-right: 0; box-shadow: none;
    border-width: 0 0 1px; border-radius: 0 0 var(--cx-r-lg) var(--cx-r-lg);
  }
}
/* le panneau du compte est ancre SOUS l'en-tete : il suit donc la reserve, sinon
   il recouvre la derniere ligne de l'en-tete quand la bande grandit. Au-dela de
   721 px c'est le bloc grand ecran qui le place (102 px), cette regle ne
   s'applique pas. */
@media (max-width: 720px) {
  body.client-app .cx-acc { top: calc(87px + env(safe-area-inset-top)); }
}
/* Le trait de marque de 2 px (`::after`, pose le 02/10/2026 sous la barre pleine
   largeur) est RETIRE avec l'arrondi (13/10/2026) : un trait colle au bas d'une
   capsule depasserait dans les deux coins courbes. Si le client le redemande, il
   faut le poser EN INTERIEUR de la capsule (bord bas du contenu, rayon 2 px), pas
   sur le bord de la barre. */
/* La nuit, le cerne passe en blanc translucide comme celui de la barre du bas :
   `--cx-cerne` n'est pas redefini en theme sombre, un cerne gris fonce disparait
   sur la surface de nuit. */
:root[data-theme="dark"] body.client-app .topbar {
  background: var(--surface); border-color: rgba(255, 255, 255, .10);
}
body.client-app .cx-logo { width: 40px; height: 40px; border-radius: 12px; background: var(--navy); }
body.client-app .cx-name { font-size: 18px; font-weight: 800; letter-spacing: -.01em; display: block; }
/* « CASHDESK » en BLEU ROI sous le nom (maquette) : c'est le seul bleu de
   l'en-tete, avec le rond gris et le rond blanc autour. */
body.client-app .cx-top .who {
  margin-top: 1px; font-size: 11.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .16em; color: var(--roi);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Demande du client (capture du 02/10/2026) : « reduit le nom du client si c est
   trop long ». Le nom de l'EN-TETE porte deja la coupe en points de suspension ;
   au-dela de 16 caracteres (classe posee par app.js, `nomLong`) on REDUIT aussi la
   taille et le tracking — c'est ce qui mange la largeur de la barre. Le bandeau du
   PROFIL, lui, n'avait aucune coupe : le nom y tient desormais sur UNE ligne,
   reduit et coupe de la meme facon. */
body.client-app .cx-top .who.who-long { font-size: 11px; letter-spacing: .06em; }
body.client-app .pf-nom { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
body.client-app .pf-nom.pf-nom-long { font-size: 15px; }
body.client-app .cx-ico {
  width: 35px; height: 35px; border-radius: 999px;
  border: 1px solid var(--cx-cerne); background: var(--surface);
}
/* les icones sont DESSINEES (trait) : a 22 px elles restaient grises ; le trait
   passe a 2,2 comme sur la barre du haut du panneau (01/10/2026). */
body.client-app .cx-ico svg { stroke-width: 2; }
body.client-app .cx-ico:hover { background: var(--brand-50); }
body.client-app .cx-avatar { border-radius: 999px; }

/* ---------- carte du haut : LE CADRE DEMANDE PAR LE CLIENT (02/10/2026) -------
   Le client a montre la carte qu'il veut — bleu nuit, grand rayon, posee sur fond
   pale — et demande « change le cadre … exactement comme sur l'image ». L'habillage
   2 repeignait cette carte en SURFACE CLAIRE (fond de page, liseré de 1 px, coche
   de marque a gauche) : on lui rend son DESSIN D'ORIGINE, le degrade bleu nuit de
   la marque et son orbe de lumiere, en GARDANT la geometrie du 01/10 (rayon 26,
   rembourrage 13/15/17, titre 16 px, bouton de copie 34 px). */
body.client-app .cx-hero {
  position: relative; overflow: hidden; border-radius: var(--cx-r-lg);
  padding: 14px 16px 14px 20px;
  /* encre et couleur viennent du DESSIN DE BASE de la carte (encre blanche) ;
     le theme sombre garde lui aussi SA carte bleu nuit, celle de la base. */
  background: linear-gradient(150deg, var(--brand-900), var(--night) 62%);
  border: 0; box-shadow: 0 22px 50px -26px rgba(15, 23, 42, .8);
}
/* l'orbe de lumiere de la carte bleu nuit revient (l'image du client le porte) */
body.client-app .cx-hero::after { display: block; }
/* la coche de marque a gauche a QUITTE cette carte le 02/10/2026 : l'image montree
   par le client n'en porte pas (elle reste sur les autres surfaces du socle). */
body.client-app .cx-hero::before { display: none; }
/* (pas de variante sombre ici : celle de la base peint deja cette carte.) */
/* La pastille reprend celle de l'image : arrondie, contour clair translucide, texte
   blanc — le dessin du socle (fond pale, texte bleu) la rendait illisible sur la
   carte bleu nuit. Seul l'empilement au-dessus de l'orbe est garde. */
body.client-app .cx-pill { position: relative; z-index: 1; }
body.client-app .cx-hello-row { margin-top: 10px; justify-content: flex-end; }  /* le titre est parti (13/10/2026) : le bouton de copie reste a DROITE */
/* Le titre garde sa TAILLE du 01/10 ; sa couleur vient du dessin bleu nuit
   (encre blanche de la carte). Le mot de marque prend le bleu clair de l'image,
   celui de la carte visiteuse : « exactement comme sur l'image ». */
body.client-app .cx-hello { font-size: 18px; }
/* 02/10/2026 — capture du client : un pseudo long passait sur TROIS lignes et faisait
   grandir la carte du haut ; la salutation tenait donc sur UNE ligne, coupee par des
   points de suspension (le pseudo entier restait copiable par le bouton d'a cote).
   MEME JOUR, demande suivante : « supprime Bonjour <pseudo> ». La salutation a donc
   disparu et c'est le TITRE de bienvenue qui occupe cette ligne, avec le meme bouton
   de copie — la regle ci-dessous sert desormais au titre : si la marque s'allonge un
   jour, elle est coupee au lieu de faire grandir la carte. `cx-hello-long` n'est plus
   pose par personne : sa regle dort, prete si la salutation revient. */
body.client-app .cx-hello-row .cx-hello {
  display: flex; align-items: baseline; gap: 6px; min-width: 0; overflow-wrap: normal;
}
body.client-app .cx-hello-row .cx-hello > b {
  min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
body.client-app .cx-hello-row .cx-hello.cx-hello-long { font-size: 14px; }
/* Le bouton de copie redevient le CARRE BLANC de la carte bleu nuit (fond blanc
   assume, deja dans la liste des blancs autorises d'ui_check) ; sa TAILLE reste
   celle du 01/10 (38 puis 34 px sur telephone). */
body.client-app .cx-copy {
  width: 38px; height: 38px; border-radius: var(--cx-r-sm); border: 0;
  background: var(--surface); color: var(--slate-900);
}

/* ---------- Depot / Retrait : deux CARTES teintees cote a cote ----------
   Habillage de l'espace client : memes cartes que partout (voir plus haut), mais
   angles francs et cerne de l'habillage, et sans ombre portee. Le bleu et l'or
   sont ceux de la maison. */
body.client-app .cx-acts { gap: 10px; margin-top: 16px; }
body.client-app .cx-act {
  border-radius: var(--cx-r-lg); border: 1px solid var(--cx-cerne); box-shadow: var(--cx-flat);
  padding: 12px 12px 14px;
}
body.client-app .cx-act-ico { width: 38px; height: 38px; border-radius: 999px; margin-bottom: 9px; }

/* CARTES D'ACTION EN VERRE (demande du client, 30/09/2026 : « maintenant rend le
   transparent comme du verre »). Du verre, ce sont DEUX choses ensemble, jamais l'une
   sans l'autre : une TEINTE translucide (les jetons --act-* a 45 % : le fond de page
   compose la couleur) ET un FLOU de ce qu'il y a derriere (backdrop-filter) — sans le
   flou, une transparence ne se lit pas comme du verre, juste comme une couleur delavee.
   L'ENCRE, elle, change avec le THEME, et c'est obligatoire : la vitre claire du jour
   exige une encre SOMBRE (du blanc sur une vitre pale tombe a 2:1, illisible) et la
   vitre composee sur la nuit, elle, est foncee : elle exige une encre BLANCHE. Ce sont
   donc les deux seules lignes du client qui basculent la nuit. Mesures ui_check
   9quinquies : 4,9:1 a 10,8:1 le jour, 7,8:1 a 12,5:1 la nuit (AA demande 4,5:1). */
body.client-app .cx-act { backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); }
body.client-app .cx-act-dep { color: var(--brand-900); }
body.client-app .cx-act-wd { color: var(--act-encre-vert); }
body.client-app .cx-act-ico { background: rgba(255, 255, 255, .55); }
/* UNE REGLE PAR CARTE, sur une seule ligne : les controles de ui_check ne lisent que
   la DERNIERE ligne d'un selecteur etale (une liste « .cx-act-dep, .cx-act-wd { » fait
   disparaitre la premiere des deux). */
:root[data-theme="dark"] body.client-app .cx-act-dep { color: var(--on-brand); }
:root[data-theme="dark"] body.client-app .cx-act-wd { color: var(--on-brand); }
:root[data-theme="dark"] body.client-app .cx-act-ico { background: rgba(255, 255, 255, .18); }
/* ---------- CARTE D'ACTION FERMEE PAR LE PANNEAU (12/10/2026) ----------
   Les deux interrupteurs de l'ecran « Application mobile » (Boutons Depot /
   Retrait) eteignent une carte : elle garde sa place et son dessin, mais elle
   n'est plus un LIEN et son sous-titre dit « Indisponible ». La vitre perd sa
   teinte — un service ferme ne doit pas avoir l'air d'un service ouvert — et
   prend le gris du theme (le libelle reste lisible : encre du theme, pas de
   blanc sur du pale).
   LE NOM COMPTE : `indispo` ne contient NI `.cx-act-dep` NI `.cx-act-wd`. Les
   controles de contraste de ui_check lisent la DERNIERE regle dont le dernier
   jeton CONTIENT la cible (`cible in fin`) : une regle nommee
   `.cx-act-dep-indispo` passerait devant la vitre et fausserait la mesure. */
body.client-app .cx-act.indispo { background: var(--slate-100); border-color: var(--slate-200);
  cursor: default; }
body.client-app .cx-act.indispo:hover { box-shadow: var(--cx-flat); }
body.client-app .cx-act.indispo:active { transform: none; }
body.client-app .cx-act.indispo .cx-act-ico { background: var(--surface); color: var(--slate-400); }
body.client-app .cx-act.indispo .cx-act-t { color: var(--slate-600); }
body.client-app .cx-act.indispo .cx-act-s { color: var(--slate-500); opacity: 1; font-weight: 600; }
body.client-app .cx-msg { border-radius: var(--cx-r); border-color: var(--cx-cerne); box-shadow: var(--cx-flat); }
body.client-app .cx-msg-ico { border-radius: 999px; }
body.client-app .cx-suivi { border-radius: var(--radius-lg); border-color: var(--cx-cerne); box-shadow: var(--cx-flat); }
body.client-app .cx-suivi-ico { border-radius: 999px; }
body.client-app .cx-suivi-go { border-radius: 999px; }

/* ---------- raccourcis : boutons courts, en pastilles ---------- */
body.client-app .cx-racc-bas { margin-top: 14px; }
body.client-app .cx-racc-a {
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 15px;
  border-radius: 999px; font: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--slate-700); background: var(--surface); border: 1px solid var(--cx-cerne);
  box-shadow: var(--cx-flat); -webkit-backdrop-filter: none; backdrop-filter: none;
}
body.client-app .cx-racc-a svg { color: var(--brand-600); }
:root[data-theme="dark"] body.client-app .cx-racc-a svg { color: var(--brand-300); }

/* ---------- reseaux sociaux : vignettes carrees ---------- */
body.client-app .cx-social { margin-top: 22px; }
body.client-app .cx-social-t {
  font-size: 12px; text-transform: uppercase; letter-spacing: .14em; color: var(--slate-500);
}
body.client-app .cx-soc {
  width: 46px; height: 46px; border-radius: 14px; border: 1px solid var(--cx-cerne);
  box-shadow: var(--cx-flat);
}

/* ---------- carte de tournoi : angles francs, cerne ---------- */
body.client-app .cx-tournoi {
  border-radius: var(--cx-r-lg); border: 1px solid var(--cx-cerne); box-shadow: var(--cx-flat);
}

/* ---------- barre du bas : pilule d'accueil a gauche, icones a droite ----------
   (30/09/2026, 2e demande du client : « colle exactement a leur barre »). La barre
   est un BANDEAU DETACHE des bords, comme la leur : elle flotte a 10 px du bord
   gauche et du bord droit, et se pose 10 px au-dessus du bord bas. L'entree
   active y est la pilule teintee, les autres des icones seules. */
/* La reserve suit la ZONE DE GESTES comme la barre elle-meme (`margin: 0 10px
   calc(10px + env(safe-area-inset-bottom))` juste en dessous) : sans ce terme,
   la barre descend plus bas que la reserve et la derniere ligne de la page
   reste coincee sous la barre (signale par le client le 03/10/2026). */
/* 12/11/2026 — « y a pas l'espace en bas pour defiler vers le bas » : la barre
   du bas est FIXE, et sur un accueil court le dernier bloc tombait pile dessous,
   sans marge et sans rien a faire defiler. La reserve passe de 104 a 150 px
   (barre ~62 + ses 10 px de marge + 24 px de respiration + la zone sure) : le
   dernier raccourci se degage de la barre, et la page a de quoi glisser. */
body.client-app .app-shell { padding-bottom: calc(150px + env(safe-area-inset-bottom)); }
/* BARRE DU BAS : pastille flottante arrondie, entree active en pilule pleine.
   (01/10/2026 — le client a laisse la main : « c'est pas joli, tu peux faire a ta
   guise ». La ligne en vallee est retiree.) Une seule capsule, arrondie aux DEUX
   bouts, posee a 10 px des bords : le fond commun RELIE les trois entrees, et
   l'active s'y detache en pilule pleine a la couleur de la maison. Fin, opaque,
   ombre douce : rien de decoratif qui puisse alourdir. */
/* 12/11/2026 — « pas de barre de navigation flottante, fais-la sur l'ecran sans le
   flottant » (capture du proprietaire) : la capsule arrondie posee a 10 px des
   bords est RETIREE. La barre reprend la geometrie de la barre d'origine — bord a
   bord, collee en bas, rayon nul, un trait fin en haut — et garde son fond opaque
   (sans lui, le contenu defilerait derriere les icones). L'entree active reste la
   pilule pleine. `margin: 0` et `width: auto` neutralisent aussi le recentrage du
   bloc « grand ecran » (688 px) : une barre d'ecran ne se borne pas. */
body.client-app .bottomnav {
  left: 0; right: 0; bottom: 0;
  margin: 0; width: auto; max-width: none;
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
  background: var(--surface);
  border: 0; border-top: 1px solid var(--cx-cerne); border-radius: 0;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  box-shadow: none;
}
body.client-app .bottomnav .item { border-radius: 999px; padding: 9px 14px; }
body.client-app .bottomnav .item.active {
  /* BLEU MARINE du prompt (#0A4232) : la pilule de l'onglet ouvert se detache de
     la barre blanche. La nuit, la meme intention demande un bleu plus clair pour
     rester visible sur la barre sombre : c'est le bleu ROI du prompt.
     12/11/2026 (maquette) : la pilule est HORIZONTALE — icone + libelle cote a
     cote — et prend la largeur de son contenu ; les trois autres restent des
     icones empilees sur leur libelle. */
  flex: 0 0 auto;
  flex-direction: row; gap: 8px;
  padding: 11px 18px;
  box-shadow: 0 10px 20px -14px rgba(15, 44, 89, .8);
}
body.client-app .bottomnav .item.active span { font-size: 13px; font-weight: 700; }
body.client-app .bottomnav .item.active svg { width: 20px; height: 20px; }
:root[data-theme="dark"] body.client-app .bottomnav {
  background: var(--surface);
  border-color: rgba(255, 255, 255, .10);
}
:root[data-theme="dark"] body.client-app .bottomnav .item.active { background: var(--roi); }
/* LARGE ECRAN (>= 721 px) : la barre bornee doit etre RECENTREE ICI.
   Le bloc « grand ecran » (plus haut dans la feuille) la pose par une MARGE
   NEGATIVE (`left: 50%; margin-left: -344px; width: 688px`). Or la regle du client
   juste au-dessus porte un `margin: 0 10px ...` PLUS SPECIFIQUE (0,2,1 contre
   0,1,0) : elle ecrasait ce -344px et la barre partait du MILIEU de l'ecran en
   debordant a droite — « Historique » hors ecran, seule la pastille « Accueil » et
   l'icone du milieu restaient visibles. Constat du client le 30/09/2026, capture a
   l'appui : bord gauche de la barre mesure a 382 px sur une page de 744 px, soit
   exactement 50 % + les 10 px de marge annonces par le calcul du CSS.
   On repose donc la geometrie bornee du client en ecrasant sa marge LATERALE ; sa
   marge BASSE (10 px + zone de gestes) n'est pas touchee, et sur telephone
   (< 721 px) cette regle ne s'applique pas : la barre reste bord a bord. */
@media (min-width: 721px) {
  /* 12/11/2026 — RIEN A REPOSER ICI : la barre du client n'est plus bornee. Depuis
     la demande « pas de barre de navigation flottante », c'est une bande pleine
     largeur collee au bord bas (bloc « design system » plus bas) : la geometrie
     bornee de 688 px du bloc grand ecran ne vaut plus que pour les pages SANS
     `body.client-app`. Ce bloc reste present pour garder la trace du -344px et ne
     pas le voir revenir par copie. */
}
/* (la silhouette « vallees et montagnes » de la reference est retiree partout depuis
   le 30/09/2026 : le bord haut de la barre est arrondi, elle depasserait dans les
   coins. La regle du bloc habillage 2 qui la masquait dans l'espace client n'a plus
   d'objet et a ete retiree avec elle.) */
/* ---------- panneau du compte : angles francs, cerne ---------- */
body.client-app .cx-acc {
  border-radius: var(--cx-r-lg); border: 1px solid var(--cx-cerne);
  box-shadow: 0 18px 40px -20px rgba(15, 23, 42, .5);
}
body.client-app .cx-acc-head { border-bottom: 1px solid var(--cx-cerne); }
body.client-app .cx-acc-row + .cx-acc-row { border-top: 1px solid var(--cx-cerne); }
body.client-app .cx-acc-sep { border-top: 1px solid var(--cx-cerne); }

/* ---------- ecrans de connexion / inscription (habillage 2) ---------- */
/* Le fond constelle de la reference (un reseau de points relies) disparait : la
   page reste sombre, sobre, avec son seul halo de marque. */
body.client-app.auth-page .auth-shell::before { display: none; }
/* LA COCHE DE MARQUE EST RETIREE (09/11/2026, demande du client : « enleve la
   ligne bleu qui se trouve en haut du panneau d inscription et de connexion »).
   C'etait un lisere de 3 px en degrade pose sur le bord haut de la carte, dans
   l'application (ecrans de connexion ET d'inscription). */
body.client-app.auth-page .auth-card::before { content: none; }
body.client-app.auth-page .auth-logo { border-radius: 11px; box-shadow: none; }
/* champs : angles francs de la maison (la reference etait en rayon 20) */
body.client-app.auth-page .fx-in { border-radius: var(--cx-r); }
body.client-app.auth-page .auth-soc-row a { border-radius: 14px; }


/* ==================== MODE DE DEPOT ET REGLAGES (12/10/2026) ====================
   Demande du client : « modifier les apercus et rendre moderne, acces a l'oeil les
   options ». Les quatre modes de depot deviennent des PASTILLES, chaque pays a sa
   carte, et sous les choix s'affiche l'APERCU de ce que le client verra. Les
   reglages de la passerelle sont replies en sections titrees, les cles secretes se
   masquent, et le retrait automatique a un vrai interrupteur. Tout est bati sur les
   variables du theme : les deux themes suivent sans retouche. */
.opt-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); }
.opt-card { display: flex; flex-direction: column; gap: 10px; padding: 14px;
  border-radius: var(--radius-sm); background: var(--surface-2); box-shadow: var(--ring); }
.opt-hd { display: flex; align-items: center; gap: 8px; }
.opt-flag { font-size: 20px; line-height: 1; }
.opt-nom { font-weight: 700; }
.opt-code { font-size: 11px; color: var(--slate-500); }
.opt-hd .badge { margin-left: auto; }
.seg { display: flex; gap: 4px; flex-wrap: wrap; padding: 4px; border-radius: 999px;
  background: var(--slate-100); }
.seg-btn { border: 0; cursor: pointer; font: inherit; font-size: 13px; font-weight: 600;
  color: var(--slate-600); background: transparent; padding: 7px 12px; border-radius: 999px;
  transition: background .2s, color .2s; }
.seg-btn:hover { color: var(--brand-600); }
.seg-btn.is-on { background: var(--surface); color: var(--brand-600); box-shadow: var(--ring); }
.opt-vu { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px;
  border-radius: var(--radius-sm); background: var(--brand-50); }
.opt-vu .v-ico { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 9px; display: flex;
  align-items: center; justify-content: center; background: var(--surface); color: var(--brand-600); }
:root[data-theme="dark"] .opt-vu .v-ico { color: var(--brand-400); }
.opt-vu .v-titre { font-weight: 700; font-size: 13px; color: var(--slate-800); }
.opt-vu .v-texte { font-size: 12.5px; line-height: 1.5; color: var(--slate-600); }
.opt-vu .v-code { display: inline-block; margin-top: 6px; padding: 3px 8px; border-radius: 8px;
  background: var(--surface); color: var(--slate-900); font-size: 12.5px; font-weight: 600;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.grp + .grp { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--slate-200); }
.grp-hd { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.grp-hd .g-ico { width: 28px; height: 28px; border-radius: 9px; display: flex; align-items: center;
  justify-content: center; background: var(--brand-50); color: var(--brand-600); }
:root[data-theme="dark"] .grp-hd .g-ico { color: var(--brand-400); }
.grp-hd .g-titre { font-weight: 700; font-size: 13.5px; }
.grp-hd .g-hint { margin-left: auto; font-size: 11.5px; color: var(--slate-500); text-align: right; }
.field-secret { display: flex; gap: 6px; align-items: center; }
.field-secret .input { flex: 1 1 auto; min-width: 0; }
.inter { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-weight: 600; }
.inter input { appearance: none; -webkit-appearance: none; width: 44px; height: 26px; margin: 0;
  padding: 0; border: 0; border-radius: 999px; background: var(--slate-300); position: relative;
  cursor: pointer; transition: background .2s; flex: 0 0 auto; }
.inter input::after { content: ''; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px;
  border-radius: 50%; background: var(--slate-50); transition: transform .2s;
  box-shadow: 0 1px 3px rgba(15, 23, 42, .35); }
:root[data-theme="dark"] .inter input::after { background: var(--slate-600); }
.inter input:checked { background: var(--brand-600); }
.inter input:checked::after { transform: translateX(18px); }


/* =====================================================================
   ACCUEIL — LES DEUX BOUTONS ET LES TROIS TUILES DE FRANCKO RECHARGE
   (10/11/2026 : « sur mon projet flash pay change les bouttons comme ca —
   comme sur franko recharge », capture a l'appui).
   Ce que montre la capture, et qui est repris tel quel :
     - deux CARTES-APLATS cote a cote : Depot en bleu plein, Retrait en vert
       plein, TITRE en gras et sous-titre, encre blanche, rayon 16, AUCUNE
       icone, AUCUN chevron ;
     - trois TUILES BLANCHES sous les cartes, une pastille ronde de couleur et
       le libelle en gras dessous : Coupons du jour (or), Mes IDs (bleu),
       Parrainage (bleu).
   Nos couleurs : le bleu de la maison #0B2E55 au depot (c'est aussi le bleu de
   la capture), notre or --amber-500 sur la tuile des coupons, le vert de la
   reference au retrait.
   Mesures : blanc sur #0B2E55 = 9,9:1 ; blanc sur #0E7A3C (jour) = 5,4:1 ;
   blanc sur #047857 (nuit) = 5,5:1 — AA pour le sous-titre de 13 px.
   ===================================================================== */
/* MESURES RELEVEES AU PIXEL sur la capture (1272 px de large = 424 CSS x 3) :
   cartes 189 x 100, rayon 16, ecart entre les deux 12 px ; tuiles 125 x 69,
   rayon 14, pastille ronde 36 px, libelle 11 px, ecart cartes -> tuiles 10 px.
   Le texte des cartes est a 24 px du haut et du bas (mesure), d'ou
   `min-height: 100px` + centrage vertical plutot qu'un rembourrage en dur. */
body.client-app .cx-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px; }
body.client-app .cx-act {
  border-radius: 16px; padding: 14px 16px; border: 1px solid transparent;
  min-height: 100px; justify-content: center;
  box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none;
}
/* la pastille d'icone n'est plus dessinee (elle n'est meme plus rendue) */
body.client-app .cx-act-ico { display: none; }
body.client-app .cx-act-t {
  font-size: clamp(14px, 4.2vw, 19px); font-weight: 800; letter-spacing: -.02em;
  line-height: 1.15; padding-right: 4px; hyphens: none; overflow-wrap: break-word;
}
body.client-app .cx-act-s { font-size: 13px; letter-spacing: 0; opacity: .95; line-height: 1.25; }
body.client-app .cx-act-dep {
  background: var(--cx-dep-fond); border-color: var(--cx-dep-fond); color: var(--on-brand);
}
body.client-app .cx-act-wd {
  background: var(--cx-wd-fond); border-color: var(--cx-wd-fond); color: var(--on-brand);
}
:root[data-theme="dark"] body.client-app .cx-act-dep {
  background: var(--cx-dep-fond); border-color: var(--cx-dep-fond); color: var(--on-brand);
}
:root[data-theme="dark"] body.client-app .cx-act-wd {
  background: var(--cx-wd-fond); border-color: var(--cx-wd-fond); color: var(--on-brand);
}

/* LES CINQ RACCOURCIS CIRCULAIRES (12/11/2026, prompt : « 5 icones circulaires
   avec libelles, defilement horizontal »). Une seule ligne qui glisse sous le
   doigt : plus de grille de trois tuiles carrees. Chaque raccourci = une PASTILLE
   RONDE de couleur et son libelle dessous. */
body.client-app .cx-tuiles {
  display: flex; gap: 16px; margin-top: 16px; padding: 2px 2px 4px;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
body.client-app .cx-tuiles::-webkit-scrollbar { display: none; }
body.client-app .cx-tui {
  flex: 0 0 auto; width: 68px; padding: 0; background: none; border-radius: 0;
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  font-family: inherit; text-align: center; color: var(--slate-900);
  scroll-snap-align: start;
}
body.client-app .cx-tui-rond {
  width: 54px; height: 54px; border-radius: 50%; display: grid; place-items: center; color: #fff;
  border: 1px solid var(--cx-cerne); box-shadow: var(--cx-flat);
}
body.client-app .cx-tui-rond svg { width: 24px; height: 24px; stroke: currentColor; }
body.client-app .cx-tui-lib {
  font-size: 11px; font-weight: 600; line-height: 1.15; color: var(--slate-600);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.client-app .cx-tui-rond.or { background: var(--amber-500); }
body.client-app .cx-tui-rond.bleu { background: var(--brand-600); }
body.client-app .cx-tui-rond.vert { background: var(--emerald-600); }
body.client-app .cx-tui-rond.violet { background: var(--violet-500); }
body.client-app .cx-tui-rond.whatsapp { background: var(--emerald-500); }

/* =====================================================================
/* =====================================================================
   SECTION « DIRECT » RETIREE (18/10/2026, demande du client) : l'espace
   client n'affiche plus de matchs. Les styles de la carte d'accueil, du
   lecteur en plein ecran, de la ligne de match et du point « en direct »
   sont partis avec l'ecran. Le panneau garde le sien : il n'utilise QUE des
   classes communes (carte, champ, bouton de la feuille).
   ===================================================================== */

/* =====================================================================
   ESPACE CLIENT — socle d'habillage commun (30/09/2026)
   Demande du client : « moderniser l'interface client, toutes ses pages ».
   Plutot que de repeindre chaque ecran a la main, on remonte le SOCLE que
   tous les ecrans partagent deja (.card, .card-hd, .card-bd, .list-item,
   .tabs, .notice, .kpi, .btn) : chaque page herite du meme air sans qu'on
   touche a son contenu. Tout est borne a `body.client-app` — le panneau
   d'administration et les ecrans de connexion ne bougent pas d'un pixel.
   Aucune couleur neuve : uniquement les variables de la palette (et les
   familles emerald/rose/sky/amber ont leur variante de nuit, verifiee par
   les controles de contraste de ui_check).
   ===================================================================== */

/* ---- en-tete d'ecran : tuile d'icone, titre, sous-titre ---- */
body.client-app .ui-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
/* ---- tuile d'icone : en-tete d'ecran ET en-tete de carte ----
   La palette fait tout le travail : --brand-50 bascule seule en bleu nuit. */
body.client-app .ui-ico { flex: 0 0 auto; width: 42px; height: 42px; border-radius: 14px;
  display: grid; place-items: center; background: var(--brand-50); color: var(--brand-600); }
body.client-app .ui-ico.sm { width: 32px; height: 32px; border-radius: 10px; }
body.client-app .ui-ico.sm svg { width: 18px; height: 18px; }
body.client-app .ui-head .ui-t { font-size: 21px; font-weight: 700; letter-spacing: -.012em; line-height: 1.15; }
body.client-app .ui-head .ui-s { font-size: 12.5px; color: var(--slate-500); margin-top: 2px; }

/* ---- cartes : un seul air dans tout l'espace client ---- */
body.client-app .card { border-radius: 18px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 16px 32px -26px rgba(15, 47, 92, .55); }
body.client-app .card-hd { padding: 14px 16px; min-height: 52px; }
body.client-app .card-bd { padding: 16px; }
body.client-app .card-ft { padding: 12px 16px; }

/* ---- lignes de liste : cible tactile, tuile d'icone, etat presse ---- */
/* Depuis le 01/10/2026 l'historique n'utilise plus « .list-item » : ses
   operations vivent dans « .hist-card ». La cible de doigt, l'ecart et l'etat
   presse se posent donc AUSSI sur cette classe — sinon les cartes de
   l'historique perdent 62 px de hauteur et le retour au toucher. */
body.client-app .list-item, body.client-app .hist-card { min-height: 62px; padding: 13px 16px; gap: 12px;
  transition: background .15s ease; }
body.client-app .list-item:active, body.client-app .list-item:hover,
body.client-app .hist-card:active, body.client-app .hist-card:hover { background: var(--slate-50); }
body.client-app .li-ico { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 13px;
  display: grid; place-items: center; background: var(--brand-50); color: var(--brand-600); }
body.client-app .li-ico.i-emerald { background: var(--emerald-50); color: var(--emerald-600); }
body.client-app .li-ico.i-rose { background: var(--rose-50); color: var(--rose-600); }
body.client-app .li-ico.i-sky { background: var(--sky-50); color: var(--sky-600); }
body.client-app .li-ico.i-amber { background: var(--amber-50); color: var(--amber-600); }

/* ---- onglets de filtre : pilules plus franches, doigt compris ---- */
body.client-app .tabs { gap: 8px; padding-bottom: 4px; }
body.client-app .tab { min-height: 38px; display: inline-flex; align-items: center; padding: 8px 14px; }

/* ---- bandeaux d'information : memes couleurs d'etat, plus ronds ---- */
body.client-app .notice { border-radius: 16px; padding: 13px 14px; }
body.client-app .empty { padding: 30px 16px; }
body.client-app .empty .strong { font-size: 15px; }

/* ---- compteurs : alignes sur les tuiles de « Mon compte » ---- */
body.client-app .kpi { border-radius: 16px; padding: 14px; }

/* ---- champs et boutons : hauteur de doigt, coins coherents ---- */
body.client-app .input, body.client-app .select, body.client-app textarea.input { min-height: 46px; }
body.client-app .btn { min-height: 42px; }
body.client-app .btn-sm { min-height: 34px; }

/* ---- accueil : la carte du haut, les tuiles rondes et la banniere de tournoi
   prennent les memes rayons et la meme lumiere que le reste de l'espace client
   (la silhouette de la barre du bas et la disposition, elles, ne bougent pas). ---- */
/* CARTE DU HAUT : COMPACTE ET PLUS RONDE (01/10/2026, capture du client :
   « reduit et arrondit le »). Le socle a le DERNIER MOT sur cette carte —
   c'est ICI qu'on change ses mesures, jamais dans l'habillage 2 plus haut.
   Rayon 22 -> 26 px ; rembourrage 20 -> 13/17 px ; et les trois textes qui
   faisaient la hauteur : titre 18 -> 16 px, question 26 -> 19 px, phrase de
   service 13,5 -> 12 px. Le bouton de copie suit la meme echelle (38 -> 34 px,
   et son icone 22 -> 18 via homeView dans app.js). */
body.client-app .cx-hero { border-radius: 26px; padding: 13px 15px 13px 17px; }
body.client-app .cx-hello-row { margin-top: 7px; }
body.client-app .cx-hello { font-size: 16px; }
body.client-app .cx-copy { width: 34px; height: 34px; border-radius: 11px; }
body.client-app .cx-ask { margin-top: 9px; font-size: 19px; }
body.client-app .cx-ask-sub { margin-top: 5px; font-size: 12px; }
body.client-app .cx-hero::before { top: 10px; bottom: 10px; }
/* les deux cartes d'action de l'accueil (30/09/2026) : memes rayons et meme
   lumiere que le reste de l'espace client.
   ARRONDI (30/09/2026, demande du client : « arrondit bien les boutons de
   l'interface ») : 18 px -> 22 px, le rayon de la carte du haut. CE BLOC EST LE
   DERNIER MOT sur les rayons de l'accueil (il vient apres le bloc habillage 2) :
   c'est ICI qu'on change celui des deux boutons Depot / Retrait, pas plus haut. */
/* 11/11/2026 — les deux boutons Depot / Retrait ne sont plus des cartes : leur
   rayon (999 px, la pilule) vit dans le bloc « BOUTONS Déposer / Retirer » a la
   FIN de la feuille. Ne pas remettre de rayon ici : il serait sans effet, et
   deux endroits pour une mesure finissent toujours par diverger. */
body.client-app .cx-msg { border-radius: 22px; }
body.client-app .cx-suivi { border-radius: 22px; }
body.client-app .cx-tournoi { border-radius: 22px; }
/* Les deux raccourcis « Mes IDs » et « Parrainage » gardent LEUR TAILLE ET LEUR
   FORME D'ORIGINE (petits boutons cote a cote, `.cx-racc-a` plus haut). Une
   version « carte » plus haute a ete essayee le 30/09/2026 et refusee par le
   client : « c'est trop gros ». Ne pas la remettre. */

/* =====================================================================
   LE CLAVIER DU TELEPHONE (30/09/2026)
   Capture du client au depôt, étape 3 : le champ « Numero mobile money » et sa
   phrase etaient CACHES SOUS la barre du bas, clavier ouvert. La barre est
   `position: fixed` : le navigateur remonte bien le champ juste au-dessus du
   clavier… et la barre se posait exactement là.
   Des qu'un champ de saisie prend le focus, la barre s'efface donc
   (`data-clavier="1"` sur <body>, posé par suivreClavier() dans app.js) ; elle
   revient quand le champ est quitte.
   La regle est bornee au client (`body.client-app[...]`) comme TOUT ce bloc : c'est
   aussi ce qui la fait gagner sur `body.client-app .bottomnav`, avec une
   specificite superieure. Ne pas la remonter plus haut.
   ===================================================================== */
body.client-app[data-clavier="1"] .bottomnav { display: none; }



/* ---------------------------------------------------------------------------
   DEPOT : MAQUETTE « RECHARGER 1XBET », HABILLAGE NEUTRE (21/10/2026)
   Retours du client, dans l'ordre : la maquette section par section, « pas
   moderne », « arrondit, separe les etapes, ajoute le bleu ou c'est necessaire »,
   puis « supprime le bleu ».
   Etat retenu : chaque ETAPE est un bloc blanc tres arrondi (20 px), ombre
   douce, espace entre les blocs — et l'habillage est NEUTRE (graphite/slate) :
   plus de libelles bleus, plus de trait bleu, plus de pastille bleue, plus de
   contour bleu sur les pilules, plus de fond bleu au recapitulatif. Le GRIS
   NOIR (slate-900) porte les etats choisis ; le seul BLEU qui reste est le
   bouton d'action principal « Continuer » (c'est l'action, pas une decoration).
   Rien qu'ici : les autres ecrans ne changent pas. Page en PLEIN ECRAN.
   Mesure au banc de rendu (VPS) : references/banc-de-rendu.md.
--------------------------------------------------------------------------- */
body.client-app.depot-page { background: var(--slate-50); }
body.client-app.depot-page .topbar,
body.client-app.depot-page .bottomnav,
body.client-app.depot-page .cx-lang-fab { display: none; }
body.client-app.depot-page .app-shell {
  padding: calc(env(safe-area-inset-top) + 6px) 16px calc(16px + env(safe-area-inset-bottom));
  max-width: 720px;
}
body.client-app .dp-page {
  position: relative; max-width: 720px; margin: 0 auto;
  display: flex; flex-direction: column;
  min-height: calc(100vh - env(safe-area-inset-top) - 32px);
  min-height: calc(100dvh - env(safe-area-inset-top) - 32px);
}
/* en-tete : pastille de retour neutre, titre centre */
body.client-app .dp-tete {
  display: grid; grid-template-columns: 40px 1fr 40px; align-items: center;
  gap: 6px; margin: 2px 0 12px;
}
body.client-app .dp-back {
  width: 40px; height: 40px; display: inline-flex; align-items: center;
  justify-content: center; border: 0; border-radius: 14px; background: var(--surface);
  color: var(--slate-700); padding: 0; justify-self: start; cursor: pointer;
  box-shadow: 0 1px 3px rgba(16,24,40,.08);
}
body.client-app .dp-back svg { transform: rotate(180deg); }
body.client-app .dp-back:active { background: var(--slate-100); }
body.client-app .dp-titre {
  font-size: 18px; font-weight: 700; letter-spacing: -.015em;
  color: var(--slate-900); text-align: center;
}
body.client-app .dp-tete-vide { width: 40px; }
body.client-app .dp-form { display: flex; flex-direction: column; flex: 1; }
/* ---- chaque etape : SON bloc, arrondi et separe -------------------------
   27/10/2026 : la carte recapitulative du depot a ete retiree — son epaisseur
   passe dans l'ECART entre les etapes (6 -> 16 px), pour bien les detacher les
   les unes des autres au lieu de laisser un vide en bas (le retrait a suivi le
   28/10/2026, et sa carte recapitulative est partie aussi). */
body.client-app .dp-section {
  position: relative; margin-bottom: 16px; padding: 9px 13px 11px;
  background: var(--surface); border-radius: 20px;
  border: 1px solid var(--brand-400);
  box-shadow: 0 2px 10px rgba(16,24,40,.05);
}
body.client-app .dp-page .label {
  display: block; margin-bottom: 8px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .01em;
  text-transform: none; color: var(--slate-600);
}
/* 1. « Payer avec » : deux tuiles douces, coche a gauche sur la choisie */
body.client-app .dp-tuiles { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
body.client-app .dp-tuile {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 54px; padding: 8px 10px; border-radius: 16px; cursor: pointer;
  border: 1px solid var(--dp-bord); background: var(--dp-champ);
  color: var(--dp-encre); font-weight: 600; font-size: 14px;
  transition: border-color .18s ease, box-shadow .18s ease, background .18s ease;
}
body.client-app .dp-tuile.on {
  border-color: var(--dp-cobalt); background: var(--dp-carte); color: var(--dp-encre);
  box-shadow: 0 1px 2px rgba(16,24,40,.06);
}
body.client-app .dp-tuile.off { opacity: .5; border-style: dashed; }
body.client-app .dp-tuile-nom { font-size: 14px; font-weight: 600; }
body.client-app .dp-tuile .paylogo { width: 24px; height: 24px; flex: none; }
body.client-app .dp-tuile .paylogo img { width: 24px; height: 24px; object-fit: contain; }
body.client-app .dp-coche {
  width: 22px; height: 22px; flex: none; border-radius: 999px;
  background: var(--dp-encre); color: var(--dp-carte); display: inline-flex;
  align-items: center; justify-content: center;
}
/* 27/10/2026 — tuiles de RESEAU, dessin du MODELE, aux DEUX ecrans (depot
   « Payer avec » et retrait « Recevoir sur » — le client a demande de les
   aligner) : vignette du reseau a gauche, nom + operateur sur deux lignes, coche
   ronde a droite sur la tuile choisie et un cadre franc (2 px) autour d'elle.
   Jetons de palette seulement : le theme nuit suit tout seul. */
body.client-app .dp-tuile.dp-tuile-l2 {
  justify-content: flex-start; gap: 11px; padding: 10px 12px; min-height: 64px;
  text-align: left;
}
body.client-app .dp-tuile.dp-tuile-l2 .paylogo { width: 38px; height: 38px; }
body.client-app .dp-tuile.dp-tuile-l2 .paylogo img { width: 38px; height: 38px; }
body.client-app .dp-tuile-txt {
  display: flex; flex-direction: column; gap: 1px; min-width: 0;
}
body.client-app .dp-tuile.dp-tuile-l2 .dp-tuile-nom {
  font-size: 16px; font-weight: 700; color: var(--slate-900); line-height: 1.15;
}
body.client-app .dp-tuile-op {
  font-size: 12.5px; font-weight: 500; color: var(--slate-500); line-height: 1.2;
}
body.client-app .dp-tuile.dp-tuile-l2 .dp-coche { margin-left: auto; }
body.client-app .dp-tuile.dp-tuile-l2.on {
  border-color: transparent;
  box-shadow: inset 0 0 0 2px var(--slate-900), 0 1px 2px rgba(16,24,40,.06);
}
/* 2. « Montant » : grand nombre, unite grise a droite */
body.client-app .dp-montant {
  display: flex; align-items: baseline; gap: 8px; padding: 10px 14px;
  border-radius: 16px; background: var(--slate-100); border: 1px solid transparent;
  transition: border-color .18s ease, box-shadow .18s ease, background .18s ease;
}
body.client-app .dp-montant:focus-within {
  border-color: var(--slate-900); background: var(--surface);
  box-shadow: 0 0 0 3px rgba(16,24,40,.06);
}
body.client-app .dp-montant-in {
  flex: 1; min-width: 0; border: 0; background: transparent; outline: none;
  font-size: 28px; font-weight: 700; color: var(--slate-900);
  font-family: inherit; letter-spacing: -.02em; padding: 0;
}
/* 25/10/2026 : le client trouve « la taille des ecritures des exemples trop
   grande » — un exemple n'est pas une valeur. Les placeholders passent donc
   d'un cran sous le texte saisi (28 -> 20 px ici, 16 -> 14 px plus bas) : la
   valeur tapee garde sa taille, l'exemple se lit comme une indication. */
body.client-app .dp-montant-in::placeholder {
  color: var(--slate-400); font-weight: 600; font-size: 20px; letter-spacing: 0;
}
body.client-app .dp-devise {
  font-size: 12.5px; font-weight: 700; letter-spacing: .06em; color: var(--slate-500);
  text-transform: uppercase;
}
body.client-app .dp-page .hint { font-size: 12px; color: var(--slate-500); margin-top: 6px; line-height: 1.35; }
/* pilules : contour neutre, pleines en graphite quand choisies */
body.client-app .dp-pilules { gap: 8px; }
body.client-app .dp-pilule {
  flex: 1; height: 40px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--slate-200); background: var(--surface);
  color: var(--slate-700); font-weight: 700; font-size: 13px;
  transition: background .18s ease, color .18s ease, box-shadow .18s ease;
}
body.client-app .dp-pilule.on {
  background: var(--slate-900); color: var(--surface); border-color: transparent;
  box-shadow: 0 6px 14px rgba(16,24,40,.18);
}
/* 3. identifiants : champ a fond doux, loupe neutre DANS le champ */
body.client-app .dp-idrow { position: relative; }
body.client-app .dp-idrow .input { height: 50px; font-size: 16px; padding-right: 52px; }
body.client-app .dp-page .input, body.client-app .dp-page .select {
  height: 50px; padding: 0 14px; font-size: 16px; border-radius: 14px;
  border: 1px solid transparent; background: var(--slate-100); color: var(--slate-900);
  transition: border-color .18s ease, background .18s ease, box-shadow .18s ease;
}
body.client-app .dp-page .input:focus, body.client-app .dp-page .select:focus {
  background: var(--surface); border-color: var(--slate-900);
  box-shadow: 0 0 0 3px rgba(16,24,40,.06);
}
body.client-app .dp-page .input::placeholder {
  color: var(--slate-400); font-size: 14px; font-weight: 500; letter-spacing: 0;
}
body.client-app .dep-loupe {
  position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; border: 0; border-radius: 12px; background: transparent;
  color: var(--slate-600);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
}
body.client-app .dep-loupe:active { background: var(--slate-100); }
body.client-app .dp-page .idcheck {
  padding: 9px 11px; gap: 9px; margin-top: 8px; border-radius: 14px;
  background: var(--emerald-50);
}
body.client-app .dp-page .idcheck .idc-ico { width: 20px; height: 20px; }
body.client-app .dp-page .idcheck .idc-name { font-size: 13px; }
body.client-app .dp-page .idcheck .idc-id { font-size: 12px; }
/* « ID enregistre » : une pastille qu'on TOUCHE — elle doit se lire et se viser.
   28/09/2026 : le client a dit « la taille de id enregistrer est trop petit »,
   d'ou l'agrandissement a 13,5 px / 40 px.
   22/10/2026 : il demande cette fois « reduit un peu, une taille moyenne » — la
   pastille prenait la place du champ qu'elle remplit. On descend d'un cran
   (12,5 px, 38 px de haut) SANS revenir au badge de base (12 px, 3 px de
   padding) : le 28/09 a montre que trop petit se paie. C'est un compromis, pas
   un retour en arriere. */
body.client-app .dp-page .badge.pill {
  font-size: 12.5px; font-weight: 600; min-height: 38px; padding: 6px 14px;
  border-radius: 999px; background: var(--slate-100); color: var(--slate-900);
  border: 1px solid var(--slate-200); display: inline-flex; align-items: center;
  letter-spacing: .01em;
}
body.client-app .dp-page .badge.pill:active { background: var(--slate-200); }
/* 4. CARTE RECAPITULATIVE — SUPPRIMEE des DEUX ecrans (depot le 27/10/2026 :
   « supprime Compte 1xBet credite / Frais FLASH PAY / Vous payez » ; retrait le
   28/10/2026 : « Numero qui recoit / Frais FLASH PAY / Vous recevez »). Les
   regles sont donc retirees : aucune regle de recapitulatif ne subsiste, seules
   ces deux lignes de commentaire en parlent encore. */
/* pied : SEULE touche bleue de l'ecran — l'action principale */
body.client-app .dp-continuer {
  height: 54px; border-radius: 18px; font-size: 16px; font-weight: 700;
  box-shadow: 0 10px 24px rgba(31, 111, 191, .22);
}
/* 27/10/2026 : la carte recapitulative du DEPOT occupait le bas de la page et
   poussait le bouton au pied de l'ecran (`margin: auto 0`). En la retirant, ce
   role revient au bouton lui-meme — sinon il remonte au milieu et laisse un vide
   sous « Comment faire ? ». 28/10/2026 : le RETRAIT a perdu sa carte pour la
   meme raison, donc son bouton prend la meme regle (une seule ligne pour les
   deux ecrans, ils ne peuvent plus diverger). */
body.client-app #dep-continuer,
body.client-app #wd-continuer { margin-top: auto; }
/* « Continuer » EN ATTENTE (25/10/2026) : la demande de depot part et le bouton
   le dit — tourniquet + « Envoi du depot... ». Il garde sa taille (54 px) pour
   que rien ne saute sous le doigt, s'efface un peu et n'accepte plus d'appui
   (il est aussi disabled, ce qui suffit dans le navigateur ; pointer-events
   couvre les vieux WebView qui laissent passer le clic). */
body.client-app .dp-continuer.attente,
body.client-app .dp-continuer[aria-busy="true"] {
  opacity: .82; cursor: progress; pointer-events: none;
  box-shadow: 0 6px 16px rgba(31, 111, 191, .18);
}
body.client-app .dp-spin {
  width: 18px; height: 18px; flex: none; display: inline-block; border-radius: 50%;
  border: 2.5px solid rgba(255, 255, 255, .45); border-top-color: #fff;
  animation: spin .8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  body.client-app .dp-spin { animation-duration: 2.4s; }
}
body.client-app .dp-aide-ligne { text-align: center; margin-top: 8px; }
body.client-app .dep-aide > summary {
  list-style: none; cursor: pointer; font-size: 12px; font-weight: 600;
  color: var(--slate-500); padding: 2px 0;
}
body.client-app .dep-aide > summary::-webkit-details-marker { display: none; }
body.client-app .dep-aide-bd {
  position: absolute; z-index: 40; left: 16px; right: 16px; margin-top: 4px;
  background: var(--surface); border: 1px solid var(--slate-200); border-radius: 16px;
  padding: 12px 14px; box-shadow: 0 12px 32px rgba(16,24,40,.14); text-align: left;
  font-size: 12.5px;
}


/* ==========================================================================
   DISCUSSION : FORME REPRISE DE SBB SERVICES (25/10/2026)
   Squelette de leur messagerie : en-tete a deux lignes (titre + sous-titre)
   pose sur un filet, pastilles de jour en petites capitales cernees, bulles
   arrondies 20 px (envoyee a la couleur de la MARQUE, recue au fond de la page
   avec un filet), horodatage dans la bulle en bas a droite avec une seule
   coche, carte de saisie cernee portant une ligne d'information puis le champ
   et le rond d'envoi, et ecran d'accueil avec un grand bonjour et deux
   raccourcis. NOS COULEURS : tout passe par les jetons --tg-* / --brand-* /
   --slate-*, aucun aplat nouveau. Le cablage (ids, data-act, enregistrement
   vocal) n'est pas touche.
   ========================================================================== */
.tg-head {
  padding: 10px 14px; gap: 10px; align-items: center;
  background: var(--tg-fond); border-bottom: 1px solid var(--slate-200);
}
.tg-tete-texte { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tg-titre { font-size: 16.5px; font-weight: 700; color: var(--tg-encre); line-height: 1.2; }
.tg-sous { font-size: 12px; color: var(--tg-meta); line-height: 1.3; }

/* pastille de jour : petites capitales, filet et ombre courte */
.tg-jour { margin: 10px 0 4px; }
.tg-jour span {
  background: var(--tg-fond); color: var(--tg-meta); font-size: 12px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; padding: 4px 10px; border-radius: 7px;
  border: 1px solid var(--slate-200); box-shadow: 0 1px 2px rgba(16, 24, 40, .06);
}

/* bulles : 20 px, sans encoche ; la mienne prend la couleur de la marque */
.tg-ligne.tg-suite { margin-top: 2px; }
.tg-bulle { padding: 8px 12px 6px; border-radius: 20px; box-shadow: none; }
.tg-ligne.me .tg-bulle {
  background: var(--brand-600); color: var(--on-brand);
  border: 1px solid var(--brand-600);
}
.tg-ligne.them .tg-bulle {
  background: var(--tg-fond); color: var(--tg-encre);
  border: 1px solid var(--slate-200);
}
.tg-ligne.me .tg-meta { color: var(--on-brand); opacity: .85; }
.tg-ligne.me .tg-meta svg { color: var(--on-brand); opacity: .9; }
.tg-ligne.me .tg-meta.tg-lu svg { color: var(--on-brand); opacity: 1; }
.tg-ligne.me .tg-cite {
  background: rgba(255, 255, 255, .16); border-left-color: var(--on-brand);
}
.tg-ligne.me .tg-cite b { color: var(--on-brand); }
.tg-ligne.me .tg-copier { background: rgba(255, 255, 255, .16); color: var(--on-brand); }
.tg-ligne.them .tg-copier { background: var(--tg-pastille); }

/* ecran d'accueil de la discussion (fil vide) */
.tg-accueil {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; text-align: center; padding: 40px 26px; min-height: 100%;
}
.tg-accueil-rond {
  width: 66px; height: 66px; border-radius: 50%; display: grid; place-items: center;
  background: var(--brand-50); color: var(--brand-600);
}
.tg-accueil-bonjour {
  font-size: 27px; font-weight: 800; letter-spacing: -.015em; color: var(--tg-encre);
}
.tg-accueil-texte { font-size: 13.5px; line-height: 1.4; color: var(--tg-meta); max-width: 27ch; }
.tg-accueil-acts { display: flex; gap: 8px; margin-top: 8px; }
.tg-accueil-act {
  display: inline-flex; align-items: center; gap: 6px; border: 0; cursor: pointer;
  border-radius: 999px; padding: 10px 18px; font-size: 12.5px; font-weight: 700;
  font-family: inherit; transition: transform .12s linear;
}
.tg-accueil-act:active { transform: scale(.95); }
.tg-accueil-act.dep { background: var(--brand-600); color: var(--on-brand); }
.tg-accueil-act.ret { background: var(--amber-500); color: var(--slate-900); }

/* carte de saisie : la ligne d'information, le CHAMP SUR SA PROPRE LIGNE
   (grand, toute la largeur), puis une rangee de trois ronds — « + » a gauche,
   micro et envoi a droite. Mesures prises sur la capture de la reference
   (25/10/2026) : ronds de 46 px, champ de 17 px de texte, carte qui monte a
   ~150 px. La version compacte (champ et rond sur une seule ligne) avait ete
   livree et refusee : c'est la TAILLE qui manquait. */
.tg-bar {
  /* align-items: stretch est INDISPENSABLE : la regle d'origine du bandeau pose
     align-items: center, et une colonne qui centre ses enfants les retrecit a la
     largeur du texte — la rangee de ronds se retrouvait centree au lieu d'etre
     posee aux deux bords (constate a la capture du 25/10). */
  position: relative; flex: none; display: flex; flex-direction: column;
  align-items: stretch; gap: 8px;
  margin: 8px 10px calc(8px + env(safe-area-inset-bottom)); padding: 10px;
  border: 1px solid var(--slate-200); border-radius: 24px; background: var(--tg-fond);
  box-shadow: 0 2px 4px rgba(11, 26, 42, .04), 0 24px 50px -22px rgba(11, 26, 42, .35);
}
/* LIGNE D'INFORMATION DE LA CARTE DE SAISIE : retiree le 06/11/2026 (demande :
   « enleve Un caissier vous repond ici, en quelques minutes — pour avoir de
   l'espace »). Aucune regle ne subsiste ; seule cette note en parle. */
/* 10/11/2026 — UNE SEULE LIGNE (capture de la reference) : trombone a gauche,
   champ au milieu, rond d'action a droite. `flex-wrap` laisse la barre
   d'enregistrement passer dessous en pleine largeur quand on enregistre. */
.tg-saisie {
  flex: none; display: flex; flex-direction: row; align-items: flex-end; flex-wrap: wrap;
  gap: 8px; height: auto; min-width: 0; border-radius: 0; padding: 0;
  background: transparent; box-shadow: none;
}
.tg-saisie .tg-plus { order: 1; }
.tg-saisie .tg-champ { order: 2; }
.tg-saisie .tg-ronds { order: 3; }
.tg-saisie .tg-rec { order: 4; flex: 1 1 100%; }
.tg-champ {
  /* LE CHAMP EST LA PASTILLE ARRONDIE DU MILIEU (10/11/2026, capture) : blanc,
     cerne de 1 px, rayon 24, il prend toute la place entre les deux ronds. */
  display: block; flex: 1 1 auto; min-width: 0; width: auto;
  border: 1px solid var(--slate-200); outline: none; background: var(--surface);
  border-radius: 24px; padding: 13px 16px; min-height: 48px;
  font-size: 16px; font-family: inherit; color: var(--tg-encre);
  text-align: left;
  /* LE CHAMP GRANDIT AVEC LE TEXTE (06/11/2026 : « ca doit s'agrandir quand le
     message saisi est beaucoup »). Un <input> ne grandit pas : il fait defiler
     son texte sur une ligne. C'est un <textarea rows="1"> dont la hauteur suit
     scrollHeight (app.js, tgChampGrandit), plafonnee ici a 150 px — meme
     plafond que le tchat du backoffice ; au-dela il defile. resize:none : pas
     de poignee de redimensionnement sur telephone. box-sizing:border-box pour
     que le calcul scrollHeight/hauteur reste juste. */
  box-sizing: border-box; resize: none; max-height: 150px; overflow-y: auto;
  line-height: 1.3;
  /* Deuxieme ceinture (06/11/2026) : « tout les message ecrit ne s affiche
     pas » — le calcul en JS peut arriver un cran trop tot quand le texte est
     COLLE (le clavier insere la valeur puis redessine). `field-sizing: content`
     fait suivre la hauteur par le moteur lui-meme (Chrome 123+ / WebView
     Android recent) ; les moteurs qui l'ignorent gardent le calcul JS. */
  field-sizing: content;
}
.tg-champ::placeholder { color: var(--tg-meta); }
/* les ronds d'action : a DROITE du champ, plus de rangee pleine largeur */
.tg-ronds {
  display: flex; flex: 0 0 auto; width: auto; align-items: center; justify-content: flex-end;
  gap: 6px; padding: 0; text-align: left;
}
/* le trombone de la capture : NU, sans pastille derriere (il ouvre la photo) */
.tg-plus {
  flex: none; width: 48px; height: 48px; padding: 0; border: 0; border-radius: 50%;
  display: grid; place-items: center; background: transparent; color: var(--tg-meta);
  cursor: pointer; transition: transform .12s linear;
}
.tg-plus svg { width: 26px; height: 26px; }
.tg-plus:active { transform: scale(.94); }
/* le rond d'action est le GROS rond de la capture ; un seul est visible a la fois
   (micro quand le champ est vide, envoi des qu'il y a du texte) */
.tg-ronds .tg-rond { width: 52px; height: 52px; }
.tg-ronds .tg-rond[hidden] { display: none; }
/* le micro reste NEUTRE (cercle clair, comme dans la reference) ; c'est le rond
   d'envoi qui porte la couleur de la marque, et seulement quand il y a du texte */
.tg-ronds #chat-mic { margin-left: 0; background: var(--brand-600); color: var(--on-brand);
  /* iOS / Safari : sans `touch-action: none`, le premier mouvement du doigt
     fait DEFILER la page, le navigateur reprend le geste et livre un
     `touchcancel` — la prise est alors annulee en silence et le rond parait
     « disparaitre ». On interdit au navigateur de prendre ce geste, et on
     coupe le menu d'appui long (copier/coller) et la selection. */
  touch-action: none; -webkit-touch-callout: none; -webkit-user-select: none;
  user-select: none; }
/* DISCUSSION VIDE : une ligne centree (capture de la reference, 10/11/2026) */
.tg-vide {
  margin: auto; padding: 26px 22px; text-align: center;
  font-size: 15px; line-height: 1.35; color: var(--tg-meta);
}
.tg-envoi {
  background: var(--slate-200); color: var(--slate-500); opacity: 1;
}
.tg-envoi.tg-envoi-on { background: var(--brand-600); color: var(--on-brand); opacity: 1; }
.tg-envoi:disabled { cursor: default; }
.tg-ico { width: 40px; height: 40px; border-radius: 50%; }

/* Ronds et champ de la discussion : etats de focus VISIBLES et mouvements
   sobres — regles tirees de l'outil de design (cible tactile 44 px, anneau de
   focus, transitions de 150 a 300 ms, respect de « mouvement reduit »). */
.tg-plus, .tg-ronds .tg-rond { transition: transform .15s ease, background-color .15s ease, opacity .15s ease; }
.tg-plus:focus-visible, .tg-ronds .tg-rond:focus-visible, .tg-accueil-act:focus-visible {
  outline: 2px solid var(--brand-400); outline-offset: 2px;
}
.tg-champ:focus-visible { outline: none; }
.tg-bar:focus-within { border-color: var(--brand-400); }
@media (prefers-reduced-motion: reduce) {
  .tg-plus, .tg-ronds .tg-rond, .tg-accueil-act { transition: none; }
}

/* ---------- MEDIAS (27/10/2026) : sections et medias du panneau ------------ */
.cx-media-sec { margin: 18px 0 8px; }
.cx-media-sec h3 { font-size: 15px; font-weight: 800; color: var(--slate-900); margin: 0 0 2px; }
.cx-media-sec p { margin: 0; font-size: 12px; color: var(--slate-500); }
.cx-media { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.cx-media-carte { border-radius: 14px; overflow: hidden; background: var(--surface);
  border: 1px solid var(--slate-200); }
.cx-media-carte img { width: 100%; display: block; aspect-ratio: 16 / 9; object-fit: cover; }
.cx-media-titre { padding: 10px 12px 0; font-size: 14px; font-weight: 700; color: var(--slate-900); }
.cx-media-cta { display: block; margin: 10px 12px 12px; text-align: center; text-decoration: none;
  padding: 10px; border-radius: 10px; background: var(--brand-600); color: #fff; font-weight: 700;
  font-size: 13px; }
.cx-media-vide { padding: 12px; font-size: 12px; color: var(--slate-500); }

/* ---------- ANNONCE DU PANNEAU EN FENETRE (27/10/2026) -------------------- */
.cx-annonce { display: flex; align-items: center; gap: 12px; padding: 12px;
  border-radius: 14px; background: var(--brand-50); }
.cx-annonce.tone-or { background: var(--amber-100); }
.cx-annonce.tone-neutre { background: var(--slate-100); }
.cx-annonce-ico { flex: none; width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center; background: var(--brand-600); color: #fff; }
.cx-annonce.tone-or .cx-annonce-ico { background: var(--amber-600); }
.cx-annonce.tone-neutre .cx-annonce-ico { background: var(--slate-500); }
.cx-annonce-titre { font-size: 16px; font-weight: 800; color: var(--slate-900); }
.cx-annonce-sous { font-size: 12.5px; color: var(--slate-600); margin-top: 2px; }
.cx-annonce-puces { margin: 10px 0 0; padding-left: 20px; }
.cx-annonce-puces li { font-size: 13px; color: var(--slate-700); margin-top: 4px; }

/* ---------- CARROUSEL D'ACCUEIL (27/10/2026, refait le 10/11/2026) ---------
   Demande du proprietaire : « ajoute cette section sur l'interface client »
   (capture de la reference : une BANNIERE qui occupe toute la largeur, l'image
   en fond, le texte PAR-DESSUS en bas a gauche, le bouton en pastille d'or, et
   des PASTILLES de position sous la banniere, l'active allongee et bleue).
   L'ancienne forme posait une carte de 84 % avec le texte SOUS l'image : elle
   datait du 27/10 et n'a plus rien a voir avec la reference — les deux formes ne
   peuvent pas cohabiter, la seconde remplace la premiere. */
.cx-slides { display: flex; gap: 0; overflow-x: auto; padding: 0;
  /* pleine largeur : l'accueil a 16 px de marge de chaque cote (`px4`) */
  margin: 0 -16px 0; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; }
.cx-slides::-webkit-scrollbar { display: none; }
.cx-slide { position: relative; flex: 0 0 100%; scroll-snap-align: start;
  overflow: hidden; background: var(--slate-200); text-decoration: none; color: inherit; display: block; }
.cx-slide img { width: 100%; display: block; aspect-ratio: 16 / 9.4; object-fit: cover; }
/* voile sombre en bas de l'image : sans lui, un titre blanc sur une photo claire
   ne se lit pas (la capture de la reference a exactement ce degrade). */
.cx-slide::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 58%;
  background: linear-gradient(to top, rgba(0, 0, 0, .62), rgba(0, 0, 0, 0)); pointer-events: none; }
.cx-slide-txt { position: absolute; left: 16px; right: 16px; bottom: 14px; z-index: 1; }
.cx-slide-titre { font-size: 21px; font-weight: 800; line-height: 1.15; color: #fff;
  text-shadow: 0 2px 10px rgba(0, 0, 0, .45); }
.cx-slide-sous { margin-top: 3px; font-size: 13px; color: rgba(255, 255, 255, .92); }
.cx-slide-cta { display: inline-block; margin-top: 9px; padding: 9px 18px; border-radius: 999px;
  background: var(--amber-500); color: var(--ah-gold-ink); font-size: 14px; font-weight: 800; }
/* pastilles de position sous la banniere */
.cx-dots { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 10px 0 2px; }
.cx-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--slate-300);
  transition: width .16s, background .16s; }
.cx-dot.on { width: 22px; border-radius: 999px; background: var(--brand-600); }

/* ==========================================================================
   ECRAN DE PAIEMENT DETAILLE (27/10/2026).
   Structure et proportions COPIEES du modele montre par le marchand ; seules
   les couleurs sont les notres (bleu #0B2E55, or en accent). Le vert du modele
   n'apparait nulle part : ce n'est pas notre identite.
   ========================================================================== */
.pay-ecran { text-align: left; }
.pay-titre { font-size: 23px; font-weight: 800; line-height: 1.2; margin: 0 0 6px; color: var(--slate-900); }
.pay-montant { font-size: 15px; color: var(--slate-500); margin: 0 0 16px; }
.pay-montant b { color: var(--slate-700); font-weight: 600; }
.pay-reseau { font-size: 12px; letter-spacing: .12em; color: var(--slate-500); margin: 0 0 10px; }
.pay-code { background: var(--slate-100); border-radius: 14px; padding: 15px 16px; }
.pay-code-v { font-family: var(--mono); font-size: 17px; color: var(--slate-800);
  word-break: break-all; display: block; }
.pay-ligne { display: flex; align-items: stretch; gap: 10px; margin-top: 12px; }
.pay-payer { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; gap: 9px;
  background: var(--brand-600); color: #fff; border-radius: 14px; min-height: 56px;
  font-size: 17px; font-weight: 700; }
.pay-payer svg { flex: 0 0 auto; }
.pay-copier { flex: 0 0 auto; width: 56px; min-height: 56px; display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--slate-200); border-radius: 14px; color: var(--slate-600); }
.pay-attente { display: flex; gap: 11px; background: var(--brand-50); border: 1px solid var(--brand-100);
  border-radius: 16px; padding: 15px; margin-top: 16px; }
.pay-attente-ic { flex: 0 0 auto; color: var(--brand-600); margin-top: 1px; }
.pay-attente-t { font-size: 15px; font-weight: 700; color: var(--slate-900); }
/* Compteur d'attente du SMS operateur : chiffres a chasse fixe pour qu'il ne
   « sautille » pas a chaque seconde, et le bleu de la maison (jeton, donc le
   theme nuit suit). */
.pay-attente-t #dep-attente-secs { font-variant-numeric: tabular-nums; color: var(--brand-700); }
.pay-attente-p { font-size: 13.5px; line-height: 1.45; color: var(--slate-500); margin-top: 6px; }
.pay-carte { background: var(--surface); border: 1px solid var(--slate-200); border-radius: 16px;
  padding: 16px; margin-top: 16px; }
.pay-carte-t { font-size: 16px; font-weight: 700; color: var(--slate-900); margin-bottom: 10px; }
.pay-carte-p { font-size: 13.5px; line-height: 1.5; color: var(--slate-500); margin: 0 0 10px; }
.pay-jaipaye { width: 100%; min-height: 54px; margin-top: 4px; border: 1.5px solid var(--brand-600);
  color: var(--brand-600); background: var(--surface); border-radius: 12px; font-size: 16px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; gap: 8px; }
.pay-ref { background: var(--slate-100); border-radius: 14px; padding: 16px; text-align: center;
  margin-top: 16px; }
.pay-ref-l { font-size: 12px; letter-spacing: .14em; color: var(--slate-500); }
.pay-ref-v { font-size: 26px; font-weight: 800; letter-spacing: .03em; margin-top: 4px;
  color: var(--slate-900); }
.pay-annuler { background: var(--surface); border: 1.5px solid var(--rose-600); color: var(--rose-600);
  border-radius: 12px; min-height: 54px; font-size: 16px; font-weight: 700; }
.pay-rond { display: inline-block; width: 20px; height: 20px; border-radius: 50%;
  border: 2.5px solid var(--brand-200); border-top-color: var(--brand-600);
  animation: pay-tourne 1s linear infinite; }
@keyframes pay-tourne { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .pay-rond { animation-duration: 3s; } }


/* L'indicateur « En attente de la confirmation du paiement… » TOURNE
   (27/10/2026, demande du marchand : c'est un chargement, pas une icone).
   Mouvement reduit si le telephone le demande. */
.pay-rond { display: inline-block; width: 20px; height: 20px; border-radius: 50%;
  border: 2.5px solid var(--brand-100); border-top-color: var(--brand-600);
  animation: pay-tourne 1s linear infinite; }
@keyframes pay-tourne { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .pay-rond { animation-duration: 3s; }
}

/* ETAT « DEPOT VALIDE » de la meme page (modele Nygma) : meme cadre, le
   bandeau d'attente devient une confirmation. Coche bleue, pas de vert. */
.pay-valide .pay-titre { color: var(--brand-700); }
.pay-valide .pay-attente { background: var(--brand-50); border-color: var(--brand-100); }
.pay-valide .pay-attente-ic { color: var(--brand-600); }
.pay-valide .pay-attente-t { color: var(--brand-700); }

/* =====================================================================
   ECRAN « DEPOT REUSSI » PLEIN ECRAN (28/10/2026)
   Mise en page reprise du modele envoye par le marchand : coche ronde, titre,
   une ligne d'explication, carte blanche de recapitulatif, gros bouton bas.
   NOS COULEURS : la coche, le montant et le bouton sont bleu maison ; le vert
   et le noir du modele ne sont pas repris.
   Le plein ecran se fait par le dialogue lui-meme (voir CD.modal, `plein`) :
   le voile sombre disparait et la carte prend toute la page, sinon le recu
   restait une petite fenetre au milieu de l'ecran.
   ===================================================================== */
/* L'ECRAN DOIT ETRE OPAQUE (corrige le 28/10/2026, « regarde ce que tu as fait,
   c'est moche »). `body.client-app .modal` peint un voile sombre et
   `body.client-app .modal-card` arrondit les fenetres : ces deux regles sont plus
   fortes qu'une simple classe, donc mes premieres declarations perdaient et la
   page de depot restait visible DERRIERE le recu — la coche, le titre et la carte
   se melangeaient au formulaire. On repond a la MEME force, et on peint le fond
   de la page : plus rien ne transparait. */
body.client-app .modal.modal-plein { padding: 0; align-items: stretch;
  background: var(--brand-50); }
body.client-app .modal-plein .modal-card { max-width: none; width: 100%; min-height: 100%;
  margin: 0; padding: 0; border-radius: 0; border: 0; box-shadow: none;
  background: transparent; }
/* Nocturne : meme regle, meme force (le fond de page y est neutre). */
:root[data-theme="dark"] body.client-app .modal.modal-plein { background: var(--slate-50); }
/* Hors espace client (panneau), la forme simple suffit. */
.modal.modal-plein { padding: 0; align-items: stretch; background: var(--brand-50); }
:root[data-theme="dark"] .modal.modal-plein { background: var(--slate-50); }
.dr { padding: calc(34px + env(safe-area-inset-top)) 16px calc(28px + env(safe-area-inset-bottom)); text-align: center; }
/* 28/10/2026 — demande du client : « change la couleur de l'icone du crochet
   bleu en verte ». La pastille de reussite prend donc le vert de la maison
   (`--emerald-600`) et garde le crochet blanc ; seul le fond change. */
.dr-coche { width: 95px; height: 95px; margin: 0 auto 20px; border-radius: 50%;
  background: var(--emerald-600); color: var(--on-brand); display: flex; align-items: center;
  justify-content: center; }
/* Le h3 de la coquille porte un retrait a droite pour la croix de fermeture :
   cet ecran n'a pas de croix, le titre doit etre centre pour de vrai. */
.dr-titre { font-size: 24px; font-weight: 800; letter-spacing: -.4px; line-height: 1.2;
  color: var(--slate-900); margin: 0 0 14px; padding: 0; }
/* 28/10/2026 — capture du client : « bien centre Depot reussi ». Le titre etait
   pousse de ~18 px A GAUCHE (mesure : centre du texte a 520 px pour une page de
   576 px sur une capture de 1152 px, echelle 3) alors que la pastille, elle,
   etait juste. La faute n'etait pas dans `.dr-titre` : `.modal-card h3`
   (specificite 0,1,1) pose `padding-right: 40px` pour la croix de fermeture et
   BAT `.dr-titre` (0,1,0) ; le `padding: 0` ecrit ici ne s'appliquait donc
   jamais. Cet ecran n'a pas de croix : on rend la place, avec un selecteur qui
   gagne (0,3,1). */
body.client-app .dr .dr-titre,
body.client-app .modal-card .dr .dr-titre { padding-right: 0; }
.dr-sous { margin: 0; font-size: 16px; line-height: 1.45; color: var(--slate-500); }
.dr-carte { margin-top: 21px; padding: 10px 20px; border-radius: 22px;
  background: var(--surface); text-align: left; }
.dr-ligne { display: flex; align-items: baseline; gap: 14px; padding: 12px 0; }
.dr-lab { flex: 0 0 85px; font-size: 14px; color: var(--slate-500); }
.dr-val { flex: 1; min-width: 0; font-size: 14px; color: var(--slate-900);
  overflow-wrap: anywhere; }
/* 28/10/2026 — demande du client sur la capture du succes : « la couleur de la
   somme en vert ». La valeur « Montant » prend le VERT de la famille de la
   coche (`--emerald-700`) au lieu du bleu de marque : le montant credite est
   l'information a lire, et elle repond a la coche.
   Jeton 700 et non 600 : en theme CLAIR, le vert 600 (#059669) ne donne que
   3,8:1 sur la carte blanche (sous le seuil de 4,5 pour du 16 px), alors que le
   700 (#047857) donne 4,9:1 ; la nuit il passe a 11:1 sur #1C1C1C. */
.dr-montant { color: var(--emerald-700); font-weight: 800; font-size: 16px; }
/* « Le bouton Nouvelle operation est trop grand » (28/10/2026) : il redescend a
   la taille des boutons de l'appli — 15 px de texte, 11 px de rembourrage
   vertical (hauteur ~46 px au lieu de ~58) — et garde le bleu de l'action
   principale. */
.dr-btn { width: 100%; margin-top: 18px; padding: 11px 16px; border: 0; border-radius: 14px;
  background: var(--brand-600); color: var(--on-brand); font: inherit; font-size: 15px;
  font-weight: 600; cursor: pointer; display: flex; align-items: center;
  justify-content: center; gap: 9px; }
.dr-btn:active { background: var(--brand-700); }
/* Les DEUX sorties de l'ecran de reussite (28/10/2026) : accueil et historique,
   cote a cote sous le bouton principal. Boutons SECONDAIRES (contour, fond
   transparent) pour que le bleu reste l'action principale. Les jetons
   `--slate-*` suivent le theme : rien en dur, la nuit comprise. */
.dr-sorties { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; }
.dr-sortie { display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 12px; border: 1px solid var(--slate-200); border-radius: 14px;
  background: transparent; color: var(--slate-700); font: inherit; font-size: 14px;
  font-weight: 600; cursor: pointer; }
.dr-sortie:active { background: var(--slate-100); }
@media (min-width: 520px) {
  .dr { max-width: 440px; margin: 0 auto; }
}

/* =====================================================================
   HABILLAGE DES DEUX ECRANS D'ENTREE — CONNEXION ET INSCRIPTION
   (06/11/2026, demande du client : « je veux un truc exactement comme
   ca, joli et lisse », avec la capture de sa reference et « meme fond
   blanc ».)

   Ce que fait ce bloc : la page passe au BLANC ; la marque occupe une
   colonne a gauche (sombre avec halo pour la connexion, claire avec les
   trois arguments pour l'inscription) ; la carte blanche porte les
   champs a libelle AU_DESSUS, comme la reference.
   Regles tenues ici :
   - les encres et les fonds sont des jetons --ah-* : ils sont declares DEUX
     fois (jour dans :root, nuit dans :root[data-theme="dark"]), donc les deux
     ecrans suivent la bascule de theme de l'interface sans une regle de plus ;
   - aucune couleur en dur dans ce bloc (controle « aucune couleur
     nouvelle ») : uniquement des variables de la palette ;
   - les reperes de structure attendus par ui_check restent en place :
     .auth-shell, .auth-card, .auth-sep, le bouton oeil (data-act) et les
     liens vers l'autre ecran.
   ===================================================================== */

body.auth-page,
body.auth-page.client-app,
body.auth-page.admin-app,
:root[data-theme="dark"] body.auth-page,
:root[data-theme="dark"] body.auth-page.client-app,
:root[data-theme="dark"] body.auth-page.admin-app { background: var(--ah-page); }

.auth-shell {
  position: relative;
  display: flex;
  align-items: stretch;
  justify-content: flex-start;
  width: 100%;
  min-height: 100svh;
  padding: 0;
  overflow-x: hidden;
  background: var(--ah-page);
}
/* L'ancien fond constelle (reseau de points) appartient a l'habillage sombre. */
.auth-shell::before { content: none; }

/* ---------- colonne de marque (bureau) ---------- */
.auth-aside { display: none; }

.auth-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 64px 20px 48px;
}

.ah-brand { display: flex; align-items: center; gap: 12px; }
.ah-logo {
  width: 52px; height: 52px; flex: none; overflow: hidden;
  border-radius: 14px; background: var(--ah-card);
  box-shadow: 0 14px 32px -12px rgba(8, 24, 47, .55);
}
.ah-logo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ah-name { font-size: 18px; font-weight: 700; line-height: 1.05; letter-spacing: -.02em; }
.ah-name span, .ah-name b { display: block; }
.ah-name b { color: var(--amber-500); font-weight: 700; }

.ah-hero { max-width: 28rem; }
.ah-hero h2 {
  margin: 0;
  font-size: 2.9rem; font-weight: 700; line-height: 1.04; letter-spacing: -.025em;
}
.ah-hero p {
  margin-top: 20px;
  font-size: 16px; line-height: 1.65;
  color: var(--brand-100);
}
.ah-hero p b { color: inherit; font-weight: 700; }

.ah-pills { display: flex; gap: 10px; font-size: 14px; font-weight: 700; }
.ah-pill { padding: 8px 16px; border-radius: 999px; }
.ah-pill--b { background: var(--ah-brand); color: var(--ah-onbrand); }
.ah-pill--g { background: var(--amber-500); color: var(--ah-gold-ink); }

.ah-badge {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 12px;
  border: 1px solid var(--ah-line); border-radius: 999px;
  background: var(--ah-card); color: var(--amber-700);
  font-size: 12px; font-weight: 600;
  box-shadow: 0 1px 2px rgba(8, 24, 47, .05);
}
.ah-feats { list-style: none; margin: 32px 0 0; padding: 0; display: flex;
  flex-direction: column; gap: 12px; max-width: 26rem; }
.ah-feats li {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px;
  border: 1px solid var(--ah-line); border-radius: 16px;
  background: var(--ah-card);
  box-shadow: 0 10px 30px -22px rgba(31, 111, 191, .4);
}
.ah-fi {
  display: grid; place-items: center;
  width: 40px; height: 40px; flex: none;
  border-radius: 12px;
  background: rgba(31, 111, 191, .08);
  color: var(--ah-brand);
}
.ah-ft { display: block; font-size: 14px; font-weight: 600; color: var(--ah-ink); }
.ah-fd { display: block; margin-top: 2px; font-size: 12px; color: var(--ah-muted); }
.ah-foot { display: flex; align-items: center; gap: 14px; font-size: 12px; color: var(--ah-muted); }
.ah-foot > span { display: inline-flex; align-items: center; gap: 6px; }
.ah-foot svg { color: var(--amber-500); }
.ah-dot { opacity: .5; }

/* ---------- vignette de marque sur telephone ---------- */
/* 06/11/2026 (client, capture du bandeau a l'appui : « corrige la couleur dans
   le bandeau bleu ou est marque flash pay » / « il y a du jaune dedans ») : les
   deux halos floutes de la colonne de bureau, ramenes a la taille d'une vignette,
   donnaient un degrade BRUN-JAUNE a gauche et bleu a droite. La vignette prend
   donc un degrade de NOTRE bleu, sans aucun halo : plus une trace de jaune dans
   le fond (l'or ne reste que sur le mot « PAY »). La nuit, elle suit le noir du
   systeme (voir plus bas). */
.ah-brand-m {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 20px; padding: 22px 20px;
  border-radius: 28px; color: var(--ah-onbrand);
  background: linear-gradient(135deg, var(--ah-brand) 0%, var(--brand-800) 72%, var(--brand-900) 100%);
  box-shadow: 0 18px 40px -24px rgba(31, 111, 191, .7);
}
.ah-brand-m::before, .ah-brand-m::after { content: none; }
.ah-brand-m .ah-name b { color: var(--amber-500); }
.ah-brand-s {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  margin-bottom: 24px; text-align: center;
}

/* ---------- carte ---------- */
.auth-card {
  margin: 0;
  padding: 28px;
  border: 1px solid var(--ah-line);
  border-radius: 28px;
  background: var(--ah-card);
  box-shadow: 0 30px 70px -28px rgba(8, 24, 47, .45);
}
.auth-card-t {
  margin: 0;
  text-align: left;
  font-size: 24px; font-weight: 700; line-height: 1.2; letter-spacing: -.025em;
  color: var(--ah-ink);
}
.auth-card-s { margin: 4px 0 20px; font-size: 14px; color: var(--ah-muted); }
.auth-card #auth-err:empty { display: none; }
.auth-card #auth-err .err-text { margin: 0 0 12px; }

/* ---------- champs : libelle au-dessus, aplat clair, focus a anneau ---------- */
.af { margin-bottom: 16px; }
.af-lb { display: block; margin-bottom: 8px; font-size: 14px; font-weight: 600; color: var(--ah-ink); }
.af-box { position: relative; }
.af-in {
  width: 100%; height: 46px;
  padding: 0 16px;
  font: inherit; font-size: 14px;
  color: var(--ah-ink);
  background: var(--ah-field);
  border: 1.5px solid transparent;
  border-radius: 16px;
  color-scheme: light;
  -webkit-appearance: none; appearance: none;
  transition: background-color .15s ease, border-color .15s ease, box-shadow .18s ease;
}
.af-in::placeholder { color: var(--slate-400); }
.af-box.has-ico .af-in { padding-left: 44px; }
.af-box.has-eye .af-in { padding-right: 44px; }
.af-box--sel .af-in { padding-right: 40px; cursor: pointer; }
.af-in:focus {
  outline: none;
  background: var(--ah-card);
  border-color: var(--ah-brand-500);
  box-shadow: 0 0 0 4px rgba(31, 111, 191, .14);
}
.af-ico {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  display: flex; color: var(--slate-400); pointer-events: none;
}
.af-caret {
  position: absolute; right: 17px; top: 50%;
  width: 8px; height: 8px; pointer-events: none;
  border-right: 2px solid var(--slate-400);
  border-bottom: 2px solid var(--slate-400);
  transform: translateY(-70%) rotate(45deg);
}
.af-eye {
  position: absolute; right: 0; top: 0; bottom: 0;
  display: flex; align-items: center; padding: 0 12px;
  border: 0; background: none; cursor: pointer;
  color: var(--slate-400);
  transition: color .15s ease;
}
.af-eye:hover { color: var(--ah-link); }

/* ---------- bouton principal et lien « mot de passe oublie » ---------- */
.af-go {
  width: 100%;
  padding: 12px 20px;
  border: 0; border-radius: 999px;
  background: var(--ah-brand); color: var(--ah-onbrand);
  font-size: 14px; font-weight: 600;
  box-shadow: 0 12px 26px -12px rgba(31, 111, 191, .75);
  transition: transform .18s var(--ressort, ease), background-color .15s ease;
}
.af-go:hover { background: var(--ah-brand-500); }
.af-go:active { transform: scale(.96); }
.af-forgot {
  display: block; width: 100%;
  margin-top: 12px; padding: 0;
  border: 0; background: none; cursor: pointer;
  text-align: center; font-size: 12px; color: var(--ah-muted);
  transition: color .15s ease;
}
.af-forgot:hover { color: var(--ah-link); }

/* ---------- separateur « ou », Google, pied de carte ---------- */
.auth-card .auth-sep { margin: 20px 0; }
.auth-card .gsi-wrap, .auth-card .gsi-comptes { width: 100%; }
.auth-card .gsi-natif { width: 100%; border-radius: 999px; }
.auth-foot { margin-top: 24px; text-align: center; font-size: 14px; color: var(--ah-muted); }
.auth-foot a { color: var(--ah-link); font-weight: 700; }
.auth-soc { margin-top: 18px; text-align: center; }
.auth-soc-t { font-size: 13px; color: var(--ah-muted); }
.auth-soc-row a { background: var(--ah-card); border: 1px solid var(--ah-line); }

/* ---------- retour : rond blanc, lisible sur les deux fonds ---------- */
.auth-back {
  position: absolute; left: 16px; top: 16px; z-index: 6;
  display: grid; place-items: center;
  width: 40px; height: 40px;
  border: 1px solid var(--ah-line); border-radius: 999px;
  background: var(--ah-card); color: var(--slate-700);
  box-shadow: 0 10px 24px -16px rgba(8, 24, 47, .6);
  cursor: pointer;
}
.auth-back:active { transform: scale(.94); }

/* La nuit : ombres plus profondes et champs en color-scheme sombre (le
   selecteur natif et l'auto-remplissage restent lisibles sur la carte). */
:root[data-theme="dark"] .auth-card { box-shadow: 0 30px 70px -28px rgba(0, 0, 0, .75); }
:root[data-theme="dark"] .auth-back { box-shadow: 0 10px 24px -16px rgba(0, 0, 0, .8); }
:root[data-theme="dark"] .af-in { color-scheme: dark; }
:root[data-theme="dark"] .ah-logo { box-shadow: 0 14px 32px -12px rgba(0, 0, 0, .8); }
/* La nuit, la colonne de marque perd son bleu de nuit : elle prend le noir du
   systeme (--slate-100, juste au-dessus du fond de page). Le halo or et bleu,
   lui, reste : c'est la signature de l'ecran, pas un fond. */
:root[data-theme="dark"] .auth-aside,
:root[data-theme="dark"] .ah-brand-m { background: var(--slate-100); }
/* ... et ses halos sont BEAUCOUP plus discrets la nuit : a pleine force, le bleu
   du bas repeignait la vignette en bleu sur une page noire (« corrige la couleur
   dans le bandeau bleu ou est marque flash pay »). */
:root[data-theme="dark"] .auth-aside::before { opacity: .18; }
:root[data-theme="dark"] .auth-aside::after { opacity: .26; }

/* ---------- bureau : la colonne de marque prend sa place ---------- */
@media (min-width: 1024px) {
  .auth-aside {
    display: flex; flex-direction: column; justify-content: space-between;
    position: relative; isolation: isolate; overflow: hidden;
    flex: 0 0 50%;
    width: 50%; margin: 16px; padding: 56px;
    border-radius: 40px;
    background: var(--brand-900); color: var(--ah-onbrand);
    box-shadow: 0 20px 45px -20px rgba(8, 24, 47, .55);
  }
  /* les deux halos de la reference : l'or en haut a gauche, le bleu en bas a droite */
  .auth-aside::before {
    content: ''; position: absolute; z-index: -1; left: 0; top: 0;
    width: min(62%, 420px); aspect-ratio: 1; border-radius: 50%;
    filter: blur(60px); transform: translate(-30%, -55%);
    background: var(--amber-500); opacity: .36;
  }
  .auth-aside::after {
    content: ''; position: absolute; z-index: -1; right: 0; bottom: 0;
    width: min(78%, 520px); aspect-ratio: 1; border-radius: 50%;
    filter: blur(60px); transform: translate(34%, 52%);
    background: var(--ah-brand-500); opacity: .6;
  }
  /* inscription : colonne CLAIRE, sans halo, avec les trois arguments */
  .auth-aside--light {
    flex: 0 0 54%; width: 54%;
    margin: 0; padding: 56px 48px;
    background: transparent; color: var(--ah-ink);
    box-shadow: none;
  }
  .auth-aside--light::before, .auth-aside--light::after { content: none; }
  .auth-aside--light .ah-hero h2 { font-size: 2.6rem; line-height: 1.1; }
  .auth-aside--light .ah-hero p { margin-top: 16px; font-size: 15px; color: var(--ah-muted); }
  .auth-aside--light .ah-hero h2 { color: var(--ah-ink); }

  .auth-main { flex: 1 1 auto; padding: 40px 20px; }
  .ah-brand-m, .ah-brand-s { display: none; }
}

/* Telephone : la colonne de marque disparait, les vignettes prennent le relais. */
@media (max-width: 1023px) {
  .auth-shell { flex-direction: column; }
  .auth-main { padding: 64px 20px 48px; }
  .ah-hero h2 { font-size: 2.1rem; }
}

/* ---------------------------------------------------------------------------
   BANDE DE LA BARRE D'ETAT SUR LES ECRANS D'ENTREE
   (« sur iOS l'entete de l'ecran est toujours flou »).
   Dans l'APPLICATION WEB installee, iOS dessine sa barre d'etat PAR-DESSUS la
   page (`viewport-fit=cover`, meta de app.html) et LAVE la bande qu'elle
   recouvre : le haut parait flou. L'en-tete du client a sa reserve depuis le
   30/09/2026 (voir `body.client-app .topbar` plus haut) ; les ecrans de
   CONNEXION et d'INSCRIPTION, eux, l'avaient perdue au changement d'habillage :
   le bouton retour y est passe de `fixed` (avec son inset, voir `.auth-back`
   plus haut) a `absolute` avec un `top: 16px` sec, et `.auth-main` n'a jamais
   porte d'inset. Sur iPhone, le rond du retour etait donc a moitie sous l'heure
   et la batterie, et tout le haut de l'ecran paraissait lave.
   Pose EN FIN de feuille avec `body.auth-page` (0,2,1) : gagne sur les trois
   `.auth-main` (0,1,0) des blocs @media, quelle que soit la largeur. L'inset
   vaut 0 dans un onglet de navigateur et dans l'application Android (sa barre
   d'etat est opaque, le WebView commence dessous) : rien ne change la-bas.
   --------------------------------------------------------------------------- */
body.auth-page .auth-main {
  padding-top: calc(64px + env(safe-area-inset-top));
  padding-bottom: calc(48px + env(safe-area-inset-bottom));
}
body.auth-page .auth-back { top: calc(16px + env(safe-area-inset-top)); }
/* Bureau : la colonne de marque prend la hauteur, la carte garde ses 40 px. */
@media (min-width: 1024px) {
  body.auth-page .auth-main {
    padding-top: calc(40px + env(safe-area-inset-top));
    padding-bottom: calc(40px + env(safe-area-inset-bottom));
  }
}

/* ---------------------------------------------------------------------------
   AUCUN DEBORDEMENT HORIZONTAL SUR LES ECRANS D'ENTREE
   (capture iOS du 06/11/2026 : « la page se decale, on peut la faire glisser
   sur le cote »).
   La mesure sur la capture dit que ce n'est PAS notre dessin : la carte fait
   1148 px de large et le bouton Google 1029 px, pose a 59 px du bord gauche et
   60 px du bord droit, soit exactement les 20 px de rembourrage de la carte.
   C'est donc la PAGE qui devient glissante. Deux sources, les deux fermees ici :
   1. les cadres que Google insere lui-meme (le bouton, plus ses cadres de
      service poses dans le document) : ils recoivent une largeur en PIXELS
      qu'on leur donne, ils ne connaissent pas la notre ;
   2. la regle du document : `overflow-x` n'etait ferme que sur `.auth-shell`.
      Un element fixe ou injecte HORS de la coquille (banniere de telechargement,
      cadre de service, toast) suffisait a rendre tout l'ecran glissant.
   `clip` d'abord : il ne cree pas de conteneur de defilement, donc aucun effet
   sur `position: fixed`, sur la barre du bas ou sur le clavier. `hidden` en
   repli pour les moteurs qui ne connaissent pas `clip`. */
body.auth-page { overflow-x: clip; }
@supports not (overflow-x: clip) {
  body.auth-page { overflow-x: hidden; }
}
body.auth-page .auth-shell,
body.auth-page .auth-wrap { max-width: 100%; }
body.auth-page .auth-aside { min-width: 0; }
/* La largeur du bouton se donne AU MOMENT DU DESSIN (`largeurGsi`, app.js) : le
   bouton de Google est dessine pour la largeur DEMANDEE, donc reduire son cadre
   apres coup coupe le « G » au bord droit (defaut constate le 06/11/2026). Le
   `max-width` ci-dessous n'est qu'un dernier garde-fou : il ne mord jamais,
   puisqu'on ne demande jamais plus large que la colonne. */
.gsi-wrap, #gsi-btn, .gsi-comptes { min-width: 0; max-width: 100%; }
/* LE BOUTON DE GOOGLE : ON NE TOUCHE PLUS A SON DESSIN (06/11/2026).
   Journal des essais de la soiree, pour ne pas refaire le chemin — chaque
   habillage ajoute s'est retourne contre le bouton :
     - `width: 100% !important` sur le cadre ET sur les boites internes de
       Google : il en imbrique plusieurs, les forcer DEFORME son dessin (rond
       rouge geant, texte coupe, deux cadres superposes a l'actualisation) ;
     - rognage (`overflow: hidden` + `border-radius`) : coupe le rond blanc du
       logo a droite, et fait entrer le fond sombre dans le blanc — « le noir
       cache le G » ;
     - cerne par-dessus (`::after`) : se pose sur le logo qui touche le bord.
   Conclusion : le dessin appartient a Google, et il est correct (pilule, logo
   rond a droite selon le theme du telephone). On ne le rogne pas, on ne le
   recouvre pas, on ne le redessine pas. Seule regle gardee : il ne depasse
   jamais la colonne, et il est centre dedans. La largeur DESSINEE est celle
   qu'on passe a Google (`largeurGsi`, app.js, mesuree en offsetWidth, insensible
   aux animations de la carte). */
/* CORRIGE LE « G COUPE » (06/11/2026, 23 h 10). Le bord n'etait pas arrondi : le
   cadre de Google etait coupe NET au milieu du logo, donc plus etroit que le
   bouton dessine. Deux regles en etaient la cause, toutes les deux retirees ici :
   `width: auto` sur le conteneur (une boite qui se retrecit sur son contenu vide,
   donc une largeur de reference instable) et `max-width: 100%` sur le `iframe`
   (calculee contre cette boite, elle rognait le cadre dessine a 320/344 px).
   On garde une boite PLEINE LARGEUR, une seule largeur demandee a Google
   (`largeurGsi`, app.js), et AUCUN echange apres coup. */
/* LES BORNES ARRONDIES (06/11/2026, derniere retouche de la serie). Une fois la
   largeur juste, il restait un RECTANGLE blanc : le cadre de Google a un fond
   blanc carre et dessine sa pilule a l'interieur, laissee a ~10 px de chaque
   bord. On ne peut pas styler l'interieur d'un cadre d'un autre domaine : on
   arrondit donc le CADRE et on rogne ses coins (`border-radius: 999px` +
   `overflow: hidden`). Le rayon vaut la moitie de la hauteur du bouton, comme
   Google ; le dessin (texte, avatar, G) est a l'interieur, donc rien n'est coupe.
   Ne JAMAIS mettre `max-width` sur le cadre : c'est ce qui rognait le G. */
body.auth-page #gsi-btn {
  display: block; width: 100%; min-width: 0; margin: 0;
  border-radius: 999px; overflow: hidden;
}
/* Le cadre garde SA hauteur et SA largeur inline (ne pas les ecraser : la hauteur
   `100%` d'un parent a hauteur automatique retombe sur 150 px par defaut). */
body.auth-page #gsi-btn iframe { display: block; border: 0; }

/* ---------------------------------------------------------------------------
   INSCRIPTION : ECRAN PLUS COURT (09/11/2026)
   « c est trop long le panneau » : les six champs (nom, email, pays,
   telephone, mot de passe, parrainage) + le bouton ne tenaient pas sur un
   telephone, il fallait faire defiler pour atteindre « Creer le compte ».
   On resserre UNIQUEMENT l'ecran d'inscription (`.auth-main--wide`) : la
   connexion et le reste du site gardent leur aeration. Environ 14 px gagnes
   par champ (interligne + hauteur + marge), plus la carte et les titres.
   Regles posees EN FIN de feuille : `body.auth-page` (0,2,1) l'emporte sur les
   `.auth-main` des blocs @media plus haut, quelle que soit la largeur.
   --------------------------------------------------------------------------- */
body.auth-page .auth-main--wide .auth-card { padding: 20px; border-radius: 22px; }
body.auth-page .auth-main--wide .auth-card-t { font-size: 21px; }
body.auth-page .auth-main--wide .auth-card-s { margin: 2px 0 14px; font-size: 13px; }
body.auth-page .auth-main--wide .af { margin-bottom: 10px; }
body.auth-page .auth-main--wide .af-lb { margin-bottom: 4px; font-size: 13px; }
body.auth-page .auth-main--wide .af-in { height: 40px; border-radius: 13px; }
body.auth-page .auth-main--wide .af-go { padding: 11px 18px; }
body.auth-page .auth-main--wide .auth-sep { margin: 14px 0; }
body.auth-page .auth-main--wide .auth-foot { margin-top: 16px; font-size: 13px; }
@media (max-width: 1023px) {
  body.auth-page .auth-main--wide {
    padding-top: calc(56px + env(safe-area-inset-top));
    padding-bottom: calc(24px + env(safe-area-inset-bottom));
  }
}

/* Pays + telephone cote a cote, sur l'inscription seulement (voir app.js,
   `.af-duo`). En dessous de 360 px de large, on revient a une colonne. */
body.auth-page .auth-main--wide .af-duo {
  /* La case « Pays » ne porte plus que l'indicatif (« +228 ») et plus aucune
     icone : 14 px de retrait + ~38 px de texte + 30 px de fleche = ~82 px, on
     prend 96 px. (96 px rognait le texte quand l'icone globe y etait encore :
     « +2 » au lieu de « +228 ».) Le telephone prend tout le reste. */
  /* 09/11/2026, « reduit encore la taille du panneau +228 » : 14 px de retrait
     + ~38 px de texte + 28 px pour la fleche = 80 px utiles, on prend 84 px. */
  display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 10px;
}
body.auth-page .auth-main--wide .af-duo .af-box--sel .af-in { padding-right: 28px; }
body.auth-page .auth-main--wide .af-duo .af { margin-bottom: 10px; min-width: 0; }
body.auth-page .auth-main--wide .af-duo .af-box,
body.auth-page .auth-main--wide .af-duo .af-in { width: 100%; min-width: 0; max-width: 100%; }
/* Plus d'icone dans la case « Pays » (09/11/2026 : « enleve le cercle rond qui
   est derriere +228 ») : le retrait de 40 px laisse la place au texte.
   ATTENTION : la regle ne vise QUE la case a liste deroulante. Ecrite sur tous
   les `.af-in` du duo, elle retirait aussi le retrait du champ TELEPHONE et son
   icone passait par-dessus le numero (« 0115476 » colle a l'icone, vu sur la
   capture du 09/11 a 10:52). */
body.auth-page .auth-main--wide .af-duo .af-box--sel .af-in { padding-left: 14px; }
@media (max-width: 359px) {
  body.auth-page .auth-main--wide .af-duo { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------------------
   CONNEXION : CARTE UN PEU PLUS COURTE (09/11/2026, « reduit un peu la panneau
   de connection »). Memes leviers que l'inscription (champs plus bas, ecarts plus
   serres, carte moins rembourree), mais en plus doux : la connexion n'a que deux
   champs, elle n'a pas besoin d'autant de gain. `:not(.auth-main--wide)` laisse
   l'inscription intacte (ses valeurs sont dans le bloc precedent).
   --------------------------------------------------------------------------- */
body.auth-page .auth-main:not(.auth-main--wide) .auth-card { padding: 24px; }
body.auth-page .auth-main:not(.auth-main--wide) .auth-card-t { font-size: 22px; }
body.auth-page .auth-main:not(.auth-main--wide) .auth-card-s { margin: 2px 0 16px; font-size: 13px; }
body.auth-page .auth-main:not(.auth-main--wide) .af { margin-bottom: 12px; }
body.auth-page .auth-main:not(.auth-main--wide) .af-lb { margin-bottom: 6px; font-size: 13px; }
body.auth-page .auth-main:not(.auth-main--wide) .af-in { height: 42px; border-radius: 14px; }
body.auth-page .auth-main:not(.auth-main--wide) .auth-sep { margin: 16px 0; }
body.auth-page .auth-main:not(.auth-main--wide) .auth-foot { margin-top: 16px; font-size: 13px; }

/* =====================================================================
   HISTORIQUE — forme de FRANCKO RECHARGE (10/11/2026 : « fait moi
   l'historique de franko recharge sur mon projet flash pay, regarde comment
   j'ai fait et change »). Le squelette vient de la capture de reference
   (ladose multiservices) ; les couleurs restent les NOTRES : l'or de la
   maison sur la pilule active, le bleu de marque sur les badges de type.
   Tete (titre + sous-titre + rond Actualiser), trois pilules de filtre,
   cartes a TROIS TEMPS avec un pied « Recu : Voir / PDF ».
   Jetons seulement (--surface, --slate-*, --amber-*) : aucun fond blanc
   fige, l'ecran suit le theme clair / nuit.
   ===================================================================== */
body.client-app .hist-page{
  background: var(--surface);
  margin: -16px -16px 0; padding: 12px 16px calc(24px + env(safe-area-inset-bottom));
  border-radius: 0 0 26px 26px;
  min-height: 100vh; padding-bottom: calc(96px + env(safe-area-inset-bottom));
}
:root[data-theme="dark"] body.client-app .hist-page{ background: var(--slate-50); }
body.client-app .hist-page .ui-head{ align-items: flex-start; }
body.client-app .hist-page .ui-head .ui-ico{ display: none; }
body.client-app .hist-page .ui-head .ui-t{ color: var(--slate-900); }
body.client-app .hist-page .ui-head .ui-s{ color: var(--slate-500); }
body.client-app .hist-tete{
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 6px 0 14px; }
body.client-app .hist-refresh{
  flex: none; width: 46px; height: 46px; border-radius: 50%; border: 1px solid var(--slate-200);
  background: var(--surface); color: var(--slate-900);
  display: grid; place-items: center; box-shadow: 0 10px 20px -14px rgba(0,0,0,.55);
}
body.client-app .hist-filtres{ display: flex; gap: 10px; flex-wrap: wrap; padding-bottom: 16px; }
body.client-app .hist-pilule{
  border: 1px solid var(--slate-200); border-radius: 999px; padding: 7px 14px; font-family: inherit;
  font-size: 12.5px; font-weight: 700; background: var(--surface); color: var(--slate-700);
}
body.client-app .hist-pilule.on{
  background: var(--amber-500); color: var(--ah-gold-ink); border-color: transparent; }

/* la carte d'une operation : trois temps, pied separe par un filet */
body.client-app .hist-card{
  display: block; background: var(--surface); border: 1px solid var(--slate-200);
  border-radius: 20px; padding: 12px 12px 0; box-shadow: 0 18px 36px -30px rgba(0,0,0,.6);
}
body.client-app .hist-card .li-ico{ display: none; }
body.client-app .hist-haut{ display: flex; align-items: center; justify-content: space-between; gap: 8px; }
body.client-app .hist-pastilles{ display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; overflow: hidden; min-width: 0; }
body.client-app .hist-pastilles .badge{ font-size: 11px; padding: 2.5px 8px; }
body.client-app .hist-ref{ font-size: 11px; color: var(--slate-500); }
body.client-app .hist-montant{ font-size: 15.5px; font-weight: 800; white-space: nowrap; }
body.client-app .hist-nom{ margin-top: 6px; font-size: 13.5px; line-height: 1.25; font-weight: 600; color: var(--slate-900); }
body.client-app .hist-meta{ margin-top: 2px; font-size: 11px; line-height: 1.25; color: var(--slate-500); }
body.client-app .hist-code{ margin-top: 6px; font-family: var(--mono); font-size: 12px; color: var(--slate-700); }
body.client-app .hist-pied{
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 10px -12px 0; padding: 10px 12px 12px; border-top: 1px solid var(--slate-100);
}
body.client-app .hist-recu{ display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--slate-500); }
body.client-app .hist-pil{
  display: inline-flex; align-items: center; gap: 5px;
  border: 1px solid var(--slate-200); background: transparent; color: var(--slate-900);
  border-radius: 999px; padding: 5px 11px; font-family: inherit; font-size: 12px; font-weight: 600;
}
body.client-app .hist-pil:active{ background: var(--slate-100); }
body.client-app .hist-list{ display: flex; flex-direction: column; gap: 12px; }
body.client-app .hist-plus{
  display: block; width: 100%; margin-top: 14px; border: 1px solid var(--slate-200); border-radius: 999px;
  padding: 13px; font-family: inherit; font-size: 14px; font-weight: 700;
  background: var(--surface); color: var(--slate-900);
}
/* la tete de l'historique : titre de 22 px sur le fond de la page */
body.client-app .hist-page .ui-head .ui-t{ font-size: 22px; font-weight: 800; letter-spacing: -.02em; line-height: 1.1; }
body.client-app .hist-page .ui-head .ui-s{ margin-top: 3px; font-size: 12px; }
body.client-app .hist-page .small.muted,
body.client-app .hist-page .empty{ color: var(--slate-500); }

/* =====================================================================
   10/11/2026 — L'ECRAN « RECHARGER 1XBet » AMELIORE (prompt du client)
   degrade bleu dans la tete + badge « Paiement 100% Securise », cartes
   blanches sans cerne bleu, tuile du reseau ACTIF teintee a la couleur de
   l'operateur (Flooz orange, Mixx bleu), logo de l'operateur DANS le champ
   du numero, montant tres large, pilule verte de l'ID verifie, bouton
   « Continuer » en degrade cyan -> bleu avec halo.
   La peau est portee par `:is(.dp-depot, .dp-retrait)` (11/11/2026 : le client a
   demande le MEME habillage sur le retrait — « oui »). Les deux ecrans partagent
   donc une seule source : ils ne peuvent plus diverger.
   Couleurs : jetons de la maison seulement (brand-800 -> 600 -> 500 pour la
   tete, sky-500 -> brand-500 pour l'action, emerald-600 pour le badge vert,
   --flooz-500 pour l'orange de l'operateur, ajoute au premier :root).
   ===================================================================== */

/* ---- 1. la tete : degrade, retour translucide, titre blanc, badge ----- */
body.client-app :is(.dp-depot, .dp-retrait) .dp-tete {
  /* deux colonnes ELASTIQUES autour du titre : il reste EXACTEMENT au centre de
     l'ecran, que le badge fasse 40 px ou 140 px. `minmax(0,1fr)` les autorise a
     descendre sous la largeur du badge sur un petit telephone (le texte du badge
     s'y coupe proprement, voir plus bas). */
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 8px;
  /* 12/11/2026 — « tu peux enlever l'entete bleu la » : PLUS DE BANDE BLEUE.
     La tete se pose sur le FOND DE LA PAGE : pas de degrade, pas de rayon, pas
     d'ombre, et plus de debordement lateral (c'est le degrade qui justifiait
     les marges negatives). Le rembourrage du haut reste, lui : la barre d'etat
     du telephone doit toujours pouvoir passer au-dessus de la fleche.
     La fleche de retour, le titre et le badge reprennent les couleurs de la
     page (surface + cerne + encre du theme) : sur un fond clair, du blanc
     translucide ne se lirait pas. */
  margin: calc(-6px - env(safe-area-inset-top)) 0 12px;
  padding: calc(8px + env(safe-area-inset-top)) 0 0;
  background: none;
  border-radius: 0;
  box-shadow: none;
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-back {
  border-radius: 999px; background: var(--surface); color: var(--slate-700);
  border: 1px solid var(--cx-cerne);
  box-shadow: none;
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-back:active { background: var(--slate-100); }
body.client-app :is(.dp-depot, .dp-retrait) .dp-titre {
  color: var(--slate-900); font-size: 18px; font-weight: 800; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.client-app .dp-secure {
  display: inline-flex; align-items: center; justify-self: end; gap: 5px;
  white-space: nowrap; min-width: 0; max-width: 100%;
  padding: 6px 9px; border-radius: 999px;
  /* meme raison que la tete : le badge se lit sur la page, pas sur du bleu. */
  background: var(--surface); color: var(--slate-600);
  border: 1px solid var(--cx-cerne);
  font-size: 10px; font-weight: 700; letter-spacing: .01em; line-height: 1;
}
body.client-app .dp-secure svg { width: 12px; height: 12px; flex: none; color: var(--emerald-600); }
body.client-app .dp-secure-t { overflow: hidden; text-overflow: ellipsis; }
/* sous 375 px, le badge ne garde que sa coche : le titre et lui ne peuvent pas
   tenir ensemble sur une ligne sans se manger. */
@media (max-width: 374px) { body.client-app .dp-secure-t { display: none; } }

/* ---- 2. les cartes : blanches, coins larges, ombre douce, SANS cerne -- */
body.client-app :is(.dp-depot, .dp-retrait) .dp-section {
  background: var(--surface); border: 1px solid rgba(16, 24, 40, .05);
  border-radius: 22px; padding: 12px 14px 14px;
  box-shadow: 0 6px 18px rgba(16, 24, 40, .06);
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-page .label,
body.client-app :is(.dp-depot, .dp-retrait) .label { color: var(--slate-700); font-size: 13px; margin-bottom: 9px; }

/* ---- 3. identifiant : champ doux + loupe, puis pilule verte verifiee --- */
body.client-app :is(.dp-depot, .dp-retrait) .input,
body.client-app :is(.dp-depot, .dp-retrait) .select,
body.client-app :is(.dp-depot, .dp-retrait) .dp-montant { background: var(--slate-100); border-radius: 16px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-idok { display: flex; align-items: center; gap: 8px; margin-top: 9px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-idpill {
  display: inline-flex; align-items: center; min-height: 38px; padding: 6px 16px;
  border-radius: 999px; background: var(--brand-50); color: var(--slate-900);
  border: 1px solid rgba(31, 111, 191, .10);
  font-size: 13px; font-weight: 700; letter-spacing: .01em;
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-idbadge {
  width: 24px; height: 24px; flex: none; border-radius: 999px;
  background: var(--emerald-600); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 6px rgba(22, 163, 74, .35);
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-idbadge svg { width: 13px; height: 13px; }

/* ---- 4. montant : tres large, unite fixe, pilules pleines a l'appui --- */
body.client-app :is(.dp-depot, .dp-retrait) .dp-montant-in { font-size: 30px; font-weight: 800; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-pilule { border-color: var(--dp-bord); background: var(--dp-carte); }
body.client-app :is(.dp-depot, .dp-retrait) .dp-pilule.on {
  background: var(--dp-cobalt-pale); color: var(--dp-cobalt); border-color: var(--dp-cobalt);
  box-shadow: none;
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-pilule:active { transform: scale(.97); }

/* ---- 5. « Payer avec » : tuile ACTIVE a la couleur de l'operateur ------ */
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile.dp-tuile-l2 {
  border: 2px solid var(--dp-bord); background: var(--dp-champ);
  border-radius: 18px; transition: border-color .18s ease, box-shadow .18s ease, background .18s ease;
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile.dp-tuile-l2.on {
  border-color: var(--dp-cobalt); background: var(--dp-carte);
  box-shadow: 0 8px 20px rgba(15, 23, 42, .10);
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile[data-m="flooz"].on {
  --op: var(--flooz-500); box-shadow: 0 8px 20px rgba(249, 115, 22, .24);
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile[data-m="mixx"].on {
  --op: var(--brand-500); box-shadow: 0 8px 20px rgba(29, 78, 216, .20);
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile .dp-coche { width: 24px; height: 24px; background: var(--dp-encre); color: var(--dp-carte); }
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile.off { opacity: .45; }

/* ---- 6. numero de paiement : logo de l'operateur DANS le champ --------- */
body.client-app :is(.dp-depot, .dp-retrait) .dp-telrow { position: relative; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-telrow .input { padding-right: 58px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-telrow .paylogo {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; border-radius: 9px; overflow: hidden;
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-telrow .paylogo img { width: 30px; height: 30px; object-fit: contain; }

/* ---- 7. l'action : degrade cyan -> bleu, halo lumineux ----------------- */
body.client-app :is(.dp-depot, .dp-retrait) .dp-continuer {
  height: 56px; border: 0; border-radius: 999px; color: #fff;
  background: linear-gradient(135deg, var(--sky-500) 0%, var(--brand-500) 100%);
  box-shadow: 0 14px 28px rgba(34, 211, 238, .30), 0 4px 10px rgba(37, 99, 235, .22);
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-continuer:hover { filter: brightness(1.04); }
body.client-app :is(.dp-depot, .dp-retrait) .dp-continuer:active {
  transform: translateY(1px);
  box-shadow: 0 8px 18px rgba(34, 211, 238, .24), 0 2px 6px rgba(37, 99, 235, .18);
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-continuer.attente,
body.client-app :is(.dp-depot, .dp-retrait) .dp-continuer[aria-busy="true"] {
  box-shadow: 0 8px 18px rgba(34, 211, 238, .22);
}

/* ---- 8. le lien du bas : « Comment faire ? » au depot, « Retrait avec
   <marque> » au retrait — MEME traitement (texte de marque, centre, sans cadre),
   pour que les deux ecrans se lisent pareil. Le contenu reste replie et
   accessible d'un appui. --------------------------------------------------- */
body.client-app :is(.dp-depot, .dp-retrait) .dep-aide > summary,
body.client-app :is(.dp-depot, .dp-retrait) .fold > summary {
  color: var(--brand-600); font-size: 13px; font-weight: 700; text-align: center;
  justify-content: center; gap: 6px;
}
body.client-app :is(.dp-depot, .dp-retrait) .fold {
  background: transparent; border: 0; border-radius: 0; box-shadow: none;
}
body.client-app :is(.dp-depot, .dp-retrait) .fold > summary { padding: 8px 6px; }
body.client-app :is(.dp-depot, .dp-retrait) .fold[open] > summary {
  border-bottom: 0; border-radius: 14px; background: var(--surface);
}

/* =====================================================================
   10/11/2026 — DESIGN SYSTEM « FLASH PAY » (prompt du client)
   En-tete en CARTE BLANCHE arrondie (logo, nom du client en majuscules
   grisees, ronds d'action), barre du bas FLOTTANTE arrondie dont l'onglet
   actif est une masse bleu nuit, cartes secondaires a pastille de couleur.
   Tout est scope `body.client-app` : le PANNEAU d'administration et les
   pages de connexion gardent leur forme.
   ===================================================================== */

/* ---- 1. l'en-tete : carte blanche posee sur le fond gris-bleu ---------- */
/* UNE SEULE CARTE (corrige le 10/11/2026 : « cest mal fait ici ») — la barre
   avait deja sa carte blanche ; en posant une seconde carte sur `.cx-top` on
   voyait DEUX cadres arrondis l'un dans l'autre. La carte reste donc la BARRE,
   et `.cx-top` redevient transparent (il ne garde que la colonne de 720 px). */
/* EN-TETE SANS PANNEAU (10/11/2026 — « enleve les panneaux de l'entete », capture
   de la maquette) : la carte blanche autour du menu, du logo et de la roue est
   retiree. Le fond prend la couleur de la PAGE, pas `transparent` : la barre est
   `position: sticky`, un fond transparent laisserait le contenu defiler DERRIERE
   le logo et le titre. Meme couleur que la page = aucun panneau visible, et la
   bande de la barre d'etat (voir `padding-top` plus haut) garde sa reserve. */
body.client-app .topbar {
  margin: calc(6px + env(safe-area-inset-top)) 12px 6px;
  padding: 10px 12px;
  background: var(--brand-50);
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
/* Le fond de la PAGE de l'espace client est `--brand-50` en clair et `--slate-50`
   la nuit (voir `body.client-app` plus haut) : l'en-tete doit suivre les DEUX,
   sinon il reste une bande plus claire que la page = un panneau. */
:root[data-theme="dark"] body.client-app .topbar { background: var(--slate-50); }
body.client-app .topbar .cx-top {
  background: transparent; border: 0; border-radius: 0; box-shadow: none;
  padding: 0; gap: 12px;
}
/* le nom du client sous la marque : MAJUSCULES grisees (design system) */
body.client-app .topbar .who {
  /* 12/11/2026 — MAQUETTE : « CASHDESK » en BLEU ROI sous « FLASH PAY ». */
  text-transform: uppercase; letter-spacing: .16em; font-size: 11px;
  font-weight: 700; color: var(--roi); opacity: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 42vw;
}
/* LES TROIS RONDS, MEME DIAMETRE ET MEME STYLE (corrige le 10/11/2026) : les
   icones etaient a 35 px et l'avatar a 38 px. Et le bouton d'avatar gardait le
   CERNE NATIF du navigateur (un lisere sombre en relief, visible sur la capture
   comme un arc noir a droite du rond bleu) : il n'avait jamais ete remis a zero. */
body.client-app .topbar .cx-actions { gap: 8px; }
body.client-app .topbar .cx-ico,
body.client-app .topbar .cx-avatar { width: 40px; height: 40px; }
body.client-app .topbar .cx-ico {
  background: var(--surface); border: 1px solid var(--cx-cerne); color: var(--slate-700);
}
body.client-app .topbar .cx-ico:hover { background: var(--brand-50); }
body.client-app .topbar .cx-avatar {
  border: 0; padding: 0; font-size: 17px; background: var(--brand-600); color: #fff;
}

@media (min-width: 721px) {
  /* grand ecran : la barre RESTE une carte arrondie (la regle d'origine
     l'aplatissait en bandeau plein largeur, d'ou le cadre carre autour de la
     carte sur la capture du client). */
  body.client-app .topbar {
    margin: calc(10px + env(safe-area-inset-top)) 12px 6px;
    padding: 12px 16px;
    border-width: 0; border-radius: 0;
    background: var(--brand-50);
    box-shadow: none;
  }
}

/* ---- 2. la barre du bas : CAPSULE flottante, onglet actif en masse bleue --
   10/11/2026 — « enleve les panneaux de la barre de navigation » / maquette : la
   barre garde son fond blanc (sans lui, le contenu defilerait derriere les icones)
   mais elle perd son air de panneau : rayon 999 px (capsule, deux bouts arrondis)
   au lieu de 28 px et ombre adoucie. */
/* 12/11/2026 — PLUS DE FLOTTANT (demande du proprietaire, capture a l'appui) :
   la capsule de 10 px de marge devient une bande PLEINE LARGEUR collee au bord bas
   de l'ecran (rayon 0, trait fin en haut, aucune ombre portee). Le fond opaque et
   la masse bleu nuit de l'onglet actif ne bougent pas. */
body.client-app .bottomnav {
  left: 0; right: 0; bottom: 0;
  margin: 0; width: auto; max-width: none;
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
  border-radius: 0; border: 0; border-top: 1px solid var(--cx-cerne);
  background: var(--surface);
  box-shadow: none;
}
body.client-app .bottomnav .item {
  border-radius: 999px; padding: 8px 4px; transition: background .18s ease, color .18s ease;
}
body.client-app .bottomnav .item.active {
  /* 12/11/2026 — MAQUETTE : masse BLEU MARINE, icone + libelle cote a cote. */
  background: var(--navy); color: #fff;
  flex-direction: row; gap: 8px;
  box-shadow: 0 6px 16px rgba(15, 44, 89, .30);
}
body.client-app .bottomnav .item.active span { font-weight: 700; }
@media (prefers-reduced-motion: reduce) {
  body.client-app .bottomnav .item { transition: none; }
}

/* ---- 3. champs et boutons : grands arrondis du design system ----------- */
body.client-app .input,
body.client-app .select,
body.client-app .textarea { border-radius: 16px; }
body.client-app .btn { border-radius: 16px; }
body.client-app .btn-block { border-radius: 18px; }

/* ---- 4. cartes secondaires : la pastille de l'icone prend une couleur vive
   (jaune / bleu / vert, design system). La classe de couleur est portee par la
   tuile elle-meme (`or` / `bleu` / `vert`, voir tuilesAccueil) : rien a deviner
   par la position. -------------------------------------------------------- */
body.client-app .cx-tui-rond.vert { background: var(--emerald-600); }

/* =====================================================================
   11/11/2026 — LA FENETRE « PAIE AVEC TON TELEPHONE » (prompt du client)
   Verre depoli, coins de 24 px, tag d'operateur avec son logo, code USSD
   en monospace, « Payer » en degrade et « Copier le code » etiquete,
   carte d'attente translucide avec barre animee, sorties bleue et rouge.
   Scope `.pay-ecran` : aucun autre ecran ne change.
   ===================================================================== */
body.client-app .pay-ecran .pay-titre {
  font-size: 22px; font-weight: 800; letter-spacing: -.02em; text-align: center; margin-bottom: 12px;
}
/* le montant : une PASTILLE, pas une ligne grise */
body.client-app .pay-ecran .pay-montant {
  display: inline-flex; align-items: baseline; gap: 8px; justify-content: center;
  font-size: 12.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--slate-500); background: var(--brand-50); border-radius: 999px;
  padding: 8px 16px; margin: 0 auto 14px; border: 1px solid var(--brand-100);
}
body.client-app .pay-ecran .pay-montant b {
  font-size: 19px; font-weight: 800; letter-spacing: -.01em; color: var(--brand-700);
}
body.client-app .pay-ecran .pay-montant { display: flex; width: fit-content; }
/* le tag de l'operateur qui recoit : logo + nom */
body.client-app .pay-ecran .pay-reseau {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em; color: var(--slate-600);
  margin: 0 0 16px;
}
body.client-app .pay-ecran .pay-reseau .paylogo { width: 26px; height: 26px; }
body.client-app .pay-ecran .pay-reseau .paylogo img { width: 26px; height: 26px; object-fit: contain; }
/* le code USSD : verre, monospace, tres lisible */
body.client-app .pay-ecran .pay-code {
  background: rgba(255, 255, 255, .72);
  border: 1px solid rgba(255, 255, 255, .75);
  box-shadow: 0 8px 24px rgba(16, 24, 40, .08), inset 0 1px 0 rgba(255, 255, 255, .9);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-radius: 20px; padding: 16px 14px; text-align: center;
}
body.client-app .pay-ecran .pay-code-v {
  font-family: var(--mono); font-size: 19px; font-weight: 700; letter-spacing: .01em;
  color: var(--brand-800); word-break: break-all;
}
/* les deux actions : Payer en degrade, puis Copier etiquete */
body.client-app .pay-ecran .pay-ligne { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
body.client-app .pay-ecran .pay-payer {
  height: 56px; border-radius: 999px; border: 0; color: #fff; font-size: 16px; font-weight: 800;
  background: linear-gradient(135deg, var(--sky-500) 0%, var(--brand-500) 100%);
  box-shadow: 0 14px 28px rgba(34, 211, 238, .30), 0 4px 10px rgba(37, 99, 235, .22);
  display: flex; align-items: center; justify-content: center; gap: 9px;
}
body.client-app .pay-ecran .pay-payer:active { transform: translateY(1px); filter: brightness(.98); }
body.client-app .pay-ecran .pay-copier {
  height: 46px; border-radius: 999px; width: 100%;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--surface); border: 1px solid var(--slate-200); color: var(--slate-700);
  font-size: 13.5px; font-weight: 700; cursor: pointer;
}
body.client-app .pay-ecran .pay-copier:active { background: var(--slate-100); }
/* apres la copie : le bouton passe au vert une seconde et demie */
body.client-app .pay-ecran .pay-copier.pay-copie-ok {
  background: var(--emerald-50); border-color: var(--emerald-600); color: var(--emerald-700);
}
/* la carte d'attente : translucide, avec sa barre animee */
body.client-app .pay-ecran .pay-attente {
  position: relative; overflow: hidden;
  background: rgba(255, 255, 255, .7);
  border: 1px solid rgba(255, 255, 255, .8);
  box-shadow: 0 10px 26px rgba(16, 24, 40, .08);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-radius: 22px; padding: 14px 14px 18px; margin-top: 16px;
}
body.client-app .pay-ecran .pay-bar {
  position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
  background: linear-gradient(90deg, transparent, var(--brand-500), var(--sky-500), transparent);
  background-size: 45% 100%; background-repeat: no-repeat;
  animation: pay-barre 1.5s linear infinite;
}
@keyframes pay-barre {
  0%   { background-position: -45% 0; }
  100% { background-position: 145% 0; }
}
@media (prefers-reduced-motion: reduce) {
  body.client-app .pay-ecran .pay-bar { animation-duration: 4s; }
}
/* sorties : historique en bleu plein, annulation en contour rouge */
body.client-app .pay-ecran .btn-row .btn { border-radius: 16px; min-height: 46px; font-weight: 700; }
body.client-app .pay-ecran .pay-annuler {
  background: var(--surface); border: 1.5px solid var(--rose-600); color: var(--rose-600);
}

/* ---- 11/11/2026 — LA MEME FENETRE LA NUIT ---------------------------------
   Le verre etait ecrit en BLANC translucide : en mode sombre il posait des
   blocs gris clair sur fond noir, avec du texte blanc dessus — le paragraphe
   d'attente devenait illisible (capture du client). Le verre devient donc du
   verre NOIR translucide, et les encres repassent en clair. ----------------- */
:root[data-theme="dark"] body.client-app .pay-ecran .pay-code,
:root[data-theme="dark"] body.client-app .pay-ecran .pay-attente {
  background: rgba(255, 255, 255, .06);
  border-color: rgba(255, 255, 255, .12);
  box-shadow: 0 10px 26px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 255, 255, .06);
}
:root[data-theme="dark"] body.client-app .pay-ecran .pay-code-v { color: var(--glass-ink); }
:root[data-theme="dark"] body.client-app .pay-ecran .pay-montant {
  background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .12);
  color: var(--glass-ink-doux);
}
:root[data-theme="dark"] body.client-app .pay-ecran .pay-montant b { color: var(--glass-accent); }
:root[data-theme="dark"] body.client-app .pay-ecran .pay-reseau { color: var(--glass-ink-clair); }
:root[data-theme="dark"] body.client-app .pay-ecran .pay-copier {
  background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .16); color: var(--glass-ink);
}
:root[data-theme="dark"] body.client-app .pay-ecran .pay-copier:active {
  background: rgba(255, 255, 255, .12);
}
:root[data-theme="dark"] body.client-app .pay-ecran .pay-attente-t { color: var(--glass-titre); }
:root[data-theme="dark"] body.client-app .pay-ecran .pay-attente-t #dep-attente-secs { color: var(--glass-accent); }
:root[data-theme="dark"] body.client-app .pay-ecran .pay-attente-p { color: var(--glass-ink-doux); }
:root[data-theme="dark"] body.client-app .pay-ecran .pay-annuler {
  background: transparent; border-color: var(--rose-500); color: var(--rose-500);
}
/* le compte a rebours ne se coupe pas entre le nombre et la seconde */
body.client-app .pay-ecran #dep-attente-secs { white-space: nowrap; }

/* =====================================================================
   11/11/2026 — « TOUT VISIBLE SANS DEFILER » puis « c est en trop petit,
   fait en plein ecran » : le premier passage avait trop reduit. On REMONTE
   les corps et les hauteurs (on garde 3 a 5 px de moins que l'origine), et
   c'est la PAGE qui prend toute la hauteur : les cartes gardent leur taille
   et l'espace libre tombe avant le bouton, colle en bas par `margin-top:
   auto`. Meme peau pour le retrait.
   ===================================================================== */
body.client-app :is(.dp-depot, .dp-retrait) .dp-form { flex: 1 1 auto; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-tete {
  margin-bottom: 12px; padding-bottom: 12px;
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-titre { font-size: 18px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-secure { padding: 6px 9px; font-size: 10px; }

/* 1. les cartes */
body.client-app :is(.dp-depot, .dp-retrait) .dp-section {
  margin-bottom: 12px; padding: 11px 13px 12px;
}
body.client-app :is(.dp-depot, .dp-retrait) .label {
  font-size: 12.5px; margin-bottom: 7px; letter-spacing: .01em;
}
body.client-app :is(.dp-depot, .dp-retrait) .hint {
  font-size: 11.5px; margin-top: 5px; line-height: 1.32;
}

/* 2. les champs */
body.client-app :is(.dp-depot, .dp-retrait) .input,
body.client-app :is(.dp-depot, .dp-retrait) .select {
  height: 48px; font-size: 16px; border-radius: 15px;
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-idrow .input { height: 48px; }
body.client-app :is(.dp-depot, .dp-retrait) .dep-loupe { width: 38px; height: 38px; right: 5px; }

/* 3. la pilule « 1xBet · id » */
body.client-app :is(.dp-depot, .dp-retrait) .dp-idok { margin-top: 8px; gap: 8px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-idpill {
  min-height: 34px; padding: 5px 15px; font-size: 12.5px;
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-idbadge { width: 22px; height: 22px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-idbadge svg { width: 12px; height: 12px; }

/* 4. le montant : le plus gros chiffre de l'ecran, presque comme avant */
body.client-app :is(.dp-depot, .dp-retrait) .dp-montant { padding: 8px 13px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-montant-in { font-size: 28px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-montant-in::placeholder { font-size: 18px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-devise { font-size: 12px; }

/* 5. les puces de montant rapide */
body.client-app :is(.dp-depot, .dp-retrait) .dp-pilules { gap: 7px; margin-top: 8px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-pilule {
  height: 36px; font-size: 12.5px; border-radius: 999px;
}

/* 6. les tuiles d'operateur */
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile.dp-tuile-l2 {
  min-height: 58px; padding: 8px 10px; gap: 10px; border-radius: 17px;
}
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile.dp-tuile-l2 .paylogo { width: 34px; height: 34px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile.dp-tuile-l2 .paylogo img { width: 34px; height: 34px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile.dp-tuile-l2 .dp-tuile-nom { font-size: 15px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile-op { font-size: 11.5px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile .dp-coche { width: 22px; height: 22px; }

/* 7. la sortie : bouton et lien du bas */
body.client-app :is(.dp-depot, .dp-retrait) .dp-continuer { height: 52px; font-size: 15.5px; }
body.client-app :is(.dp-depot, .dp-retrait) .dp-aide-ligne { margin-top: 6px; }
body.client-app :is(.dp-depot, .dp-retrait) .dep-aide > summary,
body.client-app :is(.dp-depot, .dp-retrait) .fold > summary { font-size: 12.5px; }
body.client-app :is(.dp-depot, .dp-retrait) .fold > summary { padding: 7px 4px; }

/* 8. un cran de moins sur un ecran COURT seulement */
@media (max-height: 780px) {
  body.client-app :is(.dp-depot, .dp-retrait) .dp-section { margin-bottom: 10px; padding: 9px 12px 10px; }
  body.client-app :is(.dp-depot, .dp-retrait) .input,
  body.client-app :is(.dp-depot, .dp-retrait) .select,
  body.client-app :is(.dp-depot, .dp-retrait) .dp-idrow .input { height: 44px; }
  body.client-app :is(.dp-depot, .dp-retrait) .dp-tuile.dp-tuile-l2 { min-height: 52px; }
  body.client-app :is(.dp-depot, .dp-retrait) .dp-montant-in { font-size: 26px; }
  body.client-app :is(.dp-depot, .dp-retrait) .dp-continuer { height: 50px; }
}

/* ---- 11/11/2026 — « fait en plein ecran » : la fenetre de paiement prend
   TOUTE la hauteur et garde ses marges. En plein ecran la carte de la fenetre
   a `padding: 0` (l'ecran de succes apporte le sien) : le code, les boutons et
   les sorties touchaient les bords, et tout restait colle en haut avec un
   grand vide en bas. ------------------------------------------------------ */
body.client-app .modal-paiement .modal-card {
  min-height: 100dvh;
  display: flex; flex-direction: column;
  padding: calc(14px + env(safe-area-inset-top)) 14px calc(14px + env(safe-area-inset-bottom));
}
body.client-app .modal-paiement .pay-ecran {
  flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0;
}
/* les sorties descendent au pied de l'ecran : le vide tombe ENTRE la carte
   d'attente et elles, jamais sous le contenu */
body.client-app .modal-paiement .pay-ecran .btn-row { margin-top: auto; padding-top: 16px; }
/* le halo de « Payer » debordait sur les bords de l'ecran : un cran plus discret */
body.client-app .pay-ecran .pay-payer {
  box-shadow: 0 8px 18px rgba(34, 211, 238, .22), 0 3px 8px rgba(37, 99, 235, .18);
}

/* =====================================================================
   11/11/2026 (2e passe) — « CARTE FLOTTANTE PARFAITEMENT CENTREE »
   Le plein ecran etirait la vue sur toute la hauteur. On revient a une
   CARTE compacte (384 px au plus), centree sur un voile assombri et
   floute : en-tete centre, code en gris clair, Payer 75 % / Copier 25 %
   cote a cote, statut en bleu tres clair, sorties sur deux colonnes.
   ===================================================================== */
body.client-app .modal-paiement {
  align-items: center; justify-content: center; padding: 16px;
  background: rgba(15, 23, 42, .55);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
:root[data-theme="dark"] body.client-app .modal-paiement { background: rgba(0, 0, 0, .62); }
body.client-app .modal-paiement .modal-card {
  max-width: 384px; width: 100%; min-height: 0; height: auto; margin: auto;
  display: block; border-radius: 24px; padding: 20px 18px;
  background: var(--surface);
  box-shadow: 0 24px 60px -14px rgba(15, 23, 42, .5);
}
body.client-app .modal-paiement .pay-ecran { display: block; }

/* ---- 1. l'en-tete, tout centre ---------------------------------------- */
body.client-app .modal-paiement .pay-titre {
  font-size: 19px; font-weight: 800; text-align: center; margin: 0 0 10px;
}
body.client-app .modal-paiement .pay-montant {
  background: var(--slate-100); border-color: transparent;
  padding: 5px 14px; margin: 0 auto 8px; font-size: 11px; letter-spacing: .06em;
}
body.client-app .modal-paiement .pay-montant b { font-size: 16px; }
body.client-app .modal-paiement .pay-reseau {
  margin: 0 0 12px; font-size: 11px; font-weight: 700; color: var(--slate-500);
  letter-spacing: .05em; justify-content: center;
}

/* ---- 2. le code et les deux actions cote a cote ------------------------ */
body.client-app .modal-paiement .pay-code {
  background: var(--slate-100); border: 0; box-shadow: none;
  backdrop-filter: none; -webkit-backdrop-filter: none;
  border-radius: 16px; padding: 12px 10px;
}
body.client-app .modal-paiement .pay-code-v { font-size: 16px; color: var(--slate-900); }
body.client-app .modal-paiement .pay-ligne {
  display: flex; flex-direction: row; gap: 8px; margin-top: 12px;
}
body.client-app .modal-paiement .pay-payer {
  flex: 3 1 0; width: auto; height: 48px; font-size: 15px; gap: 7px;
}
body.client-app .modal-paiement .pay-copier {
  flex: 1 1 0; width: auto; height: 48px; padding: 0 4px;
  flex-direction: column; gap: 1px; font-size: 10px; line-height: 1.1;
}
body.client-app .modal-paiement .pay-copier svg { width: 17px; height: 17px; }
/* le micro-texte sous les boutons */
body.client-app .modal-paiement .pay-ligne + .hint {
  font-size: 11px; color: var(--slate-400); text-align: center; margin-top: 6px;
}

/* ---- 3. la carte de statut : bleu tres clair --------------------------- */
body.client-app .modal-paiement .pay-attente {
  background: var(--brand-50); border: 1px solid var(--brand-100);
  box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none;
  border-radius: 18px; margin-top: 12px; padding: 11px 12px 15px;
}
body.client-app .modal-paiement .pay-attente-t { font-size: 13.5px; }
body.client-app .modal-paiement .pay-attente-p { font-size: 12px; margin-top: 4px; }

/* ---- 4. les sorties : deux colonnes ----------------------------------- */
body.client-app .modal-paiement .pay-ecran .btn-row {
  margin-top: 12px; padding-top: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
}
body.client-app .modal-paiement .pay-ecran .btn-row .btn {
  min-height: 44px; font-size: 13px; border-radius: 14px; padding: 0 8px;
}
body.client-app .modal-paiement .pay-ecran .btn-row .btn svg { width: 15px; height: 15px; }
body.client-app .modal-paiement .pay-ecran .pay-annuler { border-width: 1.5px; }

/* la nuit : le voile et la carte gardent leurs surfaces sombres */
:root[data-theme="dark"] body.client-app .modal-paiement .modal-card { background: var(--surface); }

/* =====================================================================
   11/11/2026 — « l ecriture n est pas bien visible » (capture de la barre
   du bas en mode sombre) : les libelles inactifs sortaient en #64748B sur
   une barre a #1A1A1A (3,66:1) et le libelle de l'onglet actif en blanc
   sur bleu clair (3,92:1). Trois corrections mesurees :
     - la pastille active garde le BLEU NUIT du design system la nuit
       (blanc dessus = 11,8:1) au lieu du bleu clair ;
     - les entrees inactives passent en gris clair fixe (11,4:1) ;
     - le libelle grossit d'un demi-point et l'icone prend un trait un peu
       plus ferme pour rester nette a cette taille.
   ===================================================================== */
body.client-app .bottomnav .item { color: var(--slate-600); }
body.client-app .bottomnav .item span { font-size: 11.5px; font-weight: 700; }
:root[data-theme="dark"] body.client-app .bottomnav .item {
  color: var(--glass-ink-clair);
}
/* meme selecteur que la regle d'origine du theme sombre, ecrite plus loin :
   a specificite egale, c'est la DERNIERE qui gagne. */
:root[data-theme="dark"] body.client-app .bottomnav .item.active {
  /* la nuit, le marine serait invisible sur la barre sombre : bleu ROI. */
  background: var(--roi); color: #fff;
}
:root[data-theme="dark"] body.client-app .bottomnav .item svg { stroke-width: 2.1; }
:root[data-theme="dark"] body.client-app .bottomnav .item.active span { color: #fff; }

/* =====================================================================
   11/11/2026 — ECRAN « DEPOT REUSSI » selon le prompt du design system :
   pastille verte qui apparait en rebond, sous-titre en vert emeraude,
   carte recu blanche bordee (reference en pastille mono, bookmaker avec
   son logo, joueur sur deux lignes, montant en gros vert), deux gestes
   discrets sous la carte, bouton principal bleu nuit et deux sorties.
   ===================================================================== */
body.client-app .dr-coche,
body.client-app .modal-card .dr-coche {
  width: 84px; height: 84px; margin: 0 auto 18px; border-radius: 50%;
  background: var(--emerald-500); color: #fff;
  box-shadow: 0 14px 32px -6px rgba(16, 185, 129, .45), 0 2px 8px rgba(16, 185, 129, .25);
  animation: dr-pop .52s cubic-bezier(.2, .9, .3, 1.15) both;
}
body.client-app .modal-card .dr-coche svg { width: 44px; height: 44px; stroke-width: 2.6; }
@keyframes dr-pop {
  0%   { transform: scale(.55); opacity: 0; }
  60%  { transform: scale(1.06); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  body.client-app .modal-card .dr-coche { animation: none; }
}
/* le sous-titre reprend le vert de la coche */
body.client-app .modal-card .dr-sous { color: var(--emerald-700); font-weight: 700; }

/* ---- la carte recu ------------------------------------------------------ */
body.client-app .modal-card .dr-carte {
  margin-top: 18px; padding: 4px 18px; border-radius: 24px;
  background: var(--surface);
  border: 1px solid rgba(148, 163, 184, .35);
  box-shadow: 0 6px 18px rgba(15, 23, 42, .07);
  text-align: left;
}
body.client-app .modal-card .dr-ligne {
  display: flex; align-items: center; gap: 14px; padding: 13px 0;
  border-bottom: 1px solid rgba(148, 163, 184, .28);
}
body.client-app .modal-card .dr-ligne:last-child { border-bottom: 0; }
body.client-app .modal-card .dr-lab {
  flex: 0 0 92px; font-size: 13px; color: var(--slate-500); font-weight: 600;
}
body.client-app .modal-card .dr-val { flex: 1; min-width: 0; font-size: 14px; color: var(--slate-900); }
/* reference : pastille grise, chiffres a chasse fixe */
body.client-app .modal-card .dr-ref {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  background: var(--slate-100); color: var(--slate-700);
  font-family: var(--mono); font-size: 12.5px; font-weight: 700; letter-spacing: .02em;
}
/* bookmaker : son logo devant son nom */
body.client-app .modal-card .dr-bm { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; }
body.client-app .modal-card .dr-bm .bm-logo,
body.client-app .modal-card .dr-bm img { width: 20px; height: 20px; border-radius: 6px; object-fit: contain; }
/* joueur : nom en gras, ID en second plan */
body.client-app .modal-card .dr-nom { display: block; font-weight: 700; color: var(--slate-900); }
body.client-app .modal-card .dr-id {
  display: block; margin-top: 2px; font-family: var(--mono); font-size: 12px; color: var(--slate-500);
}
/* montant : le plus gros chiffre de la carte, en vert */
body.client-app .modal-card .dr-montant {
  font-size: 19px; font-weight: 800; color: var(--emerald-700); letter-spacing: -.01em;
}
/* les deux gestes en filigrane sous la carte */
body.client-app .modal-card .dr-liens {
  display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 10px;
}
body.client-app .modal-card .dr-lien {
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 6px;
  border: 0; background: none; color: var(--slate-500);
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
body.client-app .modal-card .dr-lien:active { color: var(--brand-600); }
body.client-app .modal-card .dr-point { color: var(--slate-300); }

/* ---- les actions ------------------------------------------------------- */
body.client-app .modal-card .dr-btn {
  margin-top: 14px; padding: 13px 16px; border-radius: 16px;
  background: var(--brand-600); color: #fff; font-size: 15.5px; font-weight: 700;
  box-shadow: 0 8px 20px -8px rgba(14, 56, 103, .55);
}
body.client-app .modal-card .dr-btn:active { background: var(--brand-700); }
body.client-app .modal-card .dr-sortie {
  background: var(--surface); border: 1px solid rgba(148, 163, 184, .45);
  color: var(--slate-700); font-weight: 700;
}

/* =====================================================================
   11/11/2026 — « maintenant fait l affichage en plein ecran » (le recu) :
   le recu occupe TOUTE la page — fond gris-bleu, coche en haut, carte au
   milieu, boutons au pied — au lieu d'une petite carte au centre.
   ===================================================================== */
body.client-app .modal-recu .modal-card {
  min-height: 100dvh; min-height: 100dvh;
  display: flex; flex-direction: column;
  background: var(--brand-50);
  padding: 0; border: 0; border-radius: 0; box-shadow: none;
}
body.client-app .modal-recu .dr {
  flex: 1 1 auto; display: flex; flex-direction: column;
  width: 100%; max-width: none;
  padding: calc(26px + env(safe-area-inset-top)) 16px calc(16px + env(safe-area-inset-bottom));
}
/* la carte et les liens restent groupes, les actions tombent au pied */
body.client-app .modal-recu .dr-carte { margin-top: 18px; }
body.client-app .modal-recu .dr-liens { margin-top: 10px; }
body.client-app .modal-recu .dr-btn { margin-top: auto; }
body.client-app .modal-recu .dr-sorties { margin-top: 10px; }
/* la nuit, le fond de page du recu suit le theme */
:root[data-theme="dark"] body.client-app .modal-recu .modal-card { background: var(--slate-50); }
/* un ecran large garde une colonne lisible au centre */
@media (min-width: 520px) {
  body.client-app .modal-recu .dr { max-width: 440px; margin: 0 auto; }
}

/* =====================================================================
   11/11/2026 — LES ACTIONS DU RECU, DYNAMISEES (prompt du design system)
   Bouton principal : degrade bleu nuit -> indigo, halo colore, libelle en
   capitales, pression tactile. Sorties : cartes blanches a pastille pastel.
   ===================================================================== */
body.client-app .modal-card .dr-btn {
  background: linear-gradient(90deg, var(--brand-900) 0%, var(--brand-800) 55%, var(--indigo-900) 100%);
  color: #fff; letter-spacing: .06em; text-transform: uppercase;
  font-size: 13.5px; font-weight: 700;
  box-shadow: 0 12px 26px -10px rgba(5, 22, 40, .65), 0 2px 6px rgba(5, 22, 40, .28);
  transition: transform .2s ease, box-shadow .2s ease, filter .2s ease;
}
body.client-app .modal-card .dr-btn:hover {
  filter: brightness(1.06);
  box-shadow: 0 14px 30px -10px rgba(30, 27, 75, .55), 0 3px 8px rgba(5, 22, 40, .3);
}
body.client-app .modal-card .dr-btn:active { transform: scale(.98); }
@media (prefers-reduced-motion: reduce) {
  body.client-app .modal-card .dr-btn { transition: none; }
  body.client-app .modal-card .dr-btn:active { transform: none; }
}
/* l'icone dans sa pastille translucide */
body.client-app .modal-card .dr-btn-ic {
  width: 26px; height: 26px; border-radius: 999px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .14);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
}
body.client-app .modal-card .dr-btn-ic svg { width: 16px; height: 16px; }

/* ---- les deux sorties ------------------------------------------------- */
body.client-app .modal-card .dr-sortie {
  gap: 9px; padding: 10px 10px; border-radius: 16px;
  background: var(--surface); border: 1px solid rgba(148, 163, 184, .5);
  color: var(--slate-700); font-size: 13px; font-weight: 700;
  transition: background .18s ease, transform .18s ease, border-color .18s ease;
}
body.client-app .modal-card .dr-sortie:hover { background: var(--slate-50); }
body.client-app .modal-card .dr-sortie:active { transform: scale(.98); }
body.client-app .modal-card .dr-sortie-ic {
  width: 28px; height: 28px; border-radius: 10px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
}
body.client-app .modal-card .dr-sortie-ic.home { background: var(--brand-50); color: var(--brand-600); }
body.client-app .modal-card .dr-sortie-ic.hist { background: var(--emerald-50); color: var(--emerald-700); }
body.client-app .modal-card .dr-sortie-ic svg { width: 16px; height: 16px; stroke-width: 2.1; }
/* la nuit, les pastilles pastel gardent leur teinte mais s'assombrissent */
:root[data-theme="dark"] body.client-app .modal-card .dr-sortie-ic.home { background: rgba(78, 123, 184, .18); }
:root[data-theme="dark"] body.client-app .modal-card .dr-sortie-ic.hist { background: rgba(15, 138, 75, .18); }

/* 11/11/2026 — le vide au milieu : le contenu (coche, titre, recu, gestes)
   restait colle en haut et les boutons au pied, laissant ~500 px vides entre
   les deux. La coche prend donc aussi une marge automatique en haut : l'espace
   libre se partage entre le dessus du bloc et le dessus des boutons, et le
   recu se lit au centre de l'ecran. */
body.client-app .modal-recu .dr-coche { margin-top: auto; }
body.client-app .modal-recu .dr-liens { margin-bottom: auto; }

/* 11/11/2026 — « change la couleur en bleu d'origine du bouton Nouvelle
   operation » : le degrade bleu nuit -> indigo est retire, le bouton reprend
   l'aplat de la marque (#0B2E55), comme toutes les actions principales de
   l'application. Le reste du dessin (capitales, pastille d'icone, pression,
   taille) ne bouge pas. */
body.client-app .modal-card .dr-btn {
  background: var(--brand-600);
  box-shadow: 0 8px 20px -8px rgba(14, 56, 103, .55), 0 2px 6px rgba(14, 56, 103, .25);
}
body.client-app .modal-card .dr-btn:hover {
  background: var(--brand-700); filter: none;
  box-shadow: 0 10px 24px -8px rgba(14, 56, 103, .6), 0 2px 6px rgba(14, 56, 103, .28);
}

/* =====================================================================
   BOUTONS « Déposer / Retirer » DE L'ACCUEIL — LA FORME DE LA CAPTURE
   (11/11/2026 : « change le bouton de depot et de retrait exactement comme
   ca, sans recopier cette couleur »)

   Ce que la capture montre, et que ce bloc reprend tel quel : DEUX PILULES
   cote a cote, de meme largeur, une PLEINE et une en CONTOUR, chacune une
   icone (fleche vers le bas au depot, vers le haut au retrait) et son
   libelle sur UNE seule ligne. Plus de sous-titre, plus d'aplat carre.

   CE QUI N'EST PAS RECOPIE : le rouge de la capture. Les couleurs sont
   celles de la maison — la pilule pleine prend le bleu de la marque
   (--brand-600) avec l'encre blanche, la pilule en contour la surface avec
   le cerne et l'encre de la marque. En mode nuit les jetons basculent tout
   seuls : #2F5C93 + blanc (4,93:1) sur la pleine, #55C4A1 sur #18181B
   (6,82:1) sur la contour.
   MESURES (capture 1266 px de large = 422 CSS x 3) : pilules 169 x 37,
   rayon 999, ecart 13 px, libelle ~13 px gras, icone ~15 px. La hauteur est
   portee a 46 px (cible tactile) sans changer la forme.
   ===================================================================== */
body.client-app .cx-acts {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px;
}
body.client-app .cx-act {
  display: inline-flex; flex-direction: row; align-items: center; justify-content: center;
  gap: 9px; min-height: 46px; padding: 0 14px; border-radius: 999px;
  border: 1.5px solid transparent; box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  font-size: 15px; font-weight: 800; letter-spacing: -.01em; line-height: 1.1;
  white-space: nowrap; overflow: hidden;
}
body.client-app .cx-act:hover { box-shadow: none; filter: brightness(1.04); }
body.client-app .cx-act .cx-act-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; margin: 0; border-radius: 0; background: none;
  flex: 0 0 auto;
}
body.client-app .cx-act .cx-act-ico svg { width: 18px; height: 18px; stroke-width: 2.4; }
body.client-app .cx-act .cx-act-t { padding: 0; font: inherit; }
/* Le sous-titre n'existe a l'ecran QUE sur un service ferme (voir plus bas). */
body.client-app .cx-act .cx-act-s { display: none; }
body.client-app .cx-act-dep {
  background: var(--brand-600); border-color: var(--brand-600); color: var(--on-brand);
}
body.client-app .cx-act-wd {
  background: var(--surface); border-color: var(--brand-600); color: var(--brand-700);
}
:root[data-theme="dark"] body.client-app .cx-act-dep {
  background: var(--brand-600); border-color: var(--brand-600); color: var(--on-brand);
}
:root[data-theme="dark"] body.client-app .cx-act-wd {
  background: var(--surface); border-color: var(--brand-400); color: var(--brand-400);
}
/* FERME PAR LE PANNEAU : la meme pilule, grisee, avec « Indisponible » a la
   suite du libelle. Les trois selecteurs sont ceux que ui_check exige. */
body.client-app .cx-act.indispo {
  background: var(--slate-100); border-color: var(--slate-200); color: var(--slate-600);
  gap: 6px; cursor: default;
}
body.client-app .cx-act.indispo .cx-act-ico { color: var(--slate-400); background: none; }
body.client-app .cx-act.indispo .cx-act-t { color: var(--slate-600); }
body.client-app .cx-act.indispo .cx-act-s {
  display: inline; font-size: 12px; font-weight: 600; opacity: 1; color: var(--slate-500);
}
/* LE MODE NUIT DOIT ETRE REPETE ICI, et avec un cran de specificite de PLUS que
   les regles de nuit des deux pilules ci-dessus (0,5,1 contre 0,4,1) : sans ca,
   `:root[data-theme="dark"] ... .cx-act-dep` repeint un service FERME en bleu
   plein — il a l'air ouvert — et la pastille d'icone reprend son carre pale.
   Les jetons de gris, eux, basculent tout seuls (texte #B4B4BC sur #141416). */
:root[data-theme="dark"] body.client-app .cx-act .cx-act-ico { background: none; }
:root[data-theme="dark"] body.client-app .cx-act.indispo {
  background: var(--slate-100); border-color: var(--slate-200);
}

/* ---------- LA SALUTATION DE L'ACCUEIL (12/11/2026) ----------
   « Bonjour, » en petit au-dessus du NOM en gras, et le bouton de copie a
   droite — la zone utilisateur du prompt, au-dessus de la carte du portefeuille. */
body.client-app .cx-bj {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: 18px 2px 12px;
}
body.client-app .cx-bj-txt { min-width: 0; }
body.client-app .cx-bj-hi {
  display: block; font-size: 14px; font-weight: 500; color: var(--slate-500); line-height: 1.2;
}
body.client-app .cx-bj-nom {
  display: block; margin-top: 2px; font-size: 22px; font-weight: 800;
  letter-spacing: -.02em; color: var(--slate-900); line-height: 1.15;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.client-app .cx-bj-nom.nom-long { font-size: 16px; }
body.client-app .cx-bj-copy {
  width: 42px; height: 42px; border-radius: 999px; flex: 0 0 auto;
  display: grid; place-items: center; cursor: pointer;
  background: var(--surface); color: var(--slate-500);
  border: 1px solid var(--cx-cerne); box-shadow: var(--cx-flat);
}
body.client-app .cx-bj-copy:active { background: var(--slate-100); }

/* =====================================================================
   LE CADRE DES DEUX BOUTONS (11/11/2026 — « juste le bouton depot et retrait
   dans le cadre », capture de la reference EMB Money a l'appui)

   Sur la capture, les deux pilules sont DANS la carte coloree du portefeuille,
   pas posees sur la page. Ce cadre reprend donc le dessin de la carte de la
   maison (`.cx-hero` : degrade 150deg bleu nuit + orbe de lumiere), et les deux
   boutons dedans — RIEN d'autre : ni solde, ni points, ni nom de marque.

   Couleurs : la carte garde le bleu de la maison (pas le rouge de la capture) ;
   la pilule « Déposer » devient BLANCHE a encre bleu nuit, la pilule « Retirer »
   devient TRANSPARENTE a cerne blanc et texte blanc — exactement l'arrangement
   de l'image, transposer sur notre palette.
   ===================================================================== */
/* Le dessin vient des JETONS de la maison (aucune couleur ecrite en dur : le
   controle « aucune couleur neuve dans le socle » le refuse, et c'est ce qui
   fait que la carte suit le mode nuit toute seule). */
body.client-app .cx-cadre {
  position: relative; overflow: hidden; border-radius: 26px;
  margin-top: 14px; padding: 18px 16px 16px;
  color: var(--on-brand);
  /* BLEU FONCE DE LA MAISON (10/11/2026, prompt : « change la couleur bleu du
     panneau de depot et retrait en bleu fonce qui est dans le systeme ») : la
     carte quitte le bleu roi #0E3867 pour le bleu nuit de la marque (#0B2E55).
     Le degrade donne le relief, la teinte de base est celle de tout le site. */
  background: linear-gradient(155deg, var(--brand-700), var(--brand-600) 58%, var(--brand-500) 100%);
  box-shadow: 0 22px 50px -26px rgba(15, 44, 89, .85);
}
/* Le dessus de la carte : « Solde portefeuille » a gauche, la MARQUE a droite
   (capture EMB Money, « EMB MONEY »). */
body.client-app .cx-cadre-haut {
  position: relative; z-index: 1;
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
body.client-app .cx-cadre-lab { font-size: 14px; font-weight: 600; opacity: .92; }
body.client-app .cx-cadre-marque {
  font-size: 14px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
}
/* Le solde : le nombre en TRES GROS, la devise a cote en plus petit, et la
   capsule des points a droite — l'alignement de l'image. */
body.client-app .cx-cadre-bas {
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 12px;
}
body.client-app .cx-cadre-solde { display: inline-flex; align-items: baseline; gap: 9px; min-width: 0; }
body.client-app .cx-cadre-solde b {
  font-size: 40px; font-weight: 800; letter-spacing: -.03em; line-height: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.client-app .cx-cadre-dev { font-size: 16px; font-weight: 700; opacity: .95; }
body.client-app .cx-cadre-pts {
  flex: 0 0 auto; padding: 6px 12px; border-radius: 12px;
  font-size: 13px; font-weight: 700;
  background: rgba(255, 255, 255, .16); border: 1px solid rgba(255, 255, 255, .14);
}
/* l'orbe de lumiere, celui de la carte du haut (meme dessin, meme place) */
/* VAGUES / FILIGRANES (prompt : « vagues / filigranes geometriques discrets ») :
   deux ANNEAUX translucides qui debordent du bord droit, comme les arcs de la
   capture. Du blanc a 10 % et 7 % : assez pour se voir, trop peu pour distraire. */
body.client-app .cx-cadre::before,
body.client-app .cx-cadre::after {
  content: ''; position: absolute; pointer-events: none; border-radius: 50%;
  background: none;
  border: 26px solid rgba(255, 255, 255, .10);
}
body.client-app .cx-cadre::before { width: 210px; height: 210px; top: -74px; right: -58px; }
body.client-app .cx-cadre::after {
  width: 300px; height: 300px; top: 26px; right: -128px;
  border-color: rgba(255, 255, 255, .07);
}
:root[data-theme="dark"] body.client-app .cx-cadre {
  box-shadow: 0 22px 50px -30px rgba(0, 0, 0, .75), 0 0 0 1px var(--slate-200);
}

/* les deux pilules, telles que la capture les montre */
body.client-app .cx-cadre .cx-acts { position: relative; z-index: 1; margin-top: 20px; gap: 11px; }
body.client-app .cx-cadre .cx-act-dep {
  background: var(--on-brand); border-color: var(--on-brand); color: var(--brand-700);
}
body.client-app .cx-cadre .cx-act-wd {
  background: transparent; border-color: rgba(255, 255, 255, .55); color: var(--on-brand);
}
:root[data-theme="dark"] body.client-app .cx-cadre .cx-act-dep {
  background: var(--on-brand); border-color: var(--on-brand); color: var(--brand-900);
}
:root[data-theme="dark"] body.client-app .cx-cadre .cx-act-wd {
  background: transparent; border-color: rgba(255, 255, 255, .55); color: var(--on-brand);
}
/* service FERME : la pilule reste grise DANS le cadre (un aplat blanc ferait
   croire que le service est ouvert) — un cran de specificite au-dessus. */
body.client-app .cx-cadre .cx-act.indispo {
  background: var(--slate-100); border-color: var(--slate-200);
  gap: 5px; padding: 0 10px;
}
body.client-app .cx-cadre .cx-act.indispo .cx-act-t { color: var(--slate-600); font-size: 12.5px; }
body.client-app .cx-cadre .cx-act.indispo .cx-act-s { font-size: 10px; }
:root[data-theme="dark"] body.client-app .cx-cadre .cx-act.indispo {
  background: var(--slate-100); border-color: var(--slate-200);
}
:root[data-theme="dark"] body.client-app .cx-cadre .cx-act.indispo .cx-act-t { color: var(--slate-600); }

/* =====================================================================
   12/11/2026 — LE DOCK DE L'INTERFACE CLIENT (prompt du proprietaire,
   capture « je parle de ca » : la barre du bas, agrandie)
   12/11/2026 (soir) — la CAPSULE FLOTTANTE est retiree sur sa demande expresse
   (« fais-la sur l'ecran sans le flottant ») : la barre est desormais une bande
   pleine largeur collee au bord bas. Les mesures ci-dessous (entrees, pilule
   active) restent ; seules la pose et l'ombre ont change, voir le bloc final.
   Mesures du prompt, relues sur sa capture :
     - la capsule se detache des bords de 16 px (bottom-4 / left-4 / right-4)
       et prend 8 px de haut, 12 px de cote (py-2 / px-3) — plus d'ombre
       portee (shadow-2xl) et un cerne fin ;
     - l'onglet actif : 10 px / 20 px (py-2.5 / px-5), libelle de 12 px gras
       (text-xs font-bold), icone de 18 px, ecart de 8 px (gap-2) ;
     - les autres entrees : icone gris clair (slate-300) de 22 px, libelle
       de 10 px (text-[10px]) en slate-400 ;
     - « Chat » : la puce bleue (6 px) posee en haut a droite de l'icone
       remplace le compteur chiffre — le libelle du compteur reste dans le
       document (aria), il n'est simplement plus peint.
   C'est un bloc AJOUTE A LA FIN : a specificite egale, c'est lui qui gagne
   sur les regles datées plus haut (5581, 5930). Le bleu marine du prompt
   (#0A4232) est deja `--navy` ; la nuit la pilule reste le bleu ROI, choisi
   pour le contraste sur une barre sombre.
   ===================================================================== */
/* 12/11/2026 — « PAS DE BARRE DE NAVIGATION FLOTTANTE, FAIS-LA SUR L'ECRAN SANS
   LE FLOTTANT » (demande du proprietaire, apres la capture du dock). Le squelette
   des mesures du prompt reste, mais la barre n'est plus une capsule posee a 16/18 px
   des bords : c'est une BANDE PLEINE LARGEUR, collee au bord bas, rayon 0, un trait
   fin en haut, aucune ombre portee. La zone de gestes du telephone est reservee par
   `env(safe-area-inset-bottom)` (sans elle, la derniere rangee passerait sous la
   pilule du systeme). */
body.client-app .bottomnav {
  padding: 8px 12px calc(8px + env(safe-area-inset-bottom));
  border: 0; border-top: 1px solid var(--cx-cerne);
  box-shadow: none;
}
@media (max-width: 720px) {
  body.client-app .bottomnav {
    left: 0; right: 0;
    margin: 0;
  }
}
body.client-app .bottomnav .item {
  padding: 8px 10px; gap: 4px; color: var(--slate-400);
}
body.client-app .bottomnav .item svg { width: 22px; height: 22px; color: var(--slate-400); }
body.client-app .bottomnav .item span {
  font-size: 11px; font-weight: 600; color: var(--slate-500);
}
/* l'onglet actif : la pilule du prompt */
body.client-app .bottomnav .item.active {
  flex: 0 0 auto;
  flex-direction: row; gap: 8px;
  padding: 11px 20px;
  /* 13/11/2026 : la pilule active prend LE MEME BLEU que le panneau « Passerelle »
     et le carre de la marque (degrade navy de Flash Pay). */
  background: var(--pass-fond); color: #fff;
  box-shadow: 0 10px 20px -14px rgba(15, 44, 89, .8);
}
body.client-app .bottomnav .item.active svg { width: 18px; height: 18px; color: #fff; }
body.client-app .bottomnav .item.active span {
  font-size: 12px; font-weight: 700; color: #fff;
}
/* LA PUCE DU CHAT (prompt) : un POINT de 9 px pose sur le coin haut droit de
   l'icone, pas un compteur. `font-size: 0` rend le chiffre invisible sans le
   retirer du document (les lecteurs d'ecran l'annoncent toujours). */
body.client-app .bottomnav .item .cx-nb,
body.client-app .bottomnav .item.active .cx-nb {
  min-width: 0; width: 9px; height: 9px; padding: 0;
  font-size: 0; line-height: 0;
  top: 2px; left: 50%; margin: 0 0 0 6px; transform: none;
  background: var(--roi); border-radius: 50%;
  box-shadow: none;
}
body.client-app .bottomnav .item .cx-nb[hidden] { display: none; }
/* la nuit : la barre reste sombre (nos couleurs), seules les teintes de texte
   et la pilule suivent — bleu ROI deja pose plus haut, on ne le repete pas. */
:root[data-theme="dark"] body.client-app .bottomnav {
  /* 12/11/2026 : bande collee au bord bas — plus d'ombre portee, jour ET nuit. */
  box-shadow: none;
}
:root[data-theme="dark"] body.client-app .bottomnav .item svg { color: var(--glass-ink-clair); }
:root[data-theme="dark"] body.client-app .bottomnav .item.active span { color: #fff; }
:root[data-theme="dark"] body.client-app .bottomnav .item span { color: var(--glass-ink-clair); }
:root[data-theme="dark"] body.client-app .bottomnav .item.active span { color: #fff; }

/* =====================================================================
   IPAD iOS — CORRECTIFS D'AFFICHAGE DE L'INTERFACE CLIENT (11/11/2026)
   1. Barre du haut : margin-top retire, zone sure en padding-top.
   2. Barre du bas : repose le centrage (left:10px ecrasait left:50%).
   3. Coquille : min-height 100dvh + flex pour centrer le contenu court.
   4. Connexion/Inscription : mise en page 2 colonnes avancee de 1024px
      a 721px. La colonne de marque (aside, bleu nuit) remplit la gauche ;
      le formulaire reste a droite. Plus aucun fond noir vide visible.
   5. Bouton Google : centre dans la colonne du formulaire.
   ===================================================================== */
@media (min-width: 721px) {
  /* 1. barre du haut */
  body.client-app .topbar {
    margin-top: 0;
    padding-top: calc(12px + env(safe-area-inset-top));
  }
  /* 2. barre du bas — 12/11/2026 : PLUS DE BARRE BORNEE. Elle etait recentree en
     carte de 688 px sur grand ecran ; depuis « pas de barre de navigation
     flottante », c'est une bande pleine largeur sur TOUTES les tailles. Le
     centrage est donc explicitement annule ici (derniere regle de position de la
     feuille : c'est elle qui gagne sur grand ecran). */
  body.client-app .bottomnav {
    left: 0; right: 0;
    margin: 0;
    width: auto; max-width: none;
  }
  /* 3. coquille */
  body.client-app {
    min-height: 100vh; min-height: 100dvh;
    display: flex; flex-direction: column;
  }
  body.client-app .app-shell {
    flex: 1; display: flex; flex-direction: column;
  }
  body.client-app .app-shell #view {
    margin-top: auto; margin-bottom: auto;
  }
  /* 4. connexion / inscription : 2 colonnes */
  body.client-app.auth-page .auth-shell {
    flex-direction: row;
    min-height: 100svh; min-height: 100dvh;
  }
  body.client-app.auth-page .auth-aside {
    display: flex; flex-direction: column; justify-content: space-between;
    position: relative; isolation: isolate; overflow: hidden;
    flex: 0 0 44%; width: 44%;
    margin: 12px; padding: 36px 32px;
    border-radius: 24px;
    background: var(--brand-900); color: var(--ah-onbrand);
    box-shadow: 0 20px 45px -20px rgba(8, 24, 47, .55);
  }
  body.client-app.auth-page .auth-aside::before {
    content: ''; position: absolute; z-index: -1; left: 0; top: 0;
    width: min(62%, 420px); aspect-ratio: 1; border-radius: 50%;
    filter: blur(60px); transform: translate(-30%, -55%);
    background: var(--amber-500); opacity: .36;
  }
  body.client-app.auth-page .auth-aside::after {
    content: ''; position: absolute; z-index: -1; right: 0; bottom: 0;
    width: min(78%, 520px); aspect-ratio: 1; border-radius: 50%;
    filter: blur(60px); transform: translate(34%, 52%);
    background: var(--ah-brand-500); opacity: .6;
  }
  body.client-app.auth-page .auth-main {
    flex: 1 1 auto;
    padding: calc(env(safe-area-inset-top) + 32px) 24px 32px;
    justify-content: center; align-items: center;
  }
  /* 5. bouton Google */
  body.client-app.auth-page .gsi-wrap {
    display: flex; justify-content: center;
  }
}

/* =====================================================================
   13/11/2026 — L'ESPACE CLIENT S'ADAPTE A TOUS LES TELEPHONES
   Constat sur la capture du proprietaire (viewport du client : 363 px) :
     1. dans la carte du portefeuille, « Creer un compte » depassait sa
        pilule des DEUX cotes — le C et le « e » final rognes, alors que
        « Se connecter » tenait large ;
     2. dans la barre du bas, « Profil » sortait de la capsule par la droite.
   CAUSE, la meme dans les deux cas : les deux lignes ne peuvent pas
   descendre sous la largeur de leur libelle.
     - `.cx-acts` est une grille `1fr 1fr` : chaque colonne vaut au MINIMUM
       le min-content de son item ; or `.cx-act` porte `overflow: hidden`,
       ce qui rend son minimum automatique NUL. La colonne se reduit donc a
       sa part egale (1/2) et le libelle, en `nowrap` et centre, deborde de
       sa boite puis est rogne des deux cotes.
     - `.bottomnav .item` est en `flex: 1 1 0` avec `min-width: auto` : une
       entree ne descend pas sous la largeur de son mot (« Historique »,
       « Profil »), la ligne deborde et la derniere entree part hors de la
       capsule (qui, elle, a un rayon qui la rogne).
   CORRECTIF : les deux lignes deviennent SHRINKABLES (`minmax(0, 1fr)` et
   `min-width: 0`), leurs mesures suivent la LARGEUR DE L'ECRAN (`clamp` sur
   `vw` : rembourrages, libelles, pastilles), et un libelle qui ne tient
   toujours pas passe a la ligne au lieu d'etre coupe (les pilules grandissent
   en hauteur, `min-height` les empeche de s'affaisser).
   RIEN NE CHANGE SUR UN ECRAN LARGE : chaque `clamp` sature a son maximum,
   soit exactement les valeurs d'avant (15 px de libelle, 14 px de
   rembourrage, 11 px / 13 px dans la barre, 20 px de pilule active).
   Mesures de tete a 363 px : colonne 144 px pour un libelle de 104 px,
   barre du bas 287 px de contenu pour 343 px utiles.
   ===================================================================== */
/* 1. LES DEUX PILULES DE LA CARTE */
body.client-app .cx-acts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
body.client-app .cx-act {
  min-width: 0;
  padding: 6px clamp(8px, 2.4vw, 14px);
}
body.client-app .cx-act .cx-act-t {
  min-width: 0; text-align: center;
  font-size: clamp(12px, 3.55vw, 15px);
  line-height: 1.15; letter-spacing: -.01em;
  /* le libelle ne peut plus etre ROGNE : il passe a la ligne. `nowrap` reste
     ecrit plus haut pour la forme d'origine, cette regle-ci le leve. */
  white-space: normal; overflow-wrap: break-word; hyphens: none;
}
/* la meme protection sur la carte large (deux cartes Depot / Retrait) */
body.client-app .cx-acts > * { min-width: 0; }

/* 2. LA BARRE DU BAS */
body.client-app .bottomnav .item {
  min-width: 0;                       /* la cle : l'entree accepte de retrecir */
  padding: 8px clamp(2px, 1.4vw, 10px);
}
body.client-app .bottomnav .item span { font-size: clamp(9.5px, 2.9vw, 11px); }
body.client-app .bottomnav .item svg { flex: 0 0 auto; }
body.client-app .bottomnav .item.active { padding: 11px clamp(10px, 4.4vw, 20px); }
body.client-app .bottomnav .item.active span { font-size: clamp(10px, 3vw, 13px); }

/* 3. ECRANS ETROITS (< 340 px : anciens telephones, mode paysage serre) :
      la carte respire moins, sinon le solde en 40 px mangerait le libelle. */
@media (max-width: 340px) {
  body.client-app .cx-cadre { padding: 16px 12px 14px; border-radius: 22px; }
  body.client-app .cx-cadre-solde b { font-size: 34px; }
  body.client-app .cx-cadre-lab,
  body.client-app .cx-cadre-marque { font-size: 12.5px; }
}

/* 4. FILET DE SECURITE GENERAL : aucun media, tableau ni bloc de texte de
      l'espace client ne peut deborder de la page. */
body.client-app #view img,
body.client-app #view video,
body.client-app #view canvas { max-width: 100%; height: auto; }
body.client-app #view table { max-width: 100%; }
body.client-app #view :is(.cx-msg-t, .cx-msg-s, .li-t, .li-s, .pf-nom) { min-width: 0; }

/* =====================================================================
   13/11/2026 — LA BARRE DU HAUT N'A PLUS DE MARQUE
   « enleve flash pay avec son logo » : `.cx-brand` (la vignette et le nom)
   n'est plus ecrit par app.js. `.cx-top` est une GRILLE a deux colonnes
   (`minmax(0, 1fr) auto`) ; la premiere reste vide, la seconde garde les
   commandes. Sans cette regle, `.cx-actions` — desormais seul enfant —
   tomberait dans la colonne 1 et le rond du theme sauterait a GAUCHE.
   La hauteur de la barre ne bouge pas : elle venait du rond de 46 px, pas
   du logo de 40 px (d'ou le `min-height` qui la fige).
   Les fabriques `.cx-brand` / `.cx-logo` / `.cx-name` restent ecrites dans
   la feuille : les remettre est un appel dans app.js.
   ===================================================================== */
body.client-app .cx-top { min-height: 46px; }
body.client-app .cx-top > .cx-actions { grid-column: 2; justify-self: end; }


/* =====================================================================
   RETRAIT : montant verifie (mode automatique, regle par l'ADMIN)
   Le mode n'est pas un choix du client : le panneau pose `retrait_mode`.
   ===================================================================== */
body.client-app .wd-consigne {
  background: var(--brand-50);
  border-color: rgba(31, 111, 191, .12);
}

/* le montant annonce par le bookmaker, apres verification en lecture seule */
body.client-app .wd-verif {
  margin: 2px 0 12px; padding: 14px 16px; text-align: center;
  background: var(--brand-50); border: 1px solid rgba(31, 111, 191, .12);
  border-radius: 20px;
}
body.client-app .wd-verif-k {
  font-size: 12px; font-weight: 700; color: var(--slate-600);
  text-transform: uppercase; letter-spacing: .04em;
}
body.client-app .wd-verif-m {
  margin-top: 4px; font-size: 28px; font-weight: 800; color: var(--brand-600);
  line-height: 1.1;
}

/* champs verrouilles apres verification : on les relit, on ne les change plus.
   ATTENTION AU THEME : pas de couleur en dur ici. `#F8FAFC` rendait les trois
   champs BLANCS en mode sombre des qu'on appuyait sur « Verifier le code »
   (constate le 13/11/2026). `--surface-2` est le jeton des champs : clair le
   jour, #27272A la nuit. */
body.client-app .wd-auto .input[readonly] {
  background: var(--surface-2); color: var(--slate-600);
}

/* ====================================================================
   BARRE D'EN-TETE DE L'APPLICATION (13/11/2026, maquette du client)

   Plate, posee sur le canvas (pas de carte) : carre noir « HR. », nom et
   pastille « Actif », ligne « Prenom Nom · Ville, Pays », puis deux ronds
   blancs a droite (cloche + compte). Le plein ecran et la bascule de theme
   sont retires : la maquette n'en porte pas, le mode sombre reste dans le
   Profil. Aucune couleur en dur : jetons seulement.
   ==================================================================== */
body.client-app .cx-appbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 2px 2px 0; margin: 0 0 14px; background: none;
  border: 0; box-shadow: none;
}
body.client-app .cx-appbar-marque { display: flex; align-items: center; gap: 12px; min-width: 0; }
body.client-app .cx-appbar-logo {
  flex: none; width: 58px; height: 58px; border-radius: 19px;
  display: grid; place-items: center;
  background: var(--logo-fond); color: var(--pass-encre);
  font-size: 21px; font-weight: 800; letter-spacing: -.5px; line-height: 1;
}
body.client-app .cx-appbar-logo span { color: var(--logo-point); }
body.client-app .cx-appbar-txt { display: flex; flex-direction: column; min-width: 0; }
body.client-app .cx-appbar-ligne { display: flex; align-items: center; gap: 8px; min-width: 0; }
body.client-app .cx-appbar-txt b {
  font-size: 19px; font-weight: 800; letter-spacing: -.2px; color: var(--slate-900);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.client-app .cx-appbar-pill {
  display: inline-flex; align-items: center; gap: 5px; flex: none;
  padding: 4px 10px; border-radius: 999px;
  background: rgba(104, 182, 71, .14); color: var(--cta);
  font-size: 12px; font-weight: 700; white-space: nowrap;
}
body.client-app .cx-appbar-pill i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
body.client-app .cx-appbar-pill:not(.on) { background: rgba(229, 169, 60, .16); color: rgba(229, 169, 60, 1); }
body.client-app .cx-appbar-etat {
  margin-top: 3px; font-size: 13px; font-weight: 500; color: var(--slate-500);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
body.client-app .cx-appbar-actions { display: flex; align-items: center; gap: 10px; flex: none; }
body.client-app .cx-appbar-btn {
  position: relative; width: 52px; height: 52px; flex: none;
  display: grid; place-items: center; text-decoration: none;
  background: var(--surface); border: 1px solid var(--slate-200); border-radius: 17px;
  color: var(--slate-900); box-shadow: var(--shadow);
}
body.client-app .cx-appbar-btn:active { transform: translateY(1px); }
body.client-app .cx-appbar-dot {
  position: absolute; top: 11px; right: 12px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--brand-500); border: 2px solid var(--surface);
}

@media (max-width: 520px) {
  /* Le nom ne doit pas se couper (« HONO RECHA… » sur la capture du 13/11/2026) :
     a 424 px de large, la pastille « Déconnecté » et les deux ronds mangent la
     place — on resserre les trois avant de toucher au nom. */
  body.client-app .cx-appbar { gap: 6px; }
  body.client-app .cx-appbar-marque { gap: 8px; }
  body.client-app .cx-appbar-logo { width: 46px; height: 46px; border-radius: 15px; font-size: 17px; }
  body.client-app .cx-appbar-txt b { font-size: 14px; letter-spacing: -.1px; }
  body.client-app .cx-appbar-etat { font-size: 11px; }
  body.client-app .cx-appbar-pill { padding: 3px 7px; font-size: 9.5px; gap: 4px; }
  body.client-app .cx-appbar-actions { gap: 6px; }
  body.client-app .cx-appbar-btn { width: 40px; height: 40px; border-radius: 13px; }
}
/* ====================================================================
   PANNEAU DEPOT / RETRAIT (13/11/2026, maquette du client)

   Une carte sombre « Passerelle 1xBet Cash » portant deux tuiles : le
   DEPOT en bleu de marque (tuile pleine), le RETRAIT en blanc (icone verte
   sur fond vert pale). Elle remplace les deux pilules chez le client ; le
   visiteur garde les pilules dans sa carte.

   Aucune couleur en dur : uniquement les jetons (le socle n'accepte que
   des var()).
   ==================================================================== */
body.client-app .cx-pass {
  /* 13/11/2026 : la carte du solde a disparu — le panneau ouvre l'accueil, il
     prend donc un peu d'air sous la salutation et respire davantage en bas. */
  padding: 15px; margin: 40px 0 13px;   /* 13/11/2026 : panneau encore plus bas (3e demande) */
  background: var(--pass-fond);
  box-shadow: 0 18px 40px -26px rgba(15, 44, 89, .85);
  border-radius: 20px;
}
body.client-app .cx-pass-haut {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 10px; margin-bottom: 10px;
}
body.client-app .cx-pass-eyebrow {
  display: block; font-size: 9.5px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--slate-400);
}
body.client-app .cx-pass-titre {
  margin: 3px 0 0; font-size: 18.5px; font-weight: 800; letter-spacing: -.25px;
  color: var(--pass-encre); line-height: 1.15;
}
body.client-app .cx-pass-badge {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  padding: 6px 10px; border-radius: 999px;
  background: rgba(255, 255, 255, .08);
  color: var(--brand-400); font-size: 11.5px; font-weight: 700; white-space: nowrap;
}
body.client-app .cx-pass-tuiles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
body.client-app .cx-pass-tuile {
  display: flex; flex-direction: column; gap: 5px;
  min-height: 112px; padding: 12px; border-radius: 16px;
  text-decoration: none; border: 0;
}
body.client-app .cx-pass-tuile.dep { background: var(--bleu-depot); color: var(--pass-encre); }
body.client-app .cx-pass-tuile.wd { background: var(--pass-tuile); color: var(--pass-tuile-encre); }
body.client-app .cx-pass-ico {
  width: 32px; height: 32px; border-radius: 10px;
  display: grid; place-items: center; margin-bottom: auto;
}
body.client-app .cx-pass-tuile.dep .cx-pass-ico { background: rgba(255, 255, 255, .18); color: var(--pass-encre); }
body.client-app .cx-pass-tuile.wd .cx-pass-ico { background: rgba(104, 182, 71, .16); color: var(--cta); }
body.client-app .cx-pass-tuile b { font-size: 16px; font-weight: 800; letter-spacing: -.2px; }
body.client-app .cx-pass-sous { font-size: 11px; font-weight: 500; }
body.client-app .cx-pass-tuile.dep .cx-pass-sous { color: var(--pass-sous); }
body.client-app .cx-pass-tuile.wd .cx-pass-sous { color: var(--pass-tuile-sous); }
body.client-app .cx-pass-tuile.ferme { opacity: .55; }

@media (max-width: 380px) {
  body.client-app .cx-pass { padding: 14px; border-radius: 18px; }
  body.client-app .cx-pass-titre { font-size: 17.5px; }
  body.client-app .cx-pass-tuile { min-height: 106px; padding: 12px; border-radius: 14px; }
  body.client-app .cx-pass-tuile b { font-size: 15.5px; }
  body.client-app .cx-pass-sous { font-size: 11px; }
}

/* ====================================================================
   ECRAN « RECHARGER 1XBET » — habillage Bento fintech (13/11/2026)

   Maquette du client : fond gris perle, cartes blanches a tres grands
   arrondis, encre anthracite, cobalt pour l'action et les liens, champs
   gris clair a l'interieur des cartes. Aucune couleur en dur : les
   teintes sont dans les jetons --dp-* poses plus haut.
   ==================================================================== */
/* LES TROIS PAGES DU PARCOURS (depot, retrait, suivi) suivent le THEME par leurs
   propres jetons --dp-* : clair le jour (gris perle, cartes blanches), sombre la
   nuit (anthracite, cartes encre). Les teintes sont definies une fois pour chaque
   theme dans le :root, ces regles ne font que les consommer. */
body.client-app .dp-page { background: var(--dp-fond); color: var(--dp-encre); }
body.client-app .dp-page .dp-titre,
body.client-app .dp-page .label,
body.client-app .dp-page .dp-tuile-nom { color: var(--dp-encre); }
body.client-app .dp-page .dp-aide-ligne,
body.client-app .dp-page .dp-aide-ligne *,
body.client-app .dp-page .small.muted { color: var(--dp-gris); }

/* --- barre du haut --- */
body.client-app .dp-page .dp-tete {
  display: grid; grid-template-columns: 40px 1fr auto; align-items: center;
  gap: 10px; background: none; padding: 6px 0 14px; box-shadow: none;
}
body.client-app .dp-page .dp-back {
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--dp-carte); border: 1px solid var(--dp-bord);
  color: var(--dp-encre); box-shadow: 0 1px 2px rgba(24, 24, 27, .05);
}
body.client-app .dp-page .dp-titre {
  text-align: center; font-size: 18px; font-weight: 800; color: var(--dp-encre);
}
body.client-app .dp-page .dp-secure {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 6px 10px; border-radius: 999px;
  background: var(--dp-carte); border: 1px solid var(--dp-bord);
}
body.client-app .dp-page .dp-secure svg { color: var(--cta); }
body.client-app .dp-page .dp-secure-t {
  font-size: 11px; font-weight: 700; color: var(--dp-encre); white-space: nowrap;
}

/* --- les quatre cartes --- */
body.client-app .dp-page .dp-section {
  background: var(--dp-carte); border: 1px solid var(--dp-bord);
  border-radius: 24px; padding: 16px; margin: 0 0 14px;
  box-shadow: 0 1px 2px rgba(24, 24, 27, .04);
}
body.client-app .dp-page .dp-card-tete {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 10px;
}
body.client-app .dp-page .label {
  font-size: 15px; font-weight: 800; color: var(--dp-encre); margin: 0 0 8px;
}
body.client-app .dp-page .dp-card-tete .label { margin: 0; }
body.client-app .dp-page .dp-lien {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--dp-cobalt); font-size: 11px; font-weight: 800;
}

/* --- champs --- */
body.client-app .dp-page .input,
body.client-app .dp-page .select,
body.client-app .dp-page .dp-telrow,
body.client-app .dp-page .dp-montant {
  background: var(--dp-champ); border: 1px solid transparent; border-radius: 16px;
  color: var(--dp-encre); box-shadow: none;
}
body.client-app .dp-page #dep-player {
  height: 48px; font-family: var(--mono); font-weight: 700; font-size: 14px;
  letter-spacing: .3px;
}
body.client-app .dp-page .dp-montant { height: 56px; padding: 0 16px; display: flex; align-items: center; gap: 10px; }
body.client-app .dp-page .dp-montant-in {
  flex: 1; min-width: 0; background: none; border: 0;
  font-size: 20px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--dp-encre);
}
body.client-app .dp-page .dp-devise { font-size: 14px; font-weight: 800; color: var(--dp-gris); }
body.client-app .dp-page .hint { font-size: 11px; color: var(--dp-gris); margin-top: 8px; }

/* --- montants rapides --- */
body.client-app .dp-page .dp-pilules {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 12px;
}
body.client-app .dp-page .dp-pilule {
  height: 36px; border-radius: 999px; cursor: pointer;
  background: var(--dp-carte); border: 1px solid var(--dp-bord);
  font-size: 12px; font-weight: 800; color: var(--dp-encre);
}
body.client-app .dp-page .dp-pilule.on {
  border-color: var(--dp-cobalt); background: var(--dp-cobalt-pale); color: var(--dp-cobalt);
}

/* --- tuiles « Payer avec » --- */
body.client-app .dp-page .dp-tuiles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
body.client-app .dp-page .dp-tuile {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 12px; border-radius: 20px; cursor: pointer; text-align: left;
  background: var(--dp-champ); border: 1px solid transparent; color: var(--dp-encre);
}
body.client-app .dp-page .dp-tuile.on {
  background: var(--dp-carte); border: 2px solid var(--dp-cobalt); padding: 11px;
}
body.client-app .dp-page .dp-tuile.off { opacity: .45; cursor: not-allowed; }
body.client-app .dp-page .dp-tuile .paylogo {
  width: 44px; height: 44px; border-radius: 14px; overflow: hidden; flex: none;
  display: grid; place-items: center;
}
/* 14/11/2026 — le logo Mixx (rond) etait ROGNE par object-fit:cover :
   on garde l'image entiere, centree, avec un fond blanc pour les
   logos a fond transparent. */
/* le fond du carre suit la MARQUE du reseau (celui du fichier), comme
   dans FRANCKO RECHARGE : blanc pour Flooz, bleu #003170 pour Mixx. */
body.client-app .dp-page .dp-tuile .paylogo img {
  width: 100%; height: 100%; object-fit: contain; padding: 2px;
}
body.client-app .dp-page .dp-tuile-txt { display: flex; flex-direction: column; min-width: 0; }
body.client-app .dp-page .dp-tuile-nom { font-size: 15px; font-weight: 800; }
body.client-app .dp-page .dp-tuile-op { font-size: 12px; color: var(--dp-gris); }
body.client-app .dp-page .dp-coche {
  margin-left: auto; width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center; flex: none;
  background: var(--dp-encre); color: var(--dp-carte);
}

/* --- bouton d'action --- */
body.client-app .dp-page .dp-continuer {
  width: 100%; height: 56px; border-radius: 28px; border: 0;
  background: var(--dp-cobalt); color: var(--pass-encre);
  font-size: 17px; font-weight: 800; box-shadow: 0 12px 24px -14px rgba(37, 99, 235, .8);
}
body.client-app .dp-page .dp-aide-ligne { margin-top: 12px; }

/* Le SUIVI (les ecrans qui viennent apres « Continuer ») recoit le meme habillage :
   cartes blanches arrondies sur le fond gris perle, encre anthracite. */
body.client-app .dp-page.dp-flux { background: var(--dp-fond); padding-bottom: 28px; }
body.client-app .dp-page.dp-flux > .card {
  background: var(--dp-carte); border: 1px solid var(--dp-bord);
  border-radius: 24px; box-shadow: 0 1px 2px rgba(24, 24, 27, .04);
  padding: 4px 0;
}
body.client-app .dp-page.dp-flux .card-hd {
  border-bottom: 1px solid var(--dp-bord); padding: 14px 16px;
}
body.client-app .dp-page.dp-flux .card-hd .strong { font-size: 16px; font-weight: 800; color: var(--dp-encre); }
body.client-app .dp-page.dp-flux .card-bd { padding: 14px 16px; }
body.client-app .dp-page.dp-flux .label { font-size: 13.5px; font-weight: 800; color: var(--dp-encre); }
body.client-app .dp-page.dp-flux .hint { font-size: 11px; color: var(--slate-400); }
body.client-app .dp-page.dp-flux .btn-primary,
body.client-app .dp-page.dp-flux .dp-continuer {
  background: var(--dp-cobalt); border: 0; border-radius: 28px;
  min-height: 52px; font-weight: 800; color: var(--dp-carte);
}
body.client-app .dp-page.dp-flux .code-box,
body.client-app .dp-page.dp-flux .ussd {
  background: var(--dp-champ); border: 1px solid var(--dp-bord);
  border-radius: 16px; color: var(--dp-encre);
}

/* ====================================================================
   LES TROIS RACCOURCIS DE L'ACCUEIL EN CARTES BENTO (13/11/2026, capture)

   Carte blanche (ou encre la nuit) a tres grands arrondis, pastille d'icone
   teintee en haut, libelle en gras, sous-ligne grise. Trois colonnes, comme
   sur l'image. Les teintes des pastilles sont en rgba : elles se composent
   sur la carte, donc elles tiennent dans les deux themes.
   ==================================================================== */
body.client-app .cx-tuiles {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 6px;
}
body.client-app .cx-tui {
  /* 13/11/2026 — le client a vu des cartes etroites (« Cou… », « Mes… ») : l'ancienne
     regle des pastilles rondes imposait width:68px et flex:0 0 auto. Les cartes
     prennent donc toute leur colonne, et le libelle ne se coupe plus. */
  width: 100%; flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; padding: 9px 6px 9px; min-height: 78px;
  background: var(--surface); border: 1px solid var(--slate-200);
  border-radius: 16px; text-decoration: none;
  box-shadow: 0 1px 2px rgba(11, 14, 13, .04);
}
body.client-app .cx-tui:active { transform: translateY(1px); }
body.client-app .cx-tui-rond {
  width: 34px; height: 34px; border-radius: 11px;
  display: grid; place-items: center; margin-bottom: 1px;
}
body.client-app .cx-tui-rond.bleu { background: rgba(37, 99, 235, .11); color: var(--dp-cobalt); }
body.client-app .cx-tui-rond.violet { background: rgba(147, 51, 234, .11); color: rgba(147, 51, 234, 1); }
body.client-app .cx-tui-rond.vert { background: rgba(5, 150, 105, .11); color: rgba(5, 150, 105, 1); }
body.client-app .cx-tui-rond.or { background: rgba(229, 169, 60, .14); color: rgba(180, 120, 20, 1); }
body.client-app .cx-tui-rond.whatsapp { background: rgba(37, 211, 102, .14); color: rgba(22, 163, 74, 1); }
body.client-app .cx-tui-lib {
  font-size: 12.5px; font-weight: 800; color: var(--slate-900);
  text-align: center; letter-spacing: -.1px;
  max-width: 100%; white-space: normal; overflow: visible; text-overflow: clip;
  line-height: 1.2;
}
body.client-app .cx-tui-sous {
  font-size: 10.5px; font-weight: 500; color: var(--slate-500); text-align: center;
  max-width: 100%; white-space: normal; line-height: 1.25;
}

@media (max-width: 380px) {
  body.client-app .cx-tuiles { gap: 8px; }
  body.client-app .cx-tui { min-height: 118px; padding: 13px 8px 12px; border-radius: 19px; gap: 6px; }
  body.client-app .cx-tui-rond { width: 46px; height: 46px; border-radius: 15px; }
  body.client-app .cx-tui-lib { font-size: 13.5px; }
  body.client-app .cx-tui-sous { font-size: 10.5px; }
}

/* Le bouton du DEPOT garde l'ancien bleu vif (consigne du 13/11/2026) ; celui du
   RETRAIT suit le navy comme le reste de l'application. */
body.client-app .dp-page.dp-depot .dp-continuer { background: var(--bleu-depot); }
body.client-app .dp-page.dp-depot .dp-pilule.on { border-color: var(--bleu-depot); color: var(--bleu-depot); }

/* ====================================================================
   COULEURS DES DEUX TUILES (14/11/2026, consigne du client) :
   « change le bouton depot en blanc et le bouton retrait en vert ».
   Le depot devient la tuile CLAIRE (icone navy sur aplat pale), le retrait
   la tuile VERTE (icone blanche sur aplat translucide), texte blanc.
   ==================================================================== */
/* 14/11/2026 (2e consigne du jour) : « depot en bleu » — la tuile du depot
   reprend l'ancien bleu vif, texte et icone en blanc ; le retrait reste vert. */
body.client-app .cx-pass-tuile.dep {
  background: var(--bleu-depot); color: var(--pass-encre);
}
body.client-app .cx-pass-tuile.dep .cx-pass-ico {
  background: rgba(255, 255, 255, .18); color: var(--pass-encre);
}
body.client-app .cx-pass-tuile.dep .cx-pass-sous { color: var(--pass-sous); }
body.client-app .cx-pass-tuile.wd {
  background: var(--vert-action); color: var(--pass-encre);
}
body.client-app .cx-pass-tuile.wd .cx-pass-ico {
  background: rgba(255, 255, 255, .18); color: var(--pass-encre);
}
body.client-app .cx-pass-tuile.wd .cx-pass-sous { color: var(--pass-sous); }

/* La nuit, les cartes de saisie n'ont plus d'ombre claire (le halo se voyait
   comme un cerne lumineux sur le fond noir) ni de bordure lumineuse. */
:root[data-theme="dark"] body.client-app .dp-page .dp-section,
:root[data-theme="dark"] body.client-app .dp-page.dp-flux > .card {
  box-shadow: none; border-color: rgba(255, 255, 255, .07);
}
:root[data-theme="dark"] body.client-app .dp-page .dp-back,
:root[data-theme="dark"] body.client-app .dp-page .dp-secure {
  box-shadow: none; border-color: rgba(255, 255, 255, .09);
}
