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 {
display: grid;
grid-template-columns: 1fr 360px;
gap: 40px;
align-items: start;
}
.calculator-form {
min-width: 0;
@@ -1661,10 +1655,6 @@ a:hover {
margin-bottom: 16px;
}
.calculator-sidebar {
position: sticky;
top: 100px;
}
.price-calculator {
background: var(--color-dark);
@@ -1787,14 +1777,89 @@ a:hover {
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) {
.calculator-layout {
.calculator-layout,
.calculator-layout:has(.calculator-sidebar.visible) {
grid-template-columns: 1fr;
}
.calculator-sidebar {
position: static;
order: -1;
}
.calculator-sidebar.visible {
display: block;
}
}
/* === Animations === */

View File

@@ -62,133 +62,140 @@
<!-- Form side -->
<div class="calculator-form">
<form id="quote-form">
<!-- Yhteystiedot -->
<!-- Yhteystiedot (aina näkyvissä) -->
<div class="form-section-title">Yhteystiedot</div>
<div class="form-group">
<label for="name">Nimi</label>
<input type="text" id="name" name="name">
</div>
<div class="form-group">
<label for="company">Yritys</label>
<input type="text" id="company" name="company">
</div>
<div class="form-group">
<label for="email">Sähköposti *</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="phone">Puhelinnumero</label>
<input type="tel" id="phone" name="phone">
</div>
<!-- Laitepaikat -->
<div class="form-section-title">Laitepaikat</div>
<div class="form-group form-group-full">
<label for="units-1u">1U laitepaikka &mdash; &euro;49/kk</label>
<select id="units-1u" name="units_1u" data-price="49">
<option value="0">Ei tarvetta</option>
<option value="1">1 kpl</option>
<option value="2">2 kpl</option>
<option value="3">3 kpl</option>
<option value="4">4 kpl</option>
<option value="5">5+ kpl</option>
</select>
</div>
<div class="form-group form-group-full">
<label for="units-2u">2U laitepaikka &mdash; &euro;79/kk</label>
<select id="units-2u" name="units_2u" data-price="79">
<option value="0">Ei tarvetta</option>
<option value="1">1 kpl</option>
<option value="2">2 kpl</option>
<option value="3">3 kpl</option>
<option value="4">4 kpl</option>
<option value="5">5+ kpl</option>
</select>
</div>
<div class="form-group form-group-full">
<label for="units-4u">4U laitepaikka &mdash; &euro;139/kk</label>
<select id="units-4u" name="units_4u" data-price="139">
<option value="0">Ei tarvetta</option>
<option value="1">1 kpl</option>
<option value="2">2 kpl</option>
<option value="3">3 kpl</option>
<option value="5">5+ kpl</option>
</select>
</div>
<div class="form-group form-group-full">
<label for="units-rack">Kokokaappi (42U)</label>
<select id="units-rack" name="units_rack" data-price="0">
<option value="0">Ei tarvetta</option>
<option value="1" data-custom>1 kpl (pyydä tarjous)</option>
<option value="2" data-custom>2 kpl (pyydä tarjous)</option>
<option value="3" data-custom>3+ kpl (pyydä tarjous)</option>
</select>
</div>
<!-- Yhteysnopeus -->
<div class="form-section-title">Yhteysnopeus</div>
<div class="form-group form-group-full">
<label for="connection">Haluttu yhteysnopeus</label>
<select id="connection" name="connection" data-type="connection">
<option value="0">1 Gbit/s jaettu (sis. hintaan)</option>
<option value="99">1 Gbit/s dedicated (&euro;99/kk)</option>
<option value="299">10 Gbit/s dedicated (&euro;299/kk)</option>
<option value="custom">100 Gbit/s (räätälöity)</option>
</select>
</div>
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" name="redundant_port" value="1" data-price="10">
<span>Varmennettu portti (&euro;10/kk)</span>
</label>
</div>
<div class="form-group form-group-full">
<label for="bgp">BGP-reititys</label>
<select id="bgp" name="bgp">
<option value="0">Ei tarvetta</option>
<option value="20">Default-route (&euro;20/kk)</option>
<option value="50">Koko internet (&euro;50/kk)</option>
</select>
</div>
<!-- VPN -->
<div class="form-section-title">Site-to-Site VPN</div>
<div class="form-group form-group-full">
<label for="vpn">VPN toimitilan ja konesalin väliin</label>
<select id="vpn" name="vpn">
<option value="0">Ei tarvetta</option>
<option value="95">1G Site-to-Site (alk. &euro;95/kk)</option>
<option value="129">10G Site-to-Site (alk. &euro;129/kk)</option>
<option value="custom">Dedicated L2/MPLS (räätälöity)</option>
</select>
</div>
<!-- Lisäpalvelut -->
<div class="form-section-title">Lisäpalvelut</div>
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" name="anycast_dns" value="1" data-price="19">
<span>Anycast DNS (&euro;19/kk)</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="block_storage" value="1" data-price="29">
<span>Blokkitason storage (alk. &euro;29/kk)</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="s3_storage" value="1" data-price="19">
<span>S3-levypinta (alk. &euro;19/kk)</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="remote_hands" value="1" data-price="0">
<span>Remote Hands (tuntiveloitus)</span>
</label>
</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>
<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">
<label for="phone">Puhelinnumero</label>
<input type="tel" id="phone" name="phone">
</div>
<!-- Laitepaikat -->
<div class="form-section-title">Laitepaikat</div>
<div class="form-group form-group-full">
<label for="units-1u">1U laitepaikka &mdash; &euro;49/kk</label>
<select id="units-1u" name="units_1u" data-price="49">
<option value="0">Ei tarvetta</option>
<option value="1">1 kpl</option>
<option value="2">2 kpl</option>
<option value="3">3 kpl</option>
<option value="4">4 kpl</option>
<option value="5">5+ kpl</option>
</select>
</div>
<div class="form-group form-group-full">
<label for="units-2u">2U laitepaikka &mdash; &euro;79/kk</label>
<select id="units-2u" name="units_2u" data-price="79">
<option value="0">Ei tarvetta</option>
<option value="1">1 kpl</option>
<option value="2">2 kpl</option>
<option value="3">3 kpl</option>
<option value="4">4 kpl</option>
<option value="5">5+ kpl</option>
</select>
</div>
<div class="form-group form-group-full">
<label for="units-4u">4U laitepaikka &mdash; &euro;139/kk</label>
<select id="units-4u" name="units_4u" data-price="139">
<option value="0">Ei tarvetta</option>
<option value="1">1 kpl</option>
<option value="2">2 kpl</option>
<option value="3">3 kpl</option>
<option value="5">5+ kpl</option>
</select>
</div>
<div class="form-group form-group-full">
<label for="units-rack">Kokokaappi (42U)</label>
<select id="units-rack" name="units_rack" data-price="0">
<option value="0">Ei tarvetta</option>
<option value="1" data-custom>1 kpl (pyydä tarjous)</option>
<option value="2" data-custom>2 kpl (pyydä tarjous)</option>
<option value="3" data-custom>3+ kpl (pyydä tarjous)</option>
</select>
</div>
<!-- Yhteysnopeus -->
<div class="form-section-title">Yhteysnopeus</div>
<div class="form-group form-group-full">
<label for="connection">Haluttu yhteysnopeus</label>
<select id="connection" name="connection" data-type="connection">
<option value="0">1 Gbit/s jaettu (sis. hintaan)</option>
<option value="99">1 Gbit/s dedicated (&euro;99/kk)</option>
<option value="299">10 Gbit/s dedicated (&euro;299/kk)</option>
<option value="custom">100 Gbit/s (räätälöity)</option>
</select>
</div>
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" name="redundant_port" value="1" data-price="10">
<span>Varmennettu portti (&euro;10/kk)</span>
</label>
</div>
<div class="form-group form-group-full">
<label for="bgp">BGP-reititys</label>
<select id="bgp" name="bgp">
<option value="0">Ei tarvetta</option>
<option value="20">Default-route (&euro;20/kk)</option>
<option value="50">Koko internet (&euro;50/kk)</option>
</select>
</div>
<!-- VPN -->
<div class="form-section-title">Site-to-Site VPN</div>
<div class="form-group form-group-full">
<label for="vpn">VPN toimitilan ja konesalin väliin</label>
<select id="vpn" name="vpn">
<option value="0">Ei tarvetta</option>
<option value="95">1G Site-to-Site (alk. &euro;95/kk)</option>
<option value="129">10G Site-to-Site (alk. &euro;129/kk)</option>
<option value="custom">Dedicated L2/MPLS (räätälöity)</option>
</select>
</div>
<!-- Lisäpalvelut -->
<div class="form-section-title">Lisäpalvelut</div>
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" name="anycast_dns" value="1" data-price="19">
<span>Anycast DNS (&euro;19/kk)</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="block_storage" value="1" data-price="29">
<span>Blokkitason storage (alk. &euro;29/kk)</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="s3_storage" value="1" data-price="19">
<span>S3-levypinta (alk. &euro;19/kk)</span>
</label>
<label class="checkbox-label">
<input type="checkbox" name="remote_hands" value="1" data-price="0">
<span>Remote Hands (tuntiveloitus)</span>
</label>
</div>
</div>
<!-- Captcha -->
@@ -303,6 +310,26 @@
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
(function() {
const form = document.getElementById('quote-form');
@@ -315,13 +342,14 @@
let lines = [];
let hasCustom = false;
// Laitepaikat
// Laitepaikat (voi olla piilossa)
const units = [
{ el: document.getElementById('units-1u'), name: '1U laitepaikka', price: 49 },
{ el: document.getElementById('units-2u'), name: '2U laitepaikka', price: 79 },
{ el: document.getElementById('units-4u'), name: '4U laitepaikka', price: 139 },
];
units.forEach(u => {
if (!u.el) return;
const qty = parseInt(u.el.value) || 0;
if (qty > 0) {
const subtotal = qty * u.price;
@@ -331,7 +359,8 @@
});
// 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) {
hasCustom = true;
lines.push({ label: 'Kokokaappi x' + rackQty, amount: null });
@@ -339,7 +368,7 @@
// Yhteysnopeus
const connEl = document.getElementById('connection');
const connVal = connEl.value;
const connVal = connEl ? connEl.value : '0';
let connPrice = 0;
if (connVal === 'custom') {
hasCustom = true;
@@ -354,28 +383,28 @@
// Varmennettu portti
const redundant = form.querySelector('[name="redundant_port"]');
if (redundant.checked) {
if (redundant && redundant.checked) {
total += 10;
lines.push({ label: 'Varmennettu portti', amount: 10 });
}
// BGP
const bgpEl = document.getElementById('bgp');
const bgpPrice = parseInt(bgpEl.value) || 0;
if (bgpPrice > 0) {
const bgpPrice = bgpEl ? (parseInt(bgpEl.value) || 0) : 0;
if (bgpEl && bgpPrice > 0) {
total += bgpPrice;
lines.push({ label: bgpEl.options[bgpEl.selectedIndex].text.split('(')[0].trim(), amount: bgpPrice });
}
// VPN
const vpnEl = document.getElementById('vpn');
const vpnVal = vpnEl.value;
const vpnVal = vpnEl ? vpnEl.value : '0';
if (vpnVal === 'custom') {
hasCustom = true;
lines.push({ label: 'Dedicated L2/MPLS', amount: null });
} else {
const vpnPrice = parseInt(vpnVal) || 0;
if (vpnPrice > 0) {
if (vpnEl && vpnPrice > 0) {
total += vpnPrice;
lines.push({ label: vpnEl.options[vpnEl.selectedIndex].text.split('(')[0].trim(), amount: vpnPrice });
}