11 KiB
11 KiB
Story 1.2: Configuration de Tailwind CSS avec CLI
Status
Ready for Dev
Story
As a développeur, I want configurer Tailwind CSS avec le CLI et le build optimisé, so that je bénéficie d'un CSS performant avec purge automatique.
Acceptance Criteria
- Node.js et npm sont utilisés uniquement pour le build (pas en production)
tailwind.config.jsest créé avec les chemins des fichiers PHP à scanner- Le fichier
assets/css/input.csscontient les directives Tailwind (@tailwind base, components, utilities) - La commande
npm run buildgénèreassets/css/output.cssminifié - Une commande
npm run devpermet le développement en temps réel (watch) - Le fichier CSS généré fait moins de 50kb après purge
- La palette de couleurs personnalisée est configurée (thème sombre)
Tasks / Subtasks
-
[] Task 1 : Initialiser npm et installer les dépendances (AC: 1)
- [] Créer
package.jsonavecnpm init -y - [] Installer Tailwind CSS :
npm install -D tailwindcss postcss autoprefixer - [] Vérifier que
node_modules/est dans.gitignore
- [] Créer
-
[] Task 2 : Créer la configuration Tailwind (AC: 2, 7)
- [] Créer
tailwind.config.jsavec les chemins PHP à scanner - [] Configurer la palette de couleurs personnalisée (primary, background, surface, text, etc.)
- [] Configurer les polices (Inter, JetBrains Mono)
- [] Configurer les tailles de texte personnalisées
- [] Configurer les ombres personnalisées
- [] Créer
-
[] Task 3 : Créer le fichier CSS source (AC: 3)
- [] Créer
assets/css/input.css - [] Ajouter les directives
@tailwind base,@tailwind components,@tailwind utilities - [] Ajouter les styles de base dans
@layer base - [] Ajouter les composants réutilisables dans
@layer components(btn, card, input, badge, etc.) - [] Ajouter les animations dans
@layer utilities
- [] Créer
-
[] Task 4 : Configurer PostCSS (AC: 1)
- [] Créer
postcss.config.jsavec tailwindcss et autoprefixer
- [] Créer
-
[] Task 5 : Configurer les scripts npm (AC: 4, 5)
- [] Ajouter le script
builddans package.json - [] Ajouter le script
dev(watch) dans package.json - [] Tester les deux scripts
- [] Ajouter le script
-
[] Task 6 : Valider la taille du CSS (AC: 6)
- [] Exécuter
npm run build - [] Vérifier que
output.css< 50kb (6,4 Ko) - [] Vérifier que le purge fonctionne correctement
- [] Exécuter
Dev Notes
Dépendances npm (devDependencies uniquement)
{
"devDependencies": {
"tailwindcss": "^3.4.0",
"postcss": "^8.4.0",
"autoprefixer": "^10.4.0"
}
}
Configuration tailwind.config.js Complète
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./*.php',
'./pages/**/*.php',
'./templates/**/*.php',
'./assets/js/**/*.js'
],
theme: {
extend: {
colors: {
primary: {
DEFAULT: '#FA784F',
light: '#FB9570',
dark: '#E5623A',
},
background: '#17171F',
surface: {
DEFAULT: '#1E1E28',
light: '#2A2A36',
},
border: '#3A3A48',
text: {
primary: '#F5F5F7',
secondary: '#A1A1AA',
muted: '#71717A',
},
success: '#34D399',
warning: '#FBBF24',
error: '#F87171',
info: '#60A5FA',
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace'],
},
fontSize: {
'display': ['2.5rem', { lineHeight: '1.2', fontWeight: '700' }],
'heading': ['2rem', { lineHeight: '1.3', fontWeight: '600' }],
'subheading': ['1.5rem', { lineHeight: '1.4', fontWeight: '600' }],
'body': ['1rem', { lineHeight: '1.6', fontWeight: '400' }],
'small': ['0.875rem', { lineHeight: '1.5', fontWeight: '400' }],
},
maxWidth: {
'content': '1280px',
},
boxShadow: {
'card': '0 4px 20px rgba(0, 0, 0, 0.25)',
'card-hover': '0 10px 40px rgba(0, 0, 0, 0.3)',
'input-focus': '0 0 0 3px rgba(250, 120, 79, 0.2)',
},
},
},
plugins: [],
}
Configuration postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}
Contenu assets/css/input.css
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
html {
@apply scroll-smooth;
}
body {
@apply bg-background text-text-primary font-sans antialiased;
}
h1 { @apply text-display text-text-primary; }
h2 { @apply text-heading text-text-primary; }
h3 { @apply text-subheading text-text-primary; }
p { @apply text-body text-text-secondary; }
a {
@apply text-primary hover:text-primary-light transition-colors duration-150;
}
:focus-visible {
@apply outline-none ring-2 ring-primary ring-offset-2 ring-offset-background;
}
::selection {
@apply bg-primary/30 text-text-primary;
}
}
@layer components {
/* Container */
.container-content {
@apply max-w-content mx-auto px-4 sm:px-6 lg:px-8;
}
/* Boutons */
.btn {
@apply inline-flex items-center justify-center gap-2
px-6 py-3 font-medium rounded-lg
transition-all duration-150
focus:outline-none focus:ring-2 focus:ring-offset-2
focus:ring-offset-background
disabled:opacity-50 disabled:cursor-not-allowed;
}
.btn-primary {
@apply btn bg-primary text-background
hover:bg-primary-light active:bg-primary-dark
focus:ring-primary;
}
.btn-secondary {
@apply btn border-2 border-primary text-primary bg-transparent
hover:bg-primary hover:text-background
focus:ring-primary;
}
.btn-ghost {
@apply btn text-primary bg-transparent
hover:text-primary-light hover:bg-surface-light
focus:ring-primary;
}
/* Badges */
.badge {
@apply inline-flex items-center px-2.5 py-1
text-xs font-medium rounded
bg-surface-light text-text-secondary;
}
.badge-primary {
@apply bg-primary/20 text-primary;
}
.badge-muted {
@apply bg-border text-text-muted;
}
/* Cartes */
.card {
@apply bg-surface rounded-lg overflow-hidden
border border-border/50
transition-all duration-200;
}
.card-interactive {
@apply card cursor-pointer
hover:-translate-y-1 hover:shadow-card-hover
hover:border-border;
}
.card-body {
@apply p-4 sm:p-6;
}
/* Inputs */
.input {
@apply w-full px-4 py-3
bg-surface border border-border rounded-lg
text-text-primary placeholder-text-muted
transition-all duration-150
focus:outline-none focus:border-primary focus:shadow-input-focus;
}
.input-error {
@apply border-error focus:border-error
focus:shadow-[0_0_0_3px_rgba(248,113,113,0.2)];
}
.textarea {
@apply input min-h-[150px] resize-y;
}
.label {
@apply block text-sm font-medium text-text-secondary mb-2;
}
.label-required::after {
content: '*';
@apply text-error ml-1;
}
.error-message {
@apply text-sm text-error mt-1.5 flex items-center gap-1;
}
/* Sections */
.section {
@apply py-16 sm:py-24;
}
.section-header {
@apply text-center mb-12;
}
.section-title {
@apply text-heading mb-4;
}
.section-subtitle {
@apply text-body text-text-secondary max-w-2xl mx-auto;
}
/* Témoignage */
.testimonial {
@apply bg-surface-light rounded-lg p-6 border-l-4 border-primary;
}
/* Breadcrumb */
.breadcrumb {
@apply flex items-center gap-2 text-sm text-text-muted;
}
.breadcrumb-link {
@apply text-text-secondary hover:text-primary transition-colors;
}
.breadcrumb-current {
@apply text-text-primary;
}
}
@layer utilities {
.animate-fade-in {
animation: fadeIn 0.6s ease-out forwards;
}
.animate-fade-in-up {
animation: fadeInUp 0.6s ease-out forwards;
}
.animation-delay-100 { animation-delay: 100ms; }
.animation-delay-200 { animation-delay: 200ms; }
.animation-delay-300 { animation-delay: 300ms; }
.aspect-thumbnail {
aspect-ratio: 16 / 9;
}
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* Accessibilité - Réduction de mouvement */
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
Scripts package.json
{
"scripts": {
"dev": "tailwindcss -i ./assets/css/input.css -o ./assets/css/output.css --watch",
"build": "tailwindcss -i ./assets/css/input.css -o ./assets/css/output.css --minify"
}
}
Palette de Couleurs (Thème Sombre)
| Couleur | Hex | Usage |
|---|---|---|
| Primary | #FA784F |
CTA, liens, accents |
| Primary Light | #FB9570 |
Hover |
| Primary Dark | #E5623A |
Active/pressed |
| Background | #17171F |
Fond de page |
| Surface | #1E1E28 |
Cartes, navbar |
| Surface Light | #2A2A36 |
Hover cartes |
| Border | #3A3A48 |
Bordures |
| Text Primary | #F5F5F7 |
Titres |
| Text Secondary | #A1A1AA |
Texte secondaire |
| Text Muted | #71717A |
Placeholders |
Testing
Validation Manuelle
npm installs'exécute sans erreurnpm run buildgénèreoutput.cssnpm run devlance le watch mode- Le fichier
output.css< 50kb - Les classes Tailwind fonctionnent dans le navigateur
Commandes de Test
# Installer les dépendances
npm install
# Build production
npm run build
# Vérifier la taille du CSS
ls -lh assets/css/output.css
# Lancer le watch pour le dev
npm run dev
Test Visuel
Créer un fichier HTML temporaire pour tester les classes :
.btn-primary→ bouton orange.bg-background→ fond sombre #17171F.text-primary→ texte orange.card→ carte avec fond surface
Change Log
| Date | Version | Description | Author |
|---|---|---|---|
| 2026-01-22 | 0.1 | Création initiale de la story | Sarah (PO) |
Dev Agent Record
Agent Model Used
Claude Opus 4.5 (claude-opus-4-5-20251101)
Debug Log References
À compléter par le dev agent
Completion Notes List
- Package.json mis à jour (v2.0.0) avec scripts dev/build Tailwind
- Dépendances installées : tailwindcss ^3.4.0, postcss ^8.4.0, autoprefixer ^10.4.0
- tailwind.config.js créé avec palette couleurs sombre, polices Inter/JetBrains Mono
- input.css complet avec @layer base, components (btn, card, input, badge, etc.), utilities (animations)
- postcss.config.js configuré
- Build validé : output.css = 6,4 Ko (< 50 Ko requis)
- Warning normal : pas encore de fichiers PHP utilisant les classes
File List
| Fichier | Action |
|---|---|
package.json |
Modifié |
package-lock.json |
Modifié |
tailwind.config.js |
Créé |
postcss.config.js |
Créé |
assets/css/input.css |
Créé |
assets/css/output.css |
Généré |
QA Results
À compléter par le QA agent