Add dark mode with OS preference detection and manual toggle
- CSS token overrides (--ink, --rule, --bg-off, etc.) on html.dark - Explicit fixes for hardcoded values: nav blur bg, btn-dark inverts to light button, industry cells, kit icons, footer link colour - Sun/moon toggle button in every page's nav - Tiny inline FOUC-prevention script in <head> reads localStorage then falls back to prefers-color-scheme; toggle persists choice Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,9 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script>
|
||||||
|
(function(){var t=localStorage.getItem('theme'),d=window.matchMedia('(prefers-color-scheme: dark)').matches;if(t==='dark'||(t===null&&d))document.documentElement.classList.add('dark');})();
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@@ -30,6 +33,10 @@
|
|||||||
<a href="consultancy.html" class="active">Consultancy</a>
|
<a href="consultancy.html" class="active">Consultancy</a>
|
||||||
<a href="videos.html">Videos</a>
|
<a href="videos.html">Videos</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<button id="theme-toggle" class="theme-toggle" aria-label="Toggle dark mode">
|
||||||
|
<svg class="icon-moon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg>
|
||||||
|
<svg class="icon-sun" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
|
||||||
|
</button>
|
||||||
<a href="mailto:bournemouthtech@protonmail.com" class="btn btn-dark btn-sm">Get in touch</a>
|
<a href="mailto:bournemouthtech@protonmail.com" class="btn btn-dark btn-sm">Get in touch</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -287,5 +294,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById('theme-toggle').addEventListener('click', function() {
|
||||||
|
var dark = document.documentElement.classList.toggle('dark');
|
||||||
|
localStorage.setItem('theme', dark ? 'dark' : 'light');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
13
devkits.html
13
devkits.html
@@ -9,6 +9,9 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script>
|
||||||
|
(function(){var t=localStorage.getItem('theme'),d=window.matchMedia('(prefers-color-scheme: dark)').matches;if(t==='dark'||(t===null&&d))document.documentElement.classList.add('dark');})();
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@@ -30,6 +33,10 @@
|
|||||||
<a href="consultancy.html">Consultancy</a>
|
<a href="consultancy.html">Consultancy</a>
|
||||||
<a href="videos.html">Videos</a>
|
<a href="videos.html">Videos</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<button id="theme-toggle" class="theme-toggle" aria-label="Toggle dark mode">
|
||||||
|
<svg class="icon-moon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg>
|
||||||
|
<svg class="icon-sun" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
|
||||||
|
</button>
|
||||||
<a href="#products" class="btn btn-dark btn-sm">Buy a devkit</a>
|
<a href="#products" class="btn btn-dark btn-sm">Buy a devkit</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -319,5 +326,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById('theme-toggle').addEventListener('click', function() {
|
||||||
|
var dark = document.documentElement.classList.toggle('dark');
|
||||||
|
localStorage.setItem('theme', dark ? 'dark' : 'light');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
13
index.html
13
index.html
@@ -9,6 +9,9 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script>
|
||||||
|
(function(){var t=localStorage.getItem('theme'),d=window.matchMedia('(prefers-color-scheme: dark)').matches;if(t==='dark'||(t===null&&d))document.documentElement.classList.add('dark');})();
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@@ -30,6 +33,10 @@
|
|||||||
<a href="consultancy.html">Consultancy</a>
|
<a href="consultancy.html">Consultancy</a>
|
||||||
<a href="videos.html">Videos</a>
|
<a href="videos.html">Videos</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<button id="theme-toggle" class="theme-toggle" aria-label="Toggle dark mode">
|
||||||
|
<svg class="icon-moon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg>
|
||||||
|
<svg class="icon-sun" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
|
||||||
|
</button>
|
||||||
<a href="devkits.html" class="btn btn-dark btn-sm">Buy a devkit</a>
|
<a href="devkits.html" class="btn btn-dark btn-sm">Buy a devkit</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -324,5 +331,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById('theme-toggle').addEventListener('click', function() {
|
||||||
|
var dark = document.documentElement.classList.toggle('dark');
|
||||||
|
localStorage.setItem('theme', dark ? 'dark' : 'light');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script>
|
||||||
|
(function(){var t=localStorage.getItem('theme'),d=window.matchMedia('(prefers-color-scheme: dark)').matches;if(t==='dark'||(t===null&&d))document.documentElement.classList.add('dark');})();
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@@ -30,6 +33,10 @@
|
|||||||
<a href="consultancy.html">Consultancy</a>
|
<a href="consultancy.html">Consultancy</a>
|
||||||
<a href="videos.html">Videos</a>
|
<a href="videos.html">Videos</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<button id="theme-toggle" class="theme-toggle" aria-label="Toggle dark mode">
|
||||||
|
<svg class="icon-moon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg>
|
||||||
|
<svg class="icon-sun" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
|
||||||
|
</button>
|
||||||
<a href="devkits.html" class="btn btn-dark btn-sm">Buy a devkit</a>
|
<a href="devkits.html" class="btn btn-dark btn-sm">Buy a devkit</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -368,5 +375,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById('theme-toggle').addEventListener('click', function() {
|
||||||
|
var dark = document.documentElement.classList.toggle('dark');
|
||||||
|
localStorage.setItem('theme', dark ? 'dark' : 'light');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
92
style.css
92
style.css
@@ -1011,3 +1011,95 @@ footer {
|
|||||||
.hero-ctas .btn { justify-content: center; }
|
.hero-ctas .btn { justify-content: center; }
|
||||||
.price-block { flex-direction: column; align-items: flex-start; }
|
.price-block { flex-direction: column; align-items: flex-start; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Dark mode toggle button ─────────────────── */
|
||||||
|
.theme-toggle {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid var(--rule);
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--ink-3);
|
||||||
|
flex-shrink: 0;
|
||||||
|
transition: color 0.15s, border-color 0.15s;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.theme-toggle:hover { color: var(--ink); border-color: var(--ink-3); }
|
||||||
|
.theme-toggle .icon-sun { display: none; }
|
||||||
|
.theme-toggle .icon-moon { display: block; }
|
||||||
|
|
||||||
|
/* ── Dark mode ───────────────────────────────── */
|
||||||
|
html.dark {
|
||||||
|
color-scheme: dark;
|
||||||
|
--ink: #F0F0ED;
|
||||||
|
--ink-2: #A8A8A2;
|
||||||
|
--ink-3: #686864;
|
||||||
|
--ink-4: #4E4E4A;
|
||||||
|
--ink-5: #9A9A94;
|
||||||
|
--rule: #2C2C2A;
|
||||||
|
--rule-2: #232321;
|
||||||
|
--bg-off: #161615;
|
||||||
|
--dark-bg: #050504;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark ::selection { background: #F0F0ED; color: #0A0A0A; }
|
||||||
|
|
||||||
|
html.dark body {
|
||||||
|
background: #0F0F0E;
|
||||||
|
color: #F0F0ED;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark .nav {
|
||||||
|
background: rgba(15,15,14,0.88);
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark .theme-toggle .icon-sun { display: block; }
|
||||||
|
html.dark .theme-toggle .icon-moon { display: none; }
|
||||||
|
|
||||||
|
html.dark .btn-dark {
|
||||||
|
background: #F0F0ED;
|
||||||
|
color: #0A0A0A;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark .btn-outline {
|
||||||
|
background: transparent;
|
||||||
|
border-color: #3A3A38;
|
||||||
|
color: #F0F0ED;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark .btn-outline:hover { border-color: #F0F0ED; }
|
||||||
|
|
||||||
|
html.dark .industry-cell { background: #0F0F0E; }
|
||||||
|
html.dark .section-off .industry-cell { background: #161615; }
|
||||||
|
|
||||||
|
html.dark .kit-item-icon {
|
||||||
|
background: #2C2C2A;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark .footer-col-links { color: #9A9A94; }
|
||||||
|
|
||||||
|
html.dark .hero-links a { border-bottom-color: #3A3A38; }
|
||||||
|
|
||||||
|
html.dark .img-slot {
|
||||||
|
background: #161615;
|
||||||
|
border-color: #2C2C2A;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark .product-card.featured {
|
||||||
|
background: #F0F0ED;
|
||||||
|
color: #0A0A0A;
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
html.dark .product-card.featured .product-card-tag { color: rgba(10,10,10,0.5); }
|
||||||
|
html.dark .product-card.featured .product-desc { color: rgba(10,10,10,0.7); }
|
||||||
|
html.dark .product-card.featured .product-features { color: rgba(10,10,10,0.85); }
|
||||||
|
html.dark .product-card.featured .product-price { color: #0A0A0A; }
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html:not([data-theme="light"]):not(.dark) { /* auto-apply if JS hasn't run yet */ }
|
||||||
|
}
|
||||||
|
|||||||
13
videos.html
13
videos.html
@@ -9,6 +9,9 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script>
|
||||||
|
(function(){var t=localStorage.getItem('theme'),d=window.matchMedia('(prefers-color-scheme: dark)').matches;if(t==='dark'||(t===null&&d))document.documentElement.classList.add('dark');})();
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@@ -30,6 +33,10 @@
|
|||||||
<a href="consultancy.html">Consultancy</a>
|
<a href="consultancy.html">Consultancy</a>
|
||||||
<a href="videos.html" class="active">Videos</a>
|
<a href="videos.html" class="active">Videos</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<button id="theme-toggle" class="theme-toggle" aria-label="Toggle dark mode">
|
||||||
|
<svg class="icon-moon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/></svg>
|
||||||
|
<svg class="icon-sun" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
|
||||||
|
</button>
|
||||||
<a href="devkits.html" class="btn btn-dark btn-sm">Buy a devkit</a>
|
<a href="devkits.html" class="btn btn-dark btn-sm">Buy a devkit</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -407,5 +414,11 @@
|
|||||||
video.addEventListener('ended', function() { overlay.style.opacity = '1'; overlay.style.pointerEvents = 'auto'; });
|
video.addEventListener('ended', function() { overlay.style.opacity = '1'; overlay.style.pointerEvents = 'auto'; });
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
document.getElementById('theme-toggle').addEventListener('click', function() {
|
||||||
|
var dark = document.documentElement.classList.toggle('dark');
|
||||||
|
localStorage.setItem('theme', dark ? 'dark' : 'light');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user