One observable root owns dependencies while a single room view model drives entry, timer, ghost UI, and completion.
Focus Room
Not another timer. A room you return to.
Built to reduce friction before focus, with soft entry, low-visibility controls, and a room that settles deeper as the session unfolds.
Soft entry, low-visibility controls, and session-based atmosphere optimized for calm, not feature density.
Focus Room
A quiet room for deep work.
Hover wakes the room. Hold to step inside.
Main Room
The room remains the hero. Controls stay near-silent until invited back into view, while the atmosphere deepens slowly enough to feel alive without behaving like a dashboard.
Good work. Take a breath.
Technical credibility, surfaced with less weight
The prototype still reads like a real SwiftUI handoff, but the first scan starts with the four decisions that make the experience believable: orchestration, persistence, audio seams, and reusable views.
Sound selections, volumes, and last duration persist through a small UserDefaults seam without introducing account friction.
The prototype stays visually honest while deferring real fade-aware audio layering until the next phase.
Threshold, room, timer, mixer, background, and completion remain isolated enough to move directly into an app target.
One orchestrator, small seams, reusable views
The architecture keeps interaction quality central. State lives in one place, derived atmosphere values keep visuals coherent, and services stay thin enough to swap without rewriting the room.
AppState / ViewModel orchestration Single source of truth for phase, timer, mixer, and room atmosphere.
AppState owns dependencies. FocusRoomViewModel centralizes threshold entry, session timing, ghost UI idling, completion messaging, and derived room evolution so the visuals never feel bolted together.
RoomAtmosphere values keep lamp warmth, rain depth, and background calm in sync.
Local persistence Preferences survive without login or backend ceremony.
FocusRoomPreferencesStoring isolates persistence behind a protocol, so the room can remember last-used sound layers and duration while keeping countdown runtime state ephemeral.
UserDefaultsPreferencesStore is production-friendly for a first version.
InMemoryPreferencesStore keeps previews and local iteration fast.
Mock audio seam Visual and interaction quality can mature before real assets land.
The audio layer is intentionally abstracted behind AmbientAudioControlling. That keeps the prototype believable today and ready for fade-aware playback tomorrow.
Reusable view structure Each layer is scoped tightly enough to migrate into Xcode cleanly.
The UI is split into the same components a production app would want: threshold ritual, background composition, timer, mixer, and completion. The room stays primary because each piece knows its role.
GhostGlassPanel standardizes the low-visibility control language.
Preview data and theme tokens support iteration without turning the project into a demo-only codebase.
Start with the code that makes the prototype believable
Rather than giving every file equal weight, the page starts with the two seams that matter most on first read: the room orchestrator and the local persistence layer. The full browser is still here when you want the whole tree.
Loading source...