diff --git a/PRD.md b/PRD.md index 82a9896..dc4a928 100644 --- a/PRD.md +++ b/PRD.md @@ -15,6 +15,13 @@ TheNoiseClock is a SwiftUI-based iOS application that combines a customizable di - **Portrait and landscape orientation support** with responsive font sizing - **Optimal font sizing** that uses all available space efficiently - **Immediate updates** on orientation changes and tab bar visibility changes +- **Fixed-width digit rendering** to prevent layout shifts and jumping +- **Individual digit views** with consistent spacing and alignment +- **Font customization** with family, weight, and design selection +- **Dynamic dot sizing** that matches selected font weight +- **Safe area handling** with proper Dynamic Island avoidance +- **Full-screen mode** with status bar hiding and tab bar expansion +- **Orientation-aware spacing** for optimal layout in all orientations ### 2. Clock Customization - **Color customization**: User-selectable digit colors with color picker @@ -24,12 +31,21 @@ TheNoiseClock is a SwiftUI-based iOS application that combines a customizable di - **Opacity controls**: Separate opacity for clock digits and overlays - **Random color mode**: Automatically changes digit color every minute - **Preset themes**: Quick "Night" (black/white) and "Day" (white/black) themes +- **Font family selection**: Choose from System, San Francisco, Monaco, Courier fonts +- **Font weight options**: Ultra Light, Thin, Light, Regular, Medium, Semibold, Bold, Heavy, Black +- **Font design choices**: Default, Serif, Rounded, Monospaced designs +- **Live font preview**: Real-time preview of font changes in settings +- **Font persistence**: All font settings saved and restored automatically ### 3. Display Modes - **Normal mode**: Standard interface with navigation and settings - **Display mode**: Full-screen clock activated by long-press (0.6 seconds) - **Automatic UI hiding**: Tab bar and navigation elements hide in display mode - **Smooth transitions**: Animated transitions between modes +- **Status bar control**: Status bar automatically hidden in full-screen mode +- **Safe area expansion**: Clock expands into tab bar area when hidden +- **Dynamic Island awareness**: Proper spacing to avoid Dynamic Island overlap +- **Orientation handling**: Full-screen mode works in both portrait and landscape ### 4. Information Overlays - **Battery level display**: Real-time battery percentage with icon @@ -70,6 +86,44 @@ TheNoiseClock is a SwiftUI-based iOS application that combines a customizable di - **Next trigger preview**: Shows when the next alarm will fire - **Responsive time picker**: Font sizes adapt to available space and orientation +## Advanced Clock Display Features + +### Fixed-Width Digit Rendering +- **Individual digit views**: Each digit (0-9) rendered in its own view component +- **Consistent spacing**: All digits use the width of the widest digit ("8") for uniform layout +- **Height consistency**: All digits use the height of the tallest digit ("8") to prevent vertical jumping +- **Layout stability**: No shifting or jumping when time changes (e.g., "11" to "12") +- **Perfect centering**: Each digit is centered within its fixed-width container + +### Font Customization System +- **Font family selection**: System, San Francisco, Monaco, Courier options +- **Weight variations**: 9 weight options from Ultra Light to Black +- **Design choices**: Default, Serif, Rounded, Monospaced designs +- **Live preview**: Real-time font preview in settings interface +- **UIFont integration**: Proper font measurement for accurate sizing +- **Weight-based dot scaling**: Colon dots automatically scale with font weight + +### Dynamic Layout and Sizing +- **GeometryReader integration**: Real-time container size detection +- **Orientation-aware calculations**: Different sizing algorithms for portrait vs landscape +- **Safe area handling**: Proper Dynamic Island avoidance and tab bar expansion +- **Maximum space utilization**: Font sizes calculated to use all available space +- **Responsive updates**: Immediate recalculation on orientation or layout changes + +### Advanced Spacing and Alignment +- **Orientation-aware spacing**: Different spacing values for portrait vs landscape +- **Consistent segment spacing**: Uniform spacing between hours, minutes, seconds +- **Dot weight matching**: Colon dots scale with selected font weight +- **Overflow prevention**: Spacing calculations prevent content clipping +- **Perfect centering**: All elements centered both horizontally and vertically + +### Full-Screen Mode Enhancements +- **Status bar hiding**: Automatic status bar hiding in full-screen mode +- **Tab bar expansion**: Clock expands into tab bar area when hidden +- **Safe area management**: Proper handling of Dynamic Island and other safe areas +- **Smooth transitions**: Animated transitions between normal and full-screen modes +- **Orientation support**: Full-screen mode works seamlessly in all orientations + ## Technical Architecture ### Code Organization Principles @@ -122,7 +176,9 @@ These principles are fundamental to the project's long-term success and must be - Visual settings (colors, glow, scale, opacity) - Overlay settings (battery, date, opacity) - Background settings + - Font customization (family, weight, design) - Color caching for performance optimization + - Persistent storage with JSON encoding/decoding - **Alarm**: Codable struct for comprehensive alarm data - UUID identifier - Time and enabled state @@ -200,7 +256,7 @@ TheNoiseClock/ │ │ └── View+Extensions.swift # Common view modifiers and responsive utilities │ └── Utilities/ │ ├── ColorUtils.swift # Color manipulation utilities -│ ├── FontUtils.swift # Font sizing and typography utilities +│ ├── FontUtils.swift # Font sizing, typography, and customization utilities │ └── NotificationUtils.swift # Notification helper functions ├── Models/ │ ├── ClockStyle.swift # Clock customization data model @@ -216,7 +272,7 @@ TheNoiseClock/ │ │ ├── ClockView.swift # Main clock display view │ │ ├── ClockSettingsView.swift # Clock customization interface │ │ └── Components/ -│ │ ├── TimeDisplayView.swift # Segmented time display component +│ │ ├── TimeDisplayView.swift # Advanced segmented time display with fixed-width digits │ │ ├── BatteryOverlayView.swift # Battery level overlay │ │ ├── DateOverlayView.swift # Date display overlay │ │ └── TopOverlayView.swift # Combined overlay container @@ -360,6 +416,17 @@ The following changes **automatically require** PRD updates: - **Combine**: Timer publishers and reactive programming - **Observation**: Modern state management with @Observable - **Foundation**: Core system frameworks and utilities +- **UIKit**: UIFont integration for precise text measurement and font customization + +### Font and Typography Utilities +- **FontUtils.optimalFontSize()**: Calculates optimal font size for portrait orientation +- **FontUtils.maximumStretchedFontSize()**: Calculates maximum font size for stretched mode +- **FontUtils.customFont()**: Creates SwiftUI Font with custom family, weight, and design +- **FontUtils.customUIFont()**: Creates UIFont for precise text measurement +- **FontUtils.weightMultiplier()**: Calculates dot size multiplier based on font weight +- **FontUtils.calculateMaxTextWidth()**: Measures text width for fixed-width calculations +- **FontUtils.calculateMaxTextHeight()**: Measures text height for consistent digit sizing +- **FontUtils.timePickerFontSize()**: Optimized font sizing for DatePicker components ### Performance Considerations - **Smart timer management**: Conditional timers based on settings @@ -370,6 +437,9 @@ The following changes **automatically require** PRD updates: - **Dictionary lookups**: O(1) alarm access instead of linear search - **Smooth animations**: Hardware-accelerated transitions - **Preloaded audio**: Instant sound playback +- **Font measurement caching**: Efficient text size calculations +- **Fixed-width calculations**: Pre-calculated digit dimensions for consistent layout +- **Orientation-aware sizing**: Optimized font sizing algorithms for different orientations ## Future Enhancement Opportunities - **Additional sound types**: More white noise variants