/* Espace client (frontend/js/client.js). Remplace les styles en ligne qui s'étaient accumulés depuis le
   début du projet — jamais touchés par la refonte L1-L4, qui portait sur la caisse et l'administration.
   Suite du chantier L5 : mêmes briques (js/ui.js), même exigence de « pas de style inline résiduel ».

   Deux familles de classes ci-dessous :
   - des utilitaires à une seule déclaration (mt-*, mb-*, fs-*...), dans le même esprit que les classes
     déjà présentes dans base.css (.muted, .chip...) ;
   - des classes de composant, nommées par ce qu'elles représentent (carte-doree, gain-titre...), pour les
     styles qui n'avaient de sens qu'à un seul endroit précis.
   Les deux ou trois styles qui restent en ligne dans client.js sont des valeurs calculées à l'affichage
   (dégradé de la roue du jeu concours, largeur de la barre de progression des points) — une valeur qui
   change à chaque rendu n'est pas un résidu, c'est la même convention que .progress-fill ailleurs dans
   l'application. */

/* ----- Espacements et texte (utilitaires) --------------------------------------------------------- */
.mt-4{ margin-top:4px; } .mt-6{ margin-top:6px; } .mt-8{ margin-top:8px; }
.mt-10{ margin-top:10px; } .mt-12{ margin-top:12px; } .mt-14{ margin-top:14px; }
.mt-16{ margin-top:16px; } .mt-20{ margin-top:20px; }
.mb-4{ margin-bottom:4px; } .mb-6{ margin-bottom:6px; } .mb-8{ margin-bottom:8px; }
.mb-10{ margin-bottom:10px; } .mb-12{ margin-bottom:12px; } .mb-14{ margin-bottom:14px; }
.mb-16{ margin-bottom:16px; } .mb-24{ margin-bottom:24px; }
.m-0{ margin:0; }
.fs-10{ font-size:10px; } .fs-11{ font-size:11px; } .fs-12{ font-size:12px; } .fs-13{ font-size:13px; }
.fs-15{ font-size:15px; } .fs-16{ font-size:16px; } .fs-22{ font-size:22px; } .fs-26{ font-size:26px; }
.text-center{ text-align:center; }
.color-inherit{ color:inherit; }
.color-red{ color:var(--red); }
.color-ink{ color:var(--ink); }
.w-auto{ width:auto; }
.w-full{ width:100%; }
.nowrap{ white-space:nowrap; }
.op-70{ opacity:.7; }
.gap-8{ gap:8px; }
.d-block{ display:block; }
.d-inline-block{ display:inline-block; }
.d-none{ display:none; }

/* ----- Composants --------------------------------------------------------------------------------- */

/* Bandeau supérieur avant connexion (le logo image le remplace une fois connecté, voir syncTopNavBrand). */
.topnav-soustitre{ display:block; font-size:9px; letter-spacing:.1em; margin-top:1px; }
.topnav-logo{ height:35px; display:block; }
.logo-accueil{ height:64px; margin-bottom:12px; }

/* Carte mise en avant (inscription en cours de vérification, catégorie en attente, points bientôt
   expirés...) : bordure dorée plutôt que la bordure grise par défaut de .card. */
.card-doree{ border-color:#EABA5C; }

/* Libellé au-dessus d'un champ, hors balise <label> (ex. sélecteur de pays + numéro) : même style que
   `label span` dans base.css, pour un champ qui n'est pas un <label> unique. */
.field-label{ display:block; font-size:11px; letter-spacing:.08em; opacity:.65; margin-bottom:4px; }
/* Note d'aide sous un champ, collée dessus (marge négative) pour rester visuellement rattachée à lui. */
.field-hint{ font-size:11px; margin:-6px 0 14px; }
.field-hint-tight{ font-size:11px; margin:-8px 0 12px; }
.field-hint-loose{ font-size:11px; margin:4px 0 14px; }

/* Case à cocher + texte sur la même ligne (avis Google, consentement marketing). */
.checkbox-row{ display:flex; align-items:center; gap:8px; text-align:left; }
/* Variante mise en valeur pour le consentement marketing, en écho discret à la couleur de la marque. */
.consent-row{ display:flex; align-items:center; gap:8px; background:rgba(232,29,33,.06); padding:10px; border-radius:4px; }

/* Bouton « JOUER » du jeu concours, en rouge contour pour le distinguer des autres boutons de la page. */
.btn-contest{ border-color:var(--red); color:var(--red); }

/* Numéro de téléphone affiché en lecture seule (à côté du bouton « modifier »). */
.phone-disabled{ opacity:.7; flex:1; }

/* Titre d'un résultat de confirmation (inscription au tirage au sort, changement de numéro...). */
.titre-confirmation{ font-size:16px; font-weight:700; margin-bottom:8px; }

/* Solde de points en gros, en tête de la carte de fidélité. */
.points-chiffre{ font-size:32px; font-weight:700; color:var(--red); line-height:1; }

/* Nom de la catégorie, mis en valeur uniquement pour la catégorie VIP (voir renderDashboard). */
.categorie-vip{ color:#EABA5C; font-weight:700; opacity:1; }

/* Annonce d'un gain au jeu concours, et code à présenter en caisse. */
.gain-titre{ font-weight:700; color:#EABA5C; margin-bottom:6px; }
.code-win{ font-family:monospace; font-size:15px; font-weight:700; letter-spacing:1px; margin-top:4px; user-select:all; }
.code-referral{ font-family:monospace; font-size:22px; font-weight:700; letter-spacing:2px; margin-bottom:12px; user-select:all; }

/* Historique des points : vert doré pour un crédit, rouge pour un débit — remplace une couleur calculée
   en JavaScript à chaque ligne par deux classes fixes. */
.tx-points-positif{ color:#EABA5C; font-weight:700; }
.tx-points-negatif{ color:var(--red); font-weight:700; }

/* Statut d'une commande dans « Mes commandes » — même principe que ci-dessus. */
.statut-livree{ color:var(--ink); font-weight:700; }
.statut-a-venir, .statut-attente{ color:var(--red); font-weight:700; }
.statut-annulee{ color:var(--ink); opacity:.55; font-weight:700; text-decoration:line-through; }

/* Ligne de deux boutons Wallet (Apple / Google), alignés aux extrémités de la carte de fidélité. */
.wallet-row{ margin-top:14px; display:flex; gap:12px; align-items:center; justify-content:space-between; }
.wallet-btn{ background:none; border:none; padding:0; cursor:pointer; line-height:0; }
.wallet-btn-left{ text-align:left; }
.wallet-btn-right{ text-align:right; }
.wallet-badge{ height:44px; width:auto; display:block; }

/* Pied de page (mentions légales, copyright) : très discret, sous le reste du contenu. */
.footer-copyright{ text-align:center; margin-top:6px; font-size:10px; opacity:.6; }

/* Message affiché quand une liste est vide (aucune promo de la semaine, etc.). */
.etat-vide{ text-align:center; padding:40px 20px; }

/* Image de promo : pleine largeur de sa carte, coins légèrement arrondis. */
.promo-image{ width:100%; border-radius:4px; display:block; }

/* Ligne avec le solde de points à gauche et le sous-total à droite, alignés sur leur base de texte. */
.row-baseline-mb10{ align-items:baseline; margin-bottom:10px; }

/* ----- Jeu concours : ticket à gratter -------------------------------------------------------------
   Zone tactile fixe (220×120), face imprimée visible avant grattage, canevas de grattage par-dessus. */
.scratch-zone{ position:relative; width:220px; height:120px; margin:0 auto; }
.scratch-face{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  font-weight:700; font-size:15px; padding:10px; background:var(--panel); border:1px solid var(--line);
}
.scratch-canvas{ position:absolute; inset:0; touch-action:none; cursor:pointer; }

/* ----- Jeu concours : roue de la fortune -----------------------------------------------------------
   Zone fixe (220×220) avec un repère fixe en haut ; le disque tourne, sa forme (le dégradé conique) est
   calculée à chaque partie et reste donc en style="" — voir la remarque en tête de fichier. */
.wheel-zone{ position:relative; width:220px; height:220px; margin:0 auto; }
.wheel-pointeur{
  position:absolute; top:-6px; left:50%; transform:translateX(-50%); width:0; height:0;
  border-left:10px solid transparent; border-right:10px solid transparent; border-top:16px solid var(--red);
  z-index:2;
}
.wheel-disc{
  width:220px; height:220px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  color:#fff; font-size:10px; transition:transform 3.5s cubic-bezier(.17,.67,.2,1);
}

/* ===================================================================================================
   Coque de l'espace client — chantier C1 (voir js/client-core.js)
   ===================================================================================================
   L'espace client est un écran unique de 390 px de large dans l'immense majorité des cas. La navigation
   passe donc par une barre d'onglets fixée en bas de l'écran, à portée de pouce, plutôt que par le
   défilement d'une pile de quatorze cartes.

   La barre est en position fixe (et non dans un conteneur en colonne flexible) pour ne rien changer au
   défilement existant du document : le bandeau supérieur reste collant comme avant, le contenu défile
   comme avant, et seul un espace réservé est ajouté sous le contenu pour que la dernière carte ne passe
   jamais dessous. */

.tabbar{
  position:fixed; left:0; right:0; bottom:0; z-index:150;
  display:flex; background:var(--panel); border-top:1px solid var(--line);
  /* Encoche et barre gestuelle des téléphones récents : la barre s'appuie sur la zone sûre, sinon les
     libellés se retrouvent sous la barre d'accueil de l'iPhone. Les marges gauche/droite comptent tout
     autant en mode installé (PWA) : sans elles, les coins arrondis de l'écran rognent les onglets aux
     deux extrémités — `viewport-fit=cover` (index.html) est nécessaire pour que ces valeurs ne soient
     pas silencieusement nulles. */
  padding:0 env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
}
/* Barre vide (hors connexion) : elle ne doit pas laisser un liseré gris en bas de l'écran de connexion. */
.tabbar:empty{ display:none; }

.tab-item{
  flex:1; background:transparent; border:none; color:var(--ink);
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:5px;
  /* Cible tactile confortable dès maintenant ; le passage général à 52 px est l'objet du lot C4. */
  min-height:52px; padding:9px 0 8px; opacity:.55;
}
.tab-item .tab-ic{ font-size:20px; line-height:1; }
.tab-item .tab-lbl{ font-size:11px; letter-spacing:.03em; }
.tab-item.on{ opacity:1; color:var(--red); }

/* Même raisonnement pour le bandeau supérieur et le contenu : en mode PWA installé sur iPhone, les coins
   arrondis de l'écran rognent le texte collé au bord si rien ne s'ajoute au padding habituel. Sans effet
   sur un navigateur classique (l'inset y vaut 0), donc rien ne change hors du mode installé.
   Le bandeau est `position: sticky; top:0` (base.css) : depuis que `viewport-fit=cover` autorise le
   contenu à s'étendre sous l'encoche / l'île dynamique, ce bandeau s'y colle exactement s'il n'a pas sa
   propre marge du haut — c'est le logo caché derrière l'appareil photo au repos (en scrollant, le bandeau
   sticky se plaque normalement contre le haut, ce qui reste attendu ; c'est seulement en haut de page,
   avant tout défilement, que le logo doit rester visible). */
body.client-page .top-nav{
  padding-top:calc(14px + env(safe-area-inset-top, 0px));
  padding-left:calc(20px + env(safe-area-inset-left, 0px));
  padding-right:calc(20px + env(safe-area-inset-right, 0px));
}
body.client-page .container{
  padding-left:calc(20px + env(safe-area-inset-left, 0px));
  padding-right:calc(20px + env(safe-area-inset-right, 0px));
}

/* Espace réservé sous le contenu, égal à la hauteur de la barre plus la zone sûre. Posé sur <body> et non
   sur .container pour rester valable quel que soit l'écran affiché. */
body.a-onglets #app{ padding-bottom:calc(78px + env(safe-area-inset-bottom, 0px)); }
/* Les messages brefs (js/ui.js) remontent au-dessus de la barre d'onglets plutôt que derrière elle —
   même mécanisme que la barre d'action de la caisse, via la variable prévue pour cela dans base.css. */
body.a-onglets{ --toast-bas:calc(90px + env(safe-area-inset-bottom, 0px)); }

/* ===================================================================================================
   Écran « Ma carte » — chantier C2 (voir js/client-carte.js)
   =================================================================================================== */

.carte-entete{ margin-bottom:16px; }

/* ----- Zone d'alerte unique ------------------------------------------------------------------------
   Une seule alerte sur l'accueil, la plus urgente. Bordure dorée comme les anciens bandeaux, mais une
   présentation en ligne (icône à gauche, titre puis explication) au lieu d'une carte pleine : l'alerte ne
   doit jamais repousser le QR hors de l'écran. */
.alerte{
  display:flex; gap:12px; align-items:flex-start;
  border:1px solid #EABA5C; background:#332913; padding:14px 16px; margin-bottom:16px;
  font-size:14px; line-height:1.5;
}
.alerte-ic{ font-size:19px; line-height:1.3; }
.alerte-titre{ display:block; }
.alerte-texte{ display:block; margin-top:3px; opacity:.85; }
/* Mention « données de la dernière connexion » : informative, sans action attendue — donc neutre, pour ne
   pas concurrencer visuellement une vraie alerte affichée juste en dessous. */
.alerte-cache{ border-color:var(--line); background:#2a2a2a; }

/* ----- Carte QR -------------------------------------------------------------------------------------
   Fond blanc plein et large : la marge claire autour du motif fait partie de la spécification du QR, les
   douchettes et caméras le lisent nettement mieux ainsi. */
.carte-qr{ padding:20px; text-align:center; margin-bottom:16px; }
.carte-qr-titre{ font-size:12px; letter-spacing:.08em; opacity:.7; margin:0 0 14px; }
.qr-blanc{
  background:#FFFFFF; border-radius:14px; padding:20px;
  display:flex; align-items:center; justify-content:center;
}
.qr-blanc img, .qr-blanc canvas{ display:block; width:100%; height:auto; max-width:230px; }
.qr-blanc-petit img, .qr-blanc-petit canvas{ max-width:170px; }
/* Repli si la bibliothèque de QR n'a pas pu être chargée : le code reste lisible et saisissable en caisse. */
.qr-secours{
  color:#1C1B19; font-family:monospace; font-weight:700; font-size:20px; letter-spacing:2px;
  word-break:break-all; padding:28px 20px;
}
.carte-astuce{ margin:10px 0 0; font-size:13px; opacity:.6; }

/* ----- Wallet à égalité -----------------------------------------------------------------------------
   Apple et Google occupent exactement la même largeur : aucun des deux n'est poussé plus que l'autre. */
.wallet-egalite{ display:flex; gap:12px; margin-top:18px; }
.wallet-egalite .wallet-btn{ flex:1 1 0; min-width:0; display:flex; justify-content:center; }
.wallet-egalite .wallet-badge{ height:44px; width:auto; max-width:100%; }

/* ----- Deux chiffres sous la carte ------------------------------------------------------------------
   Solde et distance à la prochaine récompense. Ce sont des boutons : ils mènent à l'onglet « Mes points »,
   où se trouvent le détail et le catalogue. */
.carte-chiffres{ display:flex; gap:12px; }
.chiffre{
  flex:1 1 0; min-width:0; background:var(--panel); border:1px solid var(--line); color:var(--ink);
  padding:16px 12px; text-align:center; min-height:52px;
}
.chiffre-v{ display:block; font-size:26px; font-weight:700; color:var(--red); line-height:1; }
.chiffre-v-or{ color:#EABA5C; }
.chiffre-l{ display:block; font-size:13px; opacity:.7; margin-top:6px; line-height:1.3; }

/* ===================================================================================================
   Écran « Mes points » — chantier C3 (voir js/client-points.js)
   =================================================================================================== */

.section-label{ font-size:12px; letter-spacing:.08em; opacity:.7; text-transform:uppercase; margin:20px 0 10px; }
/* Distingue le titre « Historique » de « Mes récompenses » juste au-dessus — même famille de titre, mais
   plus question de confondre un mouvement passé avec une récompense à échanger. */
.section-label-rouge{ color:var(--red); opacity:1; }
.section-label:first-of-type{ margin-top:0; }

/* Solde en grand, seul en tête d'écran. */
.points-solde{ text-align:center; padding:14px 0 20px; }
.points-solde-v{ font-size:56px; font-weight:700; color:var(--red); line-height:1; display:block; }
.points-solde-l{ font-size:14px; opacity:.7; display:block; margin-top:6px; }

/* Récompenses en cartes plutôt qu'en puces — .rew* reprend le nommage retenu sur la maquette validée. */
.rec-carte{
  display:flex; align-items:center; gap:14px; border:1px solid var(--line); background:var(--panel);
  padding:14px 16px; margin-bottom:10px; min-height:52px;
}
.rec-dispo{ border-color:#EABA5C; }
.rec-nom{ flex:1; font-size:15px; }
.rec-nom small{ display:block; font-size:12px; opacity:.6; margin-top:3px; }
.rec-dispo .rec-nom small{ color:#EABA5C; opacity:1; }
.rec-cout{ font-size:14px; font-weight:700; opacity:.7; white-space:nowrap; }
.rec-dispo .rec-cout{ color:#EABA5C; opacity:1; }

/* Historique en liste (remplace le tableau à trois colonnes, illisible sur 390 px) — réutilisé tel quel
   pour la liste des commandes dans « Mon compte ». */
.hist-liste{ list-style:none; margin:0; padding:0; }
.hist-ligne{ display:flex; align-items:center; gap:14px; padding:13px 2px; border-bottom:1px dotted var(--line); }
.hist-ligne:last-child{ border-bottom:none; }
.hist-motif{ flex:1; font-size:14px; }
.hist-motif small{ display:block; font-size:12px; opacity:.55; margin-top:3px; }
.hist-pts{ font-weight:700; font-size:15px; white-space:nowrap; }

/* ===================================================================================================
   Écran « Promos » — léger polish C3 (voir js/client-promos.js)
   =================================================================================================== */
.promo-carte{ padding:14px; }
.promo-carte .promo-image{ border-radius:6px; }

/* ===================================================================================================
   Écran « Mon compte » — chantier C3 (voir js/client-compte.js)
   =================================================================================================== */

/* Lignes d'action de 52 px minimum, une action par ligne — reprend le composant .rowline de la maquette
   validée. Regroupées dans un même bloc pour porter les séparateurs, plutôt qu'une carte par action. */
.rowline-groupe{ border:1px solid var(--line); background:var(--panel); margin-bottom:16px; }
.rowline{
  width:100%; display:flex; align-items:center; gap:14px; min-height:52px; padding:12px 16px;
  background:transparent; border:none; border-bottom:1px dotted var(--line); color:var(--ink);
  font-family:inherit; font-size:15px; text-align:left; cursor:pointer;
}
.rowline-groupe > :last-child{ border-bottom:none; }
.rowline-ic{ width:24px; text-align:center; opacity:.75; flex:0 0 auto; }
.rowline-txt{ flex:1; min-width:0; }
.rowline-txt small{ display:block; font-size:12px; opacity:.6; margin-top:3px; }
.rowline-fleche{ opacity:.4; flex:0 0 auto; }
.rowline-danger .rowline-txt{ color:var(--red); }
/* La ligne Wallet n'est pas cliquable elle-même (ce sont ses deux boutons qui le sont) : pas de curseur
   pointeur ni de chevron, pour ne pas suggérer une troisième action qui n'existe pas. */
.rowline-wallet{ cursor:default; }
.wallet-mini{ display:flex; gap:8px; flex:0 0 auto; }
.wallet-badge-mini{ height:28px; width:auto; }

/* Court squelette au fil du texte (résumé des commandes pendant le chargement). */
.skel-inline{
  display:inline-block; width:120px; height:11px; border-radius:3px; vertical-align:middle;
  background:linear-gradient(90deg, var(--line) 25%, #4a4a4a 37%, var(--line) 63%);
  background-size:400% 100%; animation:skel-balayage 1.3s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce){ .skel-inline{ animation:none; background:var(--line); } }

/* ===================================================================================================
   Connexion, inscription — chantier C4 (voir js/client-auth.js)
   =================================================================================================== */

/* ----- Code SMS en six cases -------------------------------------------------------------------------
   Une case par chiffre, avance automatique à la saisie (voir attacherCasesOtp). `autocomplete="one-time-
   code"` est posé sur la première case : iOS et Android proposent alors le code au-dessus du clavier. */
.otp-cases{ display:flex; gap:8px; justify-content:center; margin-bottom:18px; }
.otp-case{
  width:44px; height:56px; text-align:center; font-size:22px; font-weight:700; padding:0;
  -moz-appearance:textfield;
}
.otp-case::-webkit-outer-spin-button, .otp-case::-webkit-inner-spin-button{ -webkit-appearance:none; margin:0; }
.resend{ text-align:center; font-size:13px; opacity:.65; margin:0; }
.resend .btn-ghost{ font-size:13px; }

/* Lien de texte au fil d'une phrase (« Pas encore de compte ? Créer un compte ») — remplace un second
   bouton pleine largeur identique au premier en tout point (même action, juste un intitulé différent),
   qui donnait deux appels à l'action de même poids visuel pour une seule et même chose. */
.lien-inline{
  background:none; border:none; padding:0; margin:0; font:inherit; color:var(--red);
  text-decoration:underline; cursor:pointer;
}

/* ----- Inscription en trois étapes ------------------------------------------------------------------- */
.reg-steps{ display:flex; gap:8px; justify-content:center; margin-bottom:10px; }
.reg-step-point{ width:8px; height:8px; border-radius:50%; background:var(--line); }
.reg-step-point.on{ background:var(--red); }
.reg-step-label{ text-align:center; font-size:13px; opacity:.6; margin:0 0 18px; }
.navrow{ display:flex; gap:12px; }
.navrow .btn-outline, .navrow .btn-primary{ flex:1; }

/* ----- Invite d'installation (PWA) --------------------------------------------------------------------
   Discrète : pas de couleur d'alerte, pas de carte pleine — une ligne de texte et deux actions, posée en
   bas de l'écran « Ma carte » après quelques visites (voir doitProposerInstallation dans client-core.js). */
.install-invite{ border:1px solid var(--line); padding:14px 16px; margin-top:16px; font-size:13px; }
.install-invite-texte{ margin:0 0 12px; opacity:.85; line-height:1.5; }
.install-invite-actions{ display:flex; gap:10px; align-items:center; justify-content:flex-end; }
.install-invite-actions .btn-outline{ width:auto; min-width:120px; padding:10px 16px; font-size:12px; }

/* ===================================================================================================
   Lisibilité — chantier C4
   ===================================================================================================
   Trois règles, portées par `body.client-page` pour ne rien changer à la caisse ni à l'administration :
     - un plancher de 13 px pour tout texte (les utilitaires fs-10/fs-11/fs-12 remontent à 13 px) ;
     - un contraste relevé pour les textes secondaires (.muted passe de 0,55 à 0,72 d'opacité) ;
     - des cibles tactiles d'au moins 52 px pour les boutons pleine largeur et les champs de saisie.
   Le corps de texte courant (paragraphes sans classe de taille) reste à la taille par défaut du
   navigateur (16 px), déjà conforme — rien à changer de ce côté. */
body.client-page .fs-10, body.client-page .fs-11, body.client-page .fs-12{ font-size:13px; }
body.client-page .muted{ opacity:.72; }
/* Les utilitaires fs-* ne couvrent pas tout : plusieurs classes nommées (étiquettes de champ, notes
   d'aide, pied de page, onglets, en-têtes de section) portaient elles aussi une taille fixe sous le
   plancher. Même règle, appliquée directement plutôt que via une classe utilitaire ici. */
body.client-page .field-label,
body.client-page .field-hint,
body.client-page .field-hint-tight,
body.client-page .field-hint-loose,
body.client-page .footer-copyright,
body.client-page .tab-lbl,
body.client-page .carte-qr-titre,
body.client-page .section-label,
body.client-page .rec-nom small,
body.client-page .hist-motif small,
body.client-page .rowline-txt small,
body.client-page .install-invite-actions .btn-outline{
  font-size:13px;
}
body.client-page .btn-primary, body.client-page .btn-outline{ min-height:52px; display:flex; align-items:center; justify-content:center; }
/* 16px minimum : sous ce seuil, Safari/Chrome iOS zooment automatiquement la page au focus d'un champ
   (accueil connexion, code SMS, inscription en 3 étapes...). Comme le blocage du zoom a été retiré
   volontairement (lot C4, pour laisser le zoom manuel), c'est ce plancher qui évite le zoom intempestif,
   sans rien réempêcher côté visiteur. Les cases du code SMS sont déjà à 22px et donc déjà couvertes. */
body.client-page input, body.client-page select, body.client-page textarea{ min-height:52px; font-size:16px; }
/* Exceptions volontaires, où 52 px casserait la mise en page plutôt que d'aider à la viser :
   les cases du code SMS (déjà 56 px de haut, mais 44 px de large — la largeur n'est pas une cible
   séparée) et les petits boutons Wallet / actions secondaires groupées sur une ligne. */
body.client-page .otp-case{ min-height:0; }
body.client-page .navrow .btn-outline, body.client-page .navrow .btn-primary{ min-height:52px; }
