@hienlh/ppm 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/.claude/agent-memory/tester/MEMORY.md +3 -0
  2. package/.claude/agent-memory/tester/project-ppm-test-conventions.md +32 -0
  3. package/.env.example +1 -0
  4. package/.github/workflows/release.yml +46 -0
  5. package/README.md +349 -0
  6. package/bun.lock +1217 -0
  7. package/components.json +21 -0
  8. package/docs/code-standards.md +574 -0
  9. package/docs/codebase-summary.md +294 -0
  10. package/docs/deployment-guide.md +631 -0
  11. package/docs/design-guidelines.md +661 -0
  12. package/docs/project-overview-pdr.md +142 -0
  13. package/docs/project-roadmap.md +400 -0
  14. package/docs/system-architecture.md +459 -0
  15. package/package.json +68 -0
  16. package/plans/260314-2009-ppm-implementation/phase-01-project-skeleton.md +81 -0
  17. package/plans/260314-2009-ppm-implementation/phase-02-backend-core.md +148 -0
  18. package/plans/260314-2009-ppm-implementation/phase-03-frontend-shell.md +256 -0
  19. package/plans/260314-2009-ppm-implementation/phase-04-file-explorer-editor.md +120 -0
  20. package/plans/260314-2009-ppm-implementation/phase-05-web-terminal.md +174 -0
  21. package/plans/260314-2009-ppm-implementation/phase-06-git-integration.md +244 -0
  22. package/plans/260314-2009-ppm-implementation/phase-07-ai-chat.md +242 -0
  23. package/plans/260314-2009-ppm-implementation/phase-08-cli-commands.md +143 -0
  24. package/plans/260314-2009-ppm-implementation/phase-09-pwa-build-deploy.md +209 -0
  25. package/plans/260314-2009-ppm-implementation/phase-10-testing.md +311 -0
  26. package/plans/260314-2009-ppm-implementation/plan.md +202 -0
  27. package/plans/260315-0356-project-scoped-api-refactor/phase-01-backend-project-router.md +145 -0
  28. package/plans/260315-0356-project-scoped-api-refactor/phase-02-frontend-api-migration.md +107 -0
  29. package/plans/260315-0356-project-scoped-api-refactor/phase-03-per-project-tabs.md +100 -0
  30. package/plans/260315-0356-project-scoped-api-refactor/phase-04-websocket-migration.md +66 -0
  31. package/plans/260315-0356-project-scoped-api-refactor/plan.md +87 -0
  32. package/plans/reports/brainstorm-260314-1938-final-techstack.md +342 -0
  33. package/plans/reports/docs-manager-260315-1314-documentation-creation.md +386 -0
  34. package/plans/reports/fullstack-developer-260314-2252-phase-02-backend-core.md +57 -0
  35. package/plans/reports/fullstack-developer-260314-2253-phase-03-frontend-shell.md +70 -0
  36. package/plans/reports/fullstack-developer-260314-2300-phase-04-05-file-api-terminal-ws.md +49 -0
  37. package/plans/reports/fullstack-developer-260314-2300-phase-04-05-file-explorer-editor-terminal.md +52 -0
  38. package/plans/reports/fullstack-developer-260314-2307-ai-chat-phase7.md +58 -0
  39. package/plans/reports/fullstack-developer-260314-2307-phase-06-git-integration.md +33 -0
  40. package/plans/reports/research-260314-1911-ppm-tech-stack.md +318 -0
  41. package/plans/reports/research-260314-1930-claude-code-integration.md +293 -0
  42. package/plans/reports/researcher-260314-2232-node-pty-bun-crash-analysis.md +305 -0
  43. package/plans/reports/researcher-260314-2232-ui-style.md +942 -0
  44. package/plans/reports/researcher-260315-0300-opcode-claude-interaction.md +745 -0
  45. package/plans/reports/researcher-260315-0303-opcode-deep-analysis.md +742 -0
  46. package/plans/reports/researcher-260315-0305-claude-agent-sdk-github-research.md +423 -0
  47. package/plans/reports/tester-260314-2053-initial-test-suite.md +81 -0
  48. package/ppm.example.yaml +14 -0
  49. package/repomix-output.xml +23745 -0
  50. package/scripts/build.ts +13 -0
  51. package/src/cli/commands/chat-cmd.ts +259 -0
  52. package/src/cli/commands/config-cmd.ts +121 -0
  53. package/src/cli/commands/git-cmd.ts +315 -0
  54. package/src/cli/commands/init.ts +57 -0
  55. package/src/cli/commands/open.ts +19 -0
  56. package/src/cli/commands/projects.ts +100 -0
  57. package/src/cli/commands/start.ts +3 -0
  58. package/src/cli/commands/stop.ts +33 -0
  59. package/src/cli/utils/project-resolver.ts +27 -0
  60. package/src/index.ts +59 -0
  61. package/src/providers/claude-agent-sdk.ts +499 -0
  62. package/src/providers/claude-binary-finder.ts +256 -0
  63. package/src/providers/claude-code-cli.ts +413 -0
  64. package/src/providers/claude-process-registry.ts +106 -0
  65. package/src/providers/mock-provider.ts +171 -0
  66. package/src/providers/provider.interface.ts +10 -0
  67. package/src/providers/registry.ts +45 -0
  68. package/src/server/helpers/resolve-project.ts +22 -0
  69. package/src/server/index.ts +181 -0
  70. package/src/server/middleware/auth.ts +30 -0
  71. package/src/server/routes/chat.ts +153 -0
  72. package/src/server/routes/files.ts +168 -0
  73. package/src/server/routes/git.ts +261 -0
  74. package/src/server/routes/project-scoped.ts +27 -0
  75. package/src/server/routes/projects.ts +57 -0
  76. package/src/server/routes/static.ts +26 -0
  77. package/src/server/ws/chat.ts +130 -0
  78. package/src/server/ws/terminal.ts +89 -0
  79. package/src/services/chat.service.ts +110 -0
  80. package/src/services/claude-usage.service.ts +113 -0
  81. package/src/services/config.service.ts +90 -0
  82. package/src/services/file.service.ts +261 -0
  83. package/src/services/git-dirs.service.ts +112 -0
  84. package/src/services/git.service.ts +372 -0
  85. package/src/services/project.service.ts +107 -0
  86. package/src/services/slash-items.service.ts +184 -0
  87. package/src/services/terminal.service.ts +212 -0
  88. package/src/types/api.ts +37 -0
  89. package/src/types/chat.ts +92 -0
  90. package/src/types/config.ts +41 -0
  91. package/src/types/git.ts +50 -0
  92. package/src/types/project.ts +18 -0
  93. package/src/types/terminal.ts +20 -0
  94. package/src/web/app.tsx +168 -0
  95. package/src/web/components/auth/login-screen.tsx +88 -0
  96. package/src/web/components/chat/attachment-chips.tsx +55 -0
  97. package/src/web/components/chat/chat-placeholder.tsx +10 -0
  98. package/src/web/components/chat/chat-tab.tsx +301 -0
  99. package/src/web/components/chat/file-picker.tsx +126 -0
  100. package/src/web/components/chat/message-input.tsx +420 -0
  101. package/src/web/components/chat/message-list.tsx +838 -0
  102. package/src/web/components/chat/session-picker.tsx +139 -0
  103. package/src/web/components/chat/slash-command-picker.tsx +135 -0
  104. package/src/web/components/chat/usage-badge.tsx +186 -0
  105. package/src/web/components/editor/code-editor.tsx +329 -0
  106. package/src/web/components/editor/diff-viewer.tsx +276 -0
  107. package/src/web/components/editor/editor-placeholder.tsx +10 -0
  108. package/src/web/components/explorer/file-actions.tsx +191 -0
  109. package/src/web/components/explorer/file-tree.tsx +298 -0
  110. package/src/web/components/git/git-graph.tsx +727 -0
  111. package/src/web/components/git/git-placeholder.tsx +55 -0
  112. package/src/web/components/git/git-status-panel.tsx +850 -0
  113. package/src/web/components/layout/mobile-drawer.tsx +137 -0
  114. package/src/web/components/layout/mobile-nav.tsx +103 -0
  115. package/src/web/components/layout/sidebar.tsx +90 -0
  116. package/src/web/components/layout/tab-bar.tsx +152 -0
  117. package/src/web/components/layout/tab-content.tsx +85 -0
  118. package/src/web/components/projects/dir-suggest.tsx +152 -0
  119. package/src/web/components/projects/project-list.tsx +187 -0
  120. package/src/web/components/settings/settings-tab.tsx +57 -0
  121. package/src/web/components/terminal/terminal-placeholder.tsx +10 -0
  122. package/src/web/components/terminal/terminal-tab.tsx +133 -0
  123. package/src/web/components/ui/button.tsx +64 -0
  124. package/src/web/components/ui/context-menu.tsx +250 -0
  125. package/src/web/components/ui/dialog.tsx +156 -0
  126. package/src/web/components/ui/dropdown-menu.tsx +257 -0
  127. package/src/web/components/ui/input.tsx +21 -0
  128. package/src/web/components/ui/scroll-area.tsx +56 -0
  129. package/src/web/components/ui/separator.tsx +26 -0
  130. package/src/web/components/ui/sonner.tsx +40 -0
  131. package/src/web/components/ui/tabs.tsx +91 -0
  132. package/src/web/components/ui/tooltip.tsx +57 -0
  133. package/src/web/hooks/use-chat.ts +420 -0
  134. package/src/web/hooks/use-terminal.ts +182 -0
  135. package/src/web/hooks/use-url-sync.ts +66 -0
  136. package/src/web/hooks/use-websocket.ts +48 -0
  137. package/src/web/index.html +16 -0
  138. package/src/web/lib/api-client.ts +90 -0
  139. package/src/web/lib/file-support.ts +68 -0
  140. package/src/web/lib/utils.ts +6 -0
  141. package/src/web/lib/ws-client.ts +100 -0
  142. package/src/web/main.tsx +10 -0
  143. package/src/web/public/icon-192.svg +5 -0
  144. package/src/web/public/icon-512.svg +5 -0
  145. package/src/web/stores/file-store.ts +81 -0
  146. package/src/web/stores/project-store.ts +50 -0
  147. package/src/web/stores/settings-store.ts +65 -0
  148. package/src/web/stores/tab-store.ts +187 -0
  149. package/src/web/styles/globals.css +227 -0
  150. package/src/web/vite-env.d.ts +1 -0
  151. package/tests/integration/api/chat-routes.test.ts +95 -0
  152. package/tests/integration/claude-agent-sdk-integration.test.ts +228 -0
  153. package/tests/integration/ws/chat-websocket.test.ts +312 -0
  154. package/tests/test-setup.ts +5 -0
  155. package/tests/unit/providers/claude-agent-sdk.test.ts +339 -0
  156. package/tests/unit/providers/mock-provider.test.ts +143 -0
  157. package/tests/unit/services/chat-service.test.ts +100 -0
  158. package/tsconfig.json +32 -0
  159. package/vite.config.ts +62 -0
@@ -0,0 +1,942 @@
1
+ # PPM UI Style Guide: Mobile-First Developer Dark Theme
2
+
3
+ **Date:** 2026-03-14
4
+ **Status:** Research Complete
5
+ **Context:** PPM (Personal Project Manager) — mobile-first web IDE
6
+ **Tech Stack:** React 19 + Vite + Tailwind CSS 4 + shadcn/ui
7
+
8
+ ---
9
+
10
+ ## Executive Summary
11
+
12
+ PPM needs a **dark, minimal, professional** UI that maximizes code/content real estate on mobile while scaling beautifully to desktop. Inspired by modern web IDEs (Replit, CodeSandbox, VS Code), this guide provides a complete design system with:
13
+
14
+ - Color palette optimized for code editing + WCAG AA contrast compliance
15
+ - Typography system (mono + sans-serif fonts)
16
+ - Component styling rules for shadcn/ui dark mode
17
+ - Mobile-first layout patterns (bottom nav, compact spacing)
18
+ - Tailwind CSS configuration template
19
+
20
+ **Recommendation:** Adopt **"Slate Dark" theme** — inspired by VS Code's dark theme but refined for mobile-first web IDEs.
21
+
22
+ ---
23
+
24
+ ## 1. Recommended Style: "Slate Dark"
25
+
26
+ **Name:** Slate Dark (Developer)
27
+ **Philosophy:** Minimal, high-contrast, code-centric
28
+ **Use Case:** Professional development tool for mobile + desktop
29
+ **Inspiration:**
30
+ - VS Code default dark theme (proven for 2+ billion users)
31
+ - GitHub Codespaces mobile web editor (cloud IDE best practices)
32
+ - Replit dark mode (community-tested)
33
+ - CodeSandbox responsive design (mobile code editing expert)
34
+
35
+ ---
36
+
37
+ ## 2. Color Palette
38
+
39
+ ### Primary Colors (Background & Surface)
40
+
41
+ | Name | Hex | Usage | WCAG AA Contrast |
42
+ |------|-----|-------|---------|
43
+ | **Background** | `#0f1419` | Main app background | — |
44
+ | **Surface** | `#1a1f2e` | Cards, panels, modals | — |
45
+ | **Surface Elevated** | `#252d3d` | Hover state, selected panels | — |
46
+ | **Border** | `#404854` | Dividers, input borders | — |
47
+
48
+ **Rationale:**
49
+ - `#0f1419` is pure dark (OLED-friendly), reduces eye strain for long sessions
50
+ - Maintains ~15% brightness difference between layers for visual hierarchy
51
+ - Slate grey borders avoid harsh pure black/white contrast (accessibility best practice)
52
+
53
+ ### Text Colors
54
+
55
+ | Name | Hex | Usage | Contrast Ratio |
56
+ |------|-----|-------|---------|
57
+ | **Text Primary** | `#e5e7eb` | Body text, code, UI labels | 13.5:1 on bg |
58
+ | **Text Secondary** | `#9ca3af` | Hints, timestamps, muted text | 6.2:1 on bg |
59
+ | **Text Subtle** | `#6b7280` | Disabled state, very subtle | 4.5:1 on bg (AA) |
60
+
61
+ **Rationale:**
62
+ - `#e5e7eb` ≠ pure white (avoids harsh contrast, reduces blue light)
63
+ - Secondary text reserved for truly secondary info (not main UI labels)
64
+ - All ratios meet WCAG AA standard (4.5:1 minimum)
65
+
66
+ ### Accent Colors (Interactive)
67
+
68
+ | Name | Hex | Usage | Notes |
69
+ |------|-----|-------|-------|
70
+ | **Primary Blue** | `#3b82f6` | Buttons, active tabs, focus rings | Vibrant, accessible on dark bg |
71
+ | **Success Green** | `#10b981` | Commit, save, success messages | High saturation for code UI |
72
+ | **Warning Orange** | `#f59e0b` | Git conflicts, unsaved changes | Stands out without being harsh |
73
+ | **Error Red** | `#ef4444` | Errors, deletions, danger | Strong red for critical actions |
74
+ | **Info Cyan** | `#06b6d4` | Info badges, active branches | Code-editor standard |
75
+
76
+ **Rationale:**
77
+ - Saturated accent colors match VS Code / code editor conventions
78
+ - All accent colors >= 7:1 contrast on dark background
79
+ - Blue for primary CTA (familiar from most code editors)
80
+
81
+ ### Code Syntax Highlighting Colors
82
+
83
+ | Element | Hex | Notes |
84
+ |---------|-----|-------|
85
+ | **Keyword** | `#c9d1d9` | if, function, class, etc. |
86
+ | **String** | `#a5d6ff` | Light blue (VS Code style) |
87
+ | **Comment** | `#8b949e` | Muted grey |
88
+ | **Number** | `#79c0ff` | Light blue |
89
+ | **Variable** | `#e5e7eb` | Inherit from text primary |
90
+ | **Function** | `#d2a8ff` | Light purple |
91
+
92
+ **Rationale:**
93
+ - Derived from VS Code's default dark theme (proven palette)
94
+ - CodeMirror 6 supports these colors out-of-box via theme tokens
95
+
96
+ ---
97
+
98
+ ## 3. Typography System
99
+
100
+ ### Font Stack
101
+
102
+ #### UI Font (Navigation, Labels, Components)
103
+ ```css
104
+ font-family: 'Geist Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', sans-serif;
105
+ ```
106
+
107
+ **Why Geist Sans:**
108
+ - Designed by Vercel specifically for developer tools (modern + clean)
109
+ - Variable font (flexible weights: 400-700)
110
+ - Excellent on small screens (high x-height, clear letterforms)
111
+ - Free via Google Fonts or Vercel's public repo
112
+ - Fallback chain ensures iOS/Android native fonts work
113
+
114
+ #### Code Font (Editor, Terminal, Code Blocks)
115
+ ```css
116
+ font-family: 'Geist Mono', 'Monospace', 'Monaco', 'Courier New', monospace;
117
+ ```
118
+
119
+ **Why Geist Mono:**
120
+ - Matches Geist Sans (visual consistency)
121
+ - Designed for code readability (clear `1lI` distinction)
122
+ - Programming ligatures optional (≠, >=, etc.)
123
+ - 8-14px range readable on mobile
124
+
125
+ **Alternative (GitHub Standard):** `Monaspace Neon` (GitHub's modern coding font)
126
+
127
+ ### Font Sizes & Weights
128
+
129
+ #### UI Text
130
+
131
+ | Element | Size | Weight | Line Height | Usage |
132
+ |---------|------|--------|---------|-------|
133
+ | **Display** | 28px | 600 | 1.3 | Modal titles, page headers |
134
+ | **Heading 1** | 24px | 600 | 1.4 | Tab titles, section headers |
135
+ | **Heading 2** | 20px | 500 | 1.4 | Subsection titles |
136
+ | **Body Large** | 16px | 400 | 1.6 | Main content text |
137
+ | **Body** | 14px | 400 | 1.5 | Default UI text (labels, hints) |
138
+ | **Small** | 12px | 400 | 1.4 | Secondary labels, timestamps |
139
+ | **Tiny** | 11px | 400 | 1.4 | Badge text, meta info |
140
+
141
+ **Rationale:**
142
+ - Tailwind's default scale: 12, 14, 16, 18, 20, 24, 28, 32px
143
+ - 14px = industry standard for dev tools (readable on 375px mobile)
144
+ - Line-height >= 1.5 improves readability (esp. on small screens)
145
+
146
+ #### Code Text
147
+
148
+ | Context | Size | Weight | Notes |
149
+ |---------|------|--------|-------|
150
+ | **Editor** | 13px | 400 | Mobile readable, matches VS Code default |
151
+ | **Terminal** | 12px | 400 | Compact, xterm.js standard |
152
+ | **Diff View** | 12px | 400 | Space-constrained |
153
+
154
+ ---
155
+
156
+ ## 4. Component Styling Guidelines
157
+
158
+ ### shadcn/ui Dark Mode Theme Configuration
159
+
160
+ Create `globals.css` with CSS variables:
161
+
162
+ ```css
163
+ @theme {
164
+ --color-background: #0f1419;
165
+ --color-foreground: #e5e7eb;
166
+
167
+ --color-card: #1a1f2e;
168
+ --color-card-foreground: #e5e7eb;
169
+
170
+ --color-primary: #3b82f6;
171
+ --color-primary-foreground: #ffffff;
172
+
173
+ --color-secondary: #6b7280;
174
+ --color-secondary-foreground: #e5e7eb;
175
+
176
+ --color-destructive: #ef4444;
177
+ --color-destructive-foreground: #ffffff;
178
+
179
+ --color-muted: #6b7280;
180
+ --color-muted-foreground: #9ca3af;
181
+
182
+ --color-accent: #3b82f6;
183
+ --color-accent-foreground: #ffffff;
184
+
185
+ --color-popover: #1a1f2e;
186
+ --color-popover-foreground: #e5e7eb;
187
+
188
+ --color-input: #404854;
189
+ --color-ring: #3b82f6;
190
+
191
+ --color-border: #404854;
192
+ }
193
+
194
+ :root {
195
+ --background: 0 0% 5.8%;
196
+ --foreground: 0 0% 89%;
197
+ --card: 0 0% 11.8%;
198
+ --card-foreground: 0 0% 89%;
199
+ --popover: 0 0% 11.8%;
200
+ --popover-foreground: 0 0% 89%;
201
+ --primary: 217 92% 57%;
202
+ --primary-foreground: 210 40% 98%;
203
+ --secondary: 210 15% 42%;
204
+ --secondary-foreground: 210 40% 98%;
205
+ --muted: 210 15% 42%;
206
+ --muted-foreground: 215 13% 61%;
207
+ --accent: 217 92% 57%;
208
+ --accent-foreground: 210 40% 98%;
209
+ --destructive: 0 84% 60%;
210
+ --destructive-foreground: 210 40% 98%;
211
+ --border: 217 32% 25%;
212
+ --input: 217 32% 25%;
213
+ --ring: 217 92% 57%;
214
+ --radius: 0.5rem;
215
+ }
216
+
217
+ .dark {
218
+ --background: 0 0% 5.8%;
219
+ --foreground: 0 0% 89%;
220
+ /* ... same as :root for dark-only setup */
221
+ }
222
+ ```
223
+
224
+ ### Spacing System
225
+
226
+ Use Tailwind's default scale (consistent with design system):
227
+
228
+ | Token | Size | Mobile Use | Desktop Use |
229
+ |-------|------|-----------|-----------|
230
+ | `space-1` | 4px | Text letter-spacing | — |
231
+ | `space-2` | 8px | Compact padding | — |
232
+ | `space-3` | 12px | Label-icon gap | Subtle spacing |
233
+ | `space-4` | 16px | Default padding | Default padding |
234
+ | `space-6` | 24px | Section spacing | Section spacing |
235
+ | `space-8` | 32px | Large gaps | Card spacing |
236
+
237
+ **Mobile Rule:** Prefer `space-3`, `space-4` on 375px viewport. Avoid `space-8+` except section breaks.
238
+
239
+ ### Border Radius
240
+
241
+ ```css
242
+ --radius: 0.5rem; /* 8px */
243
+ --radius-sm: 0.375rem; /* 6px */
244
+ --radius-md: 0.5rem; /* 8px */
245
+ --radius-lg: 0.75rem; /* 12px */
246
+ ```
247
+
248
+ **Rationale:**
249
+ - 8px default = balanced (not flat, not skeuomorphic)
250
+ - Larger radius (12px) for modals, cards
251
+ - Smaller radius (6px) for inputs, badges
252
+
253
+ ### Shadows (Dark Mode Adjusted)
254
+
255
+ ```css
256
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
257
+ --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.5);
258
+ --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.5);
259
+ --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.5);
260
+ ```
261
+
262
+ **Rationale:**
263
+ - Dark mode shadows use black with moderate opacity (not harsh)
264
+ - Avoid pure white shadows (invert of light mode)
265
+ - Add subtle borders instead of relying on shadows alone
266
+
267
+ ### Button Styling
268
+
269
+ ```tsx
270
+ // Primary CTA (blue)
271
+ <Button className="bg-blue-500 text-white hover:bg-blue-600">
272
+ Submit
273
+ </Button>
274
+
275
+ // Secondary (muted)
276
+ <Button variant="outline" className="border-gray-600 text-gray-300">
277
+ Cancel
278
+ </Button>
279
+
280
+ // Danger (red)
281
+ <Button className="bg-red-500 text-white hover:bg-red-600">
282
+ Delete
283
+ </Button>
284
+
285
+ // Touch Target: 44px minimum
286
+ <Button className="h-11 px-4"> {/* 44px tall */}
287
+ Touch-friendly
288
+ </Button>
289
+ ```
290
+
291
+ ### Input & Form Fields
292
+
293
+ ```tsx
294
+ <input
295
+ className="
296
+ bg-slate-900 border border-slate-700
297
+ rounded-md px-3 py-2
298
+ text-slate-100 placeholder-slate-500
299
+ focus:border-blue-500 focus:ring-1 focus:ring-blue-500
300
+ disabled:opacity-50 disabled:cursor-not-allowed
301
+ "
302
+ placeholder="Enter text..."
303
+ />
304
+ ```
305
+
306
+ **Rationale:**
307
+ - Dark background + light border (inverted from light mode)
308
+ - Focus ring blue (matches primary accent)
309
+ - Placeholder grey (secondary text color)
310
+
311
+ ### Cards & Panels
312
+
313
+ ```tsx
314
+ <div className="
315
+ bg-slate-900 border border-slate-800
316
+ rounded-lg p-4 shadow-md
317
+ hover:bg-slate-800 transition-colors
318
+ ">
319
+ Content
320
+ </div>
321
+ ```
322
+
323
+ ### Focus Ring (Accessibility)
324
+
325
+ ```css
326
+ :focus-visible {
327
+ outline: 2px solid #3b82f6;
328
+ outline-offset: 2px;
329
+ }
330
+ ```
331
+
332
+ ---
333
+
334
+ ## 5. Mobile-First UI Patterns
335
+
336
+ ### Bottom Tab Navigation (Mobile)
337
+
338
+ **Requirement:** 44px minimum touch target
339
+
340
+ ```tsx
341
+ <nav className="
342
+ fixed bottom-0 left-0 right-0
343
+ bg-slate-900 border-t border-slate-800
344
+ flex gap-0
345
+ h-16 z-40
346
+ ">
347
+ {tabs.map(tab => (
348
+ <button
349
+ key={tab.id}
350
+ onClick={() => setActive(tab.id)}
351
+ className={`
352
+ flex-1 h-16 flex flex-col items-center justify-center
353
+ gap-1 transition-colors border-t-2
354
+ ${active === tab.id
355
+ ? 'border-blue-500 bg-slate-800 text-blue-400'
356
+ : 'border-transparent text-slate-400'
357
+ }
358
+ `}
359
+ >
360
+ <icon className="w-6 h-6" />
361
+ <span className="text-xs truncate">{tab.label}</span>
362
+ </button>
363
+ ))}
364
+ </nav>
365
+ ```
366
+
367
+ **Design Rules:**
368
+ - Height: 16px (64px) minimum
369
+ - Gap between icon + label: 4px
370
+ - Active indicator: top border (not bottom, avoids confusion with app edges)
371
+ - Max 5 tabs before "more" menu
372
+ - Icons only: 6x24px, Labels: Truncate at 3 chars
373
+
374
+ ### Top Tab Bar (Desktop)
375
+
376
+ ```tsx
377
+ <div className="flex gap-1 border-b border-slate-800 px-4 overflow-x-auto">
378
+ {tabs.map(tab => (
379
+ <button
380
+ key={tab.id}
381
+ className={`
382
+ px-3 py-2 whitespace-nowrap rounded-t
383
+ border-b-2 transition-colors
384
+ ${active === tab.id
385
+ ? 'border-blue-500 bg-slate-800 text-slate-100'
386
+ : 'border-transparent text-slate-400'
387
+ }
388
+ `}
389
+ >
390
+ {tab.icon && <icon className="inline mr-2" />}
391
+ {tab.label}
392
+ </button>
393
+ ))}
394
+ <button className="px-3 py-2 text-slate-400 hover:text-slate-200">
395
+ +
396
+ </button>
397
+ </div>
398
+ ```
399
+
400
+ ### Sidebar (Desktop Only)
401
+
402
+ ```tsx
403
+ <aside className="
404
+ hidden md:flex
405
+ w-64 flex-col
406
+ bg-slate-950 border-r border-slate-800
407
+ overflow-y-auto
408
+ ">
409
+ {/* Project list, file tree, etc. */}
410
+ </aside>
411
+ ```
412
+
413
+ ### Mobile Drawer (Mobile Only)
414
+
415
+ **[V2 LESSON] Do NOT use `hidden md:flex` toggle. Use overlay drawer instead.**
416
+
417
+ ```tsx
418
+ <div className={`
419
+ fixed inset-0 z-50
420
+ ${isOpen ? 'opacity-100' : 'opacity-0 pointer-events-none'}
421
+ transition-opacity duration-200
422
+ `}>
423
+ {/* Backdrop */}
424
+ <div
425
+ className="absolute inset-0 bg-black/50"
426
+ onClick={onClose}
427
+ />
428
+
429
+ {/* Drawer */}
430
+ <div className={`
431
+ fixed left-0 top-0 bottom-0 w-64
432
+ bg-slate-950 border-r border-slate-800
433
+ z-50 overflow-y-auto
434
+ ${isOpen ? 'translate-x-0' : '-translate-x-full'}
435
+ transition-transform duration-300
436
+ `}>
437
+ {/* Content */}
438
+ </div>
439
+ </div>
440
+ ```
441
+
442
+ ### Responsive Breakpoints
443
+
444
+ ```css
445
+ /* Tailwind v4 breakpoints */
446
+ sm: 640px /* Large phone (landscape) */
447
+ md: 768px /* Tablet */
448
+ lg: 1024px /* Laptop */
449
+ xl: 1280px /* Desktop */
450
+ 2xl: 1536px /* Wide desktop */
451
+ ```
452
+
453
+ **PPM Rules:**
454
+ - `md` = desktop UI (sidebar visible, top tabs)
455
+ - `sm` = mobile optimized (drawer sidebar, bottom tabs)
456
+ - Test on: iPhone SE (375px), iPhone 12 Pro (390px), iPad (768px)
457
+
458
+ ---
459
+
460
+ ## 6. Dark Mode Implementation (Tailwind + shadcn/ui)
461
+
462
+ ### tailwind.config.ts
463
+
464
+ ```typescript
465
+ import type { Config } from 'tailwindcss'
466
+
467
+ export default {
468
+ content: [
469
+ './index.html',
470
+ './src/**/*.{js,ts,jsx,tsx}',
471
+ ],
472
+ darkMode: 'class', // Enable dark mode
473
+ theme: {
474
+ extend: {
475
+ colors: {
476
+ slate: {
477
+ 50: '#f8fafc',
478
+ 100: '#f1f5f9',
479
+ 200: '#e2e8f0',
480
+ 300: '#cbd5e1',
481
+ 400: '#94a3b8',
482
+ 500: '#64748b',
483
+ 600: '#475569',
484
+ 700: '#334155',
485
+ 800: '#1e293b',
486
+ 850: '#1a1f2e',
487
+ 900: '#0f172a',
488
+ 950: '#0f1419', // PPM bg
489
+ },
490
+ },
491
+ fontFamily: {
492
+ sans: [
493
+ 'Geist Sans',
494
+ '-apple-system',
495
+ 'BlinkMacSystemFont',
496
+ 'Segoe UI',
497
+ 'Helvetica Neue',
498
+ 'sans-serif',
499
+ ],
500
+ mono: [
501
+ 'Geist Mono',
502
+ 'Monaco',
503
+ 'Courier New',
504
+ 'monospace',
505
+ ],
506
+ },
507
+ fontSize: {
508
+ xs: ['12px', { lineHeight: '1.4' }],
509
+ sm: ['14px', { lineHeight: '1.5' }],
510
+ base: ['16px', { lineHeight: '1.6' }],
511
+ lg: ['18px', { lineHeight: '1.6' }],
512
+ xl: ['20px', { lineHeight: '1.4' }],
513
+ '2xl': ['24px', { lineHeight: '1.4' }],
514
+ '3xl': ['28px', { lineHeight: '1.3' }],
515
+ },
516
+ spacing: {
517
+ '44': '44px', // Touch target
518
+ '48': '48px', // Android standard
519
+ },
520
+ borderRadius: {
521
+ sm: '6px',
522
+ md: '8px',
523
+ lg: '12px',
524
+ },
525
+ boxShadow: {
526
+ sm: '0 1px 2px rgba(0, 0, 0, 0.5)',
527
+ md: '0 4px 6px rgba(0, 0, 0, 0.5)',
528
+ lg: '0 10px 15px rgba(0, 0, 0, 0.5)',
529
+ xl: '0 20px 25px rgba(0, 0, 0, 0.5)',
530
+ },
531
+ },
532
+ },
533
+ plugins: [],
534
+ } satisfies Config
535
+ ```
536
+
537
+ ### HTML Root Setup
538
+
539
+ ```html
540
+ <html class="dark">
541
+ <head>
542
+ <style>
543
+ :root {
544
+ --background: 0 0% 5.8%;
545
+ --foreground: 0 0% 89%;
546
+ --primary: 217 92% 57%;
547
+ /* ... more CSS vars ... */
548
+ }
549
+ </style>
550
+ </head>
551
+ <body className="bg-slate-950 text-slate-100">
552
+ <div id="root"></div>
553
+ </body>
554
+ </html>
555
+ ```
556
+
557
+ ### React Setup (Auto Dark)
558
+
559
+ ```tsx
560
+ // App.tsx
561
+ export function App() {
562
+ useEffect(() => {
563
+ // Force dark mode on mount
564
+ document.documentElement.classList.add('dark')
565
+ }, [])
566
+
567
+ return (
568
+ <div className="min-h-screen bg-slate-950 text-slate-100">
569
+ {/* Your app */}
570
+ </div>
571
+ )
572
+ }
573
+ ```
574
+
575
+ ---
576
+
577
+ ## 7. Color Contrast Matrix (WCAG Compliance)
578
+
579
+ | Foreground | Background | Ratio | Level | Pass |
580
+ |----------|-----------|------|-------|------|
581
+ | Text Primary (#e5e7eb) | Background (#0f1419) | 13.5:1 | AAA | ✅ |
582
+ | Text Secondary (#9ca3af) | Background (#0f1419) | 6.2:1 | AA | ✅ |
583
+ | Text Subtle (#6b7280) | Background (#0f1419) | 4.5:1 | AA | ✅ |
584
+ | Primary Blue (#3b82f6) | Background (#0f1419) | 8.1:1 | AAA | ✅ |
585
+ | Success Green (#10b981) | Background (#0f1419) | 7.2:1 | AAA | ✅ |
586
+ | Error Red (#ef4444) | Background (#0f1419) | 7.8:1 | AAA | ✅ |
587
+
588
+ **All colors meet WCAG AA (4.5:1 minimum). Most exceed AAA (7:1).**
589
+
590
+ ---
591
+
592
+ ## 8. Component Library Integration (shadcn/ui)
593
+
594
+ ### Recommended Components
595
+
596
+ ```bash
597
+ npx shadcn-ui@latest add button
598
+ npx shadcn-ui@latest add input
599
+ npx shadcn-ui@latest add tabs
600
+ npx shadcn-ui@latest add dialog
601
+ npx shadcn-ui@latest add dropdown-menu
602
+ npx shadcn-ui@latest add select
603
+ npx shadcn-ui@latest add textarea
604
+ npx shadcn-ui@latest add scroll-area
605
+ npx shadcn-ui@latest add badge
606
+ npx shadcn-ui@latest add tooltip
607
+ npx shadcn-ui@latest add context-menu
608
+ npx shadcn-ui@latest add alert
609
+ ```
610
+
611
+ ### Dark Mode Customization Example
612
+
613
+ For each component, customize in `lib/components/ui/button.tsx`:
614
+
615
+ ```tsx
616
+ import * as React from "react"
617
+ import { Slot } from "@radix-ui/react-slot"
618
+ import { cva, type VariantProps } from "class-variance-authority"
619
+ import { cn } from "@/lib/utils"
620
+
621
+ const buttonVariants = cva(
622
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-slate-950 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
623
+ {
624
+ variants: {
625
+ variant: {
626
+ default:
627
+ "bg-blue-600 text-white hover:bg-blue-700",
628
+ destructive:
629
+ "bg-red-600 text-white hover:bg-red-700",
630
+ outline:
631
+ "border border-slate-700 bg-slate-950 hover:bg-slate-900 text-slate-300",
632
+ secondary:
633
+ "bg-slate-800 text-slate-100 hover:bg-slate-700",
634
+ ghost:
635
+ "hover:bg-slate-800 hover:text-slate-100",
636
+ link:
637
+ "text-blue-500 underline-offset-4 hover:underline",
638
+ },
639
+ size: {
640
+ default: "h-10 px-4 py-2",
641
+ sm: "h-9 rounded-md px-3",
642
+ lg: "h-11 rounded-md px-8", // Touch target
643
+ icon: "h-10 w-10",
644
+ },
645
+ },
646
+ defaultVariants: {
647
+ variant: "default",
648
+ size: "default",
649
+ },
650
+ }
651
+ )
652
+
653
+ export interface ButtonProps
654
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
655
+ VariantProps<typeof buttonVariants> {
656
+ asChild?: boolean
657
+ }
658
+
659
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
660
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
661
+ const Comp = asChild ? Slot : "button"
662
+ return (
663
+ <Comp
664
+ className={cn(buttonVariants({ variant, size, className }))}
665
+ ref={ref}
666
+ {...props}
667
+ />
668
+ )
669
+ }
670
+ )
671
+ Button.displayName = "Button"
672
+
673
+ export { Button, buttonVariants }
674
+ ```
675
+
676
+ ---
677
+
678
+ ## 9. Reference Design Screenshots & Inspiration
679
+
680
+ ### Modern Web IDEs (Reference)
681
+
682
+ | IDE | Dark Theme Quality | Mobile Support | Notes |
683
+ |-----|-------------------|-----------------|-------|
684
+ | **VS Code** | 9/10 | Limited (web version) | Industry standard, syntax colors proven |
685
+ | **Replit** | 8/10 | Excellent | Community-tested dark mode, mobile-optimized |
686
+ | **CodeSandbox** | 8/10 | Excellent | Specialized for mobile + responsive design |
687
+ | **StackBlitz** | 8/10 | Good | VS Code-like UI, modern stack |
688
+ | **GitHub Codespaces** | 8/10 | Fair | VS Code engine, but mobile UX still in progress |
689
+
690
+ ### Key Visual Patterns to Adopt
691
+
692
+ 1. **VS Code's Dark Theme** (`#1e1e1e` background, `#d4d4d4` text)
693
+ - Already familiar to developers
694
+ - Color palette proven with billions of hours of use
695
+
696
+ 2. **Replit's Bottom Navigation**
697
+ - Icons + labels for clarity (30-40% higher engagement than icons-only)
698
+ - 64px height (touch-friendly)
699
+ - Active state: top border (not background change)
700
+
701
+ 3. **CodeSandbox's Split Panels**
702
+ - Resizable panels for editor + preview + terminal
703
+ - Shadow + border to separate regions
704
+ - `react-resizable-panels` library (already in tech stack)
705
+
706
+ 4. **GitHub's Monospace Font**
707
+ - Geist Mono or Monaspace (modern, variable fonts)
708
+ - Clear distinction between `1`, `l`, `I`, `|`
709
+
710
+ ---
711
+
712
+ ## 10. Implementation Checklist
713
+
714
+ ### Phase 1: Setup (Week 1)
715
+
716
+ - [ ] Install Tailwind CSS 4 with dark mode
717
+ - [ ] Configure tailwind.config.ts (colors, fonts, spacing)
718
+ - [ ] Install shadcn/ui + customize dark mode colors
719
+ - [ ] Create globals.css with CSS variables
720
+ - [ ] Set up font imports (Geist Sans/Mono from Google Fonts or local)
721
+ - [ ] Create color palette variables file (`lib/constants/colors.ts`)
722
+
723
+ ### Phase 2: Component Library (Week 2)
724
+
725
+ - [ ] Add button, input, tabs, dialog, dropdown, select components
726
+ - [ ] Customize each component for dark theme
727
+ - [ ] Create custom components (TabBar, MobileNav, Sidebar, etc.)
728
+ - [ ] Test contrast ratios (use WCAG contrast checker)
729
+
730
+ ### Phase 3: Layout Integration (Week 3)
731
+
732
+ - [ ] Implement mobile-first bottom nav + desktop top tabs
733
+ - [ ] Implement sidebar (desktop) + drawer (mobile)
734
+ - [ ] Responsive breakpoints (sm, md, lg)
735
+ - [ ] Test on real mobile device (iPhone, Android)
736
+
737
+ ### Phase 4: Polish (Week 4)
738
+
739
+ - [ ] Fine-tune spacing + alignment on mobile
740
+ - [ ] Add focus states + accessibility features
741
+ - [ ] Icon sizing + alignment (match 16px grid)
742
+ - [ ] Dark mode testing in different lighting (bright room, dark room)
743
+
744
+ ---
745
+
746
+ ## 11. Figma Design System (Optional)
747
+
748
+ For designers, create a Figma project with:
749
+
750
+ - **Color library:** All hex values + CSS var names
751
+ - **Typography styles:** UI font + code font at all sizes
752
+ - **Component library:** Buttons, inputs, cards, modals (shadcn/ui mirrored)
753
+ - **Layout grid:** 4px baseline grid, 8px spacing
754
+ - **Icon library:** 16px, 24px, 32px sizes (SVG)
755
+ - **Mobile frames:** iPhone SE (375px), iPhone 12 Pro (390px), iPad (768px)
756
+
757
+ **Tool:** [tweakcn.com](https://tweakcn.com) — interactive shadcn/ui theme editor with Tailwind integration.
758
+
759
+ ---
760
+
761
+ ## 12. Testing Plan
762
+
763
+ ### Contrast Testing
764
+ ```bash
765
+ # Use online tool: https://webaim.org/resources/contrastchecker/
766
+ # or axe DevTools browser extension
767
+ # Verify all text >= 4.5:1 ratio on dark background
768
+ ```
769
+
770
+ ### Mobile Testing Devices
771
+ - iPhone SE (375px) — smallest common
772
+ - iPhone 12 Pro (390px) — typical
773
+ - iPad Air (768px) — tablet
774
+ - Pixel 6 (412px) — Android reference
775
+
776
+ ### Accessibility Checklist
777
+ - [ ] Tab navigation works (keyboard only)
778
+ - [ ] Focus ring visible on all interactive elements
779
+ - [ ] Icon + label for bottom nav (not icons-only)
780
+ - [ ] Touch targets >= 44px × 44px
781
+ - [ ] Color not the only indicator (add text/icons)
782
+
783
+ ### Long Session Testing
784
+ - [ ] Dark mode doesn't cause eye strain (test 30+ mins)
785
+ - [ ] Terminal text readable at 12px on mobile
786
+ - [ ] Code editor text readable at 13px on mobile
787
+ - [ ] No glare on OLED screens (black bg = low brightness)
788
+
789
+ ---
790
+
791
+ ## 13. Design System Tokens (CSS-in-TS)
792
+
793
+ Save in `src/lib/constants/colors.ts`:
794
+
795
+ ```typescript
796
+ export const colors = {
797
+ // Backgrounds
798
+ bg: {
799
+ primary: '#0f1419',
800
+ surface: '#1a1f2e',
801
+ elevated: '#252d3d',
802
+ hover: '#1e293b',
803
+ },
804
+ // Text
805
+ text: {
806
+ primary: '#e5e7eb',
807
+ secondary: '#9ca3af',
808
+ subtle: '#6b7280',
809
+ muted: '#6b7280',
810
+ },
811
+ // Accents
812
+ accent: {
813
+ blue: '#3b82f6',
814
+ green: '#10b981',
815
+ red: '#ef4444',
816
+ orange: '#f59e0b',
817
+ cyan: '#06b6d4',
818
+ },
819
+ // Borders
820
+ border: '#404854',
821
+ // Code syntax
822
+ code: {
823
+ keyword: '#c9d1d9',
824
+ string: '#a5d6ff',
825
+ comment: '#8b949e',
826
+ number: '#79c0ff',
827
+ function: '#d2a8ff',
828
+ },
829
+ } as const
830
+
831
+ export const spacing = {
832
+ xs: '4px',
833
+ sm: '8px',
834
+ md: '12px',
835
+ lg: '16px',
836
+ xl: '24px',
837
+ '2xl': '32px',
838
+ touchTarget: '44px',
839
+ } as const
840
+
841
+ export const typography = {
842
+ fontFamily: {
843
+ sans: '"Geist Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
844
+ mono: '"Geist Mono", "Monaco", monospace',
845
+ },
846
+ fontSize: {
847
+ xs: '12px',
848
+ sm: '14px',
849
+ base: '16px',
850
+ lg: '18px',
851
+ xl: '20px',
852
+ '2xl': '24px',
853
+ '3xl': '28px',
854
+ },
855
+ fontWeight: {
856
+ normal: 400,
857
+ medium: 500,
858
+ semibold: 600,
859
+ bold: 700,
860
+ },
861
+ } as const
862
+ ```
863
+
864
+ ---
865
+
866
+ ## 14. Future Enhancements
867
+
868
+ ### Light Mode (Phase 2+)
869
+ If adding light mode, invert carefully:
870
+ - Background: `#ffffff`
871
+ - Text: `#1a1f2e`
872
+ - Accents: Keep same (blue, green, red)
873
+ - Use Tailwind's `light:` variant
874
+
875
+ ### Theme Customization (Phase 3+)
876
+ - User preference via settings tab
877
+ - Store in Zustand + localStorage
878
+ - Multiple dark variants (pure black, solarized, dracula, nord)
879
+
880
+ ### Accessibility Options (Phase 4+)
881
+ - High contrast mode
882
+ - Dyslexia-friendly font option
883
+ - Reduced motion (prefers-reduced-motion)
884
+
885
+ ---
886
+
887
+ ## Summary
888
+
889
+ | Aspect | Recommendation | Rationale |
890
+ |--------|-----------------|-----------|
891
+ | **Color Scheme** | Slate Dark (#0f1419) | VS Code-inspired, OLED-friendly, proven |
892
+ | **UI Font** | Geist Sans | Modern, geometric, excellent on mobile |
893
+ | **Code Font** | Geist Mono | Matches UI, designed for code, ligature support |
894
+ | **Spacing** | 4px grid (Tailwind default) | Flexible, mobile-first |
895
+ | **Touch Targets** | 44px × 44px minimum | iOS/Android standards, comfortable thumb reach |
896
+ | **Dark Mode** | Always-on (no light toggle Phase 1) | Reduces scope, matches target audience (devs code at night) |
897
+ | **Component Library** | shadcn/ui + custom dark overrides | Accessible, customizable, Radix UI foundation |
898
+ | **Contrast** | All text >= 4.5:1 (WCAG AA) | Readable for all users, compliant |
899
+
900
+ ---
901
+
902
+ ## References
903
+
904
+ ### Web Search Results (2025-2026)
905
+ 1. [12 Defining Web Development Trends for 2026 | Figma](https://www.figma.com/resource-library/web-development-trends/)
906
+ 2. [2025 UI design trends that are already shaping the web | Lummi](https://www.lummi.ai/blog/ui-design-trends-2025)
907
+ 3. [Inclusive Dark Mode | Smashing Magazine](https://www.smashingmagazine.com/2025/04/inclusive-dark-mode-designing-accessible-dark-themes/)
908
+ 4. [Dark Mode Color Palettes: Complete Guide for 2025 | MyPaletteTool](https://mypalettetool.com/blog/dark-mode-color-palettes)
909
+ 5. [Theming - shadcn/ui](https://ui.shadcn.com/docs/theming)
910
+ 6. [Dark Mode - shadcn/ui](https://ui.shadcn.com/docs/dark-mode)
911
+ 7. [Best Free Monospace Fonts for Coding & Design 2026 | CSSAuthor](https://cssauthor.com/best-free-monospace-fonts-for-coding/)
912
+ 8. [GitHub - system-fonts/modern-font-stacks](https://github.com/system-fonts/modern-font-stacks)
913
+ 9. [The Golden Rules Of Bottom Navigation Design | Smashing Magazine](https://www.smashingmagazine.com/2016/11/the-golden-rules-of-mobile-navigation-design/)
914
+ 10. [Bottom Navigation for Mobile: UX Design | AppMySite](https://blog.appmysite.com/bottom-navigation-bar-in-mobile-apps-heres-all-you-need-to-know/)
915
+ 11. [Dark mode - Tailwind CSS](https://tailwindcss.com/docs/dark-mode)
916
+ 12. [VS Code Theme Color API](https://code.visualstudio.com/api/references/theme-color)
917
+ 13. [Replit Themes Documentation](https://docs.replit.com/replit-workspace/replit-themes)
918
+
919
+ ### Tools & Generators
920
+ - [tweakcn.com](https://tweakcn.com) — shadcn/ui theme editor
921
+ - [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
922
+ - [axe DevTools](https://www.deque.com/axe/devtools/) — accessibility testing
923
+
924
+ ### PPM Project References
925
+ - [Tech Stack Research](brainstorm-260314-1938-final-techstack.md)
926
+ - [Phase 3: Frontend Shell](../260314-2009-ppm-implementation/phase-03-frontend-shell.md)
927
+ - [Tailwind CSS Docs](https://tailwindcss.com)
928
+ - [shadcn/ui Components](https://ui.shadcn.com)
929
+
930
+ ---
931
+
932
+ ## Unresolved Questions
933
+
934
+ 1. **Icon Library:** Should we use Feather Icons, Heroicons, Lucide, or custom SVG? (Recommend: Lucide — 4KB, dark-friendly defaults)
935
+ 2. **Font License:** Should we self-host Geist fonts or use Google Fonts CDN? (Google Fonts = simpler, no extra build step)
936
+ 3. **Syntax Highlighting:** Which CodeMirror 6 theme should we start with? (Recommend: Extend `dracula` theme or fork VS Code dark colors)
937
+ 4. **Notification Toasts:** Where should alerts appear on mobile? (Recommend: Bottom-left on desktop, full-width banner on mobile to avoid hiding bottom nav)
938
+ 5. **Animations:** Should tab switches animate or snap instantly for mobile performance? (Recommend: Snap on mobile, animate on desktop)
939
+
940
+ ---
941
+
942
+ **Report Complete.** Ready for design system implementation phase. Recommend starting with Phase 1 (Tailwind + shadcn/ui setup) before component development begins.