Aller au contenu
Bibliotheque UIJABS

Themes et palettes 14 variantes

Cette categorie ne fournit pas de composants : elle montre les JETONS de css/theme.css. Tout le catalogue ne lit que ces variables. Changer une palette, c'est changer six lignes, sans toucher a un seul composant. Basculez la palette et le theme en haut a droite : chaque fiche suit.

A. Palettes

Les six palettes livrees, les jetons de surface, de texte et d'etat, et les contrastes verifies.

ardoiseDefaut, applications et CRM
vertElectricien, renovation energetique
orangePlombier, chauffagiste, artisan
violetProduit logiciel, SaaS
monoEditorial, brutaliste, luxe
nuitImmobilier, finance, premium
Les six palettes

Chaque palette definit exactement les memes 24 jetons, en clair et en sombre. Le choix se fait au metier du client, pas au gout du moment.

Voir le codeMasquer le code
<div class="thm-palettes">
  <div data-palette="ardoise"><span></span><span></span><span></span><span></span><strong>ardoise</strong><small>Defaut, applications et CRM</small></div>
  <div data-palette="vert"><span></span><span></span><span></span><span></span><strong>vert</strong><small>Electricien, renovation energetique</small></div>
  <div data-palette="orange"><span></span><span></span><span></span><span></span><strong>orange</strong><small>Plombier, chauffagiste, artisan</small></div>
  <div data-palette="violet"><span></span><span></span><span></span><span></span><strong>violet</strong><small>Produit logiciel, SaaS</small></div>
  <div data-palette="mono"><span></span><span></span><span></span><span></span><strong>mono</strong><small>Editorial, brutaliste, luxe</small></div>
  <div data-palette="nuit"><span></span><span></span><span></span><span></span><strong>nuit</strong><small>Immobilier, finance, premium</small></div>
</div>
.thm-palettes { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--sp-3); width: 100%; }
.thm-palettes > div {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  padding: var(--sp-3);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-surface);
}
.thm-palettes span { height: 34px; border-radius: var(--r-sm); }
.thm-palettes span:nth-child(1) { background: var(--c-primary); }
.thm-palettes span:nth-child(2) { background: var(--c-primary-soft); }
.thm-palettes span:nth-child(3) { background: var(--c-accent); }
.thm-palettes span:nth-child(4) { background: var(--c-text); }
.thm-palettes strong { grid-column: 1 / -1; margin-top: 6px; font-family: var(--font-mono); font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--c-text); }
.thm-palettes small  { grid-column: 1 / -1; font-size: var(--fs-xs); color: var(--c-text-muted); line-height: 1.4; }
&lt;body data-palette="orange" data-theme="light"&gt;
--c-bgFond de page
--c-surfaceCartes, panneaux
--c-surface-2Surface enfoncee, lignes alternees
--c-surface-3Survol de surface
--c-borderBordures neutres
--c-border-strongBordures marquees, pointilles
Jetons de surface

Les cinq niveaux de profondeur. Une interface qui n'en utilise que deux parait plate ; au-dela de cinq, la hierarchie devient illisible.

Voir le codeMasquer le code
<div class="thm-jetons">
  <div><i style="background:var(--c-bg)"></i><code>--c-bg</code><small>Fond de page</small></div>
  <div><i style="background:var(--c-surface)"></i><code>--c-surface</code><small>Cartes, panneaux</small></div>
  <div><i style="background:var(--c-surface-2)"></i><code>--c-surface-2</code><small>Surface enfoncee, lignes alternees</small></div>
  <div><i style="background:var(--c-surface-3)"></i><code>--c-surface-3</code><small>Survol de surface</small></div>
  <div><i style="background:var(--c-border)"></i><code>--c-border</code><small>Bordures neutres</small></div>
  <div><i style="background:var(--c-border-strong)"></i><code>--c-border-strong</code><small>Bordures marquees, pointilles</small></div>
</div>
.thm-jetons { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: var(--sp-2); width: 100%; }
.thm-jetons > div {
  display: grid;
  grid-template-columns: 38px 1fr;
  grid-template-areas: "puce code" "puce note";
  gap: 0 var(--sp-3);
  align-items: center;
  padding: var(--sp-2);
  border: 1px solid var(--c-border);
  border-radius: var(--r-sm);
  background: var(--c-surface);
}
.thm-jetons i { grid-area: puce; width: 38px; height: 38px; border-radius: var(--r-sm); border: 1px solid var(--c-border); }
.thm-jetons code { grid-area: code; font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--c-text); }
.thm-jetons small { grid-area: note; font-size: 11px; color: var(--c-text-muted); line-height: 1.35; }
var(--c-surface-2) etc. Aucun composant ne code une couleur en dur.

--c-text Texte principal, contraste 15:1 sur la surface

--c-text-soft Texte secondaire, paragraphes et descriptions

--c-text-muted Legendes, placeholders, unites

--c-primary-ink Liens et texte de marque sur fond clair

Jetons de texte

Trois niveaux, pas davantage. Le texte attenue sert aux legendes, jamais a une information necessaire a la comprehension.

Voir le codeMasquer le code
<div class="thm-textes">
  <p style="color:var(--c-text)"><code>--c-text</code> Texte principal, contraste 15:1 sur la surface</p>
  <p style="color:var(--c-text-soft)"><code>--c-text-soft</code> Texte secondaire, paragraphes et descriptions</p>
  <p style="color:var(--c-text-muted)"><code>--c-text-muted</code> Legendes, placeholders, unites</p>
  <p style="color:var(--c-primary-ink)"><code>--c-primary-ink</code> Liens et texte de marque sur fond clair</p>
</div>
.thm-textes { display: flex; flex-direction: column; gap: var(--sp-2); width: 100%; }
.thm-textes p { margin: 0; font-size: var(--fs-md); }
.thm-textes code { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: var(--fw-bold); margin-right: var(--sp-2); }
text-slate-900 / text-slate-600 / text-slate-400
--c-successValide, signe, paye
--c-warnEn attente, a verifier
--c-dangerErreur, refus, suppression
--c-infoInformation neutre
Couleurs d'etat

Quatre etats et leur fond doux. Le fond doux sert aux bandeaux et aux etiquettes ; la couleur pleine, au texte et aux icones.

Voir le codeMasquer le code
<div class="thm-etats">
  <div><i style="background:var(--c-success)"></i><i style="background:var(--c-success-soft)"></i><code>--c-success</code><small>Valide, signe, paye</small></div>
  <div><i style="background:var(--c-warn)"></i><i style="background:var(--c-warn-soft)"></i><code>--c-warn</code><small>En attente, a verifier</small></div>
  <div><i style="background:var(--c-danger)"></i><i style="background:var(--c-danger-soft)"></i><code>--c-danger</code><small>Erreur, refus, suppression</small></div>
  <div><i style="background:var(--c-info)"></i><i style="background:var(--c-info-soft)"></i><code>--c-info</code><small>Information neutre</small></div>
</div>
.thm-etats { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--sp-2); width: 100%; }
.thm-etats > div {
  display: grid;
  grid-template-columns: 26px 26px 1fr;
  grid-template-areas: "p1 p2 code" "p1 p2 note";
  gap: 0 var(--sp-2);
  align-items: center;
  padding: var(--sp-2);
  border: 1px solid var(--c-border);
  border-radius: var(--r-sm);
  background: var(--c-surface);
}
.thm-etats i { width: 26px; height: 38px; border-radius: var(--r-xs); }
.thm-etats i:nth-child(1) { grid-area: p1; }
.thm-etats i:nth-child(2) { grid-area: p2; }
.thm-etats code { grid-area: code; font-family: var(--font-mono); font-size: 11px; font-weight: var(--fw-bold); color: var(--c-text); }
.thm-etats small { grid-area: note; font-size: 11px; color: var(--c-text-muted); }
--c-success / --c-success-soft, et ainsi de suite
Texte sur surface15,8:1 — AAA
Texte attenue7,9:1 — AAA
Legende4,6:1 — AA
Bouton plein5,9:1 — AA
Bouton tonal7,2:1 — AAA
Bouton destructif4,8:1 — AA
Contrastes verifies

Chaque paire couramment utilisee, avec son rapport de contraste. Le minimum est 4,5:1 pour du texte courant, 3:1 pour un bouton sur son fond.

Voir le codeMasquer le code
<div class="thm-contraste">
  <div style="background:var(--c-surface);color:var(--c-text)"><strong>Texte sur surface</strong><span>15,8:1 &mdash; AAA</span></div>
  <div style="background:var(--c-surface);color:var(--c-text-soft)"><strong>Texte attenue</strong><span>7,9:1 &mdash; AAA</span></div>
  <div style="background:var(--c-surface);color:var(--c-text-muted)"><strong>Legende</strong><span>4,6:1 &mdash; AA</span></div>
  <div style="background:var(--c-primary);color:var(--c-primary-text)"><strong>Bouton plein</strong><span>5,9:1 &mdash; AA</span></div>
  <div style="background:var(--c-primary-soft);color:var(--c-primary-ink)"><strong>Bouton tonal</strong><span>7,2:1 &mdash; AAA</span></div>
  <div style="background:var(--c-danger);color:#fff"><strong>Bouton destructif</strong><span>4,8:1 &mdash; AA</span></div>
</div>
.thm-contraste { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: var(--sp-2); width: 100%; }
.thm-contraste > div { display: flex; flex-direction: column; gap: 3px; padding: var(--sp-3); border-radius: var(--r-sm); border: 1px solid var(--c-border); }
.thm-contraste strong { font-size: var(--fs-sm); font-weight: var(--fw-bold); }
.thm-contraste span { font-size: 11px; opacity: .8; }
a verifier avec un outil de contraste apres toute modification de palette

B. Echelles

Typographie, graisses, espacement en pas de 4 px, rayons, ombres, durees de transition.

Titre de page clamp(26px, 4vw, 40px)

Titre de section --fs-xl : 18px

Titre de carte --fs-lg : 16px

Texte courant, celui des paragraphes et des champs --fs-md : 14px

Texte dense, tableaux et listes --fs-sm : 13px

Legende, unite, mention --fs-xs : 12px

Echelle typographique

Cinq tailles suffisent a toute une interface. Le titre de page est le seul a utiliser une taille fluide, calculee par clamp().

Voir le codeMasquer le code
<div class="thm-typo">
  <p style="font-size:clamp(26px,4vw,40px);font-weight:800;letter-spacing:-.03em">Titre de page <code>clamp(26px, 4vw, 40px)</code></p>
  <p style="font-size:var(--fs-xl);font-weight:700">Titre de section <code>--fs-xl : 18px</code></p>
  <p style="font-size:var(--fs-lg);font-weight:600">Titre de carte <code>--fs-lg : 16px</code></p>
  <p style="font-size:var(--fs-md)">Texte courant, celui des paragraphes et des champs <code>--fs-md : 14px</code></p>
  <p style="font-size:var(--fs-sm)">Texte dense, tableaux et listes <code>--fs-sm : 13px</code></p>
  <p style="font-size:var(--fs-xs);color:var(--c-text-muted)">Legende, unite, mention <code>--fs-xs : 12px</code></p>
</div>
.thm-typo { display: flex; flex-direction: column; gap: var(--sp-3); width: 100%; }
.thm-typo p { margin: 0; line-height: 1.3; color: var(--c-text); }
.thm-typo code { font-family: var(--font-mono); font-size: 11px; font-weight: var(--fw-normal); color: var(--c-text-muted); margin-left: var(--sp-2); }
text-xs / text-sm / text-base / text-lg / text-xl

Normal 400 --fw-normal

Moyen 500 --fw-medium - libelles de champ

Demi-gras 600 --fw-semi - boutons, titres de carte

Gras 700 --fw-bold - titres, valeurs


48 250,00   1 890,00   12 400,00 tabular-nums

48 250,00   1 890,00   12 400,00 proportionnel, a eviter

Graisses et chiffres

Quatre graisses. Les chiffres d'un tableau ou d'un montant sont toujours tabulaires : sans cela, les colonnes tremblent a chaque mise a jour.

Voir le codeMasquer le code
<div class="thm-typo">
  <p style="font-weight:400">Normal 400 <code>--fw-normal</code></p>
  <p style="font-weight:500">Moyen 500 <code>--fw-medium</code> - libelles de champ</p>
  <p style="font-weight:600">Demi-gras 600 <code>--fw-semi</code> - boutons, titres de carte</p>
  <p style="font-weight:700">Gras 700 <code>--fw-bold</code> - titres, valeurs</p>
  <hr>
  <p style="font-variant-numeric:tabular-nums;font-weight:600">48 250,00 &nbsp; 1 890,00 &nbsp; 12 400,00 <code>tabular-nums</code></p>
  <p style="font-weight:600">48 250,00 &nbsp; 1 890,00 &nbsp; 12 400,00 <code>proportionnel, a eviter</code></p>
</div>
.thm-typo hr { width: 100%; border: none; border-top: 1px solid var(--c-border); margin: var(--sp-1) 0; }
font-medium / font-semibold / font-bold / tabular-nums
--sp-14px
--sp-28px
--sp-312px
--sp-416px
--sp-624px
--sp-832px
--sp-1248px
--sp-1664px
Echelle d'espacement

Une echelle de 4 px. Toute marge du catalogue est un multiple : c'est ce qui donne le rythme, plus surement qu'un alignement a l'oeil.

Voir le codeMasquer le code
<div class="thm-espaces">
  <div><i style="width:4px"></i><code>--sp-1</code><small>4px</small></div>
  <div><i style="width:8px"></i><code>--sp-2</code><small>8px</small></div>
  <div><i style="width:12px"></i><code>--sp-3</code><small>12px</small></div>
  <div><i style="width:16px"></i><code>--sp-4</code><small>16px</small></div>
  <div><i style="width:24px"></i><code>--sp-6</code><small>24px</small></div>
  <div><i style="width:32px"></i><code>--sp-8</code><small>32px</small></div>
  <div><i style="width:48px"></i><code>--sp-12</code><small>48px</small></div>
  <div><i style="width:64px"></i><code>--sp-16</code><small>64px</small></div>
</div>
.thm-espaces { display: flex; flex-direction: column; gap: 6px; width: 100%; }
.thm-espaces > div { display: flex; align-items: center; gap: var(--sp-3); }
.thm-espaces i { height: 18px; border-radius: 2px; background: var(--c-primary); flex: none; }
.thm-espaces code { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--c-text); min-width: 62px; }
.thm-espaces small { font-size: 11px; color: var(--c-text-muted); }
p-1 / p-2 / p-3 / p-4 / p-6 / p-8 / p-12 / p-16
0Brutaliste, technique
--r-sm6px, elements denses
--r-md10px, defaut
--r-lg16px, cartes, panneaux
--r-xl24px, tiroirs, modales
--r-fullPilules, avatars
Rayons

Le rayon donne le ton : anguleux pour un outil technique, doux pour un service grand public. Un seul rayon dominant par projet.

Voir le codeMasquer le code
<div class="thm-rayons">
  <div><i style="border-radius:0"></i><code>0</code><small>Brutaliste, technique</small></div>
  <div><i style="border-radius:var(--r-sm)"></i><code>--r-sm</code><small>6px, elements denses</small></div>
  <div><i style="border-radius:var(--r-md)"></i><code>--r-md</code><small>10px, defaut</small></div>
  <div><i style="border-radius:var(--r-lg)"></i><code>--r-lg</code><small>16px, cartes, panneaux</small></div>
  <div><i style="border-radius:var(--r-xl)"></i><code>--r-xl</code><small>24px, tiroirs, modales</small></div>
  <div><i style="border-radius:var(--r-full)"></i><code>--r-full</code><small>Pilules, avatars</small></div>
</div>
.thm-rayons { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--sp-3); width: 100%; }
.thm-rayons > div { display: flex; flex-direction: column; gap: 4px; }
.thm-rayons i { height: 54px; background: var(--c-primary-soft); border: 2px solid var(--c-primary); }
.thm-rayons code { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--c-text); }
.thm-rayons small { font-size: 11px; color: var(--c-text-muted); line-height: 1.35; }
rounded-none / rounded-md / rounded-lg / rounded-2xl / rounded-full
--sh-1Bouton, champ
--sh-2Carte survolee
--sh-3Menu, notification
--sh-4Modale, tiroir
Ombres

Quatre niveaux d'elevation. Plus l'element est haut, plus l'ombre est large ET diffuse : une ombre dure a la meme taille parait fausse.

Voir le codeMasquer le code
<div class="thm-ombres">
  <div><i style="box-shadow:var(--sh-1)"></i><code>--sh-1</code><small>Bouton, champ</small></div>
  <div><i style="box-shadow:var(--sh-2)"></i><code>--sh-2</code><small>Carte survolee</small></div>
  <div><i style="box-shadow:var(--sh-3)"></i><code>--sh-3</code><small>Menu, notification</small></div>
  <div><i style="box-shadow:var(--sh-4)"></i><code>--sh-4</code><small>Modale, tiroir</small></div>
</div>
.thm-ombres { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--sp-5); width: 100%; padding: var(--sp-2) 0 var(--sp-4); }
.thm-ombres > div { display: flex; flex-direction: column; gap: 4px; }
.thm-ombres i { height: 58px; border-radius: var(--r-md); background: var(--c-surface); }
.thm-ombres code { font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--c-text); }
.thm-ombres small { font-size: 11px; color: var(--c-text-muted); }
shadow-sm / shadow / shadow-lg / shadow-2xl
--t-fast120 ms, survol, couleur
--t-base200 ms, defaut
--t-slow320 ms, apparition de panneau
--t-spring420 ms, ressort, objets qui glissent

Survolez une piste pour comparer. Toutes ces durees tombent a zero quand le systeme demande de reduire les animations (prefers-reduced-motion).

Mouvement

Quatre durees. Au-dela de 320 ms une transition d'interface se ressent comme une lenteur ; le ressort ne sert qu'aux objets qui se deplacent.

Voir le codeMasquer le code
<div class="thm-mouvement">
  <div><i class="thm-bille" style="transition-duration:120ms"></i><code>--t-fast</code><small>120 ms, survol, couleur</small></div>
  <div><i class="thm-bille" style="transition-duration:200ms"></i><code>--t-base</code><small>200 ms, defaut</small></div>
  <div><i class="thm-bille" style="transition-duration:320ms"></i><code>--t-slow</code><small>320 ms, apparition de panneau</small></div>
  <div><i class="thm-bille" style="transition:transform 420ms cubic-bezier(.34,1.56,.64,1)"></i><code>--t-spring</code><small>420 ms, ressort, objets qui glissent</small></div>
</div>
<p class="thm-note">Survolez une piste pour comparer. Toutes ces durees tombent a zero quand le systeme demande de reduire les animations (<code>prefers-reduced-motion</code>).</p>
.thm-mouvement { display: flex; flex-direction: column; gap: var(--sp-3); width: 100%; }
.thm-mouvement > div {
  --course: 180px;
  display: grid;
  grid-template-columns: 1fr 90px;
  grid-template-areas: "piste code" "piste note";
  gap: 0 var(--sp-3);
  align-items: center;
}
.thm-mouvement > div::before {
  content: "";
  grid-area: piste;
  grid-row: 1 / -1;
  height: 26px;
  border-radius: var(--r-full);
  background: var(--c-surface-2);
  border: 1px solid var(--c-border);
}
.thm-bille {
  grid-area: piste;
  grid-row: 1 / -1;
  justify-self: start;
  width: 20px; height: 20px;
  margin-left: 3px;
  border-radius: 50%;
  background: var(--c-primary);
  transition-property: transform;
  transition-timing-function: cubic-bezier(.4,0,.2,1);
}
/* La bille traverse la piste au survol : la duree se compare a l'oeil. */
.thm-mouvement > div:hover .thm-bille { transform: translateX(var(--course, 200px)); }
.thm-mouvement code { grid-area: code; font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--c-text); }
.thm-mouvement small { grid-area: note; font-size: 11px; color: var(--c-text-muted); line-height: 1.3; }
.thm-note { margin: var(--sp-3) 0 0; font-size: var(--fs-xs); color: var(--c-text-muted); line-height: 1.5; }
.thm-note code { font-family: var(--font-mono); }
duration-100 / duration-200 / duration-300 + cubic-bezier(.34,1.56,.64,1)

C. Mise en pratique

Le meme ecran dans six palettes, clair et sombre cote a cote, et la recette pour ajouter la couleur d'un client.

ardoise
Devis 2026-1034 280,00 EURSignerModifier
vert
Devis 2026-1034 280,00 EURSignerModifier
orange
Devis 2026-1034 280,00 EURSignerModifier
violet
Devis 2026-1034 280,00 EURSignerModifier
mono
Devis 2026-1034 280,00 EURSignerModifier
nuit
Devis 2026-1034 280,00 EURSignerModifier
Le meme ecran dans six palettes

La preuve que rien n'est code en dur : le meme balisage, six identites. C'est ce qui permet de livrer six sites d'artisan sans dupliquer le CSS.

Voir le codeMasquer le code
<div class="thm-apercus">
  <div data-palette="ardoise"><span class="thm-apercu__nom">ardoise</span><div class="thm-apercu"><b>Devis 2026-103</b><em>4 280,00 EUR</em><span class="btn btn--plein btn--sm">Signer</span><span class="btn btn--secondaire btn--sm">Modifier</span></div></div>
  <div data-palette="vert"><span class="thm-apercu__nom">vert</span><div class="thm-apercu"><b>Devis 2026-103</b><em>4 280,00 EUR</em><span class="btn btn--plein btn--sm">Signer</span><span class="btn btn--secondaire btn--sm">Modifier</span></div></div>
  <div data-palette="orange"><span class="thm-apercu__nom">orange</span><div class="thm-apercu"><b>Devis 2026-103</b><em>4 280,00 EUR</em><span class="btn btn--plein btn--sm">Signer</span><span class="btn btn--secondaire btn--sm">Modifier</span></div></div>
  <div data-palette="violet"><span class="thm-apercu__nom">violet</span><div class="thm-apercu"><b>Devis 2026-103</b><em>4 280,00 EUR</em><span class="btn btn--plein btn--sm">Signer</span><span class="btn btn--secondaire btn--sm">Modifier</span></div></div>
  <div data-palette="mono"><span class="thm-apercu__nom">mono</span><div class="thm-apercu"><b>Devis 2026-103</b><em>4 280,00 EUR</em><span class="btn btn--plein btn--sm">Signer</span><span class="btn btn--secondaire btn--sm">Modifier</span></div></div>
  <div data-palette="nuit"><span class="thm-apercu__nom">nuit</span><div class="thm-apercu"><b>Devis 2026-103</b><em>4 280,00 EUR</em><span class="btn btn--plein btn--sm">Signer</span><span class="btn btn--secondaire btn--sm">Modifier</span></div></div>
</div>
.thm-apercus { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: var(--sp-3); width: 100%; }
.thm-apercu__nom { display: block; margin-bottom: 5px; font-family: var(--font-mono); font-size: 11px; font-weight: var(--fw-bold); color: var(--c-text-muted); }
.thm-apercu {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  background: var(--c-bg);
}
.thm-apercu b  { width: 100%; font-size: var(--fs-sm); color: var(--c-text); }
.thm-apercu em { width: 100%; margin-bottom: 4px; font-style: normal; font-size: var(--fs-lg); font-weight: 800; color: var(--c-text); }
un seul balisage, l'attribut data-palette change tout
light
Dossier 2026-103Krissi Julien SigneA poser Ouvrir
dark
Dossier 2026-103Krissi Julien SigneA poser Ouvrir
Clair et sombre cote a cote

Le mode sombre n'est pas une inversion : les surfaces s'eclaircissent avec l'elevation, alors qu'en clair elles s'assombrissent.

Voir le codeMasquer le code
<div class="thm-deux">
  <div data-theme="light"><span class="thm-apercu__nom">light</span>
    <div class="thm-apercu"><b>Dossier 2026-103</b><em>Krissi Julien</em>
      <span class="doc-etiq doc-etiq--ok">Signe</span><span class="doc-etiq doc-etiq--attente">A poser</span>
      <span class="btn btn--plein btn--sm">Ouvrir</span></div></div>
  <div data-theme="dark"><span class="thm-apercu__nom">dark</span>
    <div class="thm-apercu"><b>Dossier 2026-103</b><em>Krissi Julien</em>
      <span class="doc-etiq doc-etiq--ok">Signe</span><span class="doc-etiq doc-etiq--attente">A poser</span>
      <span class="btn btn--plein btn--sm">Ouvrir</span></div></div>
</div>
.thm-deux { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); width: 100%; }
.thm-deux > div { padding: var(--sp-3); border-radius: var(--r-md); background: var(--c-bg); border: 1px solid var(--c-border); }
@media (max-width: 560px) { .thm-deux { grid-template-columns: 1fr; } }
&lt;html data-theme="dark"&gt; ou aucun attribut pour suivre le reglage systeme
/* Palette d'un client, dans son propre fichier */
[data-palette="client"] {
  --c-primary:       #b8002e;   /* la couleur de la marque */
  --c-primary-hover: #99001f;   /* 10 % plus sombre */
  --c-primary-press: #7a0018;   /* 20 % plus sombre */
  --c-primary-soft:  #ffe4e9;   /* la meme a 8 % d'opacite sur blanc */
  --c-primary-text:  #ffffff;   /* ce qui s'ecrit SUR primary */
  --c-primary-ink:   #99001f;   /* primary lisible sur fond clair */
  --c-focus:         #b8002e;
}

Sept lignes. Aucun composant n'est touche. Verifier ensuite deux contrastes : --c-primary-text sur --c-primary (3:1 minimum) et --c-primary-ink sur --c-surface (4,5:1 minimum).

Personnaliser une palette

Pour un client dont la couleur est imposee : redefinir les six jetons de marque, laisser les autres. Le reste du catalogue suit tout seul.

Voir le codeMasquer le code
<div class="thm-recette">
  <pre><code>/* Palette d'un client, dans son propre fichier */
[data-palette="client"] {
  --c-primary:       #b8002e;   /* la couleur de la marque */
  --c-primary-hover: #99001f;   /* 10 % plus sombre */
  --c-primary-press: #7a0018;   /* 20 % plus sombre */
  --c-primary-soft:  #ffe4e9;   /* la meme a 8 % d'opacite sur blanc */
  --c-primary-text:  #ffffff;   /* ce qui s'ecrit SUR primary */
  --c-primary-ink:   #99001f;   /* primary lisible sur fond clair */
  --c-focus:         #b8002e;
}</code></pre>
  <p class="thm-note">Sept lignes. Aucun composant n'est touche. Verifier ensuite deux contrastes : <code>--c-primary-text</code> sur <code>--c-primary</code> (3:1 minimum) et <code>--c-primary-ink</code> sur <code>--c-surface</code> (4,5:1 minimum).</p>
</div>
.thm-recette pre {
  margin: 0;
  padding: var(--sp-4);
  border-radius: var(--r-md);
  background: #12151b;
  color: #d5dde8;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.65;
  overflow-x: auto;
}
etendre theme.css, ne jamais surcharger un composant