Que fait Icon Forge ?
Dessinez des icônes personnalisées qui ressemblent à celles d'un jeu professionnel, et livrez-les sans dépendances d'exécution. Vous avez terminé lorsque chaque icône passe le lint, que vous avez regardé la prévisualisation 16/20/24px et qu'elle est nette et cohérente sur fond clair et sombre, et que les composants générés sont intégrés avec une utilisation accessible.
<skill> ci-dessous désigne le dossier contenant ce fichier (par exemple .claude/skills/icon-forge, .cursor/skills/icon-forge, .agents/skills/icon-forge). Les scripts nécessitent Node ≥18 et aucune dépendance de projet.
Quand l'utiliser / quand ne pas l'utiliser
- À utiliser : une barre latérale, une barre de navigation, un tableau de bord, une page de paramètres, un état vide ou une barre d'outils a besoin d'icônes ; l'utilisateur demande une icône personnalisée ou manquante ; l'utilisateur souhaite remplacer des émojis/icônes de substitution ou un package d'icônes lourd par un petit jeu maison.
- Ne pas utiliser : logos et marques (marques déposées ; besoin d'un designer), favicons/icônes d'application, illustrations ou vignettes, photos/raster, Lottie animé. Si l'utilisateur demande explicitement d'installer une bibliothèque (par exemple « utilise Lucide »), faites ce qu'il demande ; ce skill existe pour la voie personnalisée.
Règles strictes (et pourquoi)
- Dessinez chaque icône vous-même ; n'ajoutez aucune dépendance de bibliothèque d'icônes. L'utilisateur a choisi ses propres icônes pour la taille du bundle et un look unique. Ne collez pas des données de chemin de Lucide, Heroicons, Material, etc. (licence et originalité). Utilisez
references/glyph-cookbook.md(dessins originaux) comme géométrie de départ. - Si le projet utilise déjà une bibliothèque d'icônes, correspond à sa grille, son trait, ses extrémités et son rayon (voir
scripts/detect.mjset design-rules §10). Les nouvelles icônes doivent se placer à côté des existantes sans paraître étrangères. - Un jeu, un style. Même grille, largeur de trait, extrémités/joins, échelle de rayon, espacement et niveau de détail pour chaque icône. La cohérence est plus importante qu'une icône individuelle astucieuse.
- Les attributs de présentation résident uniquement sur le
<svg>racine, la couleur estcurrentColor, et les sources ne contiennent ni id, ni style, ni classe, ni transform, ni<g>. Sinon, le theming, le mode sombre, la propstrokeWidthet l'inline sont cassés. - Ne prétendez jamais qu'une icône est bonne sans la rendre et visualiser le PNG. Une géométrie qui semble correcte dans le code échoue systématiquement à 16px : blobs, espaces fermés, formes décentrées, poids inégal.
- Exécutez les scripts ; ne les réimplémentez pas. Le lint, l'optimisation, la prévisualisation et la génération de code sont déterministes. Ne modifiez jamais manuellement les fichiers générés ; modifiez
icons/src/et reconstruisez. - Ne modifiez pas les dépendances de l'utilisateur. Les outils de prévisualisation s'installent dans
~/.cache/icon-forge(--install) ; SVGO s'exécute vianpxs'il est absent. Demandez avant d'ajouter un package au projet. - Accessible par défaut. Les icônes sont
aria-hiddensauf si elles sont étiquetées ; les contrôles icon-seuls obtiennentaria-label; les cibles interactives ≥44px ; les icônes significatives ≥3:1 contraste.
Flux de travail
1. Détecter la stack et le style existant
node <skill>/scripts/detect.mjs .
Notez le framework, TypeScript, Tailwind, toute bibliothèque d'icônes (et son preset de style), les icônes SVG locales, et le répertoire de sortie suggéré. Si un jeu existant existe, ouvrez 2 à 3 de ses SVG et copiez leurs nombres racines. Sinon, utilisez les valeurs par défaut : grille 24, trait 2, extrémités/joins ronds.
2. Planifier la liste : sens → métaphore → nom de fichier
Écrivez un petit tableau avant de dessiner : étiquette | métaphore (ce qui est dessiné) | nom de fichier | entrée cookbook. Exemple : Projects | tableau kanban | kanban.svg | kanban. Choisissez des métaphores courantes (design-rules §7) et une métaphore par sens. Nommez les fichiers d'après l'objet, en kebab-case. Demandez à l'utilisateur uniquement si une étiquette est ambiguë et que le choix change le sens dans l'interface ; sinon, décidez et énoncez le choix.
3. Dessiner sur la grille 24
Créez icons/src/<nom>.svg avec la racine canonique (svg-code-rules.md). Pour chaque icône :
- Commencez par la keyline correspondante : cercle r10, carré 18 (x/y 3), portrait 16×20, paysage 20×16. Les keylines sont les lignes centrales du trait.
- Gardez le bord extérieur du trait à ≥1 unité du bord du canevas. Utilisez un rayon 2 pour les grands coins et 1–1.5 pour les petits ; gardez des espaces ≥2 unités d'espace libre.
- Faites en sorte que les parties se rejoignent exactement ou gardent un espace clair. Utilisez des coordonnées entières pour les traits de 2px. Utilisez le moins d'éléments possible (≤6 est typique).
- Commencez par l'entrée la plus proche dans
references/glyph-cookbook.md, puis adaptez-la. Copiez la géométrie depuis<skill>/assets/cookbook/<nom>.svglorsqu'un glyphe convient tel quel. - Calculez la géométrie répétée (dents, rayons, pointes d'étoile) avec quelques lignes de JavaScript au lieu de deviner. Dessinez d'abord le jeu complet, puis affinez. La cohérence se juge côte à côte.
4. Linter
node <skill>/scripts/lint.mjs icons/src
Corrigez chaque ✖. Traitez les ⚠ gap, density, scale et bounds comme des problèmes de conception à corriger, pas du bruit. Notez chaque ℹ gap et vérifiez-le à l'étape 6 ; les traits parallèles serrés (barres, lignes) deviennent flous à 16px à moins qu'ils ne soient espacés de 4 unités. Relancez jusqu'à ce qu'il affiche PASS sans avertissements que vous ne pouvez pas justifier. Flags : --grid, --padding, --mode fill, --strict, --json.
5. Optimiser
node <skill>/scripts/optimize.mjs icons/src icons/svg
Cela arrondit les nombres, exécute SVGO (installation locale ou npx svgo@4 ; se rabat sur le canonicaliseur intégré hors ligne), réordonne les attributs racines, et affiche les octets par icône plus le total gzip. Lint également la sortie : node <skill>/scripts/lint.mjs icons/svg.
6. Prévisualiser et REGARDER, puis itérer
node <skill>/scripts/preview.mjs icons/svg --out icons/preview.png \
--sidebar "dashboard:Dashboard,kanban:Projects" --active dashboard # ajoutez --install la première fois si aucun moteur PNG
Affichez les PNG avec votre outil de visualisation d'images, dans cet ordre :
icons/[email protected]: la bande du jeu et les maquettes de la barre latérale. Il est assez petit pour voir les détails.icons/[email protected]: chaque icône à chaque taille, plus la vue d'inspection. Il est grand, alors recadrez-le si votre visualiseur réduit l'échelle.icons/preview.png: pixels 1× réels.
Ensemble, ils montrent :
- une bande 24/16px sur fond clair et sombre ;
- une maquette de barre latérale avec un élément actif et un rail réduit ;
- des lignes par icône à 16/20/24/48 ;
- une vue d'inspection 4× avec grille, keylines bleues et la limite de padding rouge de 1px.
Répondez aux questions d'auto-évaluation dans design-rules §12. Corrections typiques :
| Vous voyez | Correction |
|---|---|
| Une icône semble plus claire/plus petite dans la bande | agrandissez-la jusqu'à sa keyline, ou ajoutez un cadre/axe (les glyphes ouverts semblent légers) |
| Une semble plus lourde/plus chargée | supprimez des détails ; ≤3 barres, ≤6 dents, ≤2 lignes de texte |
| Une tache là où les parties se rencontrent à 16px | assemblez exactement ou ouvrez l'espace à ≥2 unités |
| La forme est collée à un côté dans la vue d'inspection | recentrez, ou déplacez de 0.5–1 unité pour l'équilibre optique |
| Métaphore peu claire dans le rail réduit | choisissez une métaphore plus littérale (étape 2) |
Répétez les étapes 3 à 6 jusqu'à ce qu'un deuxième coup d'œil ne trouve rien à corriger. Généralement 1 à 3 cycles.
7. Générer la sortie framework
node <skill>/scripts/build.mjs icons/svg --out src/components/icons --framework react --lang ts \
--labels "kanban:Projects,dashboard:Dashboard"
--framework react|vue|svelte|html|all ; --lang ts|js ; --package @app/icons écrit un package.json avec sideEffects:false. La sortie est un module tree-shakable par icône, un composant de base partagé (size, color, strokeWidth, absoluteStrokeWidth, title, className), des exports nommés index, et icons.json. HTML donne sprite.svg + usage.html. Détails : references/output-formats.md.
Ensuite, vérifiez les types ou construisez le projet s'il a un script (npx tsc --noEmit, npm run build) et corrigez les erreurs.
8. Intégrer avec une utilisation accessible
Utilisez le modèle de references/accessibility-and-usage.md :
<nav aria-label>;aria-current="page"plus couleur et fond pour l'élément actif ;- icône
size-5 shrink-0et décorative ; - un
aria-labelsur les boutons icon-seuls ; déconnexion en<button>; - lignes ≥44px ; couleurs atténuées mais atteignant toujours un contraste ≥3:1.
Format de sortie
Terminez par un petit rapport à l'utilisateur :
- Icônes : tableau
étiquette → composant → métaphoreet les chemins de dossiers (icons/src,icons/svg, dossier généré). - Vérifications : résultat du lint (erreurs/avertissements), totaux d'optimisation (
moyenne B/icône,total gzip), et les chemins de prévisualisation que vous avez inspectés, plus ce que vous avez modifié après avoir regardé. - Extrait d'utilisation pour leur framework, avec attributs d'accessibilité.
- Remarques : décisions de style (grille/trait/présélection correspondant), icônes RTL à inverser, et tout ce que vous n'avez pas pu vérifier.
Exemple
Utilisateur : « J'ai besoin d'icônes pour ma barre latérale : Dashboard, Projets, Équipe, Paramètres dans mon app Next.js + Tailwind. »
→ détecter : React (Next) + TS + Tailwind, pas de bibliothèque d'icônes → planifier : dashboard/tuiles, kanban, utilisateurs, paramètres/engrenage → dessiner à partir du cookbook et adapter → lint PASS → optimiser : 4 icônes, moyenne ~340 B, ~0.4 KB gzip → prévisualisation : Projets semblait léger, donc ajouter des barres ; revérifier → construire --framework react dans src/components/icons → <DashboardIcon className="size-5 shrink-0" /> dans la nav avec aria-current.
Références
| Ouvrez quand vous avez besoin de… | Lire |
|---|---|
| choisir les tailles, keylines, rayons, espaces, métaphores, ou corriger un problème de prévisualisation | references/design-rules.md |
| écrire ou déboguer du balisage SVG, ou comprendre une erreur de lint | references/svg-code-rules.md |
| partir d'une géométrie éprouvée pour une icône d'interface courante (56 glyphes dessinés) | references/glyph-cookbook.md + assets/cookbook/*.svg |
| générer ou adapter manuellement la sortie React/Vue/Svelte/Angular/HTML, ou réduire la taille du bundle | references/output-formats.md |
| écrire l'extrait d'utilisation : modèles de nav/barre latérale, état actif, étiquettes, contraste, RTL | references/accessibility-and-usage.md |
| modifier la forme des composants générés (props, noms de classe, valeurs par défaut d'accessibilité) | templates/<framework>/, que build.mjs lit ; éditez là, jamais dans la sortie |
| tester les modifications de ce skill | evals/evals.json |
Liste de vérification (tout doit être vrai avant de signaler la fin)
- Aucune bibliothèque d'icônes ajoutée ; chaque icône a été dessinée pour cette tâche ou adaptée du cookbook.
- Le style correspond aux icônes existantes du projet (ou au présélection par défaut) sur l'ensemble du jeu.
-
lint.mjsPASS suricons/srceticons/svg; les avertissements restants sont justifiés dans le rapport. - Vous avez visualisé le PNG de prévisualisation après votre dernière modification ; les lignes 16px clair/sombre sont nettes ; aucune icône n'est plus lourde, plus légère ou plus grande que ses sœurs.
- Composants générés par
build.mjs; la vérification de type/construction du projet passe (lorsque disponible). - Utilisation : icônes décoratives masquées, contrôles icon-seuls étiquetés, état actif non limité à la couleur, cibles ≥44px, contraste ≥3:1.
- Le rapport inclut les tailles (moyenne octets/icône, total gzip) et le chemin de prévisualisation.