HTML
<section class="nn-syn" aria-label="Synthwave scene demo">
<div class="scene">
<div class="stars" data-nn-syn-stars aria-hidden="true"></div>
<div class="sun-wrap" aria-hidden="true">
<div class="sun"></div>
<div class="sun-lines"></div>
</div>
<div class="horizon" aria-hidden="true"></div>
<div class="mountains" aria-hidden="true">
<svg viewBox="0 0 700 100" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="nn-syn-mtnGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#1a0035"/>
<stop offset="100%" stop-color="#0a0015"/>
</linearGradient>
</defs>
<polygon points="0,100 0,65 60,30 120,58 180,18 240,52 300,5 360,48 420,22 480,55 540,28 600,60 660,35 700,48 700,100" fill="url(#nn-syn-mtnGrad)"/>
<line x1="0" y1="65" x2="60" y2="30" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
<line x1="60" y1="30" x2="120" y2="58" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
<line x1="120" y1="58" x2="180" y2="18" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
<line x1="180" y1="18" x2="240" y2="52" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
<line x1="240" y1="52" x2="300" y2="5" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
<line x1="300" y1="5" x2="360" y2="48" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
<line x1="360" y1="48" x2="420" y2="22" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
<line x1="420" y1="22" x2="480" y2="55" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
<line x1="480" y1="55" x2="540" y2="28" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
<line x1="540" y1="28" x2="600" y2="60" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
<line x1="600" y1="60" x2="660" y2="35" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
<line x1="660" y1="35" x2="700" y2="48" stroke="rgba(255,0,200,0.5)" stroke-width="0.8"/>
</svg>
</div>
<div class="grid-wrap" aria-hidden="true">
<div class="grid"></div>
<div class="grid-fade"></div>
</div>
<div class="scanlines" aria-hidden="true"></div>
<div class="title-wrap">
<div class="title-main">SYNTHWAVE</div>
<div class="title-sub">Retro · Future · Neon</div>
<div class="year">◈ 1 9 8 6 ◈</div>
</div>
</div>
</section> CSS
/* ─── 04 Synthwave Scene — 80s retrofuture composition ─────────── */
@import url('https://fonts.googleapis.com/css2?family=Audiowide&family=Oxanium:wght@700;800&display=swap');
.nn-syn {
position: relative;
width: 100%;
min-height: 560px;
background: #0a0015;
font-family: 'Audiowide', cursive;
display: flex;
align-items: center;
justify-content: center;
padding: 40px 16px;
overflow: hidden;
box-sizing: border-box;
}
.nn-syn *,
.nn-syn *::before,
.nn-syn *::after { box-sizing: border-box; margin: 0; padding: 0; }
.nn-syn .scene {
position: relative;
width: 700px;
max-width: 100%;
height: 480px;
overflow: hidden;
background: linear-gradient(
180deg,
#090010 0%,
#130025 30%,
#1a003a 55%,
#260050 70%,
#0f0020 100%
);
}
.nn-syn .stars { position: absolute; inset: 0 0 50% 0; overflow: hidden; }
.nn-syn .star {
position: absolute;
background: #fff;
border-radius: 50%;
animation: nn-syn-twinkle var(--dur, 2s) var(--del, 0s) ease-in-out infinite alternate;
}
@keyframes nn-syn-twinkle {
from { opacity: var(--min, 0.3); transform: scale(1); }
to { opacity: 1; transform: scale(1.4); }
}
.nn-syn .sun-wrap {
position: absolute;
left: 50%;
top: 24%;
transform: translateX(-50%);
width: 160px;
height: 160px;
}
.nn-syn .sun {
position: absolute;
inset: 0;
border-radius: 50%;
background: linear-gradient(
180deg,
#ffe066 0%,
#ff9900 20%,
#ff2d78 45%,
#c800ff 65%,
#6600cc 80%,
#2a0060 100%
);
box-shadow:
0 0 30px rgba(255,150,0,0.6),
0 0 70px rgba(255,80,150,0.5),
0 0 120px rgba(200,0,255,0.35),
0 0 200px rgba(100,0,200,0.2);
animation: nn-syn-sunpulse 4s ease-in-out infinite;
}
@keyframes nn-syn-sunpulse {
0%, 100% { box-shadow: 0 0 28px rgba(255,150,0,0.55), 0 0 65px rgba(255,80,150,0.45), 0 0 110px rgba(200,0,255,0.3); }
50% { box-shadow: 0 0 42px rgba(255,150,0,0.75), 0 0 90px rgba(255,80,150,0.6), 0 0 160px rgba(200,0,255,0.45); }
}
.nn-syn .sun-lines {
position: absolute;
inset: 0;
border-radius: 50%;
overflow: hidden;
pointer-events: none;
}
.nn-syn .sun-lines::before {
content: '';
position: absolute;
inset: 0;
background: repeating-linear-gradient(
0deg,
transparent 0px,
transparent 8px,
rgba(10,0,20,0.55) 8px,
rgba(10,0,20,0.55) 12px
);
}
.nn-syn .horizon {
position: absolute;
left: 0;
right: 0;
top: 56%;
height: 4px;
background: linear-gradient(90deg,
transparent 0%,
rgba(255,60,180,0.8) 20%,
#ff2aff 50%,
rgba(255,60,180,0.8) 80%,
transparent 100%
);
box-shadow:
0 0 18px rgba(255,40,255,0.8),
0 0 45px rgba(255,40,255,0.4),
0 0 80px rgba(255,40,255,0.2);
}
.nn-syn .grid-wrap {
position: absolute;
left: 0;
right: 0;
top: 57%;
bottom: 0;
overflow: hidden;
perspective: 300px;
}
.nn-syn .grid {
position: absolute;
width: 200%;
left: -50%;
top: 0;
height: 300%;
transform-origin: top center;
transform: rotateX(55deg) translateY(0);
background-image:
linear-gradient(rgba(255,0,200,0.7) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,0,200,0.7) 1px, transparent 1px);
background-size: 60px 60px;
animation: nn-syn-gridscroll 1.5s linear infinite;
}
@keyframes nn-syn-gridscroll {
from { background-position: 0 0; }
to { background-position: 0 60px; }
}
.nn-syn .grid-fade {
position: absolute;
inset: 0;
background:
linear-gradient(180deg, rgba(10,0,21,0.0) 0%, rgba(10,0,21,0.95) 100%),
linear-gradient(90deg, rgba(10,0,21,0.8) 0%, transparent 15%, transparent 85%, rgba(10,0,21,0.8) 100%);
pointer-events: none;
}
.nn-syn .mountains {
position: absolute;
left: 0;
right: 0;
top: 43%;
height: 18%;
overflow: hidden;
}
.nn-syn .mountains svg { width: 100%; height: 100%; }
.nn-syn .scanlines {
position: absolute;
inset: 0;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0,0,0,0.06) 2px,
rgba(0,0,0,0.06) 3px
);
pointer-events: none;
z-index: 10;
}
.nn-syn .title-wrap {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-bottom: 80px;
z-index: 5;
}
.nn-syn .title-main {
font-family: 'Oxanium', sans-serif;
font-size: 56px;
font-weight: 800;
letter-spacing: 0.18em;
color: #fff;
text-shadow:
0 0 6px #fff,
0 0 16px #ff69d0,
0 0 36px #ff2aff,
0 0 70px rgba(200,0,255,0.7);
animation: nn-syn-titlebreath 3s ease-in-out infinite;
}
.nn-syn .title-sub {
font-family: 'Audiowide', cursive;
font-size: 13px;
letter-spacing: 0.55em;
color: rgba(255,150,230,0.85);
text-shadow: 0 0 8px rgba(255,50,200,0.7), 0 0 20px rgba(255,0,200,0.4);
margin-top: 6px;
text-transform: uppercase;
}
@keyframes nn-syn-titlebreath {
0%, 100% { opacity: 1; }
50% { opacity: 0.88; }
}
.nn-syn .year {
font-family: 'Audiowide', cursive;
font-size: 11px;
letter-spacing: 0.3em;
color: rgba(255,220,0,0.8);
text-shadow: 0 0 10px rgba(255,200,0,0.7);
margin-top: 10px;
}
@media (max-width: 720px) {
.nn-syn .scene { width: 100%; height: 380px; }
.nn-syn .title-main { font-size: 40px; }
.nn-syn .sun-wrap { width: 120px; height: 120px; }
}
@media (prefers-reduced-motion: reduce) {
.nn-syn .star,
.nn-syn .sun,
.nn-syn .grid,
.nn-syn .title-main { animation: none !important; }
}