📧 Reste informé(e) !

Reçois les derniers articles et conseils EasyAngularKit directement dans ta boîte mail.

S'inscrire gratuitement

~7 min de lecture

J'ai refondu la landing EasyAngularKit avec impeccable, voici ce que ça donne

J'ai un site Angular en prod, easyangularkit.com. Tech solide (Angular 21 SSR + Nx + Tailwind v4), mais je sentais que le design avait un problème : il sentait le template SaaS AI-généré moyen. Inter + Space Grotesk + JetBrains Mono partout, glassmorphism décoratif, hero centré icon-title-CTA, grilles 3 colonnes répétées. Pas catastrophique, mais pas non plus distinctif. Or je vends une formation premium — ma landing doit être à la hauteur.

J'ai testé une skill open-source qui s'appelle impeccable. Voici le retour brut, avec les chiffres, les commits et les pièges.


L'outil : impeccable

impeccable.style (GitHub), par Paul Bakaus. C'est une skill compatible Claude Code, Cursor, Codex CLI, Gemini CLI. Une skill = un ensemble cohérent d'instructions injectées dans le contexte de l'agent.

Concrètement, impeccable apporte :

  • 23 sous-commandes design : audit, typeset, colorize, quieter, layout, harden, polish, etc.
  • Une liste codifiée d'anti-patterns : typographies "reflex-reject" (Inter, DM Sans, Cormorant…), glassmorphism par défaut, side-stripe borders, gradient text, em dashes, hero-metric template…
  • Un protocole strict : avant toute commande, l'agent doit charger PRODUCT.md (stratégie marque) et DESIGN.md (système visuel). Sans PRODUCT.md, l'audit refuse de tourner.

Installation

npx skills add pbakaus/impeccable --yes

Crée .agents/skills/impeccable/ avec :

  • SKILL.md : entrée principale, règles globales, routing des commandes
  • reference/*.md : 23 fichiers de spec, un par sous-commande
  • scripts/*.mjs : utilitaires (load-context, pin/unpin)

Le protocole imposé

Chaque sous-commande passe par des "gates" :

  1. Context gatenode .agents/skills/impeccable/scripts/load-context.mjs charge PRODUCT.md + DESIGN.md
  2. Product gatePRODUCT.md doit exister, sinon $impeccable teach est invoqué (interview courte)
  3. Command gate — la spec de la commande appelée doit être chargée

Avant le premier $impeccable audit, j'ai dû créer PRODUCT.md via une interview de 4 questions (registre brand vs product, 3 mots de personnalité, références visuelles, niveau d'a11y visé). Mes réponses : brand / "expert, direct, premium" / Linear-Vercel-Stripe / WCAG 2.1 AA. Ces réponses conditionnent tout l'audit qui suit — elles servent de filtre opinionnated pour distinguer un anti-pattern vrai d'un anti-pattern de circonstance.


Le déroulé chronologique

Phase 0 — Setup

npx skills add pbakaus/impeccable --yes

Skill installée + PRODUCT.md créé après interview.

Phase 1 — Audit initial

$impeccable audit

L'audit ne modifie rien. Score : 10/20 (D+ — Acceptable). Il a sorti une liste de findings :

  • P0 Typographie reflex-reject (Inter / Space Grotesk / JetBrains Mono — les trois explicitement bannies)
  • P0 Glassmorphism prolifique (28 backdrop-filter cumulés)
  • P0 transition: width sur la barre de progression de lecture (layout thrash à chaque scroll)
  • P0 Em dash dans la copy
  • P1 outline: none / :focus-visible incomplets
  • P1 Hex hardcodés contournant les tokens CSS
  • P1 Hero centré template
  • P1 Grilles 3-cols répétées
  • P1 Contraste insuffisant light-blue sur fond clair
  • P1 overflow-x: hidden à 3 niveaux

Phase 2 — Application des recommandations

Une commande, un commit. Dans l'ordre P0 → P1 → P2 :

# Commande Effet
1 $impeccable optimize Barre de progression widthtransform: scaleX. Blurs plafonnés à 12-16 px.
2 $impeccable clarify Em dash + typos congrats.page.ts.
3 $impeccable harden :focus-visible global, prefers-reduced-motion global, hex tokenisés.
4 $impeccable adapt overflow-x: hidden redondants retirés, touch targets 44 px + aria sur tag-filters.
5 $impeccable quieter Glassmorphism réduit à 1 surface (la navbar). 28 → 2 occurrences.
6 $impeccable colorize Token --color-link-blue (#3a6fa5, AA sur blanc), --color-white teinté, jaune décoratif retiré.
7 $impeccable typeset Inter / Space Grotesk / JetBrains Mono → Cabinet Grotesk + Switzer + Geist Mono. ~6 Mo de fonts orphelines supprimées.
8 $impeccable layout why-angular : grille 3-cols → liste-spécimen numérotée asymétrique.
9 $impeccable shape + bolder Hero centré → asymétrique 2 colonnes (texte gauche, vidéo droite).
10 $impeccable document Génération de DESIGN.md (format Stitch, 6 sections normatives).
11 $impeccable polish Tokens CSS obsolètes supprimés, CLAUDE.md aligné.

Phase 3 — Bugs découverts en preview Vercel

L'audit ne testait pas le rendu réel. Premiers déploiements ont révélé :

Bug Cause
Carré clippé en haut à gauche sur mobile background-attachment: fixed sur body — bug iOS Safari
Fond redevenu blanc html::before ne propageait pas au canvas — gradient remis sur html direct
Hero suivi directement du footer @defer (on idle) ne firait pas (CDN fonts maintenaient la page non-idle) → migration vers withIncrementalHydration() + hydrate on viewport / hydrate on timer(2s)
Photo Gaëtan en broken-image icon <picture><source> + NgOptimizedImage créait un conflit d'hydratation. Final : <img> natif simple
Pastilles dark-blue sur fond glass-card dark-blue Disques navy invisibles. Remplacés par icônes outline jaune flush
Testimonials coupé / lent iframeResizer injecté tardivement. Final : <script async> dans index.html + min-height: 480px + preconnect
Code inline qui déborde des titres blog Trois itérations pour trouver le bon équilibre : pastille sombre conservée + line-height: 1.3 heading + chip compressé
Lead atout sur 3 lignes mobile Stack vertical mobile / grid 2-col desktop

Phase 4 — Re-audit

$impeccable audit

Score : 16/20 (+6, "Good"). 4 P1 restants identifiés.

Phase 5 — Application des P1 restants

# Commande Effet
1 $impeccable harden Bug class="..." + [class]="..." sur même élément (le statique écrasé), focus:outline-none retiré
2 $impeccable optimize Hero iframe loading="eager", floating-emojis.ts supprimé (code mort, 15 nœuds DOM par page)
3 $impeccable colorize Yellow density sur wall-of-love : 4 → 2 backgrounds
4 $impeccable layout border-l-4 border-primary-yellow (side-stripe banni) → bordure 1px hairline + jaune au hover
5 $impeccable polish 9 tokens CSS morts retirés

Phase 6 — Audit final

Score : 19/20 ("Excellent — minor polish"). Le seul P2 restant est un bundle JS à 595 kB (warning band, pas blocker).


Les chiffres

Métrique Avant Après Δ
Score $impeccable audit 10/20 19/20 +9
Familles typographiques reflex-reject 3/3 0/3 -3
Surfaces glassmorphism 28 1 -27
bg-primary-yellow décoratifs (≥ 32 px hors CTA) 13 5 -8
Tokens CSS morts 18 0 -18
Self-hosted font files ~6 Mo 0 -6 Mo
Side-stripe borders 1 0 -1
Em dash dans le code 1 0 -1
Hardcoded hex colors dans composants ~20 0 -20
outline: none non remplacé 2 0 -2
Code net (.ts + .css) -503 lignes

Le top 3 de ce qui change vraiment

1. La typographie

Avant : Inter (corps) + Space Grotesk (titres) + JetBrains Mono (code) — exactement la signature de 80 % des landings AI-générées.

Après : Cabinet Grotesk + Switzer (Fontshare, gratuit) + Geist Mono (Google Fonts). Hors reflex-reject list, plus distinctif.

<!-- index.html -->
<link rel="preconnect" href="https://api.fontshare.com" crossorigin>
<link rel="preconnect" href="https://cdn.fontshare.com" crossorigin>
<link rel="stylesheet" href="https://api.fontshare.com/v2/css?f[]=cabinet-grotesk@500,600,700,800&f[]=switzer@300,400,500,600,700&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500;600&display=swap">

2. Le hero

Avant : centré icon-title-subtitle-CTA, video en glass-premium sous le tout. Template.

Après : grille asymétrique 1.05fr / 1fr — texte à gauche (eyebrow formation angular · v18 → v21, titre Cabinet Grotesk 8vw, sous-titre, CTA), vidéo YouTube à droite. Stack vertical sur mobile.

3. L'incremental hydration

Découverte forcée par un bug : @defer (on idle) ne firait jamais sur certaines sessions iOS Safari à cause des nombreux scripts tiers (analytics, Stripe, Hotjar, GTM, testimonial.to…). Migration vers :

// app.config.ts
provideClientHydration(withEventReplay(), withIncrementalHydration())
// landing.page.ts
@defer (hydrate on viewport; hydrate on timer(2s)) {
  <app-why-angular />
  <!-- ... -->
}

Toutes les sections sont SSR-rendered (visibles dès le premier paint), l'hydratation JS arrive ensuite quand le déclencheur fire.


Les apprentissages

  1. Sans PRODUCT.md et DESIGN.md, l'agent fait du générique. Les deux fichiers obligent à fixer les anti-références ("ce que je ne veux PAS être") et les principes — c'est ça qui transforme l'audit générique en audit opinionnated.

  2. Le protocole de gates oblige à ralentir. Avant chaque commande, le contexte doit être chargé. Ça force à séquencer les passes plutôt que tout faire en parallèle.

  3. L'audit n'est pas un test visuel. Il scanne le code — il ne voit pas iOS Safari, le bundle réel sur device, les hydration mismatches. La phase 3 (debug post-deploy) est inévitable et ne remet pas en cause la qualité du diagnostic initial.

  4. Le score 19/20 n'est pas une fin. C'est un signal que les anti-patterns codifiés sont éliminés. Les vrais tests d'usage (Lighthouse, A/B, conversion) restent à faire indépendamment.

  5. Beaucoup de "fixes" sont des reverts. La phase 3 a vu plusieurs commits qui détricotent des choix de la phase 2 (pastilles inline-code, photo wrapper, defer trigger). Itération > planification parfaite.


Reproductibilité

Si tu veux refaire ce travail sur un autre projet :

# 1. Installer la skill
npx skills add pbakaus/impeccable --yes

# 2. Charger le contexte (dans Claude Code)
node .agents/skills/impeccable/scripts/load-context.mjs

# 3. Si pas de PRODUCT.md
# $impeccable teach

# 4. Audit
# $impeccable audit

# 5. Appliquer chaque recommandation, un commit par commande
# $impeccable typeset / quieter / colorize / layout / harden / optimize / clarify / adapt / polish

# 6. Document quand le système est stable
# $impeccable document

# 7. Re-audit pour valider
# $impeccable audit

Verdict

impeccable n'est pas une baguette magique. C'est un filtre opinionnated qui transforme l'agent en designer-junior sérieux : il ne va pas inventer de génie créatif, mais il va éliminer les 5 ou 6 tells qui font qu'une landing ressemble à 1000 autres. Pour un projet comme EAK où "le design est un argument de preuve", c'était exactement ce qu'il fallait.

Score 10/20 → 19/20 en 28 commits, étalés sur quelques sessions. Si tu vends quelque chose en ligne et que ta landing date de plus d'un an sans refonte, tu vas trouver des choses.


🎁 Et si tu veux voir le résultat en vrai : easyangularkit.com

📧 Reste informé(e) !

Reçois les derniers articles et conseils EasyAngularKit directement dans ta boîte mail.

S'inscrire gratuitement

EasyAngularKit

Formation complète pour maîtriser Angular et développer des applications web modernes.

Navigation

Contact

Légal

© 2026 Easy Angular Kit. Tous droits réservés.