Storytell
by SvennMats
HTML
<!-- JSFiddle: HTML-panel
External resources (legg til under Resources i JSFiddle):
- https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;700;800;900&family=Inter:wght@400;500;600&display=swap
- https://player.vimeo.com/api/player.js
-->
<!-- NAVBAR ================================================= -->
<div class="svenn-wrapper">
<div class="navbar-sticky">
<nav class="navbar">
<a href="https://svenn.com/" class="nav-logo">
<img src="https://cdn.sanity.io/images/kczjvvqi/production/d4c9c4e2d4f06a0c4d93b32b2fb64d5eede8a513-300x150.png" alt="Svenn Logo">
</a>
<input type="checkbox" id="mobile-menu" class="mobile-menu-toggle">
<label for="mobile-menu" class="mobile-menu-icon">☰</label>
<div class="nav-menu">
<div class="nav-links">
<div class="nav-dropdown">
<input type="checkbox" id="verktøy-toggle" class="dropdown-toggle">
<label for="verktøy-toggle" class="dropdown-label">Verktøy ▾</label>
<div class="nav-dropdown-menu two-columns">
<a href="https://svenn.com/kalkulasjon" class="has-icon"><div class="dropdown-icon"><svg viewBox="-2 -2 24 24" fill="currentColor"><path d="M8.88 9.44c.05 0 .1-.02.13-.05.03-.04.05-.09.05-.14V1.44c0-.05-.02-.1-.05-.13A.18.18 0 008.88 1.25H4.04c-.74 0-1.45.29-1.97.82C1.54 2.59 1.25 3.3 1.25 4.04v5.21c0 .05.02.1.05.14.04.03.08.05.14.05h7.44zM7.02 6.46H5.9c-.05 0-.1.02-.13.06-.04.03-.05.08-.05.13v1.12c0 .15-.06.29-.16.39-.1.11-.25.16-.4.16-.15 0-.29-.05-.4-.16a.54.54 0 01-.16-.39V6.65c0-.05-.02-.1-.05-.13a.18.18 0 00-.13-.06H3.3c-.15 0-.29-.06-.4-.16a.54.54 0 01-.16-.4c0-.15.06-.29.16-.4.1-.1.25-.16.4-.16h1.12c.05 0 .1-.02.13-.05.04-.03.05-.08.05-.13V4.04c0-.15.06-.29.16-.4.1-.1.25-.16.4-.16.15 0 .29.06.4.16.1.1.16.25.16.4v1.12c0 .05.02.1.05.13.04.04.08.05.13.05h1.12c.15 0 .29.06.4.16.1.1.16.25.16.4 0 .15-.06.29-.16.4-.1.1-.25.16-.4.16z"></path><path d="M10.19 9.26c0...
CSS
/* =========================================
SKJUL GAMMEL MENY (Sanity/CMS-spesifikt)
========================================= */
.Header_header__qBw1J { display: none; }
.PageTransition_page__XtMgn { padding-top: 0px; }
.TopHeader_topHeader__content__cPDXk { display: none; }
/* =========================================
GLOBALE STILER
========================================= */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { background: #0d0b10; }
body { min-height: 100vh; background: #0d0b10; overflow-x: hidden; }
:root {
--orange: #F96529;
--yellow: #F5E871;
--green: #BDE37C;
--dark: #241D2D;
--dark-rgb: 36, 29, 45;
--display: 'Outfit', system-ui, sans-serif;
--body: 'Inter', system-ui, sans-serif;
}
/* =========================================
NAVBAR
========================================= */
.svenn-wrapper { font-family: 'Outfit', system-ui, sans-serif; color: #241D2D; background: transparent; padding-bottom: 0; overflow: visible; }
.svenn-wrapper .navbar-sticky { position: fixed; top: 0; z-index: 1000; width: 100%; background-color: #F4F6FB; animation: scrollNavbar linear both; animation-timeline: scroll(); animation-range: 0px 120px; }
@keyframes scrollNavbar { to { background-color: #FFFFFF; box-shadow: 0 4px 20px rgba(36,29,45,0.08); } }
.svenn-wrapper .navbar { display: flex; justify-content: space-between; align-items: center; padding: 16px 40px; max-width: 1200px; margin: 0 auto; gap: 40px; }
.svenn-wrapper .nav-logo { display: flex; align-items: center; text-decoration: none; flex-shrink: 0; }
.svenn-wrapper .nav-logo img { height: 30px; width: auto; display: block; }
.svenn-wrapper .nav-menu { display: flex; align-items: center; flex: 1; justify-content: space-between; }
.svenn-wrapper .nav-links { display: flex; gap: 32px; align-items: center; }
.svenn-wrapper .nav-links a { text-decoration: none; color: #241D2D; font-size: 16px;...
JavaScript
const sections = document.querySelectorAll('.section');
const sectionArr = Array.from(sections);
const bgImgs = document.querySelectorAll('.bg__img');
const bgVideo = document.getElementById('bg-video');
const bgDark = document.getElementById('bg-dark');
const progress = document.getElementById('progress');
// Slides 0–2 bruker video. Slide 3+ bruker stillbilde.
const VIDEO_SLIDES = 3;
// Eksplisitt mapping: slide → bg img-indeks (9 slides totalt)
const BG_MAP = [0, 0, 0, 3, 3, 5, 5, 6, 6];
let lastIndex = -1;
function bgImgIndex(i) {
return BG_MAP[i] ?? 0;
}
function activateBg(index, prevIndex) {
const useVideo = index < VIDEO_SLIDES;
const wasVideo = prevIndex < VIDEO_SLIDES;
const isLeavingVideo = wasVideo && !useVideo;
bgVideo.classList.toggle('is-active', useVideo);
const imgIdx = bgImgIndex(index);
const overlay = sectionArr[index]?.dataset.overlay || 'normal';
if (overlay === 'dark') {
bgDark.style.transition = 'none';
bgDark.style.opacity = '1';
requestAnimationFrame(() => requestAnimationFrame(() => {
bgImgs.forEach((img, i) => {
if (isLeavingVideo && i === 0) return;
img.classList.toggle('is-active', i === imgIdx);
});
bgDark.style.transition = 'opacity 0.7s ease';
}));
} else {
bgImgs.forEach((img, i) => {
if (isLeavingVideo && i === 0) return;
img.classList.toggle('is-active', i === imgIdx);
});
bgDark.style.transition = 'opacity 0.7s ease';
bgDark.style.opacity = overlay === 'medium' ? '0.6' : '0';
}
if (isLeavingVideo) {
setTimeout(() => bgImgs[0].classList.remove('is-active'), 950);
}
}
function onScroll() {
const scrollY = window.scrollY;
const vh = window.innerHeight;
const index = Math.max(0, Math.min(Math.round(scrollY / vh), sectionArr.length - 1));
if (index !== lastIndex) {
const prevIndex = lastIndex;
lastIndex =...