aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-01-20 00:16:14 -0800
committerFuwn <[email protected]>2026-01-20 00:16:14 -0800
commite09fc2af31bf99698d203d0a03e78735b4d5a6b2 (patch)
tree08b2077a70795ad518dc3b785f372190c8251c1f /internal
parentfeat: Improve theme CSS mappings for comprehensive styling (diff)
downloadkaze-e09fc2af31bf99698d203d0a03e78735b4d5a6b2.tar.xz
kaze-e09fc2af31bf99698d203d0a03e78735b4d5a6b2.zip
refactor: Use CSS variable overrides for proper theme integration
Instead of trying to override individual Tailwind classes (which was fragile and incomplete), now properly override Kaze's root CSS variables (--bg-primary, --status-ok, etc.) to use OpenCode theme values. This works because style.css already maps all Tailwind classes to these CSS variables, so overriding the variables automatically themes everything. The theme flow is now: 1. OpenCode theme defines: --theme-background, --theme-success, etc. 2. Override CSS redefines: --bg-primary = var(--theme-background), etc. 3. style.css classes use: background: var(--bg-primary), etc. This approach is much cleaner and ensures complete, consistent theming.
Diffstat (limited to 'internal')
-rw-r--r--internal/server/server.go4
-rw-r--r--internal/theme/theme.go223
2 files changed, 49 insertions, 178 deletions
diff --git a/internal/server/server.go b/internal/server/server.go
index 6d76fa0..8d491dc 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -199,8 +199,8 @@ func (s *Server) handleIndex(w http.ResponseWriter, r *http.Request) {
if err != nil {
s.logger.Warn("failed to load theme", "url", s.config.Site.ThemeURL, "error", err)
} else if resolvedTheme != nil {
- // Generate CSS variables and Tailwind mappings
- cssString := resolvedTheme.GenerateCSS() + resolvedTheme.GenerateTailwindMappings()
+ // Generate CSS: theme variables + override Kaze's CSS variables
+ cssString := resolvedTheme.GenerateCSS() + resolvedTheme.GenerateVariableOverrides()
themeCSS = template.CSS(cssString)
}
}
diff --git a/internal/theme/theme.go b/internal/theme/theme.go
index ac0fff9..ed10f80 100644
--- a/internal/theme/theme.go
+++ b/internal/theme/theme.go
@@ -183,187 +183,58 @@ func GetColorMapping() map[string]string {
}
}
-// GenerateTailwindMappings generates CSS that maps theme variables to Tailwind classes
-func (t *ResolvedTheme) GenerateTailwindMappings() string {
+// GenerateVariableOverrides generates CSS that maps OpenCode theme to Kaze's CSS variables
+// This is the proper approach - override the root CSS variables that style.css uses
+func (t *ResolvedTheme) GenerateVariableOverrides() string {
if t == nil {
return ""
}
return `
-/* OpenCode Theme Tailwind Overrides */
-
-/* ===== Page Background ===== */
-.bg-neutral-50,
-.dark .bg-neutral-950 {
- background-color: var(--theme-background) !important;
-}
-
-/* ===== Panels & Cards ===== */
-/* Group headers */
-.bg-neutral-100,
-.dark .bg-neutral-900 {
- background-color: var(--theme-background-panel) !important;
-}
-
-/* Badges, secondary elements */
-.bg-neutral-200,
-.dark .bg-neutral-800 {
- background-color: var(--theme-background-element) !important;
-}
-
-/* ===== Text Colors ===== */
-/* Primary text */
-.text-neutral-900,
-.text-neutral-950,
-.dark .text-white,
-.dark .text-neutral-100 {
- color: var(--theme-text) !important;
-}
-
-/* Muted/secondary text */
-.text-neutral-500,
-.text-neutral-600,
-.text-neutral-700,
-.dark .text-neutral-400,
-.dark .text-neutral-500 {
- color: var(--theme-text-muted) !important;
-}
-
-/* ===== Borders ===== */
-.border-neutral-200,
-.dark .border-neutral-800 {
- border-color: var(--theme-border) !important;
-}
-
-.divide-neutral-200 > * + *,
-.dark .divide-neutral-800 > * + * {
- border-color: var(--theme-border) !important;
-}
-
-/* ===== Status Colors ===== */
-/* Success/Up - status indicators and text */
-.bg-emerald-500,
-.bg-emerald-500.rounded-full,
-.bg-emerald-500.animate-pulse {
- background-color: var(--theme-success) !important;
-}
-
-.text-emerald-500,
-.text-emerald-600,
-.dark .text-emerald-400 {
- color: var(--theme-success) !important;
-}
-
-/* Status banner - success background */
-.bg-emerald-50,
-.dark .bg-emerald-950\/30 {
- background-color: color-mix(in srgb, var(--theme-success) 10%, transparent) !important;
-}
-
-.border-emerald-200,
-.dark .border-emerald-900 {
- border-color: color-mix(in srgb, var(--theme-success) 30%, var(--theme-border)) !important;
-}
-
-/* Warning/Degraded - status indicators and text */
-.bg-yellow-500,
-.bg-yellow-500.rounded-full {
- background-color: var(--theme-warning) !important;
-}
-
-.text-yellow-500,
-.text-yellow-600,
-.dark .text-yellow-400 {
- color: var(--theme-warning) !important;
-}
-
-/* Status banner - warning background */
-.bg-yellow-50,
-.dark .bg-yellow-950\/30 {
- background-color: color-mix(in srgb, var(--theme-warning) 10%, transparent) !important;
-}
-
-.border-yellow-200,
-.dark .border-yellow-900 {
- border-color: color-mix(in srgb, var(--theme-warning) 30%, var(--theme-border)) !important;
-}
-
-/* Error/Down - status indicators and text */
-.bg-red-500,
-.bg-red-500.rounded-full {
- background-color: var(--theme-error) !important;
-}
-
-.text-red-500,
-.text-red-600,
-.dark .text-red-400 {
- color: var(--theme-error) !important;
-}
-
-/* Status banner - error background */
-.bg-red-50,
-.dark .bg-red-950\/30 {
- background-color: color-mix(in srgb, var(--theme-error) 10%, transparent) !important;
-}
-
-.border-red-200,
-.dark .border-red-900 {
- border-color: color-mix(in srgb, var(--theme-error) 30%, var(--theme-border)) !important;
-}
-
-/* Unknown status */
-.bg-neutral-400.rounded-full {
- background-color: var(--theme-text-muted) !important;
-}
-
-/* ===== Interactive States ===== */
-/* Hover on group headers */
-.hover\:bg-neutral-200:hover,
-.dark .hover\:bg-neutral-800:hover {
- background-color: var(--theme-border) !important;
-}
-
-/* Hover on monitor cards */
-.hover\:bg-neutral-100\/50:hover,
-.dark .hover\:bg-neutral-900\/50:hover {
- background-color: color-mix(in srgb, var(--theme-background-panel) 50%, transparent) !important;
-}
-
-/* ===== SVG Icons ===== */
-.text-neutral-600.transition-transform,
-.dark .text-neutral-400.transition-transform {
- color: var(--theme-text-muted) !important;
-}
-
-/* ===== Tooltip ===== */
-.tooltip {
- background-color: var(--theme-background-panel) !important;
- border-color: var(--theme-border) !important;
- color: var(--theme-text) !important;
-}
-
-.tooltip-header {
- color: var(--theme-text) !important;
-}
-
-.tooltip-label {
- color: var(--theme-text-muted) !important;
-}
-
-.tooltip-value {
- color: var(--theme-text) !important;
-}
-
-.tooltip-value.success {
- color: var(--theme-success) !important;
-}
-
-.tooltip-value.error {
- color: var(--theme-error) !important;
-}
-
-.tooltip-value.warning {
- color: var(--theme-warning) !important;
+/* OpenCode Theme - Override Kaze CSS Variables */
+
+:root, :root:not(.dark) {
+ /* Background colors */
+ --bg-primary: var(--theme-background);
+ --bg-secondary: var(--theme-background-panel);
+ --bg-tertiary: var(--theme-background-element);
+
+ /* Border color */
+ --border-color: var(--theme-border);
+
+ /* Text colors */
+ --text-primary: var(--theme-text);
+ --text-secondary: var(--theme-text-muted);
+ --text-tertiary: var(--theme-text-muted);
+ --text-dim: var(--theme-border);
+
+ /* Status colors */
+ --status-ok: var(--theme-success);
+ --status-warn: var(--theme-warning);
+ --status-error: var(--theme-error);
+ --status-unknown: var(--theme-text-muted);
+}
+
+.dark {
+ /* Background colors */
+ --bg-primary: var(--theme-background);
+ --bg-secondary: var(--theme-background-panel);
+ --bg-tertiary: var(--theme-background-element);
+
+ /* Border color */
+ --border-color: var(--theme-border);
+
+ /* Text colors */
+ --text-primary: var(--theme-text);
+ --text-secondary: var(--theme-text-muted);
+ --text-tertiary: var(--theme-text-muted);
+ --text-dim: var(--theme-border);
+
+ /* Status colors */
+ --status-ok: var(--theme-success);
+ --status-warn: var(--theme-warning);
+ --status-error: var(--theme-error);
+ --status-unknown: var(--theme-text-muted);
}
`
}