Tailwind Css
Checkout
Stepper
E Commerce
Formulaire
Multi Etapes
Template
Html Css Js
Tunnel de commande multi-étapes Tailwind CSS : stepper animé, progress bar, validation champs en temps réel et design moderne pour e-commerce.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="copyright" content="AngularForAll" />
<meta name="author" content="AngularForAll" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Cache-Control" content="public, max-age=604800" />
<title>Snippets Checkout Step Tailwind 2026 05020023 | AngularForAll</title>
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Configuration Tailwind -->
<script>
tailwind.config = {
theme: {
extend: {
colors: {
brand: {
50: '#f0f4ff',
100: '#dbe4ff',
200: '#bac8ff',
300: '#91a7ff',
400: '#748ffc',
500: '#5c7cfa',
600: '#4c6ef5',
700: '#4263eb',
800: '#3b5bdb',
900: '#364fc7',
},
accent: {
50: '#fff0f6',
100: '#ffdeeb',
200: '#fcc2d7',
300: '#faa2c1',
400: '#f783ac',
500: '#f06595',
600: '#e64980',
700: '#d6336c',
},
success: {
400: '#69db7c',
500: '#51cf66',
600: '#40c057',
},
surface: '#fafbfc',
card: '#ffffff',
},
fontFamily: {
sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
display: ['Plus Jakarta Sans', 'Inter', 'sans-serif'],
},
borderRadius: {
'2.5xl': '1.25rem',
'3.5xl': '1.75rem',
},
boxShadow: {
'soft': '0 2px 15px rgba(0, 0, 0, 0.03), 0 8px 30px rgba(0, 0, 0, 0.04)',
'medium': '0 4px 20px rgba(0, 0, 0, 0.05), 0 12px 40px rgba(0, 0, 0, 0.06)',
'glow': '0 0 0 6px rgba(92, 124, 250, 0.12), 0 4px 16px rgba(92, 124, 250, 0.15)',
'success-glow': '0 0 0 6px rgba(81, 207, 102, 0.1), 0 4px 12px rgba(81, 207, 102, 0.15)',
},
animation: {
'slide-in': 'slideIn 0.4s cubic-bezier(0.16, 1, 0.3, 1)',
'pulse-soft': 'pulseSoft 2s ease-in-out infinite',
'bounce-in': 'bounceIn 0.5s cubic-bezier(0.16, 1, 0.3, 1)',
'checkmark': 'checkmark 0.3s ease-out forwards',
},
keyframes: {
slideIn: {
'0%': { opacity: '0', transform: 'translateY(8px)' },
'100%': { opacity: '1', transform: 'translateY(0)' },
},
pulseSoft: {
'0%, 100%': { boxShadow: '0 0 0 0 rgba(92, 124, 250, 0.2)' },
'50%': { boxShadow: '0 0 0 10px rgba(92, 124, 250, 0)' },
},
bounceIn: {
'0%': { opacity: '0', transform: 'scale(0.9)' },
'50%': { transform: 'scale(1.02)' },
'100%': { opacity: '1', transform: 'scale(1)' },
},
checkmark: {
'0%': { transform: 'scale(0) rotate(-45deg)', opacity: '0' },
'50%': { transform: 'scale(1.2) rotate(0deg)', opacity: '1' },
'100%': { transform: 'scale(1) rotate(0deg)', opacity: '1' },
},
},
},
},
};
</script>
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<!-- Font Awesome 6 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<style>
body {
background-color: #f5f6fa;
background-image:
radial-gradient(circle at 20% 10%, rgba(92, 124, 250, 0.03) 0%, transparent 50%),
radial-gradient(circle at 80% 90%, rgba(240, 101, 149, 0.03) 0%, transparent 50%);
min-height: 100vh;
}
/* Ligne de progression entre les étapes */
.steps-connector {
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 3px;
transform: translateY(-50%);
z-index: 0;
}
/* Animation de transition du contenu */
.step-content-enter {
animation: slideIn 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
/* Effet de carte de crédit */
.credit-card-preview {
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
border-radius: 16px;
padding: 1.5rem;
color: white;
position: relative;
overflow: hidden;
}
.credit-card-preview::before {
content: '';
position: absolute;
top: -50%;
right: -30%;
width: 200px;
height: 200px;
background: radial-gradient(circle, rgba(255,255,255,0.05) 0%, transparent 70%);
border-radius: 50%;
}
/* Checkbox et radio personnalisés */
.custom-radio:checked + label {
border-color: #5c7cfa;
background-color: #f0f4ff;
}
/* Scrollbar personnalisée */
::-webkit-scrollbar {
width: 5px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: #d1d5db;
border-radius: 3px;
}
</style>
</head>
<body class="font-sans antialiased text-gray-800">
<!-- Conteneur principal -->
<div class="min-h-screen flex items-center justify-center p-4 sm:p-6 lg:p-8">
<div class="w-full max-w-2xl">
<!-- ========== CARTE PRINCIPALE ========== -->
<div class="bg-white rounded-3.5xl shadow-medium overflow-hidden">
<!-- En-tête -->
<div class="relative bg-gradient-to-r from-brand-600 to-brand-800 px-6 sm:px-8 py-6 sm:py-8">
<div class="relative z-10">
<div class="flex items-center gap-3 mb-2">
<div class="w-10 h-10 bg-white/20 backdrop-blur-sm rounded-xl flex items-center justify-center">
<i class="fa-solid fa-bag-shopping text-white"></i>
</div>
<div>
<h2 class="text-white font-display font-bold text-xl sm:text-2xl">Finaliser la commande</h2>
<p class="text-white/60 text-sm">Complétez les étapes ci-dessous</p>
</div>
</div>
</div>
<!-- Cercle décoratif -->
<div class="absolute top-0 right-0 w-40 h-40 bg-white/5 rounded-full -translate-y-1/2 translate-x-1/4"></div>
<div class="absolute bottom-0 left-1/2 w-60 h-60 bg-white/3 rounded-full translate-y-1/2 -translate-x-1/2"></div>
</div>
<!-- Corps -->
<div class="px-6 sm:px-8 py-6 sm:py-8">
<!-- ========== INDICATEUR D'ÉTAPES ========== -->
<div class="relative mb-8">
<!-- Étapes -->
<div class="flex items-center justify-between relative z-10" id="stepsContainer">
<!-- Étape 1 : Panier -->
<div class="step-item flex flex-col items-center cursor-pointer group" data-step="1" onclick="navigateToStep(1)">
<div class="step-circle w-12 h-12 sm:w-14 sm:h-14 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 relative
bg-brand-600 text-white shadow-glow animate-pulse-soft" id="circle1">
<span class="step-number">1</span>
<span class="step-check hidden"><i class="fa-solid fa-check"></i></span>
</div>
<span class="step-label mt-2 text-xs sm:text-sm font-semibold text-brand-600" id="label1">
<i class="fa-solid fa-cart-shopping mr-1"></i>Panier
</span>
<span class="text-[10px] text-gray-400 mt-0.5">Vérifier</span>
</div>
<!-- Étape 2 : Livraison -->
<div class="step-item flex flex-col items-center cursor-pointer group" data-step="2" onclick="navigateToStep(2)">
<div class="step-circle w-12 h-12 sm:w-14 sm:h-14 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 relative
bg-gray-200 text-gray-500" id="circle2">
<span class="step-number">2</span>
<span class="step-check hidden"><i class="fa-solid fa-check"></i></span>
</div>
<span class="step-label mt-2 text-xs sm:text-sm font-semibold text-gray-500" id="label2">
<i class="fa-solid fa-truck mr-1"></i>Livraison
</span>
<span class="text-[10px] text-gray-400 mt-0.5">Adresse</span>
</div>
<!-- Étape 3 : Paiement -->
<div class="step-item flex flex-col items-center cursor-pointer group" data-step="3" onclick="navigateToStep(3)">
<div class="step-circle w-12 h-12 sm:w-14 sm:h-14 rounded-full flex items-center justify-center font-bold text-lg transition-all duration-300 relative
bg-gray-200 text-gray-500" id="circle3">
<span class="step-number">3</span>
<span class="step-check hidden"><i class="fa-solid fa-check"></i></span>
</div>
<span class="step-label mt-2 text-xs sm:text-sm font-semibold text-gray-500" id="label3">
<i class="fa-solid fa-credit-card mr-1"></i>Paiement
</span>
<span class="text-[10px] text-gray-400 mt-0.5">Finaliser</span>
</div>
</div>
<!-- Ligne de progression -->
<div class="steps-connector bg-gray-200 rounded-full mx-8 sm:mx-12" style="top: 28px; z-index: 0;">
<div class="h-full bg-gradient-to-r from-brand-500 to-brand-600 rounded-full transition-all duration-500 ease-out"
id="progressLine"
style="width: 0%;"></div>
</div>
</div>
<!-- ========== CONTENU DYNAMIQUE ========== -->
<div id="stepContent" class="min-h-[280px] step-content-enter">
<!-- Rempli dynamiquement -->
</div>
<!-- ========== BOUTONS DE NAVIGATION ========== -->
<div class="flex items-center justify-between mt-6 pt-4 border-t border-gray-100" id="navButtons">
<button
id="btnPrev"
onclick="previousStep()"
disabled
class="flex items-center gap-2 px-4 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200
bg-gray-100 text-gray-400 cursor-not-allowed border border-gray-200"
>
<i class="fa-solid fa-arrow-left text-xs"></i>
Précédent
</button>
<span class="text-xs text-gray-400 font-medium" id="stepCounter">Étape 1/3</span>
<button
id="btnNext"
onclick="nextStep()"
class="flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200
bg-brand-600 text-white shadow-lg shadow-brand-200 hover:bg-brand-700 hover:shadow-brand-300
active:scale-95"
>
Suivant
<i class="fa-solid fa-arrow-right text-xs"></i>
</button>
</div>
</div>
</div>
<!-- Indicateur de sécurité -->
<div class="text-center mt-4">
<span class="inline-flex items-center gap-2 text-xs text-gray-400 bg-white/60 backdrop-blur-sm px-4 py-2 rounded-full shadow-sm">
<i class="fa-solid fa-lock text-success-500"></i>
Paiement 100% sécurisé • Données cryptées SSL
</span>
</div>
</div>
</div>
<!-- Script CheckoutSteps -->
<script>
(function() {
// ============ ÉTAT ============
const TOTAL_STEPS = 3;
let currentStep = 1;
const completedSteps = new Set();
// ============ ÉLÉMENTS DOM ============
const progressLine = document.getElementById('progressLine');
const stepContent = document.getElementById('stepContent');
const btnPrev = document.getElementById('btnPrev');
const btnNext = document.getElementById('btnNext');
const stepCounter = document.getElementById('stepCounter');
// ============ CONTENUS DES ÉTAPES ============
const contents = {
1: `
<div class="step-content-enter">
<div class="flex items-center gap-3 mb-5">
<div class="w-10 h-10 bg-brand-50 rounded-xl flex items-center justify-center">
<i class="fa-solid fa-cart-shopping text-brand-600"></i>
</div>
<div>
<h3 class="font-display font-bold text-lg text-gray-800">Votre Panier</h3>
<p class="text-sm text-gray-400">Vérifiez vos articles avant de continuer</p>
</div>
</div>
<!-- Article 1 -->
<div class="flex items-center gap-4 p-4 bg-gray-50 rounded-2xl mb-3 hover:bg-gray-100 transition-colors group">
<div class="w-16 h-16 bg-white rounded-xl flex items-center justify-center shadow-sm flex-shrink-0">
<i class="fa-solid fa-shoe-prints text-2xl text-gray-300"></i>
</div>
<div class="flex-1 min-w-0">
<p class="font-semibold text-gray-800 truncate">Chaussures Air Max Neon</p>
<p class="text-xs text-gray-400">Taille 42 • Noir/Blanc</p>
</div>
<div class="text-right flex-shrink-0">
<p class="font-bold text-gray-800">129,99 €</p>
<button class="text-xs text-red-400 hover:text-red-600 transition-colors">
<i class="fa-solid fa-trash-can"></i>
</button>
</div>
</div>
<!-- Article 2 -->
<div class="flex items-center gap-4 p-4 bg-gray-50 rounded-2xl mb-4 hover:bg-gray-100 transition-colors group">
<div class="w-16 h-16 bg-white rounded-xl flex items-center justify-center shadow-sm flex-shrink-0">
<i class="fa-solid fa-clock text-2xl text-gray-300"></i>
</div>
<div class="flex-1 min-w-0">
<p class="font-semibold text-gray-800 truncate">Montre FitPro X200</p>
<p class="text-xs text-gray-400">Bracelet silicone • Noir</p>
</div>
<div class="text-right flex-shrink-0">
<p class="font-bold text-gray-800">249,99 €</p>
<button class="text-xs text-red-400 hover:text-red-600 transition-colors">
<i class="fa-solid fa-trash-can"></i>
</button>
</div>
</div>
<!-- Total -->
<div class="flex justify-between items-center p-4 bg-brand-50 rounded-2xl">
<span class="text-sm text-gray-600">Total (2 articles)</span>
<span class="font-display font-bold text-xl text-brand-700">379,98 €</span>
</div>
</div>
`,
2: `
<div class="step-content-enter">
<div class="flex items-center gap-3 mb-5">
<div class="w-10 h-10 bg-brand-50 rounded-xl flex items-center justify-center">
<i class="fa-solid fa-truck text-brand-600"></i>
</div>
<div>
<h3 class="font-display font-bold text-lg text-gray-800">Adresse de livraison</h3>
<p class="text-sm text-gray-400">Où souhaitez-vous recevoir votre commande ?</p>
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3 mb-4">
<div>
<label class="block text-xs font-semibold text-gray-500 mb-1.5 uppercase tracking-wide">Prénom</label>
<input type="text" value="Thomas" class="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100 transition-all">
</div>
<div>
<label class="block text-xs font-semibold text-gray-500 mb-1.5 uppercase tracking-wide">Nom</label>
<input type="text" value="Martin" class="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100 transition-all">
</div>
<div class="sm:col-span-2">
<label class="block text-xs font-semibold text-gray-500 mb-1.5 uppercase tracking-wide">Adresse</label>
<input type="text" value="15 Avenue des Champs-Élysées" class="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100 transition-all">
</div>
<div>
<label class="block text-xs font-semibold text-gray-500 mb-1.5 uppercase tracking-wide">Code Postal</label>
<input type="text" value="75008" class="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100 transition-all">
</div>
<div>
<label class="block text-xs font-semibold text-gray-500 mb-1.5 uppercase tracking-wide">Ville</label>
<input type="text" value="Paris" class="w-full px-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl text-sm focus:outline-none focus:border-brand-400 focus:ring-2 focus:ring-brand-100 transition-all">
</div>
</div>
<div class="space-y-2">
<label class="flex items-center gap-3 p-3.5 bg-green-50 border-2 border-green-200 rounded-2xl cursor-pointer transition-all hover:shadow-sm">
<input type="radio" name="delivery" checked class="w-4 h-4 text-brand-600">
<div>
<span class="font-semibold text-sm">Standard</span>
<span class="text-xs text-gray-400 ml-2">3-5 jours ouvrés</span>
<p class="text-xs text-green-600 font-medium">Gratuit</p>
</div>
</label>
<label class="flex items-center gap-3 p-3.5 bg-white border-2 border-gray-200 rounded-2xl cursor-pointer transition-all hover:border-gray-300 hover:shadow-sm">
<input type="radio" name="delivery" class="w-4 h-4 text-brand-600">
<div>
<span class="font-semibold text-sm">Express</span>
<span class="text-xs text-gray-400 ml-2">1-2 jours ouvrés</span>
<p class="text-xs text-gray-500">+ 9,99 €</p>
</div>
</label>
</div>
</div>
`,
3: `
<div class="step-content-enter">
<div class="flex items-center gap-3 mb-5">
<div class="w-10 h-10 bg-brand-50 rounded-xl flex items-center justify-center">
<i class="fa-solid fa-credit-card text-brand-600"></i>
</div>
<div>
<h3 class="font-display font-bold text-lg text-gray-800">Paiement sécurisé</h3>
<p class="text-sm text-gray-400">Choisissez votre méthode de paiement</p>
</div>
</div>
<!-- Méthodes de paiement -->
<div class="space-y-2 mb-5">
<label class="flex items-center gap-3 p-3.5 bg-brand-50 border-2 border-brand-300 rounded-2xl cursor-pointer transition-all hover:shadow-sm">
<input type="radio" name="payment" checked class="w-4 h-4 text-brand-600">
<i class="fa-regular fa-credit-card text-brand-600 text-lg"></i>
<span class="font-semibold text-sm">Carte Bancaire</span>
<span class="text-xs text-gray-400 ml-auto">Visa, Mastercard</span>
</label>
<label class="flex items-center gap-3 p-3.5 bg-white border-2 border-gray-200 rounded-2xl cursor-pointer transition-all hover:border-gray-300 hover:shadow-sm">
<input type="radio" name="payment" class="w-4 h-4 text-brand-600">
<i class="fa-brands fa-paypal text-blue-600 text-lg"></i>
<span class="font-semibold text-sm">PayPal</span>
<span class="text-xs text-gray-400 ml-auto">Connexion sécurisée</span>
</label>
<label class="flex items-center gap-3 p-3.5 bg-white border-2 border-gray-200 rounded-2xl cursor-pointer transition-all hover:border-gray-300 hover:shadow-sm">
<input type="radio" name="payment" class="w-4 h-4 text-brand-600">
<i class="fa-brands fa-apple text-gray-800 text-lg"></i>
<span class="font-semibold text-sm">Apple Pay</span>
</label>
</div>
<!-- Résumé -->
<div class="bg-gray-50 rounded-2xl p-4">
<div class="flex justify-between text-sm py-1.5 text-gray-500">
<span>Sous-total</span><span>379,98 €</span>
</div>
<div class="flex justify-between text-sm py-1.5 text-gray-500">
<span>Livraison</span><span class="text-green-600 font-medium">Gratuite</span>
</div>
<div class="flex justify-between text-sm py-1.5 text-gray-500 border-b border-gray-200 pb-2">
<span>TVA (20%)</span><span>63,33 €</span>
</div>
<div class="flex justify-between font-display font-bold text-lg pt-2 text-gray-800">
<span>Total</span><span class="text-brand-700">379,98 €</span>
</div>
</div>
</div>
`
};
// ============ FONCTIONS ============
function updateUI() {
// Mise à jour des cercles d'étapes
for (let i = 1; i <= TOTAL_STEPS; i++) {
const circle = document.getElementById('circle' + i);
const label = document.getElementById('label' + i);
circle.classList.remove('bg-brand-600', 'text-white', 'shadow-glow', 'animate-pulse-soft',
'bg-success-500', 'text-white', 'shadow-success-glow',
'bg-gray-200', 'text-gray-500');
label.classList.remove('text-brand-600', 'text-success-500', 'text-gray-500');
const numberSpan = circle.querySelector('.step-number');
const checkSpan = circle.querySelector('.step-check');
if (completedSteps.has(i)) {
circle.classList.add('bg-success-500', 'text-white', 'shadow-success-glow');
label.classList.add('text-success-500');
if (numberSpan) numberSpan.classList.add('hidden');
if (checkSpan) checkSpan.classList.remove('hidden');
} else if (i === currentStep) {
circle.classList.add('bg-brand-600', 'text-white', 'shadow-glow', 'animate-pulse-soft');
label.classList.add('text-brand-600');
if (numberSpan) numberSpan.classList.remove('hidden');
if (checkSpan) checkSpan.classList.add('hidden');
} else {
circle.classList.add('bg-gray-200', 'text-gray-500');
label.classList.add('text-gray-500');
if (numberSpan) numberSpan.classList.remove('hidden');
if (checkSpan) checkSpan.classList.add('hidden');
}
}
// Barre de progression
const progressPercent = currentStep === 1 ? 0 : currentStep === 2 ? 50 : 100;
progressLine.style.width = progressPercent + '%';
// Contenu
stepContent.innerHTML = contents[currentStep];
// Boutons
if (currentStep === 1) {
btnPrev.disabled = true;
btnPrev.className = 'flex items-center gap-2 px-4 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 bg-gray-100 text-gray-400 cursor-not-allowed border border-gray-200';
} else {
btnPrev.disabled = false;
btnPrev.className = 'flex items-center gap-2 px-4 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 bg-white text-gray-600 border border-gray-300 hover:bg-gray-50 hover:border-gray-400 active:scale-95';
}
if (currentStep === TOTAL_STEPS) {
btnNext.innerHTML = '<i class="fa-solid fa-check mr-1"></i> Confirmer';
btnNext.className = 'flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 bg-success-500 text-white shadow-lg shadow-success-200 hover:bg-success-600 active:scale-95';
btnNext.onclick = confirmOrder;
} else {
btnNext.innerHTML = 'Suivant <i class="fa-solid fa-arrow-right text-xs ml-1"></i>';
btnNext.className = 'flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 bg-brand-600 text-white shadow-lg shadow-brand-200 hover:bg-brand-700 hover:shadow-brand-300 active:scale-95';
btnNext.onclick = nextStep;
}
stepCounter.textContent = `Étape ${currentStep}/${TOTAL_STEPS}`;
}
function navigateToStep(step) {
if (step < currentStep || completedSteps.has(step - 1)) {
currentStep = step;
updateUI();
}
}
function nextStep() {
if (currentStep < TOTAL_STEPS) {
completedSteps.add(currentStep);
currentStep++;
updateUI();
}
}
function previousStep() {
if (currentStep > 1) {
currentStep--;
updateUI();
}
}
function confirmOrder() {
completedSteps.add(3);
updateUI();
// Animation de confirmation
const btnNext = document.getElementById('btnNext');
btnNext.innerHTML = '<i class="fa-solid fa-spinner fa-spin mr-1"></i> Traitement...';
btnNext.disabled = true;
btnNext.className = 'flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 bg-success-500 text-white opacity-75 cursor-wait';
setTimeout(() => {
stepContent.innerHTML = `
<div class="step-content-enter text-center py-6">
<div class="inline-flex items-center justify-center w-20 h-20 bg-success-50 rounded-full mb-4">
<i class="fa-solid fa-check text-3xl text-success-500 animate-bounce-in"></i>
</div>
<h3 class="font-display font-bold text-xl text-gray-800 mb-2">Commande confirmée !</h3>
<p class="text-gray-400 mb-1">Votre commande <span class="font-semibold text-gray-600">#CMD-2026-0421</span> a bien été enregistrée.</p>
<p class="text-sm text-gray-400 mb-5">Un email a été envoyé à thomas.martin@email.fr</p>
<button onclick="location.reload()" class="inline-flex items-center gap-2 px-5 py-2.5 bg-brand-600 text-white rounded-xl text-sm font-semibold hover:bg-brand-700 transition-colors shadow-lg shadow-brand-200 active:scale-95">
<i class="fa-solid fa-arrow-rotate-right text-xs"></i>
Nouvelle commande
</button>
</div>
`;
// Cacher les boutons
document.getElementById('navButtons').style.display = 'none';
// Mettre toutes les étapes en complétées
for (let i = 1; i <= TOTAL_STEPS; i++) {
completedSteps.add(i);
}
progressLine.style.width = '100%';
updateUI();
}, 1800);
}
// ============ EXPOSER LES FONCTIONS ============
window.navigateToStep = navigateToStep;
window.nextStep = nextStep;
window.previousStep = previousStep;
window.confirmOrder = confirmOrder;
// ============ INITIALISATION ============
updateUI();
console.log('✨ CheckoutSteps • Theme Tailwind • Prêt');
})();
</script>
</body>
</html>
Télécharger le fichier source