Add service worker for push notifications, create calendar layout, and implement WLAN QR code page
- Implemented a service worker (sw.js) to handle push notifications with dynamic options and notification click events. - Created a calendar layout in test.html with a grid system for displaying events across days and times. - Developed a visually engaging WLAN QR code page (wlan.html) with animated backgrounds, particle effects, and tips for connecting to the network.
This commit is contained in:
971
public/networktester.html
Normal file
971
public/networktester.html
Normal file
@@ -0,0 +1,971 @@
|
||||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>NETZWERKTESTER™ — Das beste Gadget der Welt</title>
|
||||
<meta name="description" content="Der übertriebenste Netzwerktester-Hype aller Zeiten. Animiert. Neon. Absolut unnötig — und genau deshalb perfekt." />
|
||||
|
||||
<style>
|
||||
:root{
|
||||
--bg:#060611;
|
||||
--bg2:#0b0b1f;
|
||||
--neon:#7CFF6B;
|
||||
--neon2:#7afcff;
|
||||
--hot:#ff4fd8;
|
||||
--warn:#ffd34d;
|
||||
--text:#f2f6ff;
|
||||
--muted:rgba(242,246,255,.72);
|
||||
--card:rgba(255,255,255,.06);
|
||||
--stroke:rgba(255,255,255,.12);
|
||||
--shadow: 0 22px 80px rgba(0,0,0,.65);
|
||||
--radius: 22px;
|
||||
--max: 1180px;
|
||||
}
|
||||
|
||||
*{box-sizing:border-box}
|
||||
html,body{height:100%}
|
||||
body{
|
||||
margin:0;
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji","Segoe UI Emoji";
|
||||
background: radial-gradient(1200px 800px at 20% 10%, rgba(122,252,255,.14), transparent 55%),
|
||||
radial-gradient(1100px 900px at 80% 20%, rgba(255,79,216,.12), transparent 55%),
|
||||
radial-gradient(900px 700px at 50% 80%, rgba(124,255,107,.10), transparent 55%),
|
||||
linear-gradient(180deg, var(--bg), var(--bg2));
|
||||
color:var(--text);
|
||||
overflow-x:hidden;
|
||||
}
|
||||
|
||||
/* ======= Animated background grid + lasers ======= */
|
||||
.bg-grid{
|
||||
position:fixed; inset:0;
|
||||
pointer-events:none;
|
||||
opacity:.55;
|
||||
background:
|
||||
linear-gradient(rgba(255,255,255,.06) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(255,255,255,.06) 1px, transparent 1px);
|
||||
background-size: 42px 42px;
|
||||
transform: perspective(900px) rotateX(60deg) translateY(-18vh);
|
||||
filter: drop-shadow(0 0 18px rgba(122,252,255,.08));
|
||||
animation: gridFloat 8s ease-in-out infinite;
|
||||
}
|
||||
@keyframes gridFloat{
|
||||
0%,100%{transform: perspective(900px) rotateX(60deg) translateY(-18vh) translateX(0)}
|
||||
50%{transform: perspective(900px) rotateX(60deg) translateY(-16vh) translateX(12px)}
|
||||
}
|
||||
|
||||
.lasers{
|
||||
position:fixed; inset:-30vh -30vw;
|
||||
pointer-events:none;
|
||||
mix-blend-mode: screen;
|
||||
opacity:.65;
|
||||
filter: blur(.2px);
|
||||
background:
|
||||
conic-gradient(from 180deg at 50% 50%,
|
||||
rgba(122,252,255,.0),
|
||||
rgba(122,252,255,.25),
|
||||
rgba(255,79,216,.18),
|
||||
rgba(124,255,107,.18),
|
||||
rgba(255,211,77,.12),
|
||||
rgba(122,252,255,.0));
|
||||
animation: spin 14s linear infinite;
|
||||
}
|
||||
@keyframes spin{to{transform:rotate(360deg)}}
|
||||
|
||||
/* ======= Layout ======= */
|
||||
.wrap{max-width:var(--max); margin:0 auto; padding: 22px 18px 90px;}
|
||||
header{
|
||||
position:sticky; top:0; z-index:50;
|
||||
backdrop-filter: blur(12px);
|
||||
background: linear-gradient(180deg, rgba(6,6,17,.78), rgba(6,6,17,.35));
|
||||
border-bottom: 1px solid rgba(255,255,255,.08);
|
||||
}
|
||||
.nav{
|
||||
max-width:var(--max); margin:0 auto;
|
||||
padding:12px 18px;
|
||||
display:flex; align-items:center; justify-content:space-between; gap:10px;
|
||||
}
|
||||
.brand{
|
||||
display:flex; align-items:center; gap:10px;
|
||||
font-weight:900;
|
||||
letter-spacing:.5px;
|
||||
text-transform:uppercase;
|
||||
user-select:none;
|
||||
}
|
||||
.brand .dot{
|
||||
width:12px;height:12px;border-radius:99px;
|
||||
background: radial-gradient(circle at 30% 30%, #fff, var(--neon2));
|
||||
box-shadow: 0 0 18px rgba(122,252,255,.55), 0 0 34px rgba(255,79,216,.18);
|
||||
animation: pulse 1.2s ease-in-out infinite;
|
||||
}
|
||||
@keyframes pulse{
|
||||
0%,100%{transform:scale(1); opacity:1}
|
||||
50%{transform:scale(1.35); opacity:.85}
|
||||
}
|
||||
.nav a{
|
||||
color:var(--muted);
|
||||
text-decoration:none;
|
||||
font-weight:700;
|
||||
padding:10px 12px;
|
||||
border-radius:12px;
|
||||
transition:.2s;
|
||||
display:none;
|
||||
}
|
||||
.nav a:hover{background:rgba(255,255,255,.06); color:var(--text)}
|
||||
@media (min-width:860px){
|
||||
.nav a{display:inline-block}
|
||||
}
|
||||
|
||||
.cta{
|
||||
display:flex; align-items:center; gap:10px;
|
||||
}
|
||||
.btn{
|
||||
border:1px solid rgba(255,255,255,.14);
|
||||
background: linear-gradient(180deg, rgba(255,255,255,.12), rgba(255,255,255,.06));
|
||||
color:var(--text);
|
||||
border-radius:14px;
|
||||
padding:10px 14px;
|
||||
font-weight:850;
|
||||
text-decoration:none;
|
||||
box-shadow: 0 10px 40px rgba(0,0,0,.35);
|
||||
transition: transform .15s ease, filter .15s ease;
|
||||
position:relative;
|
||||
overflow:hidden;
|
||||
user-select:none;
|
||||
}
|
||||
.btn:hover{transform: translateY(-2px); filter:brightness(1.08)}
|
||||
.btn.primary{
|
||||
border-color: rgba(122,252,255,.25);
|
||||
background: linear-gradient(135deg, rgba(122,252,255,.25), rgba(255,79,216,.16));
|
||||
box-shadow: 0 18px 60px rgba(122,252,255,.14), 0 18px 70px rgba(255,79,216,.10);
|
||||
}
|
||||
.btn .shine{
|
||||
content:"";
|
||||
position:absolute; inset:-30%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255,255,255,.45), transparent);
|
||||
transform: rotate(20deg) translateX(-120%);
|
||||
animation: shine 2.8s ease-in-out infinite;
|
||||
opacity:.8;
|
||||
}
|
||||
@keyframes shine{
|
||||
0%,55%{transform: rotate(20deg) translateX(-140%)}
|
||||
85%,100%{transform: rotate(20deg) translateX(140%)}
|
||||
}
|
||||
|
||||
/* ======= Hero ======= */
|
||||
.hero{
|
||||
padding: 46px 0 16px;
|
||||
display:grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap:18px;
|
||||
position:relative;
|
||||
}
|
||||
@media (min-width:980px){
|
||||
.hero{
|
||||
grid-template-columns: 1.05fr .95fr;
|
||||
align-items:center;
|
||||
padding: 64px 0 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.kicker{
|
||||
display:inline-flex; align-items:center; gap:10px;
|
||||
padding:8px 12px;
|
||||
border-radius:999px;
|
||||
border:1px solid rgba(255,255,255,.14);
|
||||
background: rgba(255,255,255,.06);
|
||||
color:var(--muted);
|
||||
font-weight:800;
|
||||
width:fit-content;
|
||||
box-shadow: 0 10px 40px rgba(0,0,0,.35);
|
||||
}
|
||||
.badge-live{
|
||||
display:inline-flex; align-items:center; gap:7px;
|
||||
padding:4px 10px;
|
||||
border-radius:999px;
|
||||
font-size:12px;
|
||||
font-weight:900;
|
||||
letter-spacing:.6px;
|
||||
color:#071208;
|
||||
background: linear-gradient(135deg, var(--neon), var(--neon2));
|
||||
box-shadow: 0 0 18px rgba(124,255,107,.22), 0 0 28px rgba(122,252,255,.18);
|
||||
text-transform:uppercase;
|
||||
}
|
||||
.badge-live i{
|
||||
width:8px;height:8px;border-radius:99px;background:#071208;
|
||||
box-shadow: 0 0 0 6px rgba(7,18,8,.15);
|
||||
animation: ping 1.1s ease-in-out infinite;
|
||||
}
|
||||
@keyframes ping{
|
||||
0%,100%{transform:scale(1); opacity:1}
|
||||
50%{transform:scale(1.35); opacity:.8}
|
||||
}
|
||||
|
||||
h1{
|
||||
margin: 14px 0 12px;
|
||||
font-size: clamp(36px, 5vw, 62px);
|
||||
line-height: 1.02;
|
||||
letter-spacing: -1.2px;
|
||||
}
|
||||
|
||||
.glitch{
|
||||
position:relative;
|
||||
display:inline-block;
|
||||
text-shadow:
|
||||
0 0 14px rgba(122,252,255,.18),
|
||||
0 0 22px rgba(255,79,216,.14);
|
||||
}
|
||||
.glitch::before,.glitch::after{
|
||||
content: attr(data-text);
|
||||
position:absolute; left:0; top:0;
|
||||
opacity:.8;
|
||||
mix-blend-mode: screen;
|
||||
clip-path: inset(0 0 0 0);
|
||||
animation: glitch 2.4s infinite linear alternate-reverse;
|
||||
}
|
||||
.glitch::before{
|
||||
transform: translate(2px,-2px);
|
||||
color: var(--neon2);
|
||||
filter: blur(.2px);
|
||||
}
|
||||
.glitch::after{
|
||||
transform: translate(-2px,2px);
|
||||
color: var(--hot);
|
||||
animation-duration: 2.9s;
|
||||
filter: blur(.25px);
|
||||
}
|
||||
@keyframes glitch{
|
||||
0%{clip-path: inset(0 0 85% 0)}
|
||||
10%{clip-path: inset(12% 0 60% 0)}
|
||||
20%{clip-path: inset(65% 0 10% 0)}
|
||||
30%{clip-path: inset(40% 0 40% 0)}
|
||||
40%{clip-path: inset(80% 0 5% 0)}
|
||||
50%{clip-path: inset(10% 0 75% 0)}
|
||||
60%{clip-path: inset(35% 0 40% 0)}
|
||||
70%{clip-path: inset(5% 0 85% 0)}
|
||||
80%{clip-path: inset(55% 0 20% 0)}
|
||||
90%{clip-path: inset(25% 0 55% 0)}
|
||||
100%{clip-path: inset(70% 0 15% 0)}
|
||||
}
|
||||
|
||||
.sub{
|
||||
color:var(--muted);
|
||||
font-size: clamp(16px, 2.1vw, 20px);
|
||||
line-height:1.5;
|
||||
margin: 0 0 18px;
|
||||
max-width: 58ch;
|
||||
}
|
||||
|
||||
.hero-actions{
|
||||
display:flex; flex-wrap:wrap; gap:10px;
|
||||
align-items:center;
|
||||
margin: 18px 0 12px;
|
||||
}
|
||||
|
||||
.stats{
|
||||
display:grid;
|
||||
grid-template-columns: repeat(2, minmax(0,1fr));
|
||||
gap:10px;
|
||||
margin-top: 14px;
|
||||
max-width: 520px;
|
||||
}
|
||||
@media(min-width:520px){
|
||||
.stats{grid-template-columns: repeat(3, minmax(0,1fr));}
|
||||
}
|
||||
.stat{
|
||||
border:1px solid rgba(255,255,255,.12);
|
||||
background: rgba(255,255,255,.06);
|
||||
border-radius: 18px;
|
||||
padding: 12px 12px;
|
||||
box-shadow: 0 12px 55px rgba(0,0,0,.35);
|
||||
position:relative;
|
||||
overflow:hidden;
|
||||
}
|
||||
.stat b{
|
||||
display:block;
|
||||
font-size: 22px;
|
||||
letter-spacing:-.3px;
|
||||
}
|
||||
.stat span{color:var(--muted); font-weight:700; font-size:13px}
|
||||
.stat::after{
|
||||
content:"";
|
||||
position:absolute; inset:-40%;
|
||||
background: radial-gradient(circle at 30% 30%, rgba(122,252,255,.18), transparent 55%),
|
||||
radial-gradient(circle at 80% 70%, rgba(255,79,216,.16), transparent 55%);
|
||||
animation: drift 6s ease-in-out infinite;
|
||||
opacity:.8;
|
||||
}
|
||||
@keyframes drift{
|
||||
0%,100%{transform: translate(0,0) rotate(0deg)}
|
||||
50%{transform: translate(18px,-12px) rotate(8deg)}
|
||||
}
|
||||
.stat > *{position:relative; z-index:1}
|
||||
|
||||
/* ======= Right side device card ======= */
|
||||
.device{
|
||||
border:1px solid rgba(255,255,255,.14);
|
||||
background: linear-gradient(180deg, rgba(255,255,255,.09), rgba(255,255,255,.04));
|
||||
border-radius: var(--radius);
|
||||
padding: 14px;
|
||||
box-shadow: var(--shadow);
|
||||
position:relative;
|
||||
overflow:hidden;
|
||||
min-height: 420px;
|
||||
}
|
||||
.device::before{
|
||||
content:"";
|
||||
position:absolute; inset:-40%;
|
||||
background: conic-gradient(from 180deg at 50% 50%,
|
||||
rgba(122,252,255,.0),
|
||||
rgba(122,252,255,.22),
|
||||
rgba(255,79,216,.18),
|
||||
rgba(124,255,107,.16),
|
||||
rgba(255,211,77,.10),
|
||||
rgba(122,252,255,.0));
|
||||
animation: spin 10s linear infinite;
|
||||
opacity:.55;
|
||||
}
|
||||
.device-inner{
|
||||
position:relative; z-index:1;
|
||||
height:100%;
|
||||
border-radius: calc(var(--radius) - 10px);
|
||||
border:1px solid rgba(255,255,255,.12);
|
||||
background: rgba(0,0,0,.22);
|
||||
overflow:hidden;
|
||||
display:grid;
|
||||
grid-template-rows: auto 1fr auto;
|
||||
}
|
||||
.device-top{
|
||||
display:flex; align-items:center; justify-content:space-between;
|
||||
padding:12px 12px 10px;
|
||||
gap:10px;
|
||||
border-bottom:1px solid rgba(255,255,255,.10);
|
||||
}
|
||||
.dots{display:flex; gap:7px}
|
||||
.dots i{
|
||||
width:10px;height:10px;border-radius:99px;
|
||||
background: rgba(255,255,255,.16);
|
||||
box-shadow: 0 0 0 6px rgba(255,255,255,.03);
|
||||
}
|
||||
.device-top .mode{
|
||||
font-size:12px; font-weight:900; letter-spacing:.7px;
|
||||
text-transform:uppercase;
|
||||
color:var(--muted);
|
||||
}
|
||||
|
||||
.screen{
|
||||
position:relative;
|
||||
padding: 14px;
|
||||
display:grid;
|
||||
place-items:center;
|
||||
}
|
||||
.screen img{
|
||||
width:100%;
|
||||
height: 280px;
|
||||
object-fit:cover;
|
||||
border-radius: 18px;
|
||||
border:1px solid rgba(255,255,255,.14);
|
||||
filter: saturate(1.15) contrast(1.05);
|
||||
transform: translateZ(0);
|
||||
box-shadow: 0 18px 70px rgba(0,0,0,.55);
|
||||
}
|
||||
.floaters{
|
||||
position:absolute; inset:0;
|
||||
pointer-events:none;
|
||||
overflow:hidden;
|
||||
}
|
||||
.floater{
|
||||
position:absolute;
|
||||
font-size: clamp(16px, 2.6vw, 26px);
|
||||
filter: drop-shadow(0 10px 18px rgba(0,0,0,.55));
|
||||
opacity:.95;
|
||||
animation: floatUp linear infinite;
|
||||
}
|
||||
@keyframes floatUp{
|
||||
from{transform: translateY(40px) rotate(0deg); opacity:0}
|
||||
15%{opacity:1}
|
||||
to{transform: translateY(-380px) rotate(22deg); opacity:0}
|
||||
}
|
||||
|
||||
.device-bottom{
|
||||
padding: 12px;
|
||||
border-top:1px solid rgba(255,255,255,.10);
|
||||
display:flex; gap:10px; align-items:center; justify-content:space-between;
|
||||
flex-wrap:wrap;
|
||||
}
|
||||
.meter{
|
||||
flex:1;
|
||||
min-width: 210px;
|
||||
border:1px solid rgba(255,255,255,.12);
|
||||
background: rgba(255,255,255,.05);
|
||||
border-radius: 999px;
|
||||
height: 14px;
|
||||
overflow:hidden;
|
||||
position:relative;
|
||||
}
|
||||
.meter span{
|
||||
display:block; height:100%;
|
||||
width: 20%;
|
||||
background: linear-gradient(90deg, var(--neon2), var(--hot), var(--neon));
|
||||
border-radius: 999px;
|
||||
animation: fill 3.2s ease-in-out infinite;
|
||||
filter: saturate(1.2);
|
||||
}
|
||||
@keyframes fill{
|
||||
0%{width:18%}
|
||||
50%{width:98%}
|
||||
100%{width:30%}
|
||||
}
|
||||
.meter-label{
|
||||
font-weight:900;
|
||||
color:var(--muted);
|
||||
font-size:12px;
|
||||
letter-spacing:.6px;
|
||||
text-transform:uppercase;
|
||||
display:flex; align-items:center; gap:8px;
|
||||
user-select:none;
|
||||
}
|
||||
|
||||
/* ======= Sections ======= */
|
||||
section{padding: 26px 0}
|
||||
.grid{
|
||||
display:grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap:14px;
|
||||
}
|
||||
@media(min-width:980px){
|
||||
.grid{grid-template-columns: 1fr 1fr}
|
||||
}
|
||||
|
||||
.card{
|
||||
border:1px solid rgba(255,255,255,.12);
|
||||
background: rgba(255,255,255,.06);
|
||||
border-radius: var(--radius);
|
||||
padding: 16px;
|
||||
box-shadow: 0 18px 70px rgba(0,0,0,.35);
|
||||
position:relative;
|
||||
overflow:hidden;
|
||||
}
|
||||
.card::before{
|
||||
content:"";
|
||||
position:absolute; inset:-30%;
|
||||
background: radial-gradient(circle at 20% 20%, rgba(122,252,255,.14), transparent 55%),
|
||||
radial-gradient(circle at 70% 70%, rgba(255,79,216,.14), transparent 55%);
|
||||
animation: drift 8s ease-in-out infinite;
|
||||
opacity:.7;
|
||||
}
|
||||
.card > *{position:relative; z-index:1}
|
||||
|
||||
.card h2{
|
||||
margin: 2px 0 10px;
|
||||
font-size: 22px;
|
||||
letter-spacing:-.4px;
|
||||
}
|
||||
.card p{margin: 0; color: var(--muted); line-height:1.55}
|
||||
.bullets{
|
||||
margin: 12px 0 0;
|
||||
padding-left: 0;
|
||||
list-style:none;
|
||||
display:grid;
|
||||
gap:10px;
|
||||
}
|
||||
.bullets li{
|
||||
display:flex; gap:10px;
|
||||
align-items:flex-start;
|
||||
padding: 10px 10px;
|
||||
border-radius: 16px;
|
||||
border:1px solid rgba(255,255,255,.10);
|
||||
background: rgba(0,0,0,.18);
|
||||
}
|
||||
.emoji{
|
||||
width: 34px; height: 34px;
|
||||
display:grid; place-items:center;
|
||||
border-radius: 14px;
|
||||
background: rgba(255,255,255,.07);
|
||||
border:1px solid rgba(255,255,255,.12);
|
||||
flex:0 0 auto;
|
||||
}
|
||||
.bullets b{display:block; margin-bottom:2px}
|
||||
.bullets span{color: var(--muted); font-weight:650}
|
||||
|
||||
/* ======= Old tester comparison ======= */
|
||||
.compare{
|
||||
display:grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 14px;
|
||||
align-items:stretch;
|
||||
}
|
||||
@media(min-width:980px){
|
||||
.compare{grid-template-columns: 1fr 1fr}
|
||||
}
|
||||
|
||||
.img-card{
|
||||
border:1px solid rgba(255,255,255,.12);
|
||||
background: rgba(255,255,255,.05);
|
||||
border-radius: var(--radius);
|
||||
overflow:hidden;
|
||||
box-shadow: var(--shadow);
|
||||
position:relative;
|
||||
}
|
||||
.img-card img{
|
||||
width:100%;
|
||||
height: 320px;
|
||||
object-fit: cover;
|
||||
display:block;
|
||||
filter: contrast(1.05) saturate(1.12);
|
||||
}
|
||||
.img-card .cap{
|
||||
padding: 14px 14px 16px;
|
||||
border-top:1px solid rgba(255,255,255,.10);
|
||||
}
|
||||
.tag{
|
||||
display:inline-flex; align-items:center; gap:8px;
|
||||
font-weight:900;
|
||||
letter-spacing:.5px;
|
||||
text-transform:uppercase;
|
||||
font-size:12px;
|
||||
padding:6px 10px;
|
||||
border-radius:999px;
|
||||
border:1px solid rgba(255,255,255,.14);
|
||||
background: rgba(0,0,0,.22);
|
||||
color:var(--muted);
|
||||
}
|
||||
|
||||
/* ======= Testimonials ======= */
|
||||
.quotes{
|
||||
display:grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 12px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
@media(min-width:860px){
|
||||
.quotes{grid-template-columns: repeat(3, 1fr)}
|
||||
}
|
||||
blockquote{
|
||||
margin:0;
|
||||
padding: 14px;
|
||||
border-radius: var(--radius);
|
||||
border:1px solid rgba(255,255,255,.12);
|
||||
background: rgba(255,255,255,.06);
|
||||
box-shadow: 0 18px 60px rgba(0,0,0,.28);
|
||||
position:relative;
|
||||
overflow:hidden;
|
||||
}
|
||||
blockquote::before{
|
||||
content:"“";
|
||||
position:absolute;
|
||||
top:-24px; left:10px;
|
||||
font-size: 88px;
|
||||
opacity:.16;
|
||||
}
|
||||
blockquote p{margin:0 0 10px; color:var(--muted); line-height:1.5}
|
||||
blockquote footer{font-weight:900; color:var(--text)}
|
||||
blockquote small{display:block; color:var(--muted); font-weight:750; margin-top:3px}
|
||||
|
||||
/* ======= Footer ======= */
|
||||
footer{
|
||||
margin-top: 26px;
|
||||
padding-top: 18px;
|
||||
border-top: 1px solid rgba(255,255,255,.10);
|
||||
color: var(--muted);
|
||||
font-weight:700;
|
||||
display:flex; flex-direction:column; gap:8px;
|
||||
}
|
||||
|
||||
/* ======= Scroll reveal ======= */
|
||||
.reveal{
|
||||
opacity:0;
|
||||
transform: translateY(14px) scale(.98);
|
||||
transition: opacity .7s ease, transform .7s ease;
|
||||
}
|
||||
.reveal.on{
|
||||
opacity:1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
|
||||
/* ======= Confetti canvas ======= */
|
||||
canvas#confetti{
|
||||
position:fixed; inset:0;
|
||||
pointer-events:none;
|
||||
z-index:999;
|
||||
}
|
||||
|
||||
/* ======= Reduced motion ======= */
|
||||
@media (prefers-reduced-motion: reduce){
|
||||
*{animation:none!important; transition:none!important; scroll-behavior:auto!important}
|
||||
.bg-grid,.lasers{display:none}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="bg-grid" aria-hidden="true"></div>
|
||||
<div class="lasers" aria-hidden="true"></div>
|
||||
<canvas id="confetti"></canvas>
|
||||
|
||||
<header>
|
||||
<div class="nav">
|
||||
<div class="brand">
|
||||
<span class="dot" aria-hidden="true"></span>
|
||||
<span>NETZWERKTESTER™</span>
|
||||
</div>
|
||||
<nav>
|
||||
<a href="#features">Features</a>
|
||||
<a href="#compare">Vergleich</a>
|
||||
<a href="#testimonials">Stimmen</a>
|
||||
</nav>
|
||||
<div class="cta">
|
||||
<a class="btn" href="#compare">👀 Showdown</a>
|
||||
<a class="btn primary" id="boostBtn" href="#features">🚀 BOOST <span class="shine" aria-hidden="true"></span></a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="wrap">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<div class="kicker">
|
||||
<span class="badge-live"><i></i> Live Hype</span>
|
||||
<span>Übertrieben. Animiert. Absolut notwendig. 😎⚡</span>
|
||||
</div>
|
||||
|
||||
<h1>
|
||||
<span class="glitch" data-text="Der Netzwerktester, den wirklich ALLE brauchen.">Der Netzwerktester, den wirklich ALLE brauchen.</span>
|
||||
<span aria-hidden="true"> 🧪🔌✨</span>
|
||||
</h1>
|
||||
|
||||
<p class="sub">
|
||||
Schluss mit „Warum geht’s nicht?!“ — unser Netzwerktester verwandelt jedes Kabel in eine <b>offiziell zertifizierte
|
||||
Glücksleitung</b>. Er misst nicht nur Durchgang… er misst <b>Aura</b>, <b>Vibes</b> und <b>Respekt</b>. 💚📈
|
||||
</p>
|
||||
|
||||
<div class="hero-actions">
|
||||
<a class="btn primary" href="#features">😤 Ich brauche das jetzt <span class="shine" aria-hidden="true"></span></a>
|
||||
<a class="btn" href="#testimonials">⭐ 100% echte Stimmen*</a>
|
||||
<span class="meter-label">POWER-LEVEL: <b id="powerLevel">9000</b>+</span>
|
||||
</div>
|
||||
|
||||
<div class="stats">
|
||||
<div class="stat">
|
||||
<b><span id="uptime">99.98</span>%</b>
|
||||
<span>Hype-Uptime</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<b><span id="cables">0</span></b>
|
||||
<span>Kabel gerettet</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<b><span id="wow">0</span>×</b>
|
||||
<span>„WOW“ pro Minute</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<aside class="device" aria-label="Animiertes Showcase">
|
||||
<div class="device-inner">
|
||||
<div class="device-top">
|
||||
<div class="dots" aria-hidden="true"><i></i><i></i><i></i></div>
|
||||
<div class="mode">ULTRA DIAG MODE 🔥</div>
|
||||
</div>
|
||||
|
||||
<div class="screen">
|
||||
<!-- Bild 1: Person mit Netzwerkkabel -->
|
||||
<img
|
||||
src="https://cdn.pixabay.com/photo/2016/08/15/20/02/compression-pressure-recorder-1596369_1280.jpg"
|
||||
alt="Person hält ein Netzwerkkabel"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div class="floaters" aria-hidden="true" id="floaters"></div>
|
||||
</div>
|
||||
|
||||
<div class="device-bottom">
|
||||
<div class="meter" aria-hidden="true"><span></span></div>
|
||||
<div class="meter-label">SCAN: <span id="scanText">LINK UP ✅</span> ⚡</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</section>
|
||||
|
||||
<section id="features" class="reveal">
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<h2>Warum ist das Ding so legendär? 🏆</h2>
|
||||
<p>
|
||||
Weil er die Realität debuggt. Du steckst ein Kabel rein — und plötzlich macht die Welt Sinn.
|
||||
(Zumindest das Patchfeld.) 🌍🔧
|
||||
</p>
|
||||
<ul class="bullets">
|
||||
<li>
|
||||
<div class="emoji">🧠</div>
|
||||
<div>
|
||||
<b>IQ-Boost für den Schaltschrank</b>
|
||||
<span>Erkennt Fehler, bevor sie überhaupt passieren. (Gefühlt.)</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="emoji">⚡</div>
|
||||
<div>
|
||||
<b>Turbo-Scan in Lichtgeschwindigkeit</b>
|
||||
<span>So schnell, dass dein Blick hinterher ruckelt.</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="emoji">🛡️</div>
|
||||
<div>
|
||||
<b>Anti-“Warum geht’s nicht?”-Shield</b>
|
||||
<span>Blockt Ausreden, Drama und Kabel-Karma.</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>Für wen? Für ALLE. Wirklich alle. 😤</h2>
|
||||
<p>
|
||||
Schüler, Azubis, Techniker, Netzwerkgötter, IT-Orakel, Menschen mit Kabeln, Menschen ohne Kabeln,
|
||||
sogar Leute, die „LAN“ für eine Stadt halten. 🏙️🔌
|
||||
</p>
|
||||
<ul class="bullets">
|
||||
<li>
|
||||
<div class="emoji">📱</div>
|
||||
<div>
|
||||
<b>Handy & PC: Perfekt sichtbar</b>
|
||||
<span>Responsive Layout, große Buttons, kein Zoomen wie 2012.</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="emoji">🎛️</div>
|
||||
<div>
|
||||
<b>Animationen: Maximum Overdrive</b>
|
||||
<span>Neon, Glitch, Laser, Floating Emojis… ja.</span>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="emoji">🧪</div>
|
||||
<div>
|
||||
<b>Wissenschaftlich übertrieben</b>
|
||||
<span>Messwerte wirken 17% seriöser, wenn sie leuchten.</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="compare" class="reveal">
|
||||
<h2 style="margin:0 0 12px; font-size:28px; letter-spacing:-.5px;">
|
||||
Der epische Vergleich: ALT vs. HYPER-ULTRA 😱
|
||||
</h2>
|
||||
|
||||
<div class="compare">
|
||||
<article class="img-card">
|
||||
<!-- Bild 2: sehr alter Netzwerktester -->
|
||||
<img
|
||||
src="https://cdn.pixabay.com/photo/2013/03/09/02/36/tester-91696_1280.jpg"
|
||||
alt="Sehr alter Netzwerktester"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div class="cap">
|
||||
<span class="tag">🕰️ Altgerät</span>
|
||||
<h3 style="margin:10px 0 6px;">Der Klassiker: „Geht… irgendwie“</h3>
|
||||
<p style="margin:0; color:var(--muted); line-height:1.5;">
|
||||
Misst Dinge. Manchmal. Mit Charme. Aber ohne Laser. Ohne Glitch. Ohne Drama. (Also langweilig.) 😴
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="img-card">
|
||||
<div style="position:relative">
|
||||
<img
|
||||
src="https://cdn.pixabay.com/photo/2017/12/24/21/08/secret-3037639_1280.jpg"
|
||||
alt="Person mit Netzwerkkabel"
|
||||
loading="lazy"
|
||||
style="filter:saturate(1.3) contrast(1.08);"
|
||||
/>
|
||||
<div style="
|
||||
position:absolute; inset:0;
|
||||
background: radial-gradient(circle at 20% 20%, rgba(122,252,255,.22), transparent 55%),
|
||||
radial-gradient(circle at 70% 70%, rgba(255,79,216,.18), transparent 55%);
|
||||
mix-blend-mode: screen;
|
||||
pointer-events:none;
|
||||
"></div>
|
||||
</div>
|
||||
<div class="cap">
|
||||
<span class="tag">🚀 HYPE-DEVICE</span>
|
||||
<h3 style="margin:10px 0 6px;">NETZWERKTESTER™: „Ich sehe alles.“</h3>
|
||||
<p style="margin:0; color:var(--muted); line-height:1.5;">
|
||||
Findet Fehler. Findet Sinn. Findet deinen verlorenen Schraubendreher (theoretisch). 🧲✨
|
||||
Und sieht dabei gefährlich gut aus. 😎
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="testimonials" class="reveal">
|
||||
<h2 style="margin:0 0 6px; font-size:28px; letter-spacing:-.5px;">
|
||||
100% echte Stimmen* ⭐
|
||||
</h2>
|
||||
<p style="margin:0 0 10px; color:var(--muted); font-weight:700;">
|
||||
*Echt im Sinne von: Niemand hat widersprochen. 🤝😇
|
||||
</p>
|
||||
|
||||
<div class="quotes">
|
||||
<blockquote>
|
||||
<p>„Ich hab ihn einmal eingeschaltet und plötzlich war mein Leben geordnet. Sogar die Patchkabel.“</p>
|
||||
<footer>Max, <small>zertifizierter Kabel-Flüsterer 🧙♂️</small></footer>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>„Er sagt ‘LINK UP’ mit so viel Selbstbewusstsein, ich fühl mich direkt kompetenter.“</p>
|
||||
<footer>Sara, <small>Fehlerfinderin auf Koffein ☕</small></footer>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>„Ich wollte keinen. Jetzt hab ich drei. Einen fürs Bett, einen fürs Auto, einen fürs Herz.“</p>
|
||||
<footer>Ali, <small>LAN-Romantiker 💘</small></footer>
|
||||
</blockquote>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div>© <span id="year"></span> Netzwerktester™ — „Wenn’s leuchtet, ist’s besser.“ ✨</div>
|
||||
<div style="opacity:.85"><a href="https://www.fsae41.de">HOME</a></div>
|
||||
</footer>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
// ===== Scroll reveal =====
|
||||
const revealEls = document.querySelectorAll('.reveal');
|
||||
const io = new IntersectionObserver((entries)=>{
|
||||
for (const e of entries){
|
||||
if (e.isIntersecting) e.target.classList.add('on');
|
||||
}
|
||||
}, {threshold: 0.12});
|
||||
revealEls.forEach(el => io.observe(el));
|
||||
|
||||
// ===== Floating emojis in the "device screen" =====
|
||||
const floaters = document.getElementById('floaters');
|
||||
const EMOJIS = ["🔌","⚡","✨","📶","🧪","😎","🟩","💥","🧠","🛠️","🌈","🚀"];
|
||||
function spawnFloater(){
|
||||
const el = document.createElement('div');
|
||||
el.className = 'floater';
|
||||
el.textContent = EMOJIS[Math.floor(Math.random()*EMOJIS.length)];
|
||||
el.style.left = Math.random()*100 + "%";
|
||||
el.style.bottom = (-10 - Math.random()*10) + "px";
|
||||
el.style.animationDuration = (2.2 + Math.random()*2.8) + "s";
|
||||
el.style.animationDelay = (Math.random()*0.2) + "s";
|
||||
el.style.transform = `translateY(40px) rotate(${(Math.random()*18-9).toFixed(1)}deg)`;
|
||||
floaters.appendChild(el);
|
||||
setTimeout(()=> el.remove(), 5200);
|
||||
}
|
||||
setInterval(spawnFloater, 180);
|
||||
|
||||
// ===== Fake live scan text =====
|
||||
const scanText = document.getElementById('scanText');
|
||||
const scanPhrases = [
|
||||
"LINK UP ✅", "PAIR OK ✅", "GIGABIT DREAM ✅", "VIBES: STABIL ✅",
|
||||
"PATCHKABEL: GLÜCKLICH ✅", "KARMA: GEROUTET ✅", "FEHLER: GEFUNDEN 🎯"
|
||||
];
|
||||
setInterval(()=>{
|
||||
scanText.textContent = scanPhrases[Math.floor(Math.random()*scanPhrases.length)];
|
||||
}, 1300);
|
||||
|
||||
// ===== Counters =====
|
||||
const yearEl = document.getElementById('year');
|
||||
yearEl.textContent = new Date().getFullYear();
|
||||
|
||||
const uptimeEl = document.getElementById('uptime');
|
||||
const cablesEl = document.getElementById('cables');
|
||||
const wowEl = document.getElementById('wow');
|
||||
const powerLevelEl = document.getElementById('powerLevel');
|
||||
|
||||
let cables = 0;
|
||||
let wow = 0;
|
||||
let power = 9001;
|
||||
|
||||
function tick(){
|
||||
cables += Math.floor(1 + Math.random()*6);
|
||||
wow += Math.floor(1 + Math.random()*4);
|
||||
power += Math.floor(6 + Math.random()*18);
|
||||
|
||||
cablesEl.textContent = cables.toLocaleString('de-DE');
|
||||
wowEl.textContent = wow.toLocaleString('de-DE');
|
||||
powerLevelEl.textContent = power.toLocaleString('de-DE');
|
||||
|
||||
// uptime wiggle
|
||||
const base = 99.90;
|
||||
const v = (base + Math.random()*0.09).toFixed(2);
|
||||
uptimeEl.textContent = v;
|
||||
}
|
||||
setInterval(tick, 900);
|
||||
tick();
|
||||
|
||||
// ===== Confetti "BOOST" (simple canvas particles) =====
|
||||
const canvas = document.getElementById('confetti');
|
||||
const ctx = canvas.getContext('2d');
|
||||
let W, H;
|
||||
function resize(){
|
||||
W = canvas.width = window.innerWidth * devicePixelRatio;
|
||||
H = canvas.height = window.innerHeight * devicePixelRatio;
|
||||
}
|
||||
window.addEventListener('resize', resize);
|
||||
resize();
|
||||
|
||||
let particles = [];
|
||||
function burst(){
|
||||
const count = 170;
|
||||
for(let i=0;i<count;i++){
|
||||
particles.push({
|
||||
x: (Math.random()*window.innerWidth) * devicePixelRatio,
|
||||
y: (-10 - Math.random()*60) * devicePixelRatio,
|
||||
vx: (-1.2 + Math.random()*2.4) * devicePixelRatio,
|
||||
vy: (2.0 + Math.random()*4.4) * devicePixelRatio,
|
||||
r: (2 + Math.random()*4) * devicePixelRatio,
|
||||
rot: Math.random()*Math.PI*2,
|
||||
vr: (-0.18 + Math.random()*0.36),
|
||||
life: 0,
|
||||
max: 160 + Math.random()*120
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function draw(){
|
||||
ctx.clearRect(0,0,W,H);
|
||||
for(const p of particles){
|
||||
p.x += p.vx;
|
||||
p.y += p.vy;
|
||||
p.vy += 0.02 * devicePixelRatio; // gravity
|
||||
p.rot += p.vr;
|
||||
p.life++;
|
||||
|
||||
const alpha = Math.max(0, 1 - p.life / p.max);
|
||||
ctx.save();
|
||||
ctx.globalAlpha = alpha * 0.9;
|
||||
ctx.translate(p.x, p.y);
|
||||
ctx.rotate(p.rot);
|
||||
|
||||
// No fixed colors: use random-ish neon via hue
|
||||
const hue = (p.life*2 + p.x/W*360) % 360;
|
||||
ctx.fillStyle = `hsla(${hue}, 95%, 60%, 1)`;
|
||||
ctx.fillRect(-p.r, -p.r, p.r*2.2, p.r*1.2);
|
||||
ctx.restore();
|
||||
}
|
||||
particles = particles.filter(p => p.life < p.max && p.y < H + 120);
|
||||
requestAnimationFrame(draw);
|
||||
}
|
||||
draw();
|
||||
|
||||
document.getElementById('boostBtn').addEventListener('click', (e)=>{
|
||||
// allow anchor scroll, but also boost visuals
|
||||
burst();
|
||||
// micro screen shake
|
||||
document.body.animate([
|
||||
{ transform: 'translate(0,0)' },
|
||||
{ transform: 'translate(2px,-2px)' },
|
||||
{ transform: 'translate(-2px,2px)' },
|
||||
{ transform: 'translate(1px,1px)' },
|
||||
{ transform: 'translate(0,0)' }
|
||||
], { duration: 320, iterations: 1 });
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user