/* ============================================================================
   BIBLIOTHEQUE UI JABS  -  signature.css
   Depend de : theme.css, buttons.css, forms.css (+ js/signature.js)

   Les champs de code a usage unique d'une signature electronique : le code
   recu par SMS ou par courriel qui vaut consentement. C'est le moment le plus
   fragile du parcours : un signataire qui bute sur le code abandonne, et le
   document reste non signe.

   Quatre regles tenues partout dans ce fichier :
   1. Le collage d'un code complet remplit toutes les cases d'un coup, et
      autocomplete="one-time-code" laisse iOS et Android proposer le code
      recu par SMS au-dessus du clavier.
   2. inputmode="numeric" ouvre le pave numerique. Jamais type="number" :
      il retire les zeros de tete et affiche des fleches.
   3. On dit toujours ou le code est parti (numero ou adresse masques), combien
      de temps il reste valable et comment en recevoir un autre.
   4. Une erreur garde les chiffres saisis visibles et annonce le nombre
      d'essais restants. Vider les cases sans explication fait recommencer a
      l'aveugle.

   Le socle .sig-code + .sig-case est decrit dans SIG-A1 : toutes les autres
   variantes ne sont que des modificateurs.
   ========================================================================= */

/* ===========================================================================
   FAMILLE A  -  STYLES DE CASES
   ======================================================================== */

/* @v SIG-A1
@nom Cases encadrees
@usage Le socle de la categorie et le choix par defaut : six cases bordees, lisibles par tous, sans ambiguite sur le nombre de chiffres attendus.
@html
<div class="champ">
  <label class="champ__label" for="sig-a1">Code de signature</label>
  <div class="sig-code" data-sig>
    <input class="sig-case" id="sig-a1" inputmode="numeric" autocomplete="one-time-code" maxlength="1" value="4" aria-label="Chiffre 1">
    <input class="sig-case" inputmode="numeric" maxlength="1" value="8" aria-label="Chiffre 2">
    <input class="sig-case" inputmode="numeric" maxlength="1" value="2" aria-label="Chiffre 3">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 4">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 5">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 6">
  </div>
  <span class="champ__aide">6 chiffres, envoyes au 06 &bull;&bull; &bull;&bull; &bull;&bull; 56 78</span>
</div>
@tw flex gap-2 [&_input]:h-14 [&_input]:w-12 [&_input]:rounded-lg [&_input]:border [&_input]:text-center [&_input]:text-2xl [&_input]:font-bold [&_input]:tabular-nums focus-within:[&_input:focus]:ring-4
@end */
.sig-code { display: flex; align-items: center; gap: var(--sp-2); max-width: 100%; }
/* La largeur sert de base flexible : dans une colonne etroite les cases
   retrecissent ensemble au lieu de deborder. */
.sig-case {
  flex: 0 1 auto;
  min-width: 30px;
  width: 46px;
  height: 56px;
  padding: 0;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-md);
  background: var(--c-surface);
  color: var(--c-text);
  font-family: var(--font-ui);
  font-size: 22px;
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
  text-align: center;
  caret-color: var(--c-primary);
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background-color var(--t-fast);
}
.sig-case:hover { border-color: var(--c-text-muted); }
.sig-case:focus {
  outline: none;
  border-color: var(--c-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-primary) 22%, transparent);
}
.sig-case:disabled { background: var(--c-surface-2); color: var(--c-text-muted); cursor: not-allowed; }
@media (max-width: 380px) { .sig-code { gap: 6px; } .sig-case { width: 40px; height: 50px; font-size: 20px; } }
/* @endv */

/* @v SIG-A2
@nom Cases soulignees
@usage Pour une page de signature epuree, posee sur le document lui-meme. Un simple trait par chiffre, qui s'epaissit et prend la couleur primaire sur la case active.
@html
<div class="champ">
  <label class="champ__label" for="sig-a2">Code recu par SMS</label>
  <div class="sig-code sig-code--trait" data-sig>
    <input class="sig-case" id="sig-a2" inputmode="numeric" autocomplete="one-time-code" maxlength="1" value="7" aria-label="Chiffre 1">
    <input class="sig-case" inputmode="numeric" maxlength="1" value="1" aria-label="Chiffre 2">
    <input class="sig-case" inputmode="numeric" maxlength="1" value="9" aria-label="Chiffre 3">
    <input class="sig-case" inputmode="numeric" maxlength="1" value="0" aria-label="Chiffre 4">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 5">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 6">
  </div>
</div>
@tw [&_input]:rounded-none [&_input]:border-0 [&_input]:border-b-2 [&_input]:bg-transparent focus:[&_input]:border-b-[3px]
@end */
.sig-code--trait { gap: var(--sp-3); }
.sig-code--trait .sig-case {
  width: 38px;
  border: 0;
  border-bottom: 2px solid var(--c-border-strong);
  border-radius: 0;
  background: transparent;
}
.sig-code--trait .sig-case:focus {
  box-shadow: none;
  border-bottom: 3px solid var(--c-primary);
}
.sig-code--trait .sig-case:not(:placeholder-shown) { border-bottom-color: var(--c-text); }
/* @endv */

/* @v SIG-A3
@nom Cases pleines
@usage Interface d'application mobile ou de produit SaaS : cases sans bordure sur un fond enfonce, la bordure n'apparait qu'au focus. Moins de traits a l'ecran, meme lisibilite.
@html
<div class="champ">
  <label class="champ__label" for="sig-a3">Code de verification</label>
  <div class="sig-code sig-code--plein" data-sig>
    <input class="sig-case" id="sig-a3" inputmode="numeric" autocomplete="one-time-code" maxlength="1" value="3" aria-label="Chiffre 1">
    <input class="sig-case" inputmode="numeric" maxlength="1" value="5" aria-label="Chiffre 2">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 3">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 4">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 5">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 6">
  </div>
</div>
@tw [&_input]:border-transparent [&_input]:bg-slate-100 [&_input]:rounded-xl focus:[&_input]:bg-white focus:[&_input]:border-primary
@end */
.sig-code--plein .sig-case {
  border-color: transparent;
  border-radius: var(--r-lg);
  background: var(--c-surface-2);
}
.sig-code--plein .sig-case:hover { border-color: transparent; background: var(--c-surface-3); }
.sig-code--plein .sig-case:focus { background: var(--c-surface); border-color: var(--c-primary); }
/* @endv */

/* @v SIG-A4
@nom Groupes de trois
@usage Un code de 6 chiffres se memorise en deux paquets de 3 : c'est ainsi qu'il est ecrit dans le SMS (482 913), le champ reprend la meme coupure. Le tiret est decoratif, il n'est ni saisi ni lu.
@html
<div class="champ">
  <label class="champ__label" for="sig-a4">Code de signature</label>
  <div class="sig-code" data-sig>
    <input class="sig-case" id="sig-a4" inputmode="numeric" autocomplete="one-time-code" maxlength="1" value="4" aria-label="Chiffre 1">
    <input class="sig-case" inputmode="numeric" maxlength="1" value="8" aria-label="Chiffre 2">
    <input class="sig-case" inputmode="numeric" maxlength="1" value="2" aria-label="Chiffre 3">
    <span class="sig-sep" aria-hidden="true"></span>
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 4">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 5">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 6">
  </div>
</div>
@tw separateur : <span class="h-0.5 w-3 bg-slate-400" aria-hidden="true">
@end */
.sig-sep {
  flex: none;
  width: 12px;
  height: 2px;
  margin: 0 2px;
  border-radius: var(--r-full);
  background: var(--c-border-strong);
}
/* @endv */

/* @v SIG-A5
@nom Cases jointes
@usage Un seul bloc partage en segments, comme un ruban. Plus compact que six cases separees, il tient sur un ecran de 320 px sans retrecir les chiffres.
@html
<div class="champ">
  <label class="champ__label" for="sig-a5">Code de signature</label>
  <div class="sig-code sig-code--joint" data-sig>
    <input class="sig-case" id="sig-a5" inputmode="numeric" autocomplete="one-time-code" maxlength="1" value="6" aria-label="Chiffre 1">
    <input class="sig-case" inputmode="numeric" maxlength="1" value="0" aria-label="Chiffre 2">
    <input class="sig-case" inputmode="numeric" maxlength="1" value="4" aria-label="Chiffre 3">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 4">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 5">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 6">
  </div>
</div>
@tw inline-flex divide-x rounded-lg border overflow-hidden [&_input]:rounded-none [&_input]:border-0
@end */
.sig-code--joint {
  display: inline-flex;
  gap: 0;
  width: max-content;
  max-width: 100%;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-md);
  background: var(--c-surface);
}
.sig-code--joint .sig-case {
  width: 44px;
  border: 0;
  border-left: 1px solid var(--c-border);
  border-radius: 0;
  background: transparent;
}
.sig-code--joint .sig-case:first-child { border-left: 0; border-radius: var(--r-md) 0 0 var(--r-md); }
.sig-code--joint .sig-case:last-child  { border-radius: 0 var(--r-md) var(--r-md) 0; }
.sig-code--joint .sig-case:focus {
  position: relative;
  box-shadow: inset 0 0 0 2px var(--c-primary);
}
.sig-code--joint:focus-within { border-color: var(--c-primary); }
/* @endv */

/* @v SIG-A6
@nom Grand format tactile
@usage Signature sur la tablette du technicien ou sur le telephone d'un client age : cases de 56 px, chiffres de 28 px. La cible tactile depasse largement les 44 px exiges.
@html
<div class="champ">
  <label class="champ__label sig-label-lg" for="sig-a6">Tapez le code recu par SMS</label>
  <div class="sig-code sig-code--lg" data-sig>
    <input class="sig-case" id="sig-a6" inputmode="numeric" autocomplete="one-time-code" maxlength="1" value="2" aria-label="Chiffre 1">
    <input class="sig-case" inputmode="numeric" maxlength="1" value="9" aria-label="Chiffre 2">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 3">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 4">
  </div>
  <span class="champ__aide">Code a 4 chiffres</span>
</div>
@tw [&_input]:h-[72px] [&_input]:w-14 [&_input]:text-[28px] [&_input]:rounded-2xl [&_input]:border-2
@end */
.sig-label-lg { font-size: var(--fs-lg); }
.sig-code--lg { gap: var(--sp-3); }
.sig-code--lg .sig-case {
  width: 56px;
  height: 72px;
  border-width: 2px;
  border-radius: var(--r-lg);
  font-size: 28px;
}
/* @endv */

/* @v SIG-A7
@nom Code masque
@usage Quand l'ecran est visible par d'autres (signature en agence, ecran partage en visio). Les chiffres sont remplaces par des points, un bouton les devoile le temps de verifier.
@html
<div class="champ">
  <label class="champ__label" for="sig-a7">Code de signature</label>
  <div class="sig-masque">
    <div class="sig-code sig-code--masque" data-sig>
      <input class="sig-case" id="sig-a7" inputmode="numeric" autocomplete="one-time-code" maxlength="1" value="4" aria-label="Chiffre 1">
      <input class="sig-case" inputmode="numeric" maxlength="1" value="8" aria-label="Chiffre 2">
      <input class="sig-case" inputmode="numeric" maxlength="1" value="2" aria-label="Chiffre 3">
      <input class="sig-case" inputmode="numeric" maxlength="1" value="9" aria-label="Chiffre 4">
      <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 5">
      <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 6">
    </div>
    <button type="button" class="btn btn--icone btn--fantome" data-sig-devoiler aria-pressed="false" aria-label="Afficher le code">{{icon:oeil}}</button>
  </div>
</div>
@tw [&_input]:[-webkit-text-security:disc] + bouton oeil aria-pressed
@end */
.sig-masque { display: flex; align-items: center; gap: var(--sp-2); max-width: 100%; }
.sig-masque .sig-code { min-width: 0; }
.sig-masque .btn { flex: none; }
.sig-code--masque .sig-case { -webkit-text-security: disc; font-size: 26px; }
.sig-code--masque.is-visible .sig-case { -webkit-text-security: none; font-size: 22px; }
/* @endv */

/* @v SIG-A8
@nom Code alphanumerique
@usage Code remis sur papier ou lu au telephone (lettres et chiffres, 8 caracteres). Police a chasse fixe, majuscules forcees, et un alphabet sans les caracteres ambigus : ni O, ni 0, ni I, ni 1.
@html
<div class="champ">
  <label class="champ__label" for="sig-a8">Code de signature</label>
  <div class="sig-code sig-code--alnum" data-sig="alnum">
    <input class="sig-case" id="sig-a8" autocapitalize="characters" autocomplete="one-time-code" maxlength="1" value="K" aria-label="Caractere 1">
    <input class="sig-case" autocapitalize="characters" maxlength="1" value="7" aria-label="Caractere 2">
    <input class="sig-case" autocapitalize="characters" maxlength="1" value="P" aria-label="Caractere 3">
    <input class="sig-case" autocapitalize="characters" maxlength="1" value="3" aria-label="Caractere 4">
    <span class="sig-sep" aria-hidden="true"></span>
    <input class="sig-case" autocapitalize="characters" maxlength="1" aria-label="Caractere 5">
    <input class="sig-case" autocapitalize="characters" maxlength="1" aria-label="Caractere 6">
    <input class="sig-case" autocapitalize="characters" maxlength="1" aria-label="Caractere 7">
    <input class="sig-case" autocapitalize="characters" maxlength="1" aria-label="Caractere 8">
  </div>
  <span class="champ__aide">Lettres et chiffres, sans distinction de casse</span>
</div>
@tw [&_input]:w-9 [&_input]:font-mono [&_input]:uppercase
@end */
.sig-code--alnum { gap: 6px; }
.sig-code--alnum .sig-case {
  width: 36px;
  height: 48px;
  font-family: var(--font-mono);
  font-size: 19px;
  text-transform: uppercase;
}
/* @endv */

/* @v SIG-A9
@nom Champ unique a peigne
@usage La technique la plus robuste : UN seul input, les cases sont dessinees en fond et les chiffres espaces pour tomber dedans. Le remplissage automatique iOS et Android, le collage et les lecteurs d'ecran fonctionnent sans une ligne de JavaScript.
@html
<div class="champ">
  <label class="champ__label" for="sig-a9">Code de signature</label>
  <input class="sig-peigne" id="sig-a9" inputmode="numeric" autocomplete="one-time-code" maxlength="6" pattern="[0-9]{6}" value="4829" spellcheck="false">
  <span class="champ__aide">6 chiffres</span>
</div>
@tw un input, letter-spacing calcule, cases en repeating-linear-gradient sur le fond
@end */
.sig-peigne {
  --pas: 44px;       /* largeur d'une case + son espace */
  --case: 38px;      /* largeur dessinee de la case */
  /* Une case de plus que necessaire : l'espacement suit aussi le dernier
     chiffre, sans cette marge le champ defilerait d'un cran a la sixieme saisie. */
  width: calc(var(--pas) * 7);
  height: 54px;
  padding: 0 0 0 calc((var(--case) - 1ch) / 2);
  border: 0;
  border-radius: 0;
  background:
    repeating-linear-gradient(90deg, var(--c-border-strong) 0 var(--case), transparent var(--case) var(--pas))
      left bottom / calc(var(--pas) * 5 + var(--case)) 2px no-repeat,
    repeating-linear-gradient(90deg, var(--c-surface) 0 var(--case), transparent var(--case) var(--pas))
      left top / calc(var(--pas) * 5 + var(--case)) 100% no-repeat;
  color: var(--c-text);
  font-family: var(--font-mono);
  font-size: 24px;
  font-weight: var(--fw-bold);
  letter-spacing: calc(var(--pas) - 1ch);
  caret-color: var(--c-primary);
}
.sig-peigne:focus {
  outline: none;
  background:
    repeating-linear-gradient(90deg, var(--c-primary) 0 var(--case), transparent var(--case) var(--pas))
      left bottom / calc(var(--pas) * 5 + var(--case)) 2px no-repeat,
    repeating-linear-gradient(90deg, var(--c-surface) 0 var(--case), transparent var(--case) var(--pas))
      left top / calc(var(--pas) * 5 + var(--case)) 100% no-repeat;
}
@media (max-width: 380px) { .sig-peigne { --pas: 42px; --case: 36px; } }
/* @endv */

/* @v SIG-A10
@nom Champ unique et cases dessinees
@usage Le schema des parcours de signature recents : un input invisible pose par-dessus six cases. On garde tous les avantages du champ unique (remplissage automatique, collage) avec le rendu des cases et un curseur qui clignote dans la case active.
@html
<div class="champ">
  <label class="champ__label" for="sig-a10">Code de signature</label>
  <div class="sig-unique" data-sig-unique>
    <input id="sig-a10" inputmode="numeric" autocomplete="one-time-code" maxlength="6" pattern="[0-9]*" spellcheck="false">
    <div class="sig-unique__cases" aria-hidden="true">
      <span class="sig-unique__case"></span><span class="sig-unique__case"></span><span class="sig-unique__case"></span>
      <span class="sig-sep"></span>
      <span class="sig-unique__case"></span><span class="sig-unique__case"></span><span class="sig-unique__case"></span>
    </div>
  </div>
  <span class="champ__aide">Cliquez puis tapez ou collez le code</span>
</div>
@tw relative ; input absolute inset-0 opacity-0 ; cases decoratives aria-hidden
@end */
.sig-unique { position: relative; width: max-content; max-width: 100%; }
.sig-unique input {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: 0;
  font-size: 16px;            /* evite le zoom automatique d'iOS au focus */
  color: transparent;
  cursor: text;
}
.sig-unique__cases { display: flex; align-items: center; gap: var(--sp-2); pointer-events: none; }
.sig-unique__case {
  position: relative;
  display: grid; place-items: center;
  flex: 0 1 46px; min-width: 30px; height: 56px;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-md);
  background: var(--c-surface);
  color: var(--c-text);
  font-size: 22px;
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.sig-unique__case.is-active {
  border-color: var(--c-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-primary) 22%, transparent);
}
.sig-unique__case.is-active:empty::after {
  content: "";
  width: 2px; height: 24px;
  background: var(--c-primary);
  animation: sig-curseur 1s steps(1) infinite;
}
@keyframes sig-curseur { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .sig-unique__case.is-active:empty::after { animation: none; } }
/* @endv */

/* ===========================================================================
   FAMILLE B  -  ETATS
   ======================================================================== */

/* @v SIG-B1
@nom Verification en cours
@usage Les cases se figent des que le sixieme chiffre est saisi : on n'attend pas de clic sur un bouton. Le message dit ce qui se passe, pas seulement qu'il se passe quelque chose.
@html
<div class="champ">
  <label class="champ__label">Code de signature</label>
  <div class="sig-code is-verif" aria-busy="true">
    <input class="sig-case" value="4" disabled aria-label="Chiffre 1"><input class="sig-case" value="8" disabled aria-label="Chiffre 2"><input class="sig-case" value="2" disabled aria-label="Chiffre 3"><input class="sig-case" value="9" disabled aria-label="Chiffre 4"><input class="sig-case" value="1" disabled aria-label="Chiffre 5"><input class="sig-case" value="3" disabled aria-label="Chiffre 6">
  </div>
  <span class="sig-statut" role="status"><span class="sig-roue" aria-hidden="true"></span>Verification du code...</span>
</div>
@tw [&_input]:opacity-70 + spinner animate-spin ; le statut porte role="status"
@end */
.sig-code.is-verif .sig-case { background: var(--c-surface); color: var(--c-text-soft); border-color: var(--c-border); }
.sig-statut {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--c-text-soft);
}
.sig-statut svg { width: 16px; height: 16px; flex: none; }
.sig-roue {
  width: 15px; height: 15px; flex: none;
  border: 2px solid var(--c-border);
  border-top-color: var(--c-primary);
  border-radius: 50%;
  animation: sig-tourne .7s linear infinite;
}
@keyframes sig-tourne { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .sig-roue { animation-duration: 2s; } }
/* @endv */

/* @v SIG-B2
@nom Code accepte
@usage Les six cases passent au vert ensemble et le message enchaine sur la suite. Pas d'ecran intermediaire a fermer : la signature se poursuit d'elle-meme.
@html
<div class="champ">
  <label class="champ__label">Code de signature</label>
  <div class="sig-code is-ok">
    <input class="sig-case" value="4" readonly aria-label="Chiffre 1"><input class="sig-case" value="8" readonly aria-label="Chiffre 2"><input class="sig-case" value="2" readonly aria-label="Chiffre 3"><input class="sig-case" value="9" readonly aria-label="Chiffre 4"><input class="sig-case" value="1" readonly aria-label="Chiffre 5"><input class="sig-case" value="3" readonly aria-label="Chiffre 6">
  </div>
  <span class="sig-statut sig-statut--ok" role="status">Code valide. Apposition de la signature...</span>
</div>
@tw [&_input]:border-green-600 [&_input]:text-green-700
@end */
.sig-code.is-ok .sig-case { border-color: var(--c-success); color: var(--c-success); }
.sig-statut--ok { color: var(--c-success); font-weight: var(--fw-semi); }
/* @endv */

/* @v SIG-B3
@nom Code incorrect
@usage Bordure rouge, secousse breve, et les chiffres restent affiches pour que le signataire voie son erreur. Le nombre d'essais restants est annonce avant qu'il soit trop tard.
@html
<div class="champ">
  <label class="champ__label">Code de signature</label>
  <div class="sig-code is-erreur" data-sig>
    <input class="sig-case" inputmode="numeric" maxlength="1" value="4" aria-invalid="true" aria-describedby="sig-b3-err" aria-label="Chiffre 1"><input class="sig-case" inputmode="numeric" maxlength="1" value="8" aria-invalid="true" aria-label="Chiffre 2"><input class="sig-case" inputmode="numeric" maxlength="1" value="2" aria-invalid="true" aria-label="Chiffre 3"><input class="sig-case" inputmode="numeric" maxlength="1" value="9" aria-invalid="true" aria-label="Chiffre 4"><input class="sig-case" inputmode="numeric" maxlength="1" value="3" aria-invalid="true" aria-label="Chiffre 5"><input class="sig-case" inputmode="numeric" maxlength="1" value="1" aria-invalid="true" aria-label="Chiffre 6">
  </div>
  <span class="champ__erreur" id="sig-b3-err" role="alert">{{icon:alerte}} Code incorrect. Verifiez le SMS : il vous reste 2 essais.</span>
</div>
@tw [&_input]:border-red-600 + animate-[secousse_400ms] ; aria-invalid sur chaque case
@end */
.sig-code.is-erreur .sig-case { border-color: var(--c-danger); color: var(--c-danger); }
.sig-code.is-erreur .sig-case:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-danger) 22%, transparent); }
.sig-code.is-secoue { animation: sig-secoue 400ms cubic-bezier(.36,.07,.19,.97); }
@keyframes sig-secoue {
  20%, 60% { transform: translateX(-5px); }
  40%, 80% { transform: translateX(5px); }
}
@media (prefers-reduced-motion: reduce) { .sig-code.is-secoue { animation: none; } }
/* @endv */

/* @v SIG-B4
@nom Code expire
@usage Le code a une duree de vie (10 minutes en general). Une fois expire, les cases se desactivent et la seule action proposee est la bonne : en recevoir un nouveau.
@html
<div class="champ">
  <label class="champ__label">Code de signature</label>
  <div class="sig-code">
    <input class="sig-case" disabled aria-label="Chiffre 1"><input class="sig-case" disabled aria-label="Chiffre 2"><input class="sig-case" disabled aria-label="Chiffre 3"><input class="sig-case" disabled aria-label="Chiffre 4"><input class="sig-case" disabled aria-label="Chiffre 5"><input class="sig-case" disabled aria-label="Chiffre 6">
  </div>
  <div class="sig-ligne">
    <span class="sig-statut">{{icon:horloge}} Ce code a expire apres 10 minutes.</span>
    <button type="button" class="btn btn--tonal btn--sm">{{icon:rotation}} Recevoir un nouveau code</button>
  </div>
</div>
@tw [&_input]:disabled:bg-slate-100 ; une seule action proposee
@end */
.sig-ligne { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
/* @endv */

/* @v SIG-B5
@nom Trop d'essais
@usage Apres 3 codes faux, la signature est suspendue un temps. On dit pourquoi, pour combien de temps, et qui contacter : un blocage sans issue fait appeler l'emetteur en colere.
@html
<div class="sig-bloque" role="alert">
  <div class="sig-bloque__tete">{{icon:alerte}}<strong>Signature suspendue</strong></div>
  <p>Trois codes incorrects ont ete saisis. Par securite, un nouveau code pourra etre demande dans <strong class="sig-rebours" data-sig-rebours="899">14:59</strong>.</p>
  <p class="sig-bloque__aide">Ce n'est pas vous ? Prevenez l'emetteur du document : <a href="#">contact@exemple.fr</a></p>
</div>
@tw rounded-lg border border-red-300 p-4 ; minuteur tabular-nums
@end */
.sig-bloque {
  max-width: 380px;
  padding: var(--sp-4);
  border: 1px solid color-mix(in srgb, var(--c-danger) 45%, var(--c-border));
  border-radius: var(--r-md);
  background: var(--c-surface);
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--c-text-soft);
}
.sig-bloque__tete { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); color: var(--c-danger); font-size: var(--fs-md); }
.sig-bloque__tete svg { width: 18px; height: 18px; }
.sig-bloque p { margin: 0 0 var(--sp-2); }
.sig-bloque__aide { margin: 0 !important; font-size: var(--fs-xs); color: var(--c-text-muted); }
.sig-rebours { color: var(--c-text); font-variant-numeric: tabular-nums; }
/* @endv */

/* ===========================================================================
   FAMILLE C  -  PARCOURS DE SIGNATURE
   ======================================================================== */

/* @v SIG-C1
@nom Signature par SMS
@usage L'ecran complet, pret a coller : le document a signer, ou le code est parti, le champ, le renvoi et l'action. Tapez 482913 pour voir la reussite, n'importe quel autre code pour l'erreur.
@html
<div class="sig-carte">
  <div class="sig-doc">
    <span class="sig-doc__icone">{{icon:f-pdf}}</span>
    <div><strong>Devis D-2026-0418</strong><span>Pompe a chaleur air/eau &middot; 3 pages</span></div>
  </div>
  <h3 class="sig-carte__titre">Saisissez votre code de signature</h3>
  <p class="sig-carte__texte">Nous venons d'envoyer un code a 6 chiffres au <strong>06 &bull;&bull; &bull;&bull; &bull;&bull; 56 78</strong>.</p>
  <div class="sig-code" data-sig data-sig-attendu="482913">
    <input class="sig-case" inputmode="numeric" autocomplete="one-time-code" maxlength="1" aria-label="Chiffre 1">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 2">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 3">
    <span class="sig-sep" aria-hidden="true"></span>
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 4">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 5">
    <input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 6">
  </div>
  <span class="sig-statut" data-sig-message role="status">Le code est valable 10 minutes.</span>
  <div class="sig-carte__pied">
    <button type="button" class="btn btn--texte btn--sm" data-sig-renvoi="30" disabled>Renvoyer le code <span>dans <b>30</b> s</span></button>
    <button type="button" class="btn btn--plein">{{icon:signature}} Signer le document</button>
  </div>
</div>
@tw max-w-sm rounded-xl border bg-white p-6 ; code centre ; pied flex justify-between
@end */
.sig-carte {
  display: flex; flex-direction: column; gap: var(--sp-3);
  width: 100%; max-width: 400px;
  padding: clamp(var(--sp-4), 5vw, var(--sp-6));
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  background: var(--c-surface);
}
.sig-carte__titre { margin: var(--sp-2) 0 0; font-size: var(--fs-xl); font-weight: var(--fw-bold); color: var(--c-text); line-height: 1.3; }
.sig-carte__texte { margin: 0; font-size: var(--fs-md); line-height: 1.5; color: var(--c-text-soft); }
.sig-carte__texte strong { color: var(--c-text); white-space: nowrap; }
.sig-carte__pied {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2);
  margin-top: var(--sp-2);
}
.sig-doc {
  display: flex; align-items: center; gap: var(--sp-3);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--c-border);
  font-size: var(--fs-sm);
}
.sig-doc strong { display: block; color: var(--c-text); }
.sig-doc span { color: var(--c-text-muted); }
.sig-doc__icone { display: inline-flex; flex: none; }
.sig-doc__icone svg { width: 30px; height: 30px; }
/* @endv */

/* @v SIG-C2
@nom Choix du canal
@usage Avant l'envoi, le signataire choisit ou recevoir son code. Les coordonnees sont masquees mais reconnaissables : assez pour verifier que c'est bien les siennes, pas assez pour les exposer.
@html
<form class="sig-carte" onsubmit="return false">
  <h3 class="sig-carte__titre">Comment recevoir votre code ?</h3>
  <p class="sig-carte__texte">Ce code confirme que c'est bien vous qui signez.</p>
  <fieldset class="sig-canaux">
    <legend class="sr-only">Canal d'envoi</legend>
    <label class="sig-canal"><input type="radio" name="sig-canal" checked><span class="sig-canal__icone">{{icon:phone}}</span><span><strong>Par SMS</strong><em>06 &bull;&bull; &bull;&bull; &bull;&bull; 56 78</em></span></label>
    <label class="sig-canal"><input type="radio" name="sig-canal"><span class="sig-canal__icone">{{icon:mail}}</span><span><strong>Par courriel</strong><em>j&bull;&bull;&bull;&bull;&bull;n@gmail.com</em></span></label>
  </fieldset>
  <button class="btn btn--plein btn--bloc">Recevoir mon code</button>
</form>
@tw radios caches, label entier cliquable, has-[:checked]:border-primary
@end */
.sig-canaux { display: flex; flex-direction: column; gap: var(--sp-2); margin: 0; padding: 0; border: 0; }
.sig-canal {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  cursor: pointer;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.sig-canal:hover { border-color: var(--c-border-strong); }
.sig-canal input { position: absolute; opacity: 0; pointer-events: none; }
.sig-canal:has(input:checked) { border-color: var(--c-primary); box-shadow: inset 0 0 0 1px var(--c-primary); }
.sig-canal:has(input:focus-visible) { outline: 2px solid var(--c-focus); outline-offset: 2px; }
.sig-canal__icone { display: inline-flex; color: var(--c-text-soft); }
.sig-canal__icone svg { width: 20px; height: 20px; }
.sig-canal:has(input:checked) .sig-canal__icone { color: var(--c-primary); }
.sig-canal strong { display: block; font-size: var(--fs-md); color: var(--c-text); }
.sig-canal em { font-style: normal; font-size: var(--fs-sm); color: var(--c-text-muted); }
.btn--bloc { width: 100%; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* @endv */

/* @v SIG-C3
@nom Renvoi du code
@usage Le lien de renvoi est bloque 30 secondes avec un decompte visible : sans cela, le signataire impatient en demande trois et saisit le premier, qui n'est plus valable. Puis deux portes de sortie : changer de numero, ou recevoir un appel.
@html
<div class="sig-renvoi">
  <p>Vous n'avez rien recu ?</p>
  <div class="sig-renvoi__actions">
    <button type="button" class="btn btn--contour btn--sm" data-sig-renvoi="30" disabled>{{icon:rotation}} Renvoyer <span>dans <b>30</b> s</span></button>
    <button type="button" class="btn btn--texte btn--sm">Recevoir un appel vocal</button>
    <button type="button" class="btn btn--texte btn--sm">Ce n'est pas mon numero</button>
  </div>
</div>
@tw disabled:opacity-60 pendant le decompte ; chiffres tabular-nums
@end */
.sig-renvoi { font-size: var(--fs-sm); color: var(--c-text-soft); }
.sig-renvoi p { margin: 0 0 var(--sp-2); }
.sig-renvoi__actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
[data-sig-renvoi] b { font-weight: inherit; font-variant-numeric: tabular-nums; }
/* @endv */

/* @v SIG-C4
@nom Consentement et code
@usage La forme qui tient juridiquement : la case d'acceptation precede le code, et le bouton reste inactif tant que les deux ne sont pas remplis. La phrase dit exactement ce qui est signe.
@html
<form class="sig-carte" data-sig-consent onsubmit="return false">
  <div class="sig-doc">
    <span class="sig-doc__icone">{{icon:f-pdf}}</span>
    <div><strong>Contrat d'entretien annuel</strong><span>Emis par ECO CONFORT HABITAT</span></div>
  </div>
  <label class="coche"><input type="checkbox"><span class="coche__boite"></span> J'ai lu le contrat et j'accepte de le signer electroniquement.</label>
  <div class="champ">
    <label class="champ__label">Code recu par SMS</label>
    <div class="sig-code" data-sig>
      <input class="sig-case" inputmode="numeric" autocomplete="one-time-code" maxlength="1" aria-label="Chiffre 1"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 2"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 3"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 4"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 5"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 6">
    </div>
  </div>
  <button class="btn btn--plein btn--bloc" disabled>{{icon:signature}} Signer le contrat</button>
  <p class="sig-mention">Votre signature sera horodatee et scellee. Elle a la meme valeur qu'une signature manuscrite (article 1367 du Code civil).</p>
</form>
@tw bouton disabled tant que case non cochee ou code incomplet
@end */
.sig-mention { margin: 0; font-size: var(--fs-xs); line-height: 1.5; color: var(--c-text-muted); }
/* @endv */

/* @v SIG-C5
@nom Feuille mobile
@usage Sur telephone, le code s'ouvre dans une feuille montee du bas, par-dessus le document. Les cases restent au-dessus du clavier, et le document reste visible en arriere-plan pour rappeler ce qu'on signe.
@large
@html
<div class="sig-tel">
  <div class="sig-tel__doc" aria-hidden="true"><i></i><i></i><i></i><i></i><i></i><i></i></div>
  <div class="sig-feuille" role="dialog" aria-label="Code de signature">
    <span class="sig-feuille__poignee" aria-hidden="true"></span>
    <h3 class="sig-carte__titre">Code de signature</h3>
    <p class="sig-carte__texte">Envoye au 06 &bull;&bull; &bull;&bull; &bull;&bull; 56 78</p>
    <div class="sig-code sig-code--plein" data-sig>
      <input class="sig-case" inputmode="numeric" autocomplete="one-time-code" maxlength="1" value="4" aria-label="Chiffre 1"><input class="sig-case" inputmode="numeric" maxlength="1" value="8" aria-label="Chiffre 2"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 3"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 4"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 5"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 6">
    </div>
    <div class="sig-feuille__suggestion" aria-hidden="true"><span>Depuis Messages</span><strong>482913</strong></div>
  </div>
</div>
@tw fixed inset-x-0 bottom-0 rounded-t-2xl ; le bandeau « Depuis Messages » est fourni par iOS grace a autocomplete="one-time-code"
@end */
.sig-tel {
  position: relative;
  width: 300px; height: 500px;
  margin: 0 auto;
  overflow: hidden;
  border: 8px solid var(--c-text);
  border-radius: 38px;
  background: var(--c-surface-2);
}
.sig-tel__doc { display: flex; flex-direction: column; gap: 10px; padding: 34px 22px; }
.sig-tel__doc i { height: 8px; border-radius: 4px; background: var(--c-surface-3); }
.sig-tel__doc i:nth-child(3n) { width: 64%; }
.sig-feuille {
  position: absolute; inset: auto 0 0 0;
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  border-radius: 22px 22px 0 0;
  background: var(--c-surface);
  box-shadow: 0 -8px 30px rgba(0,0,0,.18);
  text-align: center;
}
.sig-feuille__poignee { width: 38px; height: 5px; margin-bottom: var(--sp-2); border-radius: var(--r-full); background: var(--c-border-strong); }
.sig-feuille .sig-code { gap: 6px; }
.sig-feuille .sig-case { width: 38px; height: 48px; font-size: 20px; }
.sig-feuille__suggestion {
  display: flex; flex-direction: column; align-items: center;
  width: calc(100% + 2 * var(--sp-4));
  margin: var(--sp-3) calc(-1 * var(--sp-4)) calc(-1 * var(--sp-4));
  padding: var(--sp-2) 0;
  background: var(--c-surface-3);
  font-size: 11px; color: var(--c-text-muted);
}
.sig-feuille__suggestion strong { font-size: var(--fs-lg); color: var(--c-text); letter-spacing: .04em; }
/* @endv */

/* @v SIG-C6
@nom Code envoye par courriel
@usage Quand le code part par courriel, le signataire doit changer d'application. Un raccourci vers sa messagerie et un rappel des dossiers ou chercher evitent l'abandon.
@html
<div class="sig-carte">
  <span class="sig-pastille">{{icon:mail}}</span>
  <h3 class="sig-carte__titre">Verifiez votre boite mail</h3>
  <p class="sig-carte__texte">Le code a ete envoye a <strong>j&bull;&bull;&bull;&bull;&bull;n@gmail.com</strong>. Il arrive en general en moins d'une minute.</p>
  <div class="sig-code sig-code--trait" data-sig>
    <input class="sig-case" inputmode="numeric" autocomplete="one-time-code" maxlength="1" aria-label="Chiffre 1"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 2"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 3"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 4"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 5"><input class="sig-case" inputmode="numeric" maxlength="1" aria-label="Chiffre 6">
  </div>
  <div class="sig-ligne">
    <a class="btn btn--secondaire btn--sm" href="https://mail.google.com" target="_blank" rel="noopener">{{icon:google}} Ouvrir Gmail</a>
    <a class="btn btn--secondaire btn--sm" href="https://outlook.live.com" target="_blank" rel="noopener">{{icon:mail}} Ouvrir Outlook</a>
  </div>
  <p class="sig-mention">Rien recu ? Regardez dans les courriers indesirables et l'onglet Promotions, ou <a href="#">recevez le code par SMS</a>.</p>
</div>
@tw lien vers le webmail deduit du domaine de l'adresse
@end */
.sig-pastille {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border-radius: var(--r-full);
  background: var(--c-surface-2);
  color: var(--c-text);
}
.sig-pastille svg { width: 22px; height: 22px; }
/* @endv */

/* @v SIG-C7
@nom SMS du code
@usage Le message lui-meme fait partie de l'interface. Le nom de l'emetteur en premier, le code en clair, la duree de validite, l'avertissement de ne pas le transmettre, et la derniere ligne au format WebOTP pour que le navigateur remplisse le champ tout seul.
@html
<div class="sig-sms">
  <div class="sig-sms__tete"><strong>ODISIGN</strong><span>maintenant</span></div>
  <div class="sig-sms__bulle">
    ECO CONFORT HABITAT vous invite a signer le devis D-2026-0418.<br>
    Votre code : <strong>482 913</strong><br>
    Valable 10 min. Ne le communiquez a personne, meme a l'emetteur.<br><br>
    <span class="sig-sms__otp">@signer.exemple.fr #482913</span>
  </div>
</div>
@tw la derniere ligne « @domaine #code » est lue par l'API WebOTP (Chrome Android) et par le remplissage iOS
@end */
.sig-sms { width: 100%; max-width: 320px; font-size: var(--fs-sm); }
.sig-sms__tete { display: flex; justify-content: space-between; margin: 0 var(--sp-2) var(--sp-1); color: var(--c-text-muted); font-size: var(--fs-xs); }
.sig-sms__tete strong { color: var(--c-text); letter-spacing: .04em; }
.sig-sms__bulle {
  padding: var(--sp-3) var(--sp-4);
  border-radius: 18px 18px 18px 4px;
  background: var(--c-surface-3);
  color: var(--c-text);
  line-height: 1.5;
}
.sig-sms__bulle strong { font-variant-numeric: tabular-nums; letter-spacing: .03em; }
.sig-sms__otp { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--c-text-muted); }
/* @endv */

/* @v SIG-C8
@nom Signature confirmee
@usage Le dernier ecran sert de preuve : qui a signe, quand (a la seconde), par quel moyen, et la reference du dossier de preuve. Le document signe se telecharge tout de suite, sans attendre le courriel.
@html
<div class="sig-carte">
  <h3 class="sig-carte__titre">Document signe</h3>
  <p class="sig-carte__texte">Une copie vous est envoyee par courriel. Vous pouvez fermer cette page.</p>
  <dl class="sig-preuve">
    <div><dt>Signataire</dt><dd>Martine Lefevre</dd></div>
    <div><dt>Date</dt><dd>24/10/2026 a 14:32:07</dd></div>
    <div><dt>Moyen</dt><dd>Code SMS au 06 &bull;&bull; &bull;&bull; &bull;&bull; 56 78</dd></div>
    <div><dt>Reference</dt><dd class="sig-preuve__ref">SIG-7F3A-92C1-0B4E</dd></div>
  </dl>
  <div class="sig-ligne">
    <button type="button" class="btn btn--plein">{{icon:download}} Telecharger le PDF signe</button>
    <button type="button" class="btn btn--texte">Dossier de preuve</button>
  </div>
</div>
@tw dl en grille 2 colonnes, reference en font-mono
@end */
.sig-preuve {
  display: grid; gap: 0;
  margin: var(--sp-2) 0;
  border-top: 1px solid var(--c-border);
  font-size: var(--fs-sm);
}
.sig-preuve > div {
  display: grid; grid-template-columns: 96px 1fr; gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px solid var(--c-border);
}
.sig-preuve dt { color: var(--c-text-muted); }
.sig-preuve dd { margin: 0; color: var(--c-text); font-weight: var(--fw-medium); }
.sig-preuve__ref { font-family: var(--font-mono); font-size: var(--fs-xs); letter-spacing: .03em; }
/* @endv */
