Aller au contenu

Jetons

phil/ux-css

Chaque jeton est une propriété personnalisée de :root nommée --phil-*, dans l'un de trois fichiers : css/tokens/dimensions.css, css/tokens/palette.css et css/tokens/colors.css, chacun dans sa couche. Le CSS est la source ; dist/tokens.json donne les mêmes jetons aux outils de conception, au format du Design Tokens Community Group — voir Les jetons en JSON.

Les échelles

Chaque échelle est calculée à partir d'une unité et d'un multiplicateur global : un site change une échelle entière d'un coup.

MultiplicateurPar défautChange
--phil-scale1Les espaces et les rayons
--phil-scale-spacevar(--phil-scale)Les espaces
--phil-scale-text1Les tailles du texte
--phil-scale-radiusvar(--phil-scale)Les rayons
ÉchelleTaillesUnité
--phil-space-*3xs (⅛) 2xs (¼) xs (½) sm (¾) md (1) lg (1½) xl (2) 2xl (3) 3xl (4) 4xl (6)--phil-space-unit, 1rem
--phil-text-*xs sm md lg xl 2xl 3xl 4xl--phil-text-md, 1rem, sur le rapport --phil-text-ratio (1.25)
--phil-radius-*none sm (1) md (2) lg (4) xl (6) full--phil-radius-unit, 0.25rem
--phil-shadow-*sm md lgLeur couleur est --phil-color-shadow

Les autres dimensions : --phil-leading-tight et --phil-leading-md, --phil-measure (65ch) et --phil-measure-narrow (36ch), les piles de polices --phil-font-sans, --phil-font-serif et --phil-font-mono — celles du système, rien de téléchargé —, --phil-focus-width et --phil-focus-offset, les durées --phil-duration-sm, -md, -lg et -loop, et les courbes --phil-ease-out et --phil-ease-in-out.

JetonPar défautPour
--phil-weight-regular, -medium, -bold400, 500, 700Les graisses
--phil-border-sm, -md, -lg1px, 2px, 0.25remLes lignes et les filets
--phil-control-sm, -md, -lg2rem, 2.75rem, 3.25remLa hauteur d'un contrôle ; md est une cible tactile
--phil-check-size1.5remUne case à cocher, un bouton radio, la hauteur d'un interrupteur
--phil-panel-sm, -md, -lg20rem, 32rem, 48remLa largeur d'un menu, d'un dialogue, d'un panneau latéral
--phil-z-raised, --phil-z-overlay1, 10L'empilement dans la page
--phil-opacity-disabled0.55Ce qui est désactivé, la pulsation d'un squelette
--phil-mix-hover, --phil-mix-active12 %, 24 %De combien un remplissage va vers la couleur du texte

La palette

Sept teintes — neutral, brand, red, green, amber, blue, violet — de onze tons chacune, numérotés selon leur clarté OKLCH : --phil-brand-40 est oklch(0.40 …). Les neutres ajoutent 99, le presque blanc de la page.

Numéro0510203040506070809095
Clarté0.050.100.200.300.400.500.600.700.800.900.95

Puisque le numéro est la clarté, la différence de deux numéros donne le contraste, quelles que soient les teintes :

DifférenceContraste atteintPour
50 ou plus4,5:1Le texte de toute taille
40 ou plus3:1Le grand texte, les bordures, les icônes, les anneaux de focus

Chaque chroma est propre à sa teinte, tenu dans la gamme sRGB à chaque clarté : un ton paraît le même sur chaque écran.

Les rôles de couleur

Les composants lisent des rôles, jamais la palette. Chaque rôle est light-dark(<light tone>, <dark tone>).

RôleClairSombre
--phil-color-surfaceneutral 99neutral 10
--phil-color-surface-raisedneutral 95neutral 20
--phil-color-textneutral 10neutral 95
--phil-color-text-mutedneutral 40neutral 70
--phil-color-linkbrand 40brand 70
--phil-color-focusblue 50blue 70
--phil-color-borderneutral 80neutral 30
--phil-color-shadownoir à 12 %noir à 50 %
--phil-color-backdropnoir à 40 %noir à 60 %
--phil-color-veilnoir à 72 %noir à 72 %
--phil-color-on-veilblanc (clarté 0,99)blanc (clarté 0,99)
--phil-color-activity-0neutral 95neutral 20
--phil-color-activity-1brand 90brand 30
--phil-color-activity-2brand 70brand 50
--phil-color-activity-3brand 50brand 70
--phil-color-activity-4brand 30brand 90

La grille

Six rôles — brand, neutral, danger (rouge), success (vert), warning (ambre), info (bleu) — ont chacun six couleurs : un remplissage, une bordure et la couleur sur ce remplissage, chacun discret (une teinte légère) ou fort (plein).

PartieClairSombreEmploi
fill-quiet9520Le fond d'une teinte légère : un avis, une rangée choisie
fill-loud4070Le fond d'un plein : un bouton principal
border-quiet8030Une bordure décorative
border-loud5060Une bordure qu'il faut voir, 3:1 sur la surface
on-quiet3090Le texte et les icônes sur fill-quiet
on-loud9510Le texte et les icônes sur fill-loud
.isNotice {
    color: var(--phil-color-info-on-quiet);
    background: var(--phil-color-info-fill-quiet);
    border: 1px solid var(--phil-color-info-border-loud);
}

Les jetons en JSON

dist/tokens.json contient les jetons au format du W3C Design Tokens Community Group (2025.10), que lisent et écrivent les outils de conception. Il est produit à partir du CSS, qui reste la source, par la même commande que le fichier unique :

php bin/build.php    # from the package, after a change under css/

Les tests le comparent à un export des sources et échouent tant qu'il est périmé : l'intégration continue attrape un changement du CSS sans son JSON. Le paquet npm l'exporte en @phil/ux-css/tokens.json.

CSSJSON
--phil-space-smLe jeton sm du groupe space : le premier mot est le groupe, le reste le nom
--phil-scaleLe jeton $root du groupe scale : un nom d'un seul mot
var(--phil-brand-40)L'alias {brand.40}, du type de ce qu'il nomme
oklch(0.40 0.058 195 / 0.5)Une color : {"colorSpace": "oklch", "components": [0.4, 0.058, 195], "alpha": 0.5}
light-dark(A, B)La valeur de A ; la valeur de B sous dark dans l'extension du jeton
1rem, 2px et leurs calc()Une dimension, calc() calculé aux multiplicateurs par défaut : {"value": 0.75, "unit": "rem"}
150ms, 1sUne duration
1.25, 10Un number ; un fontWeight dans le groupe weight
Une liste de policesUne fontFamily, chaque famille sans guillemets
cubic-bezier(…)Une cubicBezier
0 1px 2px var(--phil-color-shadow), et leurs listesUne shadow, ou une liste d'ombres, chaque couleur un alias ou une valeur
0 parmi les longueurs d'un groupeUne dimension de 0px

Chaque jeton porte, sous l'extension ca.ph-il.phil-ux, sa propriété personnalisée et son CSS tel qu'il est écrit, pour qu'un outil qui réécrit du CSS garde les formules :

"sm": {
    "$type": "dimension",
    "$value": {"value": 0.75, "unit": "rem"},
    "$extensions": {
        "ca.ph-il.phil-ux": {"property": "--phil-space-sm", "css": "calc(var(--phil-space-unit) * 0.75)"}
    }
}

Une valeur pour laquelle le format n'a pas de type est laissée de côté, et nommée dans l'extension du fichier : --phil-measure et --phil-measure-narrow, en ch, et --phil-mix-hover et --phil-mix-active, en pourcentage. calc() n'est calculé que là où il est une simple arithmétique d'une unité — +, -, *, /, parenthèses et var() —, dans des bornes sur sa longueur, ses morceaux et la profondeur de var() ; Token\DesignTokens fait l'export et Token\Calc l'arithmétique, pour un site qui exporte ses propres surcharges :

use Phil\UxCss\Token\DesignTokens;
use Phil\UxCss\Token\TokenSheet;

$sources = [...DesignTokens::sources('vendor/phil/ux-css/css'), 'assets/theme.css'];
$json = DesignTokens::fromSheet(TokenSheet::fromFiles(...$sources))->toJson();