/* ════════════════════════════════════════════════════════════════════════════
   mib-code.css — la saisie d'un code, la même partout

   Michel : « il serait bien que pour toute demande de code PIN on utilise le
   même design ; un coup on a un clavier, un coup pas de clavier. »

   Il y avait trois façons de demander la même chose, sur six écrans : six
   points avec un pavé, six cases sans pavé, et un champ masqué avec un œil.
   Un agent qui passe du poste au téléphone ne devrait pas avoir à réapprendre.

   Le dessin retenu prend le meilleur des trois :
     • les six CASES, parce qu'on voit où on en est — un champ masqué ne dit
       ni combien de chiffres sont entrés, ni lequel on corrige ;
     • le PAVÉ, parce qu'un poste dédié est souvent un écran tactile sans
       clavier physique, et parce qu'un pouce vise mieux 56 px qu'une case ;
     • l'ŒIL, parce qu'on se trompe, et qu'un code à six chiffres relu une
       seconde vaut mieux qu'un code retapé trois fois.

   Les couleurs, rayons et espacements viennent tous de « design-tokens.css » :
   ce fichier n'invente aucune valeur, il assemble.
   ════════════════════════════════════════════════════════════════════════════ */

.mib-code {
  max-width: 300px;
  margin: 0 auto;

  /* ── Des tailles qui suivent l'écran, et non des seuils ────────────────────
     Première rédaction : des hauteurs fixes (56 px) et deux « @media » à 400 px
     de large et 640 px de haut. La mesure a été sans appel — sur 27 des 36
     combinaisons écran × appareil, le ✓ tombait SOUS la ligne de flottaison :
     il fallait faire défiler pour valider. Sur un iPhone SE (667 px de haut),
     aucun des deux seuils ne se déclenchait, et le pavé gardait sa taille de
     bureau. Sur le poste dédié en 1024×600 — celui de Michel — non plus.

     Un seuil ne connaît que deux mondes ; « clamp » les traverse tous. La
     touche rétrécit continûment avec la hauteur disponible, sans jamais passer
     sous 34 px : en deçà, un pouce ganté ne vise plus. */
  --code-case-h:   clamp(38px, 7.2vh, 56px);
  --code-case-w:   clamp(30px, 8.6vw, 42px);
  --code-touche-h: clamp(34px, 6.6vh, 56px);
  --code-gap:      clamp(4px, 1.1vh, 8px);
}

.mib-code__aide {
  font-size: var(--text-xs);
  color: var(--text-3);
  text-align: center;
  margin-bottom: var(--space-3);
}

/* ── Les six cases ───────────────────────────────────────────────────────── */
.mib-code__cases {
  display: flex;
  gap: var(--code-gap);
  justify-content: center;
  margin-bottom: var(--code-gap);
}

.mib-code__case {
  width: var(--code-case-w);
  height: var(--code-case-h);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: clamp(1rem, 3.4vh, 1.5rem);
  font-weight: var(--weight-extrabold);
  color: var(--text-4);
  transition: all var(--duration-fast);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .9) inset,
              0 1px 2px rgba(15, 23, 42, .04);
}

/* La case où l'on va écrire. Sans elle, on ne sait plus où on en est dès
   qu'on a effacé un chiffre au milieu. */
.mib-code__case--active {
  border-color: var(--vigil-500);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .9) inset,
              0 0 0 3px rgba(16, 185, 129, .15);
}

.mib-code__case--pleine {
  color: var(--vigil-700);
  border-color: var(--vigil-300);
  background: var(--vigil-50);
}

/* Un code refusé se voit AVANT de se lire : l'écran secoue, puis se vide. */
@keyframes mib-code-refus {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-7px); }
  40%      { transform: translateX(7px); }
  60%      { transform: translateX(-4px); }
  80%      { transform: translateX(4px); }
}
.mib-code__cases--refus { animation: mib-code-refus .38s ease; }
.mib-code__cases--refus .mib-code__case {
  border-color: var(--danger-300, #fca5a5);
  color: var(--danger-700, #b91c1c);
  background: var(--danger-50, #fef2f2);
}

/* ── L'œil ───────────────────────────────────────────────────────────────── */
.mib-code__oeil {
  display: block;
  margin: 0 auto var(--space-3);
  background: none;
  border: 0;
  cursor: pointer;
  font: var(--weight-semibold, 600) var(--text-xs) var(--font-body, inherit);
  color: var(--text-3);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  margin-bottom: var(--code-gap);
}
.mib-code__oeil:hover { color: var(--text-1); background: var(--neutral-50); }

/* ── Le pavé ─────────────────────────────────────────────────────────────── */
.mib-code__pave {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--code-gap);
  max-width: 260px;
  margin: 0 auto var(--code-gap);
}

.mib-code__touche {
  padding: 0;
  min-height: var(--code-touche-h);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-default);
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: clamp(.95rem, 3vh, 1.3rem);
  color: var(--text-1);
  background: #fff;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .9) inset,
              0 2px 6px -1px rgba(15, 23, 42, .08),
              0 1px 3px -1px rgba(15, 23, 42, .04);
  transition: all var(--duration-fast);
  /* Un appui long sur tactile sélectionnait le chiffre au lieu de le taper. */
  -webkit-user-select: none; user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.mib-code__touche:hover  { background: var(--neutral-50); border-color: var(--border-strong); transform: translateY(-1px); }
.mib-code__touche:active { transform: scale(.95); }

.mib-code__touche--eff { color: var(--text-2); font-size: 1rem; }

.mib-code__touche--ok {
  background: var(--gradient-primary);
  color: #fff;
  border-color: rgba(255, 255, 255, .15);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .25) inset,
              0 6px 14px -4px rgba(16, 185, 129, .45);
}
.mib-code__touche--ok:hover:not(:disabled) { background: var(--gradient-primary-hover); }
.mib-code__touche--ok:disabled { opacity: .4; cursor: not-allowed; transform: none; }

/* ── Le téléphone couché, et le poste large et bas ───────────────────────────
   En 740×360 — un téléphone tourné, ou un poste embarqué — six cases EMPILÉES
   sur quatre rangées de touches ne tiennent pas, quelle que soit la taille des
   touches : il n'y a pas 360 px de hauteur à distribuer.

   La largeur, elle, est là et ne sert à rien. On met donc le compteur à gauche
   et le pavé à droite. Ce n'est pas un troisième dessin : ce sont les mêmes
   éléments, dans un autre ordre — et c'est précisément ce qu'une mise en page
   doit savoir faire. */
@media (orientation: landscape) and (max-height: 500px) {
  /* La carte doit s'ÉLARGIR autant que le composant s'étale, sinon elle le
     rogne — et un « overflow:hidden » rogne en silence. C'est ce qui est
     arrivé : deux mesures géométriques de suite ont dit vert pendant que la
     troisième colonne du pavé, ✓ compris, était coupée par le bord de la
     carte. La capture d'écran, elle, ne mentait pas. */
  body.ecran-code .auth-card,
  body.ecran-code .card,
  body.ecran-code .carte {
    max-width: min(96vw, 680px) !important;
    width: 100% !important;
  }
  .mib-code {
    width: 100%;
    max-width: 100%;
    display: grid;
    /* « minmax(0,1fr) » et non « 1fr » : sans le zéro, la colonne des cases
       refuse de descendre sous sa taille naturelle et écrase le pavé — on a
       vu des touches de 28 px de large, joignables et pourtant inratables
       à rater. C'est le compteur qui cède, jamais le clavier. */
    grid-template-columns: minmax(0, 1fr) 174px;
    grid-template-areas: 'compteur pave';
    align-items: center;
    gap: var(--space-4);
  }
  /* Sept pixels manquaient encore sur un téléphone couché : l'aide, qui
     répète ce que les six cases montrent déjà, cède sa ligne. */
  .mib-code__aide  { display: none; }
  .mib-code__cases { grid-area: compteur; align-self: center; }
  /* L'œil cède aussi : sur un téléphone couché, on le retrouve en le
     redressant, et le ✓ vaut mieux que lui. */
  .mib-code__oeil  { display: none; }
  .mib-code__pave  { grid-area: pave; margin: 0; width: 174px; max-width: none; }
  /* Là, c'est la LARGEUR qui est abondante : les touches reprennent de la
     hauteur au lieu de suivre celle, très courte, de l'écran. */
  .mib-code { --code-touche-h: clamp(26px, 9.6vh, 35px); --code-case-h: clamp(30px, 11vh, 40px);
              --code-case-w: clamp(22px, 4.6vw, 34px); --code-gap: 4px; }
  .mib-code__cases { min-width: 0; }
}

/* ── La variante sombre ──────────────────────────────────────────────────────
   « rondier-login » porte une carte volontairement sombre. Michel, en la
   demandant : « cet écran-là ne se regarde pas au bureau — le rondier l'ouvre
   dans un couloir de service à deux heures du matin, souvent avec des gants. »
   Une carte blanche pleine lumière l'éblouit.

   Le composant clair y serait illisible. Plutôt qu'un second dessin — ce qui
   nous ramènerait au problème qu'on vient de résoudre — c'est le MÊME
   composant, avec sa palette retournée. Les formes, les tailles, les gestes et
   le code ne changent pas.
   ───────────────────────────────────────────────────────────────────────── */
.mib-code--sombre .mib-code__aide { color: rgba(255, 255, 255, .70); }

/* Michel, en voyant la première version : « c'est joli mais sombre en général ;
   on peut peut-être mettre des touches de clavier grises pour trancher, et le
   champ agent et le code aussi — ça cassera cet aspect très sombre. »

   Il a raison, et pas seulement pour l'œil : sur une carte uniformément sombre,
   RIEN ne dit ce qui se touche et ce qui se lit. Des touches translucides sur
   fond translucide, c'est du camouflage. Un vrai pavé de clavier est clair sur
   son boîtier — c'est même ainsi qu'on le repère sans le regarder.

   La carte reste donc de nuit ; ce qu'on touche remonte à la lumière. */
.mib-code--sombre .mib-code__case {
  background: #E2E8F0;
  border-color: #CBD5E1;
  color: #94A3B8;
  box-shadow: 0 2px 6px -2px rgba(0, 0, 0, .45);
}
.mib-code--sombre .mib-code__case--active {
  border-color: var(--vigil-500, #10b981);
  box-shadow: 0 0 0 3px rgba(16, 185, 129, .45), 0 2px 6px -2px rgba(0, 0, 0, .45);
}
.mib-code--sombre .mib-code__case--pleine {
  background: #fff;
  border-color: var(--vigil-400, #34d399);
  color: var(--vigil-700, #047857);
}
.mib-code--sombre .mib-code__cases--refus .mib-code__case {
  background: #FEE2E2;
  border-color: #F87171;
  color: #B91C1C;
}

.mib-code--sombre .mib-code__oeil { color: rgba(255, 255, 255, .62); }
.mib-code--sombre .mib-code__oeil:hover {
  color: #fff;
  background: rgba(255, 255, 255, .12);
}

/* Les touches : grises et pleines, comme celles d'un clavier posé sur le
   bureau. Le chiffre est sombre sur clair — c'est le sens de lecture le plus
   sûr à deux heures du matin, et le seul qui tienne avec des gants. */
.mib-code--sombre .mib-code__touche {
  background: linear-gradient(180deg, #F1F5F9 0%, #CBD5E1 100%);
  border-color: #94A3B8;
  color: #0F172A;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .8) inset,
              0 3px 8px -2px rgba(0, 0, 0, .50);
}
.mib-code--sombre .mib-code__touche:hover {
  background: linear-gradient(180deg, #FFFFFF 0%, #E2E8F0 100%);
  border-color: #CBD5E1;
}
.mib-code--sombre .mib-code__touche--eff { color: #334155; }

/* Le ✓ garde le vert de la charte : c'est le seul geste qui engage, il ne doit
   pas se confondre avec les dix qui ne font que compter. */
.mib-code--sombre .mib-code__touche--ok {
  background: var(--gradient-primary);
  border-color: rgba(255, 255, 255, .30);
  color: #fff;
  box-shadow: 0 1px 0 rgba(255, 255, 255, .25) inset,
              0 6px 16px -4px rgba(16, 185, 129, .60);
}
.mib-code--sombre .mib-code__touche--ok:disabled { opacity: .45; }

/* La saisie réelle : hors de l'écran, mais dans le document — c'est elle qui
   reçoit le clavier physique, le collage et le clavier numérique du
   téléphone. Ni « display:none » ni « hidden », qui la rendraient
   infocusable. */
.mib-code__vraie-saisie {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 1px; height: 1px;
  left: -9999px;
}

/* ════════════════════════════════════════════════════════════════════════════
   L'ÉCRAN QUI PORTE LE COMPOSANT

   Michel : « travaille le responsive pour que tout passe correctement. »

   La mesure, sur six écrans × six tailles d'appareil : sur 27 combinaisons
   sur 36, le ✓ tombait SOUS la ligne de flottaison. Il fallait faire défiler
   pour valider un code — y compris sur le poste dédié en 1024×600.

   Rendre le composant plus petit n'a corrigé qu'UNE situation sur 27. La
   mesure suivante a dit pourquoi : sur « login-formateur », en 375×667, le
   composant tient dans 300 px et l'habillage en prend 533. Le seul bandeau de
   marque en occupe 243 — et il affiche le logo MIBsoft DEUX fois, l'image
   puis la pastille. On corrigeait le mauvais tiers de la page.

   D'où ces règles, portées par « body.ecran-code » : elles ne s'appliquent
   qu'aux six écrans qui demandent un code, et seulement quand la hauteur
   manque. Sur une tablette ou un bureau, rien ne change.
   ════════════════════════════════════════════════════════════════════════════ */

@media (max-height: 800px) {
  /* Le logo est une signature, pas un titre : il rétrécit avec la place. */
  body.ecran-code .brand-logo,
  body.ecran-code .logo:not(.logo-icon) {
    width: clamp(96px, 17vh, 200px) !important;
    margin-bottom: var(--space-2) !important;
  }
  body.ecran-code .logo-wrap { margin-bottom: var(--space-3) !important; }

  /* La pastille ronde répète le logo déjà affiché au-dessus. Deux fois la même
     marque, 64 px de haut, sur un écran où le ✓ ne tient pas. */
  body.ecran-code .logo-wrap .brand-logo ~ .logo-icon { display: none !important; }

  body.ecran-code .auth-card,
  body.ecran-code .card,
  body.ecran-code .carte { padding: var(--space-5) var(--space-5) !important; }

  body.ecran-code .logo-title { font-size: var(--text-lg) !important; }
  body.ecran-code .auth-prompt { margin-bottom: var(--space-2) !important; }

  /* Une boîte d'erreur vide occupait sa hauteur en permanence sur les écrans
     Patrol : 71 px réservés à un message qui n'existe pas encore. */
  body.ecran-code .err:empty { display: none !important; }
}

@media (max-height: 680px) {
  body.ecran-code .logo-wrap,
  body.ecran-code > .wrap > .logo,
  body.ecran-code .card > .logo { display: none !important; }
  body.ecran-code .logo-sub,
  body.ecran-code .subtitle { display: none !important; }
  body.ecran-code .auth-card,
  body.ecran-code .card,
  body.ecran-code .carte { padding: var(--space-4) !important; }
  body { padding: var(--space-2) !important; }
}

/* Le téléphone couché reste le cas le plus dur : 360 px de haut pour un titre,
   un champ « agent », le code et le pavé. La mise en page du composant passe
   déjà en deux colonnes ; ce qui le SURMONTE doit maigrir d'autant. */
@media (orientation: landscape) and (max-height: 500px) {
  body.ecran-code .titre,
  body.ecran-code .card > h1,
  body.ecran-code .carte h1,
  body.ecran-code .logo-title {
    font-size: var(--text-base) !important;
    margin-bottom: var(--space-1) !important;
  }
  body.ecran-code .champ,
  body.ecran-code .input,
  body.ecran-code select { padding: 7px 12px !important; }
  body.ecran-code .lbl,
  body.ecran-code .field-label { margin-bottom: 2px !important; }
  body.ecran-code .bloc { margin-bottom: var(--space-2) !important; }
  body.ecran-code .auth-card,
  body.ecran-code .card,
  body.ecran-code .carte { padding: var(--space-2) !important; }
  body.ecran-code { padding: 4px !important; }
  body.ecran-code .lbl,
  body.ecran-code .field-label { font-size: 10px !important; letter-spacing: 0 !important; }
  body.ecran-code .org,
  body.ecran-code .subtitle,
  body.ecran-code .logo-sub { display: none !important; }
}
