deepsite-project-0eeaz / simulateur.html
Yocapp's picture
✍️ 14/04 - 12:28 - Manual changes.
2d85b81 verified
Raw
History Blame Contribute Delete
34.4 kB
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>TIE - Combien gagnez-vous vraiment ?</title>
<script src="https://cdn.tailwindcss.com"></script>
<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@400;500;600;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Inter', ui-sans-serif, system-ui, sans-serif;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type=number] {
-moz-appearance: textfield;
}
.step-container {
display: none;
animation: fadeIn 0.3s ease-out;
}
.step-container.active {
display: block;
}
.analysis-container {
display: none;
animation: fadeIn 0.35s ease-out;
}
.analysis-container.active {
display: block;
}
.info-box {
display: none;
animation: fadeIn 0.25s ease-out;
}
.info-box.active {
display: block;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body class="bg-[#0b0b0f] text-white antialiased min-h-screen">
<header class="sticky top-0 z-50 bg-[#0b0b0f]/90 backdrop-blur-xl border-b border-white/5">
<div class="max-w-3xl mx-auto px-5 py-4 flex items-center justify-between">
<a href="index.html" class="text-sm text-white/60 hover:text-white transition flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg>
Retour
</a>
<div class="text-lg font-semibold tracking-tight text-white">TIE</div>
</div>
</header>
<main class="max-w-3xl mx-auto px-5 pt-6 pb-28">
<div class="text-[11px] text-white/50 mb-3 uppercase tracking-wide">Simulation rapide</div>
<h1 class="text-[26px] leading-tight font-semibold text-white mb-3">Combien gagnez-vous vraiment ?</h1>
<p class="text-sm text-white/60 mb-6">En 30 secondes, estimez la rentabilité réelle d'une course.</p>
<div class="mb-6">
<div class="flex justify-between items-center mb-2">
<span class="text-xs text-white/45">Étape <span id="stepLabel">1</span> sur 4</span>
</div>
<div class="w-full h-1.5 bg-white/10 rounded-full overflow-hidden">
<div id="progressFill" class="h-full bg-emerald-500 rounded-full transition-all duration-300 ease-out" style="width: 25%"></div>
</div>
</div>
<!-- Step 1 -->
<div id="step1" class="step-container active">
<div class="bg-[#151821] border border-white/10 rounded-2xl p-5">
<label class="block text-sm text-white/80 mb-1.5 font-medium">Montant reçu pour la course (€)</label>
<p class="text-[11px] text-white/40 mb-3">
Indiquez le montant net versé par la plateforme ou le montant facturé si c’est un client privé.
</p>
<input
type="number"
id="price"
placeholder="Ex : 15"
step="0.01"
class="w-full rounded-xl bg-black/40 border border-white/10 px-4 py-3 text-white text-sm outline-none focus:border-emerald-500/50 transition mb-4"
>
<button id="btnStep1Next" class="w-full py-3 rounded-xl bg-emerald-500 text-black font-medium text-sm hover:opacity-90 transition">
Suivant
</button>
</div>
</div>
<!-- Step 2 -->
<div id="step2" class="step-container">
<div class="bg-[#151821] border border-white/10 rounded-2xl p-5">
<label class="block text-sm text-white/80 mb-4 font-medium">Distance et temps total</label>
<div class="space-y-3 mb-4">
<div>
<label class="block text-xs text-white/60 mb-1.5">Distance totale parcourue (km)</label>
<p class="text-[11px] text-white/40 mb-1.5">Inclure l’approche + la course</p>
<input
type="number"
id="distance"
placeholder="Ex : 8"
step="0.1"
class="w-full rounded-xl bg-black/40 border border-white/10 px-4 py-3 text-white text-sm outline-none focus:border-emerald-500/50 transition"
>
</div>
<div>
<label class="block text-xs text-white/60 mb-1.5">Temps total mobilisé (minutes)</label>
<p class="text-[11px] text-white/40 mb-1.5">Inclure l’approche, l’attente et le trajet</p>
<input
type="number"
id="time"
placeholder="Ex : 20"
class="w-full rounded-xl bg-black/40 border border-white/10 px-4 py-3 text-white text-sm outline-none focus:border-emerald-500/50 transition"
>
</div>
</div>
<div class="flex gap-3">
<button id="btnStep2Back" class="w-1/3 py-3 rounded-xl bg-white/5 text-white border border-white/10 text-sm font-medium hover:bg-white/10 transition">
Retour
</button>
<button id="btnStep2Next" class="w-2/3 py-3 rounded-xl bg-emerald-500 text-black font-medium text-sm hover:opacity-90 transition">
Suivant
</button>
</div>
</div>
</div>
<!-- Step 3 -->
<div id="step3" class="step-container">
<div class="bg-[#151821] border border-white/10 rounded-2xl p-5">
<label class="block text-sm text-white/80 mb-4 font-medium">Plateforme utilisée</label>
<div class="grid grid-cols-2 gap-2 mb-4" id="platformButtons">
<button type="button" data-value="uber" class="platform-btn flex-1 text-xs py-2.5 rounded-full border border-white/10 text-white/60 bg-transparent transition hover:border-white/30">Uber</button>
<button type="button" data-value="bolt" class="platform-btn flex-1 text-xs py-2.5 rounded-full border border-white/10 text-white/60 bg-transparent transition hover:border-white/30">Bolt</button>
<button type="button" data-value="heetch" class="platform-btn flex-1 text-xs py-2.5 rounded-full border border-white/10 text-white/60 bg-transparent transition hover:border-white/30">Heetch</button>
<button type="button" data-value="direct" class="platform-btn flex-1 text-xs py-2.5 rounded-full border border-white/10 text-white/60 bg-transparent transition hover:border-white/30">Client privé</button>
</div>
<input type="hidden" id="platform" value="">
<div class="flex gap-3">
<button id="btnStep3Back" class="w-1/3 py-3 rounded-xl bg-white/5 text-white border border-white/10 text-sm font-medium hover:bg-white/10 transition">
Retour
</button>
<button id="btnStep3Next" class="w-2/3 py-3 rounded-xl bg-emerald-500 text-black font-medium text-sm hover:opacity-90 transition disabled:opacity-40 disabled:cursor-not-allowed" disabled>
Suivant
</button>
</div>
</div>
</div>
<!-- Step 4 -->
<div id="step4" class="step-container">
<div class="bg-[#151821] border border-white/10 rounded-2xl p-5">
<label class="block text-sm text-white/80 mb-4 font-medium">Type de véhicule</label>
<div class="grid grid-cols-3 gap-2 mb-4" id="vehicleButtons">
<button type="button" data-value="thermique" class="vehicle-btn flex-1 text-xs py-2.5 rounded-full border border-white/10 text-white/60 bg-transparent transition hover:border-white/30">Thermique</button>
<button type="button" data-value="hybride" class="vehicle-btn flex-1 text-xs py-2.5 rounded-full border border-white/10 text-white/60 bg-transparent transition hover:border-white/30">Hybride</button>
<button type="button" data-value="electrique" class="vehicle-btn flex-1 text-xs py-2.5 rounded-full border border-white/10 text-white/60 bg-transparent transition hover:border-white/30">Électrique</button>
</div>
<input type="hidden" id="vehicle" value="">
<div class="flex gap-3">
<button id="btnStep4Back" class="w-1/3 py-3 rounded-xl bg-white/5 text-white border border-white/10 text-sm font-medium hover:bg-white/10 transition">
Retour
</button>
<button id="btnStep4Calculate" class="w-2/3 py-3 rounded-xl bg-emerald-500 text-black font-medium text-sm hover:opacity-90 transition disabled:opacity-40 disabled:cursor-not-allowed" disabled>
Calculer ma rentabilité
</button>
</div>
</div>
</div>
<!-- Result -->
<div id="resultScreen" class="step-container">
<div id="resultBlock" class="mt-2 rounded-2xl border border-emerald-500/30 bg-[#1a1f2b] p-5">
<div class="text-[11px] text-emerald-400/70 mb-2 uppercase tracking-wide">Résultat</div>
<div id="mainResult" class="text-[32px] font-semibold text-white mb-2">Il vous reste : 0,00 €</div>
<div id="hourlyRate" class="text-sm text-white/60 mb-1">Soit 0,00 €/heure</div>
<div id="statusLine" class="text-sm text-white/60 mt-1 mb-5">Rentabilité correcte</div>
<button id="btnRevealAnalysis" class="w-full py-3 rounded-xl bg-emerald-500 text-black font-medium text-sm hover:opacity-90 transition mb-3">
Découvrir l'analyse TIE
</button>
<button id="btnResetResult" class="w-full py-2 text-xs text-white/60 hover:text-white transition">
Refaire une simulation
</button>
</div>
<div id="analysisContainer" class="analysis-container mt-4 rounded-2xl border border-emerald-500/30 bg-[#1a1f2b] p-5">
<div class="mb-4 rounded-xl bg-black/30 border border-white/10 p-4">
<div class="text-[11px] text-emerald-400/80 uppercase tracking-wide mb-2">Lecture TIE</div>
<div id="analysisHeadline" class="text-base font-semibold text-white mb-1">Analyse de votre course</div>
<div id="analysisSummary" class="text-sm text-white/65 leading-relaxed">
Résumé de votre rentabilité.
</div>
</div>
<div class="rounded-xl bg-black/20 border border-white/10 p-4 mb-4">
<div class="flex items-center justify-between mb-3">
<div class="text-sm font-medium text-white">Détail estimatif</div>
<button
id="btnChargesInfo"
type="button"
class="inline-flex items-center justify-center w-6 h-6 rounded-full border border-white/10 text-[11px] text-white/60 hover:text-white hover:border-white/30 transition"
aria-expanded="false"
aria-controls="chargesInfoBox"
>i</button>
</div>
<div class="space-y-2 text-xs text-white/55">
<div class="flex justify-between gap-4">
<span>CA brut estimé à déclarer</span>
<span id="grossRevenueDetail" class="text-white/85">0,00 €</span>
</div>
<div class="flex justify-between gap-4">
<span>Énergie</span>
<span id="energyDetail" class="text-white/85">-0,00 €</span>
</div>
<div class="flex justify-between gap-4">
<span>Usure véhicule</span>
<span id="wearDetail" class="text-white/85">-0,00 €</span>
</div>
<div class="flex justify-between gap-4">
<span>Charges sociales & activité</span>
<span id="chargesDetail" class="text-white/85">-0,00 €</span>
</div>
</div>
<div id="chargesInfoBox" class="info-box mt-3 rounded-xl bg-white/5 border border-white/10 p-3">
<div class="text-[11px] text-white/65 leading-relaxed">
Les charges varient selon votre statut. Cette estimation est basée sur un profil <span class="text-white font-medium">micro-entrepreneur</span>.
Pour les plateformes, le <span class="text-white font-medium">CA brut déclaré</span> est reconstitué à partir d’une commission moyenne indicative, car les commissions réelles peuvent varier.
</div>
</div>
</div>
<div class="rounded-xl bg-black/40 border border-white/10 p-4 mb-4">
<div class="text-sm font-medium text-white mb-3">Analyse</div>
<div id="analysisBullets" class="space-y-2 text-sm text-white/70"></div>
</div>
<div id="tieComparison" class="hidden rounded-xl bg-emerald-500/10 border border-emerald-500/20 p-4 text-sm text-emerald-300"></div>
</div>
</div>
</main>
<script>
let currentStep = 1;
const totalSteps = 4;
let formData = {
price: 0,
distance: 0,
time: 0,
platform: '',
vehicle: ''
};
function formatMoney(value) {
return value.toFixed(2).replace('.', ',') + ' €';
}
function formatNumber(value) {
return value.toFixed(2).replace('.', ',');
}
function getVehicleLabel(vehicle) {
if (vehicle === 'thermique') return 'Thermique';
if (vehicle === 'hybride') return 'Hybride';
if (vehicle === 'electrique') return 'Électrique';
return '-';
}
function getEstimatedCommissionRate(platform) {
if (platform === 'uber') return 0.25;
if (platform === 'bolt') return 0.20;
if (platform === 'heetch') return 0.15;
if (platform === 'direct') return 0;
return 0.20;
}
function getEnergyCostPerKm(vehicle) {
if (vehicle === 'thermique') return 0.117;
if (vehicle === 'hybride') return 0.081;
if (vehicle === 'electrique') return 0.03;
return 0.117;
}
function updateProgress() {
const progress = (currentStep / totalSteps) * 100;
document.getElementById('progressFill').style.width = progress + '%';
document.getElementById('stepLabel').textContent = Math.min(currentStep, totalSteps);
}
function showStep(step) {
document.querySelectorAll('.step-container').forEach(el => el.classList.remove('active'));
if (step === 5) {
document.getElementById('resultScreen').classList.add('active');
document.getElementById('stepLabel').textContent = '4';
document.getElementById('progressFill').style.width = '100%';
currentStep = 4;
return;
}
currentStep = step;
const target = document.getElementById('step' + step);
if (target) {
target.classList.add('active');
}
updateProgress();
}
function ensureLoadingScreen() {
let loadingScreen = document.getElementById('loadingScreen');
if (loadingScreen) return loadingScreen;
const resultScreen = document.getElementById('resultScreen');
loadingScreen = document.createElement('div');
loadingScreen.id = 'loadingScreen';
loadingScreen.className = 'step-container';
loadingScreen.innerHTML = `
<div class="bg-[#151821] border border-white/10 rounded-2xl p-6 text-center">
<div class="w-14 h-14 mx-auto mb-4 rounded-full border-2 border-white/10 border-t-emerald-500 animate-spin"></div>
<div class="text-sm font-medium text-white mb-1">Analyse de votre course</div>
<div class="text-xs text-white/50">TIE calcule votre rentabilité...</div>
</div>
`;
resultScreen.parentNode.insertBefore(loadingScreen, resultScreen);
return loadingScreen;
}
function showLoadingScreen() {
ensureLoadingScreen();
document.querySelectorAll('.step-container').forEach(el => el.classList.remove('active'));
document.getElementById('loadingScreen').classList.add('active');
document.getElementById('stepLabel').textContent = '4';
document.getElementById('progressFill').style.width = '100%';
}
function setSelectedButtons(buttons, activeBtn) {
buttons.forEach(btn => {
btn.classList.remove('bg-white', 'text-black', 'border-white');
btn.classList.add('bg-transparent', 'text-white/60', 'border-white/10');
});
activeBtn.classList.remove('bg-transparent', 'text-white/60', 'border-white/10');
activeBtn.classList.add('bg-white', 'text-black', 'border-white');
}
function buildAnalysis(result) {
const bullets = [];
if (result.classification === 'Peu rentable') {
bullets.push("Le montant reçu est trop faible par rapport à la distance et au temps mobilisé.");
} else if (result.classification === 'Rentabilité moyenne') {
bullets.push("La course reste acceptable, mais votre marge est encore fragile.");
} else {
bullets.push("La course présente un bon équilibre entre prix, distance et temps.");
}
if (result.platform !== 'direct') {
bullets.push(`Le montant saisi est traité comme votre net réellement versé. Le CA brut estimé à déclarer est reconstitué à ${formatMoney(result.estimatedGrossRevenue)}.`);
} else {
bullets.push(`Comme il s’agit d’un client privé, le montant saisi correspond directement à votre CA brut estimé à déclarer : ${formatMoney(result.estimatedGrossRevenue)}.`);
}
if (result.vehicle === 'thermique') {
bullets.push("Avec un thermique, les courses trop faibles au kilomètre dégradent vite votre marge.");
} else if (result.vehicle === 'hybride') {
bullets.push("L’hybride protège mieux votre marge, mais il ne compense pas un tarif trop bas.");
} else {
bullets.push("L’électrique réduit fortement votre coût énergie, mais le temps mobilisé reste décisif.");
}
return bullets;
}
function calculateAndShow() {
const price = parseFloat(formData.price);
const distance = parseFloat(formData.distance);
const totalMinutes = parseFloat(formData.time);
const platform = formData.platform;
const vehicle = formData.vehicle;
if (!price || price <= 0 || !distance || distance <= 0 || !totalMinutes || totalMinutes <= 0 || !vehicle || !platform) {
alert('Veuillez compléter correctement toutes les informations.');
return;
}
const pricePerKm = price / distance;
const pricePerMinute = price / totalMinutes;
let classification = '';
let distanceScore = 0;
let timeScore = 0;
let vehicleScore = 0;
let scoreTotal = 0;
if (pricePerKm < 1.00) {
classification = 'Peu rentable';
scoreTotal = 0;
} else {
if (pricePerKm < 1.20) {
distanceScore = 0;
} else if (pricePerKm < 1.80) {
distanceScore = 1;
} else {
distanceScore = 2;
}
if (pricePerMinute < 0.50) {
timeScore = 0;
} else if (pricePerMinute < 0.80) {
timeScore = 1;
} else {
timeScore = 2;
}
if (vehicle === 'thermique') {
vehicleScore = 0;
} else if (vehicle === 'hybride') {
vehicleScore = 1;
} else if (vehicle === 'electrique') {
vehicleScore = 2;
}
scoreTotal = distanceScore + timeScore + vehicleScore;
if (scoreTotal <= 2) {
classification = 'Peu rentable';
} else if (scoreTotal <= 4) {
classification = 'Rentabilité moyenne';
} else {
classification = 'Rentable';
}
}
const estimatedCommissionRate = getEstimatedCommissionRate(platform);
const estimatedGrossRevenue = platform === 'direct'
? price
: price / (1 - estimatedCommissionRate);
const energyCostPerKm = getEnergyCostPerKm(vehicle);
const energyCost = distance * energyCostPerKm;
const wearCostPerKm = 0.20;
const wearCost = distance * wearCostPerKm;
const chargesRate = 0.22;
const chargesCost = estimatedGrossRevenue * chargesRate;
const estimatedRemaining = price - energyCost - wearCost - chargesCost;
const privatePrice = distance * 2;
const privateGrossRevenue = privatePrice;
const privateChargesCost = privateGrossRevenue * chargesRate;
const privateRemaining = privatePrice - energyCost - wearCost - privateChargesCost;
const privateDifference = privateRemaining - estimatedRemaining;
let statusText = '';
let summaryText = '';
if (classification === 'Peu rentable') {
statusText = 'Cette course vous rapporte trop peu pour la distance totale parcourue.';
summaryText = 'Marge faible : cette course use votre temps et votre véhicule plus qu’elle ne vous rémunère.';
} else if (classification === 'Rentabilité moyenne') {
statusText = 'Cette course peut se défendre, mais sa marge reste fragile.';
summaryText = 'Marge correcte mais fragile : intéressante seulement si l’approche est faible ou bien optimisée.';
} else {
statusText = 'Cette course présente un bon équilibre entre prix, distance et temps.';
summaryText = 'Bonne course : vous avez ici un niveau de rémunération cohérent avec votre mobilisation.';
}
const analysisBullets = buildAnalysis({
classification,
estimatedGrossRevenue,
platform,
vehicle
});
window.calculationResult = {
classification,
pricePerKm,
pricePerMinute,
vehicleLabel: getVehicleLabel(vehicle),
estimatedRemaining,
privatePrice,
privateRemaining,
privateDifference,
estimatedGrossRevenue,
estimatedCommissionRate,
energyCost,
wearCost,
chargesCost,
statusText,
summaryText,
analysisBullets,
platform,
vehicle,
price,
distance,
totalMinutes
};
showLoadingScreen();
setTimeout(() => {
document.getElementById('mainResult').textContent = formatMoney(estimatedRemaining);
document.getElementById('hourlyRate').innerHTML =
`${formatNumber((estimatedRemaining / totalMinutes) * 60)} €/heure estimé<br>` +
`Prix/km : ${formatNumber(pricePerKm)} € · Prix/minute : ${formatNumber(pricePerMinute)} €`;
document.getElementById('statusLine').textContent = statusText;
document.getElementById('analysisContainer').classList.remove('active');
document.getElementById('btnRevealAnalysis').style.display = 'block';
document.getElementById('chargesInfoBox').classList.remove('active');
document.getElementById('btnChargesInfo').setAttribute('aria-expanded', 'false');
showStep(5);
}, 1200);
}
// Step 1
document.getElementById('btnStep1Next').addEventListener('click', () => {
const price = parseFloat(document.getElementById('price').value);
if (!price || price <= 0) {
alert('Veuillez entrer un prix valide.');
return;
}
formData.price = price;
showStep(2);
});
// Step 2
document.getElementById('btnStep2Back').addEventListener('click', () => showStep(1));
document.getElementById('btnStep2Next').addEventListener('click', () => {
const distance = parseFloat(document.getElementById('distance').value);
const time = parseFloat(document.getElementById('time').value);
if (!distance || distance <= 0) {
alert('Veuillez entrer une distance valide.');
return;
}
if (!time || time <= 0) {
alert('Veuillez entrer un temps valide.');
return;
}
formData.distance = distance;
formData.time = time;
showStep(3);
});
// Step 3
const platformBtns = document.querySelectorAll('.platform-btn');
const btnStep3Next = document.getElementById('btnStep3Next');
platformBtns.forEach(btn => {
btn.addEventListener('click', () => {
setSelectedButtons(platformBtns, btn);
formData.platform = btn.dataset.value;
document.getElementById('platform').value = btn.dataset.value;
btnStep3Next.disabled = false;
});
});
document.getElementById('btnStep3Back').addEventListener('click', () => showStep(2));
document.getElementById('btnStep3Next').addEventListener('click', () => {
if (!formData.platform) {
alert('Veuillez sélectionner une plateforme.');
return;
}
showStep(4);
});
// Step 4
const vehicleBtns = document.querySelectorAll('.vehicle-btn');
const btnStep4Calculate = document.getElementById('btnStep4Calculate');
vehicleBtns.forEach(btn => {
btn.addEventListener('click', () => {
setSelectedButtons(vehicleBtns, btn);
formData.vehicle = btn.dataset.value;
document.getElementById('vehicle').value = btn.dataset.value;
btnStep4Calculate.disabled = false;
});
});
document.getElementById('btnStep4Back').addEventListener('click', () => showStep(3));
document.getElementById('btnStep4Calculate').addEventListener('click', calculateAndShow);
// Analysis reveal
document.getElementById('btnRevealAnalysis').addEventListener('click', () => {
const result = window.calculationResult;
if (!result) {
alert("Aucune analyse disponible. Veuillez recalculer la simulation.");
return;
}
document.getElementById('analysisHeadline').textContent =
result.classification === 'Rentable'
? 'Votre course semble bien calibrée'
: result.classification === 'Rentabilité moyenne'
? 'Votre course reste acceptable, mais surveillez votre marge'
: 'Votre course paraît peu rentable';
document.getElementById('analysisSummary').textContent = result.summaryText;
document.getElementById('grossRevenueDetail').textContent = formatMoney(result.estimatedGrossRevenue);
document.getElementById('energyDetail').textContent = '-' + formatMoney(result.energyCost);
document.getElementById('wearDetail').textContent = '-' + formatMoney(result.wearCost);
document.getElementById('chargesDetail').textContent = '-' + formatMoney(result.chargesCost);
const bulletsContainer = document.getElementById('analysisBullets');
bulletsContainer.innerHTML = result.analysisBullets
.map(item => `<div class="flex gap-2"><span class="text-emerald-400">•</span><span>${item}</span></div>`)
.join('');
const tieComparison = document.getElementById('tieComparison');
if (result.privateDifference > 0) {
tieComparison.textContent =
`À titre indicatif, un client privé facturé à 2 €/km sur cette même course pourrait vous laisser environ ${formatMoney(result.privateDifference)} de plus.`;
tieComparison.classList.remove('hidden');
} else {
tieComparison.textContent = '';
tieComparison.classList.add('hidden');
}
document.getElementById('analysisContainer').classList.add('active');
document.getElementById('btnRevealAnalysis').style.display = 'none';
document.getElementById('analysisContainer').scrollIntoView({
behavior: 'smooth',
block: 'nearest'
});
});
// Info button
document.getElementById('btnChargesInfo').addEventListener('click', () => {
const box = document.getElementById('chargesInfoBox');
const btn = document.getElementById('btnChargesInfo');
const isOpen = box.classList.contains('active');
box.classList.toggle('active');
btn.setAttribute('aria-expanded', String(!isOpen));
});
// Reset
function resetSimulation() {
formData = {
price: 0,
distance: 0,
time: 0,
platform: '',
vehicle: ''
};
window.calculationResult = null;
document.getElementById('price').value = '';
document.getElementById('distance').value = '';
document.getElementById('time').value = '';
document.getElementById('platform').value = '';
document.getElementById('vehicle').value = '';
platformBtns.forEach(b => {
b.classList.remove('bg-white', 'text-black', 'border-white');
b.classList.add('bg-transparent', 'text-white/60', 'border-white/10');
});
vehicleBtns.forEach(b => {
b.classList.remove('bg-white', 'text-black', 'border-white');
b.classList.add('bg-transparent', 'text-white/60', 'border-white/10');
});
btnStep3Next.disabled = true;
btnStep4Calculate.disabled = true;
document.getElementById('analysisContainer').classList.remove('active');
document.getElementById('btnRevealAnalysis').style.display = 'block';
document.getElementById('tieComparison').classList.add('hidden');
document.getElementById('tieComparison').textContent = '';
document.getElementById('chargesInfoBox').classList.remove('active');
document.getElementById('btnChargesInfo').setAttribute('aria-expanded', 'false');
const loadingScreen = document.getElementById('loadingScreen');
if (loadingScreen) loadingScreen.classList.remove('active');
showStep(1);
currentStep = 1;
updateProgress();
window.scrollTo({ top: 0, behavior: 'smooth' });
}
document.getElementById('btnResetResult').addEventListener('click', resetSimulation);
document.getElementById('price').addEventListener('keypress', (e) => {
if (e.key === 'Enter') document.getElementById('btnStep1Next').click();
});
document.getElementById('time').addEventListener('keypress', (e) => {
if (e.key === 'Enter') document.getElementById('btnStep2Next').click();
});
</script>
</body>
</html>