Calculateur de prix TTC – Pergola Evolution
:root {
–pe-ink: #17211c;
–pe-muted: #66736c;
–pe-line: #dfe6e1;
–pe-soft: #f4f7f5;
–pe-green: #21633f;
–pe-green-dark: #174a30;
–pe-accent: #e6b85c;
–pe-white: #ffffff;
–pe-radius: 18px;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: #eef2ef;
color: var(–pe-ink);
font-family: Arial, Helvetica, sans-serif;
line-height: 1.45;
}
.pergola-calculator {
width: min(100% – 32px, 980px);
margin: 40px auto;
overflow: hidden;
background: var(–pe-white);
border: 1px solid var(–pe-line);
border-radius: 24px;
box-shadow: 0 18px 48px rgba(23, 33, 28, .10);
}
.pergola-calculator__header {
padding: 34px 36px 30px;
color: #fff;
background:
radial-gradient(circle at 92% 15%, rgba(230, 184, 92, .24), transparent 27%),
linear-gradient(135deg, var(–pe-green-dark), var(–pe-green));
}
.pergola-calculator__eyebrow {
margin: 0 0 8px;
color: #e6efe9;
font-size: 13px;
font-weight: 700;
letter-spacing: .09em;
text-transform: uppercase;
}
.pergola-calculator h1 {
margin: 0;
font-size: clamp(26px, 4vw, 40px);
line-height: 1.12;
}
.pergola-calculator__intro {
max-width: 690px;
margin: 12px 0 0;
color: #e8f0eb;
font-size: 16px;
}
.pergola-calculator__body {
display: grid;
grid-template-columns: minmax(0, 1.25fr) minmax(290px, .75fr);
gap: 28px;
padding: 34px 36px 36px;
}
.pergola-form {
display: grid;
gap: 25px;
}
.pergola-fieldset {
min-width: 0;
margin: 0;
padding: 0;
border: 0;
}
.pergola-fieldset legend {
width: 100%;
margin-bottom: 11px;
padding: 0;
font-size: 16px;
font-weight: 700;
}
.pergola-fieldset legend span {
display: block;
margin-top: 3px;
color: var(–pe-muted);
font-size: 13px;
font-weight: 400;
}
.choice-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 9px;
}
.choice input {
position: absolute;
width: 1px;
height: 1px;
opacity: 0;
pointer-events: none;
}
.choice label {
display: flex;
min-height: 46px;
align-items: center;
justify-content: center;
padding: 9px 8px;
cursor: pointer;
user-select: none;
border: 1px solid var(–pe-line);
border-radius: 11px;
background: var(–pe-white);
font-size: 15px;
font-weight: 700;
transition: border-color .18s ease, background .18s ease, color .18s ease, transform .18s ease;
}
.choice label:hover {
border-color: #8a9d91;
transform: translateY(-1px);
}
.choice input:checked + label {
color: #fff;
border-color: var(–pe-green);
background: var(–pe-green);
box-shadow: 0 7px 18px rgba(33, 99, 63, .18);
}
.choice input:focus-visible + label {
outline: 3px solid rgba(230, 184, 92, .55);
outline-offset: 2px;
}
.color-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
.color-choice label {
justify-content: flex-start;
gap: 11px;
min-height: 58px;
padding: 11px 14px;
}
.swatch {
width: 27px;
height: 27px;
flex: 0 0 auto;
border: 1px solid rgba(23, 33, 28, .20);
border-radius: 50%;
box-shadow: inset 0 0 0 3px rgba(255, 255, 255, .45);
}
.swatch–white { background: #f7f7f4; }
.swatch–grey { background: linear-gradient(135deg, #666761 0 50%, #6e5243 50%); }
.price-card {
position: sticky;
top: 20px;
align-self: start;
overflow: hidden;
border: 1px solid #d4dfd8;
border-radius: var(–pe-radius);
background: var(–pe-soft);
}
.price-card__top {
padding: 23px 23px 18px;
}
.price-card__label {
margin: 0 0 4px;
color: var(–pe-muted);
font-size: 13px;
font-weight: 700;
letter-spacing: .05em;
text-transform: uppercase;
}
.price-card__price {
margin: 0;
color: var(–pe-green-dark);
font-size: clamp(34px, 5vw, 48px);
font-weight: 800;
line-height: 1.08;
letter-spacing: -.04em;
}
.price-card__tax {
color: var(–pe-muted);
font-size: 14px;
font-weight: 700;
}
.price-card__details {
display: grid;
gap: 0;
margin: 0;
padding: 0 23px 23px;
}
.price-card__row {
display: flex;
justify-content: space-between;
gap: 16px;
padding: 10px 0;
border-top: 1px solid #d8e1dc;
font-size: 14px;
}
.price-card__row dt { color: var(–pe-muted); }
.price-card__row dd { margin: 0; font-weight: 700; text-align: right; }
.price-card__notice {
margin: 0;
padding: 14px 23px;
border-top: 1px solid #d4dfd8;
background: #fff;
color: var(–pe-muted);
font-size: 12px;
}
@media (max-width: 760px) {
.pergola-calculator { width: min(100% – 20px, 620px); margin: 18px auto; }
.pergola-calculator__header { padding: 27px 22px 24px; }
.pergola-calculator__body { grid-template-columns: 1fr; padding: 26px 22px 28px; }
.price-card { position: static; }
}
@media (max-width: 430px) {
.choice-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.color-grid { grid-template-columns: 1fr; }
}
(() => {
const widths = [2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 7];
const depths = [1.6, 2.1, 2.6, 3.1, 3.6, 4.1];
const prices = {
white: {
« 1.6 »: [993, 1147, 1235, 1500, 1590, 1844, 1895, 1990, 2238],
« 2.1 »: [1121, 1310, 1408, 1706, 1807, 2093, 2156, 2287, 2577],
« 2.6 »: [1252, 1472, 1580, 1927, 2023, 2336, 2524, 2575, 2913],
« 3.1 »: [1383, 1638, 1751, 2132, 2240, 2583, 2811, 2869, 3252],
« 3.6 »: [1918, 2283, 2446, 2970, 3118, 3599, 3926, 4013, 4748],
« 4.1 »: [2304, 2701, 2907, 3438, 3850, 4125, 4504, 4810, 5415]
},
grey: {
« 1.6 »: [1092, 1261, 1358, 1649, 1748, 2028, 2084, 2188, 2461],
« 2.1 »: [1233, 1440, 1548, 1876, 1987, 2302, 2371, 2515, 2834],
« 2.6 »: [1377, 1619, 1737, 2119, 2225, 2569, 2776, 2832, 3204],
« 3.1 »: [1521, 1801, 1926, 2345, 2463, 2841, 3092, 3155, 3577],
« 3.6 »: [2109, 2511, 2690, 3266, 3429, 3958, 4318, 4414, 5222],
« 4.1 »: [2534, 2971, 3197, 3781, 4234, 4537, 4954, 5290, 5956]
}
};
const formatMeters = value => value.toLocaleString(« fr-FR », { maximumFractionDigits: 1 }) + » m »;
const formatPrice = value => value.toLocaleString(« fr-FR », { style: « currency », currency: « EUR », maximumFractionDigits: 0 });
function makeOptions(containerId, name, values, selectedIndex = 0) {
const container = document.getElementById(containerId);
values.forEach((value, index) => {
const wrapper = document.createElement(« div »);
wrapper.className = « choice »;
const input = document.createElement(« input »);
input.type = « radio »;
input.name = name;
input.id = `${name}-${String(value).replace(« . », « -« )}`;
input.value = value;
input.checked = index === selectedIndex;
const label = document.createElement(« label »);
label.htmlFor = input.id;
label.textContent = formatMeters(value);
wrapper.append(input, label);
container.appendChild(wrapper);
});
}
makeOptions(« width-options », « width », widths);
makeOptions(« depth-options », « depth », depths);
const form = document.querySelector(« .pergola-form »);
const priceOutput = document.getElementById(« price »);
const summaryWidth = document.getElementById(« summary-width »);
const summaryDepth = document.getElementById(« summary-depth »);
const summaryColor = document.getElementById(« summary-color »);
function updatePrice() {
const width = Number(form.elements.width.value);
const depth = Number(form.elements.depth.value);
const color = form.elements.color.value;
const widthIndex = widths.indexOf(width);
const price = prices[color][depth.toFixed(1)][widthIndex];
priceOutput.textContent = formatPrice(price);
summaryWidth.textContent = formatMeters(width);
summaryDepth.textContent = formatMeters(depth);
summaryColor.textContent = color === « white » ? « Blanc » : « Gris / marron »;
}
form.addEventListener(« change », updatePrice);
updatePrice();
})();