Repository navigation
feat(graph): responsive mobile layout, light/dark/system theme, and zoom controls - #10
Conversation
✅ All automated checks passedThe following checks completed successfully:
Your contribution is ready for review. 🎉 |
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe knowledge graph UI now supports light, dark, and system themes. It adds persisted theme selection, system-theme synchronization, responsive inspector and zoom controls, accessible navigation, theme-aware graph palettes, and centralized node repainting. The generator and generated page contain matching changes. ChangesTheme-aware graph UI
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant ThemeControls
participant localStorage
participant matchMedia
participant applyTheme
participant paintNodes
participant Graph
ThemeControls->>localStorage: Persist selected theme
ThemeControls->>applyTheme: Apply light, dark, or system theme
matchMedia->>applyTheme: Report system theme changes
applyTheme->>Graph: Update graph palette
applyTheme->>paintNodes: Repaint nodes
paintNodes->>Graph: Update search and node colors
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches✨ Simplify code
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ast-grep (0.45.1)docs/index.htmlast-grep timed out on this file Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/build_knowledge_graph.py`:
- Around line 1023-1027: Update the Graph.cameraPosition call in
scripts/build_knowledge_graph.py to pass 0 instead of 220 when
prefers-reduced-motion: reduce matches, while retaining 220 otherwise.
Regenerate docs/index.html so its corresponding Graph.cameraPosition call
reflects the same behavior.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 98fd712b-cf87-4402-8c49-1b2e28917acb
📒 Files selected for processing (2)
docs/index.htmlscripts/build_knowledge_graph.py
Description
Makes the knowledge graph page usable on phones, and adds a theme switcher plus zoom controls.
1. Mobile layout fix. The page had no media queries at all — it was a desktop-only fixed-panel layout, so panels overlapped on a phone:
#headerwasleft:20px; max-width:380px→ 400px of panel on a 390px screen, overflowing the right edge.bottom:24px. On a phone they met in the middle, and nothing bounded either one.body{overflow:hidden}meant anything buried under a panel was unreachable.height:100vhincludes Safari's collapsing URL bar, pushing the bottom card under browser chrome.Overlap is now impossible by construction: the header caps at
40dvhfrom the top and the bottom stack at45dvhfrom the bottom, leaving a 15dvh gutter regardless of content. Both scroll internally instead of growing. Also:100dvh, a 16px input font, 44px tap targets, a landscape branch that places panels side-by-side, and aprefers-reduced-motionguard. The library's "Left-click: rotate, Mouse-wheel: zoom" hint is hidden on touch devices, where it was clipped behind the card and described controls that don't exist.2. Theme switcher (light / dark / system). A segmented control in the header (
role="radiogroup", arrow-key navigable, roving tabindex), persisted tolocalStorageand defaulting to the OS preference.The page was hardcoded dark, so the bulk of this is tokenizing every colour into CSS custom properties — no hardcoded colours remain in the stylesheet. Tokens use the three-state pattern: light on bare
:root, dark layered twice (@media (prefers-color-scheme: dark)guarded with:not([data-theme="light"])for system mode, and[data-theme="dark"]so an explicit pick beats the OS).Three things needed more than CSS:
backgroundColor()/linkColor()/linkOpacity()on each switch.paintNodes()owner.Card tags moved from JS inline styles to data attributes, since inline dark-only hex values can't respond to a theme.
3. Zoom controls, bottom-right. The inspector card already occupied
bottom:24px; right:24px— exactly where the buttons go. Instead of nudging offsets, they're flex siblings in one positioned wrapper, so normal flow guarantees they can't overlap at any content size. The wrapper ispointer-events:nonewith childrenauto, so its empty area still rotates the graph rather than creating a dead zone. Zoom scales camera distance, clamped to 40–4000 so repeated clicks can't invert through the origin or lose the graph.Accessibility
All 14 tag variants and every text token now clear WCAG AA (4.5:1) in both themes. Computing tag text against its actual tinted background (not the panel) surfaced 4 variants at 3.96–4.30:1; lowering
--tag-alphato 0.10/0.15 fixes it. Note the dark-mode failures there were pre-existing, not introduced here.Verification
Measured in headless Chromium rather than assumed:
cameraPosition()works as a getter (1390 → 1030 → 1390); clamps hold at exactly 40 and 4000; camera direction stays finite.validate_content.pyandgenerate_indexes.py --checkpass, and the build is deterministic (byte-identical rebuild), so CI won't churn the diff.Type of Change
Topic
Not topic-scoped — this changes the generated knowledge-graph UI.
scripts/(template) anddocs/(generated output)Checklist
See CONTRIBUTING.md for the full format.
python3 scripts/generate_indexes.pyandpython3 scripts/build_knowledge_graph.py— indexes verified up to date via--check; graph HTML is regenerated, not hand-edited. All UI changes were made in theHTML_TEMPLATEinscripts/build_knowledge_graph.py, since the workflow rebuildsdocs/index.htmlon every push tomainand a direct HTML edit would be silently overwritten.python3 scripts/validate_content.pyand it passed.