System default.
Voltage on.
Heat rising.
Back to source.
// Mechanisme: content-theme-section-kinetic (techniek #10 — theme-shift on scroll)
// IntersectionObserver per sectie -> CSS custom-property swap (--bg/--fg/--accent) op .theme-stage.
// Snappy 0.4s power4.out transition op CSS-vars. Vier paletten: ink -> acid -> coral -> ink-end.
// Reduced-motion: zet eindstate (laatste palette), geen transitions.
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const stage = document.querySelector('.theme-stage');
const palettes = {
ink: { bg: '#0A0A0A', fg: '#F4F1EB', accent: '#FFE600' },
acid: { bg: '#FFE600', fg: '#0A0A0A', accent: '#FF4D2E' },
coral: { bg: '#FF4D2E', fg: '#0A0A0A', accent: '#FFE600' },
end: { bg: '#0A0A0A', fg: '#FFE600', accent: '#FF4D2E' },
};
const apply = (key) => {
const p = palettes[key]; if (!p || !stage) return;
stage.style.setProperty('--bg', p.bg);
stage.style.setProperty('--fg', p.fg);
stage.style.setProperty('--accent', p.accent);
};
if (stage) {
const sections = stage.querySelectorAll('[data-palette]');
if (reduce) {
apply(sections[sections.length - 1]?.dataset.palette || 'ink');
} else {
apply('ink');
const io = new IntersectionObserver((entries) => {
entries.forEach(e => { if (e.isIntersecting) apply(e.target.dataset.palette); });
}, { threshold: 0.55 });
sections.forEach(s => io.observe(s));
}
} <!-- Skeleton: content-theme-section-kinetic --> <div class="theme-stage"> <section data-palette="ink"><h2>BLACK</h2><p>System default.</p></section> <section data-palette="acid"><h2>ACID</h2><p>Voltage on.</p></section> <section data-palette="coral"><h2>CORAL</h2><p>Heat rising.</p></section> <section data-palette="end"><h2>RESET</h2><p>Back to source.</p></section> </div>
/* Styling: content-theme-section-kinetic — Archivo Black, oversize, snappy 0.4s */
.theme-stage {
--bg: #0A0A0A;
--fg: #F4F1EB;
--accent: #FFE600;
background: var(--bg);
color: var(--fg);
transition: background 0.4s cubic-bezier(.7,0,.2,1), color 0.4s cubic-bezier(.7,0,.2,1);
font-family: 'Archivo Black', 'Anton', 'Archivo', sans-serif;
}
.theme-stage section {
min-height: 100vh;
display: grid;
place-content: center;
padding: clamp(3rem, 8vw, 6rem);
}
.theme-stage h2 {
font-size: clamp(5rem, 18vw, 16rem);
line-height: 0.85;
letter-spacing: -0.04em;
margin: 0;
text-transform: uppercase;
}
.theme-stage h2 .dot {
display: inline-block;
width: 0.6em; height: 0.15em;
background: var(--accent);
margin-left: 0.2em;
vertical-align: 0.2em;
transition: background 0.4s;
}
.theme-stage p {
font-family: 'Archivo', sans-serif;
font-weight: 700;
font-size: clamp(1rem, 1.5vw, 1.4rem);
letter-spacing: 0.04em;
text-transform: uppercase;
margin: 1.5rem 0 0;
}