/* =====================================================================
   FRANCKO RECHARGE - 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 #143C72 (marque), bleu clair #4A7CBE (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 #143C72 sous du texte blanc ; l'ambre ne sert plus qu'aux etats
   ===================================================================== */
:root {
  /* Palette MAISON (11/11/2026) : le bleu d'origine #143C72 + l'or en accent.
     La feuille avait ete repeinte en ORANGE a moitie (les jetons en #143C72,
     mais les degrades, les rgba et les ombres etaient restes bleus) : deux
     familles de couleurs dans la meme page. Ici tout vient du meme bleu. */
  --brand-50: #EFF4FB;  --brand-100: #D8E4F3; --brand-200: #B3C9E6; --brand-300: #7FA6D4;
  --brand-400: #4A7CBE; --brand-500: #21589C; --brand-600: #143C72; --brand-700: #113160;
  --brand-800: #0D2749; --brand-900: #0A1F3C;

  --slate-50: #F8FAFC; --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: #0F172A; --slate-950: #020617;

  --amber-50: #FFFBEB; --amber-100: #FEF3C7; --amber-200: #FDE68A; --amber-500: #F59E0B;
  --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;
  --emerald-50: #ECFDF5; --emerald-200: #A7F3D0; --emerald-500: #10B981; --emerald-600: #059669;
  --emerald-700: #047857; --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(84, 142, 207, .72); --act-dep-2: rgba(38, 106, 185, .72);
  --act-wd-1: rgba(0, 180, 0, .72); --act-wd-2: rgba(0, 165, 0, .72);

  /* Croquis de reference : bordures et puce des tuiles d'action (nos couleurs). */
  --tile-line: rgba(255, 255, 255, .16);
  --tile-line-fort: rgba(255, 255, 255, .34);
  --tile-ico-bg: rgba(255, 255, 255, .22);
  /* Aplats PLEINS des tuiles d'action (croquis du 07/11/2026). Definies une
     seule fois : elles ne basculent pas la nuit, comme les --act-* du verre.
     blanc / #143C72 = 10,4:1 ; blanc / #0E7A3C = 4,7:1 (AA). */
  --act-dep-plein: #143C72;
  --act-wd-plein: #0E7A3C;
  /* PAIRE DE TUILES DU CROQUIS (07/11/2026, « comme sur la capture ») : la
     premiere est CLAIRE avec une encre foncee, la seconde EN CREUX et prend
     l'encre du theme. Teintes : notre bleu pale, notre encre ; rien d'autre. */
  --act-dep-clair: #D8E4F3;   /* brand-100 : la tuile claire */
  --act-dep-encre: #0A1F3C;   /* brand-900 : sur la tuile claire = 9,9:1 */
  /* 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;

  /* CROQUIS BOZOSERVICE (07/11/2026) : rayons plus serres que les notres
     (16/24 -> 12/16). C'est la difference la plus visible du croquis,
     et elle s'applique a TOUTES les cartes de l'espace client. */
  --radius: 12px; --radius-lg: 16px; --radius-sm: 10px;
  /* surfaces (le mode sombre les redefinit : voir :root[data-theme="dark"]) */
  --surface: #FFFFFF; --surface-2: #F7FAFD;
  /* 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);
  --shadow-lg: 0 24px 60px -24px rgba(15, 47, 92, .35);
  --shadow-hover: 0 4px 20px rgba(20, 60, 114, .12);
  --shadow-cta: 0 8px 24px rgba(20, 60, 114, .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: #143C72;    /* le bleu de la maison, FIGE (--brand-600 s'eclaircit la nuit) */
  --ah-brand-500: #143C72;
  --ah-link: #143C72;     /* 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, #113160, #4A7CBE);                 /* titre du hero : bleu -> bleu clair */
  --grad-cta: linear-gradient(135deg, #143C72, #3E7FD6);
  /* 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;
  /* TIROIR DU MENU CLIENT (11/11/2026) : teintes relevees dans la feuille de
     la reference, nommees par ROLE comme chez elle (--nuit/--nuit-2/--or/--or-clair).
     Declarees ICI pour que les regles du tiroir n'ecrivent aucune couleur en dur. */
  --cxd-nuit: #03081b; --cxd-panneau: #0a1436;
  --cxd-or: #e89f1e; --cxd-or-clair: #f7c052; --cxd-encre: #0b1330;
  --cxd-lang-2: #EDF0F7; --cxd-cta: #21589C;
  /* BARRE DE L'EN-TETE (08/11/2026) : la teinte de la BARRE DU BAS, relevee au
     pixel (#0A1436 = --cxd-panneau). Deux corrections du proprietaire le meme
     jour : --brand-600 (#143C72) donnait a l'en-tete la couleur de la carte
     Depot, puis le bleu de la capture BOZO (#0E609C) ne lui allait pas — il a
     demande « cette couleur a l entete » en montrant la barre du bas. Les deux
     barres de l'application sont donc EXACTEMENT de la meme teinte. */
  --cx-entete: #0A1436;

/* aplats des deux cartes d'action (11/11/2026) : FIGES dans les deux themes,
     comme les --act-* : blanc sur bleu 9,9:1 et blanc sur vert 4,7:1. */
  --cxf-dep-fond: #143C72; --cxf-wd-fond: #0E7A3C;
  /* fond du fichier logo (echantillonne sur l'image du client) */
  --cxf-nuit-logo: #031334;
  --cxf-etape: #1B5FBF; --cxf-etape-halo: rgba(27,95,191,.12);
  /* encre de la CARTE BLANCHE des assistants (elle reste blanche la nuit) */
  --cxf-card-ink: #0B1330; --cxf-card-ink-2: #64748B;
  --cxf-card-line: #E2E8F0; --cxf-card-soft: #F1F5F9; --cxf-card-bg: #FFFFFF;
  /* gris du nocturne de FlashPay (echelle du backoffice) */
  --cxf-noir: #0C0C0E; --cxf-noir-2: #18181B;
  /* 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: #143C72; --landing-red-dark: #113160; --landing-red-light: #143C72;
}

/* =====================================================================
   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 'fr_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"] {
  /* la carte des assistants SUIT le theme : blanche le jour, marine la nuit */
  --cxf-card-ink: #FFFFFF; --cxf-card-ink-2: #9D9DA6;
  --cxf-card-line: #27272A; --cxf-card-soft: #27272A; --cxf-card-bg: #18181B;
  /* 11/11/2026 : les aplats des deux cartes d'action ne basculent pas la nuit —
     ils sont donc redefinis ICI a l'identique (un controle de contraste lit les
     jetons du bloc de theme, pas ceux de :root). */
  --cxf-dep-fond: #143C72; --cxf-wd-fond: #0E7A3C;
  color-scheme: dark;

  /* 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
     (#143C72) 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. */
  /* 08/11/2026 — « le mode sombre a change en mode noir : prend mon mode noir
     de flashpay ». Les valeurs etaient parties en MARINE (#080e1e / #0b1329 /
     #0d1c3a) alors que la reference ecrite du projet EST le nocturne de
     flashpay / du backoffice (echelle --ink-* de panneau-v2.css) : gris NEUTRE
     sans derive bleue. On remet ces six jetons, et EUX SEULS decident des
     fonds — ne pas les reteinter « a l'oeil », le controle « nocturne » de
     tests/ui_check.py compare jeton par jeton. */
  --slate-50: #0C0C0E;   /* --ink-900 : fond de page du panneau */
  --slate-100: #141416;  /* entre le fond et la carte */
  --slate-200: #27272A;  /* --ink-700 : bordure / champ */
  --slate-300: #3F3F46;
  --slate-400: #71717A;  /* --ink-400 : placeholder */
  --slate-500: #9D9DA6;  /* --ink-300 : texte secondaire */
  --slate-600: #B4B4BC;
  --slate-700: #D4D4D8;
  --slate-800: #E8E8EB;
  --slate-900: #FFFFFF;  /* texte du panneau : blanc franc */
  --slate-950: #FFFFFF;

  /* surfaces */
  --surface: #18181B;      /* --ink-800 : cartes, barres */
  --surface-2: #27272A;    /* --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 (#2F6FCB) 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. */
  --brand-50: #1A1A1A; --brand-100: #242424; --brand-200: #333333; --brand-300: #4A76B4;
  --brand-400: #6FA3E8; --brand-500: #3E7FD6; --brand-600: #2F6FCB; --brand-700: #143C72;
  --brand-800: #143C72; --brand-900: #113160;

  /* teintes semantiques : fonds sombres, accents eclaircis */
  --amber-50: #41300F;   --amber-100: #3A2C0C; --amber-200: #6B4E12; --amber-500: #F59E0B;
  --amber-600: #FBBF24;  --amber-700: #FCD34D; --amber-800: #FDE68A;
  --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: #143C72; --landing-red-dark: #143C72; --landing-red-light: #4A7CBE;

  --ring: 0 0 0 1px var(--slate-200);
  --shadow: 0 1px 2px rgba(0, 0, 0, .5);
  --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, #6FA3E8, #B3C8E5);                 /* nuit : bleu clair -> bleu pale */
  --grad-cta: linear-gradient(135deg, #143C72, #3E7FD6);
  /* 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: 0; 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. */
  display: flex; justify-content: flex-start; align-items: center; gap: 6px;
  padding: 6px 10px 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 {
  position: relative; flex: 0 0 auto; display: flex; flex-direction: row; align-items: center;
  gap: 8px; padding: 9px 12px; border-radius: 999px; color: var(--slate-500);
  font-size: 13.5px; font-weight: 600; 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. */
.bottomnav .item.active { background: var(--brand-600); color: var(--on-brand); padding: 9px 16px; }
/* 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. */
.bottomnav .item span { display: none; }
.bottomnav .item.active span { display: inline; }
.bottomnav .item svg { width: 22px; height: 22px; }
/* 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(36, 89, 156, .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: #143C72; 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(20, 60, 114, .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 #143C72
   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: #143C72; }
.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, #143C72 0%, #2C6BB0 55%, #F59E0B 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: #143C72; 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: #4A7CBE; 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(20, 60, 114, .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: 8px; padding: 8px 8px 8px 11px; border-radius: 16px;
  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; flex: 0 0 auto; white-space: nowrap; }
/* 08/11/2026 (« c'est trop grand » / « reduit ca ») : le libelle « Mettre a jour »
   se coupait sur QUATRE lignes et la carte prenait une demi-page. Le bouton ne se
   comprime plus et ne se coupe plus ; sa hauteur est bornee par un selecteur plus
   fort que `body.client-app .btn` (min-height 42 px), sinon la regle generale
   gagne. */
body.client-app .maj-banner .btn { flex: 0 0 auto; white-space: nowrap;
  min-height: 34px; height: 34px; padding: 0 14px; font-size: 12.5px; }
/* 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(245, 158, 11, .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, #FBBF24) ; 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
       #143C72 / --brand-600 #143C72, nuit --brand-400 #4A7CBE.
   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(20, 60, 114, .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(20, 60, 114, .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: #86A6D2; }              /* pseudo affiche sur la carte sombre */
:root[data-theme="dark"] { --hero-id: #6FA3E8; }

/* 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; }
.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;
  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); }

/* CONNEXION / INSCRIPTION — la paire posee en haut de l'accueil du VISITEUR
   (11/11/2026). Meme grille que les deux tuiles qui la suivent, pour que les
   quatre blocs s'alignent. Aucune couleur en dur : le plein prend le bleu de la
   maison et son encre claire, le cerne prend la surface de la carte et le meme
   bleu. La nuit, les jetons basculent seuls (--brand-600 s'eclaircit). */
.cx-auth { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.cx-auth-b { display: flex; align-items: center; justify-content: center;
  min-height: 46px; padding: 0 10px; border-radius: var(--radius);
  font-size: 14.5px; font-weight: 700; text-decoration: none;
  border: 1px solid transparent;
  transition: transform .12s var(--fx-ease, ease), filter .15s ease; }
.cx-auth-in { background: var(--brand-600); color: var(--on-brand); }
.cx-auth-up { background: var(--surface); color: var(--brand-600); border-color: var(--brand-300); }
.cx-auth-b:active { transform: scale(.98); }
/* La nuit, le libelle cerne passe au bleu clair : le bleu de la maison sur la
   surface sombre ne donne que 3,6:1 (mesure) — insuffisant pour un libelle,
   alors que --brand-400 monte a 6,8:1. */
:root[data-theme="dark"] .cx-auth-up { color: var(--brand-400); border-color: var(--brand-500); }

/* 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, #143C72); }
/* 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, #143C72); }
.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, #143C72); 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(20, 60, 114, .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(36,89,156,.12); }
.tg-ligne.them .tg-cite b { color: var(--brand-600); }
.tg-ligne.me .tg-cite { border-left-color: var(--brand-500); background: rgba(36,89,156,.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(20, 60, 114, .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(20, 60, 114, .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);
  padding: 20px; color: #fff;
  background: linear-gradient(140deg, var(--brand-600) 0%, var(--brand-700) 60%, var(--brand-800) 100%);
  box-shadow: 0 18px 34px -22px rgba(8, 24, 47, .9); }
.pf-hero::after { content: ""; position: absolute; right: -46px; top: -58px; width: 168px; height: 168px;
  border-radius: 50%; background: rgba(255, 255, 255, .10); pointer-events: none; }
.pf-hero-top { position: relative; display: flex; align-items: center; gap: 14px; }
.pf-ava { flex: 0 0 auto; width: 58px; height: 58px; border-radius: 19px; display: grid; place-items: center;
  background: rgba(255, 255, 255, .18); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .30);
  font-weight: 800; font-size: 21px; letter-spacing: .02em; }
.pf-nom { font-size: 19px; font-weight: 700; line-height: 1.2; }
.pf-meta { font-size: 12.5px; color: rgba(255, 255, 255, .84); margin-top: 3px; }
.pf-chip { position: relative; display: inline-flex; align-items: center; gap: 6px; margin-top: 16px;
  padding: 6px 11px; border-radius: 999px; background: rgba(255, 255, 255, .14);
  font-size: 12px; color: rgba(255, 255, 255, .94); }

/* ---- 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: 36px; height: 36px; border-radius: 11px; display: grid; place-items: center;
  background: var(--brand-50); color: var(--brand-600); }
.pf-ico.sm { width: 32px; height: 32px; border-radius: 10px; }
.pf-stat .pf-ico { margin-bottom: 8px; }
:root[data-theme="dark"] .pf-ico { background: rgba(111, 163, 232, .16); 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: 13.5px; }
.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); }

/* ---- 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: 26px; height: 26px; border-radius: 8px; display: grid;
  place-items: center; background: rgba(255, 255, 255, .16); }
:root[data-theme="dark"] .maj-banner .mb-ico { background: rgba(20, 60, 114, .14); color: var(--brand-500); }
.maj-banner .mb-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
.maj-banner .mb-t { font-size: 12px; font-weight: 700; line-height: 1.25; }
.maj-banner .mb-s { font-size: 11px; font-weight: 500; opacity: .74; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* ==========================================================================
   LE MARCHE (30/09/2026) : rayons, cartes d'articles, panier, commande.
   Meme palette que le reste : bleu maison #143C72, or #F59E0B, 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(20, 60, 114, .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(20, 60, 114, .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(20, 60, 114, .15), 0 8px 10px -6px rgba(20, 60, 114, .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(36, 89, 156, .28), transparent 70%),
      radial-gradient(460px 300px at 82% 4%, rgba(20, 60, 114, .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). */
/* 08/11/2026 : le PANNEAU de l'en-tete est agrandi (demande du proprietaire :
   « agrandit l entete francko recharge », puis « pas l ecriture, le panneau »).
   Rembourrage vertical 12 -> 22 px : la barre gagne ~20 px de haut, le titre
   garde sa taille. Les 8 px lateraux sont conserves : le burger et les commandes
   de droite y sont accroches en absolu. */
body.client-app .topbar {
  background: var(--surface); border: 1px solid var(--cx-cerne); border-radius: var(--radius-lg);
  margin: 10px 10px 0; padding: 22px 8px;
  box-shadow: 0 16px 32px -22px rgba(20, 60, 114, .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(84px + 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. */
/* 08/11/2026 — « ici aussi c'est pas noir » : la nuit, l'en-tete prend le NOIR DE
   LA PAGE (--slate-50, #0C0C0E) et non plus la surface des cartes (#18181B) ;
   les deux barres et le fond ne font plus qu'un aplat, les cartes seules se
   detachent. Le cerne passe en blanc translucide comme celui de la barre du bas. */
:root[data-theme="dark"] body.client-app .topbar {
  background: var(--slate-50); border-color: rgba(255, 255, 255, .10);
}
body.client-app .cx-logo { width: 36px; height: 36px; border-radius: 10px; background: var(--brand-600); }
body.client-app .cx-name { font-size: 17px; letter-spacing: .005em; display: block; }
body.client-app .cx-top .who {
  font-size: 12px; text-transform: uppercase; letter-spacing: .14em; color: var(--slate-500);
  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 {
  display: grid;
  grid-template-areas: "ico title chev" "ico sub chev";
  grid-template-columns: auto 1fr auto;
  column-gap: 14px; row-gap: 2px; align-items: center;
  border-radius: var(--cx-r-lg); border: none;
  box-shadow: 0 2px 10px rgba(0,0,0,.12);
  padding: 16px;
}
body.client-app .cx-act-ico {
  grid-area: ico; width: 46px; height: 46px; border-radius: 999px; margin-bottom: 0;
  background: rgba(255,255,255,.18); border: 2px solid rgba(255,255,255,.70); color: #fff; box-shadow: none;
  align-self: center;
}
body.client-app .cx-act-t { grid-area: title; font-size: 17px; }
body.client-app .cx-act-s { grid-area: sub; }
body.client-app .cx-act-chev { grid-area: chev; color: rgba(255,255,255,.65); align-self: center; }

/* 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: none; -webkit-backdrop-filter: none; }
body.client-app .cx-act-dep { color: #fff; background: #143C72 !important; }
body.client-app .cx-act-wd { color: #fff; background: #059669 !important; }
body.client-app .cx-act-dep .cx-act-ico { background: rgba(0,0,0,.16); border: 0; color: var(--on-brand); box-shadow: none; border-radius: 14px; width: 44px; height: 44px; display: grid; place-items: center; }
body.client-app .cx-act-wd .cx-act-ico { background: rgba(0,0,0,.16); border: 0; color: var(--on-brand); box-shadow: none; border-radius: 14px; width: 44px; height: 44px; display: grid; place-items: center; }
/* 08/11/2026 — « en mode noir, mets le bouton Depot en bleu » : la carte Depot
   prenait l'orange (#ea6c0a) la nuit ; elle reprend le BLEU DE LA MAISON, la
   meme teinte que le jour (#143C72) et que --cxf-dep-fond. Le Retrait, lui,
   garde son vert. Encre blanche dans les deux cas (9,9:1 sur #143C72).
   (Le troisieme passage du 08/11 au soir — « le theme sombre est bleu, corrige
   comme ca » — ne se fait PAS ici : voir la regle finale en bas de la feuille,
   seule a pouvoir battre le bloc « 11/11/2026 capture de reference ».) */
:root[data-theme="dark"] body.client-app .cx-act-dep { color: #fff; background: #143C72 !important; }
:root[data-theme="dark"] body.client-app .cx-act-wd { color: #fff; background: #047857 !important; }
:root[data-theme="dark"] body.client-app .cx-act-dep .cx-act-ico { background: rgba(255,255,255,.15); border-color: rgba(255,255,255,.60); color: #fff; box-shadow: none; border-radius: 999px; }
:root[data-theme="dark"] body.client-app .cx-act-wd .cx-act-ico { background: rgba(255,255,255,.15); border-color: rgba(255,255,255,.60); color: #fff; box-shadow: none; border-radius: 999px; }
/* ---------- 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). */
body.client-app .app-shell { padding-bottom: calc(104px + 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. */
/* 11/11/2026 (capture de reference) : la barre n'est plus une PILULE BLANCHE
   flottante mais une bande BLEU NUIT pleine largeur, collee en bas, arrondie en
   haut. Les CINQ libelles sont toujours visibles et l'entree active passe en or.
   C'est CE bloc qui fait foi (il est plus specifique qu'une classe ajoutee). */
body.client-app .bottomnav {
  background: var(--cxd-panneau);
  border: 0;
  border-radius: 26px 26px 0 0;
  margin: 0;
  padding: 8px 6px calc(env(safe-area-inset-bottom, 0px) + 8px);
  -webkit-backdrop-filter: none; backdrop-filter: none;
  box-shadow: 0 -18px 34px -26px rgba(3, 8, 27, .55);
  gap: 2px;
}
body.client-app .bottomnav .item { border-radius: 16px; padding: 6px 2px; color: rgba(255,255,255,.72); }
body.client-app .bottomnav .item span { display: inline; font-size: 11px; font-weight: 600; letter-spacing: 0; }
body.client-app .bottomnav .item svg { width: 23px; height: 23px; }
body.client-app .bottomnav .item.active {
  background: transparent;
  color: var(--cxd-or-clair);
  padding: 6px 2px;
  box-shadow: none;
}
/* 08/11/2026 — « en mode noir le bas n'est pas noir » : la nuit, la barre prend
   le NOIR DE LA PAGE (--slate-50), comme l'en-tete et le tiroir ; les cartes
   (#18181B) restent ce qui se detache. C'est CETTE regle qui fait foi (0,4,1) :
   une regle sur .cxf-bar seul (0,3,0) serait battue ici. Le jour, la barre reste
   bleu nuit par la regle du dessus — ne pas la toucher. */
:root[data-theme="dark"] body.client-app .bottomnav {
  background: var(--slate-50);
  border-color: transparent;
}
:root[data-theme="dark"] body.client-app .bottomnav .item.active { background: transparent; color: var(--cxd-or-clair); }
/* 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) {
  body.client-app .bottomnav {
    left: 50%; right: auto; margin-left: -344px; margin-right: 0;
    width: 688px; max-width: calc(100% - 32px);
  }
}
/* (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, la meme que sur le bandeau d'accueil */
body.client-app.auth-page .auth-card::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 3px; pointer-events: none;
  background: linear-gradient(90deg, var(--brand-600), var(--brand-300) 62%, transparent);
}
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); }


/* =====================================================================
   08/11/2026 (soir) — MODE NOIR : LA CARTE DEPOT N'EST PLUS BLEUE
   Demande : « le theme sombre de franko est bleu, corrige comme ca », capture
   FLASH SERVICE a l'appui (page noire, cartes #18181B, le bleu de la marque
   reserve aux PASTILLES d'icone).

   PLACEMENT : ce bloc est AVANT la section « ESPACE CLIENT — socle d'habillage
   commun » EXPRES. Le controle « aucune couleur neuve dans le socle » lit tout
   ce qui suit ce titre jusqu'a la fin du fichier et n'y tolere que #fff : poser
   cette regle a la fin de la feuille le faisait echouer. Il doit seulement
   rester APRES le bloc du 08/11 (« mets le bouton Depot en bleu », ligne ~3737)
   qui porte deja !important : a specificite egale, l'ordre tranche.
   Il bat aussi le bloc du 11/11 (« les deux cartes sont des aplats pleins »),
   qui n'a pas !important.
   Le RETRAIT garde son vert : aucune demande pour lui. Encre #FFFFFF sur
   #18181B (17:1) — valeurs du nocturne : --surface, --slate-200, --brand-400. */
:root[data-theme="dark"] body.client-app .cx-act.cx-act-dep {
  background: #18181B !important;
  border: 1px solid #27272A !important;
  color: #FFFFFF !important;
}
:root[data-theme="dark"] body.client-app .cx-act.cx-act-dep .cx-act-chev {
  color: #4A76B4 !important;
}
:root[data-theme="dark"] body.client-app .cx-act.cx-act-dep .cx-act-ico {
  background: rgba(47, 111, 203, .22) !important;
  border: 1px solid rgba(111, 163, 232, .55) !important;
  color: #6FA3E8 !important;
  border-radius: 14px !important;
}

/* =====================================================================
/* =====================================================================
   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. CE BLOC EST LE DERNIER MOT sur les rayons de
   l'accueil : c'est ICI qu'on les change, pas plus haut.
   DECISION DU 07/11/2026 (demande du client : reprendre le croquis du site de
   reference, « oui vas-y ») : 22 px -> 12 px, la valeur du croquis. Cela
   remplace le 22 px du 30/09 SUR DEMANDE, pas par inadvertance ; le controle
   correspondant d'ui_check a ete reecrit avec cette decision. */
body.client-app .cx-act { border-radius: 12px; }
body.client-app .cx-msg { border-radius: 12px; }
body.client-app .cx-suivi { border-radius: 12px; }
body.client-app .cx-tournoi { border-radius: 12px; }
/* 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 {
  /* 11/11/2026 (« eleve les ligne bleu et les separation ») : plus de FILET BLEU
     autour des blocs, plus d'ombre de separation — le bloc se lit a son fond et a
     son rayon, comme sur la capture. */
  position: relative; margin-bottom: 16px; padding: 9px 13px 11px;
  background: var(--surface); border-radius: 20px;
  border: 0;
  box-shadow: none;
}
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(--slate-200); background: var(--slate-100);
  color: var(--slate-700); 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(--slate-900); background: var(--surface); color: var(--slate-900);
  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(--slate-900); color: var(--surface); 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 FRANCKO RECHARGE / Vous payez » ; retrait le
   28/10/2026 : « Numero qui recoit / Frais FRANCKO RECHARGE / 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(20, 60, 114, .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(20, 60, 114, .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. */
.tg-saisie {
  flex: none; display: flex; flex-direction: column; align-items: stretch; gap: 6px;
  height: auto; min-width: 0; border-radius: 0; padding: 0; background: transparent;
  box-shadow: none;
}
.tg-champ {
  display: block; width: 100%; border: 0; outline: none; background: transparent;
  padding: 4px 8px 2px; font-size: 17px; 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); }
.tg-ronds {
  display: flex; width: 100%; align-items: center; justify-content: flex-start;
  gap: 8px; padding: 0 2px 2px; text-align: left;
}
.tg-plus {
  flex: none; width: 46px; height: 46px; padding: 0; border: 0; border-radius: 50%;
  display: grid; place-items: center; background: var(--tg-saisie); color: var(--tg-encre);
  cursor: pointer; transition: transform .12s linear;
}
.tg-plus:active { transform: scale(.94); }
.tg-ronds .tg-rond { width: 46px; height: 46px; }
/* 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: auto; background: var(--tg-saisie); color: var(--tg-encre);
  /* 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; }
.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; }
}

/* ==========================================================================
   TCHAT : FOND BLEU NUIT + ECRITURES PLUS PETITES (09/11/2026)
   Demande du proprietaire sur SA capture du tchat Support : « reduit la taille
   des ecritures » et « change le background ». Le fond de la page prend le bleu
   nuit de la maison — le meme que les ecrans Depot / Retrait (--cxd-panneau) —,
   l'en-tete devient transparent sur ce fond avec son titre en blanc, et toutes
   les tailles de texte baissent d'environ 12 a 20 % : titre 16,5 -> 15 px,
   sous-titre 12 -> 11, bulle 14,5 -> 13, heure 12 -> 11, pastille de jour
   12 -> 11, champ de saisie 17 -> 15, emoji seul 42 -> 33. Les cibles tactiles
   (46 px) ne bougent pas : seule l'ecriture rapetisse.
   Les bulles RECUES restent blanches (--tg-fond) : sur le bleu nuit elles se
   detachent seules. La bulle ENVOYEE passe de --brand-600 a --brand-500 : le
   bleu 600 sur le bleu nuit ne se distinguait plus (mesure a l'appui).
   Le theme SOMBRE n'est pas touche (il a deja son noir a lui).
   Aucune couleur en dur : jetons et #fff seulement (contrat de ui_check). */
:root:not([data-theme="dark"]) .tg { background: var(--cxd-panneau); }
:root:not([data-theme="dark"]) .tg-head {
  background: transparent; border-bottom-color: rgba(255, 255, 255, .16);
}
:root:not([data-theme="dark"]) .tg-titre { color: #fff; }
:root:not([data-theme="dark"]) .tg-sous { color: rgba(255, 255, 255, .74); }
:root:not([data-theme="dark"]) .tg-jour span {
  background: rgba(255, 255, 255, .12); color: #fff; border-color: rgba(255, 255, 255, .18);
}
:root:not([data-theme="dark"]) .tg-ligne.them .tg-bulle {
  background: var(--tg-fond); border-color: transparent;
}
:root:not([data-theme="dark"]) .tg-ligne.me .tg-bulle {
  background: var(--brand-500); border-color: var(--brand-500);
}
/* ce qui vit SUR la page (pas dans une bulle) : encre claire */
:root:not([data-theme="dark"]) .tg-vide,
:root:not([data-theme="dark"]) .tg-accueil-bonjour { color: #fff; }
:root:not([data-theme="dark"]) .tg-accueil-texte { color: rgba(255, 255, 255, .72); }
:root:not([data-theme="dark"]) .tg-act { color: rgba(255, 255, 255, .68); }
:root:not([data-theme="dark"]) .tg-act:hover { background: rgba(255, 255, 255, .12); color: #fff; }

/* --- tailles (les 46 px des ronds et des champs ne changent pas) ---------- */
.tg-titre { font-size: 15px; }
.tg-sous { font-size: 11px; }
.tg-texte { font-size: 13px; }
.tg-meta { font-size: 11px; }
.tg-jour span { font-size: 11px; }
.tg-champ { font-size: 15px; }
.tg-emoji-seul { font-size: 33px; }
.tg-accueil-bonjour { font-size: 23px; }
.tg-accueil-texte { font-size: 12.5px; }

/* ==========================================================================
   TCHAT : UNE SEULE COULEUR, PLUS AUCUN BLANC (09/11/2026)
   Demande : « enleve les blancs, fais une couleur unique sur l'interface du
   chat ». Tout l'ecran est le bleu nuit de la page ; les elements ne se
   distinguent plus par un fond blanc mais par la TRANSPARENCE du blanc (8 a
   18 %) : mes bulles un peu plus opaques que celles du caissier, la carte de
   saisie et les ronds au meme niveau. Le texte reste blanc, les heures en blanc
   adouci. Le seul aplat blanc restant est le rond d'envoi ACTIF — c'est le
   signal « on peut envoyer », et il ne dure que le temps de la frappe.
   Theme sombre : non touche (il a deja son noir a lui). */
:root:not([data-theme="dark"]) .tg-back,
:root:not([data-theme="dark"]) .tg-head-plus { background: rgba(255, 255, 255, .10); color: #fff; }
:root:not([data-theme="dark"]) .tg-ligne.them .tg-bulle {
  background: rgba(255, 255, 255, .08); border-color: rgba(255, 255, 255, .10); color: #fff;
}
:root:not([data-theme="dark"]) .tg-ligne.me .tg-bulle {
  background: rgba(255, 255, 255, .17); border-color: transparent; color: #fff;
}
:root:not([data-theme="dark"]) .tg-ligne.me .tg-meta,
:root:not([data-theme="dark"]) .tg-ligne.them .tg-meta { color: rgba(255, 255, 255, .62); opacity: 1; }
:root:not([data-theme="dark"]) .tg-ligne.me .tg-meta svg,
:root:not([data-theme="dark"]) .tg-ligne.them .tg-meta svg { color: rgba(255, 255, 255, .62); opacity: 1; }
:root:not([data-theme="dark"]) .tg-ligne.me .tg-meta.tg-lu svg { color: var(--tg-valide); opacity: 1; }
:root:not([data-theme="dark"]) .tg-ligne.me .tg-cite,
:root:not([data-theme="dark"]) .tg-ligne.them .tg-cite {
  background: rgba(255, 255, 255, .10); border-left-color: rgba(255, 255, 255, .45);
}
:root:not([data-theme="dark"]) .tg-ligne.me .tg-cite b,
:root:not([data-theme="dark"]) .tg-ligne.them .tg-cite b { color: #fff; }
:root:not([data-theme="dark"]) .tg-bar {
  background: rgba(255, 255, 255, .08); border-color: rgba(255, 255, 255, .14);
  box-shadow: none;
}
:root:not([data-theme="dark"]) .tg-champ { color: #fff; }
:root:not([data-theme="dark"]) .tg-champ::placeholder { color: rgba(255, 255, 255, .55); }
:root:not([data-theme="dark"]) .tg-plus,
:root:not([data-theme="dark"]) .tg-ronds #chat-mic { background: rgba(255, 255, 255, .10); color: #fff; }
:root:not([data-theme="dark"]) .tg-envoi { background: rgba(255, 255, 255, .14); color: #fff; }
:root:not([data-theme="dark"]) .tg-envoi.tg-envoi-on { background: rgba(255, 255, 255, .24); color: #fff; }
:root:not([data-theme="dark"]) .tg-saisie { background: transparent; box-shadow: none; }
:root:not([data-theme="dark"]) .tg-emoji { background: rgba(255, 255, 255, .06); }
:root:not([data-theme="dark"]) .tg-citation { background: rgba(255, 255, 255, .10); color: #fff; }
:root:not([data-theme="dark"]) .tg-descendre { background: rgba(255, 255, 255, .16); color: #fff; }
:root:not([data-theme="dark"]) .tg-accueil-rond { background: rgba(255, 255, 255, .10); color: #fff; }
:root:not([data-theme="dark"]) .tg-plus:focus-visible,
:root:not([data-theme="dark"]) .tg-ronds .tg-rond:focus-visible { outline-color: rgba(255, 255, 255, .7); }

/* GLISSER UN MESSAGE VERS LA DROITE POUR REPONDRE (09/11/2026, geste WhatsApp) :
   le rond « repondre » se devoile derriere la bulle qui glisse. Le rond est cree
   par le JS au premier geste (aucun noeud de plus dans le fil au repos). */
.tg-ligne { position: relative; }
.tg-glisse-ic {
  position: absolute; top: 50%; left: 4px; transform: translateY(-50%) scale(.6);
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255, 255, 255, .14); color: #fff; opacity: 0; z-index: 0;
  transition: opacity .12s linear, transform .12s ease-out; pointer-events: none;
}
.tg-ligne.tg-glisse-on .tg-glisse-ic { opacity: .6; transform: translateY(-50%) scale(1); }
.tg-ligne.tg-glisse-prete .tg-glisse-ic { opacity: 1; background: var(--brand-500); }
/* la bulle passe DEVANT le rond pendant le glissement */
.tg-bulle, .tg-emoji-seul { position: relative; z-index: 1; }

/* ---------- 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) ------------------------------ */
.cx-slides { display: flex; gap: 10px; overflow-x: auto; padding: 2px 2px 8px;
  margin-bottom: 12px; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; }
.cx-slides::-webkit-scrollbar { display: none; }
.cx-slide { flex: 0 0 84%; scroll-snap-align: start; border-radius: 16px; overflow: hidden;
  background: var(--surface); border: 1px solid var(--slate-200); text-decoration: none;
  color: inherit; display: block; }
.cx-slide img { width: 100%; display: block; aspect-ratio: 16 / 9; object-fit: cover; }
.cx-slide-txt { padding: 10px 12px 12px; }
.cx-slide-titre { font-size: 14.5px; font-weight: 800; color: var(--slate-900); }
.cx-slide-sous { font-size: 12px; color: var(--slate-600); margin-top: 2px; }
.cx-slide-cta { display: inline-block; margin-top: 8px; padding: 7px 12px; border-radius: 999px;
  background: var(--brand-600); color: #fff; font-size: 12.5px; font-weight: 700; }

/* ==========================================================================
   ECRAN DE PAIEMENT DETAILLE (27/10/2026).
   Structure et proportions COPIEES du modele montre par le marchand ; seules
   les couleurs sont les notres (bleu #143C72, 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(20, 60, 114, .4);
}
.ah-fi {
  display: grid; place-items: center;
  width: 40px; height: 40px; flex: none;
  border-radius: 12px;
  background: rgba(20, 60, 114, .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(20, 60, 114, .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(20, 60, 114, .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(20, 60, 114, .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); }

/* BOUTON « TELECHARGER L'APPLICATION ANDROID » (08/11/2026) : pleine largeur,
   sous la carte des DEUX ecrans d'entree. Il remplace la barre flottante ; les
   jetons `--ah-*` sont ceux de l'ecran (theme clair et nuit), donc aucune couleur
   en dur et rien a redefinir la nuit. */
.apk-btn {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  margin-top: 18px; min-height: 48px; padding: 0 16px;
  border: 1px solid var(--ah-line); border-radius: var(--radius);
  background: var(--ah-card); color: var(--ah-ink);
  font-size: 14.5px; font-weight: 700; text-decoration: none;
  transition: transform .12s var(--fx-ease, ease), filter .15s ease;
}
.apk-btn:active { transform: scale(.98); }
.apk-btn svg { flex: 0 0 auto; }
.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; }

/* ---------------------------------------------------------------------------
   PANNEAU CONNEXION / INSCRIPTION UN PEU PLUS PETIT (11/11/2026, demande du
   proprietaire : « tu peux reduire un peu la taille du panneau d inscription et
   de connexion »).
   La carte prenait toute la colonne : sur son telephone, 424 px de page moins
   deux fois 20 px de rembourrage = 384 px de large. On la ramene a 342 px
   (environ -11 %) et on resserre la verticale d'autant — champs 46 -> 44 px,
   ecarts de champ 16 -> 14 px, separateur « ou » et pied de carte rapproches.
   La largeur de reference de `.auth-wrap` et le rembourrage de `.auth-card`
   (384 px / 28 px) restent ECRITS tels quels dans leurs blocs : le controle du
   projet les cite mot pour mot, et la reduction se pose donc ici sur des
   selecteurs plus specifiques qui ne les touchent pas.
   --------------------------------------------------------------------------- */
body.client-app.auth-page .auth-wrap {
  max-width: 342px; margin-left: auto; margin-right: auto;
}
body.client-app.auth-page .auth-card .af { margin-bottom: 14px; }
body.client-app.auth-page .auth-card .af-lb { margin-bottom: 7px; }
body.client-app.auth-page .auth-card .af-in { height: 44px; }
body.client-app.auth-page .auth-card .af-forgot { margin-top: 10px; }
body.client-app.auth-page .auth-card .auth-card-s { margin: 4px 0 17px; }
body.client-app.auth-page .auth-card .auth-sep { margin: 17px 0; }
body.client-app.auth-page .auth-card .auth-foot { margin-top: 20px; }
body.client-app.auth-page .auth-card .auth-soc { margin-top: 15px; }
/* 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; }

/* =====================================================================
   CROQUIS DE REFERENCE — FORMES SEULEMENT (07/11/2026)
   ---------------------------------------------------------------------
   Demande du client : « garder ta base claire et ne reprendre que les formes
   (tuiles, boutons, onglets) ». Ce bloc est le SEUL endroit qui touche a ces
   composants : les essais precedents (aplats, champ bleu, verre) ont ete
   retires, il n'y a plus de regles qui se combattent.
   On reprend de la capture :
     - tuiles : rayon 16, icone NUE (pas de pastille), titre large, chevron ;
       la premiere CLAIRE (fond plein pale, encre foncee), la seconde EN CREUX
       (fond transparent, filet, encre du theme) ;
     - boutons : rayon 12 ; le bouton secondaire est un CONTOUR, pas un aplat ;
     - raccourcis : petites pastilles a filet, MEME dessin pour les deux (aucune
       n'est « active » : ce sont deux liens, pas deux onglets d'un choix) ;
     - rayons de cartes a 12, ombres plates, montants en mono tabulaire.
   AUCUNE teinte nouvelle : notre bleu pale, notre encre, notre vert.
   ===================================================================== */

/* ---- tuiles ---- */
body.client-app .cx-act {
  border-radius: 16px;
  padding: 15px 15px 17px;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
body.client-app .cx-act-ico {
  /* L'icone se pose a GAUCHE, alignee avec le titre (la reference la met en
     haut a gauche). Sans `align-self`, l'etirement de la colonne la centrait :
     c'est ce qui se voyait sur la capture du client. */
  width: auto; height: auto; border-radius: 0; margin-bottom: 12px;
  background: transparent;
  align-self: flex-start;
  justify-content: flex-start;
}
/* 11/11/2026 : en ANGLAIS « Withdrawal » debordait de la carte et le chevron
   passait sur « Deposit ». Le titre se reduit avec la largeur et laisse 16 px
   au chevron ; les mots trop longs se coupent proprement. */
body.client-app .cx-act-t {
  /* Pas de CESURE : « Retrait » se coupait en « Re-trait ». Le titre se reduit
     avec la largeur, et ne coupe un mot que s'il est vraiment trop long. */
  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-chev { position: absolute; top: 10px; right: 9px; opacity: .85; }

/* 11/11/2026 (capture de reference) : les deux cartes sont des APLATS PLEINS a
   encre blanche — c'etait un aplat bleu que le titre ecrivait en bleu nuit
   (illisible sur la capture du client). Depose/Retrait gardent LEURS teintes. */
body.client-app .cx-act-dep {
  background: var(--cxf-dep-fond);
  border: 1px solid var(--cxf-dep-fond);
  color: var(--on-brand);
}
body.client-app .cx-act-dep .cx-act-ico,
body.client-app .cx-act-dep .cx-act-chev { color: var(--on-brand); }
:root[data-theme="dark"] body.client-app .cx-act-dep {
  background: var(--cxf-dep-fond); border-color: var(--cxf-dep-fond); color: var(--on-brand);
}

body.client-app .cx-act-wd {
  background: var(--cxf-wd-fond);
  border: 1px solid var(--cxf-wd-fond);
  color: var(--on-brand);
}
body.client-app .cx-act-wd .cx-act-ico,
body.client-app .cx-act-wd .cx-act-chev { color: var(--on-brand); }
:root[data-theme="dark"] body.client-app .cx-act-wd {
  background: var(--cxf-wd-fond); border-color: var(--cxf-wd-fond); color: var(--on-brand);
}

/* ---- boutons ---- */
body.client-app .btn { border-radius: 12px; }
body.client-app .btn-ghost {
  background: transparent;
  border: 1px solid var(--brand-300);
  color: var(--brand-800);
}
body.client-app .btn-ghost:hover { background: var(--brand-50); }
:root[data-theme="dark"] body.client-app .btn-ghost {
  border-color: rgba(255, 255, 255, .30); color: #fff;
}

/* ---- raccourcis : pastilles a filet, dessin identique ---- */
body.client-app a.cx-racc-a {
  border-radius: 12px;
  padding: 9px 16px;
  border: 1px solid var(--slate-200);
  background: transparent;
  color: var(--slate-700);
}
body.client-app a.cx-racc-a svg { color: var(--brand-600); }
:root[data-theme="dark"] body.client-app a.cx-racc-a {
  border-color: rgba(255, 255, 255, .26); color: #fff;
}
:root[data-theme="dark"] body.client-app a.cx-racc-a svg { color: var(--brand-300); }

/* ---- libelles et montants ---- */
body.client-app .etiquette, body.client-app .dp-page .label {
  font-size: 10.5px; font-weight: 800; letter-spacing: .09em;
  text-transform: uppercase; color: var(--slate-500);
}
body.client-app .cx-bal, body.client-app .money, body.client-app .tx-amt,
body.client-app .hist-amt, body.client-app .dp-montant, body.client-app .wd-amount {
  font-family: ui-monospace, SFMono-Regular, "Roboto Mono", Menlo, monospace;
  font-variant-numeric: tabular-nums;
}

/* ---- cartes des parcours Depot / Retrait / Historique ---- */
body.client-app .dp-section,
body.client-app .dp-tuile,
body.client-app .dp-form,
body.client-app .dp-idrow,
.hist-list .hist-card,
.hist-list .card { border-radius: 12px; }
body.client-app .dp-section { box-shadow: none; }

/* ---- BANDEAU DU CROQUIS (07/11/2026) ---------------------------------------
   La capture pose des BOUTONS CARRES a filet (menu, cloche, initiale) et une
   CAPSULE pour la marque. On reprend ces deux formes sur notre bandeau ; les
   teintes restent les notres, et le fond de page ne bouge pas. */
body.client-app .cx-ico {
  width: 40px; height: 40px; border-radius: 12px;
  border: 1px solid var(--slate-200);
  background: transparent;
}
body.client-app .cx-ico:hover { background: var(--brand-50); }
body.client-app .cx-avatar { border-radius: 12px; }
/* 11/11/2026 : la marque se pose SUR la barre bleu nuit — plus de pastille
   blanche (elle faisait une tache claire au milieu de l'en-tete) ni de filet. */
body.client-app .cx-brand {
  border: 0;
  border-radius: 0;
  padding: 0;
  background: transparent;
}
:root[data-theme="dark"] body.client-app .cx-ico { border-color: rgba(255, 255, 255, .22); }
:root[data-theme="dark"] body.client-app .cx-brand {
  background: transparent; border-color: transparent;
}

/* ---- ONGLETS DU HAUT + BOUTON DU BAS (07/11/2026, croquis valide) ----------
   La capture remplace la barre du bas par deux choses : une RANGEE D'ONGLETS
   sous le bandeau, et UN bouton vers la discussion en bas de l'ecran. Memes
   pilules que la barre d'avant (trois entrees), meme geste (`data-act="nav"`).
   Nos couleurs : pastille active en bleu maison, filet sinon. */
.cx-tabs {
  max-width: 720px; margin: 10px auto 0; padding: 0 16px;
  display: flex; gap: 8px; align-items: center;
}
.cx-tabs .item {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 16px; border-radius: 12px;
  border: 1px solid var(--slate-200); background: transparent;
  color: var(--slate-700); font-weight: 700; font-size: 13.5px;
}
.cx-tabs .item span { display: inline; }        /* le libelle est TOUJOURS lisible */
.cx-tabs .item.active {
  background: var(--brand-600); border-color: var(--brand-600); color: var(--on-brand);
}
:root[data-theme="dark"] .cx-tabs .item { border-color: rgba(255, 255, 255, .22); color: #fff; }
:root[data-theme="dark"] .cx-tabs .item.active {
  background: var(--brand-500); border-color: var(--brand-500);
}

.cx-cta { position: fixed; left: 0; right: 0; bottom: 0; padding: 10px 16px calc(12px + env(safe-area-inset-bottom));
  background: linear-gradient(to top, var(--brand-50) 60%, transparent); }
.cx-cta .btn { width: 100%; justify-content: center; border-radius: 12px;
  min-height: 52px; font-size: 15px; }
:root[data-theme="dark"] .cx-cta { background: linear-gradient(to top, var(--slate-50) 60%, transparent); }
/* la place du bouton : le contenu ne passe pas dessous */
body.client-app .app-shell { padding-bottom: 92px; }
/* masquer la place du bouton quand le clavier est ouvert */
body.client-app[data-clavier="1"] .cx-cta { display: none; }


/* =====================================================================
   TIROIR DU MENU CLIENT (11/11/2026) — FORME reprise de la reference
   ldmservice.com/client (capture du client : « une interface comme cela »).
   Valeurs relevees dans la feuille SERVIE de la reference, pas a l'oeil :
     --nuit:#03081b  --nuit-2:#0a1436  --or:#e89f1e  --or-clair:#f7c052
     --papier:#fff   --ligne:#e3e7f1  --sourdine:#5b6685
     ressort : cubic-bezier(.34,1.4,.64,1)
   NOS couleurs restent la marque (bleu #143C72 / or) : la reference fournit la
   FORME (panneau plein a gauche, 26 px de rayon a droite, lignes de 52 px,
   bascule FR/EN en pilule blanche, carte de pied avec deux boutons).
   Prefixe `cxd-` : `dr-` est deja pris par l'ecran de depot.
   ===================================================================== */
body.client-app{ --cxd-ligne:rgba(255,255,255,.09); --cxd-ressort:cubic-bezier(.34,1.4,.64,1); }
.cxd-fond{
  position:fixed; inset:0; z-index:70; padding:0; border:0;
  background:rgba(3,8,27,.66);
  -webkit-backdrop-filter:blur(7px); backdrop-filter:blur(7px);
  opacity:0; transition:opacity .22s ease;
}
.cxd-fond[hidden]{display:none}
body.cxd-ouvert .cxd-fond{opacity:1}
.cxd{
  /* 08/11/2026 : MEME TAILLE, MEME FORME QUE LA REFERENCE (site.ldmservice.com/client,
     capture du jour) — panneau flottant detache de 10 px a gauche, en haut et en bas,
     largeur 73 vw plafonnee a 306 px, coins arrondis 24 px, listes d'entrees de 46 px
     de haut (mesures prises au pixel sur la capture : pas de 46,5 px, libelles 15 px,
     icones 22 px, bascule FR/EN haute de 29 px). */
  position:fixed; z-index:71;
  top:calc(env(safe-area-inset-top,0px) + 10px);
  bottom:calc(env(safe-area-inset-bottom,0px) + 10px);
  left:10px; width:min(73vw,306px);
  display:flex; flex-direction:column; gap:0;
  padding:10px 8px;
  background:var(--cxd-panneau); border-radius:24px;
  box-shadow:0 30px 70px -28px rgba(3,8,27,.8);
  transform:translateX(calc(-100% - 14px)); transition:transform .28s var(--cxd-ressort);
  overflow-y:auto;
}
.cxd[hidden]{display:none}
/* 08/11/2026 — « ici aussi n'est pas noir en mode sombre » : le tiroir gardait le
   BLEU NUIT de --cxd-panneau (#0a1436). La nuit, il prend le NOIR DE LA PAGE
   (--slate-50), comme l'en-tete et la barre du bas ; le JOUR il reste bleu nuit
   (panneau de nuit assume, voir plus haut). Le voile .cxd-fond, lui, ne bouge pas. */
:root[data-theme="dark"] .cxd{ background: var(--slate-50); }
body.cxd-ouvert .cxd{transform:none}
.cxd-tete{display:flex; align-items:flex-start; justify-content:space-between; padding:8px 8px 24px}
/* Marque sur deux lignes : premier mot blanc, le reste en or (comme la reference). */
.cxd-marque{display:flex; flex-direction:column; line-height:1.05; font-size:17px;
  font-weight:800; letter-spacing:.3px; text-transform:uppercase; min-width:0}
.cxd-marque .cxd-m1{color:#fff}
.cxd-marque .cxd-m2{color:var(--cxd-or-clair)}
.cxd-x{border:0; background:none; color:rgba(255,255,255,.72); display:flex; padding:8px; border-radius:12px}
.cxd-nav{display:flex; flex-direction:column; gap:0}
.cxd-item{
  display:flex; align-items:center; gap:14px; width:100%; min-height:46px; padding:12px 14px;
  border:0; border-radius:14px; background:none;
  color:rgba(255,255,255,.9); font-family:inherit; font-size:15px; font-weight:500; text-align:left;
}
.cxd-item svg{flex:none; width:22px; height:22px; stroke:var(--cxd-or); stroke-width:1.6}
.cxd-item.on{background:rgba(255,255,255,.09); color:#fff}
.cxd-item.on svg{stroke:var(--cxd-or-clair)}
.cxd-lang{margin-top:12px; display:flex; gap:0; background:var(--surface); border-radius:999px; padding:3px}
.cxd-lang svg{display:none}
.cxd-lang .cx-lang-b{
  flex:1; border:0; background:transparent; border-radius:999px; padding:6px 0;
  font-family:inherit; font-size:13px; font-weight:600; color:var(--cxd-encre);
}
.cxd-lang .cx-lang-b.on{background:var(--cxd-lang-2); box-shadow:0 1px 2px rgba(3,8,27,.12)}
.cxd-pied{margin-top:12px; border:1px solid var(--cxd-ligne); border-radius:16px; padding:12px; background:rgba(255,255,255,.045)}
.cxd-pied p{margin:0 0 10px; font-size:13px; line-height:1.35; color:rgba(255,255,255,.72)}
.cxd-btns{display:flex; gap:10px}
.cxd-btn{
  flex:1; border-radius:999px; padding:10px 6px; font-family:inherit; font-size:13.5px; font-weight:600;
  border:1px solid rgba(255,255,255,.3); background:transparent; color:#fff;
}
.cxd-btn.plein{background:var(--cxd-cta); border-color:var(--cxd-cta)}
/* En mode clair le tiroir garde son fond de NUIT : c'est un panneau, pas la page. */
:root[data-theme="light"] .cxd, :root[data-theme="light"] .cxd-fond{color-scheme:dark}


/* =====================================================================
   ACCUEIL CLIENT — FORME DE LA REFERENCE (11/11/2026, capture
   site.ldmservice.com/client) : barre du haut BLEU NUIT arrondie en bas,
   marque centree (premier mot en OR), tuiles blanches a icone ronde,
   carte « nos bookmakers partenaires », barre du bas a cinq entrees avec
   l'entree active en OR et son trait.
   Teintes : les jetons du tiroir (--cxd-*), releves dans leur feuille.
   ===================================================================== */
body.client-app .topbar{ background:var(--cxd-panneau); border-radius:0 0 26px 26px; }
body.client-app .cx-top{ position:relative; justify-content:center; }
body.client-app .cx-top #cxd-burger{ position:absolute; left:0; top:50%; transform:translateY(-50%); }
body.client-app .cx-top .cx-actions{ position:absolute; right:0; top:50%; transform:translateY(-50%); }
body.client-app .cx-brand{ justify-content:center; }
body.client-app .cx-name{ display:none; }
.cxf-marque{
  /* 08/11/2026 : le titre N'A PAS ete agrandi (le proprietaire voulait le
     PANNEAU de l'en-tete plus grand, « pas l ecriture ») : retour a 15,5 px et a
     la largeur utile d'origine. C'est `body.client-app .topbar` qui grandit. */
  font-size:15.5px; font-weight:800; letter-spacing:.3px; text-transform:uppercase;
  color:var(--on-brand); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  max-width:44vw; display:inline-block; vertical-align:middle;
}
.cxf-marque .cxf-or{ color:var(--cxd-or-clair); }
body.client-app .cx-logo{ display:none; }

/* Le logo fourni porte son propre fond bleu nuit : la barre prend EXACTEMENT
   cette teinte pour que l'image ne montre pas de rectangle. */
body.client-app .topbar{ background: var(--cxf-nuit-logo); }
body.client-app .cx-brand{ background: transparent; border: 0; padding: 0; }
.cxf-logo-img{ display: block; height: 44px; width: auto; max-width: 70vw; }

/* En-tete de la capture : les commandes sont des ICONES NUES, sans rond ni
   filet (les trois cercles blancs de la capture du client venaient de la). */
body.client-app .cx-top .cx-ico{ border:0; background:transparent; color:rgba(255,255,255,.92); border-radius:12px; }
body.client-app .cx-top .cx-avatar{ border:0; background:rgba(255,255,255,.14); color:var(--on-brand); }

/* barre du bas — cinq entrees, l'active en or */
.cxf-bar{
  position:fixed; left:0; right:0; bottom:0; z-index:45;
  display:flex; align-items:stretch; gap:2px;
  padding:8px 6px calc(env(safe-area-inset-bottom,0px) + 8px);
  background:var(--cxd-panneau); border-radius:26px 26px 0 0;
}
.cxf-bar .item{
  flex:1; display:flex; flex-direction:column; align-items:center; gap:5px;
  padding:6px 2px; border:0; background:none; border-radius:16px;
  color:rgba(255,255,255,.72); font-family:inherit; font-size:11px; font-weight:600;
}
.cxf-bar .item svg{ width:23px; height:23px; stroke:currentColor; }
.cxf-bar .item span{ display:inline; }
.cxf-bar .item.active{ background:transparent; color:var(--cxd-or-clair); padding:6px 2px; }
.cxf-bar .item.active::after{
  content:""; display:block; width:22px; height:3px; margin-top:-2px;
  border-radius:3px; background:var(--cxd-or);
}
body.client-app .app-shell{ padding-bottom:calc(env(safe-area-inset-bottom,0px) + 84px); }

/* tuiles blanches a icone ronde */
.cxf-tuiles{ display:grid; grid-template-columns:repeat(3,1fr); gap:7px; margin-top:9px; }
.cxf-tuile{
  background:var(--surface); border-radius:14px; padding:8px 4px 7px;
  display:flex; flex-direction:column; align-items:center; gap:5px;
  border:0; font-family:inherit; text-align:center;
}
.cxf-tuile .cxf-rond{ width:34px; height:34px; border-radius:50%; display:grid; place-items:center; }
.cxf-tuile .cxf-rond svg{ width:17px; height:17px; stroke:var(--on-brand); }
.cxf-tuile .cxf-lib{ font-size:10.5px; font-weight:600; line-height:1.1; color:var(--slate-900); }
.cxf-rond.or{ background:var(--cxd-or); }
.cxf-rond.bleu{ background:var(--cxd-cta); }

/* carte « nos bookmakers partenaires » */
.cxf-bm{ margin-top:14px; border:1px solid var(--slate-200); border-radius:22px; padding:16px 14px 14px; background:var(--surface); }
.cxf-bm-tete{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:12px; }
.cxf-bm-t{ font-size:15px; font-weight:700; color:var(--slate-900); }
.cxf-bm-tout{ font-size:13px; font-weight:700; color:var(--amber-700); background:none; border:0; font-family:inherit; }
.cxf-bm-row{ display:flex; gap:14px; overflow-x:auto; padding-bottom:4px; }
.cxf-bm-item{ flex:none; width:78px; display:flex; flex-direction:column; align-items:center; gap:7px; background:none; border:0; font-family:inherit; }
.cxf-bm-item .logo, .cxf-bm-item img{ width:56px; height:56px; border-radius:14px; object-fit:contain; }
.cxf-bm-nom{ font-size:11.5px; font-weight:600; color:var(--slate-600); }

/* cartes d'action : icone dans un carre arrondi, comme la reference */
body.client-app .cx-act{ border-radius:20px; padding:16px 14px; align-items:flex-start; }
body.client-app .cx-act-ico{ width:44px; height:44px; border-radius:14px; display:grid; place-items:center; background:rgba(0,0,0,.18); }
body.client-app .cx-act-t{ font-size:20px; font-weight:800; }

/* =====================================================================
   EN-TETE CLIENT — FORME DE LA CAPTURE DU 08/11/2026 (BOZO SERVICE)
   Barre BLEUE pleine largeur ; les commandes sont des CARRES arrondis
   cercles (filet blanc translucide) ; la marque est posee dans une
   PASTILLE BLANCHE au centre, logo a gauche et nom sur DEUX LIGNES.
   TEINTE DE LA BARRE : celle de la CAPTURE, `#0E609C`, relevee au pixel
   (`--cx-entete`). Le 08/11/2026 le proprietaire a demande de « corriger la
   couleur de l'en-tete » : la barre prenait `--brand-600` (#143C72), donc la
   MEME teinte que la carte Depot, et l'en-tete ne se detachait plus.
   Premier mot `--brand-700`, second mot `--slate-500`.
   Mesures relevees sur la capture (1272 px de large pour 424 px de page,
   echelle 3) : barre 75 px, carres 44 px de cote (rayon 14), pastille 37 px.
   Ce bloc vient APRES les regles du 01/10 et du 13/10 : a specificite egale,
   la derniere gagne — ne pas le deplacer vers le haut de la feuille.
   ===================================================================== */
body.client-app .topbar{
  background: var(--cx-entete);
  /* 08/11/2026 : « arrondit l entete » — meme rayon (26 px) et meme geste que la
     barre du bas, qui est arrondie en HAUT : l'en-tete l'est en BAS, pleine
     largeur. Les deux barres se repondent. */
  border: 0; border-radius: 0 0 26px 26px; box-shadow: none;
  margin: 0; top: 0;
  padding: calc(15px + env(safe-area-inset-top, 0px)) 10px 15px;
}
/* Disposition de la capture : burger a gauche, ONGLET DE MARQUE juste a sa
   droite (il n'est plus centre), puis les commandes poussees au bord droit. */
body.client-app .cx-top{ justify-content: flex-start; gap: 10px; }
body.client-app .cx-top #cxd-burger{ position: static; transform: none; }
/* 08/11/2026 — « corrige l en-tete » : les trois carres de droite (lune, cloche,
   initiale) etaient ROGNES EN HAUT, coupes par le bord de la barre. La regle du
   01/10 (ligne ~5270) les placait en absolu avec `top:50%` ET
   `transform:translateY(-50%)` ; en repassant en flux (`position: static`), le
   `top` tombe mais le `transform`, lui, RESTE : la rangee remontait d'une
   demi-hauteur (22 px sur 44) et sortait de la barre. Le burger, corrige le meme
   jour, portait deja son `transform: none` — les commandes l'avaient oublie.
   Ne pas retirer ce `transform: none` : il est le correctif. */
body.client-app .cx-top .cx-actions{ position: static; margin-left: auto; transform: none; }
body.client-app .cx-top #cxd-burger,
body.client-app .cx-top .cx-ico,
body.client-app .cx-top .cx-avatar{
  width: 44px; height: 44px; border-radius: 14px;
  border: 1px solid rgba(255,255,255,.45);
  background: transparent; color: #fff;
  align-items: center; justify-content: center;
}
body.client-app .cx-top .cx-ico{ padding: 0; }
body.client-app .cx-top .cx-ico svg{ width: 22px; height: 22px; stroke-width: 2; }
body.client-app .cx-top .cx-avatar{ font-size: 16px; font-weight: 700; }
body.client-app .cx-brand{ justify-content: center; min-width: 0; }
/* la pastille blanche de la marque */
.cx-mpill{
  display: inline-flex; align-items: center; gap: 8px;
  height: 37px; padding: 0 12px; background: #fff; border-radius: 14px;
  box-shadow: 0 6px 14px -10px rgba(3, 8, 27, .5);
}
.cx-mpill-logo{ width: 24px; height: 24px; display: block; border-radius: 6px; }
.cx-mpill-txt{ display: flex; flex-direction: column; line-height: 1.02; min-width: 0; }
.cx-mpill-1{ font-size: 14px; font-weight: 800; letter-spacing: .2px;
  text-transform: uppercase; color: var(--brand-700); }
.cx-mpill-2{ font-size: 11.5px; font-weight: 800; letter-spacing: .2px;
  text-transform: uppercase; color: var(--slate-500); }


/* =====================================================================
   TEXTES LONGS EN ANGLAIS (11/11/2026) — « en mode anglais les ecritures
   debordent ». Les libelles anglais sont plus longs que les francais
   (« Withdrawal », « Applications bookmakers », « Our partner bookmakers ») :
   dans une rangee souple, un texte sans ces regles POUSSE la rangee et sort de
   l'ecran. Chaque zone de texte d'une rangee flexible prend donc min-width:0
   (sinon le minimum du texte gagne) et coupe proprement.
   ===================================================================== */
body.client-app .cx-act-t, body.client-app .cx-act-s{ min-width:0; }
body.client-app .cx-act-s{ overflow-wrap:anywhere; }
.cxd-item span{ min-width:0; overflow-wrap:anywhere; }
.cxd-marque{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bottomnav .item span{
  max-width:100%; min-width:0; white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis; font-size:clamp(9px, 2.5vw, 11px);
}
.cxf-tuile .cxf-lib{ min-width:0; overflow-wrap:anywhere; }
.cxf-bm-t{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cxf-bm-tout{ flex:none; white-space:nowrap; }
.cxf-bm-nom{ max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
body.client-app .cx-acc-row span{ min-width:0; overflow-wrap:anywhere; }
body.client-app .btn{ overflow-wrap:anywhere; }

/* 11/11/2026 : plus d'icone dans les deux cartes — le rembourrage compense.
   (Regle posee HORS de :root : la premiere fois elle avait ete inseree DANS le
   bloc des jetons, ce qui tronquait la lecture des variables.) */
body.client-app .cx-act{ padding:18px 16px; }

/* ---- RACCOURCIS DE L'ACCUEIL, PLUS VISIBLES (08/11/2026) ------------------
   « Fait que sa soit plus visible » : les deux pilules (Mes IDs / Parrainage)
   etaient un simple FILET gris sur le fond de page (bord `--slate-200`, fond
   transparent) et se lisaient comme du texte. Elles deviennent de vraies
   pastilles : fond blanc franc, filet bleu plus present, libelle a la couleur
   de la maison et en gras, ombre courte pour les decoller du fond. La FORME ne
   bouge pas (rayon, hauteur, ordre) : seuls le contraste et la teinte.
   Ne pas repasser le fond en transparent : c'est ce qui les rendait invisibles. */
body.client-app a.cx-racc-a {
  background: var(--surface);
  border: 1.5px solid rgba(20, 60, 114, .24);
  color: var(--brand-800);
  font-size: 14px; font-weight: 700;
  box-shadow: 0 10px 20px -16px rgba(20, 60, 114, .65);
}
body.client-app a.cx-racc-a svg { color: var(--brand-600); stroke-width: 2; }
:root[data-theme="dark"] body.client-app a.cx-racc-a {
  background: rgba(255, 255, 255, .06);
  border-color: rgba(255, 255, 255, .34);
  color: #fff;
  box-shadow: none;
}

/* =====================================================================
   ETAPES, CHAMPS ET BOUTONS « PILULE » (11/11/2026, capture du client) :
   cercles numerotes relies par des tirets, etape courante cernee avec halo ;
   champs arrondis en pilule ; boutons en pilule avec fleche.
   ===================================================================== */
/* 08/11/2026 (capture du client : le trait s'arretait au milieu de la carte,
   laissant un grand vide a droite) : l'etape 1 reste au bord gauche, la
   derniere au bord droit, et le trait REMPLIT l'espace entre les deux. */
body.client-app .stepbar{ display:flex; align-items:center; justify-content:space-between; gap:0; padding:10px 0 18px; }
body.client-app .stepbar .s{ display:flex; align-items:center; justify-content:center; position:relative; flex:0 0 auto; }
body.client-app .stepbar .s .n{
  width:40px; height:40px; border-radius:50%; display:grid; place-items:center;
  border:2px solid var(--slate-200); background:var(--surface);
  color:var(--slate-500); font-size:16px; font-weight:700; line-height:1;
}
/* L'ETAPE COURANTE : cercle BLANC, anneau bleu epais et NET, halo regulier
   (11/11/2026 : « un truc en boucle bien visible et net »). Le halo passe par
   box-shadow et non par un ::after en z-index:-1, qui se perdait sous le fond. */
body.client-app .stepbar .s.on .n{
  background:var(--surface); border:2.5px solid var(--cxf-etape); color:var(--cxf-etape);
  box-shadow:0 0 0 7px var(--cxf-etape-halo);
}
body.client-app .stepbar .s.on .n::after{ content:none; }
body.client-app .stepbar .s.done .n{
  background:var(--surface); border:2.5px solid var(--cxf-etape); color:var(--cxf-etape);
}
body.client-app .stepbar .s.done .n svg{ stroke:var(--cxf-etape); }
body.client-app .stepbar .c{ flex:1 1 auto; max-width:none; height:5px; min-width:14px; border-radius:3px; background:var(--slate-300); margin:0 10px; }

/* champs : pilule, 56 px de haut, chevron a droite pour les listes */
body.client-app .dp-form .input, body.client-app .dp-form .select,
body.client-app .input, body.client-app .select{
  border-radius:999px; min-height:52px; padding-left:18px; padding-right:18px;
  border:1px solid var(--slate-200); background:var(--surface); font-size:15px;
}
body.client-app select.select{ padding-right:44px; }
body.client-app textarea.input{ border-radius:18px; min-height:96px; padding:14px 16px; }
/* titres de section des assistants : gros libelle, casse normale (comme la capture) */
/* 11/11/2026 (« la taille de l'ecriture n'est pas conforme au system ») : les
   libelles de section reviennent a l'echelle MAISON des `.label` (12,5 px, 700)
   — les 20 px de la capture etaient plus gros que partout ailleurs. */
body.client-app .dp-form .label, body.client-app .dp-section .label{
  font-size:12.5px; font-weight:700; text-transform:none; letter-spacing:.01em;
  color:var(--slate-600); margin:0 0 8px;
}
/* boutons en pilule, avec fleche */
body.client-app .btn{ border-radius:999px; }
body.client-app .dp-continuer{ position:relative; padding-right:52px; }
body.client-app .dp-continuer::after{
  content:"\2192"; position:absolute; right:22px; top:50%; transform:translateY(-50%);
  font-size:20px; line-height:1;
}
/* (.dp-back est le rond du haut : il porte DEJA son chevron retourne —
   ne pas y ajouter de fleche CSS, elle se doublerait.) */

/* 11/11/2026 (capture « Joueur vérifié ») : l'encadre vert se lit en COLONNE —
   titre avec la coche, puis « Nom : … » et « ID : … » sur deux lignes. */
body.client-app .idcheck{ align-items:flex-start; flex-direction:column; gap:6px; }
body.client-app .idcheck .idc-tete{ display:flex; align-items:center; gap:9px; }
body.client-app .idcheck .idc-ico{ width:24px; height:24px; }
body.client-app .idcheck .idc-name{ color:var(--emerald-700); font-size:15px; font-weight:700; letter-spacing:0; }
body.client-app .idcheck .idc-ligne{ font-size:14.5px; color:var(--slate-900); line-height:1.35; }

/* =====================================================================
   PARCOURS DEPOT / RETRAIT — forme de la capture (11/11/2026, « oui fait ») :
   PAGE bleu nuit, TITRE en blanc dessus, et le formulaire dans une grande
   CARTE BLANCHE (rayon 26 px). Les blocs internes perdent leur fond : ils se
   lisent dans la carte, plus comme des cartes dans la carte.
   ===================================================================== */
body.client-app .dp-page{
  background: var(--cxd-panneau);
  margin: -16px -16px 0;
  padding: 10px 16px calc(26px + env(safe-area-inset-bottom));
  max-width: none;
  border-radius: 0 0 26px 26px;
}
body.client-app .dp-titre{ color: var(--on-brand); }
body.client-app .dp-page .dp-back{ background: rgba(255,255,255,.12); color: var(--on-brand); }
body.client-app .dp-page .dp-back:active{ background: rgba(255,255,255,.22); }
body.client-app .dp-page .dp-form{
  background: var(--surface); border-radius: 26px; padding: 16px 14px 18px;
  box-shadow: 0 24px 48px -30px rgba(3,8,27,.75);
}
body.client-app .dp-page .dp-form .dp-section{
  background: transparent; border: 0; box-shadow: none;
  padding: 0; margin: 0 0 18px; border-radius: 0;
}
body.client-app .dp-page .dp-form .dp-section:last-of-type{ margin-bottom: 14px; }
body.client-app .dp-page .dp-aide-ligne{ margin-top: 10px; }
body.client-app .dp-page .dp-aide-ligne,
body.client-app .dp-page .dp-aide-ligne a{ color: var(--slate-600); }




/* 11/11/2026 (capture) : le bouton de l'assistant est un APLAT bleu, plus un
   degrade — le degrade venait de `.btn-primary { background-image: var(--grad-cta) }`. */
body.client-app .dp-form .btn-primary{
  background-image: none; background-color: var(--cxf-etape);
  box-shadow: 0 12px 24px -14px rgba(3,8,27,.55);
}
body.client-app .dp-form .stepbar{ padding: 2px 0 16px; }

/* =====================================================================
   LA CARTE DES ASSISTANTS RESTE BLANCHE DANS LES DEUX THEMES (capture du
   client : page bleu nuit + carte blanche). En mode sombre, `--surface` est
   marine : la carte se fondait dans la page et l'encre devenait blanche sur
   blanc. Ici la carte impose son fond ET son encre.
   ===================================================================== */
body.client-app .dp-page .dp-form{ background:var(--cxf-card-bg); color:var(--cxf-card-ink); }
body.client-app .dp-page .dp-form .label,
body.client-app .dp-page .dp-form .hint{ color:var(--cxf-card-ink-2); }
body.client-app .dp-page .dp-form .input,
body.client-app .dp-page .dp-form .select{
  background:var(--cxf-card-bg); color:var(--cxf-card-ink); border-color:var(--slate-200);
}
body.client-app .dp-page .dp-form .input::placeholder{ color:var(--cxf-card-ink-2); }
body.client-app .dp-page .dp-form .dp-montant{ background:var(--slate-100); }
body.client-app .dp-page .dp-form .dp-montant-in{ color:var(--cxf-card-ink); }
body.client-app .dp-page .dp-form .dp-pilule{ background:var(--cxf-card-bg); color:var(--cxf-card-ink); border-color:var(--cxf-card-line); }
body.client-app .dp-page .dp-form .stepbar .s .n{ border-color:var(--cxf-card-line); color:var(--cxf-card-ink-2); background:var(--cxf-card-bg); }
/* etape FAITE : cercle PLEIN bleu + coche blanche (comme la capture) */
body.client-app .dp-page .dp-form .stepbar .s.done .n{ background:var(--cxf-etape); border-color:var(--cxf-etape); color:#fff; }
body.client-app .dp-page .dp-form .stepbar .s.done .n svg{ stroke:#fff; }
body.client-app .dp-page .dp-form .stepbar .c{ background:var(--slate-300); }
body.client-app .dp-page .dp-form .stepbar .s.done + .c{ background:var(--cxf-etape); }

/* Carte blanche des assistants, MEME EN MODE SOMBRE (capture du 11/11/2026) : les
   jetons `--slate-*` basculent la nuit, ce qui noircissait la barre d'etapes, le
   champ Montant et les tuiles « Payer avec » SUR la carte blanche. Ici tout vient
   des jetons de carte, figes. */
body.client-app .dp-page .dp-form .stepbar .c{ background:var(--cxf-card-line); }
body.client-app .dp-page .dp-form .stepbar .s .n{ border-color:var(--cxf-card-line); color:var(--cxf-card-ink-2); }
body.client-app .dp-page .dp-form .dp-montant{ background:var(--cxf-card-soft); border-color:transparent; }
body.client-app .dp-page .dp-form .dp-montant-in{ color:var(--cxf-card-ink); }
body.client-app .dp-page .dp-form .dp-montant-in::placeholder{ color:var(--cxf-card-ink-2); }
body.client-app .dp-page .dp-form .dp-devise{ color:var(--cxf-card-ink-2); }
body.client-app .dp-page .dp-form .dp-tuile{
  background:var(--cxf-card-soft); border-color:var(--cxf-card-line); color:var(--cxf-card-ink);
}
body.client-app .dp-page .dp-form .dp-tuile.on{
  background:var(--cxf-card-bg); border-color:var(--cxf-card-ink); color:var(--cxf-card-ink);
}
body.client-app .dp-page .dp-form .dp-tuile-op{ color:var(--cxf-card-ink-2); }
body.client-app .dp-page .dp-form .dp-pilule{ color:var(--cxf-card-ink); border-color:var(--cxf-card-line); }
body.client-app .dp-page .dp-form .dep-loupe{ background:var(--cxf-card-soft); color:var(--cxf-card-ink-2); }

/* =====================================================================
   DEPOT / RETRAIT — TYPOGRAPHIE ALIGNEE SUR LE RESTE (11/11/2026 : « ecriture
   trop gras et trop grand »). On garde la forme (pilules, carte blanche) et on
   redescend d'un cran : libelles 11,5 px / 600, montant 22 px / 600, boutons
   15 px / 600, title 17 px / 600.
   ===================================================================== */
body.client-app .dp-page .dp-titre{ font-size:17px; font-weight:600; }
body.client-app .dp-form .label, body.client-app .dp-section .label{
  font-size:11.5px; font-weight:600; letter-spacing:.01em; color:var(--cxf-card-ink-2);
}
body.client-app .dp-page .dp-form .hint,
body.client-app .dp-form .hint{ font-size:11.5px; font-weight:400; }
body.client-app .dp-form .dp-montant-in{ font-size:22px; font-weight:600; letter-spacing:-.01em; }
body.client-app .dp-form .dp-devise{ font-size:11px; font-weight:600; }
body.client-app .dp-form .dp-pilule{ font-size:13px; font-weight:600; }
body.client-app .dp-form .dp-tuile-nom{ font-size:13.5px; font-weight:600; }
body.client-app .dp-form .dp-tuile-op{ font-size:11.5px; font-weight:400; }
body.client-app .dp-form .btn{ font-size:15px; font-weight:600; }
body.client-app .dp-form .stepbar .s .n{ font-size:15px; font-weight:600; }

/* MODE SOMBRE (11/11/2026) : deux restes de l'ANCIENNE barre d'etapes dessinaient
   un trait noir sur la carte blanche (`.stepbar .s::before`), et les libelles des
   tuiles prenaient l'encre de nuit (blanc sur blanc). */
body.client-app .stepbar .s::before{ content:none; background:none; }
body.client-app .dp-page .dp-form .dp-tuile .dp-tuile-nom{ color:var(--cxf-card-ink); }
body.client-app .dp-page .dp-form .dp-tuile .dp-tuile-op{ color:var(--cxf-card-ink-2); }
body.client-app .dp-page .dp-form .dp-tuile.on .dp-tuile-nom{ color:var(--cxf-card-ink); }
body.client-app .dp-page .dp-form .dep-loupe{ background:var(--cxf-card-soft); color:var(--cxf-card-ink-2); }

/* Mode nocturne (11/11/2026, « corrige ca ») : la carte etait du MEME marine que
   la page — on ne voyait pas ou elle commencait. Elle prend un marine plus clair,
   un filet et une ombre portee : elle se detache. */
:root[data-theme="dark"] body.client-app .dp-page .dp-form{
  border: 1px solid var(--cxf-card-line);
  box-shadow: 0 28px 60px -34px rgba(0,0,0,.85);
}
:root[data-theme="dark"] body.client-app .dp-page .dp-form .input,
:root[data-theme="dark"] body.client-app .dp-page .dp-form .select{
  border-color: var(--cxf-card-line);
}

/* =====================================================================
   NOIR COMME LE SYSTEME (11/11/2026, « ca doit etre noir comme le system ») :
   en mode nocturne la page, les barres et le tiroir passent au NOIR PUR (#000),
   la carte des assistants a #0A0A0A, les champs #151515 et les traits #2A2A2A.
   Le mode clair garde page claire + carte blanche.
   ===================================================================== */
:root[data-theme="dark"] body.client-app,
:root[data-theme="dark"] body.client-app .topbar,
:root[data-theme="dark"] body.client-app .bottomnav,
:root[data-theme="dark"] body.client-app .dp-page,
:root[data-theme="dark"] .cxd,
:root[data-theme="dark"] .cxf-bar{ background: var(--cxf-noir); }
:root[data-theme="dark"] body.client-app .dp-page .dp-form{ background: var(--cxf-card-bg); }

/* =====================================================================
   HISTORIQUE — forme de la capture (11/11/2026, « exactement comme ca ») :
   page bleu nuit, titre et sous-titre en clair, actualiser en ROND BLANC,
   filtres en pilules (active en OR), cartes BLANCHES a trois temps avec un
   pied « Reçu : Voir / PDF ».
   ===================================================================== */
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;
}
/* 08/11/2026 (« change le background bleu en blanc comme sur l'interface elle
   meme ») : la page de l'historique prend le BLANC de l'interface le jour, et le
   NOIR de la page la nuit (--slate-50), comme l'en-tete et la barre du bas. Les
   encres suivent les jetons qui basculent (--slate-900 / --slate-500) : un titre
   blanc sur fond blanc ne se lirait pas. */
:root[data-theme="dark"] body.client-app .hist-page{ background: var(--slate-50); }
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-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-page .tabs .tab{
  background: var(--surface); color: var(--slate-700); border: 1px solid var(--slate-200);
  border-radius: 999px; padding: 9px 18px; font-weight: 700; font-size: 14.5px;
}
body.client-app .hist-page .tabs .tab.active{
  background: var(--cxd-or); color: var(--cxd-encre); border-color: transparent;
}
body.client-app .hist-page .hist-q .input{ background: var(--surface); }
body.client-app .hist-page .small.muted,
body.client-app .hist-page .empty{ color: var(--slate-500); }

/* la carte d'une operation */
body.client-app .hist-card{
  display: block; background: var(--surface); border: 1px solid var(--slate-200); border-radius: 22px;
  padding: 14px 16px 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: 10px; }
body.client-app .hist-pastilles{ display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
body.client-app .hist-ref{ font-size: 13px; color: var(--slate-500); }
body.client-app .hist-montant{ font-size: 18px; font-weight: 800; white-space: nowrap; }
body.client-app .hist-nom{ margin-top: 8px; font-size: 15.5px; font-weight: 600; color: var(--slate-900); }
body.client-app .hist-meta{ margin-top: 3px; font-size: 13px; color: var(--slate-500); }
body.client-app .hist-code{ margin-top: 6px; font-family: var(--mono); font-size: 13px; color: var(--slate-700); }
body.client-app .hist-pied{
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 12px -16px 0; padding: 10px 16px 12px; border-top: 1px solid var(--slate-100);
}
body.client-app .hist-recu{ display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--slate-500); }
body.client-app .hist-pil{
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--slate-200); background: transparent; color: var(--slate-900);
  border-radius: 999px; padding: 6px 13px; font-family: inherit; font-size: 13px; font-weight: 600;
}
body.client-app .hist-pil:active{ background: var(--slate-100); }

/* ---- HISTORIQUE, structure de la capture (11/11/2026) --------------------
   Tete (titre 28 px + sous-titre), rond Actualiser, trois pilules de filtre,
   liste de cartes blanches. Rien d'autre : l'ecran a ete REECRIT. */
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-titre-page{ font-size:28px; font-weight:800; letter-spacing:-.02em; line-height:1.1; color:var(--slate-900); }
body.client-app .hist-sous{ margin-top:6px; font-size:14px; color:var(--slate-500); line-height:1.3; }
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:11px 22px; font-family:inherit;
  font-size:15px; font-weight:700; background:var(--surface); color:var(--slate-700);
}
body.client-app .hist-pilule.on{ background:var(--cxd-or); color:var(--cxd-encre); border-color:transparent; }
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:15px; font-weight:700;
  background:var(--surface); color:var(--slate-900);
}

/* la tete de l'historique : titre de 28 px (capture) sur le fond nuit */
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{ font-size:28px; font-weight:800; letter-spacing:-.02em; line-height:1.1; }
body.client-app .hist-page .ui-head .ui-s{ margin-top:6px; font-size:14px; color:var(--slate-500); }

/* 11/11/2026 — echelle de l'historique, arretee apres deux passages :
   « reduit la taille » (tout etait trop gros) puis « encore trop petit, fais une
   taille moyenne ». On garde donc une echelle MOYENNE, entre les deux essais, et
   la page nuit occupe la hauteur de l'ecran (le bas restait clair sous la carte). */
body.client-app .hist-page{
  min-height: 100vh;
  padding-bottom: calc(96px + env(safe-area-inset-bottom));
}
body.client-app .hist-titre-page,
body.client-app .hist-page .ui-head .ui-t{ font-size: 25.5px; }
body.client-app .hist-sous,
body.client-app .hist-page .ui-head .ui-s{ margin-top: 5px; font-size: 13.5px; }
body.client-app .hist-pilule{ font-size: 13.5px; padding: 8.5px 16px; }
body.client-app .hist-montant{ font-size: 17px; }
body.client-app .hist-nom{ margin-top: 7px; font-size: 15px; }
body.client-app .hist-meta{ font-size: 12px; }
body.client-app .hist-page .pill,
body.client-app .hist-pastilles .pill{ font-size: 12px; padding: 3px 10px; }
body.client-app .hist-pil{ font-size: 13px; padding: 6.5px 13px; }
body.client-app .hist-pied{ padding-top: 11px; }
body.client-app .hist-card{ padding: 15px; }

/* 11/11/2026 (« c'est toujours grand ») — DERNIER CRAN, plus compact :
   la carte d'historique perd de la hauteur (pastilles et reference sur une
   seule ligne, interlignes serres) et les libelles baissent encore. */
body.client-app .hist-page .ui-head .ui-t,
body.client-app .hist-titre-page{ font-size: 22px; }
body.client-app .hist-page .ui-head .ui-s,
body.client-app .hist-sous{ font-size: 12px; margin-top: 3px; }
body.client-app .hist-pilule{ font-size: 12.5px; padding: 7px 14px; }
body.client-app .hist-card{ padding: 12px; border-radius: 20px; }
body.client-app .hist-pastilles{ flex-wrap: nowrap; overflow: hidden; gap: 6px; }
body.client-app .hist-pastilles .badge{ font-size: 11px; padding: 2.5px 8px; }
body.client-app .hist-ref{ font-size: 11px; }
body.client-app .hist-montant{ font-size: 15.5px; }
body.client-app .hist-nom{ margin-top: 6px; font-size: 13.5px; line-height: 1.25; }
body.client-app .hist-meta{ margin-top: 2px; font-size: 11px; line-height: 1.25; }
body.client-app .hist-pied{ padding-top: 9px; margin-top: 9px; }
body.client-app .hist-recu{ font-size: 11.5px; }
body.client-app .hist-pil{ font-size: 12px; padding: 5px 11px; gap: 5px; }
body.client-app .hist-haut{ gap: 8px; }

/* =====================================================================
   ACCUEIL CLIENT — date + grand « Bonjour », panneau « aucune demande en
   cours », derniers recus (08/11/2026, demande du proprietaire).
   Prefixe `cx-acc-` / `cx-recus` : `.cx-hello` appartient deja au heros du
   VISITEUR (`.cx-hero .cx-hello`), ne pas le reutiliser ici.
   Jetons seulement : `--slate-900` bascule en blanc la nuit, `--surface`
   donne la carte. Aucune couleur en dur, aucun fond blanc fige.
   ===================================================================== */
body.client-app .cx-acc-tete{ padding:2px 2px 14px; }
body.client-app .cx-acc-date{ font-size:12.5px; font-weight:600; letter-spacing:.02em;
  text-transform:capitalize; color:var(--slate-500); }
body.client-app .cx-acc-bonjour{ margin-top:2px; font-size:26px; font-weight:800;
  line-height:1.15; letter-spacing:-.01em; color:var(--slate-900); }

body.client-app .cx-rien{ display:flex; align-items:center; gap:12px;
  background:var(--surface); border:1px solid var(--slate-200); border-radius:18px;
  padding:13px 15px; margin-bottom:16px; }
body.client-app .cx-rien-ico{ width:36px; height:36px; border-radius:50%; flex:0 0 auto;
  display:grid; place-items:center; background:var(--slate-100); color:var(--emerald-600); }
body.client-app .cx-rien-t{ display:block; font-size:14.5px; font-weight:700; color:var(--slate-900); }
body.client-app .cx-rien-s{ display:block; margin-top:1px; font-size:12.5px; color:var(--slate-500); }

body.client-app .cx-recus{ margin:16px 0 4px; padding:4px 14px 8px;
  background:var(--surface); border:1px solid var(--slate-200); border-radius:18px; }
body.client-app .cx-recus-hd{ display:flex; align-items:baseline; justify-content:space-between;
  padding:9px 2px 5px; }
body.client-app .cx-recus-t{ font-size:13px; font-weight:800; color:var(--slate-900); }
body.client-app .cx-recus-a{ font-size:12.5px; font-weight:600; color:var(--brand-600);
  text-decoration:none; }
body.client-app .cx-rec{ display:flex; align-items:center; gap:11px; padding:9px 2px;
  border-top:1px solid var(--slate-100); }
body.client-app .cx-rec-ico{ width:30px; height:30px; border-radius:10px; flex:0 0 auto;
  display:grid; place-items:center; background:var(--slate-100); }
body.client-app .cx-rec-ico.dep{ color:var(--brand-600); }
body.client-app .cx-rec-ico.ret{ color:var(--emerald-600); }
body.client-app .cx-rec-t{ display:block; font-size:13.5px; font-weight:700; color:var(--slate-900); }
body.client-app .cx-rec-s{ display:block; font-size:11.5px; color:var(--slate-500); }


