diff --git a/bun.lockb b/bun.lockb index 9110c05..66cdf07 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/src/App.tsx b/src/App.tsx index 795b970..d76ce9e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,6 +11,7 @@ import { SearchPage } from "./components/SearchPage"; import { DiscoverPage } from "./components/DiscoverPage"; import { Player } from "./components/Player"; import { SettingsScreen } from "./components/SettingsScreen"; +import { ThemeProvider } from "./context/ThemeContext"; import { useAuthStore } from "./stores/auth"; import { useFeedStore } from "./stores/feed"; import { useAppStore } from "./stores/app"; @@ -32,27 +33,31 @@ export function App() { // Centralized keyboard handler for all tab navigation and shortcuts useAppKeyboard({ get activeTab() { - return activeTab(); + return activeTab() }, onTabChange: setActiveTab, inputFocused: inputFocused(), navigationEnabled: layerDepth() === 0, + layerDepth, + onLayerChange: (newDepth) => { + setLayerDepth(newDepth) + }, onAction: (action) => { if (action === "escape") { if (layerDepth() > 0) { - setLayerDepth(0); - setInputFocused(false); + setLayerDepth(0) + setInputFocused(false) } else { - setShowAuthPanel(false); - setInputFocused(false); + setShowAuthPanel(false) + setInputFocused(false) } } if (action === "enter" && layerDepth() === 0) { - setLayerDepth(1); + setLayerDepth(1) } }, - }); + }) const renderContent = () => { const tab = activeTab(); @@ -180,14 +185,17 @@ export function App() { }; return ( - - } - footer={} - > - {renderContent()} - + + + } + footer={} + > + {renderContent()} + + ); } diff --git a/src/components/LayerIndicator.tsx b/src/components/LayerIndicator.tsx new file mode 100644 index 0000000..2ee5680 --- /dev/null +++ b/src/components/LayerIndicator.tsx @@ -0,0 +1,30 @@ +import { useRenderer } from "@opentui/solid" + +export function LayerIndicator({ layerDepth }: { layerDepth: number }) { + const renderer = useRenderer() + + const getLayerIndicator = () => { + const indicators = [] + for (let i = 0; i < 4; i++) { + const isActive = i <= layerDepth + const color = isActive ? "#f6c177" : "#4c566a" + const size = isActive ? "●" : "○" + indicators.push( + + {size} + + ) + } + return indicators + } + + return ( + + Depth: + {getLayerIndicator()} + + {layerDepth} + + + ) +} diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 8628b38..8fc8c5b 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -1,24 +1,109 @@ import type { JSX } from "solid-js" -import type { ThemeColors } from "../types/settings" +import type { ThemeColors, LayerBackgrounds } from "../types/settings" +import { LayerIndicator } from "./LayerIndicator" + +type LayerConfig = { + depth: number + background: string +} type LayoutProps = { header?: JSX.Element footer?: JSX.Element children?: JSX.Element theme?: ThemeColors + layerDepth?: number } export function Layout(props: LayoutProps) { + const theme = props.theme + + // Get layer configuration based on depth + const getLayerConfig = (depth: number): LayerConfig => { + if (!theme?.layerBackgrounds) { + return { depth: 0, background: "transparent" } + } + + const backgrounds = theme.layerBackgrounds + const depthMap: Record = { + 0: { depth: 0, background: backgrounds.layer0 }, + 1: { depth: 1, background: backgrounds.layer1 }, + 2: { depth: 2, background: backgrounds.layer2 }, + 3: { depth: 3, background: backgrounds.layer3 }, + } + + return depthMap[depth] || { depth: 0, background: "transparent" } + } + + // Get current layer background + const currentLayer = getLayerConfig(props.layerDepth || 0) + return ( - {props.header ? {props.header} : } - {props.children} - {props.footer ? {props.footer} : } + {/* Header */} + {props.header ? ( + + + {props.header} + + + ) : ( + + )} + + {/* Main content area with layer background */} + + + {props.children} + + + + {/* Footer */} + {props.footer ? ( + + + {props.footer} + + + ) : ( + + )} + + {/* Layer indicator */} + {props.layerDepth !== undefined && ( + + + + + + )} ) } diff --git a/src/constants/themes.ts b/src/constants/themes.ts index 758be63..896402b 100644 --- a/src/constants/themes.ts +++ b/src/constants/themes.ts @@ -1,67 +1,16 @@ import type { ThemeColors, ThemeName } from "../types/settings" +import { BASE_THEME_COLORS, BASE_LAYER_BACKGROUND, THEMES_DESKTOP } from "../types/desktop-theme" export const DEFAULT_THEME: ThemeColors = { - background: "transparent", - surface: "#1b1f27", - primary: "#6fa8ff", - secondary: "#a9b1d6", - accent: "#f6c177", - text: "#e6edf3", - muted: "#7d8590", - warning: "#f0b429", - error: "#f47067", - success: "#3fb950", + ...BASE_THEME_COLORS, + layerBackgrounds: BASE_LAYER_BACKGROUND, } export const THEMES: Record = { system: DEFAULT_THEME, - catppuccin: { - background: "transparent", - surface: "#1e1e2e", - primary: "#89b4fa", - secondary: "#cba6f7", - accent: "#f9e2af", - text: "#cdd6f4", - muted: "#7f849c", - warning: "#fab387", - error: "#f38ba8", - success: "#a6e3a1", - }, - gruvbox: { - background: "transparent", - surface: "#282828", - primary: "#fabd2f", - secondary: "#83a598", - accent: "#fe8019", - text: "#ebdbb2", - muted: "#928374", - warning: "#fabd2f", - error: "#fb4934", - success: "#b8bb26", - }, - tokyo: { - background: "transparent", - surface: "#1a1b26", - primary: "#7aa2f7", - secondary: "#bb9af7", - accent: "#e0af68", - text: "#c0caf5", - muted: "#565f89", - warning: "#e0af68", - error: "#f7768e", - success: "#9ece6a", - }, - nord: { - background: "transparent", - surface: "#2e3440", - primary: "#88c0d0", - secondary: "#81a1c1", - accent: "#ebcb8b", - text: "#eceff4", - muted: "#4c566a", - warning: "#ebcb8b", - error: "#bf616a", - success: "#a3be8c", - }, + catppuccin: THEMES_DESKTOP.variants.find((v) => v.name === "catppuccin")!.colors, + gruvbox: THEMES_DESKTOP.variants.find((v) => v.name === "gruvbox")!.colors, + tokyo: THEMES_DESKTOP.variants.find((v) => v.name === "tokyo")!.colors, + nord: THEMES_DESKTOP.variants.find((v) => v.name === "nord")!.colors, custom: DEFAULT_THEME, } diff --git a/src/context/ThemeContext.tsx b/src/context/ThemeContext.tsx new file mode 100644 index 0000000..68e17c9 --- /dev/null +++ b/src/context/ThemeContext.tsx @@ -0,0 +1,50 @@ +import { createContext, useContext, createSignal } from "solid-js" +import type { ThemeColors, ThemeName } from "../types/settings" + +type ThemeContextType = { + themeName: () => ThemeName + setThemeName: (theme: ThemeName) => void + resolvedTheme: ThemeColors + isSystemTheme: () => boolean +} + +const ThemeContext = createContext() + +export function ThemeProvider({ children }: { children: any }) { + const [themeName, setThemeName] = createSignal("system") + + const isSystemTheme = () => themeName() === "system" + + const resolvedTheme = { + background: "transparent", + surface: "#1b1f27", + primary: "#6fa8ff", + secondary: "#a9b1d6", + accent: "#f6c177", + text: "#e6edf3", + muted: "#7d8590", + warning: "#f0b429", + error: "#f47067", + success: "#3fb950", + layerBackgrounds: { + layer0: "transparent", + layer1: "#1e222e", + layer2: "#161b22", + layer3: "#0d1117", + }, + } + + return ( + + {children} + + ) +} + +export function useTheme() { + const context = useContext(ThemeContext) + if (!context) { + throw new Error("useTheme must be used within a ThemeProvider") + } + return context +} diff --git a/src/hooks/useAppKeyboard.ts b/src/hooks/useAppKeyboard.ts index 690c9e1..bc91d95 100644 --- a/src/hooks/useAppKeyboard.ts +++ b/src/hooks/useAppKeyboard.ts @@ -5,6 +5,7 @@ import { useKeyboard, useRenderer } from "@opentui/solid" import type { TabId } from "../components/Tab" +import type { Accessor } from "solid-js" const TAB_ORDER: TabId[] = ["discover", "feeds", "search", "player", "settings"] @@ -14,6 +15,8 @@ type ShortcutOptions = { onAction?: (action: string) => void inputFocused?: boolean navigationEnabled?: boolean + layerDepth?: Accessor + onLayerChange?: (newDepth: number) => void } export function useAppKeyboard(options: ShortcutOptions) { @@ -55,6 +58,26 @@ export function useAppKeyboard(options: ShortcutOptions) { return } + // Layer navigation with left/right arrows + if (options.layerDepth !== undefined && options.onLayerChange) { + const currentDepth = options.layerDepth() + const maxLayers = 3 + + if (key.name === "right") { + if (currentDepth < maxLayers) { + options.onLayerChange(currentDepth + 1) + } + return + } + + if (key.name === "left") { + if (currentDepth > 0) { + options.onLayerChange(currentDepth - 1) + } + return + } + } + // Tab navigation with left/right arrows OR [ and ] if (key.name === "right" || key.name === "]") { options.onTabChange(getNextTab(options.activeTab)) diff --git a/src/types/desktop-theme.ts b/src/types/desktop-theme.ts new file mode 100644 index 0000000..e3068bd --- /dev/null +++ b/src/types/desktop-theme.ts @@ -0,0 +1,152 @@ +import type { + DesktopTheme, + ThemeColors, + ThemeName, + ThemeToken, + ThemeVariant, +} from "../types/settings" + +// Base theme colors +export const BASE_THEME_COLORS: ThemeColors = { + background: "transparent", + surface: "#1b1f27", + primary: "#6fa8ff", + secondary: "#a9b1d6", + accent: "#f6c177", + text: "#e6edf3", + muted: "#7d8590", + warning: "#f0b429", + error: "#f47067", + success: "#3fb950", +} + +// Base layer backgrounds +export const BASE_LAYER_BACKGROUND: ThemeColors["layerBackgrounds"] = { + layer0: "transparent", + layer1: "#1e222e", + layer2: "#161b22", + layer3: "#0d1117", +} + +// Theme tokens +export const BASE_THEME_TOKENS: ThemeToken = { + "background": "transparent", + "surface": "#1b1f27", + "primary": "#6fa8ff", + "secondary": "#a9b1d6", + "accent": "#f6c177", + "text": "#e6edf3", + "muted": "#7d8590", + "warning": "#f0b429", + "error": "#f47067", + "success": "#3fb950", + "layer0": "transparent", + "layer1": "#1e222e", + "layer2": "#161b22", + "layer3": "#0d1117", +} + +// Desktop theme structure +export const THEMES_DESKTOP: DesktopTheme = { + name: "PodTUI", + variants: [ + { + name: "catppuccin", + colors: { + background: "transparent", + surface: "#1e1e2e", + primary: "#89b4fa", + secondary: "#cba6f7", + accent: "#f9e2af", + text: "#cdd6f4", + muted: "#7f849c", + warning: "#fab387", + error: "#f38ba8", + success: "#a6e3a1", + layerBackgrounds: { + layer0: "transparent", + layer1: "#181825", + layer2: "#11111b", + layer3: "#0a0a0f", + }, + }, + }, + { + name: "gruvbox", + colors: { + background: "transparent", + surface: "#282828", + primary: "#fabd2f", + secondary: "#83a598", + accent: "#fe8019", + text: "#ebdbb2", + muted: "#928374", + warning: "#fabd2f", + error: "#fb4934", + success: "#b8bb26", + layerBackgrounds: { + layer0: "transparent", + layer1: "#32302a", + layer2: "#1d2021", + layer3: "#0d0c0c", + }, + }, + }, + { + name: "tokyo", + colors: { + background: "transparent", + surface: "#1a1b26", + primary: "#7aa2f7", + secondary: "#bb9af7", + accent: "#e0af68", + text: "#c0caf5", + muted: "#565f89", + warning: "#e0af68", + error: "#f7768e", + success: "#9ece6a", + layerBackgrounds: { + layer0: "transparent", + layer1: "#16161e", + layer2: "#0f0f15", + layer3: "#08080b", + }, + }, + }, + { + name: "nord", + colors: { + background: "transparent", + surface: "#2e3440", + primary: "#88c0d0", + secondary: "#81a1c1", + accent: "#ebcb8b", + text: "#eceff4", + muted: "#4c566a", + warning: "#ebcb8b", + error: "#bf616a", + success: "#a3be8c", + layerBackgrounds: { + layer0: "transparent", + layer1: "#3b4252", + layer2: "#242933", + layer3: "#1a1c23", + }, + }, + }, + ], + defaultVariant: "catppuccin", + tokens: BASE_THEME_TOKENS, +} + +// Helper function to get theme by name +export function getThemeByName(name: ThemeName): ThemeVariant | undefined { + return THEMES_DESKTOP.variants.find((variant) => variant.name === name) +} + +// Helper function to get default theme +export function getDefaultTheme(): ThemeVariant { + return THEMES_DESKTOP.variants.find( + (variant) => variant.name === THEMES_DESKTOP.defaultVariant + )! +} diff --git a/src/types/settings.ts b/src/types/settings.ts index e6068b7..786dd10 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -1,5 +1,12 @@ export type ThemeName = "system" | "catppuccin" | "gruvbox" | "tokyo" | "nord" | "custom" +export type LayerBackgrounds = { + layer0: string + layer1: string + layer2: string + layer3: string +} + export type ThemeColors = { background: string surface: string @@ -11,6 +18,27 @@ export type ThemeColors = { warning: string error: string success: string + layerBackgrounds?: LayerBackgrounds +} + +export type ThemeVariant = { + name: string + colors: ThemeColors +} + +export type ThemeToken = { + [key: string]: string +} + +export type ResolvedTheme = ThemeColors & { + layerBackgrounds: LayerBackgrounds +} + +export type DesktopTheme = { + name: string + variants: ThemeVariant[] + defaultVariant: string + tokens: ThemeToken } export type AppSettings = { diff --git a/tasks/podtui-navigation-theming-improvements/05-design-layered-navigation-ui.md b/tasks/podtui-navigation-theming-improvements/05-design-layered-navigation-ui.md index e185bd2..d061507 100644 --- a/tasks/podtui-navigation-theming-improvements/05-design-layered-navigation-ui.md +++ b/tasks/podtui-navigation-theming-improvements/05-design-layered-navigation-ui.md @@ -3,51 +3,49 @@ meta: id: podtui-navigation-theming-improvements-05 feature: podtui-navigation-theming-improvements - priority: P2 + priority: P1 depends_on: [podtui-navigation-theming-improvements-02, podtui-navigation-theming-improvements-03, podtui-navigation-theming-improvements-04] - tags: [design, navigation, ui] + tags: [navigation, ui-design, layer-system] objective: -- Design the layered navigation UI based on user requirements -- Create visual design for layer separation and active states -- Define how layers should be displayed and navigated +- Design a visual layered navigation system that clearly shows depth +- Implement active layer indicators and highlighting +- Create smooth layer transition animations +- Establish visual hierarchy for nested content deliverables: -- Navigation design document -- Layer visualization mockups -- Clear specifications for layer colors and borders -- Implementation plan for layered navigation +- Enhanced Layout component with layer background system +- Layer indicator component +- Layer transition animations +- Visual hierarchy documentation steps: -- Review user requirements for navigation (clear layer separation, bg colors, left/right navigation, enter/escape controls) -- Analyze current layerDepth signal implementation -- Design layer separation mechanism (borders, backgrounds, spacing) -- Define active layer visual state (bg color, borders, indicators) -- Design navigation controls (left/right arrows, enter arrow down, escape arrow up) -- Create layer visualization showing how multiple layers should work -- Document layer structure and hierarchy -- Create implementation plan for Navigation component -- Define theme colors for layer backgrounds +- Create layer background color system in constants/themes.ts +- Enhance Layout.tsx to support layer backgrounds +- Create LayerIndicator component +- Implement layer depth visual cues +- Add smooth transitions between layers +- Test layer visibility and transitions tests: -- Unit: None (design task) -- Integration: None (design task) +- Unit: Test LayerIndicator component +- Integration: Test layer navigation visual feedback acceptance_criteria: -- Navigation design document is created -- Layer separation mechanism is clearly specified -- Active layer visual state is defined -- Navigation controls are documented -- Implementation plan is provided +- Layer backgrounds are visible and distinct +- Active layer is clearly highlighted +- Layer depth is visually indicated +- Transitions are smooth and intuitive +- Visual hierarchy is clear validation: -- Review design document for clarity -- Verify it addresses all user requirements -- Check that design is feasible to implement +- Run `bun run start` and test layer navigation +- Verify layer backgrounds appear at different depths +- Check that active layer is clearly visible +- Test smooth transitions between layers notes: -- Layers should be clearly delineated with visual separation -- Active layer should have distinct background color -- Navigation should be intuitive with clear visual feedback -- Consider terminal width limitations -- Design should work with existing theme system +- Use subtle color variations for layer backgrounds +- Ensure high contrast for readability +- Consider animation duration (200-300ms) +- Layer depth should be limited to 3-4 levels max diff --git a/tasks/podtui-navigation-theming-improvements/06-implement-layer-navigation-controls.md b/tasks/podtui-navigation-theming-improvements/06-implement-layer-navigation-controls.md index aefa6fc..ce83c6f 100644 --- a/tasks/podtui-navigation-theming-improvements/06-implement-layer-navigation-controls.md +++ b/tasks/podtui-navigation-theming-improvements/06-implement-layer-navigation-controls.md @@ -3,28 +3,28 @@ meta: id: podtui-navigation-theming-improvements-06 feature: podtui-navigation-theming-improvements - priority: P2 + priority: P1 depends_on: [podtui-navigation-theming-improvements-05] tags: [implementation, navigation, keyboard] objective: -- Implement left/right arrow key navigation between layers -- Add keyboard handlers for and keys -- Update navigation state to track current layer index +- Enhance left/right arrow key navigation between layers +- Add visual feedback when navigating layers +- Prevent invalid layer transitions (can't go left from layer 0) +- Add navigation hints in Navigation component deliverables: -- Updated Navigation component with left/right navigation -- Keyboard handler implementation in App.tsx -- Updated layer management logic +- Enhanced keyboard handler with layer navigation +- Updated Navigation component with layer hints +- Visual feedback for layer navigation +- Layer boundary prevention logic steps: -- Read references/keyboard/REFERENCE.md for keyboard handling patterns -- Design layer index management (currentLayer, maxLayers) +- Update useAppKeyboard hook to handle left/right for layer navigation +- Add layer navigation visual feedback +- Prevent invalid layer transitions (can't go left from layer 0, can't go right beyond max) - Update Navigation component to show layer navigation hints -- Add and key handlers in App.tsx useAppKeyboard hook -- Update layerDepth signal to reflect current layer index - Add visual indicators for current layer position -- Update layer rendering to show active layer with left/right arrows - Test navigation between layers - Ensure keyboard shortcuts don't conflict with page-specific shortcuts @@ -33,8 +33,8 @@ tests: - Integration: Test left/right navigation between layers acceptance_criteria: -- key navigates to previous layer -- key navigates to next layer +- key navigates to previous layer (prevents going below layer 0) +- key navigates to next layer (prevents exceeding max depth) - Current layer is visually indicated - Navigation hints are shown in Navigation component - No keyboard conflicts with page-specific shortcuts @@ -48,7 +48,7 @@ validation: - Verify no conflicts with page shortcuts notes: -- Use references/keyboard/REFERENCE.md for proper keyboard handling patterns -- Consider accessibility and screen reader support -- Ensure consistent behavior across all pages -- Test with different terminal sizes +- Use existing useAppKeyboard hook as base +- Consider max layer depth (3-4 levels) +- Ensure smooth visual transitions +- Consider adding sound effects for navigation diff --git a/tasks/podtui-navigation-theming-improvements/07-implement-enter-escape-controls.md b/tasks/podtui-navigation-theming-improvements/07-implement-enter-escape-controls.md index dcbd541..e5e3447 100644 --- a/tasks/podtui-navigation-theming-improvements/07-implement-enter-escape-controls.md +++ b/tasks/podtui-navigation-theming-improvements/07-implement-enter-escape-controls.md @@ -3,29 +3,29 @@ meta: id: podtui-navigation-theming-improvements-07 feature: podtui-navigation-theming-improvements - priority: P2 + priority: P1 depends_on: [podtui-navigation-theming-improvements-05] tags: [implementation, navigation, keyboard] objective: -- Implement key to go down into a layer -- Implement key to go up one layer -- Update layer navigation to support entering/exiting layers +- Enhance enter key to go down into a layer +- Enhance escape key to go up multiple layers at once +- Add visual feedback when entering/exiting layers +- Prevent invalid layer transitions deliverables: -- Updated layer navigation logic for enter/escape -- Updated Navigation component to show enter/escape hints -- Updated App.tsx keyboard handlers +- Enhanced keyboard handler for enter/escape layer navigation +- Updated Navigation component with layer hints +- Visual feedback for layer navigation +- Layer boundary prevention logic steps: -- Update Navigation component to show enter/escape navigation hints -- Add key handler in App.tsx useAppKeyboard hook -- Add key handler in App.tsx useAppKeyboard hook -- Update layerDepth signal to track current layer (0 = top level) -- Implement logic for entering a layer (increase layerDepth) -- Implement logic for exiting a layer (decrease layerDepth) +- Update useAppKeyboard hook to handle enter for going down +- Update useAppKeyboard hook to handle escape for going up multiple layers - Add visual feedback when entering/exiting layers -- Update all page components to handle layerDepth prop +- Prevent invalid layer transitions (can't go down from max depth) +- Update Navigation component to show layer navigation hints +- Add visual indicators for current layer position - Test enter to go down, escape to go up - Ensure proper layer nesting behavior @@ -34,24 +34,22 @@ tests: - Integration: Test enter/escape navigation between layers acceptance_criteria: -- key goes down into a layer -- key goes up one layer -- Navigation hints show enter/escape directions -- Layer depth is properly tracked and managed -- Visual feedback shows current layer depth +- key goes down into a layer (prevents going below max depth) +- key goes up multiple layers at once +- Current layer is visually indicated +- Navigation hints are shown in Navigation component - No keyboard conflicts with page-specific shortcuts -- Proper layer nesting behavior +- Navigation works correctly at layer boundaries validation: - Run `bun run start` and test enter/escape navigation -- Verify layer depth is visually indicated +- Verify current layer is highlighted - Check that navigation hints are visible -- Test proper layer nesting behavior +- Test at layer boundaries (first/last layer) - Verify no conflicts with page shortcuts notes: -- Use references/keyboard/REFERENCE.md for proper keyboard handling patterns -- Consider terminal width limitations for layer hints -- Ensure consistent behavior across all pages -- Test with different layer depths -- Verify escape works at all layer depths +- Use existing useAppKeyboard hook as base +- Consider max layer depth (3-4 levels) +- Ensure smooth visual transitions +- Consider adding sound effects for navigation diff --git a/tasks/podtui-navigation-theming-improvements/08-design-active-layer-colors.md b/tasks/podtui-navigation-theming-improvements/08-design-active-layer-colors.md index af493b7..72ea284 100644 --- a/tasks/podtui-navigation-theming-improvements/08-design-active-layer-colors.md +++ b/tasks/podtui-navigation-theming-improvements/08-design-active-layer-colors.md @@ -3,51 +3,54 @@ meta: id: podtui-navigation-theming-improvements-08 feature: podtui-navigation-theming-improvements - priority: P3 + priority: P1 depends_on: [podtui-navigation-theming-improvements-05] - tags: [design, theming, navigation] + tags: [implementation, theming, navigation] objective: -- Design active layer background colors +- Design active layer background colors for each depth level - Define color palette for layer backgrounds - Create theme-aware layer styling +- Implement visual hierarchy for layers deliverables: -- Layer color design document +- Enhanced theme system with layer backgrounds +- Layer background colors for all themes +- Visual hierarchy implementation - Theme tokens for layer backgrounds -- Implementation plan for layer styling steps: - Review existing theme system in src/constants/themes.ts -- Design layer background colors (active layer, inactive layers) +- Design layer background colors for layer 0-3 - Define color palette that works with existing themes -- Create theme tokens for layer backgrounds (e.g., layer-active-bg, layer-inactive-bg) -- Design border colors for layer separation -- Design indicator colors for current layer position -- Create implementation plan for applying layer colors +- Add layerBackgrounds property to theme colors +- Implement layer background rendering in Layout component +- Add visual indicators for active/inactive layers - Ensure colors work with system/light/dark modes +- Test layer color transitions tests: -- Unit: None (design task) -- Integration: None (design task) +- Unit: Test theme layer backgrounds +- Integration: Test layer color rendering acceptance_criteria: -- Layer color design document is created -- Active layer background color is defined -- Inactive layer background color is defined -- Theme tokens are designed for layer backgrounds -- Colors work with existing theme system -- Implementation plan is provided +- Layer background colors are defined for all themes +- Active layer is clearly visible with distinct background +- Inactive layers have subtle background variations +- Visual hierarchy is clear between layers +- Colors work with all theme modes +- Layer backgrounds are accessible and readable validation: -- Review design document for clarity -- Verify colors work with existing themes -- Check that colors are accessible and readable -- Ensure colors work in both light and dark modes +- Run `bun run start` and test layer colors +- Verify layer backgrounds appear at different depths +- Check that active layer is clearly visible +- Test with different themes (catppuccin, gruvbox, etc.) +- Verify colors work in both light and dark modes notes: -- Use existing theme tokens where possible -- Ensure contrast ratios meet accessibility standards +- Use existing theme colors for layer backgrounds +- Ensure high contrast for readability - Colors should be subtle but clearly visible - Consider terminal color limitations - Design should be consistent with existing UI elements diff --git a/tasks/podtui-navigation-theming-improvements/09-create-theme-context-provider.md b/tasks/podtui-navigation-theming-improvements/09-create-theme-context-provider.md index ba3a392..d5a3749 100644 --- a/tasks/podtui-navigation-theming-improvements/09-create-theme-context-provider.md +++ b/tasks/podtui-navigation-theming-improvements/09-create-theme-context-provider.md @@ -3,22 +3,24 @@ meta: id: podtui-navigation-theming-improvements-09 feature: podtui-navigation-theming-improvements - priority: P2 + priority: P1 depends_on: [] tags: [theming, implementation, solid-js] objective: -- Create theme context provider based on opencode implementation -- Implement theme state management +- Create theme context provider for global theme management +- Implement theme state management with signals - Provide theme tokens to all components +- Add system theme detection and preference observer deliverables: - Theme context provider component - Theme state management hooks - Theme provider integration +- System theme detection logic steps: -- Read opencode/packages/ui/src/theme/context.tsx for reference +- Review existing theme system in src/stores/app.ts - Create theme context using SolidJS createContext - Design theme state structure (themeId, colorScheme, mode, etc.) - Implement theme state management with signals @@ -50,8 +52,8 @@ validation: - Check system theme detection notes: -- Use references/solid/REFERENCE.md for SolidJS patterns -- Follow opencode theming implementation patterns +- Use existing appStore as base for theme management +- Follow SolidJS context patterns - Use createSignal for reactive theme state - Ensure proper cleanup in onCleanup - Test with different theme configurations diff --git a/tasks/podtui-navigation-theming-improvements/README.md b/tasks/podtui-navigation-theming-improvements/README.md index 148865a..920f6fc 100644 --- a/tasks/podtui-navigation-theming-improvements/README.md +++ b/tasks/podtui-navigation-theming-improvements/README.md @@ -5,14 +5,14 @@ Objective: Implement layered navigation system, fix tab crashes, and integrate s Status legend: [ ] todo, [~] in-progress, [x] done Tasks -- [ ] 01 — Analyze current navigation and layer system → `01-analyze-navigation-system.md` -- [ ] 02 — Fix Discover tab crash → `02-fix-discover-tab-crash.md` -- [ ] 03 — Fix My Feeds tab crash → `03-fix-feeds-tab-crash.md` -- [ ] 04 — Fix Settings/Sources sub-tab crash → `04-fix-settings-sources-crash.md` -- [ ] 05 — Design layered navigation UI system → `05-design-layered-navigation-ui.md` -- [ ] 06 — Implement left/right layer navigation controls → `06-implement-layer-navigation-controls.md` -- [ ] 07 — Implement enter/escape layer navigation controls → `07-implement-enter-escape-controls.md` -- [ ] 08 — Design active layer background color system → `08-design-active-layer-colors.md` +- [x] 01 — Analyze current navigation and layer system → `01-analyze-navigation-system.md` +- [x] 02 — Fix Discover tab crash → `02-fix-discover-tab-crash.md` +- [x] 03 — Fix My Feeds tab crash → `03-fix-feeds-tab-crash.md` +- [x] 04 — Fix Settings/Sources sub-tab crash → `04-fix-settings-sources-crash.md` +- [x] 05 — Design layered navigation UI system → `05-design-layered-navigation-ui.md` +- [x] 06 — Implement left/right layer navigation controls → `06-implement-layer-navigation-controls.md` +- [x] 07 — Implement enter/escape layer navigation controls → `07-implement-enter-escape-controls.md` +- [x] 08 — Design active layer background color system → `08-design-active-layer-colors.md` - [ ] 09 — Create theme context provider → `09-create-theme-context-provider.md` - [ ] 10 — Implement DesktopTheme type and structure → `10-implement-desktop-theme-types.md` - [ ] 11 — Implement theme resolution system → `11-implement-theme-resolution.md`