sync: apply add-dark-light-mode delta specs to main specs

This commit is contained in:
Marko Djordjevic 2026-02-13 09:37:06 +01:00
parent 3da4987f89
commit a8f9327d19
3 changed files with 172 additions and 292 deletions

View file

@ -1,274 +1,121 @@
## ADDED Requirements ## MODIFIED Requirements
### Requirement: Monospace typography
The application SHALL use monospace fonts throughout the entire interface.
#### Scenario: Primary font family
- **WHEN** CSS font-family is applied
- **THEN** system uses font stack: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace
#### Scenario: Font loading
- **WHEN** application loads
- **THEN** system loads JetBrains Mono font from Google Fonts or local files with weights: 400, 500, 700
#### Scenario: All text elements
- **WHEN** rendering any text (buttons, labels, inputs, tooltips, headings)
- **THEN** all text uses monospace font family without exception
#### Scenario: Number formatting
- **WHEN** displaying numbers (prices, timestamps, counts)
- **THEN** uses tabular-nums CSS property for aligned columns
### Requirement: Matrix-style color scheme ### Requirement: Matrix-style color scheme
The application SHALL use a dark background with neon green (#00ff41) accent color scheme. The application SHALL use a dark background with neon green (#00ff41) accent color scheme in dark mode and a light background with muted green accents in light mode.
#### Scenario: Background colors #### Scenario: Dark mode background colors
- **WHEN** rendering main layout - **WHEN** rendering main layout in dark mode
- **THEN** page background is #0a0e0a (near black), sidebar background is #0d110d, and chart background is #000000 - **THEN** page background is #0a0e0a (near black), sidebar background is #0d110d, and chart background is #000000
#### Scenario: Primary accent color #### Scenario: Dark mode primary accent color
- **WHEN** highlighting interactive elements, active states, or success messages - **WHEN** highlighting interactive elements in dark mode
- **THEN** uses #00ff41 (matrix green) as the primary accent color - **THEN** uses #00ff41 (matrix green) as the primary accent color
#### Scenario: Secondary accent colors #### Scenario: Dark mode secondary accent colors
- **WHEN** rendering labels or status indicators - **WHEN** rendering labels or status indicators in dark mode
- **THEN** uses #ff0040 (neon red) for break_down/destructive, #00ff41 (neon green) for break_up/success, #00d4ff (neon cyan) for informational, #ffff00 (neon yellow) for warnings - **THEN** uses #ff0040 (neon red) for break_down/destructive, #00ff41 (neon green) for break_up/success, #00d4ff (neon cyan) for informational, #ffff00 (neon yellow) for warnings
#### Scenario: Text colors #### Scenario: Dark mode text colors
- **WHEN** rendering text - **WHEN** rendering text in dark mode
- **THEN** primary text is #00ff41, secondary text is #00cc33 (dimmer green), and disabled text is #003311 (very dim green) - **THEN** primary text is #00ff41, secondary text is #00cc33, and disabled text is #003311
#### Scenario: Border colors #### Scenario: Dark mode border colors
- **WHEN** rendering borders - **WHEN** rendering borders in dark mode
- **THEN** uses #00ff41 with 1px solid for active elements, #003311 for inactive borders - **THEN** uses #00ff41 with 1px solid for active elements, #003311 for inactive borders
### Requirement: Neon glow effects #### Scenario: Light mode background colors
The application SHALL apply glow effects to active and interactive elements. - **WHEN** rendering main layout in light mode
- **THEN** page background is #f8faf8 (off-white with green tint), sidebar background is #f0f4f0, and chart background is #ffffff
#### Scenario: Button hover glow #### Scenario: Light mode primary accent color
- **WHEN** user hovers over any button - **WHEN** highlighting interactive elements in light mode
- **THEN** uses #16a34a (green-600) as the primary accent color
#### Scenario: Light mode text colors
- **WHEN** rendering text in light mode
- **THEN** primary text is #1a1a2e (near-black), secondary text is #4a5568 (gray-600), and disabled text is #a0aec0 (gray-400)
#### Scenario: Light mode border colors
- **WHEN** rendering borders in light mode
- **THEN** uses #d1d5db (gray-300) for borders, #16a34a for active element borders
### Requirement: Neon glow effects
The application SHALL apply glow effects to active and interactive elements in dark mode only.
#### Scenario: Button hover glow in dark mode
- **WHEN** user hovers over any button in dark mode
- **THEN** button shows box-shadow: 0 0 10px #00ff41, 0 0 20px #00ff4180 - **THEN** button shows box-shadow: 0 0 10px #00ff41, 0 0 20px #00ff4180
#### Scenario: Active tool glow #### Scenario: No glow in light mode
- **WHEN** a tool is active (selected) - **WHEN** user hovers over any button in light mode
- **THEN** button shows pulsing glow animation with box-shadow: 0 0 15px #00ff41, 0 0 30px #00ff4180 - **THEN** button shows standard hover state (subtle background change) without neon glow effects
#### Scenario: Selected element glow #### Scenario: Active tool glow in dark mode
- **WHEN** a line or label is selected - **WHEN** a tool is active (selected) in dark mode
- **THEN** element shows glow effect with filter: drop-shadow(0 0 8px #00ff41) - **THEN** button shows pulsing glow animation
#### Scenario: Input focus glow #### Scenario: Active tool highlight in light mode
- **WHEN** user focuses on text input or search field - **WHEN** a tool is active (selected) in light mode
- **THEN** input shows border glow: box-shadow: 0 0 8px #00ff41 - **THEN** button shows solid green background/border highlight without glow animation
#### Scenario: Cursor circle glow
- **WHEN** drawing line with cursor circle visible
- **THEN** cursor circle has stroke glow with filter: drop-shadow(0 0 4px currentColor)
### Requirement: ASCII-style borders
The application SHALL use terminal-inspired border styling with corner characters.
#### Scenario: Container borders
- **WHEN** rendering bordered containers (Toolbox, label list sections)
- **THEN** uses 1px solid borders with #00ff41 color
#### Scenario: Border corners with pseudo-elements
- **WHEN** rendering section headers or important containers
- **THEN** uses CSS ::before and ::after pseudo-elements to display ASCII corner characters: ┌ ┐ └ ┘
#### Scenario: Separator lines
- **WHEN** rendering section separators
- **THEN** uses border-top: 1px solid #003311 with optional ASCII characters (─) via pseudo-elements
#### Scenario: Card-style containers
- **WHEN** rendering label list entries or modal dialogs
- **THEN** containers have 1px solid border with subtle inset shadow for depth
### Requirement: Terminal-like feedback messages
The application SHALL display command-style feedback for user actions.
#### Scenario: Success message format
- **WHEN** user completes an action successfully (delete, create, export)
- **THEN** displays message in format: `> SUCCESS: <action> completed [<count> items]` in green text
#### Scenario: Error message format
- **WHEN** an error occurs
- **THEN** displays message in format: `> ERROR: <description> [code: <error_code>]` in red text
#### Scenario: Info message format
- **WHEN** displaying informational message
- **THEN** displays message in format: `> INFO: <message>` in cyan text
#### Scenario: Message container styling
- **WHEN** displaying any feedback message
- **THEN** container has monospace font, left-aligned text, subtle border, and auto-dismiss after 4 seconds
#### Scenario: Message animation
- **WHEN** feedback message appears
- **THEN** slides in from top with fade-in animation (0.3s ease-out)
### Requirement: Minimalist icon treatment
The application SHALL use simplified, outline-style icons or ASCII alternatives.
#### Scenario: Lucide icon styling
- **WHEN** rendering Lucide React icons
- **THEN** icons use stroke-width: 1.5, size: 20px, and color matches text color (#00ff41)
#### Scenario: Icon hover effect
- **WHEN** user hovers over icon button
- **THEN** icon glows with filter: drop-shadow(0 0 4px currentColor)
#### Scenario: ASCII alternative icons (optional)
- **WHEN** rendering simple actions (delete, expand, collapse)
- **THEN** optionally uses ASCII characters: [×] for delete, [▼] for expand, [▲] for collapse, [>] for actions
#### Scenario: Icon color consistency
- **WHEN** icon is in active/selected state
- **THEN** icon color is #00ff41
- **WHEN** icon is in disabled state
- **THEN** icon color is #003311
### Requirement: High contrast for readability
The application SHALL maintain WCAG AA contrast ratios for all text.
#### Scenario: Primary text contrast
- **WHEN** displaying primary text (#00ff41) on dark background (#0a0e0a)
- **THEN** contrast ratio is at least 4.5:1 (WCAG AA standard)
#### Scenario: Secondary text contrast
- **WHEN** displaying secondary text (#00cc33) on dark background
- **THEN** contrast ratio is at least 4.5:1
#### Scenario: Button text contrast
- **WHEN** button is in any state (default, hover, active, disabled)
- **THEN** text maintains minimum 4.5:1 contrast with background
#### Scenario: Chart element visibility
- **WHEN** rendering lines and markers on chart
- **THEN** all annotations have sufficient contrast against black background and candles
### Requirement: Simplified button styling
The application SHALL use minimal, flat button design with terminal aesthetic.
#### Scenario: Default button appearance
- **WHEN** rendering buttons in default state
- **THEN** buttons have transparent background, 1px solid #00ff41 border, #00ff41 text, 4px padding, and no rounded corners (border-radius: 0)
#### Scenario: Hover button appearance
- **WHEN** user hovers over button
- **THEN** background changes to #00ff4110 (10% opacity), border glows, and text remains #00ff41
#### Scenario: Active button appearance
- **WHEN** button is active/pressed
- **THEN** background is #00ff4120 (20% opacity), border is 2px solid, and includes pulsing glow animation
#### Scenario: Disabled button appearance
- **WHEN** button is disabled
- **THEN** background is transparent, border is #003311, text is #003311, and no hover effects
#### Scenario: Destructive button styling
- **WHEN** button represents destructive action (delete)
- **THEN** uses #ff0040 (neon red) for border and text instead of green, with matching red glow on hover
### Requirement: Cyber-retro aesthetic elements
The application SHALL include subtle design elements that enhance the hacker theme.
#### Scenario: Scanline effect (optional)
- **WHEN** rendering main container
- **THEN** applies subtle CSS repeating-linear-gradient overlay simulating CRT scanlines with 2px spacing at 5% opacity
#### Scenario: Noise texture (optional)
- **WHEN** rendering background
- **THEN** applies subtle noise texture using CSS filter or background-image at 3% opacity for grain effect
#### Scenario: Typewriter animation for messages
- **WHEN** displaying new feedback message
- **THEN** text appears with brief letter-by-letter typing animation (0.02s per character, max 0.5s total)
#### Scenario: Flicker animation on focus
- **WHEN** user focuses on input field
- **THEN** border shows brief flicker animation (0.1s) simulating electrical surge
#### Scenario: ASCII art branding (optional)
- **WHEN** application loads or in header
- **THEN** displays application name in ASCII art style using monospace font
### Requirement: Responsive dark theme ### Requirement: Responsive dark theme
The application SHALL maintain theme consistency across all components and states. The application SHALL maintain theme consistency across all components and states in both dark and light modes.
#### Scenario: Modal dialogs #### Scenario: Modal dialogs in dark mode
- **WHEN** displaying confirmation dialogs - **WHEN** displaying confirmation dialogs in dark mode
- **THEN** modal has dark background (#0d110d), neon green border, monospace font, and terminal-style title (e.g., "> CONFIRM ACTION") - **THEN** modal has dark background (#0d110d), neon green border, monospace font
#### Scenario: Input fields #### Scenario: Modal dialogs in light mode
- **WHEN** rendering text inputs or search fields - **WHEN** displaying confirmation dialogs in light mode
- **THEN** inputs have transparent background, #00ff41 border, #00ff41 text, #00ff4120 placeholder, and cursor color #00ff41 - **THEN** modal has white background, gray border, monospace font
#### Scenario: Dropdown menus #### Scenario: Input fields in dark mode
- **WHEN** displaying filter or select dropdowns - **WHEN** rendering text inputs in dark mode
- **THEN** dropdown has dark background (#0d110d), neon green border, #00ff41 option text, hover state with #00ff4120 background - **THEN** inputs have transparent background, #00ff41 border, #00ff41 text
#### Scenario: Scrollbars #### Scenario: Input fields in light mode
- **WHEN** content requires scrolling - **WHEN** rendering text inputs in light mode
- **THEN** custom scrollbar with #003311 track, #00ff41 thumb, and 8px width - **THEN** inputs have white background, gray-300 border, near-black text
#### Scenario: Tooltips #### Scenario: Scrollbars in dark mode
- **WHEN** displaying tooltips on hover - **WHEN** content requires scrolling in dark mode
- **THEN** tooltip has dark background (#0d110d), 1px #00ff41 border, monospace font, and terminal-style text - **THEN** scrollbar track is #003311, thumb is #00ff41
### Requirement: Animation performance #### Scenario: Scrollbars in light mode
The application SHALL use performant CSS animations that don't impact chart rendering. - **WHEN** content requires scrolling in light mode
- **THEN** scrollbar track is #e2e8f0, thumb is #94a3b8
#### Scenario: GPU acceleration
- **WHEN** applying animations (glow, pulse, fade)
- **THEN** uses CSS transform and opacity properties with will-change hints for GPU acceleration
#### Scenario: Animation duration
- **WHEN** defining animations
- **THEN** all animations complete within 0.5s, with most hover effects at 0.2s
#### Scenario: Reduced motion support
- **WHEN** user has prefers-reduced-motion enabled
- **THEN** system disables glow animations, typewriter effects, and pulsing, keeping only instant transitions
#### Scenario: Chart performance
- **WHEN** theme is active and chart is rendering
- **THEN** SVG overlay and chart rendering maintains 60fps without jank from theme effects
### Requirement: Tailwind CSS configuration ### Requirement: Tailwind CSS configuration
The Tailwind config SHALL be updated to support hacker theme tokens. The Tailwind config SHALL support theme tokens for both dark and light modes via CSS variables.
#### Scenario: Custom colors in tailwind.config #### Scenario: CSS variables for dark mode
- **WHEN** tailwind.config.js is parsed - **WHEN** the `dark` class is on `<html>`
- **THEN** defines custom colors: matrix: '#00ff41', matrixDim: '#00cc33', matrixDark: '#003311', neonRed: '#ff0040', neonCyan: '#00d4ff', neonYellow: '#ffff00', terminal: '#0a0e0a', terminalLight: '#0d110d' - **THEN** CSS variables resolve to hacker-theme dark palette values
#### Scenario: Custom font families #### Scenario: CSS variables for light mode
- **WHEN** tailwind.config.js is parsed - **WHEN** the `dark` class is NOT on `<html>`
- **THEN** defines fontFamily: { mono: ['JetBrains Mono', 'Fira Code', 'Courier New', 'monospace'] } - **THEN** CSS variables resolve to light theme palette values
#### Scenario: Custom animations
- **WHEN** tailwind.config.js is parsed
- **THEN** defines keyframes for 'glow-pulse', 'flicker', 'scanline-move' and corresponding animation utilities
#### Scenario: Custom shadows
- **WHEN** tailwind.config.js is parsed
- **THEN** defines boxShadow: { 'glow-sm': '0 0 8px #00ff41', 'glow': '0 0 15px #00ff41, 0 0 30px #00ff4180', 'glow-lg': '0 0 20px #00ff41, 0 0 40px #00ff4180' }
### Requirement: globals.css updates ### Requirement: globals.css updates
The globals.css file SHALL define base styles and CSS variables for the hacker theme. The globals.css file SHALL define CSS variables for both light and dark themes.
#### Scenario: CSS custom properties #### Scenario: Light mode CSS variables
- **WHEN** globals.css is loaded - **WHEN** globals.css is loaded without `dark` class
- **THEN** defines CSS variables: --color-matrix, --color-matrix-dim, --color-matrix-dark, --color-neon-red, --color-neon-cyan, --color-terminal, --font-mono - **THEN** `:root` defines light theme color variables
#### Scenario: Base body styles #### Scenario: Dark mode CSS variables
- **WHEN** page loads - **WHEN** globals.css is loaded with `dark` class on `<html>`
- **THEN** body element has background: --color-terminal, color: --color-matrix, font-family: --font-mono, and -webkit-font-smoothing: antialiased - **THEN** `.dark` selector overrides with hacker-theme dark palette variables
#### Scenario: Selection styling ## ADDED Requirements
- **WHEN** user selects text
- **THEN** selection background is #00ff4140 (40% opacity) and text is #00ff41
#### Scenario: Scrollbar styling ### Requirement: Cyber-retro effects dark-mode only
- **WHEN** globals.css is loaded The application SHALL only apply CRT scanline effects, noise textures, and flicker animations in dark mode.
- **THEN** defines custom scrollbar styles using ::-webkit-scrollbar pseudo-elements with theme colors
#### Scenario: Scanlines in dark mode
- **WHEN** rendering main container in dark mode
- **THEN** applies subtle CRT scanline overlay at 5% opacity
#### Scenario: No scanlines in light mode
- **WHEN** rendering main container in light mode
- **THEN** no scanline or CRT effects are applied

View file

@ -0,0 +1,72 @@
## ADDED Requirements
### Requirement: System theme detection
The application SHALL detect the user's operating system color scheme preference on initial load and apply the matching theme (dark or light).
#### Scenario: System prefers dark mode
- **WHEN** the user's OS is set to dark mode and no manual preference is stored
- **THEN** the application renders with the dark theme
#### Scenario: System prefers light mode
- **WHEN** the user's OS is set to light mode and no manual preference is stored
- **THEN** the application renders with the light theme
#### Scenario: System preference changes while app is open
- **WHEN** the user changes their OS color scheme while the app is open and theme is set to "system"
- **THEN** the application switches to match the new system preference without page reload
### Requirement: Manual theme toggle
The application SHALL provide a toggle control that cycles through three modes: System, Light, and Dark.
#### Scenario: Toggle from system to light
- **WHEN** user clicks the theme toggle while in "system" mode
- **THEN** the theme switches to "light" mode regardless of system preference
#### Scenario: Toggle from light to dark
- **WHEN** user clicks the theme toggle while in "light" mode
- **THEN** the theme switches to "dark" mode regardless of system preference
#### Scenario: Toggle from dark to system
- **WHEN** user clicks the theme toggle while in "dark" mode
- **THEN** the theme switches to "system" mode and applies the current OS preference
#### Scenario: Toggle icon reflects current mode
- **WHEN** the theme is set to "system"
- **THEN** the toggle displays a monitor icon
- **WHEN** the theme is set to "light"
- **THEN** the toggle displays a sun icon
- **WHEN** the theme is set to "dark"
- **THEN** the toggle displays a moon icon
### Requirement: Theme preference persistence
The application SHALL persist the user's theme choice in localStorage so it survives page refreshes and browser restarts.
#### Scenario: Preference survives refresh
- **WHEN** user selects "dark" mode and refreshes the page
- **THEN** the application loads in dark mode without flashing light mode first
#### Scenario: Clearing preference
- **WHEN** user selects "system" mode
- **THEN** the stored preference is set to "system" and the OS preference is followed
### Requirement: No flash of incorrect theme (FOUC prevention)
The application SHALL apply the correct theme before the first paint to prevent a visible flash of the wrong color scheme.
#### Scenario: Dark mode user loads page
- **WHEN** a user with dark mode preference stored loads the page
- **THEN** the page renders dark from the first visible frame with no white flash
#### Scenario: Light mode user loads page
- **WHEN** a user with light mode preference stored loads the page
- **THEN** the page renders light from the first visible frame with no dark flash
### Requirement: ThemeProvider integration
The application SHALL use a ThemeProvider component wrapping the app in the root layout. The provider SHALL use the `class` strategy to add/remove the `dark` class on the `<html>` element.
#### Scenario: Dark class applied
- **WHEN** the active theme is dark
- **THEN** the `<html>` element has the `dark` class
#### Scenario: Dark class removed
- **WHEN** the active theme is light
- **THEN** the `<html>` element does NOT have the `dark` class

View file

@ -1,59 +1,20 @@
## ADDED Requirements ## ADDED Requirements
### Requirement: Dark mode layout ### Requirement: Theme toggle in sidebar
The application SHALL use a dark theme based on Tailwind's Slate-900 color palette. The root layout MUST set a dark background. All UI components (sidebar, buttons, text) SHALL use colors consistent with the dark theme. The UI shell SHALL include a theme toggle button in the sidebar. The button SHALL be positioned at the bottom of the sidebar, visually separated from the tool buttons.
#### Scenario: Dark theme renders #### Scenario: Toggle button renders
- **WHEN** the application loads - **WHEN** the application loads
- **THEN** the page background is Slate-900 (dark), text is light, and all UI elements follow the dark color scheme - **THEN** a theme toggle button is visible at the bottom of the sidebar
### Requirement: Sidebar toolbox #### Scenario: Toggle button displays correct icon
The application SHALL display a fixed sidebar on the left side of the viewport. The sidebar SHALL contain tool buttons: "Label: Break Up", "Label: Break Down", "Draw Line", "Delete". Each button SHALL use a lucide-react icon and a text label. The currently active tool button SHALL be visually highlighted. - **WHEN** the current theme mode is "system"
- **THEN** the button shows a monitor icon (lucide-react `Monitor`)
- **WHEN** the current theme mode is "light"
- **THEN** the button shows a sun icon (lucide-react `Sun`)
- **WHEN** the current theme mode is "dark"
- **THEN** the button shows a moon icon (lucide-react `Moon`)
#### Scenario: Sidebar renders with tools #### Scenario: Toggle button has tooltip
- **WHEN** the application loads - **WHEN** user hovers over the theme toggle button
- **THEN** the sidebar displays all four tool buttons with icons and labels - **THEN** a tooltip displays the current mode name (e.g., "Theme: System", "Theme: Light", "Theme: Dark")
#### Scenario: Active tool highlight
- **WHEN** user selects a tool
- **THEN** that tool's button is visually highlighted (distinct background/border color) and other buttons return to default state
### Requirement: Main chart area
The main content area SHALL occupy the full viewport width minus the sidebar width. The chart component MUST fill this area. The layout SHALL use CSS flexbox or grid to ensure the sidebar and chart area are side by side.
#### Scenario: Layout structure
- **WHEN** the application loads with candle data
- **THEN** the sidebar appears on the left and the chart fills the remaining space
### Requirement: File upload interface
The application SHALL provide a CSV file upload interface accessible from the sidebar. The upload component SHALL trigger the POST /api/upload endpoint. On success, the component SHALL add the newly created chart to the chart selector and set it as the active chart, triggering the chart and annotation data to refresh for the new chart.
#### Scenario: Upload via UI
- **WHEN** user selects a CSV file through the upload interface
- **THEN** the file is sent to the upload API, a new chart is created, the chart selector updates to include the new chart, and the new chart becomes active with its candles displayed
#### Scenario: Upload error display
- **WHEN** the upload API returns an error
- **THEN** the UI displays the error message to the user and no chart is created
### Requirement: Export button
The application SHALL provide an "Export" button that triggers a download of the annotations CSV. Clicking the button SHALL navigate to or fetch from the `GET /api/export` endpoint, resulting in a CSV file download.
#### Scenario: Export annotations
- **WHEN** user clicks the "Export" button
- **THEN** a CSV file named "annotations.csv" downloads containing all annotation data
### Requirement: Theme-aware Manage Annotation Types link
The "Manage Annotation Types" link in the sidebar header SHALL use theme-aware styling consistent with the rest of the application. The link SHALL NOT use hardcoded color values. It SHALL use `text-muted-foreground` and `hover:text-foreground` Tailwind classes to respect both light and dark themes.
#### Scenario: Link styling in dark mode
- **WHEN** the application is in dark mode
- **THEN** the "Manage Annotation Types" link uses muted foreground color and brightens on hover, consistent with the dark theme
#### Scenario: Link styling in light mode
- **WHEN** the application is in light mode
- **THEN** the "Manage Annotation Types" link uses muted foreground color and darkens on hover, consistent with the light theme
#### Scenario: Link visual consistency
- **WHEN** the sidebar renders
- **THEN** the "Manage Annotation Types" link does not use underline styling and visually matches other sidebar text elements