Use style tag with !important for accent color persistence

Inline style attribute on <html> gets stripped during page load.
Switch to injecting a <style id="umbra-accent"> tag with !important
CSS custom properties which persists in the DOM and beats @layer base
defaults. useTheme updates the same style tag when settings load.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kyle 2026-03-12 20:29:53 +08:00
parent fce7405b14
commit b202ee1a84
2 changed files with 14 additions and 13 deletions

View File

@ -9,9 +9,9 @@
<meta name="mobile-web-app-capable" content="yes" /> <meta name="mobile-web-app-capable" content="yes" />
<title>UMBRA</title> <title>UMBRA</title>
<script> <script>
// Apply accent color with !important inline styles — highest CSS priority. // Inject a <style> tag with !important accent color vars.
// Beats all stylesheet rules regardless of @layer, specificity, or source order. // Inline style attr gets stripped during page load (unknown cause),
// useTheme.ts updates these with !important when settings load from the API. // but a <style> tag with !important persists and beats @layer base defaults.
(function() { (function() {
var h = '187', s = '85.7%', l = '53.3%'; var h = '187', s = '85.7%', l = '53.3%';
try { try {
@ -23,10 +23,10 @@
if (p.l) l = p.l; if (p.l) l = p.l;
} }
} catch(e) {} } catch(e) {}
var d = document.documentElement.style; var el = document.createElement('style');
d.setProperty('--accent-h', h, 'important'); el.id = 'umbra-accent';
d.setProperty('--accent-s', s, 'important'); el.textContent = ':root{--accent-h:' + h + ' !important;--accent-s:' + s + ' !important;--accent-l:' + l + ' !important}';
d.setProperty('--accent-l', l, 'important'); document.head.appendChild(el);
})(); })();
</script> </script>
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />

View File

@ -16,8 +16,8 @@ export function useTheme() {
const { settings } = useSettings(); const { settings } = useSettings();
// Only apply accent color once settings have loaded from the API. // Only apply accent color once settings have loaded from the API.
// The inline script in index.html handles initial paint from localStorage. // Updates the <style id="umbra-accent"> tag injected by index.html.
// Both use !important inline styles — the highest CSS cascade priority. // Uses !important to beat @layer base defaults in the stylesheet.
useEffect(() => { useEffect(() => {
if (!settings) return; if (!settings) return;
@ -29,10 +29,11 @@ export function useTheme() {
const s = `${preset.s}%`; const s = `${preset.s}%`;
const l = `${preset.l}%`; const l = `${preset.l}%`;
const d = document.documentElement.style; // Update the persistent <style> tag (inline style attr gets stripped)
d.setProperty('--accent-h', h, 'important'); const el = document.getElementById('umbra-accent');
d.setProperty('--accent-s', s, 'important'); if (el) {
d.setProperty('--accent-l', l, 'important'); el.textContent = `:root{--accent-h:${h} !important;--accent-s:${s} !important;--accent-l:${l} !important}`;
}
try { try {
localStorage.setItem('umbra-accent-color', JSON.stringify({ h, s, l })); localStorage.setItem('umbra-accent-color', JSON.stringify({ h, s, l }));