1 · Primitives
Le catalogue brut. Aucune sémantique, aucune référence. Jamais modifié par projet.
tokens/primitives/color.json est produit par
npm run ramps:write — ne l'édite pas à la main, il serait écrasé.
Les rampes de couleur
Chaque palette est définie par une teinte + un pic de chroma. Ses 11 crans sont calculés en OKLCH sur une courbe de luminosité commune à toutes les palettes.
Survole un aplat pour son hex et sa luminosité perçue (L*).
gray et 89 % en turquoise (un néon).
Un bouton primaire en turquoise donnait alors un contraste de 1,85:1 — illisible.
Comme les rôles sont interchangeables, un rôle sémantique ne peut tenir sa promesse de contraste
que si toutes les palettes partagent la même courbe. Après régénération : 4,60:1.
OKLCH et pas HSL : la luminosité HSL n'est pas perceptuelle — un
jaune et un bleu à L=50 % n'ont rien à voir à l'œil. OKLCH, si.
Les voiles alpha
Chaque teinte expose un voile translucide à 5 % et 10 % (colonnes α ci-dessus, sur damier), calculé sur son cran 500. Ils servent aux fonds d'états : survol et état actif d'un bouton outlined ou ghost, ligne de tableau sélectionnée.
color.alpha.*
séparé. Le rôle brand.primary alias la palette entière : changer la tonique
emporte donc l'alpha avec elle. Un groupe séparé obligerait à swapper deux fois — et un oubli
donnerait un bouton violet au survol turquoise.
Un voile se compose sur le fond qui est dessous : il s'adapte tout seul au thème sombre. Les tokens alpha sont donc identiques en light et dark.
Les échelles de taille
size.spacing
Échelle d'espacement brute. Sert aux paddings et aux gaps.
size.spacing.0 | 0 |
size.spacing.1 | 2px |
size.spacing.2 | 4px |
size.spacing.3 | 8px |
size.spacing.4 | 12px |
size.spacing.5 | 16px |
size.spacing.6 | 20px |
size.spacing.7 | 24px |
size.spacing.8 | 32px |
size.spacing.9 | 40px |
size.spacing.10 | 48px |
size.spacing.11 | 64px |
size.radius
Échelle d'arrondi brute.
size.radius.none | 0 |
size.radius.sm | 4px |
size.radius.md | 8px |
size.radius.lg | 16px |
size.radius.xl | 24px |
size.radius.full | 9999px |
size.border
Échelle d'épaisseur de bordure brute.
size.border.none | 0 |
size.border.sm | 1px |
size.border.md | 2px |
size.border.lg | 4px |
size.container
Largeurs de conteneur borné (modale, panneau, feuille). Le consommateur les combine avec un min(…, Nvw) pour rester responsive : le token donne la largeur MAXIMALE, pas une largeur figée.
size.container.sm | 360px |
size.container.md | 480px |
size.container.lg | 640px |
size.container.xl | 800px |
size.breakpoint
Points de rupture. Une media query CSS ne peut pas lire une custom property : la valeur est inlinée par le build.
size.breakpoint.xs | 480px |
size.breakpoint.sm | 640px |
size.breakpoint.md | 768px |
size.breakpoint.lg | 1024px |
size.breakpoint.xl | 1280px |
Les polices
Le catalogue typographique brut : piles de polices, graisses, interlignes, approches. Comme
les couleurs, rien n'est choisi ici — c'est le brand
qui désigne la pile qui joue heading, body et mono. C'est ici
qu'un rôle typo trouve sa weight, sa lineHeight et son letterSpacing.
font.stack
Catalogue de piles de polices. AUCUNE n'est choisie ici : c'est la couche brand (`font.brand.*`) qui désigne celle qui joue le rôle sans / serif / mono. Ajouter une pile ici ne change rien tant que le brand ne la sélectionne pas.
font.stack.inter | Inter, system-ui, -apple-system, sans-serif |
font.stack.geist | Geist, system-ui, -apple-system, sans-serif |
font.stack.systemSans | system-ui, -apple-system, 'Segoe UI', sans-serif |
font.stack.georgia | Georgia, 'Times New Roman', serif |
font.stack.jetbrainsMono | 'JetBrains Mono', ui-monospace, 'SF Mono', monospace |
font.stack.systemMono | ui-monospace, 'SF Mono', Menlo, monospace |
font.weight
font.weight.regular | 400 |
font.weight.medium | 500 |
font.weight.semibold | 600 |
font.weight.bold | 700 |
font.lineHeight
Sans unité : l'interligne se multiplie par le corps du texte, il suit donc la bascule mobile tout seul.
font.lineHeight.tight | 1.2 |
font.lineHeight.normal | 1.5 |
font.lineHeight.relaxed | 1.75 |
font.letterSpacing
En `em`, jamais en px : l'approche doit être PROPORTIONNELLE au corps, sinon un titre passé de 48px à 32px en mobile garderait un crénage calculé pour 48px. Le principe est optique — plus le texte est gros, plus on resserre ; plus il est petit ou capitalisé, plus on aère.
font.letterSpacing.tight | -0.02em |
font.letterSpacing.snug | -0.01em |
font.letterSpacing.normal | 0 |
font.letterSpacing.wide | 0.02em |
font.letterSpacing.caps | 0.08em |