swiss-editorial-minimalist (SKILLS.md v3.1)
Une page construite par un modèle ressemble généralement à la moyenne de toutes les pages qu'il a vues : un hero en dégradé, une rangée de cartes arrondies avec des icônes emoji, une ombre sous chaque bouton, et un CDN Tailwind qui charge un arc-en-ciel de couleurs. Rien n'y est faux, et rien n'y a été décidé.
Ce fichier remplace ces valeurs par défaut par des décisions. Il couvre trois choses : le style maison (ce qu'il faut montrer et ce qu'il faut omettre), les règles techniques qui le font tenir (jetons, échelles, points de rupture, accessibilité), et les portes qui vérifient le résultat avant sa livraison.
Suivez les règles telles qu'elles sont écrites. Lorsqu'une demande entre en conflit avec elles, la section 0 explique quoi faire.
0. Méta-règles (à lire en premier)
Que faire lorsque vous recevez ce fichier
-
Lisez le fichier en entier avant d'écrire du code. Les règles dépendent les unes des autres.
-
Ne demandez pas d'éclaircissements sur quoi que ce soit que ce fichier décide déjà. Exécutez avec des hypothèses raisonnables et énoncez-les sur une ligne.
-
Si la demande entre en conflit avec le style maison (par exemple « coloré », « ludique », « hero en dégradé », « icônes emoji », « cartes arrondies à 20px »), confirmez une fois avant de procéder :
Cette demande enfreint la section X de SKILLS.md. Je l'interpréterai dans le style Swiss-Editorial Minimalist, sauf si vous souhaitez quitter le guide.
Attendez la réponse, puis construisez.
-
La sortie par défaut est un fichier HTML complet avec
<style>et<script>en ligne. Ne livrez pas de fragments sauf si l'utilisateur les demande. -
Commencez toujours le CSS par le bloc
:rootde la section 12.
Comment nommer ce style
Utilisez ces termes pour que le vocabulaire reste cohérent. N'utilisez pas « moderne », « propre » ou « élégant » seuls ; ils ne disent rien de spécifique.
- « Minimaliste suisse-éditorial » : la valeur par défaut, décrite dans ce fichier.
- « Brutalisme doux » : bordures plus épaisses et grille plus rugueuse.
- « Éditorial néo-brutaliste » : une couleur d'accent ajoutée et une ombre décalée dure. Les ombres sont interdites dans le style par défaut, utilisez donc ce nom uniquement lorsque l'utilisateur le demande explicitement.
- « Magazine monochrome » : axé sur la typographie, sans cartes illustrées.
1. Philosophie de conception
Trois principes, aucun n'est négociable :
- Le contenu est le roi ; la typographie est l'architecture. Il n'y a pas d'illustrations décoratives. Le grand titre est l'élément visuel principal.
- La structure reste visible. Les bordures, les grilles et les numéros de section apparaissent tels quels. Ils ne sont pas cachés.
- Monochrome d'abord, couleur ensuite. La valeur par défaut est le noir, le blanc et le gris. La couleur n'apparaît qu'en mode sombre ou comme un accent minimal.
La page doit se sentir calme, ferme, intelligente et éditoriale, comme un magazine imprimé conçu par des ingénieurs.
2. Palette
Mode clair (par défaut)
:root {
--bg: #f5f5f5; /* fond principal, pas blanc pur */
--ink: #111111; /* texte principal, pas noir pur */
--muted: #666666; /* texte secondaire */
--line: #e0e0e0; /* bordures et séparateurs */
--card: #eeeeee; /* fond de carte */
--accent: #d4d4d4; /* accent neutre */
--dark: #0a0a0a; /* sections à fort contraste (déclaration, pied de page) */
--white: #ffffff;
}
Mode sombre
body.dark {
--bg: #121212;
--ink: #f0f0f0;
--muted: #999999;
--line: #333333;
--card: #1e1e1e;
--accent: #2a2a2a;
--dark: #050505;
--white: #181818;
}
Règles de couleur (obligatoires)
- Le fond du corps n'est jamais
#fff. Utilisez un blanc cassé#f5f5f5. - Le texte n'est jamais
#000. Utilisez#111. - La couleur de la marque apparaît une ou deux fois par page au maximum, et toujours via une variable CSS, jamais codée en dur.
- Les couleurs vives sont interdites pour le statut, les icônes et le texte. Exemples de ce qui est interdit : emerald-500, green-600, red-500, blue-500, yellow-400,
#27c93f,#ff5f56,#ffbd2e. Remplacez-les par des symboles monochromes (●, ▲, ✕, →) dansvar(--ink)ouvar(--muted). - Les sections de contraste (déclaration, CTA, pied de page) utilisent
var(--dark)avec du texte clair. - Le mode sombre est obligatoire. Suivez
prefers-color-schemepar défaut et laissez l'utilisateur le remplacer, en enregistrant le choix danslocalStorage. Le bouton de bascule utilise le balisage obligatoire de la section 5 (« Bascule de thème »).
3. Typographie
Appariement de polices
Titre : 'Space Grotesk' (ou Inter Tight, General Sans, Neue Montreal)
Corps : 'DM Sans' (ou Inter, Satoshi, IBM Plex Sans)
Mono : 'JetBrains Mono' (ou système monospace)
N'utilisez pas de polices décoratives, script ou serif pour le texte du corps. Un serif est autorisé uniquement pour les citations ou les signatures (par exemple Georgia, italique).
Échelle typographique (clamp est obligatoire, afin que la typographie évolue sans requêtes média)
/* Hero H1 */
font-size: clamp(55px, 5.6vw, 94px); /* ou clamp(32px, 4.3vw, 62px) pour un hero étroit */
line-height: 1.025;
letter-spacing: -0.07em; /* négatif, toujours */
font-weight: 500; /* pas 700, pas 400 */
/* Section H2 */
font-size: clamp(42px, 4.2vw, 69px);
line-height: 1.08;
letter-spacing: -0.06em;
font-weight: 500;
/* Carte H3 */
font-size: clamp(22px, 2.2vw, 27px);
line-height: 1.2;
letter-spacing: -0.04em;
font-weight: 500;
/* Corps */
font-size: 16px–18px;
line-height: 1.7–1.8;
color: var(--muted);
/* Micro / sourcil / étiquette */
font-size: 12px;
letter-spacing: 0.15em–0.17em;
font-weight: 700;
text-transform: uppercase;
Règles typographiques strictes
- Les titres utilisent toujours un crénage négatif (entre -0.04em et -0.07em). C'est la signature du style.
- Le poids du titre est 500. Le gras 700 aplatit la sensation éditoriale.
- Les sourcils et les micro-étiquettes sont toujours EN MAJUSCULES avec un espacement large (0.15em ou plus).
- Les numéros de section (01, 02, 03) apparaissent comme micro-étiquettes. Ne les cachez pas.
- Un point à la fin d'un titre peut servir d'accent, en option :
<h1>Titre.<span style="color:var(--muted)">.</span></h1> - Le texte du corps est aligné à gauche. Ne centrez pas les longs paragraphes.
4. Mise en page et grille
Conteneur
.wrap {
max-width: 1440px;
margin: auto;
padding: 0 clamp(24px, 5vw, 84px);
}
Espacement vertical
- Entre les sections :
padding: 130px 0sur ordinateur, réduit à85pxsur mobile. - Hauteur de l'en-tête : 88px sur ordinateur, 75px sur mobile.
- Écart entre les cartes : 15–16px. Gardez-le serré, pas 24px ou plus.
Patrons de grille courants
/* Hero asymétrique */
.hero { grid-template-columns: 1.04fr .96fr; }
/* Titre de section à deux colonnes */
.section-head { grid-template-columns: 1fr 1fr; align-items: end; }
/* Fonctionnalités à trois colonnes */
.features { grid-template-columns: repeat(3, 1fr); gap: 15px; }
/* Déclaration */
.statement-grid { grid-template-columns: 1fr 1fr; gap: 60px; }
/* Témoignage (voir section 8) */
.testimonial-grid { grid-template-columns: 1.2fr .8fr; gap: 60px; }
Règles de mise en page (obligatoires)
- Les sections sont séparées par une bordure de 1px
var(--line), pas par une ombre ou un arrière-plan différent. - Évitez les grands rayons de bordure. Les boutons et les cartes ont au maximum 4px. Seules les images et les captures d'écran prennent 12–22px.
- Utilisez
align-items: endsur les titres de section pour que le titre et le paragraphe soient sur la même ligne de base. C'est l'astuce éditoriale. - Les grilles asymétriques (1.04fr / .96fr) sont plus belles que 1fr / 1fr.
- Ne centrez jamais le texte du corps. Alignez toujours à gauche.
- Chaque section a besoin d'un
border-topouborder-bottomde 1pxvar(--line).
5. Composants
Boutons
.btn {
display: inline-flex;
align-items: center;
gap: 14px;
border-radius: 4px; /* presque carré */
padding: 15px 20px;
background: var(--ink);
color: var(--bg);
border: 1px solid var(--ink);
font-size: 14px;
font-weight: 700;
cursor: pointer;
transition: transform .2s, background .2s;
}
@media (hover: hover) {
.btn:hover { transform: translateY(-2px); background: #333333; }
}
/* Variantes */
.btn.outline { background: transparent; color: var(--ink); border-color: var(--line); }
.btn.light { background: var(--bg); color: var(--ink); border-color: var(--bg); }
Règles des boutons :
- Chaque bouton a une icône de flèche : ↗ pour un lien externe, ↓ pour un défilement.
- Le survol soulève le bouton de -2px, uniquement à l'intérieur de
@media (hover: hover). Il ne redimensionne pas et n'ajoute pas d'ombre. - N'utilisez jamais
#fffpour.btn.light. Utilisezvar(--bg).
Cartes de fonctionnalités
┌─────────────────────────┐
│ [SVG line-art 8:5] │ ← illustration monochrome abstraite, ou vide
├─────────────────────────┤
│ MICRO ÉTIQUETTE │ ← majuscules, espacement large
│ Titre de la carte. │ ← Space Grotesk 24–27px
│ Description 1–2 phrases│ ← muted, 14px
└─────────────────────────┘
- Fond
var(--card), pas de rayon de bordure (ou 4px au maximum). - Pas de bordure (la carte se fond dans le fond), ou
1px solid var(--line). - Survol :
transform: translateY(-5px), uniquement à l'intérieur de@media (hover: hover):@media (hover: hover) { .card:hover { transform: translateY(-5px); } } - L'illustration est un SVG line-art avec
stroke-width: 1.2px,fill: none, dans la couleur d'encre. Pas une photo, pas un dégradé, pas un emoji.
En-tête
- Hauteur 88px,
border-bottom: 1px solid var(--line). - Marque : logo 34px et nom en Space Grotesk 22px,
letter-spacing: -1.1px. - Navigation : 14px, poids 600, écart 36px.
- Actions : bascule de thème (icône soleil/lune, balisage obligatoire dans « Bascule de thème » ci-dessous), le bouton CTA, et le hamburger sur mobile.
- Le menu mobile s'ouvre comme un panneau absolu sous l'en-tête et se ferme sur Échap.
- Le hamburger a besoin de
aria-label,aria-expandedetaria-controls. La bascule de thème a besoin dearia-labeletaria-pressed(voir ci-dessous).
Bascule de thème (balisage obligatoire)
Chaque page a une bascule de mode sombre, et elle utilise toujours ce balisage. Ne redessinez pas les icônes, ne les échangez pas contre des emoji, et n'ajoutez pas d'étiquette de texte. Les chemins SVG, les valeurs id et le aria-label sont fixes.
<div class="header-actions">
<!-- Bouton de bascule de mode sombre -->
<button id="theme-toggle" type="button" class="theme-toggle" aria-label="Ganti mode gelap/terang" aria-pressed="false">
<!-- Icône Soleil (cachée en mode clair, visible en mode sombre) -->
<svg id="sun-icon" class="theme-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.8" aria-hidden="true">
<circle cx="12" cy="12" r="5"></circle>
<path d="M12 1v2m0 18v2M4.22 4.22l1.42 1.42m12.72 12.72l1.42 1.42M1 12h2m18 0h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"></path>
</svg>
<!-- Icône Lune (visible en mode clair, cachée en mode sombre) -->
<svg id="moon-icon" class="theme-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.8" aria-hidden="true">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"></path>
</svg>
</button>
<!-- Le bouton CTA et le hamburger vont ici, dans le même conteneur -->
</div>
.header-actions { display: flex; align-items: center; gap: 16px; }
.theme-toggle {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 44px; /* cible tactile */
min-height: 44px;
padding: 8px;
color: var(--ink);
background: transparent;
border: 1px solid var(--line);
border-radius: var(--radius-sm);
cursor: pointer;
transition: background .2s;
}
@media (hover: hover) {
.theme-toggle:hover { background: var(--card); }
}
.theme-icon { width: 20px; height: 20px; }
/* L'état de l'icône suit body.dark, donc pas d'échange de classe en JavaScript */
#sun-icon { display: none; }
#moon-icon { display: block; }
body.dark #sun-icon { display: block; }
body.dark #moon-icon { display: none; }
<script>
(function () {
var KEY = 'theme';
var saved = null;
try { saved = localStorage.getItem(KEY); } catch (e) {}
var dark = saved ? saved === 'dark'
: window.matchMedia('(prefers-color-scheme: dark)').matches;
document.body.classList.toggle('dark', dark);
document.addEventListener('DOMContentLoaded', function () {
var btn = document.getElementById('theme-toggle');
if (!btn) return;
btn.setAttribute('aria-pressed', String(document.body.classList.contains('dark')));
btn.addEventListener('click', function () {
var isDark = document.body.classList.toggle('dark');
btn.setAttribute('aria-pressed', String(isDark));
try { localStorage.setItem(KEY, isDark ? 'dark' : 'light'); } catch (e) {}
});
});
})();
</script>
Règles de bascule de thème :
- Gardez le conteneur (
.header-actions), le boutonid="theme-toggle", et les identifiants d'icônessun-iconetmoon-iconexactement comme écrits. Les scripts et la liste de contrôle les recherchent. - La lune apparaît en mode clair (cliquez pour passer en sombre). Le soleil apparaît en mode sombre (cliquez pour passer en clair). L'état par défaut est clair, sauf si
prefers-color-scheme: darkou un choix enregistré dit le contraire. - Le bouton prend sa couleur uniquement à partir des variables :
var(--ink)pour l'icône et le texte,var(--line)pour la bordure,var(--card)pour le fond au survol. Ne codez jamais une couleur en dur. - Le rayon de bordure est de 4px au maximum, la cible tactile est d'au moins 44×44px, et l'état de survol se trouve à l'intérieur de
@media (hover: hover). - Les icônes mesurent 20px,
stroke="currentColor",stroke-width="1.8",fill="none", avecaria-hidden="true". Le bouton porte learia-label. - Utilisez
aria-pressedsur ce bouton.aria-expandedest pour le hamburger, pas pour la bascule de thème. - Enregistrez le choix dans
localStoragesous la clétheme, avec les valeurslightoudark. Enveloppez les appels de stockage danstry/catch. - La bascule fonctionne sans Tailwind. L'extrait original utilisait des classes utilitaires Tailwind (
flex items-center gap-4,p-2,w-5 h-5,hidden/block), et celles-ci sont remplacées ici par le CSS vanille ci-dessus, car le CDN Tailwind est interdit (section 10). Si un projet exécute déjà Tailwind avec une étape de construction, les classes utilitaires peuvent rester, mais la couleur doit être écritetext-[var(--ink)]. La formetext.var(--ink)est une faute de frappe et ne fait rien.
Pied de page
- Fond
var(--dark), textevar(--bg). - Grille :
grid-template-columns: repeat(3, 1fr); gap: 60px;. - Pas de formulaire d'abonnement par e-mail.
- Copyright et liens de navigation en bas.
6. Sections
Hero
<section class="hero">
<div>
<span class="section-label">01 / Présentation</span>
<h1>Titre principal ici.</h1>
<p class="subtitle">Description en une phrase.</p>
<a href="#" class="btn">Commencer ↗</a>
</div>
<figure>
<img src="screenshot.jpg" alt="Capture d'écran du produit">
</figure>
</section>
- Le hero est une grille asymétrique. L'image n'est jamais un graphique abstrait ; c'est une capture d'écran, une photo ou une illustration SVG monochrome montrant le produit.
- Le titre a un crénage négatif (-0.07em).
- L'image est encadrée d'une bordure de 1px
var(--line)et d'un rayon de bordure de 12px.
Fonctionnalités
<section class="features">
<div class="section-head">
<span class="section-label">02 / Fonctionnalités</span>
<h2>Ce que nous faisons.</h2>
<p>Description courte.</p>
</div>
<div class="features-grid">
<div class="card">
<svg>...monochrome 8:5...</svg>
<span class="micro-label">Étiquette</span>
<h3>Titre de la fonctionnalité.</h3>
<p>Description.</p>
</div>
<!-- répéter -->
</div>
</section>
Déclaration
<section class="statement">
<div class="statement-content">
<span class="section-label">03 / Déclaration</span>
<h2>Une citation puissante ou un message central.</h2>
<p>Contexte ou auteur.</p>
</div>
</section>
- Fond
var(--dark)avec du texte clair. Pas d'image de fond.
Témoignage
<section class="testimonials">
<div class="section-head">
<span class="section-label">04 / Témoignages</span>
<h2>Ce qu'ils disent.</h2>
</div>
<div class="testimonials-grid">
<blockquote>
<p>"Citation."</p>
<cite>— Nom, Titre</cite>
</blockquote>
<!-- répéter -->
</div>
</section>
- Les témoignages sont dans des blockquotes, pas dans des cartes.
- Les citations sont en italique ou en police serif.
CTA
<section class="cta">
<div class="cta-content">
<span class="section-label">05 / Commencer</span>
<h2>Dernier appel à l'action.</h2>
<a href="#" class="btn">Démarrer ↗</a>
</div>
</section>
- Le CTA est une section à fond plein (
var(--dark)ouvar(--bg)selon le contexte). - Pas de formulaire.
7. Accessibilité
- Tous les boutons et les liens interactifs ont un
aria-labeldescriptif. - La bascule de thème a
aria-pressed. - Le hamburger a
aria-expandedetaria-controls. - Les icônes décoratives ont
aria-hidden="true". - Le texte du corps est au moins 16px.
- Les cibles tactiles font au moins 44×44px.
- L'ordre de tabulation est logique.
- Les sauts de focus (
:focus-visible) utilisent2px solid var(--ink).
8. Anti-patrons (ne faites pas ça)
- Ombre :
box-shadow,text-shadow,drop-shadow(). Remplacer par une bordure. - Dégradés :
linear-gradient(),radial-gradient(). Remplacer par des blocs de couleur unie. - Arrière-plan d'image pour les héros ou les sections. Utilisez
background-color. - Icônes emoji dans les cartes : 🙃, 🚀, ⚡, ✅. Remplacer par des SVG monochromes.
- Boutons à fond blanc :
background: #fff;. Utilisezvar(--bg). - Boutons arrondis :
border-radius: 9999px;. Utilisez 4px. - Boutons fantômes avec texte blanc sur fond clair.
- Pavés de texte centrés, sauf pour les citations.
- Formulaires d'abonnement par e-mail dans le pied de page.
- Importer Tailwind depuis un CDN. Utilisez la construction ou le CSS vanille.
- Utiliser
!importantsans raison valable. Si vous devez le faire, commentez-le. - Images non responsives :
max-width: 100%; height: auto;partout.
9. Checklist avant livraison
Exécutez cette liste après avoir écrit le code, avant de le montrer à l'utilisateur.
- Palette :
backgroundn'est jamais#fff?colorn'est jamais#000? Les couleurs vives sont-elles remplacées par des symboles monochromes ? - Typographie : Les titres ont-ils un crénage négatif ? Le poids est-il 500 ? Les étiquettes de section sont-elles en majuscules avec un espacement large ?
- Mise en page : Les sections ont-elles une bordure ? Les grilles asymétriques sont-elles utilisées lorsque cela est approprié ? Le texte du corps est-il aligné à gauche ?
- Composants : Les boutons ont-ils une icône de flèche ? Les cartes ont-elles un fond et une bordure corrects ? La bascule de thème a-t-elle le bon balisage et le bon
aria-label? - Accessibilité :
aria-labelsur les éléments interactifs ?aria-pressedsur la bascule de thème ?aria-expandedsur le hamburger ?:focus-visiblestylisé ? - Performances : Aucun CDN lourd ? Les polices sont-elles chargées localement ou avec
font-display: swap? - Cohérence : Tous les titres, tous les paragraphes, toutes les cartes suivent-ils le même patron ?
- Validation HTML : Pas de balises non fermées, pas d'attributs en double.
10. Règles techniques
- Sortie par défaut : un fichier HTML unique avec du CSS et du JavaScript en ligne. Pas de fragments sauf demande explicite.
- Pas de frameworks CSS : Tailwind, Bootstrap, etc. sont interdits, sauf si la page en contient déjà une instance construite.
- Pas de polices Google via CDN : chargez les polices localement ou utilisez
font-display: swap. - Le script de bascule de thème est le premier élément après
<body>, avant tout autre contenu. - Toutes les images sont responsives :
max-width: 100%; height: auto;. - Utilisez
loading="lazy"sur les images en dessous de la ligne de flottaison. - Les animations sont limitées aux transitions de survol et aux transformations de menu déroulant. Pas d'animations de défilement ou de chargement complexes.
- Pas de JavaScript inutile. Si le JavaScript n'ajoute pas de fonctionnalité (bascule de thème, menu hamburger), supprimez-le.
11. Exemple de structure HTML
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nom du site</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="..." rel="stylesheet">
<style>
:root { /* ... */ }
/* CSS vanille */
</style>
</head>
<body>
<script>/* bascule de thème ici */</script>
<header>
<nav id="nav" class="wrap">
<a href="/">Logo</a>
<ul>
<li><a href="#fonctionnalites">Fonctionnalités</a></li>
<li><a href="#à-propos">À propos</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
<div class="header-actions">
<button id="theme-toggle" ...>...</button>
<button id="hamburger" aria-label="Menu" aria-expanded="false" aria-controls="nav">...</button>
</div>
</nav>
</header>
<main>
<section class="hero wrap">...</section>
<section class="features wrap">...</section>
<section class="statement">...</section>
<section class="testimonials wrap">...</section>
<section class="cta">...</section>
</main>
<footer>
<div class="wrap">
<p>© Nom du site 2024</p>
</div>
</footer>
</body>
</html>
12. Bloc :root de départ (obligatoire)
:root {
--bg: #f5f5f5;
--ink: #111111;
--muted: #666666;
--line: #e0e0e0;
--card: #eeeeee;
--accent: #d4d4d4;
--dark: #0a0a0a;
--white: #ffffff;
--radius-sm: 4px;
--radius-md: 12px;
--font-sans: 'Space Grotesk', 'Inter Tight', 'General Sans', sans-serif;
--font-body: 'DM Sans', 'Inter', 'Satoshi', sans-serif;
--font-mono: 'JetBrains Mono', monospace;
}
Ce bloc est la toute première chose dans le CSS. Copiez-le et ajustez les polices si nécessaire.
13. Licence et crédits
Ce guide de style est fourni avec le skill « RydzzKen/swiss-editorial-minimalist ». Utilisez-le librement, modifiez-le selon vos besoins, mais conservez la paternité du style comme « Swiss-Editorial Minimalist ».
