The Background tab fills in — facets rendered to order, eight hues in a carousel

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-08-07 16:08:29 -04:00
parent 56e37be158
commit fb96e30df0
19 changed files with 3031 additions and 38 deletions
+24 -24
View File
@@ -7,12 +7,12 @@ import SwiftUI
/// **Restructuring in progress (2026-08-07): the popover is going tabbed.** The symbol/name header
/// stays at the top; below it sit three tabs **Info**, **Background**, **Git** each a settings
/// surface for one aspect of board configuration, each settled in its own dedicated design session.
/// **Info is settled** (same day `BoardInfoTabView`, the metrics dossier); Background and Git
/// remain deliberately empty until theirs. The former body the embedded style editor and the
/// mode-aware git section is unrendered for the interim but parked in this file (see the
/// "Parked" marks below), because its pure seams (`BoardGitSection`, the posture notes,
/// `BoardSettingsAvailability`'s caller) are settled design and will rehome into the tabs as those
/// sessions rule.
/// **Info and Background are settled** (both 2026-08-07 `BoardInfoTabView`, the metrics dossier;
/// `BoardBackgroundTabView`, the re-homed style editor plus the generated-background picker); Git
/// remains deliberately empty until its own session. The former body's mode-aware git section is
/// unrendered for the interim but parked in this file (see the "Parked" mark below), because its
/// pure seams (`BoardGitSection`, the posture notes, `BoardSettingsAvailability`'s caller) are
/// settled design and will rehome into the Git tab once that session rules.
///
/// ### One home, deliberately
///
@@ -257,9 +257,9 @@ func boardInfoTitlebarAccessory(
// MARK: - Tabs
/// The popover's three aspects, one tab each (03-board-ui.md § Board popover, the 2026-08-07 tab
/// restructure): **Info**, **Background**, **Git**. Info is settled (`BoardInfoTabView`);
/// Background and Git are placeholders empty on purpose until each gets its dedicated design
/// session, which then only has to fill its case in.
/// restructure): **Info**, **Background**, **Git**. Info and Background are settled
/// (`BoardInfoTabView`, `BoardBackgroundTabView`); Git is a placeholder empty on purpose until
/// its own dedicated design session, which then only has to fill its case in.
enum BoardInfoTab: String, CaseIterable, Identifiable {
case info = "Info"
@@ -275,9 +275,9 @@ enum BoardInfoTab: String, CaseIterable, Identifiable {
/// (03-board-ui.md § Board popover).
///
/// Width is the style editor's the number that keeps the Style popover narrow enough to sit
/// beside a card kept through the restructure so the popover's footprint doesn't wander while the
/// tabs are placeholders; whether the tabbed surface wants its own width is each tab session's
/// question to raise.
/// beside a card kept through the restructure so the popover's footprint doesn't wander while Git
/// is still a placeholder; both tabs settled so far (Info, Background) kept it too, so whether the
/// tabbed surface ever wants its own width remains open, but nothing has needed one yet.
struct BoardInfoView: View {
let store: BoardStore
@@ -375,15 +375,16 @@ struct BoardInfoView: View {
.padding(.horizontal, inset)
.padding(.top, inset)
// The selected tab's surface. Info is settled (2026-08-07 `BoardInfoTabView`);
// Background and Git stay placeholders until their own sessions, holding a fixed
// height so an empty tab reads as a surface awaiting content rather than a collapsed
// sliver `Color.clear`, because an `EmptyView` inside a frame renders nothing at all.
// The selected tab's surface. Info and Background are settled (2026-08-07
// `BoardInfoTabView`, `BoardBackgroundTabView`); Git stays a placeholder until its own
// session, holding a fixed height so an empty tab reads as a surface awaiting content
// rather than a collapsed sliver `Color.clear`, because an `EmptyView` inside a frame
// renders nothing at all.
switch tab {
case .info:
BoardInfoTabView(store: store, inset: inset)
case .background:
Color.clear.frame(height: 120)
BoardBackgroundTabView(store: store, recents: recents, inset: inset)
case .git:
Color.clear.frame(height: 120)
}
@@ -394,14 +395,13 @@ struct BoardInfoView: View {
.frame(width: StyleEditorLayout.popover(bodyPointSize: CardWindowMetrics.bodyPointSize).width)
}
// MARK: Parked pending the tab sessions (2026-08-07)
// MARK: Parked pending the Git tab session (2026-08-07)
//
// Nothing below this mark renders today. The style-editor embed left the body with the tab
// restructure (its Background-tab fate is that session's), and the git section postures,
// notes, and the Board Settings row waits here for the Git tab's session. Parked rather
// than deleted because every seam it hangs on is settled, test-pinned design
// (`BoardGitSectionTests`, `BoardSettingsAvailabilityTests`), and the tab sessions rehome
// surfaces, not rulings.
// Nothing below this mark renders today. The style-editor embed that once lived here has
// rehomed to `BoardBackgroundTabView`; what is left is the git section postures, notes, and
// the Board Settings row waiting for the Git tab's own session. Parked rather than deleted
// because every seam it hangs on is settled, test-pinned design (`BoardGitSectionTests`,
// `BoardSettingsAvailabilityTests`), and the tab sessions rehome surfaces, not rulings.
/// The popover's closing section, whichever of the six postures this board is in see
/// `BoardGitSection`.