Repository navigation
feat: Hearth theme restyle - #49
Conversation
…bar margins Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…and row glow Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…HearthCard color inlining
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Use a tighter shadowRadius (10) on the terminal pane hearthCard so the shadow fades out within the available clearance; expose shadowRadius as a hearthCard parameter (default 25) so other cards are unaffected. Also fix SessionListView trailing/top insets that were set to hardcoded values from a previous iteration. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the left-edge vertical bar with a thin circular ring around the status dot. The ring uses the same status color/glow and the dot container is fixed-size so centers stay aligned across all rows. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Lower the default shadowRadius (25 → 15) and shadow opacity (0.55 → 0.30) on hearthCard so the drop shadow is less heavy. Pass shadowRadius: 10 on sidebar cards (app header, group card, group drag preview, UpdateAvailableBox, HookSetupBox) and bump their surrounding padding from 8pt to 14pt so the halo fades within the available clearance instead of being clipped by the panel edge and ScrollView bounds. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces full Dark and Light theme support by making all OcakTheme colors dynamic based on AppearanceConfigStore mode. Replaces the previous auto/system mode with Hearth as the default, adds visualEffectAppearance routing so HearthCard adapts across themes, and pins the selection ring to the ember color regardless of theme. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bump terminal pane top padding from 8→12 to match the session list's top inset so both cards share the same horizontal baseline. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the native macOS sidebar with a custom warm-dark sidebar when Hearth is active, and applies OcakTheme background and text colors throughout all settings tabs so the settings window matches the drawer's Hearth aesthetic. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fonts are now canonical in assets/fonts/ (alongside images in assets/images/). A sync-assets Makefile target copies them to macos/Sources/Ocak/Resources/Fonts/ before every build, run, and build-wrapped invocation. Resources/Fonts/ is gitignored since it is now a generated directory. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR adds a Hearth appearance mode, refactors OcakTheme into Hearth-aware computed colors, introduces HearthCard and EmberDot UI primitives, updates many views to use the new theme and typography, and adds a font asset pipeline with build-time syncing and runtime font registration. ChangesHearth Theme System & UI Component Integration
Font Asset Pipeline & Registration
Sequence Diagram(s)sequenceDiagram
participant Makefile
participant Filesystem as Resources_Fonts
participant Package as Package.swift
participant OcakApp
participant CTFontManager
Makefile->>Resources_Fonts: rsync TTF/OTF into macos/Sources/Ocak/Resources/Fonts (sync-assets)
Package->>Resources_Fonts: include Resources/Fonts/ in target resources
OcakApp->>Resources_Fonts: Bundle.module.url(forResource: fontName)
OcakApp->>CTFontManager: CTFontManagerRegisterFontsForURL(fontURL)
CTFontManager-->>OcakApp: fonts available to process
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
macos/Sources/Ocak/Views/DrawerView.swift (1)
135-135: ⚡ Quick winConsider extracting the session-list padding constant.
The padding value
8is hardcoded here and also embedded inPanelSizeStore's chrome calculations (lines 19, 21). If this spacing needs adjustment in the future, it would require updates in 4 locations across 2 files.♻️ Suggested approach
In
PanelSizeStore, expose the padding as a constant:static let sessionListLeadingPad: CGFloat = 8 static let terminalChrome: CGFloat = 6 + sessionListLeadingPad + 6 static let sessionListChrome: CGFloat = sessionListLeadingPad + 6Then reference it in
DrawerView:if edge == .right { sessionResizeHandle.padding(.leading, PanelSizeStore.sessionListLeadingPad) } // ... if edge == .left { sessionResizeHandle.padding(.trailing, PanelSizeStore.sessionListLeadingPad) }Also applies to: 151-151
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@macos/Sources/Ocak/Views/DrawerView.swift` at line 135, Extract the hardcoded padding value (8) into a named constant on PanelSizeStore (e.g., sessionListLeadingPad or similar) and update PanelSizeStore's chrome calculations (terminalChrome, sessionListChrome) to use that constant; then replace the inline 8 in DrawerView's sessionResizeHandle.padding calls (both the right and left edge branches where sessionResizeHandle.padding(.leading, 8) and .padding(.trailing, 8) appear) to reference PanelSizeStore.sessionListLeadingPad so all usages share the same source of truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@macos/Sources/Ocak/Views/SessionListView.swift`:
- Around line 25-33: FlameIcon currently hardcodes gradient and shadow hex
colors in SessionListView (LinearGradient colors and shadow color); move those
color values into OcakTheme color tokens in Theme/Colors.swift (e.g., add tokens
like ocakFlameGradientStart, ocakFlameGradientMid, ocakFlameGradientEnd, and
ocakFlameShadow), then update FlameIcon/SessionListView to reference
OcakTheme.<colorTokenName> instead of Color(hex: ...) so all color usage is
centralized in Theme/Colors.swift and no hex literals remain in the view.
- Around line 35-40: The current flicker logic only checks reduceMotion in the
onAppear closure, so toggling Reduce Motion at runtime won't stop or start the
animation; update the view to react to changes by adding an onChange(of:
reduceMotion) handler (in addition to the existing onAppear) that mirrors the
onAppear behavior: when reduceMotion becomes false, start the flicker animation
(withAnimation(.easeInOut(duration: 1.6).repeatForever(autoreverses: true)) {
flickering = true }) and when reduceMotion becomes true, stop the animation by
setting flickering = false (and optionally wrap in withAnimation if you want a
smooth stop). Ensure you reference the existing flickering and reduceMotion
properties so the runtime toggle updates the animation state.
In `@macos/Sources/Ocak/Views/SettingsView.swift`:
- Around line 27-30: The view currently hardcodes Color(hex: 0x0C0A08) in
SettingsView (background modifiers tied to isHearth) — move that color into the
centralized theme tokens in Theme/Colors.swift (e.g., add a token on OcakTheme
such as ocakHearthBackground or hearthBackgroundColor) and then replace the
inline Color(hex: 0x0C0A08) occurrences in SettingsView.swift (the
.background(...) calls that use isHearth) with references to the new OcakTheme
color token; ensure the token exposes a SwiftUI Color and update all three
hardcoded instances so the view reads OcakTheme.<tokenName> instead of
Color(hex: ...).
---
Nitpick comments:
In `@macos/Sources/Ocak/Views/DrawerView.swift`:
- Line 135: Extract the hardcoded padding value (8) into a named constant on
PanelSizeStore (e.g., sessionListLeadingPad or similar) and update
PanelSizeStore's chrome calculations (terminalChrome, sessionListChrome) to use
that constant; then replace the inline 8 in DrawerView's
sessionResizeHandle.padding calls (both the right and left edge branches where
sessionResizeHandle.padding(.leading, 8) and .padding(.trailing, 8) appear) to
reference PanelSizeStore.sessionListLeadingPad so all usages share the same
source of truth.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 5655a9c2-d6ec-4e88-8958-70923f8d108d
⛔ Files ignored due to path filters (3)
assets/fonts/InstrumentSerif-Italic.ttfis excluded by!**/*.ttfassets/fonts/JetBrainsMono-Medium.ttfis excluded by!**/*.ttfassets/fonts/JetBrainsMono-Regular.ttfis excluded by!**/*.ttf
📒 Files selected for processing (19)
.gitignoreMakefileassets/fonts/.gitkeepmacos/Package.swiftmacos/Sources/Ocak/App/AppDelegate.swiftmacos/Sources/Ocak/App/OcakApp.swiftmacos/Sources/Ocak/Models/AppearanceConfigStore.swiftmacos/Sources/Ocak/Models/PanelSizeStore.swiftmacos/Sources/Ocak/Theme/Colors.swiftmacos/Sources/Ocak/Theme/HearthCard.swiftmacos/Sources/Ocak/Views/DrawerView.swiftmacos/Sources/Ocak/Views/EmberDot.swiftmacos/Sources/Ocak/Views/HookSetupBox.swiftmacos/Sources/Ocak/Views/SessionListRowView.swiftmacos/Sources/Ocak/Views/SessionListView.swiftmacos/Sources/Ocak/Views/SettingsView.swiftmacos/Sources/Ocak/Views/TerminalPaneView.swiftmacos/Sources/Ocak/Views/UpdateAvailableBox.swiftscripts/build-macos-app.sh
- Add hearthBackground, hearthSidebarBackground, flame gradient, and flameShadow tokens to Colors.swift - Replace all inline Color(hex:) literals in SettingsView and FlameIcon with OcakTheme references - Add onChange(of: reduceMotion) to FlameIcon so toggling Reduce Motion at runtime starts/stops animation - Extract PanelSizeStore.sessionListLeadingPad constant and use it in chrome calculations and DrawerView padding Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@macos/Sources/Ocak/Views/EmberDot.swift`:
- Around line 38-52: The pulsing opacity is applied to the entire ZStack (in
EmberDot.body) so the outer stroked ring pulses with the inner dot; move the
animation-only opacity from the ZStack to the inner filled Circle so only the
dot uses .opacity(reduceMotion ? 1.0 : phase) while the outer Circle stroke
remains controlled by .opacity(isMarked ? 1 : 0); update EmberDot.body to apply
the phase-based opacity to the inner Circle (the one using .fill(dotColor) and
.shadow(...)) and remove the phase opacity from the ZStack so the marked ring
stays visually stable.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 29d7a87b-dbcb-4ae1-831b-eff0026e966c
📒 Files selected for processing (6)
macos/Sources/Ocak/Models/PanelSizeStore.swiftmacos/Sources/Ocak/Theme/Colors.swiftmacos/Sources/Ocak/Views/DrawerView.swiftmacos/Sources/Ocak/Views/EmberDot.swiftmacos/Sources/Ocak/Views/SessionListView.swiftmacos/Sources/Ocak/Views/SettingsView.swift
✅ Files skipped from review due to trivial changes (1)
- macos/Sources/Ocak/Views/DrawerView.swift
🚧 Files skipped from review as they are similar to previous changes (4)
- macos/Sources/Ocak/Models/PanelSizeStore.swift
- macos/Sources/Ocak/Views/SettingsView.swift
- macos/Sources/Ocak/Views/SessionListView.swift
- macos/Sources/Ocak/Theme/Colors.swift
Summary
assets/fonts/as the canonical source, synced to Swift package resources at build time via async-assetsMakefile targetTest plan
make build,make run, andmake build-wrappedall sync fonts before compilingmake buildpicks up fonts fromassets/fonts/correctly🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Improvements
Chores