diff --git a/src/components/UtilityBar.astro b/src/components/UtilityBar.astro
index 277ab87..3be6039 100644
--- a/src/components/UtilityBar.astro
+++ b/src/components/UtilityBar.astro
@@ -64,7 +64,12 @@ const email = site?.data?.email ?? 'contact@moreminimore.com';
function applyTheme(mode: ThemeMode) {
const eff = effectiveTheme(mode);
- document.documentElement.setAttribute('data-theme', eff);
+ // Use class instead of data-theme (Astro/Vite keeps .dark selectors)
+ if (eff === 'dark') {
+ document.documentElement.classList.add('dark');
+ } else {
+ document.documentElement.classList.remove('dark');
+ }
const indicator = document.getElementById('fx-mode-indicator');
const btn = document.getElementById('fx-theme-toggle');
if (indicator) indicator.textContent = mode; // shows user's chosen mode (not effective)
diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro
index f7e2b92..fc67f2f 100644
--- a/src/layouts/Base.astro
+++ b/src/layouts/Base.astro
@@ -38,10 +38,13 @@ const {
{title}
-
+ Inline (no defer) is intentional — must run synchronously.
+ NOTE: We use .dark class instead of data-theme="dark" because
+ Astro/Vite CSS optimizer strips [data-theme="..."] selectors
+ that don't match any static HTML (we set it dynamically via JS). -->
diff --git a/src/styles/fx-system.css b/src/styles/fx-system.css
index 43703dd..89118d2 100644
--- a/src/styles/fx-system.css
+++ b/src/styles/fx-system.css
@@ -248,9 +248,10 @@ img{max-width:100%;display:block}
.fx-utility-bar-left,.fx-utility-bar-right{display:flex;align-items:center;gap:16px}
.fx-utility-item{display:inline-flex;align-items:center;gap:6px;color:rgba(250,250,250,0.7)}
.fx-utility-item strong{color:var(--brand-yellow);font-weight:700}
-.fx-theme-toggle{display:inline-flex;align-items:center;gap:6px;background:rgba(250,250,250,0.1);border:1px solid rgba(250,250,250,0.2);color:#FAFAFA;padding:4px 10px;font:600 10px/1 'JetBrains Mono',monospace;text-transform:uppercase;border-radius:999px;cursor:pointer}
.fx-mode-indicator{font:500 9px/1 'JetBrains Mono',monospace;color:rgba(250,250,250,0.5)}
.fx-mode-indicator::before{content:'●';color:var(--brand-yellow);margin-right:4px}
+/* .fx-theme-toggle base rule REMOVED — opacity 0.1 background made button invisible.
+ See consolidated rule below with proper contrast for both light/dark modes. */
.fx-marquee{background:var(--paper-2);border-bottom:1.5px solid var(--ink);overflow:hidden;font:700 11px/1 'JetBrains Mono',monospace;padding:6px 0}
.fx-marquee-track{display:flex;gap:32px;white-space:nowrap;animation:marquee 40s linear infinite}
.fx-marquee-track span{color:var(--text-dim)}
@@ -513,9 +514,14 @@ img{max-width:100%;display:block}
--faq-item-bg: rgba(255,255,255,0.7);
/* soft yellow glow for hero side (3D feel) */
--soft-yellow-glow: 6px 6px 0 rgba(255,214,10,0.3);
+ /* Body aliases (mirror global.css --color-white/black for theme parity) */
+ --body-bg: #FFFFFF;
+ --body-fg: #0A0A0A;
+ --card-bg: #FFFFFF;
+ --input-bg: #FFFFFF;
}
-[data-theme="dark"] {
+html.dark {
--ink: #FAFAFA;
--ink-2: #F0F0F0;
--paper: #0A0A0A;
@@ -536,22 +542,66 @@ img{max-width:100%;display:block}
--hero-content-bg: rgba(26,26,26,0.7);
--faq-item-bg: rgba(26,26,26,0.6);
--soft-yellow-glow: 6px 6px 0 rgba(255,214,10,0.2);
+ /* Body aliases (inverted) */
+ --body-bg: #0A0A0A;
+ --body-fg: #FAFAFA;
+ --card-bg: #1A1A1A;
+ --input-bg: #1A1A1A;
/* Coral stays vibrant in dark mode (it's already high-contrast) */
/* Yellow stays vibrant (high luminance) */
}
+/* ============================================
+ BODY / HTML THEME OVERRIDE (added 2026-06-13)
+ global.css sets body { color:var(--color-black); background:var(--color-white); }
+ which keeps body white in dark mode → text from v7-5 sections
+ (which use --ink = cream) becomes invisible on white body.
+ Override body + html here using --body-bg/--body-fg aliases.
+ ============================================ */
+html { background: var(--body-bg); color: var(--body-fg); }
+body { background: var(--body-bg); color: var(--body-fg); }
+
/* Utility bar: use --utility-* vars instead of hardcoded colors */
.fx-utility-bar{background:var(--utility-bg);color:var(--utility-fg)}
.fx-utility-item{color:var(--utility-fg-dim)}
.fx-utility-item strong{color:var(--brand-yellow)}
-.fx-theme-toggle{background:rgba(0,0,0,0.08);border:1px solid rgba(0,0,0,0.15);color:var(--ink)}
-[data-theme="dark"] .fx-theme-toggle{background:rgba(250,250,250,0.08);border:1px solid rgba(250,250,250,0.18);color:var(--ink)}
+/* Theme toggle override REMOVED — see consolidated rule below */
.fx-mode-indicator{color:var(--utility-fg-dimmer)}
-[data-theme="dark"] .fx-mode-indicator{color:var(--utility-fg-dimmer)}
+html.dark .fx-mode-indicator{color:var(--utility-fg-dimmer)}
-/* Theme toggle button itself */
-.fx-theme-toggle{cursor:pointer;user-select:none}
-.fx-theme-toggle:hover{transform:scale(1.05);background:var(--brand-yellow);color:var(--ink)}
+/* Theme toggle button — VISIBLE in both modes (not hidden)
+ Earlier rules used rgba(0.08-0.1) backgrounds which were nearly
+ invisible. User reported: "It is hidden and show when hover only." */
+.fx-theme-toggle{
+ display:inline-flex;
+ align-items:center;
+ gap:6px;
+ /* Light mode utility bar is dark (--utility-bg) — use light fill */
+ background:rgba(255,255,255,0.18);
+ border:1.5px solid rgba(255,255,255,0.35);
+ color:#FAFAFA;
+ padding:4px 10px;
+ font:600 10px/1 'JetBrains Mono',monospace;
+ text-transform:uppercase;
+ border-radius:999px;
+ cursor:pointer;
+ user-select:none;
+ transition:all 0.15s ease;
+ font-weight:700;
+ letter-spacing:0.3px;
+}
+/* Dark mode utility bar is light — use dark fill for contrast */
+html.dark .fx-theme-toggle{
+ background:rgba(10,10,10,0.85);
+ border:1.5px solid rgba(10,10,10,0.5);
+ color:#FAFAFA;
+}
+.fx-theme-toggle:hover{
+ background:var(--brand-yellow);
+ color:var(--ink);
+ border-color:var(--ink);
+ transform:scale(1.05);
+}
/* Nav: use --nav-bg for theme-aware glass */
.fx-nav{background:var(--nav-bg)}
@@ -564,16 +614,32 @@ img{max-width:100%;display:block}
.fx-faq-item{background:var(--faq-item-bg)}
/* Specific dark mode tweaks for elements that need extra contrast */
-[data-theme="dark"] .fx-nav-dropdown{background:var(--paper);border-color:var(--ink)}
-[data-theme="dark"] .fx-pricing-card.featured{background:rgba(255,214,10,0.15)}
-[data-theme="dark"] .fx-callout{background:linear-gradient(180deg,#FFE600,var(--brand-yellow))}
-[data-theme="dark"] .fx-portfolio-card.featured{background:var(--coral);color:#FAFAFA}
-[data-theme="dark"] .fx-portfolio-name{background:var(--ink);color:var(--paper)}
-[data-theme="dark"] .fx-portfolio-card .fx-portfolio-name{color:#FAFAFA;background:var(--ink)}
-[data-theme="dark"] .fx-portfolio-card.featured .fx-portfolio-name{color:var(--brand-yellow);background:var(--ink)}
-[data-theme="dark"] .fx-process-num{background:var(--brand-yellow);color:var(--ink)}
-[data-theme="dark"] .fx-service-num{background:var(--brand-yellow);color:var(--ink)}
-[data-theme="dark"] .fx-prose{color:var(--ink)}
+html.dark body { background: var(--body-bg); color: var(--body-fg); }
+
+/* v7-5 uses rgba(10,10,10,0.3) for dim text (.ts in log + footer-bottom)
+ Invert to cream-equivalent for dark mode */
+html.dark .ts { color: rgba(250,250,250,0.3); }
+html.dark .fx-footer-bottom { color: rgba(250,250,250,0.3); }
+
+/* Coral backgrounds keep their cream text — already high contrast.
+ No override needed for .fx-btn.coral, .fx-nav-cta, .fx-pricing-cta,
+ .fx-service-num, .fx-portfolio-card.featured (all have dark bg + cream text) */
+
+/* Mode indicator: in dark mode, utility bar is light, so indicator should be dark */
+html.dark .fx-mode-indicator { color: rgba(10,10,10,0.5); }
+
+/* Theme toggle override is now consolidated in the .fx-theme-toggle rule
+ below (removed the duplicate low-contrast rules) */
+html.dark .fx-nav-dropdown{background:var(--paper);border-color:var(--ink)}
+html.dark .fx-pricing-card.featured{background:rgba(255,214,10,0.15)}
+html.dark .fx-callout{background:linear-gradient(180deg,#FFE600,var(--brand-yellow))}
+html.dark .fx-portfolio-card.featured{background:var(--coral);color:#FAFAFA}
+html.dark .fx-portfolio-name{background:var(--ink);color:var(--paper)}
+html.dark .fx-portfolio-card .fx-portfolio-name{color:#FAFAFA;background:var(--ink)}
+html.dark .fx-portfolio-card.featured .fx-portfolio-name{color:var(--brand-yellow);background:var(--ink)}
+html.dark .fx-process-num{background:var(--brand-yellow);color:var(--ink)}
+html.dark .fx-service-num{background:var(--brand-yellow);color:var(--ink)}
+html.dark .fx-prose{color:var(--ink)}
/* Smooth theme transition (not too jarring) */
html { transition: background-color 0.3s ease, color 0.3s ease; }