4
konesaliturku/.gitignore
vendored
4
konesaliturku/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
.DS_Store
|
||||
*.swp
|
||||
*.swo
|
||||
.env
|
||||
@@ -1,126 +0,0 @@
|
||||
<?php
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
// Rate limiting (simple file-based)
|
||||
function checkRateLimit($ip, $maxRequests = 5, $windowSeconds = 300) {
|
||||
$file = __DIR__ . '/data/rate_limits.json';
|
||||
$limits = [];
|
||||
|
||||
if (file_exists($file)) {
|
||||
$limits = json_decode(file_get_contents($file), true) ?: [];
|
||||
}
|
||||
|
||||
$now = time();
|
||||
// Clean old entries
|
||||
foreach ($limits as $key => $entries) {
|
||||
$limits[$key] = array_filter($entries, fn($t) => $now - $t < $windowSeconds);
|
||||
if (empty($limits[$key])) {
|
||||
unset($limits[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$count = count($limits[$ip] ?? []);
|
||||
if ($count >= $maxRequests) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$limits[$ip][] = $now;
|
||||
|
||||
$dir = dirname($file);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
file_put_contents($file, json_encode($limits));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
$action = $_GET['action'] ?? '';
|
||||
|
||||
switch ($action) {
|
||||
case 'contact':
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['error' => 'Method not allowed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Honeypot
|
||||
if (!empty($_POST['website'])) {
|
||||
echo json_encode(['success' => true]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Rate limit
|
||||
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
||||
if (!checkRateLimit($ip)) {
|
||||
http_response_code(429);
|
||||
echo json_encode(['error' => 'Liian monta viestiä. Yritä myöhemmin uudelleen.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Validate
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$company = trim($_POST['company'] ?? '');
|
||||
$email = trim($_POST['email'] ?? '');
|
||||
$phone = trim($_POST['phone'] ?? '');
|
||||
$message = trim($_POST['message'] ?? '');
|
||||
|
||||
if (!$name || !$email || !$message) {
|
||||
echo json_encode(['error' => 'Täytä kaikki pakolliset kentät.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
echo json_encode(['error' => 'Tarkista sähköpostiosoite.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Save to file
|
||||
$contactFile = __DIR__ . '/data/contacts.json';
|
||||
$contacts = [];
|
||||
if (file_exists($contactFile)) {
|
||||
$contacts = json_decode(file_get_contents($contactFile), true) ?: [];
|
||||
}
|
||||
|
||||
$contacts[] = [
|
||||
'id' => uniqid(),
|
||||
'name' => $name,
|
||||
'company' => $company,
|
||||
'email' => $email,
|
||||
'phone' => $phone,
|
||||
'message' => $message,
|
||||
'ip' => $ip,
|
||||
'created_at' => date('Y-m-d H:i:s')
|
||||
];
|
||||
|
||||
$dir = dirname($contactFile);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
file_put_contents($contactFile, json_encode($contacts, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
|
||||
// Send email
|
||||
$to = 'info@konesaliturku.fi';
|
||||
$subject = 'Yhteydenotto: ' . $name . ($company ? " ($company)" : '');
|
||||
$body = "Uusi yhteydenotto konesaliturku.fi:n kautta\n\n";
|
||||
$body .= "Nimi: $name\n";
|
||||
if ($company) $body .= "Yritys: $company\n";
|
||||
$body .= "Sähköposti: $email\n";
|
||||
if ($phone) $body .= "Puhelin: $phone\n";
|
||||
$body .= "\nViesti:\n$message\n";
|
||||
|
||||
$headers = "From: noreply@konesaliturku.fi\r\n";
|
||||
$headers .= "Reply-To: $email\r\n";
|
||||
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
|
||||
|
||||
@mail($to, $subject, $body, $headers);
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
break;
|
||||
|
||||
default:
|
||||
http_response_code(404);
|
||||
echo json_encode(['error' => 'Unknown action']);
|
||||
break;
|
||||
}
|
||||
@@ -1,450 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fi">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Konesali Turku — Colocation & konesalipalvelut Turussa</title>
|
||||
<meta name="description" content="Luotettavat konesalipalvelut Turussa. Colocation-laitepaikkoja 1U:sta kokokaappiin. Redundantti infrastruktuuri, henkilökohtainen palvelu.">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header -->
|
||||
<header class="header" id="header">
|
||||
<div class="container header-inner">
|
||||
<a href="/" class="logo">
|
||||
<svg class="logo-icon" viewBox="0 0 32 32" width="32" height="32" fill="none">
|
||||
<rect x="2" y="6" width="28" height="20" rx="3" stroke="currentColor" stroke-width="2"/>
|
||||
<rect x="6" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="6" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="14" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="14" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="22" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="22" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
</svg>
|
||||
<span>Konesali<strong>Turku</strong></span>
|
||||
</a>
|
||||
<nav class="nav" id="nav">
|
||||
<a href="#palvelut">Palvelut</a>
|
||||
<a href="konesali.html">Konesali</a>
|
||||
<a href="#hinnat">Hinnat</a>
|
||||
<a href="#yhteystiedot">Yhteystiedot</a>
|
||||
</nav>
|
||||
<button class="nav-toggle" id="nav-toggle" aria-label="Avaa valikko">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Hero -->
|
||||
<section class="hero">
|
||||
<div class="container">
|
||||
<div class="hero-content">
|
||||
<h1>Luotettavat konesalipalvelut <span class="highlight">Turussa</span></h1>
|
||||
<p class="hero-subtitle">Colocation-laitepaikkoja ammattimaisessa laitetilassa. Redundantti sähkönsyöttö, nopeat tietoliikenneyhteydet ja henkilökohtainen palvelu.</p>
|
||||
<div class="hero-actions">
|
||||
<a href="#yhteystiedot" class="btn btn-primary">Pyydä tarjous</a>
|
||||
<a href="#hinnat" class="btn btn-secondary">Katso hinnat</a>
|
||||
</div>
|
||||
<div class="hero-stats">
|
||||
<div class="stat">
|
||||
<span class="stat-value">99,9%</span>
|
||||
<span class="stat-label">Käytettävyys SLA</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-value">24/7</span>
|
||||
<span class="stat-label">Valvonta</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-value">10 Gbit/s</span>
|
||||
<span class="stat-label">Yhteysnopeus</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Palvelut -->
|
||||
<section class="section" id="palvelut">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Palvelut</h2>
|
||||
<p class="section-subtitle">Tarjoamme colocation-laitepaikkoja kaikenkokoisille tarpeille</p>
|
||||
<div class="services-grid">
|
||||
<div class="service-card">
|
||||
<div class="service-icon">
|
||||
<svg viewBox="0 0 48 48" width="48" height="48" fill="none">
|
||||
<rect x="14" y="8" width="20" height="32" rx="3" stroke="currentColor" stroke-width="2"/>
|
||||
<circle cx="24" cy="16" r="2" fill="currentColor"/>
|
||||
<line x1="18" y1="24" x2="30" y2="24" stroke="currentColor" stroke-width="2"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3>1U Laitepaikka</h3>
|
||||
<p>Yksittäinen palvelinpaikka 42U kaapissa. Sopii pienille palvelimille ja verkkolaitteille.</p>
|
||||
<ul class="service-features">
|
||||
<li>1 rack unit (1U)</li>
|
||||
<li>Jaettu 1 Gbit/s yhteys</li>
|
||||
<li>1x 230V sähkösyöttö</li>
|
||||
<li>Rajoittamaton liikenne</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="service-card featured">
|
||||
<div class="service-badge">Suosituin</div>
|
||||
<div class="service-icon">
|
||||
<svg viewBox="0 0 48 48" width="48" height="48" fill="none">
|
||||
<rect x="8" y="4" width="32" height="40" rx="3" stroke="currentColor" stroke-width="2"/>
|
||||
<circle cx="24" cy="12" r="2" fill="currentColor"/>
|
||||
<circle cx="24" cy="20" r="2" fill="currentColor"/>
|
||||
<line x1="14" y1="28" x2="34" y2="28" stroke="currentColor" stroke-width="2"/>
|
||||
<line x1="14" y1="34" x2="34" y2="34" stroke="currentColor" stroke-width="2"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Puolikaappi (21U)</h3>
|
||||
<p>Puolet 42U kaapista omassa lukitussa tilassa. Ihanteellinen kasvavalle yritykselle.</p>
|
||||
<ul class="service-features">
|
||||
<li>21 rack unitia (21U)</li>
|
||||
<li>Oma 1 Gbit/s yhteys</li>
|
||||
<li>2x 230V / 16A sähkösyöttö</li>
|
||||
<li>Rajoittamaton liikenne</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="service-card">
|
||||
<div class="service-icon">
|
||||
<svg viewBox="0 0 48 48" width="48" height="48" fill="none">
|
||||
<rect x="6" y="2" width="36" height="44" rx="3" stroke="currentColor" stroke-width="2"/>
|
||||
<circle cx="24" cy="10" r="2" fill="currentColor"/>
|
||||
<circle cx="24" cy="18" r="2" fill="currentColor"/>
|
||||
<circle cx="24" cy="26" r="2" fill="currentColor"/>
|
||||
<line x1="12" y1="34" x2="36" y2="34" stroke="currentColor" stroke-width="2"/>
|
||||
<line x1="12" y1="40" x2="36" y2="40" stroke="currentColor" stroke-width="2"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Kokokaappi (42U)</h3>
|
||||
<p>Kokonainen 42U kaappi omassa lukitussa tilassa. Täysi hallinta ja maksimikapasiteetti.</p>
|
||||
<ul class="service-features">
|
||||
<li>42 rack unitia (42U)</li>
|
||||
<li>Oma 10 Gbit/s yhteys</li>
|
||||
<li>2x 230V / 32A A/B-syöttö</li>
|
||||
<li>Rajoittamaton liikenne</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Miksi me -->
|
||||
<section class="section section-dark" id="miksi">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Miksi Konesali Turku?</h2>
|
||||
<p class="section-subtitle">Pienen konesalin edut isoihin ketjuihin verrattuna</p>
|
||||
<div class="features-grid">
|
||||
<div class="feature">
|
||||
<div class="feature-icon">
|
||||
<svg viewBox="0 0 24 24" width="40" height="40" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/>
|
||||
<path d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Paikallinen palvelu</h3>
|
||||
<p>Laitteesi ovat lähellä. Voit käydä konesalilla milloin vain ja tapaat aina tutun henkilökunnan.</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<div class="feature-icon">
|
||||
<svg viewBox="0 0 24 24" width="40" height="40" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Redundantti infrastruktuuri</h3>
|
||||
<p>Kahdennettu sähkönsyöttö, UPS-järjestelmä ja varavoimageneraattori takaavat katkeamattoman toiminnan.</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<div class="feature-icon">
|
||||
<svg viewBox="0 0 24 24" width="40" height="40" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Nopeat yhteydet</h3>
|
||||
<p>Moniliittymäinen tietoliikenne usealta operaattorilta. 1–10 Gbit/s porttinopeudet.</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<div class="feature-icon">
|
||||
<svg viewBox="0 0 24 24" width="40" height="40" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3>24/7 tuki</h3>
|
||||
<p>Remote hands -palvelu ja tekninen tuki ympäri vuorokauden. Ongelmatilanteissa reagoimme nopeasti.</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<div class="feature-icon">
|
||||
<svg viewBox="0 0 24 24" width="40" height="40" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Turvallisuus</h3>
|
||||
<p>Kulunvalvonta, kameravalvonta ja lukitut kaapit. Laitteesi ovat turvassa ympäri vuorokauden.</p>
|
||||
</div>
|
||||
<div class="feature">
|
||||
<div class="feature-icon">
|
||||
<svg viewBox="0 0 24 24" width="40" height="40" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3>Selkeä hinnoittelu</h3>
|
||||
<p>Ei piilokustannuksia. Kuukausihintaan sisältyy laitepaikka, yhteys ja peruspalvelut.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Hinnat -->
|
||||
<section class="section" id="hinnat">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Hinnat</h2>
|
||||
<p class="section-subtitle">Kaikki hinnat alv 0%. Sähkö laskutetaan erikseen kulutuksen mukaan.</p>
|
||||
<div class="pricing-grid">
|
||||
<div class="pricing-card">
|
||||
<div class="pricing-header">
|
||||
<h3>1U Laitepaikka</h3>
|
||||
<div class="price">
|
||||
<span class="price-amount">€49</span>
|
||||
<span class="price-period">/kk</span>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="pricing-features">
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
1 rack unit (1U)
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
Jaettu 1 Gbit/s
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
1x 230V sähkösyöttö
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
Rajoittamaton liikenne
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
1x IPv4-osoite
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
99,9% SLA
|
||||
</li>
|
||||
</ul>
|
||||
<a href="#yhteystiedot" class="btn btn-outline">Pyydä tarjous</a>
|
||||
</div>
|
||||
<div class="pricing-card pricing-featured">
|
||||
<div class="pricing-badge">Suosituin</div>
|
||||
<div class="pricing-header">
|
||||
<h3>Puolikaappi</h3>
|
||||
<div class="price">
|
||||
<span class="price-amount">€249</span>
|
||||
<span class="price-period">/kk</span>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="pricing-features">
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
21 rack unitia (21U)
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
Oma 1 Gbit/s
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
2x 230V / 16A sähkösyöttö
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
Rajoittamaton liikenne
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
4x IPv4-osoitetta
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
IPv6 /64 -verkko
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
99,9% SLA
|
||||
</li>
|
||||
</ul>
|
||||
<a href="#yhteystiedot" class="btn btn-primary">Pyydä tarjous</a>
|
||||
</div>
|
||||
<div class="pricing-card">
|
||||
<div class="pricing-header">
|
||||
<h3>Kokokaappi</h3>
|
||||
<div class="price">
|
||||
<span class="price-amount">€490</span>
|
||||
<span class="price-period">/kk</span>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="pricing-features">
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
42 rack unitia (42U)
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
Oma 10 Gbit/s
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
2x 230V / 32A A/B-syöttö
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
Rajoittamaton liikenne
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
8x IPv4-osoitetta
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
IPv6 /48 -verkko
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
Remote hands sisältyy
|
||||
</li>
|
||||
<li>
|
||||
<svg viewBox="0 0 20 20" width="16" height="16" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
|
||||
99,9% SLA
|
||||
</li>
|
||||
</ul>
|
||||
<a href="#yhteystiedot" class="btn btn-outline">Pyydä tarjous</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="pricing-note">Sähkönkulutus laskutetaan erikseen toteutuneen kulutuksen mukaan hintaan 0,25 €/kWh (alv 0%). Kaikki hinnat ovat kuukausihintoja, alv 0%. Sopimuksen minimikesto 1 kuukausi.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Yhteystiedot -->
|
||||
<section class="section section-dark" id="yhteystiedot">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Ota yhteyttä</h2>
|
||||
<p class="section-subtitle">Kerro tarpeistasi, niin teemme sinulle tarjouksen</p>
|
||||
<div class="contact-grid">
|
||||
<form class="contact-form" id="contact-form">
|
||||
<div class="form-group">
|
||||
<label for="name">Nimi *</label>
|
||||
<input type="text" id="name" name="name" required>
|
||||
</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>
|
||||
<div class="form-group form-group-full">
|
||||
<label for="message">Viesti *</label>
|
||||
<textarea id="message" name="message" rows="5" required placeholder="Kerro meille tarpeistasi: montako laitepaikkaa tarvitset, millaisia laitteita, tehovaatimukset..."></textarea>
|
||||
</div>
|
||||
<!-- Honeypot -->
|
||||
<div style="display:none" aria-hidden="true">
|
||||
<input type="text" name="website" tabindex="-1" autocomplete="off">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-submit">Lähetä viesti</button>
|
||||
<div class="form-status" id="form-status"></div>
|
||||
</form>
|
||||
<div class="contact-info">
|
||||
<div class="contact-item">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/>
|
||||
<path d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||
</svg>
|
||||
<div>
|
||||
<strong>Osoite</strong>
|
||||
<p>Esimerkkikatu 1<br>20100 Turku</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
|
||||
</svg>
|
||||
<div>
|
||||
<strong>Sähköposti</strong>
|
||||
<p>info@konesaliturku.fi</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"/>
|
||||
</svg>
|
||||
<div>
|
||||
<strong>Puhelin</strong>
|
||||
<p>+358 2 123 4567</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||||
</svg>
|
||||
<div>
|
||||
<strong>Aukioloajat</strong>
|
||||
<p>Ma-Pe 8:00-17:00<br>Konesali 24/7</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container footer-inner">
|
||||
<div class="footer-brand">
|
||||
<a href="/" class="logo">
|
||||
<svg class="logo-icon" viewBox="0 0 32 32" width="24" height="24" fill="none">
|
||||
<rect x="2" y="6" width="28" height="20" rx="3" stroke="currentColor" stroke-width="2"/>
|
||||
<rect x="6" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="6" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="14" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="14" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="22" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="22" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
</svg>
|
||||
<span>Konesali<strong>Turku</strong></span>
|
||||
</a>
|
||||
<p>Luotettavat konesalipalvelut Turussa.</p>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<h4>Sivusto</h4>
|
||||
<a href="#palvelut">Palvelut</a>
|
||||
<a href="konesali.html">Konesali</a>
|
||||
<a href="#hinnat">Hinnat</a>
|
||||
<a href="#yhteystiedot">Yhteystiedot</a>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<h4>Palvelut</h4>
|
||||
<a href="#hinnat">1U Laitepaikka</a>
|
||||
<a href="#hinnat">Puolikaappi</a>
|
||||
<a href="#hinnat">Kokokaappi</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bottom">
|
||||
<div class="container">
|
||||
<p>© 2026 Konesali Turku. Kaikki oikeudet pidätetään.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,382 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fi">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Konesali — Tekniset tiedot | Konesali Turku</title>
|
||||
<meta name="description" content="Konesali Turun tekniset tiedot: sähköjärjestelmät, jäähdytys, tietoliikenneyhteydet, turvallisuus ja tilat.">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Header -->
|
||||
<header class="header" id="header">
|
||||
<div class="container header-inner">
|
||||
<a href="/" class="logo">
|
||||
<svg class="logo-icon" viewBox="0 0 32 32" width="32" height="32" fill="none">
|
||||
<rect x="2" y="6" width="28" height="20" rx="3" stroke="currentColor" stroke-width="2"/>
|
||||
<rect x="6" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="6" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="14" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="14" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="22" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="22" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
</svg>
|
||||
<span>Konesali<strong>Turku</strong></span>
|
||||
</a>
|
||||
<nav class="nav" id="nav">
|
||||
<a href="index.html#palvelut">Palvelut</a>
|
||||
<a href="konesali.html" class="active">Konesali</a>
|
||||
<a href="index.html#hinnat">Hinnat</a>
|
||||
<a href="index.html#yhteystiedot">Yhteystiedot</a>
|
||||
</nav>
|
||||
<button class="nav-toggle" id="nav-toggle" aria-label="Avaa valikko">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Page Hero -->
|
||||
<section class="page-hero">
|
||||
<div class="container">
|
||||
<h1>Konesalin tekniset tiedot</h1>
|
||||
<p>Ammattimaisesti suunniteltu ja ylläpidetty laitetila Turussa</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Overview -->
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="specs-overview">
|
||||
<div class="spec-highlight">
|
||||
<div class="spec-highlight-value">99,9%</div>
|
||||
<div class="spec-highlight-label">Käytettävyys (SLA)</div>
|
||||
</div>
|
||||
<div class="spec-highlight">
|
||||
<div class="spec-highlight-value">N+1</div>
|
||||
<div class="spec-highlight-label">Redundanssi</div>
|
||||
</div>
|
||||
<div class="spec-highlight">
|
||||
<div class="spec-highlight-value">24/7</div>
|
||||
<div class="spec-highlight-label">Valvonta</div>
|
||||
</div>
|
||||
<div class="spec-highlight">
|
||||
<div class="spec-highlight-value">10 Gbit/s</div>
|
||||
<div class="spec-highlight-label">Yhteysnopeus</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Sähkö -->
|
||||
<section class="section section-dark" id="sahko">
|
||||
<div class="container">
|
||||
<div class="spec-section">
|
||||
<div class="spec-section-header">
|
||||
<div class="spec-section-icon">
|
||||
<svg viewBox="0 0 24 24" width="48" height="48" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Sähköjärjestelmät</h2>
|
||||
<p>Kahdennettu sähkönsyöttö varmistaa katkeamattoman toiminnan</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spec-table">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="spec-label">Sähkönsyöttö</td>
|
||||
<td>Kahdennettu A/B-syöttö kahdelta eri muuntajalta</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">UPS-järjestelmä</td>
|
||||
<td>Online double-conversion UPS, N+1 redundantti</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Akuston kapasiteetti</td>
|
||||
<td>Vähintään 15 minuuttia täydellä kuormalla</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Varavoimageneraattori</td>
|
||||
<td>Dieselgeneraattori, automaattinen käynnistys sähkökatkossa</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Teho per kaappi</td>
|
||||
<td>2–8 kW (räätälöitävissä tarpeen mukaan)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Liitännät</td>
|
||||
<td>230V / 16A tai 32A, C13/C19 -pistokkeet</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">PDU</td>
|
||||
<td>Monitoroidut PDU:t (virrankulutuksen seuranta)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Jäähdytys -->
|
||||
<section class="section" id="jaahdytys">
|
||||
<div class="container">
|
||||
<div class="spec-section">
|
||||
<div class="spec-section-header">
|
||||
<div class="spec-section-icon">
|
||||
<svg viewBox="0 0 24 24" width="48" height="48" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M12 3v18m0-18l-3 3m3-3l3 3m-3 15l-3-3m3 3l3-3M3 12h18M3 12l3-3M3 12l3 3m15-3l-3-3m3 3l-3 3"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Jäähdytys</h2>
|
||||
<p>Tehokas ja energiaoptimoitu jäähdytysjärjestelmä</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spec-table">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="spec-label">Jäähdytystyyppi</td>
|
||||
<td>Precision air cooling, Cold Aisle Containment</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Redundanssi</td>
|
||||
<td>N+1 jäähdytyskapasiteetti</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Lämpötila</td>
|
||||
<td>Tavoite 20–24 °C (ASHRAE A1 -suositus)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Ilmankosteus</td>
|
||||
<td>40–60% suhteellinen kosteus</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Valvonta</td>
|
||||
<td>Jatkuva lämpötila- ja kosteusseuranta, hälytykset</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Free cooling</td>
|
||||
<td>Ulkoilman hyödyntäminen Suomen ilmaston ansiosta</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Tietoliikenne -->
|
||||
<section class="section section-dark" id="tietoliikenne">
|
||||
<div class="container">
|
||||
<div class="spec-section">
|
||||
<div class="spec-section-header">
|
||||
<div class="spec-section-icon">
|
||||
<svg viewBox="0 0 24 24" width="48" height="48" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Tietoliikenne</h2>
|
||||
<p>Moniliittymäinen verkko usealta operaattorilta</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spec-table">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="spec-label">Porttinopeudet</td>
|
||||
<td>1 Gbit/s – 10 Gbit/s (päivitettävissä 100 Gbit/s)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Operaattorit</td>
|
||||
<td>Moniliittymäinen (useampi operaattori redundanssia varten)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Liikenne</td>
|
||||
<td>Rajoittamaton sisäänpäin/ulospäin</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">IPv4</td>
|
||||
<td>1–8 osoitetta paketista riippuen (lisäosoitteet saatavilla)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">IPv6</td>
|
||||
<td>/64 – /48 -verkot saatavilla</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Reititys</td>
|
||||
<td>BGP-reititys, oma AS-numero saatavilla</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Cross-connect</td>
|
||||
<td>Suorat yhteydet muihin operaattoreihin ja asiakkaisiin</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">SLA</td>
|
||||
<td>99,9% verkon käytettävyys</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Turvallisuus -->
|
||||
<section class="section" id="turvallisuus">
|
||||
<div class="container">
|
||||
<div class="spec-section">
|
||||
<div class="spec-section-header">
|
||||
<div class="spec-section-icon">
|
||||
<svg viewBox="0 0 24 24" width="48" height="48" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Turvallisuus</h2>
|
||||
<p>Monikerroksiset turvallisuusjärjestelmät suojaavat laitteita</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spec-table">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="spec-label">Kulunvalvonta</td>
|
||||
<td>Sähköinen kulunvalvonta, avainkortti + PIN-koodi</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Kameravalvonta</td>
|
||||
<td>24/7 kameravalvonta sisä- ja ulkotiloissa, tallentava</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Palontorjunta</td>
|
||||
<td>Automaattinen palonilmaisinjärjestelmä, inerttikaasu-sammutusjärjestelmä</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Kaappien lukitus</td>
|
||||
<td>Lukittavat 42U-kaapit, asiakaskohtaiset avaimet</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Hälytysjärjestelmä</td>
|
||||
<td>Reaaliaikaiset hälytykset: lämpötila, kosteus, sähkö, murto</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Pääsyloki</td>
|
||||
<td>Kaikki käynnit kirjataan ja aikaleimotaan</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Tilat -->
|
||||
<section class="section section-dark" id="tilat">
|
||||
<div class="container">
|
||||
<div class="spec-section">
|
||||
<div class="spec-section-header">
|
||||
<div class="spec-section-icon">
|
||||
<svg viewBox="0 0 24 24" width="48" height="48" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<path d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Tilat ja kaapit</h2>
|
||||
<p>Ammattitason laitetila suunniteltu vaativaan käyttöön</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spec-table">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="spec-label">Sijainti</td>
|
||||
<td>Turku, Suomi</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Kaapit</td>
|
||||
<td>Standardi 42U / 600mm x 1000mm serverikaapit</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Ilmavirtaus</td>
|
||||
<td>Hot Aisle / Cold Aisle -erottelu</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Korotettu lattia</td>
|
||||
<td>Korotettu lattia kaapelointia ja ilmavirtausta varten</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Kantavuus</td>
|
||||
<td>Riittävä raskaimmillekin palvelinratkaisuille</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-label">Pääsy</td>
|
||||
<td>24/7 pääsy konesalille etukäteisilmoituksella</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA -->
|
||||
<section class="section">
|
||||
<div class="container" style="text-align: center;">
|
||||
<h2 class="section-title">Kiinnostuitko?</h2>
|
||||
<p class="section-subtitle">Kerro tarpeistasi ja teemme sinulle räätälöidyn tarjouksen</p>
|
||||
<div style="display: flex; gap: 16px; justify-content: center; flex-wrap: wrap;">
|
||||
<a href="index.html#yhteystiedot" class="btn btn-primary">Pyydä tarjous</a>
|
||||
<a href="index.html#hinnat" class="btn btn-secondary">Katso hinnat</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container footer-inner">
|
||||
<div class="footer-brand">
|
||||
<a href="/" class="logo">
|
||||
<svg class="logo-icon" viewBox="0 0 32 32" width="24" height="24" fill="none">
|
||||
<rect x="2" y="6" width="28" height="20" rx="3" stroke="currentColor" stroke-width="2"/>
|
||||
<rect x="6" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="6" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="14" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="14" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="22" y="10" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
<rect x="22" y="18" width="4" height="4" rx="1" fill="currentColor"/>
|
||||
</svg>
|
||||
<span>Konesali<strong>Turku</strong></span>
|
||||
</a>
|
||||
<p>Luotettavat konesalipalvelut Turussa.</p>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<h4>Sivusto</h4>
|
||||
<a href="index.html#palvelut">Palvelut</a>
|
||||
<a href="konesali.html">Konesali</a>
|
||||
<a href="index.html#hinnat">Hinnat</a>
|
||||
<a href="index.html#yhteystiedot">Yhteystiedot</a>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<h4>Palvelut</h4>
|
||||
<a href="index.html#hinnat">1U Laitepaikka</a>
|
||||
<a href="index.html#hinnat">Puolikaappi</a>
|
||||
<a href="index.html#hinnat">Kokokaappi</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bottom">
|
||||
<div class="container">
|
||||
<p>© 2026 Konesali Turku. Kaikki oikeudet pidätetään.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,126 +0,0 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// === Mobile nav toggle ===
|
||||
const navToggle = document.getElementById('nav-toggle');
|
||||
const nav = document.getElementById('nav');
|
||||
|
||||
if (navToggle && nav) {
|
||||
navToggle.addEventListener('click', () => {
|
||||
nav.classList.toggle('open');
|
||||
navToggle.classList.toggle('open');
|
||||
});
|
||||
|
||||
// Close nav on link click
|
||||
nav.querySelectorAll('a').forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
nav.classList.remove('open');
|
||||
navToggle.classList.remove('open');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// === Sticky header ===
|
||||
const header = document.getElementById('header');
|
||||
if (header) {
|
||||
window.addEventListener('scroll', () => {
|
||||
header.classList.toggle('scrolled', window.scrollY > 50);
|
||||
}, { passive: true });
|
||||
}
|
||||
|
||||
// === Scroll animations ===
|
||||
const observerOptions = {
|
||||
threshold: 0.1,
|
||||
rootMargin: '0px 0px -50px 0px'
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('visible');
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, observerOptions);
|
||||
|
||||
// Add fade-in to sections
|
||||
document.querySelectorAll('.service-card, .feature, .pricing-card, .contact-form, .contact-info').forEach(el => {
|
||||
el.classList.add('fade-in');
|
||||
observer.observe(el);
|
||||
});
|
||||
|
||||
// === Contact form ===
|
||||
const form = document.getElementById('contact-form');
|
||||
const formStatus = document.getElementById('form-status');
|
||||
|
||||
if (form) {
|
||||
form.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const submitBtn = form.querySelector('.btn-submit');
|
||||
const originalText = submitBtn.textContent;
|
||||
submitBtn.textContent = 'Lähetetään...';
|
||||
submitBtn.disabled = true;
|
||||
|
||||
// Honeypot check
|
||||
const honeypot = form.querySelector('input[name="website"]');
|
||||
if (honeypot && honeypot.value) {
|
||||
formStatus.textContent = 'Kiitos viestistäsi!';
|
||||
formStatus.className = 'form-status success';
|
||||
form.reset();
|
||||
submitBtn.textContent = originalText;
|
||||
submitBtn.disabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData(form);
|
||||
|
||||
try {
|
||||
const response = await fetch('api.php?action=contact', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
formStatus.textContent = 'Kiitos viestistäsi! Otamme yhteyttä pian.';
|
||||
formStatus.className = 'form-status success';
|
||||
form.reset();
|
||||
} else {
|
||||
formStatus.textContent = data.error || 'Viestin lähetys epäonnistui. Yritä uudelleen.';
|
||||
formStatus.className = 'form-status error';
|
||||
}
|
||||
} catch {
|
||||
formStatus.textContent = 'Viestin lähetys epäonnistui. Yritä uudelleen.';
|
||||
formStatus.className = 'form-status error';
|
||||
}
|
||||
|
||||
submitBtn.textContent = originalText;
|
||||
submitBtn.disabled = false;
|
||||
});
|
||||
}
|
||||
|
||||
// === Active nav link on scroll ===
|
||||
const sections = document.querySelectorAll('section[id]');
|
||||
const navLinks = document.querySelectorAll('.nav a[href^="#"]');
|
||||
|
||||
if (sections.length && navLinks.length) {
|
||||
window.addEventListener('scroll', () => {
|
||||
let current = '';
|
||||
sections.forEach(section => {
|
||||
const top = section.offsetTop - 100;
|
||||
if (window.scrollY >= top) {
|
||||
current = section.getAttribute('id');
|
||||
}
|
||||
});
|
||||
|
||||
navLinks.forEach(link => {
|
||||
link.classList.remove('active');
|
||||
if (link.getAttribute('href') === '#' + current) {
|
||||
link.classList.add('active');
|
||||
}
|
||||
});
|
||||
}, { passive: true });
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
def main():
|
||||
try:
|
||||
subprocess.run(
|
||||
["php", "-S", "localhost:3001"],
|
||||
check=True
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
print("\nServer stopped.")
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,970 +0,0 @@
|
||||
/* === Reset & Base === */
|
||||
*, *::before, *::after {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
--color-bg: #0a1628;
|
||||
--color-bg-light: #0f1f3d;
|
||||
--color-bg-card: #132244;
|
||||
--color-primary: #1a73e8;
|
||||
--color-primary-light: #4a9af5;
|
||||
--color-primary-dark: #1557b0;
|
||||
--color-accent: #00d4aa;
|
||||
--color-text: #e2e8f0;
|
||||
--color-text-muted: #94a3b8;
|
||||
--color-text-heading: #f1f5f9;
|
||||
--color-border: #1e3a5f;
|
||||
--color-surface: #162a4a;
|
||||
--color-white: #ffffff;
|
||||
--font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif;
|
||||
--max-width: 1200px;
|
||||
--header-height: 72px;
|
||||
--radius: 12px;
|
||||
--radius-sm: 8px;
|
||||
--shadow: 0 4px 24px rgba(0, 0, 0, 0.3);
|
||||
--shadow-lg: 0 8px 48px rgba(0, 0, 0, 0.4);
|
||||
--transition: 0.3s ease;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
scroll-padding-top: var(--header-height);
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-family);
|
||||
background: var(--color-bg);
|
||||
color: var(--color-text);
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-primary-light);
|
||||
text-decoration: none;
|
||||
transition: color var(--transition);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: var(--max-width);
|
||||
margin: 0 auto;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
/* === Header === */
|
||||
.header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: var(--header-height);
|
||||
background: rgba(10, 22, 40, 0.9);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
z-index: 1000;
|
||||
transition: background var(--transition);
|
||||
}
|
||||
|
||||
.header.scrolled {
|
||||
background: rgba(10, 22, 40, 0.98);
|
||||
box-shadow: 0 2px 20px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.header-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
color: var(--color-white);
|
||||
font-size: 1.25rem;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.logo strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.logo-icon {
|
||||
color: var(--color-primary-light);
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.nav a {
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.95rem;
|
||||
font-weight: 500;
|
||||
transition: color var(--transition);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav a:hover,
|
||||
.nav a.active {
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.nav a::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -4px;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
background: var(--color-primary);
|
||||
transition: width var(--transition);
|
||||
}
|
||||
|
||||
.nav a:hover::after {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nav-toggle {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.nav-toggle span {
|
||||
display: block;
|
||||
width: 24px;
|
||||
height: 2px;
|
||||
background: var(--color-white);
|
||||
transition: all var(--transition);
|
||||
}
|
||||
|
||||
/* === Hero === */
|
||||
.hero {
|
||||
padding: 160px 0 100px;
|
||||
background: linear-gradient(135deg, var(--color-bg) 0%, var(--color-bg-light) 50%, var(--color-bg) 100%);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background:
|
||||
radial-gradient(ellipse 800px 600px at 20% 50%, rgba(26, 115, 232, 0.08) 0%, transparent 70%),
|
||||
radial-gradient(ellipse 600px 400px at 80% 30%, rgba(0, 212, 170, 0.05) 0%, transparent 70%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
position: relative;
|
||||
max-width: 720px;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: clamp(2.2rem, 5vw, 3.5rem);
|
||||
font-weight: 800;
|
||||
line-height: 1.15;
|
||||
color: var(--color-white);
|
||||
margin-bottom: 20px;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: var(--color-primary-light);
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.2rem;
|
||||
color: var(--color-text-muted);
|
||||
line-height: 1.7;
|
||||
margin-bottom: 36px;
|
||||
max-width: 560px;
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: 56px;
|
||||
}
|
||||
|
||||
.hero-stats {
|
||||
display: flex;
|
||||
gap: 48px;
|
||||
}
|
||||
|
||||
.stat {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 0.85rem;
|
||||
color: var(--color-text-muted);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* === Buttons === */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 14px 28px;
|
||||
border-radius: var(--radius-sm);
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: all var(--transition);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--color-primary);
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: var(--color-primary-dark);
|
||||
color: var(--color-white);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 20px rgba(26, 115, 232, 0.4);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--color-surface);
|
||||
color: var(--color-text);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: var(--color-bg-card);
|
||||
color: var(--color-white);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.btn-outline {
|
||||
background: transparent;
|
||||
color: var(--color-primary-light);
|
||||
border: 2px solid var(--color-primary);
|
||||
}
|
||||
|
||||
.btn-outline:hover {
|
||||
background: var(--color-primary);
|
||||
color: var(--color-white);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* === Sections === */
|
||||
.section {
|
||||
padding: 100px 0;
|
||||
}
|
||||
|
||||
.section-dark {
|
||||
background: var(--color-bg-light);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 2.2rem;
|
||||
font-weight: 800;
|
||||
color: var(--color-text-heading);
|
||||
text-align: center;
|
||||
margin-bottom: 12px;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.section-subtitle {
|
||||
font-size: 1.1rem;
|
||||
color: var(--color-text-muted);
|
||||
text-align: center;
|
||||
margin-bottom: 56px;
|
||||
max-width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* === Services === */
|
||||
.services-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.service-card {
|
||||
background: var(--color-bg-card);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius);
|
||||
padding: 36px 28px;
|
||||
transition: all var(--transition);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.service-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.service-card.featured {
|
||||
border-color: var(--color-primary);
|
||||
background: linear-gradient(180deg, rgba(26, 115, 232, 0.08) 0%, var(--color-bg-card) 100%);
|
||||
}
|
||||
|
||||
.service-badge {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
right: 20px;
|
||||
background: var(--color-primary);
|
||||
color: var(--color-white);
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
padding: 4px 14px;
|
||||
border-radius: 20px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.service-icon {
|
||||
color: var(--color-primary-light);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.service-card h3 {
|
||||
font-size: 1.35rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-heading);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.service-card p {
|
||||
color: var(--color-text-muted);
|
||||
margin-bottom: 20px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.service-features {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.service-features li {
|
||||
padding: 6px 0;
|
||||
color: var(--color-text);
|
||||
font-size: 0.9rem;
|
||||
border-bottom: 1px solid rgba(30, 58, 95, 0.5);
|
||||
}
|
||||
|
||||
.service-features li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* === Features (Miksi me) === */
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.feature {
|
||||
text-align: center;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
color: var(--color-primary-light);
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.feature h3 {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-heading);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.feature p {
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* === Pricing === */
|
||||
.pricing-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 24px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.pricing-card {
|
||||
background: var(--color-bg-card);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius);
|
||||
padding: 36px 28px;
|
||||
text-align: center;
|
||||
transition: all var(--transition);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pricing-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.pricing-featured {
|
||||
border-color: var(--color-primary);
|
||||
background: linear-gradient(180deg, rgba(26, 115, 232, 0.1) 0%, var(--color-bg-card) 100%);
|
||||
transform: scale(1.04);
|
||||
}
|
||||
|
||||
.pricing-featured:hover {
|
||||
transform: scale(1.04) translateY(-4px);
|
||||
}
|
||||
|
||||
.pricing-badge {
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: var(--color-primary);
|
||||
color: var(--color-white);
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
padding: 4px 18px;
|
||||
border-radius: 20px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.pricing-header h3 {
|
||||
font-size: 1.3rem;
|
||||
font-weight: 700;
|
||||
color: var(--color-text-heading);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.price {
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.price-amount {
|
||||
font-size: 3rem;
|
||||
font-weight: 800;
|
||||
color: var(--color-white);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.price-period {
|
||||
font-size: 1.1rem;
|
||||
color: var(--color-text-muted);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.pricing-features {
|
||||
list-style: none;
|
||||
text-align: left;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.pricing-features li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 8px 0;
|
||||
font-size: 0.95rem;
|
||||
color: var(--color-text);
|
||||
border-bottom: 1px solid rgba(30, 58, 95, 0.4);
|
||||
}
|
||||
|
||||
.pricing-features li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.pricing-features svg {
|
||||
color: var(--color-accent);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pricing-note {
|
||||
text-align: center;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.9rem;
|
||||
margin-top: 40px;
|
||||
max-width: 700px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* === Contact === */
|
||||
.contact-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1.2fr 0.8fr;
|
||||
gap: 48px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.contact-form {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-group-full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
color: var(--color-text);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.form-group input,
|
||||
.form-group textarea {
|
||||
background: var(--color-bg-card);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 12px 16px;
|
||||
color: var(--color-text);
|
||||
font-family: inherit;
|
||||
font-size: 1rem;
|
||||
transition: border-color var(--transition);
|
||||
}
|
||||
|
||||
.form-group input:focus,
|
||||
.form-group textarea:focus {
|
||||
outline: none;
|
||||
border-color: var(--color-primary);
|
||||
box-shadow: 0 0 0 3px rgba(26, 115, 232, 0.15);
|
||||
}
|
||||
|
||||
.form-group textarea {
|
||||
resize: vertical;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
grid-column: 1 / -1;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.form-status {
|
||||
grid-column: 1 / -1;
|
||||
font-size: 0.95rem;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.form-status.success {
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.form-status.error {
|
||||
color: #f87171;
|
||||
}
|
||||
|
||||
.contact-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 28px;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.contact-item svg {
|
||||
color: var(--color-primary-light);
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.contact-item strong {
|
||||
display: block;
|
||||
color: var(--color-text-heading);
|
||||
font-size: 0.95rem;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.contact-item p {
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* === Footer === */
|
||||
.footer {
|
||||
background: var(--color-bg);
|
||||
border-top: 1px solid var(--color-border);
|
||||
padding-top: 56px;
|
||||
}
|
||||
|
||||
.footer-inner {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr 1fr;
|
||||
gap: 48px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.footer-brand .logo {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.footer-brand p {
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.footer-links h4 {
|
||||
color: var(--color-text-heading);
|
||||
font-size: 0.95rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.footer-links a {
|
||||
display: block;
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.9rem;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.footer-links a:hover {
|
||||
color: var(--color-primary-light);
|
||||
}
|
||||
|
||||
.footer-bottom {
|
||||
border-top: 1px solid var(--color-border);
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.footer-bottom p {
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.85rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* === Konesali Page === */
|
||||
.page-hero {
|
||||
padding: 140px 0 60px;
|
||||
background: linear-gradient(135deg, var(--color-bg) 0%, var(--color-bg-light) 100%);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.page-hero h1 {
|
||||
font-size: clamp(1.8rem, 4vw, 2.8rem);
|
||||
font-weight: 800;
|
||||
color: var(--color-white);
|
||||
margin-bottom: 12px;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.page-hero p {
|
||||
font-size: 1.15rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.specs-overview {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.spec-highlight {
|
||||
background: var(--color-bg-card);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius);
|
||||
padding: 32px 20px;
|
||||
}
|
||||
|
||||
.spec-highlight-value {
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
color: var(--color-primary-light);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.spec-highlight-label {
|
||||
font-size: 0.9rem;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.spec-section {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.spec-section-header {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.spec-section-icon {
|
||||
color: var(--color-primary-light);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.spec-section-header h2 {
|
||||
font-size: 1.8rem;
|
||||
font-weight: 800;
|
||||
color: var(--color-text-heading);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.spec-section-header p {
|
||||
color: var(--color-text-muted);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.spec-table {
|
||||
background: var(--color-bg-card);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.spec-table table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.spec-table tr {
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.spec-table tr:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.spec-table td {
|
||||
padding: 16px 20px;
|
||||
font-size: 0.95rem;
|
||||
color: var(--color-text);
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.spec-label {
|
||||
font-weight: 600;
|
||||
color: var(--color-text-heading);
|
||||
width: 200px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.specs-overview {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.spec-section-header {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.spec-label {
|
||||
width: auto;
|
||||
white-space: normal;
|
||||
display: block;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.spec-table td {
|
||||
display: block;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
.spec-table tr {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.spec-table td:first-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.specs-overview {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* === Animations === */
|
||||
.fade-in {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
transition: opacity 0.6s ease, transform 0.6s ease;
|
||||
}
|
||||
|
||||
.fade-in.visible {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* === Responsive === */
|
||||
@media (max-width: 1024px) {
|
||||
.services-grid,
|
||||
.pricing-grid,
|
||||
.features-grid {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.pricing-featured {
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.pricing-featured:hover {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: var(--header-height);
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: var(--color-bg);
|
||||
flex-direction: column;
|
||||
padding: 24px;
|
||||
gap: 0;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.nav.open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.nav a {
|
||||
padding: 14px 0;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.nav a:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.nav a::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-toggle {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.nav-toggle.open span:nth-child(1) {
|
||||
transform: rotate(45deg) translate(5px, 5px);
|
||||
}
|
||||
|
||||
.nav-toggle.open span:nth-child(2) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.nav-toggle.open span:nth-child(3) {
|
||||
transform: rotate(-45deg) translate(5px, -5px);
|
||||
}
|
||||
|
||||
.hero {
|
||||
padding: 120px 0 60px;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.hero-stats {
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.services-grid,
|
||||
.pricing-grid,
|
||||
.features-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 64px 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
.contact-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 40px;
|
||||
}
|
||||
|
||||
.contact-form {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.footer-inner {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.hero-stats {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.stat {
|
||||
flex-direction: row;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user