Communitygithub.com

Formule de palette OKLCH

Construire ou migrer la palette neutre d'une UI (fonds, surfaces, lignes, encre/texte) sous forme d'une formule OKLCH pilotée par quelques entrées au lieu de dizaines de valeurs hexadécimales choisies à l'œil, avec thèmes clair et sombre, remplacements d'échelon par étape, un script d'ajustement qui reproduit les couleurs existantes, et un audit de contraste dans le navigateur.

Qu'est-ce que Formule de palette OKLCH ?

Cette compétence permet de remplacer les palettes de couleurs neutres (fonds, surfaces, lignes, texte) d'une UI, généralement constituées de 15 à 30 valeurs hexadécimales choisies manuellement, par une formule basée sur l'espace colorimétrique OKLCH. Elle est pilotée par seulement trois paramètres (teinte, clarté, chroma/contraste) et une échelle (ladder) par thème. Cela permet de retinter facilement un produit en modifiant une seule variable (`--hue`), de générer un thème sombre cohérent, et d'auditer automatiquement le contraste texte/fond pour garantir l'accessibilité WCAG. La compétence fournit des fichiers de référence (CSS), des scripts Python pour ajuster la formule à une palette existante, un audit de contraste dans le navigateur, et des utilitaires de conversion OKLCH. Elle est conçue pour être utilisée avec des tokens de design et s'intègre avec Tailwind v4.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Adamparishspok/skills/tree/HEAD/skills/oklch-palette-formula

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Que fait Formule de palette OKLCH ?

Les neutres d'un produit (fond de page, surface de carte, encarts, filets, quatre niveaux de texte) sont généralement 15 à 30 valeurs hexadécimales par thème, choisies à l'œil. Elles dérivent, le mode sombre est un second ensemble choisi à la main, et personne ne sait quelles paires passent encore le contraste. Remplacez-les par une formule :

token de type surface :  L = papier + profondeur × n(token)     chroma = teinte      hue = teinte
token de type encre  :  L = encre   + échelon × n(token)     chroma = teinte-encre  hue = teinte

n(token) est la position du token sur une échelle (ladder), une échelle par thème. Déplacez une entrée et toute la rampe se déplace ensemble, de sorte que les écarts entre les échelons, là où se trouve le contraste, survivent à une retinte. Retinter un produit est une seule ligne (--hue).

Trois boutons (--hue, --lightness, --chroma ou --contrast) pilotent chaque couleur.

Fichiers

  • references/palette.css : règles prêtes à l'emploi avec des entrées et échelles de démarrage.
  • scripts/fit_palette.py : ajuste les entrées à une palette hexadécimale existante et imprime ΔE par token.
  • scripts/ladders.json : les échelles par défaut (clair, sombre).
  • scripts/palette-audit.mjs : résout chaque token dans un vrai navigateur dans les deux thèmes et échoue sur le contraste.
  • scripts/oklch.py : conversions et aides ΔE / WCAG.

Procédure

  1. Nommez les tokens par leur rôle, pas par leur valeur. Les valeurs par défaut :

    • Fonds : ground (page), panel (rails, barres), surface (cartes, menus), surface-2 (encarts), surface-3 (chips, lignes survolées), field.
    • Lignes : line, line-2, line-3 (filets, du plus clair au plus foncé), plus field-line, le bord d'un champ, qui doit passer 3:1.
    • Encre : ink, ink-2, ink-3, ink-4 (texte, du plus foncé au plus discret). Chaque échelon d'encre est du texte, donc chacun doit passer 4.5:1.
  2. Ajustez, ne re-choisissez pas. Pour un produit existant, exécutez python3 scripts/fit_palette.py theme.css. Il lit les déclarations hexadécimales --color-* (clair, puis la règle [data-theme="dark"]), ajuste les entrées par rapport à l'échelle par défaut, et imprime ΔE par token. En dessous de 2, c'est visuellement identique.

  3. Remplacez les échelons de l'échelle là où le design les espace différemment, jamais la couleur. Évaluez les candidats avec fit_palette.py theme.css light '<entrées>' '<remplacements>' jusqu'à ce que le pire ΔE soit inférieur à ~2. Remplacements typiques : field: 0 (les champs sont la face de la carte), un line-3 plus large, un écart plus grand entre ink et ink-2.

  4. Écrivez les règles (voir references/palette.css) :

    • Placez les entrées et les formules --color-* sur l'élément qui porte l'attribut de thème.
    • Reformulez chaque entrée que vous modifiez dans la règle sombre. Une règle sombre écrite pour les valeurs par défaut du kit gagne sinon avec ses valeurs.
    • Avec Tailwind v4, conservez les noms de tokens dans @theme pour que les utilitaires existent ; les déclarations d'exécution les remplacent.
  5. Auditez dans un vrai navigateur : node scripts/palette-audit.mjs <url>. Il peint chaque token, lit le sRGB renvoyé, et vérifie :

    • chaque échelon d'encre à 4.5:1 contre chaque fond ;
    • field-line et ring à 3:1.

    Corrigez un ÉCHEC en déplaçant l'échelon de l'échelle de ce token, pas en spécialisant une couleur. Attendez-vous à des ÉCHECs sur les palettes existantes : dans une migration de 17 apps, l'audit a trouvé des valeurs ink-4 ou field-line défaillantes dans plus de la moitié d'entre elles, toutes déjà livrées.

Pièges

  • var() à l'intérieur d'une propriété personnalisée se résout là où elle est déclarée.
    • Déclarez les formules sur :root et définissez les entrées sur un enfant : l'enfant ne se recolorie jamais.
    • Les tokens alias (--color-heading: var(--color-ink)) doivent également être déclarés sur le même élément thématisé.
  • Les valeurs @theme de Tailwind v4 vivent sur :root. Un thème limité à une racine d'app ([data-app]) doit déclarer la formule là, pas dans @theme.
  • Tout ce qui transmet des couleurs à un canvas ou une bibliothèque cartographique (getComputedStyle(...).getPropertyValue('--color-x')) reçoit désormais une chaîne oklch(calc(...)) non résolue. Résolvez-la d'abord : peignez un élément sonde et lisez un canvas de 1 px, comme le fait l'audit.
  • Une seule teinte pour les fonds et les encres. Si les encres du design portent une teinte différente de leurs fonds, gardez --ink-tint bas ; à L 0.98, toute chroma se lit comme une dominante colorée.
  • Les couleurs de marque, de statut et de graphiques restent en dehors de la formule. Dérivez les variantes texte-sur-teinte (par exemple brand-text) de la même teinte à une clarté fixe plutôt que de les choisir séparément.
  • Les palettes à teinte mixte, uniquement claires, échantillonnées à partir de maquettes peuvent ne pas rentrer dans ~2 ΔE. Ignorez-les plutôt que de déformer le design. L'audit s'applique toujours.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

Adamparishspok/skills

Make a website, web app or online store ready for AI agents. Scan it with Cloudflare's Agent Readiness checks, decide which checks apply to this kind of site, ship the discovery files and headers in priority order, and add the AI-first basics the scanner does not score (server-rendered content, JSON-LD, llms.txt). Covers robots.txt AI rules, Content Signals, sitemap, Markdown for Agents (Accept text/markdown), Link headers, API catalog, OAuth discovery, auth.md, MCP server card, A2A agent card, agent skills index, WebMCP, and commerce protocols (ACP, UCP, AP2, MPP, x402). Use when making a site AI-ready, agent-ready or AI-first, or fixing an isitagentready.com or Cloudflare Agent Readiness report. Triggers on: AI ready, agent ready, AI-first, agent readiness, isitagentready, AI Crawl Control, Markdown for Agents, text/markdown, llms.txt, GPTBot, ClaudeBot, AI crawlers, Content-Signal, ai-train, api-catalog, .well-known, oauth-protected-resource, auth.md, MCP server card, agent card, agent skills, WebMCP, a...

Adamparishspok/skills

Install a complete, lean favicon set on any website or web app — the five files modern browsers, iOS and Android actually use, one block of head markup added once in the root layout, and a check that every file resolves. Covers finding the public folder per framework, generating the set from one SVG (or from a RealFaviconGenerator package), dark-mode SVG icons, maskable manifest icons, cache busting and verification. Use when adding, replacing or auditing a favicon, app icon, apple-touch-icon or web manifest. Triggers on: favicon, favicon.ico, favicon.svg, apple-touch-icon, site.webmanifest, manifest.json, app icon, PWA icon, maskable icon, tab icon, RealFaviconGenerator.

Adamparishspok/skills

Give an interface one shared tempo and a small vocabulary of hover and state micro-interactions: duration tiers (tap/pop/hover/card/layout) for CSS and Motion, swap hand-offs, rows whose highlight grows in, trailing arrows, chevron nudges, card lifts without translate, scroll-edge fades, and icon/label swaps for copy and toggle buttons. Use when animations feel inconsistent, durations are scattered magic numbers, hovers only change colour, or a product feels flat or unfinished. Triggers on: animation duration, transition timing, hover state, micro-interaction, polish, copy button feedback, menu icon to close, back arrow, card hover, scroll fade, motion tokens, Framer Motion durations.

Adamparishspok/skills

Consolidate several apps or prototypes onto one shared component library without flattening their looks. Covers finding duplicated local components (buttons, selects, fields, modals, pagers, toasts), making shared components token-sized so each suite or app sets its own measurements, mapping variant names, deciding what stays app-specific, and the tailwind-merge traps that silently break custom tokens. Use when several apps each grew their own Btn/Select/Modal, when a design system's components "don't fit" a second product, or when retheming a family of apps. Triggers on: shared component library, design system consolidation, duplicate components, retheme, suite of apps, shadcn retokened, token-driven components, cn tailwind-merge custom tokens, variant mapping.

Skills associés