From c9b1b3cf62a89145bf941f7d6a9d807019559a12 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sat, 31 Jan 2026 11:05:55 -0600 Subject: [PATCH] Signed-off-by: Matt Bruce --- PRD.md | 7 +- README.md | 2 +- TheNoiseClock.xcodeproj/project.pbxproj | 31 +++++--- .../xcschemes/xcschememanagement.plist | 2 +- .../Shared/{ => Design}/BrandingConfig.swift | 0 .../Shared/Design/UIConstants+Animation.swift | 19 +++++ .../Shared/Design/UIConstants+Colors.swift | 21 ++++++ .../Shared/Design/UIConstants+Layout.swift | 45 ++++++++++++ TheNoiseClock/Shared/Design/UIConstants.swift | 70 +------------------ 9 files changed, 114 insertions(+), 83 deletions(-) rename TheNoiseClock/Shared/{ => Design}/BrandingConfig.swift (100%) create mode 100644 TheNoiseClock/Shared/Design/UIConstants+Animation.swift create mode 100644 TheNoiseClock/Shared/Design/UIConstants+Colors.swift create mode 100644 TheNoiseClock/Shared/Design/UIConstants+Layout.swift diff --git a/PRD.md b/PRD.md index fe19f9b..8322831 100644 --- a/PRD.md +++ b/PRD.md @@ -373,10 +373,13 @@ TheNoiseClock/ │ │ ├── Debug.xcconfig # Debug settings │ │ └── Release.xcconfig # Release settings │ ├── Shared/ -│ │ ├── BrandingConfig.swift # Bedrock branding + launch config │ │ ├── Design/ +│ │ │ ├── BrandingConfig.swift # Bedrock branding + launch config │ │ │ ├── AppConstants.swift # App-wide constants and configuration -│ │ │ ├── UIConstants.swift # UI-specific constants (colors, sizes, etc.) +│ │ │ ├── UIConstants.swift # UI constants namespace +│ │ │ ├── UIConstants+Colors.swift # Theme-backed colors +│ │ │ ├── UIConstants+Layout.swift # Spacing/radius/opacity +│ │ │ ├── UIConstants+Animation.swift # Animation curves │ │ │ └── Fonts/ │ │ │ ├── Font.Design.swift │ │ │ ├── Font.Weight.swift diff --git a/README.md b/README.md index ff80fa7..d2dfdad 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ xcodebuild -project TheNoiseClock/TheNoiseClock.xcodeproj -scheme TheNoiseClock The app uses Bedrock for theme tokens, settings UI, and the launch experience. - Theme: `TheNoiseClock/Shared/Theme/NoiseClockTheme.swift` -- Branding config: `TheNoiseClock/Shared/BrandingConfig.swift` +- Branding config: `TheNoiseClock/Shared/Design/BrandingConfig.swift` - Launch screen: `TheNoiseClock/Resources/LaunchScreen.storyboard` To generate an app icon in DEBUG: diff --git a/TheNoiseClock.xcodeproj/project.pbxproj b/TheNoiseClock.xcodeproj/project.pbxproj index 05caf6f..b843864 100644 --- a/TheNoiseClock.xcodeproj/project.pbxproj +++ b/TheNoiseClock.xcodeproj/project.pbxproj @@ -32,9 +32,8 @@ EA384AFB2E6E6B6000CA7D50 /* TheNoiseClock.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TheNoiseClock.app; sourceTree = BUILT_PRODUCTS_DIR; }; EA384B082E6E6B6100CA7D50 /* TheNoiseClockTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TheNoiseClockTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; EA384B122E6E6B6100CA7D50 /* TheNoiseClockUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TheNoiseClockUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - EAD6E3AE5A7F4D3DB37CF6D1 /* Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TheNoiseClock/Configuration/Base.xcconfig; sourceTree = SOURCE_ROOT; }; - EAD6E3AF5A7F4D3DB37CF6D1 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TheNoiseClock/Configuration/Debug.xcconfig; sourceTree = SOURCE_ROOT; }; - EAD6E3B05A7F4D3DB37CF6D1 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TheNoiseClock/Configuration/Release.xcconfig; sourceTree = SOURCE_ROOT; }; + EAD6E3AF5A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TheNoiseClock/Configuration/Debug.xcconfig; sourceTree = SOURCE_ROOT; }; + EAD6E3B05A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TheNoiseClock/Configuration/Release.xcconfig; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ @@ -102,6 +101,7 @@ EA384B0B2E6E6B6100CA7D50 /* TheNoiseClockTests */, EA384B152E6E6B6100CA7D50 /* TheNoiseClockUITests */, EA384AFC2E6E6B6000CA7D50 /* Products */, + EAC057642F2E69E8007F87EA /* Recovered References */, ); sourceTree = ""; }; @@ -115,6 +115,15 @@ name = Products; sourceTree = ""; }; + EAC057642F2E69E8007F87EA /* Recovered References */ = { + isa = PBXGroup; + children = ( + EAD6E3AF5A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Debug.xcconfig */, + EAD6E3B05A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Release.xcconfig */, + ); + name = "Recovered References"; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -300,7 +309,7 @@ /* Begin XCBuildConfiguration section */ EA384B1A2E6E6B6100CA7D50 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EAD6E3AF5A7F4D3DB37CF6D1 /* Debug.xcconfig */; + baseConfigurationReference = EAD6E3AF5A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -365,7 +374,7 @@ }; EA384B1B2E6E6B6100CA7D50 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EAD6E3B05A7F4D3DB37CF6D1 /* Release.xcconfig */; + baseConfigurationReference = EAD6E3B05A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -423,7 +432,7 @@ }; EA384B1D2E6E6B6100CA7D50 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EAD6E3AF5A7F4D3DB37CF6D1 /* Debug.xcconfig */; + baseConfigurationReference = EAD6E3AF5A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -457,7 +466,7 @@ }; EA384B1E2E6E6B6100CA7D50 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EAD6E3B05A7F4D3DB37CF6D1 /* Release.xcconfig */; + baseConfigurationReference = EAD6E3B05A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -491,7 +500,7 @@ }; EA384B202E6E6B6100CA7D50 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EAD6E3AF5A7F4D3DB37CF6D1 /* Debug.xcconfig */; + baseConfigurationReference = EAD6E3AF5A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -514,7 +523,7 @@ }; EA384B212E6E6B6100CA7D50 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EAD6E3B05A7F4D3DB37CF6D1 /* Release.xcconfig */; + baseConfigurationReference = EAD6E3B05A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -537,7 +546,7 @@ }; EA384B232E6E6B6100CA7D50 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EAD6E3AF5A7F4D3DB37CF6D1 /* Debug.xcconfig */; + baseConfigurationReference = EAD6E3AF5A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Debug.xcconfig */; buildSettings = { CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; @@ -558,7 +567,7 @@ }; EA384B242E6E6B6100CA7D50 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EAD6E3B05A7F4D3DB37CF6D1 /* Release.xcconfig */; + baseConfigurationReference = EAD6E3B05A7F4D3DB37CF6D1 /* TheNoiseClock/Configuration/Release.xcconfig */; buildSettings = { CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; diff --git a/TheNoiseClock.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist b/TheNoiseClock.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist index 9fcb510..27be183 100644 --- a/TheNoiseClock.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/TheNoiseClock.xcodeproj/xcuserdata/mattbruce.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ TheNoiseClock.xcscheme_^#shared#^_ orderHint - 2 + 0 diff --git a/TheNoiseClock/Shared/BrandingConfig.swift b/TheNoiseClock/Shared/Design/BrandingConfig.swift similarity index 100% rename from TheNoiseClock/Shared/BrandingConfig.swift rename to TheNoiseClock/Shared/Design/BrandingConfig.swift diff --git a/TheNoiseClock/Shared/Design/UIConstants+Animation.swift b/TheNoiseClock/Shared/Design/UIConstants+Animation.swift new file mode 100644 index 0000000..2668eb3 --- /dev/null +++ b/TheNoiseClock/Shared/Design/UIConstants+Animation.swift @@ -0,0 +1,19 @@ +// +// UIConstants+Animation.swift +// TheNoiseClock +// +// Created by Matt Bruce on 1/31/26. +// + +import SwiftUI +import Bedrock + +extension UIConstants { + + // MARK: - Animation Curves + enum AnimationCurves { + static let smooth = Animation.smooth(duration: Design.Animation.standard) + static let bouncy = Animation.spring(duration: Design.Animation.springDuration, bounce: Design.Animation.springBounce) + static let quick = Animation.easeInOut(duration: Design.Animation.quick) + } +} diff --git a/TheNoiseClock/Shared/Design/UIConstants+Colors.swift b/TheNoiseClock/Shared/Design/UIConstants+Colors.swift new file mode 100644 index 0000000..aea8680 --- /dev/null +++ b/TheNoiseClock/Shared/Design/UIConstants+Colors.swift @@ -0,0 +1,21 @@ +// +// UIConstants+Colors.swift +// TheNoiseClock +// +// Created by Matt Bruce on 1/31/26. +// + +import SwiftUI + +extension UIConstants { + + // MARK: - Colors + enum Colors { + static let accentColor = AppAccent.primary + static let primaryText = AppTextColors.primary + static let secondaryText = AppTextColors.secondary + static let background = AppSurface.primary + static let overlayBackground = AppSurface.overlay + static let overlayBorder = AppBorder.subtle + } +} diff --git a/TheNoiseClock/Shared/Design/UIConstants+Layout.swift b/TheNoiseClock/Shared/Design/UIConstants+Layout.swift new file mode 100644 index 0000000..67060bb --- /dev/null +++ b/TheNoiseClock/Shared/Design/UIConstants+Layout.swift @@ -0,0 +1,45 @@ +// +// UIConstants+Layout.swift +// TheNoiseClock +// +// Created by Matt Bruce on 1/31/26. +// + +import SwiftUI +import Bedrock + +extension UIConstants { + + // MARK: - Spacing + enum Spacing { + static let extraSmall: CGFloat = Design.Spacing.xSmall + static let small: CGFloat = Design.Spacing.small + static let medium: CGFloat = Design.Spacing.medium + static let large: CGFloat = Design.Spacing.large + static let extraLarge: CGFloat = Design.Spacing.xLarge + static let huge: CGFloat = Design.Spacing.xxLarge + } + + // MARK: - Corner Radius + enum CornerRadius { + static let small: CGFloat = Design.CornerRadius.small + static let medium: CGFloat = Design.CornerRadius.large + static let large: CGFloat = 16 + static let extraLarge: CGFloat = Design.CornerRadius.xxLarge + } + + // MARK: - Border Width + enum BorderWidth { + static let thin: CGFloat = Design.LineWidth.hairline + static let normal: CGFloat = Design.LineWidth.thin + static let thick: CGFloat = Design.LineWidth.standard + } + + // MARK: - Opacity + enum Opacity { + static let disabled: Double = Design.Opacity.light + static let secondary: Double = Design.Opacity.accent + static let primary: Double = Design.Opacity.heavy + static let full: Double = 1.0 + } +} diff --git a/TheNoiseClock/Shared/Design/UIConstants.swift b/TheNoiseClock/Shared/Design/UIConstants.swift index 4e7096f..d8953dd 100644 --- a/TheNoiseClock/Shared/Design/UIConstants.swift +++ b/TheNoiseClock/Shared/Design/UIConstants.swift @@ -7,71 +7,5 @@ import SwiftUI -/// UI-specific constants for colors, sizes, and styling -enum UIConstants { - - // MARK: - Colors - enum Colors { - static let accentColor = Color.blue - static let primaryText = Color.white - static let secondaryText = Color.gray - static let background = Color.black - static let overlayBackground = Color.black.opacity(0.25) - static let overlayBorder = Color.white.opacity(0.05) - } - - // MARK: - Font Sizes - enum FontSizes { - static let largeTitle: CGFloat = 34 - static let title: CGFloat = 28 - static let title2: CGFloat = 22 - static let title3: CGFloat = 20 - static let headline: CGFloat = 17 - static let body: CGFloat = 17 - static let callout: CGFloat = 16 - static let subheadline: CGFloat = 15 - static let footnote: CGFloat = 13 - static let caption: CGFloat = 12 - static let caption2: CGFloat = 11 - } - - // MARK: - Spacing - enum Spacing { - static let extraSmall: CGFloat = 4 - static let small: CGFloat = 8 - static let medium: CGFloat = 12 - static let large: CGFloat = 16 - static let extraLarge: CGFloat = 20 - static let huge: CGFloat = 24 - } - - // MARK: - Corner Radius - enum CornerRadius { - static let small: CGFloat = 8 - static let medium: CGFloat = 12 - static let large: CGFloat = 16 - static let extraLarge: CGFloat = 20 - } - - // MARK: - Border Width - enum BorderWidth { - static let thin: CGFloat = 0.5 - static let normal: CGFloat = 1 - static let thick: CGFloat = 2 - } - - // MARK: - Opacity - enum Opacity { - static let disabled: Double = 0.3 - static let secondary: Double = 0.6 - static let primary: Double = 0.8 - static let full: Double = 1.0 - } - - // MARK: - Animation Curves - enum AnimationCurves { - static let smooth = Animation.smooth(duration: AppConstants.AnimationDurations.medium) - static let bouncy = Animation.bouncy(duration: AppConstants.AnimationDurations.bouncy) - static let quick = Animation.easeInOut(duration: AppConstants.AnimationDurations.short) - } -} +/// UI-specific constants for styling and layout. +enum UIConstants {}