Fondations

Composants

Patterns & Layouts

Utiliser le système

Choisissez une section, ou ouvrez la page entière. Le bouton Accueil de la colonne de gauche ramène ici.

Couleurs

Quatre couleurs ont un rôle. Le violet #8A3AAF porte toutes les actions. Le rouge #E2006E est réservé au menu gauche et au wordmark. Le bleu #3B82F6 ne sert qu'au focus des champs de saisie. Le rouge sombre #B42318 signale le destructif. Tout le reste est neutre.

Primary — Violet
#8A3AAF
Menu gauche & wordmark
#E2006E
Destructive
#B42318
Focus des champs
#3B82F6
Sidebar Gestion
#13041C
Sidebar Reporting
#0A032D
Texte Principal
#111827
Texte Secondaire
#4B5563
Texte Tertiaire
#9CA3AF
Bordures
#E5E7EB
Fond Principal
#F3F4F6

Typographie

Nous utilisons l'Inter pour tous les corps de texte et les composants, et la Geist pour les titres de page, assurant une esthétique moderne et épurée. Voici les styles extraits des fichiers de production.

H1 - Page Header / Design System - font-weight: 700 / 32px
Statistiques pré-formatées
Page Title / H1 - Geist / font-weight: 600 / 22px / Letter-spacing: -0.01em
Statistiques pré-formatées
Widget Title - Inter / font-weight: 600 / 15px / Color: --t1
Modules par mois
Body Text / Main - Inter / font-weight: 400 / 14px
Gérez vos utilisateurs et vos formations depuis une interface intuitive.
Description Text - Inter / font-weight: 400 / 12.5px / Color: --t3
Dernière mise à jour il y a 2 jours
Table Header - Inter / font-weight: 600 / 11.5px / Color: --t2 / Background: --ps
Colonne tableau
Table Cell - Inter / font-weight: 400 / 13.5px / Color: --t1
Contenu de cellule
Chart Label (X-Axis) - Inter / font-weight: 400 / 12px / Color: #6B7280
Jan · Fév · Mar
Donut Legend - Inter / font-weight: 400 / 12.5px / Color: --t1 (with badge)
RH Central 22%
Horizontal Bar Label - Inter / font-weight: 400 / 12.5px / Color: --t2 / Right-aligned
Sécurité au travail
Horizontal Bar Value - Inter / font-weight: 600 / 12.5px / Color: --t1
91%

Boutons

Le bouton est le composant le plus répété de l'interface : il doit porter une hiérarchie lisible en un coup d'œil. 4 poids, 3 tons, 4 tailles, 6 états et 4 compositions, pilotés par des tokens CSS locaux (--btn-h, --btn-px, --btn-fs, --btn-icon) : une classe de taille suffit à tout redimensionner.

1 — La couleur d'action

Une seule couleur d'action, le violet #8A3AAF, déclinée par le poids : plein pour le primaire, en contour pour le secondaire, en texte seul pour le tertiaire. Le blanc bordé couvre les actions neutres. Le rouge #E2006E est réservé à la navigation et n'apparaît sur aucun bouton.

Base
#8A3AAF  ·  --a
Hover
#783298  ·  --a-h
Pressed
#662B81  ·  --a-p
Bordure teintée
#E0CAEA  ·  --a2
Surface teintée
#F8F1FB  ·  --a1
Sur fond sombre
#9B4BC4  ·  --a-dark
Vérification de contraste (WCAG 2.1) Ratio Niveau Usage validé
Texte blanc sur #8A3AAF 6.35:1 AA (tout texte) Bouton .primary au repos
Texte blanc sur #783298 puis #662B81 7.75 → 9.43 AAA Hover puis pressed — le contraste monte, jamais l'inverse
Violet sur fond blanc 6.35:1 AA .secondary, .tertiary, liens, icônes
#662B81 sur surface #F8F1FB 8.51:1 AAA Survol de .secondary et .tertiary
Texte blanc sur #9B4BC4 5.00:1 AA .primary.on-dark sur les sidebars
:root {
  --a: #8A3AAF;       --a-h: #783298;   --a-p: #662B81;
  --a1: #F8F1FB;      --a2: #E0CAEA;   --a-rgb: 138, 58, 175;
  --a-dark: #9B4BC4;  /* violet éclairci pour les sidebars sombres */
}

2 — Deux axes, pas une liste

Deux axes indépendants, sur le modèle de Shopify : le poids de l'action dans la page (variant) et le sens qu'elle porte (tone). Un nouveau cas se compose à partir des deux, sans ajouter de classe.

Axe 1 · variant

Le poids

Où l'action se situe dans la hiérarchie de l'écran, indépendamment de ce qu'elle fait : .primary, .secondary, .tertiary, ou aucune classe.

Axe 2 · tone

Le sens

Ce que l'action signifie. Par défaut le ton suit la variante ; .critical la bascule en rouge, .neutral lui retire sa couleur.

Axe 1 — le poids

Live Preview
Poids Classe Traitement Quand l'utiliser
Primary .btn.primary violet plein #8A3AAF L'action qui engage. Une seule par écran.
Secondary .btn.secondary contour --a2 · texte #8A3AAF L'action importante mais non engageante : valider, enregistrer, prévisualiser
Auto (défaut) .btn blanc + bordure --bd Les actions supplémentaires : annuler, fermer, exporter, filtrer, trier
Tertiary .btn.tertiary texte #8A3AAF seul Aucun poids visuel : au fil du texte, en tableau dense, ou icône seule en barre d'outils

Le violet porte directement le texte. Sur .secondary et .tertiary, #8A3AAF est appliqué tel quel : 6.35:1 sur blanc, AA pour du texte normal.

Axe 2 — le ton, sur n'importe quel poids

Live Preview — chaque ligne est un poids, chaque colonne un ton
Auto
Neutral
Critical
Primary
Secondary
Tertiary
Ton Classe Effet Quand l'utiliser
Auto (défaut) La couleur de la variante Tout le temps, sauf les deux cas ci-dessous
Critical .critical Rouge #B42318 Destructif. .critical seul pour proposer, .primary.critical pour la confirmation finale — l'unique bouton rouge plein du système.
Neutral .neutral Gris --t2 / noir --t1 Retire la couleur sans changer le poids : barres d'outils, actions répétées en tableau
<!-- Axe 1 : le poids -->
<button class="btn primary">Publier la formation</button>
<button class="btn secondary">Valider</button>
<button class="btn">Exporter</button>
<button class="btn tertiary">En savoir plus</button>

<!-- Axe 2 : le ton se pose par-dessus -->
<button class="btn critical">Supprimer</button>
<button class="btn primary critical">Supprimer définitivement</button>
<button class="btn tertiary neutral">Filtrer</button>

<!-- Un bouton qui navigue reste un bouton : <a> + les mêmes classes -->
<a href="/rapports" class="btn secondary">Voir les rapports</a>
<button type="submit" class="btn primary">Enregistrer</button>

3 — Les 4 tailles

Une seule classe change la hauteur, le padding, la taille de police et celle des icônes : les proportions restent justes à toutes les échelles.

Live Preview
xs · 26px
sm · 30px
md · 36px (défaut)
lg · 44px
Taille Hauteur Padding H · Police · Icône Contexte
.btn.xs 26px 10px · 12px · 13px Actions inline dans une cellule de tableau
.btn.sm 30px 12px · 12.5px · 14px En-têtes de widget, barres de filtres
.btn (md) 36px = --ch 16px · 13.5px · 16px Défaut : formulaires, topbar, actions de page
.btn.lg 44px 22px · 15px · 18px CTA isolé, empty state, pied de modale

4 — Icônes

L'icône se place avant le libellé quand elle décrit l'action, après quand elle annonce une suite (navigation, menu déroulant). Jamais deux icônes sur un même bouton.

Icône + libellé

Icône seule

Réservée aux interfaces denses — barres d'outils, en-têtes de widget, cellules de tableau — et aux icônes universellement comprises. Poids par défaut .tertiary. Le bouton devient carré (largeur = hauteur) et exige un aria-label, seule chose qu'un lecteur d'écran puisse annoncer.

Live Preview
Règle Détail
Taille 13 / 14 / 16 / 18px selon xs / sm / md / lg — pilotée par --btn-icon, jamais en dur
Jeu Eva Icons, variante outline, grille 24 × 24
Épaisseur stroke-width: 1.8 pour tout le système, quelle que soit la taille
Couleur stroke="currentColor" — l'icône suit le texte, donc la variante et le ton
Écart au libellé 5 / 6 / 8 / 10px selon la taille — --btn-gap
Icône seule aria-label obligatoire, décrivant l'action et son objet : « Supprimer la formation », pas « Supprimer »
Décoratif Une icône accompagnée d'un libellé est redondante pour l'assistance : aria-hidden="true" sur le SVG
<!-- Icône avant : décrit l'action -->
<button class="btn secondary"><svg aria-hidden="true">…</svg>Enregistrer</button>

<!-- Icône après : annonce une suite -->
<button class="btn primary">Étape suivante<svg aria-hidden="true">…</svg></button>

<!-- Icône seule : tertiary + aria-label décrivant l'objet -->
<button class="btn tertiary neutral icon-only" aria-label="Supprimer la formation">
  <svg>…</svg>
</button>

Formes

Pleine largeur · compteur
<button class="btn primary lg block">Valider</button>
<button class="btn">Filtrer<span class="btn-count">3</span></button>

5 — Les 6 états

Chaque variante assombrit au survol et s'enfonce d'1px au clic. Le focus utilise :focus-visible (anneau au clavier uniquement, jamais à la souris) et l'anneau reprend la teinte de la variante.

Live Preview — survolez, cliquez, puis naviguez au clavier (Tab)
Default
Hover
Pressed
Focus
Disabled
Loading
Démo réelle :
État Sélecteur Traitement Règle
Default .btn Couleur de base de la variante
Hover :hover Fond assombri, bordure suivie Transition 0.15s ease
Pressed :active Fond encore assombri + translateY(1px) Transition 0.06s : le clic doit être instantané
Focus :focus-visible box-shadow: 0 0 0 3px teinté à 28 % Jamais outline:none sans remplacement
Disabled :disabled Fond --bg, texte --t3, pointer-events:none Voir ci-dessous — c'est l'état le plus souvent mal employé
Loading .is-loading Contenu masqué + spinner ::after 0.6s La largeur reste figée : pas de saut de mise en page

Le cas du disabled

Un bouton désactivé ne prend pas le focus clavier et n'est donc jamais annoncé par un lecteur d'écran. Règle : désactiver seulement quand la raison est visible à côté du bouton. Sinon, le laisser actif et expliquer le blocage au clic.

Désactiver est justifié

  • La raison est écrite juste à côté : « Sélectionnez au moins une formation ».
  • Une étape précédente n'est pas finie et cela se voit à l'écran.
  • Le bouton est déjà en cours de traitement — mais alors c'est .is-loading, pas disabled.

Préférer un bouton actif

  • Un formulaire incomplet : laisser soumettre et signaler les champs en erreur.
  • Un droit manquant : afficher le bouton et expliquer au clic qui contacter.
  • Toute règle que l'utilisateur ne peut pas deviner en regardant l'écran.
Live Preview — disabled avec sa raison
Sélectionnez au moins un apprenant dans la liste
Point Traitement retenu
Rendu Toutes les variantes pleines ou bordées convergent vers le même gris : fond --bg, texte --t3, bordure --bd. Un disabled ne doit pas laisser deviner son poids, sinon il ressemble à un bouton actif terne. Seul .tertiary garde sa transparence — un rectangle gris à la place d'un lien serait plus visible désactivé qu'actif.
Jamais d'opacité opacity: .6 délave aussi la bordure et le fond de la page à travers le bouton, et donne un résultat différent sur chaque surface. Le gris est explicite et stable.
Contraste 2.54:1 texte sur fond. Sous WCAG 1.4.3, un composant inactif est exempté — c'est volontaire : un disabled trop lisible se confond avec un bouton actif.
Attribut disabled natif, pas une classe. Il retire le bouton de l'ordre de tabulation et bloque la soumission du formulaire, ce qu'une classe ne fait pas. .is-disabled n'existe que pour un <a>, qui n'accepte pas l'attribut.
Icône seule L'aria-label reste obligatoire même désactivé : le bouton redeviendra actif.
Disabled ≠ loading Disabled = « pas encore possible ». Loading = « en cours, patientez ». Pendant un envoi, utiliser .is-loading : le spinner dit que quelque chose se passe, le gris ne dit rien.
<!-- Disabled : l'attribut natif, et la raison à côté -->
<button class="btn primary" disabled>Inscrire les apprenants</button>
<span class="hint">Sélectionnez au moins un apprenant</span>

<!-- Loading : envelopper le contenu pour qu'il soit masqué -->
<button class="btn primary is-loading"><span>Publication…</span></button>

<!-- Un lien ne prend pas disabled : classe + aria -->
<a class="btn is-disabled" aria-disabled="true">Voir le rapport</a>

6 — Compositions

Groupe accolé · Split button · Segmented control
Button group — actions de même niveau
Split button — action par défaut + variantes
Segmented control — choix exclusif d'affichage
Barre d'actions — pied de modale

Ordre de lecture : action destructive à gauche, isolée par le spacer ; action de confirmation toujours en dernier, à droite — c'est la position que l'œil atteint en fin de parcours.

<div class="btn-group">
  <button class="btn sm">Liste</button>
  <button class="btn sm">Grille</button>
</div>

<div class="btn-split">
  <button class="btn secondary">Exporter en PDF</button>
  <button class="btn secondary" aria-label="Autres formats"><svg>…</svg></button>
</div>

<div class="btn-seg">
  <button class="active">Jour</button><button>Semaine</button>
</div>

<div class="btn-bar">
  <button class="btn critical">Supprimer</button>
  <span class="spacer"></span>
  <button class="btn">Annuler</button>
  <button class="btn primary">Enregistrer</button>
</div>

7 — Sur les sidebars sombres

Les deux sidebars sont violettes (#13041C, #0A032D) : le violet de marque n'y ressort qu'à 3.11:1, au seuil de 3:1 du WCAG 1.4.11. Sur ces surfaces, la variante primaire passe à --a-dark #9B4BC43.95:1 sur les deux fonds, texte blanc à 5.00:1. La variante neutre devient un fond blanc à 8 % d'opacité.

Sidebar Gestion — #13041C
Sidebar Reporting — #0A032D

8 — Règles d'usage

À faire

  • Une seule action .primary violette par écran.
  • Choisir d'abord le poids, puis le ton — jamais l'inverse.
  • Un verbe à l'infinitif, 1 à 3 mots : « Enregistrer », « Exporter en PDF ».
  • Placer la confirmation en dernier, à droite, dans une barre d'actions.
  • Toujours un aria-label sur un bouton icon-only, décrivant l'objet.
  • Passer en .is-loading dès la soumission pour bloquer le double-clic.
  • Sur les sidebars, ajouter .on-dark au primaire et .neutral-dark au neutre.

À éviter

  • Recréer une classe pour un cas particulier : c'est toujours un poids × un ton.
  • Deux .primary côte à côte : la hiérarchie disparaît.
  • Le violet pour une action ordinaire — il perd sa valeur d'appel.
  • opacity: 0.6 pour simuler un disabled : utiliser l'attribut disabled.
  • Désactiver un bouton sans écrire pourquoi juste à côté.
  • Supprimer l'anneau de focus sans le remplacer.
  • Mélanger deux tailles de boutons dans une même barre d'actions.
  • Le violet de marque sur une sidebar sans .on-dark : il se fond dans le fond.

Badges & Status

Utilisés pour indiquer un état (Terminé, En cours, Non commencé) ou une catégorie (SA, Siège Social).

Live Preview
Terminé En cours Non commencé Premium Mode Test

Blocs & Cartes (Widgets)

Les widgets de reporting utilisent des icônes colorées avec backgrounds spécifiques. Chaque thème a sa propre couleur d'accent pour une meilleure organisation visuelle.

Variantes d'icônes de widgets

Live Preview
Modules par mois
Inscriptions par mois
Répartition par groupe
Par sous-thème
Activité par heure
Taux de complétion

Palette d'icônes par contexte

Contexte Background Couleur SVG Usage
Stats / Modules #E0F8EF #10B981 Graphiques à barres vert
Inscriptions / Utilisateurs #EDE9FE #7C3AED Données de comptes violettes
Répartition / Groupes #FEF3C7 #B45309 Donut chart ambre — seule teinte chaude, aucune collision avec le violet de marque
Thèmes / Catégories #EFF6FF #3B82F6 Barres horizontales bleu
Activité / Temps #E0F2FE #0EA5E9 Line charts cyan
Profils / Utilisateurs #F3E8FF #A855F7 Données de profils violet clair

Formulaires

Pages de réglages longues, découpées en sections, sur deux colonnes. Motifs extraits de la page Paramètres → Carte de visite.

1 — Anatomie d'un champ

Live Preview
14 chiffres, sans espaces
Élément Traitement Règle
Label 12.5px · 700 · --t2 Toujours au-dessus, jamais à l'intérieur : un placeholder qui sert de label disparaît à la saisie
Obligatoire <span class="req">*</span> Astérisque violet collé au label. Quand une majorité de champs est obligatoire, marquer plutôt les champs facultatifs — moins de bruit
Champ 38px · --r · bordure --bd Plus haut que les boutons sm (30px) : la cible de saisie doit être confortable
Aide .form-hint Sous le champ, 12px --t3. Pour le format attendu, jamais pour répéter le label
Erreur .form-error Remplace l'aide, avec l'icône. Dit quoi corriger, pas seulement qu'il y a une erreur
Espacement gap 8px Entre le label et le champ, et entre le champ et son aide

2 — Contrôles & états

Live Preview
France
Suisse
Belgique
Attribué par la DREETS
Le code postal doit compter 5 chiffres
État Sélecteur Traitement
Repos .form-input Fond blanc, bordure --bd
Survol :hover Bordure #D6DAE1 — signale la cible avant le clic
Focus :focus Bordure --s + anneau 3px --s1 : le bleu est réservé à cet usage
Lecture seule [readonly] Fond --ps, texte --t1 conservé — la valeur reste lisible et sélectionnable
Désactivé :disabled Fond --bg, texte --t3 — même traitement que les boutons désactivés
Erreur .has-error Bordure et anneau --d, message sous le champ

Lecture seule n'est pas désactivé. Lecture seule : la valeur compte et doit rester lisible et copiable — texte en #0F172A, poids 500. Désactivé : le champ ne s'applique pas au contexte — texte en --t3.

3 — Groupement en sections

Toujours regrouper en .fs-block : un en-tête à icône, puis une .fs-card blanche qui contient les grilles. Les sections se posent sur deux colonnes — un bloc qui prend toute la largeur de la page étire les champs et casse la lecture.

Live Preview
Informations générales
<div class="fs-block">
  <div class="fs-header">
    <div class="fs-icon"><svg>…</svg></div>
    <div class="fs-title">Informations générales</div>
  </div>
  <div class="fs-card">
    <div class="form-grid col-full">…</div>
    <div class="form-grid">…</div>
  </div>
</div>

À faire — deux colonnes de sections

Informations générales
Références légales

À éviter — un bloc sur toute la largeur

Informations générales

Sur toute la largeur, un champ court comme « Code postal » s'étire sur 300px et les libellés s'éloignent de leurs valeurs. En deux colonnes, chaque section reste sous 560px : l'œil balaie une carte sans se déplacer.

4 — Import de fichier

Contraintes de poids et de format écrites avant la sélection.

Ligne compacte — un réglage parmi d'autres
Logo de l'entité
Importez le logo
Poids maximum 20 Mo · Formats : .png, .jpg, .svg
Signature visuelle
Importez la signature
Poids maximum 20 Mo · Sera apposée sur les documents officiels

5 — Choix & bascules

Cartes de choix — options exclusives à expliquer
Bascule — un réglage qui s'applique immédiatement
Activer le tutorat Onlineformapro
Associer des tuteurs aux apprenants pour un suivi personnalisé
Contrôle Classe Quand l'utiliser
Carte de choix .form-card-check 2 à 4 options exclusives dont chacune demande une phrase d'explication
Sélecteur .w-dd-wrap.block Au-delà de 5 options, ou quand les libellés se passent d'explication — le dropdown du système, en pleine largeur et à 38px
Bascule .form-switch Un réglage binaire qui prend effet immédiatement, sans enregistrer
Case à cocher .form-check-inline Une option secondaire qui n'est appliquée qu'à l'enregistrement du formulaire

6 — Plage de dates

Le déclencheur a le gabarit d'un dropdown de widget, icône calendrier en --a. Le panneau : les deux bornes en champs, un calendrier mensuel, une colonne de suggestions. La plage se lit en --a1, ses bornes en --a. Rien n'est appliqué avant « Appliquer ».

Live Preview — fermé
lun.
mar.
mer.
jeu.
ven.
sam.
dim.
Suggestions
Aujourd'hui
Cette semaine
Les 7 derniers jours
Les 30 derniers jours
Ce mois-ci
Cette année
Le mois dernier
L'année dernière
Live Preview — ouvert, cliquez deux jours ou une suggestion
lun.
mar.
mer.
jeu.
ven.
sam.
dim.
Suggestions
Aujourd'hui
Cette semaine
Les 7 derniers jours
Les 30 derniers jours
Ce mois-ci
Cette année
Le mois dernier
L'année dernière
Élément Classe Traitement
Déclencheur .drp-btn 32px · même fond que .w-dd-btn · icône calendrier --a · chevron
Panneau .drp-pop 640px · radius 14px · ombre 0 12px 32px
Bornes .drp-head .form-input 36px · 150px · lecture seule, remplies par le calendrier
Jour .drp-day 46px · 13px · autre mois en --t3
Dans la plage .drp-day.in fond --a1, texte --a
Bornes de la plage .drp-day.start / .end disque --a de 36px centré, texte blanc 600
Suggestions .drp-sug-item libellé 13.5px + dates en 11.5px --t3, calculées à l'ouverture
Pied .drp-foot Annuler puis Appliquer en .primary, filet haut
<div class="drp">
  <button class="drp-btn" onclick="drpOpen(this)"><svg class="cal">…</svg>
    <span class="lbl">janv. 1, 2025</span><span class="arr">→</span><span class="lbl2">déc. 31, 2025</span><svg class="chev">…</svg>
  </button>
  <div class="drp-pop" data-y="2025" data-m="11" data-start="2025-01-01" data-end="2025-12-31">…</div>
</div>

7 — Layout d'une page de réglages

Deux colonnes de sections, réparties par fréquence de modification : ce qui change souvent à gauche, ce qui est stable (références légales, signature) à droite.

Live Preview
Informations générales
Logo de l'entité
Importez le logo
20 Mo max · .png, .jpg
Références légales
EUR (€)
Signature visuelle
Importez la signature
Documents officiels
<div class="form-body">
  <div class="col"><!-- sections modifiées souvent --></div>
  <div class="col"><!-- sections stables --></div>
</div>

Iconographie

Jeu de référence : Eva Icons, variante outline, grille 24 × 24, rendu en currentColor. Les icônes ci-dessous sont celles du jeu, chargées depuis le paquet officiel — 187 sur les 490. Cliquer une icône copie son nom.

Navigation

home
menu
menu-2
arrow-back
arrow-forward
arrow-up
arrow-down
chevron-left
chevron-right
chevron-up
chevron-down
arrowhead-left
arrowhead-right
corner-down-left
corner-up-right
external-link
navigation-2
compass
map
pin
expand
collapse
maximize
minimize

Actions

plus
plus-circle
minus
minus-circle
close
close-circle
checkmark
checkmark-circle-2
edit
edit-2
trash-2
copy
save
download
upload
cloud-download
cloud-upload
refresh
sync
undo
search
funnel
options-2
settings-2
share
link-2
attach-2
printer
scissors
crop
move
swap
shuffle-2
flip-2

Contenu & fichiers

file
file-text
file-add
file-remove
folder
folder-add
folder-remove
archive
inbox
clipboard
book
book-open
bookmark
layers
layout
grid
list
text
hash
at
code
code-download
image
image-2
film
browser
cube

Personnes

person
person-add
person-delete
person-done
person-remove
people
smiling-face
award
briefcase
shield
lock
unlock
log-in
log-out
credit-card
gift
pricetags
shopping-bag
shopping-cart

Communication

email
message-circle
message-square
paper-plane
phone
phone-call
phone-missed
phone-off
bell
bell-off
mic
mic-off
headphones
video
video-off
globe-2
wifi
wifi-off
cast
monitor
smartphone
tv

Statut & feedback

info
question-mark-circle
alert-circle
alert-triangle
checkmark-square-2
close-square
radio-button-on
radio-button-off
toggle-left
toggle-right
loader
slash
flag
star
heart
eye
eye-off
bulb
flash
flash-off
power

Données & temps

bar-chart
bar-chart-2
pie-chart
pie-chart-2
trending-up
trending-down
activity
calendar
clock
percent
thermometer
battery
charging
hard-drive
keypad

Média & apparence

play-circle
pause-circle
stop-circle
skip-back
skip-forward
rewind-left
rewind-right
volume-up
volume-down
volume-mute
volume-off
music
speaker
camera
color-palette
color-picker
brush
pantone
droplet
sun
moon
umbrella
car
npm
Règle Détail
Variante outline partout. La variante fill n'est utilisée que pour un état actif de navigation
Tailles 13 / 14 / 16 / 18px dans les boutons selon xs / sm / md / lg ; 15px dans le menu gauche ; 18px en topbar ; 22px seul dans une cellule
Couleur fill: currentColor — l'icône prend la couleur du texte du composant qui la porte
Intégration <i data-eva="trash-2-outline"></i> puis eva.replace() au chargement, ou le SVG inline exporté depuis le site
Icône seule aria-label sur le bouton, aria-hidden="true" sur l'icône
<script src="https://cdn.jsdelivr.net/npm/eva-icons@1.1.3/eva.min.js"></script>
<button class="btn tertiary neutral icon-only" aria-label="Supprimer la formation">
  <i data-eva="trash-2-outline" aria-hidden="true"></i>
</button>
<script>eva.replace({ width: 16, height: 16 });</script>

Widgets Stats

Gabarit de widget utilisé dans la section Reporting → Stats pré-formatées : icône colorée + titre + ⓘ dans le header, contrôles à droite, corps vide avec empty-state.

Variante 1 — Badge + Unité + Période

Live Preview
Modules par mois
4 821
Aucune donnée trouvée, essayez d'autres filtres

Variante 2 — Ligne de filtres sous le header

Live Preview
Activité par heure · Dernière semaine
Aucune donnée trouvée, essayez d'autres filtres

Tableaux

Le tableau est la vue principale du produit. En-tête sur deux lignes — libellés puis filtres —, actions au survol de la ligne, pied de tableau avec pagination.

1 — Tableau complet

Live Preview — survolez une ligne
Nom E-mail Statut Groupe Inscription
Tous
Actif
Inactif
Tous
RH Central
Produit
Colonnes
Apprenant
État
E-mail
Identifiant
Groupes
Département
Rôle
Profil formations
Dernière connexion
Date de création
MG
Michèle GUERRIN
PDG
m.guerrin@onlineformapro.com Actif RH Central3 12 mars 2026
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
AD
Alan DRABCZYNSKI
Designer
a.drabczynski@onlineformapro.com Actif Produit 9 mars 2026
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
JD
Jean DUPONT
Formateur
j.dupont@onlineformapro.com Inactif Sécurité au travail 2 févr. 2026
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
SL
Sophie LEROY
Gestionnaire
s.leroy@onlineformapro.com Actif Management2 28 janv. 2026
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
TB
Thomas BERNARD
Formateur
t.bernard@onlineformapro.com Actif Sécurité au travail 21 janv. 2026
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
CM
Claire MOREAU
Responsable RH
c.moreau@onlineformapro.com Actif RH Central 14 janv. 2026
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
PR
Paul ROUSSEAU
Apprenant
p.rousseau@onlineformapro.com Inactif Management 8 janv. 2026
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
NL
Nadia LAMBERT
Gestionnaire
n.lambert@onlineformapro.com Actif Produit5 19 déc. 2025
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
KB
Karim BENALI
Formateur
k.benali@onlineformapro.com Actif RGPD 11 déc. 2025
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
EF
Émilie FONTAINE
Apprenante
e.fontaine@onlineformapro.com Inactif Sécurité au travail 3 déc. 2025
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
LG
Lucas GIRARD
Apprenant
l.girard@onlineformapro.com Actif RGPD 26 nov. 2025
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
AP
Anaïs PETIT
Responsable formation
a.petit@onlineformapro.com Actif Management 18 nov. 2025
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
12 résultats sur 128
Par page

2 — Couleurs de ligne

Les fonds de ligne sont neutres : une teinte colorée au survol entre en concurrence avec les statuts, qui eux portent du sens.

Live Preview
Ligne impaire Fond blanc #FFFFFF
Ligne paire --row-even #F9FAFB
Survol --row-hover #F1F3F5
Clic maintenu --row-active #E3E6EA
Token Valeur Usage
--row-even #F9FAFB Zébrure une ligne sur deux, assez faible pour ne pas hacher la lecture
--row-hover #F1F3F5 Survol — lisible aussi bien sur une ligne blanche que sur une ligne paire
--row-active #E3E6EA Clic maintenu, un cran plus foncé

3 — En-tête sur deux lignes

Élément Classe Traitement
Fond thead tr --ps · 11.5px · 600 · --t2 · casse normale
Ligne 1 — libellés .thr th padding 10px 14px, padding-bottom 6px, sans filet
Ligne 2 — filtres .thr-filter th padding-top 0, padding-bottom 12px, filet bas --bd
Champ de filtre .th-search 30px · radius 6px · focus --a + anneau 2px --a1
Colonne triable th.srt curseur pointer, texte --t1 au survol
Redimensionnement .rez 8px de large, filet 2px qui passe en --a et grandit au survol
Groupement .gsth / .gbtn colonne 44px, bouton 36px, actif sur --a1
Colonnes .cgear-th colonne 44px en fin de ligne, porte la roue crantée — voir 4

4 — Édition des colonnes

La roue crantée ferme la ligne de filtres, dans la colonne .cgear-th de 44px. Elle ouvre le panneau des colonnes : une case affiche ou masque la colonne dans le tableau, une poignée la réordonne par glisser-déposer. La première colonne est verrouillée. « Réinitialiser » rétablit l'ordre et la visibilité par défaut. Le panneau se ferme au clic en dehors ou avec Échap.

Live Preview — cochez une colonne, glissez une poignée
Apprenant État Groupes Profil formations Date de création
Colonnes
Apprenant
État
E-mail
Identifiant
Groupes
Département
Rôle
Profil formations
Dernière connexion
Date de création
Michèle GUERRIN Actif RH Central Management 12 mars 2026
Alan DRABCZYNSKI Actif Produit RGPD 9 mars 2026
Jean DUPONT Inactif Sécurité Sécurité au travail 2 févr. 2026
Sophie LEROY Actif Management Management 28 janv. 2026
Élément Classe Traitement
Roue crantée .cgear / .cgear.on 30px · --t3 · ouvert sur --a1 et --a
Panneau .cpanel 248px · ancré à droite sous la roue · ombre 0 8px 28px
En-tête .cph / .cprst « Colonnes » en 11.5px capitales, « Réinitialiser » en --a
Ligne .crow poignée --bd · case --a · libellé 13px · curseur grab
En déplacement .crow.dg fond --a1, opacité .7
Verrouillée .crow.lk poignée et case atténuées, pas de glisser

5 — Actions de ligne

Le bouton .rdots occupe la dernière colonne .catd et n'apparaît qu'au survol de la ligne. Il ouvre le menu .rmenu, ancré à droite : les actions courantes d'abord, puis, après un filet, les actions d'état et le destructif en rouge.

Live Preview — menu ouvert
Bouton au survol
Menu
Modifier l'apprenant
Affecter une formation
Affecter une évaluation
Ajouter au groupe
Message
Désactiver
Supprimer
Élément Classe Traitement
Colonne td.catd 44px en fin de ligne, position: relative pour ancrer le menu
Bouton .rdots 28px · bordure --bd · visible au survol de la ligne ou quand le menu est ouvert
Menu .rmenu / .rmenu.oo 220px min · ancré à droite · ombre 0 8px 30px
Entrée .rmi 13.5px · icône 17px --t2 · survol --ps
Séparateur .rmdiv 1px --bg, isole les actions d'état
Destructif .rmi.dn texte et icône en --d, toujours en dernier

6 — Pied de tableau & densité

Live Preview
4 résultats sur 128
Par page
Élément Classe Traitement
Pied .tfoot padding 10px 14px · fond --ps · filet haut --bg
Compteur .fi 12.5px --t3
Pagination .pb / .pb.on 28px · radius 7px · page courante sur --t1
Par page .lpp-btn 28px, même gabarit que la pagination
Mode compact .tcard.cmp cellules à 5px de padding, avatars et sous-titres masqués
<div class="tcard">
  <div class="tw">
    <table>
      <thead>
        <tr class="thr"><th class="srt">Nom<span class="rez"></span></th>…</tr>
        <tr class="thr-filter"><th><input class="th-search"></th>…</tr>
      </thead>
      <tbody>…</tbody>
    </table>
  </div>
  <div class="tfoot">compteur + pagination + par page</div>
</div>

L'application source cible les deux lignes d'en-tête par id (#thr, #thr-filter). Le système les expose en classes, un identifiant ne pouvant pas se répéter sur plusieurs tableaux d'une même page.

Layouts & Grilles

Systèmes de grille et de layout pour composer les pages. Tous les layouts incluent sidebar + main content area.

Layout 1 — Grid 1 col (Full)

Widget pleine largeur
<div style="display: grid; grid-template-columns: 1fr; gap: 20px;"> <div>Widget pleine largeur</div> </div>

Layout 2 — Grid 2 col (1:1)

Widget 50%
Widget 50%
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;"> <div>Widget 50%</div> <div>Widget 50%</div> </div>

Layout 3 — Grid 2 col (1:2) + Full

Widget 1/3
Widget 2/3
Widget pleine largeur
<div style="display: grid; grid-template-columns: 1fr 2fr; gap: 20px;"> <div>Widget 1/3</div> <div>Widget 2/3</div> <div style="grid-column: span 2;">Widget full</div> </div>

Layout 4 — Grid 3 col (1:1:1)

Widget 33%
Widget 33%
Widget 33%
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 20px;"> <div>Widget 33%</div> <div>Widget 33%</div> <div>Widget 33%</div> </div>

Templates de Pages

Le squelette d'une page : la topbar, le menu gauche, et le contenu vide. Seule l'entrée active du menu change d'une page à l'autre.

1 — Liste · une entrée de premier niveau active

2 — Réglages · une sous-entrée active, son groupe ouvert

3 — Dashboard · une entrée du bloc Reporting active

Zone Classe Traitement
Page body.app 100vh · fond --bg · colonne flex · overflow hidden
Corps .layout > .sidebar + .main .main défile seul, padding-top 56px sous la topbar
Contenu .content padding 24px 32px · tout le contenu de la page vit ici
Entrée active .ni.act · .ni-sub.act une seule par page · le groupe d'une sous-entrée porte .open
<body class="app">
  <header class="topbar">…</header>
  <div class="layout">
    <aside class="sidebar">…</aside>
    <main class="main">
      <div class="content"><!-- la page --></div>
    </main>
  </div>
  <script src="components.js" defer></script>
</body>

Modales & Overlays

Patterns pour les dialogs, popovers, date pickers et autres overlays.

Exemple : Import de photo

Modal Structure (Code)

<!-- MODAL DIALOG --> <div class="modal"> <div class="modal-header"> <div class="modal-icon">...</div> <div class="modal-title-wrap"> <div class="modal-title">Titre</div> <div class="modal-subtitle">Sous-titre</div> </div> <button class="modal-close">✕</button> </div> <div class="modal-body">...</div> <div class="modal-footer"> <button class="btn">Annuler</button> <button class="btn primary">Action</button> </div> </div>

États & Feedback

Tous les états des composants : hover, active, disabled, loading, error, success.

États des Boutons

Live Preview

Le détail des 6 états est documenté dans la section Boutons → 5.

États des Inputs

Live Preview
Ce champ est requis

États des Badges

Live Preview
Terminé En cours Non commencé Erreur

Messages & Notifications

Type Couleur Icône Usage
Success ✓ #059669 Check circle Action réussie
Error ✕ #DC2626 Alert circle Action échouée
Warning ⚠ #D97706 Alert triangle Attention requise
Info ℹ #3B82F6 Info circle Information

Transitions & Animations

Élément Transition Timing Use case
Boutons background 0.2s Easing: ease-out Hover / Active
Dropdown chevron transform 0.2s Easing: ease Rotation 180°
Charts bars height 0.4s Easing: ease Data load animation
Page transitions opacity 0.3s Easing: ease-in-out Route change

Ressources & téléchargements

Deux fichiers à importer dans une page, et les règles à donner à un assistant.

v1.0.0 mise en ligne le 15 septembre 2026 Les trois fichiers sortent ensemble et portent le même numéro. Vérifiez celui de votre copie dans l'en-tête du fichier.

<link rel="stylesheet" href="components.css">
<script src="components.js" defer></script>