diff --git a/src/App.tsx b/src/App.tsx
index ddc78ac..b6f99a3 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -2,7 +2,6 @@ import { createSignal } from "solid-js";
import { Layout } from "./components/Layout";
import { Navigation } from "./components/Navigation";
import { TabNavigation } from "./components/TabNavigation";
-import { SyncPanel } from "./components/SyncPanel";
import { FeedList } from "./components/FeedList";
import { LoginScreen } from "./components/LoginScreen";
import { CodeValidation } from "./components/CodeValidation";
@@ -10,6 +9,8 @@ import { OAuthPlaceholder } from "./components/OAuthPlaceholder";
import { SyncProfile } from "./components/SyncProfile";
import { SearchPage } from "./components/SearchPage";
import { DiscoverPage } from "./components/DiscoverPage";
+import { Player } from "./components/Player";
+import { SettingsScreen } from "./components/SettingsScreen";
import { useAuthStore } from "./stores/auth";
import { useFeedStore } from "./stores/feed";
import { FeedVisibility } from "./types/feed";
@@ -101,29 +102,15 @@ export function App() {
}
return (
-
-
-
-
-
- Account:
- {auth.isAuthenticated ? (
- Signed in as {auth.user?.email}
- ) : (
- Not signed in
- )}
- setShowAuthPanel(true)}
- >
-
- {auth.isAuthenticated ? "[A] Account" : "[A] Sign In"}
-
-
-
-
-
+ setShowAuthPanel(true)}
+ accountLabel={
+ auth.isAuthenticated
+ ? `Signed in as ${auth.user?.email}`
+ : "Not signed in"
+ }
+ accountStatus={auth.isAuthenticated ? "signed-in" : "signed-out"}
+ />
);
case "discover":
@@ -154,13 +141,15 @@ export function App() {
);
case "player":
+ return ;
+
default:
return (
{tab}
- Player - coming in later phases
+ Coming soon
);
diff --git a/src/components/DiscoverPage.tsx b/src/components/DiscoverPage.tsx
index 1a45c28..4d49267 100644
--- a/src/components/DiscoverPage.tsx
+++ b/src/components/DiscoverPage.tsx
@@ -39,15 +39,17 @@ export function DiscoverPage(props: DiscoverPageProps) {
// Category navigation
if (area === "categories") {
if (key.name === "left" || key.name === "h") {
- setCategoryIndex((i) => Math.max(0, i - 1))
- const cat = DISCOVER_CATEGORIES[categoryIndex()]
+ const nextIndex = Math.max(0, categoryIndex() - 1)
+ setCategoryIndex(nextIndex)
+ const cat = DISCOVER_CATEGORIES[nextIndex]
if (cat) discoverStore.setSelectedCategory(cat.id)
- setShowIndex(0) // Reset show selection when changing category
+ setShowIndex(0)
return
}
if (key.name === "right" || key.name === "l") {
- setCategoryIndex((i) => Math.min(DISCOVER_CATEGORIES.length - 1, i + 1))
- const cat = DISCOVER_CATEGORIES[categoryIndex()]
+ const nextIndex = Math.min(DISCOVER_CATEGORIES.length - 1, categoryIndex() + 1)
+ setCategoryIndex(nextIndex)
+ const cat = DISCOVER_CATEGORIES[nextIndex]
if (cat) discoverStore.setSelectedCategory(cat.id)
setShowIndex(0)
return
@@ -67,10 +69,15 @@ export function DiscoverPage(props: DiscoverPageProps) {
if (area === "shows") {
const shows = discoverStore.filteredPodcasts()
if (key.name === "down" || key.name === "j") {
+ if (shows.length === 0) return
setShowIndex((i) => Math.min(i + 1, shows.length - 1))
return
}
if (key.name === "up" || key.name === "k") {
+ if (shows.length === 0) {
+ setFocusArea("categories")
+ return
+ }
const newIndex = showIndex() - 1
if (newIndex < 0) {
setFocusArea("categories")
diff --git a/src/components/FeedDetail.tsx b/src/components/FeedDetail.tsx
index 9d5cb8f..b7dd44f 100644
--- a/src/components/FeedDetail.tsx
+++ b/src/components/FeedDetail.tsx
@@ -4,6 +4,7 @@
*/
import { createSignal, For, Show } from "solid-js"
+import { useKeyboard } from "@opentui/solid"
import type { Feed } from "../types/feed"
import type { Episode } from "../types/episode"
import { format } from "date-fns"
@@ -72,6 +73,11 @@ export function FeedDetail(props: FeedDetailProps) {
}
}
+ useKeyboard((key) => {
+ if (!props.focused) return
+ handleKeyPress(key)
+ })
+
return (
{/* Header with back button */}
diff --git a/src/components/FeedList.tsx b/src/components/FeedList.tsx
index f4f812c..69a9438 100644
--- a/src/components/FeedList.tsx
+++ b/src/components/FeedList.tsx
@@ -4,6 +4,7 @@
*/
import { createSignal, For, Show } from "solid-js"
+import { useKeyboard } from "@opentui/solid"
import { FeedItem } from "./FeedItem"
import { useFeedStore } from "../stores/feed"
import { FeedVisibility, FeedSortField } from "../types/feed"
@@ -65,6 +66,11 @@ export function FeedList(props: FeedListProps) {
}
}
+ useKeyboard((key) => {
+ if (!props.focused) return
+ handleKeyPress(key)
+ })
+
const cycleVisibilityFilter = () => {
const current = feedStore.filter().visibility
let next: FeedVisibility | "all"
diff --git a/tasks/podcast-tui-app/50-global-state-store.md b/tasks/podcast-tui-app/50-global-state-store.md
new file mode 100644
index 0000000..59e8b67
--- /dev/null
+++ b/tasks/podcast-tui-app/50-global-state-store.md
@@ -0,0 +1,52 @@
+# 50. Create Global State Store (Signals)
+
+meta:
+ id: podcast-tui-app-50
+ feature: podcast-tui-app
+ priority: P1
+ depends_on: [66]
+ tags: [state-management, signals, solidjs, global-store]
+
+objective:
+- Create a global state store using SolidJS Signals for reactive state management
+- Implement a store that manages application-wide state (feeds, settings, user, etc.)
+- Provide reactive subscriptions for state changes
+- Ensure thread-safe state updates
+
+deliverables:
+- `/src/store/index.ts` - Global state store with Signals
+- `/src/store/types.ts` - State type definitions
+- `/src/store/hooks.ts` - Custom hooks for state access
+- Updated `src/index.tsx` to initialize the store
+
+steps:
+- Define state interface with all application state properties (feeds, settings, user, etc.)
+- Create Signal-based store using `createSignal` from SolidJS
+- Implement computed signals for derived state (filtered feeds, search results, etc.)
+- Create state update functions that trigger reactivity
+- Add subscription mechanism for reactive UI updates
+- Export store and hooks for use across components
+
+tests:
+- Unit: Test that signals update correctly when state changes
+- Unit: Test computed signals produce correct derived values
+- Integration: Verify store updates trigger UI re-renders
+- Integration: Test multiple components can subscribe to same state
+
+acceptance_criteria:
+- Store can be initialized with default state
+- State changes trigger reactive updates in components
+- Computed signals work correctly for derived state
+- Multiple components can access and subscribe to store
+- State updates are thread-safe
+
+validation:
+- Run `bun run build` to verify TypeScript compilation
+- Run application and verify state changes are reactive
+- Check console for any errors during state updates
+
+notes:
+- Use `createSignal`, `createComputed`, `createEffect` from SolidJS
+- Store should follow single source of truth pattern
+- Consider using `batch` for multiple state updates
+- State should be serializable for persistence
diff --git a/tasks/podcast-tui-app/59-theme-system.md b/tasks/podcast-tui-app/59-theme-system.md
new file mode 100644
index 0000000..4f7ae56
--- /dev/null
+++ b/tasks/podcast-tui-app/59-theme-system.md
@@ -0,0 +1,56 @@
+# 59. Create Theme System Architecture
+
+meta:
+ id: podcast-tui-app-59
+ feature: podcast-tui-app
+ priority: P1
+ depends_on: [09]
+ tags: [theming, architecture, solidjs, design-system]
+
+objective:
+- Design and implement a flexible theme system architecture
+- Support multiple color themes (Catppuccin, Gruvbox, Tokyo, Nord, custom)
+- Provide theme switching capabilities
+- Ensure theme persistence across sessions
+- Define theme properties (colors, fonts, spacing, borders)
+
+deliverables:
+- `/src/themes/types.ts` - Theme type definitions
+- `/src/themes/theme.ts` - Theme system core implementation
+- `/src/themes/themes/` - Directory with theme files
+- `/src/themes/default.ts` - Default system theme
+- `/src/themes/hooks.ts` - Theme hooks (useTheme, useThemeColor)
+
+steps:
+- Define `Theme` interface with properties: name, colors, fonts, spacing, borders
+- Create theme color palettes (background, foreground, primary, secondary, accent, etc.)
+- Implement `ThemeManager` class to handle theme loading, switching, and persistence
+- Create `useTheme` hook for React/Solid components to access current theme
+- Implement `useThemeColor` hook for accessing specific theme colors
+- Add theme persistence using localStorage or file-based storage
+- Export theme utilities for programmatic theme access
+
+tests:
+- Unit: Test theme loading from JSON file
+- Unit: Test theme switching updates current theme
+- Unit: Test theme persistence saves/loads correctly
+- Integration: Verify components update when theme changes
+
+acceptance_criteria:
+- Theme system can load multiple theme definitions
+- Theme switching works instantly across all components
+- Theme preferences persist across application restarts
+- Theme colors are accessible via hooks
+- Theme manager handles errors gracefully
+
+validation:
+- Run `bun run build` to verify TypeScript compilation
+- Test theme switching manually in application
+- Verify localStorage/file storage works
+- Check all theme colors render correctly
+
+notes:
+- Theme files should be JSON or TypeScript modules
+- Use CSS variables or terminal color codes
+- Consider dark/light mode compatibility
+- Themes should be easily extensible
diff --git a/tasks/podcast-tui-app/60-default-theme.md b/tasks/podcast-tui-app/60-default-theme.md
new file mode 100644
index 0000000..a72744c
--- /dev/null
+++ b/tasks/podcast-tui-app/60-default-theme.md
@@ -0,0 +1,52 @@
+# 60. Implement Default Theme (System Terminal)
+
+meta:
+ id: podcast-tui-app-60
+ feature: podcast-tui-app
+ priority: P1
+ depends_on: [59]
+ tags: [theming, default, solidjs, terminal]
+
+objective:
+- Implement the default system terminal theme
+- Define colors matching common terminal environments
+- Ensure good readability and contrast
+- Support both light and dark terminal modes
+
+deliverables:
+- `/src/themes/themes/default.ts` - Default theme definition
+- `/src/themes/themes/default-light.ts` - Light mode theme
+- `/src/themes/themes/default-dark.ts` - Dark mode theme
+- Updated `/src/themes/theme.ts` to load default theme
+
+steps:
+- Define default color palette for system terminals
+- Create light mode theme with standard terminal colors
+- Create dark mode theme with standard terminal colors
+- Ensure proper contrast ratios for readability
+- Test theme in both light and dark terminal environments
+- Export default theme as fallback
+
+tests:
+- Unit: Verify default theme colors are defined
+- Unit: Test theme renders correctly in light mode
+- Unit: Test theme renders correctly in dark mode
+- Visual: Verify text contrast meets accessibility standards
+
+acceptance_criteria:
+- Default theme works in light terminal mode
+- Default theme works in dark terminal mode
+- Colors have good readability and contrast
+- Theme is used as fallback when no theme selected
+
+validation:
+- Run `bun run build` to verify TypeScript compilation
+- Test in light terminal (e.g., iTerm2, Terminal.app)
+- Test in dark terminal (e.g., Kitty, Alacritty)
+- Check color contrast visually
+
+notes:
+- Use standard terminal color codes (ANSI escape codes)
+- Consider common terminal themes (Solarized, Dracula, etc.)
+- Test on multiple terminal emulators
+- Document terminal requirements
diff --git a/tasks/podcast-tui-app/61-catppuccin-theme.md b/tasks/podcast-tui-app/61-catppuccin-theme.md
new file mode 100644
index 0000000..bf6cf3c
--- /dev/null
+++ b/tasks/podcast-tui-app/61-catppuccin-theme.md
@@ -0,0 +1,52 @@
+# 61. Add Catppuccin Theme
+
+meta:
+ id: podcast-tui-app-61
+ feature: podcast-tui-app
+ priority: P1
+ depends_on: [59]
+ tags: [theming, catppuccin, solidjs, popular]
+
+objective:
+- Implement Catppuccin Mocha theme for the podcast TUI
+- Provide beautiful, modern color scheme
+- Ensure high contrast and readability
+- Support both dark and light variants
+
+deliverables:
+- `/src/themes/themes/catppuccin.ts` - Catppuccin theme definition
+- `/src/themes/themes/catppuccin-mocha.ts` - Dark mode Catppuccin
+- `/src/themes/themes/catppuccin-latte.ts` - Light mode Catppuccin
+- Updated `/src/themes/themes/index.ts` to export Catppuccin themes
+
+steps:
+- Research and implement Catppuccin Mocha color palette
+- Define all color tokens (background, foreground, surface, primary, secondary, etc.)
+- Create Catppuccin Mocha (dark) theme
+- Create Catppuccin Latte (light) theme
+- Ensure proper color contrast for accessibility
+- Add Catppuccin to theme registry
+
+tests:
+- Unit: Verify Catppuccin theme colors are defined
+- Unit: Test Catppuccin Mocha renders correctly
+- Unit: Test Catppuccin Latte renders correctly
+- Visual: Verify Catppuccin colors are visually appealing
+
+acceptance_criteria:
+- Catppuccin Mocha theme works in dark terminals
+- Catppuccin Latte theme works in light terminals
+- Colors match official Catppuccin design
+- Theme is selectable from theme list
+
+validation:
+- Run `bun run build` to verify TypeScript compilation
+- Test Catppuccin theme manually in application
+- Compare with official Catppuccin color palette
+- Check color harmony and contrast
+
+notes:
+- Catppuccin Mocha is the recommended dark theme
+- Include all standard Catppuccin colors (latte, frappe, macchiato, mocha)
+- Use official color values from Catppuccin repository
+- Consider adding custom color variations
diff --git a/tasks/podcast-tui-app/62-gruvbox-theme.md b/tasks/podcast-tui-app/62-gruvbox-theme.md
new file mode 100644
index 0000000..fdcf85a
--- /dev/null
+++ b/tasks/podcast-tui-app/62-gruvbox-theme.md
@@ -0,0 +1,52 @@
+# 62. Add Gruvbox Theme
+
+meta:
+ id: podcast-tui-app-62
+ feature: podcast-tui-app
+ priority: P1
+ depends_on: [59]
+ tags: [theming, gruvbox, solidjs, retro]
+
+objective:
+- Implement Gruvbox Dark theme for the podcast TUI
+- Provide warm, nostalgic color scheme
+- Ensure good contrast and readability
+- Support both dark and light variants
+
+deliverables:
+- `/src/themes/themes/gruvbox.ts` - Gruvbox theme definition
+- `/src/themes/themes/gruvbox-dark.ts` - Dark mode Gruvbox
+- `/src/themes/themes/gruvbox-light.ts` - Light mode Gruvbox
+- Updated `/src/themes/themes/index.ts` to export Gruvbox themes
+
+steps:
+- Research and implement Gruvbox Dark theme color palette
+- Define all color tokens (background, foreground, primary, secondary, etc.)
+- Create Gruvbox Dark theme
+- Create Gruvbox Light theme
+- Ensure proper color contrast for accessibility
+- Add Gruvbox to theme registry
+
+tests:
+- Unit: Verify Gruvbox theme colors are defined
+- Unit: Test Gruvbox Dark renders correctly
+- Unit: Test Gruvbox Light renders correctly
+- Visual: Verify Gruvbox colors are visually appealing
+
+acceptance_criteria:
+- Gruvbox Dark theme works in dark terminals
+- Gruvbox Light theme works in light terminals
+- Colors match official Gruvbox design
+- Theme is selectable from theme list
+
+validation:
+- Run `bun run build` to verify TypeScript compilation
+- Test Gruvbox theme manually in application
+- Compare with official Gruvbox color palette
+- Check color harmony and contrast
+
+notes:
+- Gruvbox Dark is the recommended variant
+- Include all standard Gruvbox colors (hard, soft, light)
+- Use official color values from Gruvbox repository
+- Gruvbox is popular among developers for its warmth
diff --git a/tasks/podcast-tui-app/63-tokyo-theme.md b/tasks/podcast-tui-app/63-tokyo-theme.md
new file mode 100644
index 0000000..cdfd6d8
--- /dev/null
+++ b/tasks/podcast-tui-app/63-tokyo-theme.md
@@ -0,0 +1,52 @@
+# 63. Add Tokyo Night Theme
+
+meta:
+ id: podcast-tui-app-63
+ feature: podcast-tui-app
+ priority: P1
+ depends_on: [59]
+ tags: [theming, tokyo-night, solidjs, modern]
+
+objective:
+- Implement Tokyo Night theme for the podcast TUI
+- Provide modern, vibrant color scheme
+- Ensure good contrast and readability
+- Support both dark and light variants
+
+deliverables:
+- `/src/themes/themes/tokyo-night.ts` - Tokyo Night theme definition
+- `/src/themes/themes/tokyo-night-day.ts` - Light mode Tokyo Night
+- `/src/themes/themes/tokyo-night-night.ts` - Dark mode Tokyo Night
+- Updated `/src/themes/themes/index.ts` to export Tokyo Night themes
+
+steps:
+- Research and implement Tokyo Night theme color palette
+- Define all color tokens (background, foreground, primary, secondary, etc.)
+- Create Tokyo Night Night (dark) theme
+- Create Tokyo Night Day (light) theme
+- Ensure proper color contrast for accessibility
+- Add Tokyo Night to theme registry
+
+tests:
+- Unit: Verify Tokyo Night theme colors are defined
+- Unit: Test Tokyo Night Night renders correctly
+- Unit: Test Tokyo Night Day renders correctly
+- Visual: Verify Tokyo Night colors are visually appealing
+
+acceptance_criteria:
+- Tokyo Night Night theme works in dark terminals
+- Tokyo Night Day theme works in light terminals
+- Colors match official Tokyo Night design
+- Theme is selectable from theme list
+
+validation:
+- Run `bun run build` to verify TypeScript compilation
+- Test Tokyo Night theme manually in application
+- Compare with official Tokyo Night color palette
+- Check color harmony and contrast
+
+notes:
+- Tokyo Night Night is the recommended variant
+- Include all standard Tokyo Night colors
+- Use official color values from Tokyo Night repository
+- Tokyo Night is popular for its modern, clean look
diff --git a/tasks/podcast-tui-app/64-nord-theme.md b/tasks/podcast-tui-app/64-nord-theme.md
new file mode 100644
index 0000000..8f30cb9
--- /dev/null
+++ b/tasks/podcast-tui-app/64-nord-theme.md
@@ -0,0 +1,52 @@
+# 64. Add Nord Theme
+
+meta:
+ id: podcast-tui-app-64
+ feature: podcast-tui-app
+ priority: P1
+ depends_on: [59]
+ tags: [theming, nord, solidjs, minimal]
+
+objective:
+- Implement Nord theme for the podcast TUI
+- Provide clean, minimal color scheme
+- Ensure good contrast and readability
+- Support both dark and light variants
+
+deliverables:
+- `/src/themes/themes/nord.ts` - Nord theme definition
+- `/src/themes/themes/nord-dark.ts` - Dark mode Nord
+- `/src/themes/themes/nord-light.ts` - Light mode Nord
+- Updated `/src/themes/themes/index.ts` to export Nord themes
+
+steps:
+- Research and implement Nord theme color palette
+- Define all color tokens (background, foreground, primary, secondary, etc.)
+- Create Nord Dark theme
+- Create Nord Light theme
+- Ensure proper color contrast for accessibility
+- Add Nord to theme registry
+
+tests:
+- Unit: Verify Nord theme colors are defined
+- Unit: Test Nord Dark renders correctly
+- Unit: Test Nord Light renders correctly
+- Visual: Verify Nord colors are visually appealing
+
+acceptance_criteria:
+- Nord Dark theme works in dark terminals
+- Nord Light theme works in light terminals
+- Colors match official Nord design
+- Theme is selectable from theme list
+
+validation:
+- Run `bun run build` to verify TypeScript compilation
+- Test Nord theme manually in application
+- Compare with official Nord color palette
+- Check color harmony and contrast
+
+notes:
+- Nord Dark is the recommended variant
+- Include all standard Nord colors
+- Use official color values from Nord repository
+- Nord is popular for its minimalist, clean aesthetic
diff --git a/tasks/podcast-tui-app/65-custom-theme.md b/tasks/podcast-tui-app/65-custom-theme.md
new file mode 100644
index 0000000..098e3e0
--- /dev/null
+++ b/tasks/podcast-tui-app/65-custom-theme.md
@@ -0,0 +1,56 @@
+# 65. Implement Custom Theme Editor
+
+meta:
+ id: podcast-tui-app-65
+ feature: podcast-tui-app
+ priority: P2
+ depends_on: [59]
+ tags: [theming, editor, custom, solidjs]
+
+objective:
+- Build a UI for creating and editing custom themes
+- Allow users to modify color palettes
+- Provide live preview of theme changes
+- Save custom themes to storage
+
+deliverables:
+- `/src/components/ThemeEditor.tsx` - Theme editor component
+- `/src/components/ThemePreview.tsx` - Live theme preview component
+- `/src/components/ColorPicker.tsx` - Custom color picker component
+- `/src/store/theme-editor.ts` - Theme editor state management
+- Updated settings screen to include theme editor
+
+steps:
+- Create ThemeEditor component with color palette editor
+- Implement ColorPicker component for selecting theme colors
+- Create ThemePreview component showing live theme changes
+- Build form controls for editing all theme properties
+- Add save functionality for custom themes
+- Implement delete functionality for custom themes
+- Add validation for theme color values
+- Update settings screen to show theme editor
+
+tests:
+- Unit: Test theme editor saves custom themes correctly
+- Unit: Test color picker updates theme colors
+- Unit: Test theme preview updates in real-time
+- Integration: Test custom theme can be loaded
+
+acceptance_criteria:
+- Theme editor allows editing all theme colors
+- Custom theme can be saved and loaded
+- Live preview shows theme changes in real-time
+- Custom themes persist across sessions
+- Invalid color values are rejected
+
+validation:
+- Run `bun run build` to verify TypeScript compilation
+- Test theme editor manually in application
+- Verify custom themes save/load correctly
+- Check live preview works smoothly
+
+notes:
+- Use existing theme type definitions
+- Provide preset color palettes for quick selection
+- Consider adding theme templates
+- Ensure editor works on small terminal sizes
diff --git a/tasks/podcast-tui-app/66-theme-selector.md b/tasks/podcast-tui-app/66-theme-selector.md
new file mode 100644
index 0000000..8f95eb3
--- /dev/null
+++ b/tasks/podcast-tui-app/66-theme-selector.md
@@ -0,0 +1,56 @@
+# 66. Add Theme Selector in Settings
+
+meta:
+ id: podcast-tui-app-66
+ feature: podcast-tui-app
+ priority: P1
+ depends_on: [59, 60, 61, 62, 63, 64, 65]
+ tags: [theming, settings, selector, solidjs]
+
+objective:
+- Add theme selection UI in settings screen
+- Display all available themes (default, Catppuccin, Gruvbox, Tokyo, Nord, custom)
+- Allow users to select and switch themes
+- Show currently selected theme
+- Persist theme preference
+
+deliverables:
+- `/src/components/ThemeSelector.tsx` - Theme selector component
+- Updated `/src/components/SettingsScreen.tsx` to include theme selector
+- Updated `/src/store/theme.ts` to handle theme preference persistence
+- Theme selector in settings navigation
+
+steps:
+- Create ThemeSelector component with theme list
+- Implement theme selection logic
+- Display current theme with visual indicator
+- Add theme descriptions or icons
+- Integrate theme selector into Settings screen
+- Save theme preference to storage
+- Handle theme switching with instant updates
+- Add keyboard navigation for theme list
+
+tests:
+- Unit: Test theme selector displays all themes
+- Unit: Test theme selection updates current theme
+- Unit: Test theme preference saves to storage
+- Integration: Test theme switching works across all components
+
+acceptance_criteria:
+- Theme selector shows all available themes
+- Users can select and switch themes
+- Current theme is clearly indicated
+- Theme preference persists across sessions
+- Theme changes apply immediately to all components
+
+validation:
+- Run `bun run build` to verify TypeScript compilation
+- Test theme selector manually in settings
+- Verify theme preference saves/loads correctly
+- Check theme applies to all UI components
+
+notes:
+- Use existing theme manager for theme switching
+- Consider adding theme search/filter
+- Show theme preview in selector if possible
+- Ensure accessibility for keyboard navigation
diff --git a/tasks/podcast-tui-app/67-browser-redirect.md b/tasks/podcast-tui-app/67-browser-redirect.md
new file mode 100644
index 0000000..ad505cd
--- /dev/null
+++ b/tasks/podcast-tui-app/67-browser-redirect.md
@@ -0,0 +1,57 @@
+# 67. Implement Browser Redirect Flow for OAuth
+
+meta:
+ id: podcast-tui-app-67
+ feature: podcast-tui-app
+ priority: P2
+ depends_on: [04]
+ tags: [oauth, authentication, browser, solidjs]
+
+objective:
+- Implement browser redirect flow for OAuth authentication
+- Handle OAuth callback in terminal application
+- Exchange authorization code for access token
+- Store authentication tokens securely
+
+deliverables:
+- `/src/auth/oauth-redirect.ts` - OAuth redirect handler
+- `/src/auth/oauth-callback.ts` - OAuth callback handler
+- `/src/auth/token-handler.ts` - Token exchange and storage
+- Updated `/src/auth/login-screen.tsx` with OAuth option
+- Updated `/src/auth/authentication-state.ts` for OAuth state
+
+steps:
+- Implement OAuth authorization URL generation with client ID/secret
+- Create OAuth redirect handler to capture callback
+- Handle authorization code exchange with token endpoint
+- Store access token and refresh token securely
+- Implement error handling for OAuth failures
+- Add OAuth state parameter for security
+- Update authentication state to track OAuth login status
+- Add OAuth logout functionality
+
+tests:
+- Unit: Test OAuth authorization URL generation
+- Unit: Test token exchange with valid/invalid code
+- Unit: Test token storage and retrieval
+- Integration: Test OAuth flow from start to finish
+
+acceptance_criteria:
+- OAuth authorization URL is generated correctly
+- OAuth callback is handled without errors
+- Access token is stored securely
+- OAuth flow works with valid credentials
+- OAuth errors are handled gracefully
+
+validation:
+- Run `bun run build` to verify TypeScript compilation
+- Test OAuth flow manually with test credentials
+- Verify token storage in localStorage
+- Check error handling for invalid tokens
+
+notes:
+- Use standard OAuth 2.0 flow (authorization code grant)
+- Document OAuth requirements (client ID, redirect URI)
+- Consider using PKCE for enhanced security
+- Test with real OAuth provider if possible
+- Document limitations and requirements
diff --git a/tasks/podcast-tui-app/68-qr-code-display.md b/tasks/podcast-tui-app/68-qr-code-display.md
new file mode 100644
index 0000000..4f1a2a9
--- /dev/null
+++ b/tasks/podcast-tui-app/68-qr-code-display.md
@@ -0,0 +1,58 @@
+# 68. Build QR Code Display for Mobile Verification
+
+meta:
+ id: podcast-tui-app-68
+ feature: podcast-tui-app
+ priority: P2
+ depends_on: [04]
+ tags: [authentication, qr-code, mobile, verification, solidjs]
+
+objective:
+- Display QR code for mobile device verification
+- Generate QR code from verification URL
+- Handle manual code entry as fallback
+- Show verification status and expiration
+
+deliverables:
+- `/src/components/QrCodeDisplay.tsx` - QR code display component
+- `/src/utils/qr-code-generator.ts` - QR code generation utility
+- `/src/auth/verification-handler.ts` - Verification flow handler
+- Updated `/src/auth/login-screen.tsx` with QR code option
+- Updated `/src/auth/code-validation.tsx` for manual entry
+
+steps:
+- Integrate QR code generation library (e.g., `qrcode` package)
+- Create QRCodeDisplay component with generated QR image
+- Implement verification URL generation
+- Add manual code entry fallback UI
+- Show verification expiration timer
+- Display verification success/failure status
+- Handle QR code scan timeout
+- Update authentication state on successful verification
+
+tests:
+- Unit: Test QR code generation
+- Unit: Test verification URL generation
+- Unit: Test verification code validation
+- Integration: Test complete verification flow
+
+acceptance_criteria:
+- QR code is generated correctly from verification URL
+- QR code is displayed in terminal
+- Manual code entry works as fallback
+- Verification status is shown clearly
+- Verification expires after timeout
+- Successful verification updates auth state
+
+validation:
+- Run `bun run build` to verify TypeScript compilation
+- Test QR code display manually
+- Test manual code entry fallback
+- Verify verification flow works end-to-end
+
+notes:
+- Use `qrcode` or similar library for QR generation
+- Display QR code in ASCII or image format
+- Consider using external scanner app
+- Add verification expiration (e.g., 5 minutes)
+- Document mobile app requirements for scanning