Loop prep

This commit is contained in:
2026-02-17 20:58:56 +00:00
parent 06ca2a2b46
commit 025f860815
15 changed files with 214 additions and 207 deletions
-17
View File
@@ -1,17 +0,0 @@
# Memories
## Patterns
### mem-1771337886-d0ab
> Global focus mode: DashboardLayout manages globalFocusId state + focusRelatedIds derived set. Relationship data: skillToRoles and roleToSkills maps built from timelineEntities.skills[]. focusRelatedIds passed to timeline, skills, and LastConsultationCard. Constellation axis dims via CSS class constellation-focus-active on SVG.
<!-- tags: constellation, focus-mode, architecture | created: 2026-02-17 -->
## Decisions
### mem-1771337892-8cc2
> useConstellationInteraction mouseenter now calls onNodeHover for ALL node types (was previously skill-filtered). handleNodeHover in DashboardLayout checks nodeType to decide what to set for highlightedRoleId. Do NOT set highlightedNodeId from handleNodeHover — it breaks resolveGraphFallback timing.
<!-- tags: constellation, interaction | created: 2026-02-17 -->
## Fixes
## Context
View File
-63
View File
@@ -1,63 +0,0 @@
# Constellation Hover Focus Mode - Scratchpad
## Understanding
The feature requires a **global dimming** effect when hovering constellation nodes or skill pills. Currently:
1. **Constellation internal highlighting** already works well via `useConstellationHighlight` - dims non-connected nodes to 0.15 opacity within the SVG.
2. **Skill pill hover** (`RepeatMedicationsSubsection`) calls `onHighlight(skill.id)` → flows to `setHighlightedNodeId` → passed to `CareerConstellation` as prop → triggers `applyGraphHighlight(skillId)`.
3. **Timeline item hover** calls `onHighlight(entity.id)` → same flow → highlights that role in constellation.
4. **Constellation node hover** calls `onNodeHover(roleId)``setHighlightedRoleId` → highlights matching timeline item via `isHighlightedFromGraph` prop.
### What's Missing
The **cross-component dimming** doesn't exist yet:
- When hovering a constellation node: timeline items and skill pills don't dim (only the matching timeline item highlights)
- When hovering a skill pill: the constellation highlights but timeline items and other skill pills don't dim
- No global "focus mode" overlay or coordinated dimming across all three areas
### Architecture Decision
**Approach: CSS class-based global dimming with React context**
Rather than a heavy context, I'll use the existing `DashboardLayout` state pattern:
1. Add a `globalFocusId` state to `DashboardLayout` (the orchestrator)
2. Add a `globalFocusType` to know if it's a skill or role focus
3. Pass this down to timeline, skill pills, and constellation
4. Each component applies a dimming class/style when not related to the focused ID
5. Use the existing `connectedMap` data (already built in constellation) to resolve relationships
**Key insight**: When a skill is focused, the "related" timeline items are those whose `entity.skills` array contains that skill ID. When a role is focused, the "related" skills are those in that role's `entity.skills`. This data is already in `timelineEntities`.
**Dimming approach**: CSS transitions on opacity. Apply `opacity: 0.25` to non-related elements, keep related ones at full opacity. Use `transition: opacity 0.15s` for smooth enter/exit.
### Implementation (COMPLETED)
All implemented in a single commit (`47b52b5`):
1. **DashboardLayout** — Added `globalFocusId` state, lookup maps (`skillToRoles`, `roleToSkills`, `nodeTypeById`), and computed `focusRelatedIds: Set<string> | null`. Both `handleNodeHighlight` and `handleNodeHover` now set `globalFocusId`.
2. **useConstellationInteraction** — Removed `d.type !== 'skill'` guard on `onNodeHover` so skill node hovers also propagate to parent for global focus.
3. **TimelineInterventionsSubsection** — Receives `focusRelatedIds`, computes `isDimmedByFocus` per entity, passes to `ExpandableCardShell`.
4. **ExpandableCardShell** — New `isDimmedByFocus` prop applies `opacity: 0.25` with 150ms transition.
5. **RepeatMedicationsSubsection**`focusRelatedIds` flows through `CategorySection``SkillRow`, each skill row dims if not in related set.
6. **LastConsultationCard** — Dims when `focusRelatedIds` is active and consultation.id not in set.
7. **CareerConstellation** — New `globalFocusActive` prop + SVG class `constellation-focus-active` triggers CSS axis dimming.
8. **index.css** — CSS rules dim `.axis-line`, `.year-tick`, `.year-label` to 0.25 opacity when `constellation-focus-active` class is present. Reduced-motion override removes transitions.
### Verification
- `npm run typecheck` — PASS
- `npm run lint` — PASS (5 pre-existing warnings only)
- `npm run build` — PASS
### Remaining
- Playwright MCP visual verification (reviewer task)
- Manual QA: hover each source (constellation node, skill pill, timeline item), verify dimming/restore
-5
View File
@@ -1,5 +0,0 @@
{"id":"task-1771337307-83ce","title":"Add global focus state to DashboardLayout with relationship resolution","description":"Add globalFocusId/globalFocusType state, derive relatedSkillIds and relatedRoleIds sets using timelineEntities data, wire into existing hover handlers","status":"closed","priority":1,"blocked_by":[],"loop_id":"primary-20260217-140555","created":"2026-02-17T14:08:27.099307+00:00","closed":"2026-02-17T14:17:28.063483065+00:00"}
{"id":"task-1771337311-1f39","title":"Apply focus-mode dimming to TimelineInterventionsSubsection","description":"Pass globalFocusId/relatedRoleIds to timeline, dim non-related timeline items with opacity transition","status":"closed","priority":2,"blocked_by":["task-1771337307-83ce"],"loop_id":"primary-20260217-140555","created":"2026-02-17T14:08:31.532282963+00:00","closed":"2026-02-17T14:17:28.154478577+00:00"}
{"id":"task-1771337316-d45f","title":"Apply focus-mode dimming to RepeatMedicationsSubsection","description":"Pass globalFocusId/relatedSkillIds to skill pills, dim non-related skill rows with opacity transition","status":"closed","priority":2,"blocked_by":["task-1771337307-83ce"],"loop_id":"primary-20260217-140555","created":"2026-02-17T14:08:36.447585246+00:00","closed":"2026-02-17T14:17:28.246180358+00:00"}
{"id":"task-1771337321-b56c","title":"Wire constellation node hover to global focus and add graph background dimming","description":"Update onNodeHover to set globalFocusId for both role AND skill node hovers, add CSS dimming to constellation background/axis during focus mode","status":"closed","priority":2,"blocked_by":["task-1771337307-83ce"],"loop_id":"primary-20260217-140555","created":"2026-02-17T14:08:41.046446549+00:00","closed":"2026-02-17T14:17:28.342976988+00:00"}
{"id":"task-1771337325-9009","title":"Verify lint, typecheck, build pass and manual testing","description":"Run validation gates, check for stuck states, verify reduced-motion respect","status":"closed","priority":3,"blocked_by":["task-1771337311-1f39","task-1771337316-d45f","task-1771337321-b56c"],"loop_id":"primary-20260217-140555","created":"2026-02-17T14:08:45.626698271+00:00","closed":"2026-02-17T14:17:39.422234149+00:00"}
View File
-1
View File
@@ -1 +0,0 @@
.ralph/events-20260217-140555.jsonl
-1
View File
@@ -1 +0,0 @@
primary-20260217-140555
-1
View File
@@ -1 +0,0 @@
{"ts":"2026-02-17T14:04:00.938681910+00:00","iteration":0,"hat":"loop","topic":"task.start","triggered":"planner","payload":"# Task: Constellation Hover Focus Mode With Global Dimming\n\nImplement a focused hover mode so that when a user hovers a skill or node in the constellation area, non-related UI darkens and only the relevant relationship remains emphasized.\n\n## Requirements\n\n- Support hover-triggered focus mode from:\n - constellation node hover\n - skill pill hover\n- In focus mode, darken non-related UI across the page, including:\n - graph axis/background\n - unrelated graph nodes/labels/links\n - unrelated time... [truncated, 3038 chars total]"}
-3
View File
@@ -1,3 +0,0 @@
{"ts":"2026-02-17T14:05:55.280271324+00:00","iteration":0,"hat":"loop","topic":"task.start","triggered":"planner","payload":"# Task: Constellation Hover Focus Mode With Global Dimming\n\nImplement a focused hover mode so that when a user hovers a skill or node in the constellation area, non-related UI darkens and only the relevant relationship remains emphasized.\n\n## Requirements\n\n- Support hover-triggered focus mode from:\n - constellation node hover\n - skill pill hover\n- In focus mode, darken non-related UI across the page, including:\n - graph axis/background\n - unrelated graph nodes/labels/links\n - unrelated time... [truncated, 3038 chars total]"}
{"payload":"Global focus mode implemented: hover any constellation node, skill pill, or timeline item to dim non-related UI to 0.25 opacity. Axis/labels dim via CSS. Typecheck pass, lint pass (pre-existing warnings only), build pass. Commit: 47b52b5","topic":"build.done","ts":"2026-02-17T14:18:22.337524276+00:00"}
{"payload":"tests: pass (no test framework), lint: pass (0 errors, 5 pre-existing warnings), typecheck: pass, audit: pass, coverage: N/A, complexity: low, duplication: pass, performance: pass","topic":"build.done","ts":"2026-02-17T14:19:11.040920579+00:00"}
-2
View File
@@ -1,2 +0,0 @@
{"ts":"2026-02-17T14:04:01.040268715Z","type":{"kind":"loop_started","prompt":"# Task: Constellation Hover Focus Mode With Global Dimming\n\nImplement a focused hover mode so that when a user hovers a skill or node in the constellation area, non-related UI darkens and only the relevant relationship remains emphasized.\n\n## Requirements\n\n- Support hover-triggered focus mode from:\n - constellation node hover\n - skill pill hover\n- In focus mode, darken non-related UI across the page, including:\n - graph axis/background\n - unrelated graph nodes/labels/links\n - unrelated timeline and dashboard elements\n- Keep the following elements visually emphasized (not darkened):\n - hovered skill pill\n - hovered/active constellation node\n - connection lines between related node/skill items\n - timeline series item related to that skill/node\n- On hover exit, restore default appearance cleanly with no stuck state.\n- Preserve existing click behavior, keyboard behavior, and detail panel opening logic.\n- Respect reduced-motion preferences and existing accessibility patterns.\n\n## Likely Files To Update\n\n- `src/components/DashboardLayout.tsx`\n- `src/hooks/useConstellationInteraction.ts`\n- `src/hooks/useConstellationHighlight.ts`\n- `src/components/TimelineInterventionsSubsection.tsx`\n- `src/components/RepeatMedicationsSubsection.tsx`\n- `src/components/ExpandableCardShell.tsx`\n- `src/index.css`\n\nUpdate additional files only if necessary.\n\n## Success Criteria\n\nAll of the following must be true:\n\n- [ ] Hovering a constellation node enters focus mode with global dimming.\n- [ ] Hovering a skill pill enters focus mode with global dimming.\n- [ ] In focus mode, only the relevant node + relationship links + related timeline series item + active skill pill remain visually highlighted.\n- [ ] Graph axis/background visibly darken during focus mode.\n- [ ] Focus mode exits correctly on mouse leave with no lingering darkened state.\n- [ ] Existing interactions (role click, skill click, panel open, timeline expand/collapse) still work.\n- [ ] `npm run lint` passes.\n- [ ] `npm run typecheck` passes.\n- [ ] `npm run build` passes.\n- [ ] Playwright MCP evidence confirms behavior for both node-hover and skill-pill-hover scenarios.\n\n## Playwright MCP Verification\n\nReviewer must validate with Playwright MCP and record evidence in `.ralph/review.md`:\n\n- Run or confirm dev server at `http://localhost:5173`\n- Capture baseline screenshot before hover\n- Hover a constellation node and capture screenshot\n- Hover a skill pill and capture screenshot\n- In both hover screenshots, verify:\n - unrelated areas are darkened\n - related graph + timeline + skill elements remain emphasized\n\n## Constraints\n\n- Do not add new dependencies.\n- Follow existing TypeScript/React conventions and current styling system.\n- Keep changes focused to this feature only.\n- If a blocker repeats with identical evidence across 3 cycles, escalate in `.ralph/review.md` instead of forcing completion.\n\n## Status\n\nTrack progress in `.ralph/plan.md`, `.ralph/build.md`, and `.ralph/review.md`.\nWhen all success criteria are met, print `LOOP_COMPLETE`.\n"}}
{"ts":"2026-02-17T14:05:55.382060260Z","type":{"kind":"loop_started","prompt":"# Task: Constellation Hover Focus Mode With Global Dimming\n\nImplement a focused hover mode so that when a user hovers a skill or node in the constellation area, non-related UI darkens and only the relevant relationship remains emphasized.\n\n## Requirements\n\n- Support hover-triggered focus mode from:\n - constellation node hover\n - skill pill hover\n- In focus mode, darken non-related UI across the page, including:\n - graph axis/background\n - unrelated graph nodes/labels/links\n - unrelated timeline and dashboard elements\n- Keep the following elements visually emphasized (not darkened):\n - hovered skill pill\n - hovered/active constellation node\n - connection lines between related node/skill items\n - timeline series item related to that skill/node\n- On hover exit, restore default appearance cleanly with no stuck state.\n- Preserve existing click behavior, keyboard behavior, and detail panel opening logic.\n- Respect reduced-motion preferences and existing accessibility patterns.\n\n## Likely Files To Update\n\n- `src/components/DashboardLayout.tsx`\n- `src/hooks/useConstellationInteraction.ts`\n- `src/hooks/useConstellationHighlight.ts`\n- `src/components/TimelineInterventionsSubsection.tsx`\n- `src/components/RepeatMedicationsSubsection.tsx`\n- `src/components/ExpandableCardShell.tsx`\n- `src/index.css`\n\nUpdate additional files only if necessary.\n\n## Success Criteria\n\nAll of the following must be true:\n\n- [ ] Hovering a constellation node enters focus mode with global dimming.\n- [ ] Hovering a skill pill enters focus mode with global dimming.\n- [ ] In focus mode, only the relevant node + relationship links + related timeline series item + active skill pill remain visually highlighted.\n- [ ] Graph axis/background visibly darken during focus mode.\n- [ ] Focus mode exits correctly on mouse leave with no lingering darkened state.\n- [ ] Existing interactions (role click, skill click, panel open, timeline expand/collapse) still work.\n- [ ] `npm run lint` passes.\n- [ ] `npm run typecheck` passes.\n- [ ] `npm run build` passes.\n- [ ] Playwright MCP evidence confirms behavior for both node-hover and skill-pill-hover scenarios.\n\n## Playwright MCP Verification\n\nReviewer must validate with Playwright MCP and record evidence in `.ralph/review.md`:\n\n- Run or confirm dev server at `http://localhost:5173`\n- Capture baseline screenshot before hover\n- Hover a constellation node and capture screenshot\n- Hover a skill pill and capture screenshot\n- In both hover screenshots, verify:\n - unrelated areas are darkened\n - related graph + timeline + skill elements remain emphasized\n\n## Constraints\n\n- Do not add new dependencies.\n- Follow existing TypeScript/React conventions and current styling system.\n- Keep changes focused to this feature only.\n- If a blocker repeats with identical evidence across 3 cycles, escalate in `.ralph/review.md` instead of forcing completion.\n\n## Status\n\nTrack progress in `.ralph/plan.md`, `.ralph/build.md`, and `.ralph/review.md`.\nWhen all success criteria are met, print `LOOP_COMPLETE`.\n"}}
View File
-5
View File
@@ -1,5 +0,0 @@
{
"pid": 2082303,
"started": "2026-02-17T14:05:55.274566523Z",
"prompt": "# Task: Constellation Hover Focus Mode With Global Dimming\n\nImplement a focused hover mode so that ..."
}
+88 -57
View File
@@ -1,72 +1,103 @@
# Task: Constellation Hover Focus Mode With Global Dimming # Task: Fix Mobile Responsiveness for Small Viewport Widths (≤430px)
Implement a focused hover mode so that when a user hovers a skill or node in the constellation area, non-related UI darkens and only the relevant relationship remains emphasized. The portfolio website is broken on phones with viewport widths around 400px. Text overflows off-screen, elements are hidden behind `overflow: hidden`, and layout components are sized inappropriately for small screens.
## Context
- **Tech stack:** React + TypeScript + Tailwind CSS + Framer Motion + D3
- **Dev server:** `npm run dev` (localhost:5173)
- **Quality gates:** `npm run lint && npm run typecheck && npm run build`
- **Smallest configured breakpoint:** `xs: 480px` in tailwind.config.js — there is no sub-480px handling
- **Key layout file:** `src/components/DashboardLayout.tsx` orchestrates all dashboard tiles
- **CSS media queries:** `src/index.css` contains most custom responsive rules
- **Tailwind config:** `tailwind.config.js` defines breakpoints and theme
## Target Viewports
Test and fix at these widths (all portrait orientation, 812px height):
- **320px** — iPhone SE / smallest realistic phone
- **360px** — Common Android (Samsung Galaxy S series)
- **375px** — iPhone 12 mini / iPhone SE 3rd gen
- **390px** — iPhone 14
- **400px** — User's specific device (primary target)
- **414px** — iPhone 8 Plus / larger phones
- **430px** — iPhone 14 Pro Max
## Known Issues (from codebase analysis)
### Critical
1. **Sidebar must become a bottom nav bar at <600px** — The current sidebar is a 304px-wide overlay on mobile, leaving only 96px for content at 400px. At viewport widths below 600px, replace the sidebar with a **bottom navigation bar** that:
- **Collapsed state (default):** A slim fixed bar along the bottom edge of the screen with icon-based navigation items (like a mobile tab bar / iOS-style bottom nav). Should not obscure content — main content area accounts for its height.
- **Expanded state (on tap/click):** Slides up as a drawer/sheet showing the full sidebar content (patient name, navigation links, etc.). Tapping the bar or a close affordance collapses it back down.
- The existing sidebar behavior for viewports ≥600px should remain completely unchanged.
- Use Framer Motion for the drawer slide animation, consistent with existing animation patterns.
2. **KPI grid forces 2 columns**`repeat(2, minmax(0, 1fr))` creates cramped cards at small widths. Values use `30px` font.
3. **Timeline text silently clipped**`overflow: hidden` on Card.tsx hides content with no visual indication (no ellipsis, no wrapping).
4. **Project carousel cards too small** — At 400px with 2 cards per view, each card is only ~194px wide.
### Important
5. **Constellation graph** — 520px height at <768px may be disproportionate; needs better sizing.
6. **No sub-480px breakpoint** — The smallest Tailwind breakpoint is `xs: 480px`, leaving 320-479px unhandled.
### Minor
8. **Padding/spacing**`p-5` (20px) main content + `24px` card padding eats significant space at 400px.
9. **Detail panel header** — Close button (44px) + title cramped at narrow widths.
10. **Skills/medications grid** — May need column count reduction at small widths.
## Requirements ## Requirements
- Support hover-triggered focus mode from: - **All text must be visible** — no text clipped by `overflow: hidden` without ellipsis or wrapping. Truncated text needs `text-overflow: ellipsis` with title attribute for accessibility.
- constellation node hover - **All interactive elements must be reachable** — nothing hidden off-screen or behind other elements.
- skill pill hover - **Touch targets** — minimum 44x44px for interactive elements.
- In focus mode, darken non-related UI across the page, including: - **Readable font sizes** — minimum 12px body text, 14px primary content.
- graph axis/background - **No horizontal scroll** — page must never scroll horizontally at any target viewport.
- unrelated graph nodes/labels/links - **Maintain visual identity** — keep PMR aesthetic, teal/coral palette, existing design language. Adapt proportionally, don't radically redesign.
- unrelated timeline and dashboard elements - **Respect existing patterns** — use Tailwind classes where possible, use existing CSS custom properties, follow project conventions.
- Keep the following elements visually emphasized (not darkened):
- hovered skill pill
- hovered/active constellation node
- connection lines between related node/skill items
- timeline series item related to that skill/node
- On hover exit, restore default appearance cleanly with no stuck state.
- Preserve existing click behavior, keyboard behavior, and detail panel opening logic.
- Respect reduced-motion preferences and existing accessibility patterns.
## Likely Files To Update
- `src/components/DashboardLayout.tsx`
- `src/hooks/useConstellationInteraction.ts`
- `src/hooks/useConstellationHighlight.ts`
- `src/components/TimelineInterventionsSubsection.tsx`
- `src/components/RepeatMedicationsSubsection.tsx`
- `src/components/ExpandableCardShell.tsx`
- `src/index.css`
Update additional files only if necessary.
## Success Criteria ## Success Criteria
All of the following must be true: All of the following must be true:
- [ ] Hovering a constellation node enters focus mode with global dimming. - [ ] `npm run lint` passes with zero errors
- [ ] Hovering a skill pill enters focus mode with global dimming. - [ ] `npm run typecheck` passes with zero errors
- [ ] In focus mode, only the relevant node + relationship links + related timeline series item + active skill pill remain visually highlighted. - [ ] `npm run build` succeeds
- [ ] Graph axis/background visibly darken during focus mode. - [ ] At 320px viewport: no horizontal scrollbar, all text readable, no content clipped without indication
- [ ] Focus mode exits correctly on mouse leave with no lingering darkened state. - [ ] At 360px viewport: same as above
- [ ] Existing interactions (role click, skill click, panel open, timeline expand/collapse) still work. - [ ] At 375px viewport: same as above
- [ ] `npm run lint` passes. - [ ] At 390px viewport: same as above
- [ ] `npm run typecheck` passes. - [ ] At 400px viewport: same as above (primary target)
- [ ] `npm run build` passes. - [ ] At 414px viewport: same as above
- [ ] Playwright MCP evidence confirms behavior for both node-hover and skill-pill-hover scenarios. - [ ] At 430px viewport: same as above
- [ ] At <600px: sidebar is replaced by a bottom nav bar with collapsed (tab bar) and expanded (drawer) states
## Playwright MCP Verification - [ ] Bottom nav bar does not obscure page content in collapsed state (content has bottom padding/margin to account for it)
- [ ] Bottom nav drawer expands on tap and shows full navigation content
Reviewer must validate with Playwright MCP and record evidence in `.ralph/review.md`: - [ ] Bottom nav drawer can be collapsed back down
- [ ] At ≥600px: existing sidebar behavior is completely unchanged
- Run or confirm dev server at `http://localhost:5173` - [ ] KPI cards are readable with appropriate font sizing
- Capture baseline screenshot before hover - [ ] Timeline entries show full text or have proper ellipsis truncation
- Hover a constellation node and capture screenshot - [ ] Project carousel cards are adequately sized (consider 1 card per view if needed)
- Hover a skill pill and capture screenshot - [ ] Constellation graph fits within viewport without excessive scrolling
- In both hover screenshots, verify: - [ ] Desktop/tablet layouts (768px+) remain unchanged and unbroken
- unrelated areas are darkened
- related graph + timeline + skill elements remain emphasized
## Constraints ## Constraints
- Do not add new dependencies. - Do NOT change boot sequence, ECG animation, or login screen (already handle small screens)
- Follow existing TypeScript/React conventions and current styling system. - Do NOT change D3 force simulation logic — only container sizing
- Keep changes focused to this feature only. - Do NOT add new npm dependencies
- If a blocker repeats with identical evidence across 3 cycles, escalate in `.ralph/review.md` instead of forcing completion. - Do NOT remove existing features or functionality
- Keep changes minimal and focused — fix responsiveness, don't redesign
- Preserve all existing breakpoint behavior for md (768px) and above
## Visual Validation Method
Use Playwright MCP to:
1. Navigate to `http://localhost:5173` (dev server must be running)
2. Get past boot sequence + ECG + login to reach dashboard
3. Set viewport to each target width × 812px height
4. Take screenshots of dashboard at each viewport
5. Visually inspect for: overflow, clipping, cramped text, unreachable elements
6. Scroll through full page and verify no content is hidden
## Status ## Status
Track progress in `.ralph/plan.md`, `.ralph/build.md`, and `.ralph/review.md`. Track progress here. When all success criteria are met, print LOOP_COMPLETE.
When all success criteria are met, print `LOOP_COMPLETE`.
+125 -51
View File
@@ -20,88 +20,162 @@ backpressure:
hats: hats:
planner: planner:
name: "Hover Focus Planner" name: "Responsive Planner"
description: "Plans the hover-focus dimming implementation and incorporates reviewer feedback." description: "Audits the codebase for mobile responsiveness issues and creates an ordered fix plan."
triggers: ["work.start", "review.changes_requested"] triggers: ["work.start", "review.changes_requested"]
publishes: ["plan.ready"] publishes: ["plan.ready"]
memory: memory:
path: ".ralph/agent/memories.md" path: ".ralph/agent/memories.md"
scope: "global" scope: "global"
instructions: | instructions: |
You are the planner. Read PROMPT.md first. You are the Planner. Read PROMPT.md for the full task specification.
If triggered by review.changes_requested, read .ralph/review.md and update the plan for the exact issues raised. If triggered by review.changes_requested, read .ralph/review.md for visual
review feedback and update the plan to address those specific issues.
Your job: Your job:
1. Inspect the relevant files and current highlight flow. 1. Read the existing codebase to understand current responsive patterns
2. Write a concrete implementation plan to .ralph/plan.md. 2. Identify all components that break at viewport widths 320-430px
3. Include exact files to change and how hover state should propagate. 3. Create a prioritised, ordered fix plan in .ralph/plan.md
4. Include a verification checklist matching PROMPT.md success criteria. 4. Each fix should specify: which file, what change, and why
5. Group fixes by component/file to minimise context switches
Rules: Key files to audit:
- Do not write code in this hat. - src/index.css (media queries)
- Keep the plan iteration-scoped and actionable. - tailwind.config.js (breakpoints)
- If all PROMPT.md criteria are already satisfied and validated, print LOOP_COMPLETE. - src/components/DashboardLayout.tsx (main layout)
- src/components/Sidebar.tsx (sidebar overlay width)
- src/components/tiles/PatientSummaryTile.tsx (KPI grid)
- src/components/tiles/ProjectsTile.tsx (carousel)
- src/components/timeline/TimelineInterventionsSubsection.tsx
- src/components/constellation/CareerConstellation.tsx
- src/components/DetailPanel.tsx
- src/components/ui/Card.tsx (overflow behavior)
Emit plan.ready when the plan is complete. Write the plan to .ralph/plan.md then emit plan.ready.
Do NOT write any implementation code. Planning only.
CIRCUIT BREAKER: If you see the same review feedback 3 times in a row,
escalate by writing the blocker to .ralph/review.md with status "NEEDS_HUMAN"
and print LOOP_COMPLETE.
builder: builder:
name: "Hover Focus Builder" name: "Responsive Builder"
description: "Implements the planned dimming/highlight behavior and prepares for review." description: "Implements responsive CSS/layout fixes from the plan, ensuring lint/typecheck/build pass."
triggers: ["plan.ready"] triggers: ["plan.ready"]
publishes: ["build.done"] publishes: ["build.done"]
memory: memory:
path: ".ralph/agent/memories.md" path: ".ralph/agent/memories.md"
scope: "global" scope: "global"
instructions: | instructions: |
You are the builder. Read PROMPT.md and .ralph/plan.md. You are the Builder. Read PROMPT.md for the task and .ralph/plan.md for the
implementation plan.
Your job: Your job:
1. Implement the plan in the codebase. 1. Follow the plan step by step
2. Ensure hover interactions cover graph node hover and skill pill hover. 2. Make focused, minimal changes to fix mobile responsiveness
3. Keep the active skill pill, active node, connecting lines, and related timeline series item visually emphasized while non-related UI darkens. 3. After each significant change, run: npm run lint && npm run typecheck
4. Preserve accessibility and reduced-motion behavior. 4. Mark completed steps in .ralph/plan.md
5. Run npm run lint && npm run typecheck && npm run build. 5. Prefer Tailwind utility classes over custom CSS where possible
6. Record what changed and what was validated in .ralph/build.md. 6. Use existing CSS custom properties and design tokens
7. Verify changes don't break desktop layouts (768px+)
Rules: Key conventions:
- Follow existing project conventions and styling patterns. - Path alias: @/* maps to src/*
- Do not add new dependencies. - TypeScript strict mode with noUnusedLocals/noUnusedParameters
- Do not claim completion if any gate fails. - Tailwind for styling, inline CSSProperties for dynamic values
- Framer Motion for animations (respect prefers-reduced-motion)
Emit build.done when implementation is complete and gates pass. When all planned fixes are implemented and quality gates pass,
emit build.done.
Do NOT assess visual quality — that's the Reviewer's job.
CIRCUIT BREAKER: If you've attempted the same fix 3 times and it keeps
failing lint/typecheck/build, write the blocker to .ralph/review.md
and emit build.done so the Reviewer can assess.
reviewer: reviewer:
name: "Hover Focus Reviewer" name: "Visual Reviewer"
description: "Validates feature behavior and runs Playwright MCP checks before approving." description: "Uses Playwright MCP to visually validate mobile responsiveness at all target viewports."
triggers: ["build.done"] triggers: ["build.done"]
publishes: ["review.changes_requested"] publishes: ["review.changes_requested"]
memory: memory:
path: ".ralph/agent/memories.md" path: ".ralph/agent/memories.md"
scope: "global" scope: "global"
instructions: | instructions: |
You are the reviewer. Read PROMPT.md, .ralph/plan.md, and .ralph/build.md. You are the Visual Reviewer. Use Playwright MCP to visually verify the
portfolio website is responsive at small viewport widths.
Validation order: Read PROMPT.md for requirements and success criteria.
1. Run npm run lint && npm run typecheck && npm run build.
2. Verify code changes match PROMPT.md requirements.
3. Use Playwright MCP to verify behavior in the running app:
- Ensure dev server is running at http://localhost:5173 (start npm run dev if needed).
- Navigate to the dashboard where the constellation chart is visible.
- Hover a constellation node and confirm:
a) page/axis/background and unrelated UI are darkened,
b) hovered node remains highlighted,
c) connection lines for the hovered/related skill relationship remain highlighted,
d) related timeline series item remains highlighted.
- Hover a skill pill and confirm the same focused-state behavior.
- Capture evidence with at least one screenshot per hover scenario.
4. Write findings to .ralph/review.md with pass/fail evidence.
Decision: ## Review Process
- If every criterion is satisfied, print LOOP_COMPLETE.
- If anything fails, write exact fixes in .ralph/review.md and emit review.changes_requested.
Circuit breaker: 1. Ensure the dev server is running at http://localhost:5173
- If the same blocker repeats with materially identical evidence for 3 cycles, If not, run `npm run dev` in the background from the project root.
record status ESCALATE in .ralph/review.md with owner + target date,
emit review.changes_requested, and require human clarification before continuing. 2. Use Playwright MCP to launch a browser and navigate to http://localhost:5173
3. Get past the boot sequence to reach the dashboard:
- Wait for boot sequence to complete
- Click through login screen if present
- Wait until dashboard is fully rendered
4. For each target viewport width (320, 360, 375, 390, 400, 414, 430px):
a. Set viewport to {width}x812px
b. Take a screenshot
c. Visually inspect for:
- Horizontal scrollbar (body must not scroll horizontally)
- Text clipped/hidden without ellipsis
- Elements overlapping or pushed off-screen
- Text too small to read (< 12px)
- Interactive elements too small to tap (< 44px)
- Excessive empty space or cramped layouts
- Bottom nav bar should be visible at bottom of screen (not a sidebar)
d. Scroll through the full page and check each section
e. Test the bottom nav bar:
- Verify collapsed state shows icon-based navigation at bottom edge
- Tap/click to expand the drawer and verify full nav content appears
- Verify drawer can be collapsed back
- Verify collapsed bar does not obscure page content
f. Record findings
5. Verify desktop is not broken:
- Set viewport to 1280x800
- Take screenshot
- Verify dashboard layout is unchanged
## Writing Your Review
Write findings to .ralph/review.md:
```
# Visual Review
## Viewport Results
### 320px
- [PASS/FAIL] [description]
### 360px
- [PASS/FAIL] [description]
(... each viewport ...)
### Desktop (1280px)
- [PASS/FAIL] Must be unchanged
## Issues Found
- [ ] [Specific issue with component name and description]
## Verdict
[APPROVED / CHANGES_REQUESTED]
```
If ALL viewports pass and desktop is unchanged, print LOOP_COMPLETE.
If issues remain, write specific actionable feedback and emit review.changes_requested.
CIRCUIT BREAKER: If materially identical issues persist across 3 consecutive
reviews, write to .ralph/review.md with status "NEEDS_HUMAN", note recurring
issues and what was attempted, then print LOOP_COMPLETE.
+1 -1
View File
@@ -2,7 +2,7 @@ cli:
backend: "claude" backend: "claude"
event_loop: event_loop:
prompt_file: "PROMPT.md" starting_event: "work.start"
completion_promise: "LOOP_COMPLETE" completion_promise: "LOOP_COMPLETE"
max_iterations: 40 max_iterations: 40