Aller au contenu
Bibliotheque UIJABS

Codes de signature 23 variantes

Le code a usage unique qui vaut consentement dans une signature electronique. 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 : le collage et le remplissage automatique (autocomplete="one-time-code") remplissent toutes les cases d'un coup, inputmode="numeric" ouvre le pave numerique (jamais type="number"), on dit ou le code est parti et combien de temps il reste valable, et une erreur garde les chiffres visibles en annoncant les essais restants. Les champs des demonstrations sont actifs : tapez, collez, effacez.

A. Styles de cases

Encadrees, soulignees, pleines, groupees, jointes, grand format, masquees, alphanumeriques, et les deux techniques a champ unique. Le socle est SIG-A1, le reste n'est que modificateurs.

6 chiffres, envoyes au 06 •• •• •• 56 78
Cases encadrees

Le socle de la categorie et le choix par defaut : six cases bordees, lisibles par tous, sans ambiguite sur le nombre de chiffres attendus.

Voir le codeMasquer le code
<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>
.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; } }
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
Cases soulignees

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.

Voir le codeMasquer le code
<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>
.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); }
[&_input]:rounded-none [&_input]:border-0 [&_input]:border-b-2 [&_input]:bg-transparent focus:[&_input]:border-b-[3px]
Cases pleines

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.

Voir le codeMasquer le code
<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>
.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); }
[&_input]:border-transparent [&_input]:bg-slate-100 [&_input]:rounded-xl focus:[&_input]:bg-white focus:[&_input]:border-primary
Groupes de trois

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.

Voir le codeMasquer le code
<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>
.sig-sep {
  flex: none;
  width: 12px;
  height: 2px;
  margin: 0 2px;
  border-radius: var(--r-full);
  background: var(--c-border-strong);
}
separateur : <span class="h-0.5 w-3 bg-slate-400" aria-hidden="true">
Cases jointes

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.

Voir le codeMasquer le code
<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>
.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); }
inline-flex divide-x rounded-lg border overflow-hidden [&_input]:rounded-none [&_input]:border-0
Code a 4 chiffres
Grand format tactile

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.

Voir le codeMasquer le code
<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>
.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;
}
[&_input]:h-[72px] [&_input]:w-14 [&_input]:text-[28px] [&_input]:rounded-2xl [&_input]:border-2
Code masque

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.

Voir le codeMasquer le code
<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"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg></button>
  </div>
</div>
.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; }
[&_input]:[-webkit-text-security:disc] + bouton oeil aria-pressed
Lettres et chiffres, sans distinction de casse
Code alphanumerique

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.

Voir le codeMasquer le code
<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>
.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;
}
[&_input]:w-9 [&_input]:font-mono [&_input]:uppercase
6 chiffres
Champ unique a peigne

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.

Voir le codeMasquer le code
<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>
.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; } }
un input, letter-spacing calcule, cases en repeating-linear-gradient sur le fond
Cliquez puis tapez ou collez le code
Champ unique et cases dessinees

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.

Voir le codeMasquer le code
<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>
.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; } }
relative ; input absolute inset-0 opacity-0 ; cases decoratives aria-hidden

B. Etats

Verification, code accepte, code incorrect, code expire, signature suspendue. Chaque etat dit ce qui se passe et quelle est la suite.

Verification du code...
Verification en cours

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.

Voir le codeMasquer le code
<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>
.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; } }
[&_input]:opacity-70 + spinner animate-spin ; le statut porte role="status"
Code valide. Apposition de la signature...
Code accepte

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.

Voir le codeMasquer le code
<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>
.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); }
[&_input]:border-green-600 [&_input]:text-green-700
Code incorrect. Verifiez le SMS : il vous reste 2 essais.
Code incorrect

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.

Voir le codeMasquer le code
<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"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 9v4M12 17h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z"/></svg> Code incorrect. Verifiez le SMS : il vous reste 2 essais.</span>
</div>
.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; } }
[&_input]:border-red-600 + animate-[secousse_400ms] ; aria-invalid sur chaque case
Ce code a expire apres 10 minutes.
Code expire

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.

Voir le codeMasquer le code
<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"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg> Ce code a expire apres 10 minutes.</span>
    <button type="button" class="btn btn--tonal btn--sm"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12a9 9 0 1 1-3-6.7M21 3v6h-6"/></svg> Recevoir un nouveau code</button>
  </div>
</div>
.sig-ligne { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
[&_input]:disabled:bg-slate-100 ; une seule action proposee
Trop d'essais

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.

Voir le codeMasquer le code
<div class="sig-bloque" role="alert">
  <div class="sig-bloque__tete"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 9v4M12 17h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z"/></svg><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>
.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; }
rounded-lg border border-red-300 p-4 ; minuteur tabular-nums

C. Parcours de signature

Ecrans complets prets a coller : signature par SMS, choix du canal, renvoi, consentement, feuille mobile, courriel, texte du SMS, preuve de signature.

Devis D-2026-0418Pompe a chaleur air/eau · 3 pages

Saisissez votre code de signature

Nous venons d'envoyer un code a 6 chiffres au 06 •• •• •• 56 78.

Le code est valable 10 minutes.
Signature par SMS

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.

Voir le codeMasquer le code
<div class="sig-carte">
  <div class="sig-doc">
    <span class="sig-doc__icone"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" fill="#e8453c"/><path d="M14 2v6h6" fill="#fff" fill-opacity=".35"/><text x="12" y="17" font-family="system-ui,sans-serif" font-size="6.5" font-weight="700" fill="#fff" text-anchor="middle">PDF</text></svg></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"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 17c3 0 3-9 6-9s3 9 6 9 3-5 6-5"/><path d="M3 21h18"/></svg> Signer le document</button>
  </div>
</div>
.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; }
max-w-sm rounded-xl border bg-white p-6 ; code centre ; pied flex justify-between

Comment recevoir votre code ?

Ce code confirme que c'est bien vous qui signez.

Canal d'envoi
Choix du canal

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.

Voir le codeMasquer le code
<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"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1 19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2 4.2 2 2 0 0 1 4 2h3a2 2 0 0 1 2 1.7c.1 1 .4 1.9.7 2.8a2 2 0 0 1-.5 2.1L8 9.8a16 16 0 0 0 6 6l1.2-1.2a2 2 0 0 1 2.1-.5c.9.3 1.8.6 2.8.7A2 2 0 0 1 22 16.9Z"/></svg></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"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m2 7 10 6 10-6"/></svg></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>
.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; }
radios caches, label entier cliquable, has-[:checked]:border-primary

Vous n'avez rien recu ?

Renvoi du code

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.

Voir le codeMasquer le code
<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><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12a9 9 0 1 1-3-6.7M21 3v6h-6"/></svg> 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>
.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; }
disabled:opacity-60 pendant le decompte ; chiffres tabular-nums
Contrat d'entretien annuelEmis par ECO CONFORT HABITAT

Votre signature sera horodatee et scellee. Elle a la meme valeur qu'une signature manuscrite (article 1367 du Code civil).

Consentement et code

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.

Voir le codeMasquer le code
<form class="sig-carte" data-sig-consent onsubmit="return false">
  <div class="sig-doc">
    <span class="sig-doc__icone"><svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z" fill="#e8453c"/><path d="M14 2v6h6" fill="#fff" fill-opacity=".35"/><text x="12" y="17" font-family="system-ui,sans-serif" font-size="6.5" font-weight="700" fill="#fff" text-anchor="middle">PDF</text></svg></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><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 17c3 0 3-9 6-9s3 9 6 9 3-5 6-5"/><path d="M3 21h18"/></svg> 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>
.sig-mention { margin: 0; font-size: var(--fs-xs); line-height: 1.5; color: var(--c-text-muted); }
bouton disabled tant que case non cochee ou code incomplet
Feuille mobile

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.

Voir le codeMasquer le code
<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>
.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; }
fixed inset-x-0 bottom-0 rounded-t-2xl ; le bandeau « Depuis Messages » est fourni par iOS grace a autocomplete="one-time-code"

Verifiez votre boite mail

Le code a ete envoye a j•••••n@gmail.com. Il arrive en general en moins d'une minute.

Rien recu ? Regardez dans les courriers indesirables et l'onglet Promotions, ou recevez le code par SMS.

Code envoye par courriel

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.

Voir le codeMasquer le code
<div class="sig-carte">
  <span class="sig-pastille"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m2 7 10 6 10-6"/></svg></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"><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#4285F4" d="M23 12.3c0-.8-.1-1.6-.2-2.3H12v4.5h6.2a5.3 5.3 0 0 1-2.3 3.5v2.9h3.7c2.2-2 3.4-5 3.4-8.6Z"/><path fill="#34A853" d="M12 23.5c3.1 0 5.7-1 7.6-2.8l-3.7-2.9c-1 .7-2.3 1.1-3.9 1.1-3 0-5.5-2-6.4-4.7H1.8v3A11.5 11.5 0 0 0 12 23.5Z"/><path fill="#FBBC05" d="M5.6 14.2a6.9 6.9 0 0 1 0-4.4v-3H1.8a11.5 11.5 0 0 0 0 10.4Z"/><path fill="#EA4335" d="M12 5.1c1.7 0 3.2.6 4.4 1.7l3.3-3.3A11.5 11.5 0 0 0 1.8 6.8l3.8 3a6.9 6.9 0 0 1 6.4-4.7Z"/></svg> Ouvrir Gmail</a>
    <a class="btn btn--secondaire btn--sm" href="https://outlook.live.com" target="_blank" rel="noopener"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="m2 7 10 6 10-6"/></svg> 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>
.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; }
lien vers le webmail deduit du domaine de l'adresse
ODISIGNmaintenant
ECO CONFORT HABITAT vous invite a signer le devis D-2026-0418.
Votre code : 482 913
Valable 10 min. Ne le communiquez a personne, meme a l'emetteur.

@signer.exemple.fr #482913
SMS du code

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.

Voir le codeMasquer le code
<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>
.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); }
la derniere ligne « @domaine #code » est lue par l'API WebOTP (Chrome Android) et par le remplissage iOS

Document signe

Une copie vous est envoyee par courriel. Vous pouvez fermer cette page.

Signataire
Martine Lefevre
Date
24/10/2026 a 14:32:07
Moyen
Code SMS au 06 •• •• •• 56 78
Reference
SIG-7F3A-92C1-0B4E
Signature confirmee

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.

Voir le codeMasquer le code
<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"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg> Telecharger le PDF signe</button>
    <button type="button" class="btn btn--texte">Dossier de preuve</button>
  </div>
</div>
.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; }
dl en grille 2 colonnes, reference en font-mono