Simplify quote form with expandable details section

Show only name, email and message by default. Detailed fields
(units, connections, VPN, extras) and price calculator open via
"Tarkemmat tiedot & hintalaskuri" button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 21:49:06 +02:00
parent b78345e4c8
commit 3d0215130f
2 changed files with 229 additions and 135 deletions

View File

@@ -1616,12 +1616,6 @@ a:hover {
} }
/* === Calculator Layout === */ /* === Calculator Layout === */
.calculator-layout {
display: grid;
grid-template-columns: 1fr 360px;
gap: 40px;
align-items: start;
}
.calculator-form { .calculator-form {
min-width: 0; min-width: 0;
@@ -1661,10 +1655,6 @@ a:hover {
margin-bottom: 16px; margin-bottom: 16px;
} }
.calculator-sidebar {
position: sticky;
top: 100px;
}
.price-calculator { .price-calculator {
background: var(--color-dark); background: var(--color-dark);
@@ -1787,14 +1777,89 @@ a:hover {
border-top: 1px solid var(--color-border); border-top: 1px solid var(--color-border);
} }
/* Expand form button */
.btn-expand-form {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
padding: 14px 20px;
margin: 8px 0 24px;
background: var(--color-bg-alt);
border: 1px dashed var(--color-border);
border-radius: var(--radius);
color: var(--color-text-heading);
font-size: 0.95rem;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
font-family: inherit;
}
.btn-expand-form:hover {
border-color: var(--color-primary);
color: var(--color-primary);
background: rgba(240, 112, 96, 0.04);
}
.btn-expand-form .btn-expand-icon {
display: flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
border-radius: 50%;
background: var(--color-primary);
color: var(--color-white);
font-size: 1.1rem;
font-weight: 700;
flex-shrink: 0;
transition: transform 0.3s ease;
}
.btn-expand-form.expanded .btn-expand-icon {
transform: rotate(180deg);
}
/* Form details (expandable) */
.form-details {
animation: slideDown 0.3s ease;
}
@keyframes slideDown {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
/* Calculator sidebar: hidden by default, shown when expanded */
.calculator-sidebar {
display: none;
}
.calculator-sidebar.visible {
display: block;
position: sticky;
top: 100px;
}
/* When sidebar not visible, form takes full width */
.calculator-layout {
display: grid;
grid-template-columns: 1fr;
gap: 40px;
align-items: start;
}
.calculator-layout:has(.calculator-sidebar.visible) {
grid-template-columns: 1fr 360px;
}
@media (max-width: 900px) { @media (max-width: 900px) {
.calculator-layout { .calculator-layout,
.calculator-layout:has(.calculator-sidebar.visible) {
grid-template-columns: 1fr; grid-template-columns: 1fr;
} }
.calculator-sidebar { .calculator-sidebar {
position: static; position: static;
order: -1; order: -1;
} }
.calculator-sidebar.visible {
display: block;
}
} }
/* === Animations === */ /* === Animations === */

View File

@@ -62,20 +62,33 @@
<!-- Form side --> <!-- Form side -->
<div class="calculator-form"> <div class="calculator-form">
<form id="quote-form"> <form id="quote-form">
<!-- Yhteystiedot --> <!-- Yhteystiedot (aina näkyvissä) -->
<div class="form-section-title">Yhteystiedot</div> <div class="form-section-title">Yhteystiedot</div>
<div class="form-group"> <div class="form-group">
<label for="name">Nimi</label> <label for="name">Nimi</label>
<input type="text" id="name" name="name"> <input type="text" id="name" name="name">
</div> </div>
<div class="form-group">
<label for="company">Yritys</label>
<input type="text" id="company" name="company">
</div>
<div class="form-group"> <div class="form-group">
<label for="email">Sähköposti *</label> <label for="email">Sähköposti *</label>
<input type="email" id="email" name="email" required> <input type="email" id="email" name="email" required>
</div> </div>
<div class="form-group form-group-full">
<label for="message">Viesti</label>
<textarea id="message" name="message" rows="4" placeholder="Kerro tarpeistasi: laitemäärät, tehovaatimukset, aikataulu, erityistoiveet..."></textarea>
</div>
<!-- Koko lomake -nappi -->
<button type="button" class="btn-expand-form" id="btn-expand-form">
<span class="btn-expand-icon">+</span>
Tarkemmat tiedot &amp; hintalaskuri
</button>
<!-- Yksityiskohtainen lomake (piilotettu oletuksena) -->
<div class="form-details" id="form-details" style="display:none;">
<div class="form-group">
<label for="company">Yritys</label>
<input type="text" id="company" name="company">
</div>
<div class="form-group"> <div class="form-group">
<label for="phone">Puhelinnumero</label> <label for="phone">Puhelinnumero</label>
<input type="tel" id="phone" name="phone"> <input type="tel" id="phone" name="phone">
@@ -183,12 +196,6 @@
<span>Remote Hands (tuntiveloitus)</span> <span>Remote Hands (tuntiveloitus)</span>
</label> </label>
</div> </div>
<!-- Lisätiedot -->
<div class="form-section-title">Lisätiedot</div>
<div class="form-group form-group-full">
<label for="message">Viesti</label>
<textarea id="message" name="message" rows="4" placeholder="Kerro lisää tarpeistasi: tehovaatimukset, aikataulu, erityistoiveet..."></textarea>
</div> </div>
<!-- Captcha --> <!-- Captcha -->
@@ -303,6 +310,26 @@
window._refreshCaptcha = generateCaptcha; window._refreshCaptcha = generateCaptcha;
})(); })();
// Expand form toggle
(function() {
var btn = document.getElementById('btn-expand-form');
var details = document.getElementById('form-details');
var sidebar = document.querySelector('.calculator-sidebar');
var expanded = false;
btn.addEventListener('click', function() {
expanded = !expanded;
details.style.display = expanded ? '' : 'none';
sidebar.classList.toggle('visible', expanded);
btn.classList.toggle('expanded', expanded);
btn.querySelector('.btn-expand-icon').textContent = expanded ? '' : '+';
btn.childNodes[btn.childNodes.length - 1].textContent = expanded ? ' Piilota tarkemmat tiedot' : ' Tarkemmat tiedot & hintalaskuri';
if (expanded) {
details.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
});
})();
// Price Calculator // Price Calculator
(function() { (function() {
const form = document.getElementById('quote-form'); const form = document.getElementById('quote-form');
@@ -315,13 +342,14 @@
let lines = []; let lines = [];
let hasCustom = false; let hasCustom = false;
// Laitepaikat // Laitepaikat (voi olla piilossa)
const units = [ const units = [
{ el: document.getElementById('units-1u'), name: '1U laitepaikka', price: 49 }, { el: document.getElementById('units-1u'), name: '1U laitepaikka', price: 49 },
{ el: document.getElementById('units-2u'), name: '2U laitepaikka', price: 79 }, { el: document.getElementById('units-2u'), name: '2U laitepaikka', price: 79 },
{ el: document.getElementById('units-4u'), name: '4U laitepaikka', price: 139 }, { el: document.getElementById('units-4u'), name: '4U laitepaikka', price: 139 },
]; ];
units.forEach(u => { units.forEach(u => {
if (!u.el) return;
const qty = parseInt(u.el.value) || 0; const qty = parseInt(u.el.value) || 0;
if (qty > 0) { if (qty > 0) {
const subtotal = qty * u.price; const subtotal = qty * u.price;
@@ -331,7 +359,8 @@
}); });
// Kokokaappi // Kokokaappi
const rackQty = parseInt(document.getElementById('units-rack').value) || 0; const rackEl = document.getElementById('units-rack');
const rackQty = rackEl ? (parseInt(rackEl.value) || 0) : 0;
if (rackQty > 0) { if (rackQty > 0) {
hasCustom = true; hasCustom = true;
lines.push({ label: 'Kokokaappi x' + rackQty, amount: null }); lines.push({ label: 'Kokokaappi x' + rackQty, amount: null });
@@ -339,7 +368,7 @@
// Yhteysnopeus // Yhteysnopeus
const connEl = document.getElementById('connection'); const connEl = document.getElementById('connection');
const connVal = connEl.value; const connVal = connEl ? connEl.value : '0';
let connPrice = 0; let connPrice = 0;
if (connVal === 'custom') { if (connVal === 'custom') {
hasCustom = true; hasCustom = true;
@@ -354,28 +383,28 @@
// Varmennettu portti // Varmennettu portti
const redundant = form.querySelector('[name="redundant_port"]'); const redundant = form.querySelector('[name="redundant_port"]');
if (redundant.checked) { if (redundant && redundant.checked) {
total += 10; total += 10;
lines.push({ label: 'Varmennettu portti', amount: 10 }); lines.push({ label: 'Varmennettu portti', amount: 10 });
} }
// BGP // BGP
const bgpEl = document.getElementById('bgp'); const bgpEl = document.getElementById('bgp');
const bgpPrice = parseInt(bgpEl.value) || 0; const bgpPrice = bgpEl ? (parseInt(bgpEl.value) || 0) : 0;
if (bgpPrice > 0) { if (bgpEl && bgpPrice > 0) {
total += bgpPrice; total += bgpPrice;
lines.push({ label: bgpEl.options[bgpEl.selectedIndex].text.split('(')[0].trim(), amount: bgpPrice }); lines.push({ label: bgpEl.options[bgpEl.selectedIndex].text.split('(')[0].trim(), amount: bgpPrice });
} }
// VPN // VPN
const vpnEl = document.getElementById('vpn'); const vpnEl = document.getElementById('vpn');
const vpnVal = vpnEl.value; const vpnVal = vpnEl ? vpnEl.value : '0';
if (vpnVal === 'custom') { if (vpnVal === 'custom') {
hasCustom = true; hasCustom = true;
lines.push({ label: 'Dedicated L2/MPLS', amount: null }); lines.push({ label: 'Dedicated L2/MPLS', amount: null });
} else { } else {
const vpnPrice = parseInt(vpnVal) || 0; const vpnPrice = parseInt(vpnVal) || 0;
if (vpnPrice > 0) { if (vpnEl && vpnPrice > 0) {
total += vpnPrice; total += vpnPrice;
lines.push({ label: vpnEl.options[vpnEl.selectedIndex].text.split('(')[0].trim(), amount: vpnPrice }); lines.push({ label: vpnEl.options[vpnEl.selectedIndex].text.split('(')[0].trim(), amount: vpnPrice });
} }