From 52585dd3e73b09fb797625133d843825f29dd65f Mon Sep 17 00:00:00 2001 From: Frank Tovar Date: Sat, 21 Mar 2026 13:34:24 +0100 Subject: [PATCH] Strengthen visible theme mode styling --- ...s_frontend_overhaul_implementation_plan.md | 2 + src/RolemasterDb.App/wwwroot/app.css | 90 ++++++++++++++----- 2 files changed, 71 insertions(+), 21 deletions(-) diff --git a/docs/tables_frontend_overhaul_implementation_plan.md b/docs/tables_frontend_overhaul_implementation_plan.md index ae93d79..0725e60 100644 --- a/docs/tables_frontend_overhaul_implementation_plan.md +++ b/docs/tables_frontend_overhaul_implementation_plan.md @@ -47,6 +47,7 @@ It is intentionally implementation-focused: | 2026-03-21 | P1.7 | Completed | Added a shell-level skip link and tightened the top-level header, navigation, and main landmarks around the new shell structure. | | 2026-03-21 | P1.8 | Completed | Introduced a cooler tooling emphasis for `Tools`, diagnostics, and API surfaces, and styled the `Tools` destination as distinct without splitting the shell. | | 2026-03-21 | Post-P1 fix 1 | Completed | Closed the 768px-1023px navigation gap by adding a shell hamburger menu and drawer so primary navigation never disappears at tablet widths. | +| 2026-03-21 | Post-P1 fix 2 | Completed | Replaced the most visible light-only surface and control colors with theme-aware tokens so switching between `Light`, `Dark`, and `System` produces a clear visual change. | ### Lessons Learned @@ -63,6 +64,7 @@ It is intentionally implementation-focused: - Accessibility work is cheaper when the shell owns the landmarks. Adding skip links and nav/main structure at the shell layer avoids repeating that work page by page. - Tooling can feel distinct through cooler surfaces and labeling alone. A separate app shell is unnecessary and would undermine the shared-product goal. - Responsive shell design needs an explicit tablet state, not just desktop and phone states. The original breakpoints left a navigation dead zone between the top nav and bottom nav layouts. +- Theme infrastructure is not enough on its own. Any surface that keeps hardcoded light values will make the theme switch feel broken even when the selector logic is correct. ## Target Outcomes diff --git a/src/RolemasterDb.App/wwwroot/app.css b/src/RolemasterDb.App/wwwroot/app.css index 39371a7..fce926b 100644 --- a/src/RolemasterDb.App/wwwroot/app.css +++ b/src/RolemasterDb.App/wwwroot/app.css @@ -35,6 +35,22 @@ --info-1: #e5eef4; --info-2: #9fb8c8; --info-3: #4f7086; + --bg-radial-glow: rgba(240, 223, 185, 0.55); + --bg-canvas-end: #e2d3b7; + --surface-card: rgba(255, 255, 255, 0.72); + --surface-card-strong: rgba(255, 255, 255, 0.85); + --surface-inline: rgba(255, 250, 240, 0.72); + --surface-input: rgba(255, 252, 247, 0.92); + --surface-input-hover: rgba(255, 248, 236, 0.98); + --surface-subtle-accent: rgba(255, 250, 242, 0.84); + --surface-chip: rgba(238, 223, 193, 0.65); + --surface-callout: rgba(255, 247, 230, 0.76); + --field-label-color: #75562f; + --link-hover: #6e4320; + --button-secondary-bg: rgba(255, 248, 236, 0.9); + --button-secondary-bg-hover: rgba(250, 236, 210, 0.95); + --button-secondary-text: #6a4b28; + --button-secondary-border: rgba(127, 96, 55, 0.18); --font-display: "Fraunces", Georgia, serif; --font-body: "IBM Plex Sans", "Segoe UI", sans-serif; --font-ui: "IBM Plex Sans", "Segoe UI", sans-serif; @@ -95,6 +111,22 @@ --info-1: #18252f; --info-2: #45677d; --info-3: #9ec0d5; + --bg-radial-glow: rgba(237, 181, 109, 0.12); + --bg-canvas-end: #090807; + --surface-card: rgba(32, 28, 25, 0.9); + --surface-card-strong: rgba(24, 21, 19, 0.94); + --surface-inline: rgba(40, 34, 30, 0.9); + --surface-input: rgba(29, 25, 22, 0.94); + --surface-input-hover: rgba(39, 33, 29, 0.98); + --surface-subtle-accent: rgba(48, 39, 32, 0.84); + --surface-chip: rgba(78, 62, 46, 0.76); + --surface-callout: rgba(56, 42, 28, 0.8); + --field-label-color: #d2b28b; + --link-hover: #f5c487; + --button-secondary-bg: rgba(40, 34, 30, 0.94); + --button-secondary-bg-hover: rgba(52, 44, 38, 0.98); + --button-secondary-text: #f0ddc8; + --button-secondary-border: rgba(209, 188, 163, 0.2); } @media (prefers-color-scheme: dark) { @@ -137,14 +169,30 @@ --info-1: #18252f; --info-2: #45677d; --info-3: #9ec0d5; + --bg-radial-glow: rgba(237, 181, 109, 0.12); + --bg-canvas-end: #090807; + --surface-card: rgba(32, 28, 25, 0.9); + --surface-card-strong: rgba(24, 21, 19, 0.94); + --surface-inline: rgba(40, 34, 30, 0.9); + --surface-input: rgba(29, 25, 22, 0.94); + --surface-input-hover: rgba(39, 33, 29, 0.98); + --surface-subtle-accent: rgba(48, 39, 32, 0.84); + --surface-chip: rgba(78, 62, 46, 0.76); + --surface-callout: rgba(56, 42, 28, 0.8); + --field-label-color: #d2b28b; + --link-hover: #f5c487; + --button-secondary-bg: rgba(40, 34, 30, 0.94); + --button-secondary-bg-hover: rgba(52, 44, 38, 0.98); + --button-secondary-text: #f0ddc8; + --button-secondary-border: rgba(209, 188, 163, 0.2); } } html, body { min-height: 100%; background: - radial-gradient(circle at top, rgba(240, 223, 185, 0.55), transparent 28%), - linear-gradient(180deg, var(--bg-canvas-strong) 0%, var(--bg-canvas) 38%, #e2d3b7 100%); + radial-gradient(circle at top, var(--bg-radial-glow), transparent 28%), + linear-gradient(180deg, var(--bg-canvas-strong) 0%, var(--bg-canvas) 38%, var(--bg-canvas-end) 100%); color: var(--text-primary); font-family: var(--font-body); font-weight: 400; @@ -203,7 +251,7 @@ a, .btn-link { } a:hover { - color: #6e4320; + color: var(--link-hover); } button, @@ -288,16 +336,16 @@ pre, font-size: 0.85rem; letter-spacing: 0.08em; text-transform: uppercase; - color: #75562f; + color: var(--field-label-color); } .input-shell { width: 100%; border-radius: 14px; - border: 1px solid rgba(127, 96, 55, 0.2); - background: rgba(255, 252, 247, 0.92); + border: 1px solid var(--button-secondary-border); + background: var(--surface-input); padding: 0.8rem 0.9rem; - color: var(--ink); + color: var(--text-primary); box-sizing: border-box; } @@ -331,14 +379,14 @@ pre, flex: 0 0 auto; min-width: 4.5rem; border-radius: 14px; - border: 1px solid rgba(127, 96, 55, 0.18); - background: rgba(255, 248, 236, 0.9); - color: #6a4b28; + border: 1px solid var(--button-secondary-border); + background: var(--button-secondary-bg); + color: var(--button-secondary-text); padding: 0.8rem 0.95rem; } .roll-button:hover { - background: rgba(250, 236, 210, 0.95); + background: var(--button-secondary-bg-hover); } .lookup-roll-note { @@ -361,8 +409,8 @@ pre, border-radius: 999px; border: 1px solid rgba(143, 90, 47, 0.18); padding: 0.4rem 0.7rem; - background: rgba(255, 250, 242, 0.84); - color: #5d4429; + background: var(--surface-subtle-accent); + color: var(--text-primary); font-size: 0.82rem; } @@ -375,7 +423,7 @@ pre, .result-card { border-radius: 20px; padding: 1rem; - background: rgba(255, 255, 255, 0.72); + background: var(--surface-card); border: 1px solid rgba(127, 96, 55, 0.14); } @@ -397,12 +445,12 @@ pre, gap: 0.15rem; padding: 0.65rem 0.75rem; border-radius: 14px; - background: rgba(255, 250, 240, 0.72); + background: var(--surface-inline); border: 1px solid rgba(127, 96, 55, 0.12); } .detail-label { - color: #75562f; + color: var(--field-label-color); font-size: 0.76rem; letter-spacing: 0.08em; text-transform: uppercase; @@ -418,8 +466,8 @@ pre, .stat-pill { border-radius: 999px; padding: 0.35rem 0.65rem; - background: rgba(238, 223, 193, 0.65); - color: #5b4327; + background: var(--surface-chip); + color: var(--text-primary); font-size: 0.85rem; } @@ -427,9 +475,9 @@ pre, margin-top: 0.9rem; padding: 0.85rem 0.95rem; border-radius: 16px; - background: rgba(255, 247, 230, 0.76); + background: var(--surface-callout); border: 1px solid rgba(184, 121, 59, 0.18); - color: #5b4327; + color: var(--text-primary); } .branch-list { @@ -862,7 +910,7 @@ pre, .table-shell { border-radius: 20px; padding: 1.2rem; - background: rgba(255, 255, 255, 0.85); + background: var(--surface-card-strong); border: 1px solid rgba(127, 96, 55, 0.2); box-shadow: 0 18px 30px rgba(41, 22, 11, 0.08); }