# UI Plan 1 Block 02 — App Shell and Visual System

**Status:** Complete on 2026-06-30.
**Goal:** Build the dark desktop shell and static visual system that matches the compact mockup frame.

---

## Block outcome

After this block, the app should render the full static desktop frame:

- dark app surface,
- sidebar,
- header/top controls,
- compact/normal segmented control,
- settings button,
- required banner placeholder,
- timeline content area placeholder.

The actual seeded timeline cards are implemented in later blocks.

---

## Chunk 2.1 — Define visual tokens

### Tasks

Create `theme/focus_flow_tokens.dart` with centralized tokens for:

1. App background and panels:
   - near-black app background,
   - elevated panel background,
   - glass/magenta panel overlay,
   - border color variants.
2. Text colors:
   - primary white,
   - secondary muted gray/lavender,
   - disabled/completed gray,
   - accent magenta,
   - task-type colors.
3. Task semantic colors:
   - flexible/green,
   - required/critical pink,
   - inflexible/appointment blue,
   - free-slot/rest purple,
   - completed/surprise gray,
   - neutral outline.
4. Radii:
   - app frame,
   - sidebar nav item,
   - banner,
   - card,
   - modal,
   - small icon button.
5. Spacing:
   - sidebar width,
   - main content gutter,
   - header height,
   - timeline rail width,
   - card horizontal padding.
6. Typography sizes/weights:
   - page title,
   - card title,
   - card metadata,
   - sidebar nav,
   - modal title,
   - modal button.

### Design guidance

- Do not add external font/network dependencies for this block.
- Use Flutter text styles and system fonts.
- It is okay if exact mockup font metrics differ slightly.
- Keep tokens plain Dart/Flutter constants. Do not reach into scheduler core.

### Acceptance criteria

- Colors and dimensions are not scattered as magic numbers across widgets.
- Later card/modal widgets can reuse tokens.
- No theme token imports any scheduler package.

---

## Chunk 2.2 — Build `FocusFlowApp` and root theme

### Tasks

1. Replace the counter template with `FocusFlowApp`.
2. Use `MaterialApp` or `WidgetsApp` with:
   - debug banner hidden,
   - dark theme,
   - transparent/near-black scaffold background,
   - no white default Material surfaces.
3. Render the app shell directly on launch.
4. Ensure initial app size/responsiveness works at desktop mockup proportions.
5. Avoid adding routes/navigation for this plan.

### Acceptance criteria

- Launching the app shows the FocusFlow shell, not a counter app.
- There is no white flash/background in steady state.
- `FocusFlowApp` can receive a controller/composition later rather than creating all state inline.

---

## Chunk 2.3 — Build the desktop app shell frame

### Tasks

Create `widgets/app_shell.dart` that composes:

1. Outer app frame.
2. Sidebar slot.
3. Main content slot.
4. Minimum desktop width behavior.
5. Optional horizontal scroll/flexible scaling for narrower windows.

Suggested layout:

```dart
Row(
  children: [
    SizedBox(width: tokens.sidebarWidth, child: Sidebar(...)),
    Expanded(child: MainTodayArea(...)),
  ],
)
```

### Visual requirements

- The shell background should match the clean mockups.
- Main content should not touch the outer frame edge.
- Keep sidebar and main content separated by subtle border/contrast.
- No drop shadows that make the app feel heavy or busy.

### Acceptance criteria

- Sidebar and main area are both visible at 1586×992.
- The shell is stable under `flutter test` widget pumping.
- Shell has no scheduler/domain dependency.

---

## Chunk 2.4 — Build the sidebar

### Tasks

Create `widgets/sidebar.dart` with:

1. Decorative window controls.
2. Brand icon and `FocusFlow` text.
3. Nav items:
   - Today active,
   - Backlog inactive,
   - Projects inactive,
   - Reports inactive,
   - Settings inactive below divider.
4. Icon approximations using either built-in icons or simple custom painters.
5. All nav rows no-op except Today's active visual state.

### Visual requirements

- Today item has magenta-tinted active background and border.
- Inactive rows have white icon/text with lower opacity.
- Sidebar spacing should closely follow the mockup.
- Use no-op `onTap` callbacks rather than disabled widgets.

### Acceptance criteria

- Widget tests can find all nav labels.
- Today is visually marked active through a stable key/semantic or widget property.
- Inactive nav items do not navigate or mutate app state.

---

## Chunk 2.5 — Build the top bar and segmented toggle

### Tasks

Create `widgets/top_bar.dart` with:

1. `Today` title.
2. Calendar icon button.
3. Previous arrow icon button.
4. Date label derived from selected date display text.
5. Next arrow icon button.
6. Segmented control with `Compact` selected and `Normal` unselected.
7. Settings button visible/no-op.

### Behavior requirements

- Calendar/arrow/settings/Normal controls are no-op.
- Compact remains visually selected.
- Date label comes from controller/display model, not a widget constant.

### Acceptance criteria

- Tests can assert `Today`, `Compact`, `Normal`, and `Settings` are present.
- Controls look enabled but do not alter state.
- Date label can be fixture-controlled in tests.

---

## Chunk 2.6 — Build the required banner frame

### Tasks

Create `widgets/required_banner.dart` that takes a display model:

```dart
class RequiredBannerModel {
  final String title;
  final String timeText;
}
```

or use equivalent existing UI model.

For this block, allow a placeholder model. Block 3 will wire it to backend state.

### Visual requirements

- Magenta/pink glass panel with border.
- Sparkle icon on the left.
- Text format: `Next required task: Pay bill at 6:00 PM`.
- `Show upcoming` button on the right, no-op.
- Proper text emphasis: label neutral, task title accent.

### Acceptance criteria

- Banner component can render with a null/empty model if no required task exists, but default seed path should show the banner.
- Button looks enabled but is inert.
- Component has no scheduler imports; it accepts display text/model.

---

## Block acceptance criteria

- Static shell visually resembles the mockup frame.
- App has no white background.
- No-op controls look enabled.
- Top-level components are separated into focused files.
- Backend/core remains untouched.

## Validation after block

```sh
cd apps/focus_flow_flutter
flutter analyze
flutter test
```

At this point tests should cover shell/sidebar/top bar/banner presence.

---

## Completed implementation

1. Added `FocusFlowTokens` and `FocusFlowTheme` for the dark visual system.
2. Replaced the provisional app surface with a desktop shell that has a sidebar,
   top bar, segmented Compact/Normal control, Settings button, required banner,
   and Today content area.
3. Kept all shell controls enabled-looking and no-op.
4. Preserved backend package boundaries.

## Verification

1. `dart format lib test`: passed.
2. `flutter analyze`: passed, no issues found.
3. `flutter test`: passed.
