diff --git a/docs/FINDINGS.md b/docs/FINDINGS.md
index 1846c24..3834bae 100644
--- a/docs/FINDINGS.md
+++ b/docs/FINDINGS.md
@@ -2835,6 +2835,313 @@ Current filter tabs take significant horizontal space (5 buttons). Consolidating
---
-**Document Version:** 2.0
-**Last Updated by:** Planner Agent (RECIPE-0009 Iteration 0)
+### [Planner] Research Notes - RECIPE-0009 Iteration 1 (2026-02-18)
+
+**Task:** UI enhancements - footer status bar, icon-only buttons, toggle Add Recipe visibility
+
+#### Current Homepage UI Structure Analysis
+
+**Research Date:** 2026-02-18
+**Source:** Analysis of [src/routes/+page.svelte](src/routes/+page.svelte), iteration 0 implementation
+
+**Current Implementation (Iteration 0)**:
+
+1. **Connection Status Widget** (lines 369-383):
+ - Fixed position: bottom-right (`fixed bottom-4 right-4`)
+ - Shows connection status with colored dot + text label
+ - Shows last ping timestamp
+ - Will be REMOVED and replaced with footer bar
+
+2. **Action Bar** (lines 263-297):
+ - Filter dropdown (lines 266-276)
+ - Refresh button with icon + text (lines 277-285)
+ - Add Recipe button with icon + text (lines 288-297)
+ - Currently: Add Recipe button ALWAYS visible (iteration 0 requirement)
+
+3. **Empty State** (lines 310-342):
+ - Shows when `!loading && filteredItems.length === 0`
+ - Contains "Add Recipe URL" link
+
+**Changes Required for Iteration 1**:
+
+1. Remove floating connection status widget
+2. Add footer status bar (icons only)
+3. Convert refresh button to icon-only
+4. Convert Add Recipe button to icon-only
+5. Toggle Add Recipe button visibility (hide when empty, show when has items)
+
+---
+
+#### Footer Status Bar Design - RECIPE-0009 Iteration 1
+
+**Research Date:** 2026-02-18
+**Source:** Web PWA patterns, existing codebase styling patterns
+
+**Design Requirements**:
+
+- **Position**: Fixed at bottom (`fixed bottom-0 left-0 right-0`)
+- **Layout**: Full width with max-width container matching page layout (`max-w-6xl`)
+- **Content**: Two sections (notification status left, live updates right)
+- **Display**: Icons only, no text labels
+- **Accessibility**: title and aria-label attributes on interactive elements
+- **Z-index**: `z-50` to ensure visibility above all content
+- **Visual**: White background, top border, shadow for lift effect
+
+**State Integration**:
+
+Footer needs access to two state sources:
+
+1. **Notification Status**: Via `pushNotificationManager.getState()`
+ - Need to add `notificationViewModel` state variable in +page.svelte
+ - Subscribe to state changes in `onMount`
+ - Cleanup subscription in `onDestroy`
+
+2. **Connection Status**: Already exists as `connectionStatus` state
+ - Reuse existing variable
+ - States: 'connecting' | 'connected' | 'disconnected'
+
+**Notification Icon Logic**:
+
+```typescript
+if (!supported || permission === 'denied') {
+ // Show bell with slash (not supported/denied)
+ icon = 'bell-slash';
+ color = 'text-gray-400';
+} else if (subscribed) {
+ // Show bell icon (enabled)
+ icon = 'bell';
+ color = 'text-green-600';
+} else {
+ // Show bell icon (available but not enabled)
+ icon = 'bell';
+ color = 'text-gray-400';
+}
+```
+
+**Live Update Indicator Logic**:
+
+```typescript
+if (connectionStatus === 'connected') {
+ dotColor = 'bg-green-400';
+ title = 'Live updates active';
+} else if (connectionStatus === 'connecting') {
+ dotColor = 'bg-yellow-400';
+ title = 'Connecting to live updates...';
+} else {
+ dotColor = 'bg-red-400';
+ title = 'Live updates disconnected';
+}
+```
+
+**Click Behavior**:
+
+Clicking notification icon scrolls to NotificationSettings component:
+```typescript
+onclick={() => {
+ document.querySelector('[data-notification-settings]')?.scrollIntoView({ behavior: 'smooth' });
+}}
+```
+
+Requires adding `data-notification-settings` attribute to NotificationSettings wrapper.
+
+---
+
+#### Icon-Only Button Patterns - RECIPE-0009 Iteration 1
+
+**Research Date:** 2026-02-18
+**Source:** Existing codebase button styles, Tailwind CSS documentation, WCAG 2.1 guidelines
+
+**Current Button Pattern (with text)**:
+
+```svelte
+
+```
+
+- Padding: `px-4 py-2` (horizontal + vertical)
+- Icon size: `w-4 h-4` (16x16px)
+- Spacing: `space-x-2` (gap between icon and text)
+
+**Icon-Only Button Pattern**:
+
+```svelte
+
+```
+
+**Changes**:
+- Padding: `p-2` (square/circular button)
+- Icon size: `w-5 h-5` (20x20px - slightly larger for better visibility)
+- Remove: `space-x-2` class (no text to space from)
+- Add: `title` attribute (tooltip on hover)
+- Add: `aria-label` attribute (screen reader accessibility)
+
+**Accessibility Requirements** (WCAG 2.1):
+
+1. **Title Attribute**: Provides tooltip text for sighted users on hover
+2. **Aria-label Attribute**: Provides accessible name for screen readers
+3. **Minimum Touch Target**: 24x24px recommended (20x20px icon + 8px padding = 36x36px total ✓)
+4. **Color Contrast**: Must meet 3:1 ratio for non-text (icons)
+
+**Examples**:
+
+Refresh button:
+```svelte
+
+```
+
+Add Recipe button:
+```svelte
+
+
+
+```
+
+---
+
+#### Add Recipe Button Visibility Logic - RECIPE-0009 Iteration 1
+
+**Research Date:** 2026-02-18
+**Source:** context_compact.yaml requirement analysis, UX patterns
+
+**Iteration 0 Implementation**:
+- Add Recipe button ALWAYS visible in controls bar
+- Rationale: User complained "do not hide the add recipe component when there are items in the queue"
+
+**Iteration 1 Requirement**:
+> "Toggle "Add Recipe" button visibility in controls bar (hide when queue empty, show when items exist - opposite of placeholder rule)"
+
+**Interpretation**:
+
+"Opposite of placeholder rule":
+- Placeholder (empty state) shows when: `items.length === 0`
+- Add Recipe button in controls shows when: `items.length > 0` (opposite condition)
+
+**Logic**:
+
+```svelte
+{#if items.length > 0}
+
+
+
+{/if}
+```
+
+**Rationale**:
+
+1. **Empty State**: When queue is empty, user sees empty state with centered "Add Recipe URL" link
+2. **Non-Empty State**: When queue has items, controls bar shows Add Recipe button (icon-only)
+3. **No Redundancy**: Button doesn't appear when empty state link is already visible
+4. **Consistent Access**: User always has access to "Add Recipe" via either empty state link OR controls bar button
+
+**UX Benefits**:
+
+- Cleaner UI when queue is empty (no redundant button)
+- Convenient access when queue has items (quick add more recipes)
+- Fulfills opposite condition of empty state placeholder
+
+---
+
+#### Svelte 5 Notification State Management
+
+**Research Date:** 2026-02-18
+**Source:** Existing iteration 0 implementation, [PushNotificationManager.ts](src/lib/client/PushNotificationManager.ts)
+
+**NotificationState Type**:
+
+```typescript
+interface NotificationState {
+ supported: boolean;
+ permission: NotificationPermission; // 'default' | 'granted' | 'denied'
+ subscribed: boolean;
+ loading: boolean;
+ error: string | null;
+}
+```
+
+**State Subscription Pattern**:
+
+```typescript
+// Import type
+import type { NotificationState } from '$lib/client/PushNotificationManager';
+
+// Declare state
+let notificationViewModel = $state(null);
+
+// Subscribe in onMount
+onMount(() => {
+ // ... existing code ...
+
+ const unsubscribeNotifications = pushNotificationManager.onStateChange((newState) => {
+ notificationViewModel = newState;
+ });
+
+ return () => {
+ unsubscribeNotifications?.();
+ };
+});
+```
+
+**Cleanup in onDestroy**:
+
+Current onDestroy only cleans up `eventSource`. Need to also cleanup notification subscription:
+
+```typescript
+onDestroy(() => {
+ if (eventSource) {
+ console.log('[SSE] Closing connection on component destroy');
+ eventSource.close();
+ connectionStatus = 'disconnected';
+ }
+ // No cleanup needed - handled by onMount return callback
+});
+```
+
+**Note**: Svelte 5's `onMount` return function handles cleanup automatically when component unmounts.
+
+**State Access in Footer**:
+
+Footer component needs null-safe access since initial state is `null`:
+
+```svelte
+{#if notificationViewModel}
+ {#if !notificationViewModel.supported || notificationViewModel.permission === 'denied'}
+
+ {:else if notificationViewModel.subscribed}
+
+ {:else}
+
+ {/if}
+{:else}
+
+
+{/if}
+```
+
+**Initial State Handling**:
+
+`pushNotificationManager.onStateChange()` sends initial state immediately on subscription, so `notificationViewModel` will be populated almost instantly after component mount.
+
+---
+
+**Document Version:** 3.0
+**Last Updated by:** Planner Agent (RECIPE-0009 Iteration 1)
**Next Update:** Developer Agent