M
Makefile
+1,
-1
1@@ -39,7 +39,7 @@ test-site:
2 --label testdata \
3 --desc "pgit testing site" \
4 --theme "dracula" \
5- --revs main
6+ --revs "main,branch-c"
7 .PHONY: test-site
8
9 static: build clean
+0,
-639
1@@ -1,639 +0,0 @@
2-# Git Static Site Design Enhancement
3-
4-## Overview
5-
6-This document outlines the visual design enhancements for the pgit static site generator. The goal is to create a bold, developer-focused aesthetic with improved typography, visual hierarchy, and CSS-only interactions.
7-
8-## Typography System
9-
10-### Font Stack (Option A: Tech Bold)
11-
12-| Element | Font | Weights | Usage |
13-|---------|------|---------|-------|
14-| Headers/Display | Space Grotesk | 500, 600, 700, 800 | Repo names, section titles, navigation |
15-| Body | Inter | 400, 500, 600, 700 | Paragraphs, labels, metadata |
16-| Code/Mono | JetBrains Mono | 400, 500, 600, 700 | Commit hashes, code blocks, file paths |
17-
18-### Google Fonts URL
19-
20-```html
21-<link rel="preconnect" href="https://fonts.googleapis.com">
22-<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
23-<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700;800&display=swap" rel="stylesheet">
24-```
25-
26-### Type Scale
27-
28-| Element | Size | Weight | Line-Height | Letter-Spacing | Notes |
29-|---------|------|--------|-------------|----------------|-------|
30-| H1 (Repo Name) | 2rem | 800 | 1.2 | -0.02em | Space Grotesk |
31-| H2 (Section) | 1.25rem | 700 | 1.3 | 0.05em | Space Grotesk, uppercase |
32-| H3 (Subsection) | 1rem | 600 | 1.4 | 0 | Space Grotesk |
33-| Body | 1rem | 400 | 1.6 | 0 | Inter |
34-| Body Bold | 1rem | 600 | 1.6 | 0 | Inter |
35-| Small | 0.875rem | 500 | 1.4 | 0.01em | Inter, metadata |
36-| Code | 0.9rem | 500 | 1.5 | 0.02em | JetBrains Mono |
37-| Code Bold | 0.9rem | 700 | 1.5 | 0.02em | JetBrains Mono, hashes |
38-
39-## Color Scheme
40-
41-**Note:** Colors are defined at build time using the Chroma library. Design works with any theme.
42-
43-### Existing Variables (Preserve)
44-- `--bg-color`: Background
45-- `--text-color`: Primary text
46-- `--link-color`: Links and accents
47-- `--hover`: Hover states
48-- `--visited`: Visited links
49-- `--border`: Borders and dividers
50-- `--grey-light`: Muted text
51-
52-### New Variables to Add
53-```css
54---font-display: 'Space Grotesk', system-ui, sans-serif;
55---font-body: 'Inter', system-ui, sans-serif;
56---font-mono: 'JetBrains Mono', 'Fira Code', monospace;
57-
58---transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
59---transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);
60-
61---shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);
62---shadow-md: 0 4px 12px rgba(0, 0, 0, 0.15);
63-```
64-
65-## Layout & Spacing
66-
67-### Spacing Scale
68-```css
69---space-1: 0.25rem; /* 4px */
70---space-2: 0.5rem; /* 8px */
71---space-3: 0.75rem; /* 12px */
72---space-4: 1rem; /* 16px */
73---space-5: 1.5rem; /* 24px */
74---space-6: 2rem; /* 32px */
75---space-8: 2.5rem; /* 40px */
76-```
77-
78-### Section Spacing
79-- **Header**: 2.5rem padding, border-bottom separator
80-- **Main content**: 2rem gap between major sections
81-- **Footer**: 2rem top padding, smaller text, top border
82-
83-## Components
84-
85-### Navigation (Desktop)
86-
87-**Layout:** Horizontal pill buttons
88-
89-**Structure:**
90-```
91-[summary] [refs] [main] [code] [commits]
92-```
93-
94-**Styles:**
95-```css
96-nav {
97- display: flex;
98- gap: var(--space-2);
99- flex-wrap: wrap;
100-}
101-
102-nav a {
103- font-family: var(--font-display);
104- font-weight: 600;
105- font-size: 0.9rem;
106- padding: var(--space-2) var(--space-4);
107- border: 1px solid var(--border);
108- border-radius: 4px;
109- text-decoration: none;
110- transition: all var(--transition-base);
111-}
112-
113-nav a:hover {
114- background: var(--link-color);
115- color: var(--bg-color);
116- transform: translateY(-2px);
117- box-shadow: 0 4px 12px rgba(139, 233, 253, 0.15);
118- text-decoration: none;
119-}
120-
121-nav a:active {
122- transform: translateY(0);
123-}
124-
125-nav .current {
126- background: var(--link-color);
127- color: var(--bg-color);
128- font-weight: 700;
129-}
130-```
131-
132-### Navigation (Mobile)
133-
134-**Layout:** 2-column grid, responsive stacking
135-
136-**Structure:**
137-```
138-┌─────────────┬─────────────┐
139-│ summary │ refs │
140-├─────────────┼─────────────┤
141-│ main │ code │
142-├─────────────┴─────────────┤
143-│ commits │
144-└───────────────────────────┘
145-```
146-
147-**Styles:**
148-```css
149-@media (max-width: 600px) {
150- nav {
151- display: grid;
152- grid-template-columns: 1fr 1fr;
153- gap: var(--space-2);
154- }
155-
156- nav a {
157- text-align: center;
158- min-height: 44px;
159- display: flex;
160- align-items: center;
161- justify-content: center;
162- }
163-
164- /* Full width for commits */
165- nav a[href*="commits"] {
166- grid-column: 1 / -1;
167- }
168-}
169-```
170-
171-### Commit List
172-
173-**Structure:**
174-```
175-┌─────────────────────────────────────────────────────────────┐
176-│ ● a7f3d9e Add user authentication feature (main) │
177-│ Author Name · 2 hours ago │
178-│ Full commit message with proper typography... │
179-└─────────────────────────────────────────────────────────────┘
180-```
181-
182-**Styles:**
183-```css
184-.commit-row {
185- border-left: 2px solid transparent;
186- padding-left: var(--space-3);
187- margin-bottom: var(--space-4);
188- transition: border-color var(--transition-fast),
189- background var(--transition-fast);
190-}
191-
192-.commit-row:hover {
193- border-left-color: var(--link-color);
194- background: rgba(139, 233, 253, 0.03);
195-}
196-
197-.commit-hash {
198- font-family: var(--font-mono);
199- font-weight: 600;
200- font-size: 0.9rem;
201- color: var(--link-color);
202-}
203-
204-.commit-message {
205- font-family: var(--font-body);
206- font-size: 1.05rem;
207- font-weight: 500;
208- line-height: 1.5;
209- margin: var(--space-2) 0;
210-}
211-
212-.commit-meta {
213- font-size: 0.875rem;
214- color: var(--grey-light);
215- font-weight: 500;
216-}
217-
218-.commit-meta span + span::before {
219- content: "·";
220- margin: 0 var(--space-2);
221- opacity: 0.6;
222-}
223-
224-.commit-refs {
225- display: inline-flex;
226- gap: var(--space-1);
227-}
228-
229-.commit-ref {
230- font-size: 0.8rem;
231- padding: 0.1rem var(--space-2);
232- border: 1px solid var(--link-color);
233- border-radius: 3px;
234- color: var(--link-color);
235- font-weight: 600;
236-}
237-```
238-
239-### Commit Graph (Simple)
240-
241-**Visual:** Vertical line with commit dots
242-
243-```
244-│ ●─── 3a7f2e9 Latest commit message
245-│
246-│ ●─── 8c4d1a2 Previous commit
247-│
248-│ ●─── 9e1b3c4 Older commit
249-```
250-
251-**Implementation:** CSS pseudo-elements
252-```css
253-.commit-graph {
254- position: relative;
255- padding-left: 1.5rem;
256-}
257-
258-.commit-graph::before {
259- content: "";
260- position: absolute;
261- left: 0;
262- top: 0;
263- bottom: 0;
264- width: 2px;
265- background: var(--border);
266-}
267-
268-.commit-dot {
269- position: absolute;
270- left: -5px;
271- width: 12px;
272- height: 12px;
273- border-radius: 50%;
274- background: var(--link-color);
275- border: 2px solid var(--bg-color);
276-}
277-
278-/* On mobile: hide graph, keep simple list */
279-@media (max-width: 600px) {
280- .commit-graph {
281- padding-left: 0;
282- }
283- .commit-graph::before,
284- .commit-dot {
285- display: none;
286- }
287-}
288-```
289-
290-### Tree View (Desktop - Compact)
291-
292-**Structure:**
293-```
294-┌─────────────────────────────────────────────────────────────┐
295-│ 📁 src/ 3 commits ago ─── │
296-│ 📄 main.go 2 hours ago 245 L │
297-│ 📄 utils.go 1 day ago 128 L │
298-│ 📁 internal/ 5 days ago ─── │
299-└─────────────────────────────────────────────────────────────┘
300-```
301-
302-**Styles:**
303-```css
304-.tree-row {
305- display: flex;
306- align-items: center;
307- justify-content: space-between;
308- padding: var(--space-2) var(--space-3);
309- border-bottom: 1px solid rgba(98, 114, 164, 0.2);
310- transition: background var(--transition-fast);
311-}
312-
313-.tree-row:hover {
314- background: rgba(255, 255, 255, 0.03);
315-}
316-
317-.tree-row:last-child {
318- border-bottom: none;
319-}
320-
321-.tree-icon {
322- width: 16px;
323- height: 16px;
324- margin-right: var(--space-2);
325- opacity: 0.8;
326- transition: opacity var(--transition-fast);
327-}
328-
329-.tree-row:hover .tree-icon {
330- opacity: 1;
331-}
332-
333-.tree-name {
334- font-family: var(--font-mono);
335- font-weight: 500;
336- flex: 1;
337-}
338-
339-.tree-commit {
340- font-size: 0.875rem;
341- color: var(--grey-light);
342- flex: 1;
343- text-align: right;
344- margin-right: var(--space-4);
345-}
346-
347-.tree-size {
348- font-family: var(--font-mono);
349- font-size: 0.8rem;
350- color: var(--grey-light);
351- min-width: 60px;
352- text-align: right;
353-}
354-```
355-
356-### Tree View (Mobile - Touch Optimized)
357-
358-**Structure:**
359-```
360-┌────────────────────────────┐
361-│ 📄 main.go │
362-│ Updated 2 hours ago │
363-├────────────────────────────┤
364-│ 📄 utils.go │
365-│ Updated 1 day ago │
366-└────────────────────────────┘
367-```
368-
369-**Mobile Styles:**
370-```css
371-@media (max-width: 768px) {
372- .tree-row {
373- flex-direction: column;
374- align-items: flex-start;
375- padding: var(--space-3);
376- min-height: 60px; /* Touch target */
377- }
378-
379- .tree-name {
380- font-size: 1.05rem;
381- font-weight: 600;
382- margin-bottom: var(--space-1);
383- }
384-
385- .tree-commit {
386- display: none; /* Hidden on mobile */
387- }
388-
389- .tree-size {
390- display: none; /* Hidden on mobile */
391- }
392-
393- .tree-meta-mobile {
394- display: block;
395- font-size: 0.875rem;
396- color: var(--grey-light);
397- }
398-}
399-```
400-
401-### Header Component
402-
403-**Structure:**
404-```
405-┌─────────────────────────────────────────────────────────────┐
406-│ │
407-│ REPOSITORY NAME [nav pills...] │
408-│ Repository description text │
409-│ git clone https://... │
410-│ │
411-└─────────────────────────────────────────────────────────────┘
412-```
413-
414-**Styles:**
415-```css
416-.site-header {
417- padding: var(--space-6) 0;
418- border-bottom: 1px solid var(--border);
419- margin-bottom: var(--space-6);
420-}
421-
422-.repo-name {
423- font-family: var(--font-display);
424- font-size: 2rem;
425- font-weight: 800;
426- letter-spacing: -0.02em;
427- margin: 0 0 var(--space-2) 0;
428-}
429-
430-.repo-name a {
431- color: var(--text-color);
432- text-decoration: none;
433-}
434-
435-.repo-desc {
436- font-family: var(--font-body);
437- font-size: 1rem;
438- color: var(--grey-light);
439- margin: var(--space-2) 0;
440-}
441-
442-.clone-cmd {
443- font-family: var(--font-mono);
444- font-size: 0.875rem;
445- background: rgba(98, 114, 164, 0.15);
446- padding: var(--space-2) var(--space-3);
447- border-radius: 4px;
448- margin-top: var(--space-3);
449-}
450-
451-/* Mobile header */
452-@media (max-width: 768px) {
453- .site-header {
454- padding: var(--space-4) 0;
455- }
456-
457- .repo-name {
458- font-size: 1.5rem;
459- }
460-
461- .header-content {
462- flex-direction: column;
463- gap: var(--space-4);
464- }
465-}
466-```
467-
468-### Breadcrumbs
469-
470-**Structure:**
471-```
472-src / components / Button.tsx
473-```
474-
475-**Styles:**
476-```css
477-.breadcrumbs {
478- font-family: var(--font-mono);
479- font-size: 0.9rem;
480- margin-bottom: var(--space-4);
481-}
482-
483-.breadcrumbs a {
484- color: var(--link-color);
485- text-decoration: none;
486-}
487-
488-.breadcrumbs a:hover {
489- text-decoration: underline;
490-}
491-
492-.breadcrumbs .current {
493- font-weight: 600;
494- color: var(--text-color);
495-}
496-
497-.breadcrumbs .separator {
498- margin: 0 var(--space-2);
499- opacity: 0.5;
500-}
501-```
502-
503-## Animations & Transitions
504-
505-### Global Transitions
506-```css
507-* {
508- transition: background-color var(--transition-fast),
509- border-color var(--transition-fast);
510-}
511-
512-a {
513- transition: color var(--transition-fast),
514- background var(--transition-fast),
515- transform var(--transition-base),
516- box-shadow var(--transition-base);
517-}
518-```
519-
520-### Hover Effects
521-
522-**Links:**
523-```css
524-a:hover {
525- text-decoration: underline;
526- text-decoration-thickness: 2px;
527- text-underline-offset: 2px;
528-}
529-```
530-
531-**Buttons/Nav:**
532-```css
533-.btn:hover,
534-nav a:hover {
535- transform: translateY(-2px);
536- box-shadow: 0 4px 12px rgba(139, 233, 253, 0.15);
537-}
538-
539-.btn:active,
540-nav a:active {
541- transform: translateY(0);
542- box-shadow: none;
543-}
544-```
545-
546-**Commit Rows:**
547-```css
548-.commit-row {
549- border-left: 2px solid transparent;
550- transition: border-color var(--transition-fast),
551- background var(--transition-fast),
552- padding-left var(--transition-fast);
553-}
554-
555-.commit-row:hover {
556- border-left-color: var(--link-color);
557- background: rgba(139, 233, 253, 0.03);
558- padding-left: calc(var(--space-3) + 2px);
559-}
560-```
561-
562-### Focus States (Accessibility)
563-```css
564-:focus-visible {
565- outline: 2px solid var(--link-color);
566- outline-offset: 2px;
567-}
568-
569-:focus:not(:focus-visible) {
570- outline: none;
571-}
572-```
573-
574-## Responsive Breakpoints
575-
576-| Breakpoint | Width | Target |
577-|------------|-------|--------|
578-| sm | < 600px | Mobile |
579-| md | 600-900px | Tablet |
580-| lg | > 900px | Desktop |
581-
582-## Template Changes Required
583-
584-### base.layout.tmpl
585-- Add Google Fonts link in `<head>`
586-- Add `font-display` class to body or root
587-
588-### header.partial.tmpl
589-- Add `site-header` wrapper class
590-- Add `repo-name` class to h1
591-- Update navigation structure (remove pipes, add pill classes)
592-- Add mobile-friendly nav classes
593-
594-### log.page.tmpl
595-- Add `commit-graph` wrapper
596-- Add `commit-row` class to each commit
597-- Add `commit-dot` elements
598-- Add `commit-hash`, `commit-message`, `commit-meta` classes
599-
600-### tree.page.tmpl
601-- Add `tree-row` classes
602-- Add mobile-specific meta elements (conditionally hidden)
603-
604-### commit.page.tmpl
605-- Add typography classes to definition list
606-- Enhance diff file headers
607-
608-## Performance Considerations
609-
610-1. **Font Loading**: Use `display=swap` for Google Fonts to prevent FOIT
611-2. **CSS Variables**: All theme colors use CSS variables for instant theme switching
612-3. **No JavaScript**: All interactions are CSS-only for maximum performance
613-4. **Touch Targets**: Minimum 44px on mobile for accessibility
614-5. **Will-change**: Consider adding `will-change: transform` on frequently animated elements
615-
616-## Accessibility
617-
618-1. **Focus indicators**: Visible outline on all interactive elements
619-2. **Color contrast**: Works with existing Chroma themes (assume compliant)
620-3. **Touch targets**: Minimum 44x44px on mobile
621-4. **Reduced motion**: Respect `prefers-reduced-motion` media query
622-
623-```css
624-@media (prefers-reduced-motion: reduce) {
625- *,
626- *::before,
627- *::after {
628- animation-duration: 0.01ms !important;
629- animation-iteration-count: 1 !important;
630- transition-duration: 0.01ms !important;
631- }
632-}
633-```
634-
635-## Future Enhancements (Out of Scope)
636-
637-- Dark/light mode toggle (requires JavaScript or CSS-only checkbox hack)
638-- Search functionality
639-- File preview modals
640-- Copy-to-clipboard buttons
+0,
-1385
1@@ -1,1385 +0,0 @@
2-# Git Static Site Design Enhancement Implementation Plan
3-
4-> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
5-
6-**Goal:** Implement bold typography, visual hierarchy, CSS-only navigation with hover states, simple commit graph, and responsive tree view for the pgit static site generator.
7-
8-**Architecture:** Enhance existing CSS files (vars.css, smol.css, main.css) and minimal template updates to add Google Fonts, new component classes, and responsive design without JavaScript. The build system generates static HTML which uses these enhanced styles.
9-
10-**Tech Stack:** Go templates, CSS3 (variables, flexbox, grid, transitions), Google Fonts (Space Grotesk, Inter, JetBrains Mono)
11-
12----
13-
14-## Testing Strategy
15-
16-Before and after each major change, use Playwright CLI to capture screenshots:
17-
18-```bash
19-# Start test server
20-python3 -m http.server 8888 --directory /home/btburke/projects/pgit/testdata.site &
21-
22-# Take screenshot of page
23-playwright-cli open http://localhost:8888
24-playwright-cli screenshot --filename=screenshot-index.png
25-playwright-cli goto http://localhost:8888/logs/main/index.html
26-playwright-cli screenshot --filename=screenshot-commits.png
27-playwright-cli goto http://localhost:8888/tree/main/index.html
28-playwright-cli screenshot --filename=screenshot-tree.png
29-playwright-cli close
30-```
31-
32-Compare screenshots to verify visual changes.
33-
34----
35-
36-### Task 1: Update vars.css with Font Variables and Design Tokens
37-
38-**Files:**
39-- Modify: `/home/btburke/projects/pgit/static/vars.css` (entire file)
40-
41-**Step 1: Add Google Fonts and CSS variables**
42-
43-The vars.css is copied to each generated site. Add the design tokens here.
44-
45-```css
46-:root {
47- /* Existing theme colors (preserve) */
48- --bg-color: #282a36;
49- --text-color: #f8f8f2;
50- --border: #6272a4;
51- --link-color: #8be9fd;
52- --hover: #ff79c6;
53- --visited: #bd93f9;
54-
55- /* Typography - Fonts */
56- --font-display: 'Space Grotesk', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
57- --font-body: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
58- --font-mono: 'JetBrains Mono', 'Fira Code', 'Consolas', monospace;
59-
60- /* Typography - Scale */
61- --text-xs: 0.75rem;
62- --text-sm: 0.875rem;
63- --text-base: 1rem;
64- --text-lg: 1.125rem;
65- --text-xl: 1.25rem;
66- --text-2xl: 1.5rem;
67- --text-3xl: 2rem;
68-
69- /* Typography - Weights */
70- --font-normal: 400;
71- --font-medium: 500;
72- --font-semibold: 600;
73- --font-bold: 700;
74- --font-extrabold: 800;
75-
76- /* Spacing */
77- --space-1: 0.25rem;
78- --space-2: 0.5rem;
79- --space-3: 0.75rem;
80- --space-4: 1rem;
81- --space-5: 1.5rem;
82- --space-6: 2rem;
83- --space-8: 2.5rem;
84-
85- /* Transitions */
86- --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
87- --transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);
88-
89- /* Shadows */
90- --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);
91- --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.15);
92-
93- /* Layout */
94- --max-width: 900px;
95- --touch-target: 44px;
96-}
97-```
98-
99-**Step 2: Verify file exists and test site regeneration**
100-
101-Run: `make test-site`
102-Expected: Site regenerates without errors
103-
104-**Step 3: Commit**
105-
106-```bash
107-jj commit -m "design: add typography and design tokens to vars.css"
108-```
109-
110----
111-
112-### Task 2: Update smol.css with Typography and Base Styles
113-
114-**Files:**
115-- Modify: `/home/btburke/projects/pgit/static/smol.css` (multiple sections)
116-
117-**Step 1: Update font-family definitions**
118-
119-Replace the html font-family block (lines 61-86):
120-
121-```css
122-html {
123- background-color: var(--bg-color);
124- color: var(--text-color);
125- font-size: 16px;
126- line-height: 1.6;
127- font-family: var(--font-body);
128- -webkit-text-size-adjust: 100%;
129- -moz-tab-size: 4;
130- -o-tab-size: 4;
131- tab-size: 4;
132-}
133-```
134-
135-**Step 2: Update heading styles (lines 155-166)**
136-
137-Replace with:
138-
139-```css
140-h1, h2, h3, h4 {
141- margin: 0;
142- padding: 0;
143- font-family: var(--font-display);
144- font-weight: var(--font-bold);
145- line-height: 1.2;
146-}
147-
148-h1 {
149- font-size: var(--text-3xl);
150- font-weight: var(--font-extrabold);
151- letter-spacing: -0.02em;
152-}
153-
154-h2 {
155- font-size: var(--text-xl);
156- font-weight: var(--font-bold);
157- letter-spacing: 0.05em;
158- text-transform: uppercase;
159-}
160-
161-h3 {
162- font-size: var(--text-lg);
163- font-weight: var(--font-semibold);
164-}
165-
166-h4 {
167- font-size: var(--text-base);
168- font-weight: var(--font-semibold);
169-}
170-```
171-
172-**Step 3: Update code/pre styles (lines 102-134)**
173-
174-Update font-family references:
175-
176-```css
177-code, kbd, samp, pre {
178- font-family: var(--font-mono);
179-}
180-
181-code, kbd, samp {
182- border: 2px solid var(--code);
183- font-size: 0.9rem;
184- font-weight: var(--font-medium);
185-}
186-
187-pre {
188- font-size: 0.85rem;
189- line-height: 1.5;
190-}
191-```
192-
193-**Step 4: Add reduced motion support at end of file**
194-
195-Add to end of smol.css:
196-
197-```css
198-/* Reduced motion support */
199-@media (prefers-reduced-motion: reduce) {
200- *,
201- *::before,
202- *::after {
203- animation-duration: 0.01ms !important;
204- animation-iteration-count: 1 !important;
205- transition-duration: 0.01ms !important;
206- scroll-behavior: auto !important;
207- }
208-}
209-
210-/* Focus visibility for accessibility */
211-:focus-visible {
212- outline: 2px solid var(--link-color);
213- outline-offset: 2px;
214-}
215-
216-:focus:not(:focus-visible) {
217- outline: none;
218-}
219-```
220-
221-**Step 5: Regenerate test site and verify**
222-
223-Run: `make test-site`
224-Expected: No errors, fonts should be referenced (but not loaded yet without Google Fonts link)
225-
226-**Step 6: Commit**
227-
228-```bash
229-jj commit -m "design: update smol.css with new typography system"
230-```
231-
232----
233-
234-### Task 3: Update base.layout.tmpl with Google Fonts
235-
236-**Files:**
237-- Modify: `/home/btburke/projects/pgit/html/base.layout.tmpl`
238-
239-**Step 1: Add Google Fonts link**
240-
241-Insert after `<meta name="keywords"...>` and before `{{template "meta" .}}`:
242-
243-```html
244- <link rel="preconnect" href="https://fonts.googleapis.com">
245- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
246- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700;800&display=swap" rel="stylesheet">
247-```
248-
249-**Step 2: Add body font class**
250-
251-Update body tag:
252-
253-```html
254- <body class="font-body">
255-```
256-
257-Full template should be:
258-
259-```html
260-{{define "base"}}
261-<!doctype html>
262-<html lang="en">
263- <head>
264- <meta charset='utf-8'>
265- <meta name="viewport" content="width=device-width, initial-scale=1" />
266- <title>{{template "title" .}}</title>
267-
268- <meta name="keywords" content="git code forge repo repository" />
269-
270- <link rel="preconnect" href="https://fonts.googleapis.com">
271- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
272- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700;800&display=swap" rel="stylesheet">
273-
274- {{template "meta" .}}
275-
276- <link rel="stylesheet" href="{{.Repo.RootRelative}}vars.css" />
277- <link rel="stylesheet" href="{{.Repo.RootRelative}}smol.css" />
278- <link rel="stylesheet" href="{{.Repo.RootRelative}}main.css" />
279- </head>
280- <body class="font-body">
281- <header class="site-header box">{{template "header" .}}</header>
282- <hr class="my" />
283- <main>{{template "content" .}}</main>
284- <hr class="my" />
285- <footer>{{template "footer" .}}</footer>
286- </body>
287-</html>
288-{{end}}
289-```
290-
291-**Step 3: Regenerate test site**
292-
293-Run: `make test-site`
294-Expected: No template errors
295-
296-**Step 4: Verify fonts load in browser**
297-
298-Open test site in browser, inspect element, verify Space Grotesk/Inter/JetBrains Mono are applied.
299-
300-**Step 5: Commit**
301-
302-```bash
303-jj commit -m "design: add Google Fonts to base layout"
304-```
305-
306----
307-
308-### Task 4: Create Enhanced main.css with Component Styles
309-
310-**Files:**
311-- Modify: `/home/btburke/projects/pgit/static/main.css` (rewrite with new styles)
312-
313-**Step 1: Write complete main.css**
314-
315-```css
316-/* ========================================
317- PGIT DESIGN SYSTEM - COMPONENT STYLES
318- ======================================== */
319-
320-/* ---- Base ---- */
321-body {
322- max-width: var(--max-width);
323- font-family: var(--font-body);
324-}
325-
326-pre {
327- border: 1px solid var(--border);
328- padding: var(--grid-height);
329- background-color: var(--pre) !important;
330- font-family: var(--font-mono);
331- font-size: 0.85rem;
332- line-height: 1.5;
333-}
334-
335-/* ---- Typography Utilities ---- */
336-.font-display {
337- font-family: var(--font-display);
338-}
339-
340-.font-body {
341- font-family: var(--font-body);
342-}
343-
344-.font-mono {
345- font-family: var(--font-mono);
346-}
347-
348-/* ---- Header ---- */
349-.site-header {
350- padding: var(--space-6) 0;
351- border-bottom: 1px solid var(--border);
352- margin-bottom: var(--space-6);
353-}
354-
355-.repo-name {
356- font-family: var(--font-display);
357- font-size: var(--text-3xl);
358- font-weight: var(--font-extrabold);
359- letter-spacing: -0.02em;
360- margin: 0 0 var(--space-2) 0;
361-}
362-
363-.repo-name a {
364- color: var(--text-color);
365- text-decoration: none;
366- transition: color var(--transition-fast);
367-}
368-
369-.repo-name a:hover {
370- color: var(--link-color);
371-}
372-
373-.repo-desc {
374- font-family: var(--font-body);
375- font-size: var(--text-base);
376- color: var(--grey-light);
377- margin: var(--space-2) 0;
378-}
379-
380-.clone-cmd {
381- font-family: var(--font-mono);
382- font-size: var(--text-sm);
383- background: rgba(98, 114, 164, 0.15);
384- padding: var(--space-2) var(--space-3);
385- border-radius: 4px;
386- margin-top: var(--space-3);
387-}
388-
389-/* ---- Navigation (Desktop) ---- */
390-.site-nav {
391- display: flex;
392- gap: var(--space-2);
393- flex-wrap: wrap;
394- margin: var(--space-4) 0;
395-}
396-
397-.site-nav a {
398- font-family: var(--font-display);
399- font-weight: var(--font-semibold);
400- font-size: 0.9rem;
401- padding: var(--space-2) var(--space-4);
402- border: 1px solid var(--border);
403- border-radius: 4px;
404- text-decoration: none;
405- color: var(--link-color);
406- transition: all var(--transition-base);
407- display: inline-flex;
408- align-items: center;
409- justify-content: center;
410- min-height: 36px;
411-}
412-
413-.site-nav a:hover {
414- background: var(--link-color);
415- color: var(--bg-color);
416- transform: translateY(-2px);
417- box-shadow: 0 4px 12px rgba(139, 233, 253, 0.15);
418- text-decoration: none;
419-}
420-
421-.site-nav a:active {
422- transform: translateY(0);
423- box-shadow: none;
424-}
425-
426-.site-nav .nav-current {
427- background: var(--link-color);
428- color: var(--bg-color);
429- font-weight: var(--font-bold);
430-}
431-
432-/* ---- Navigation (Mobile) ---- */
433-@media (max-width: 600px) {
434- .site-nav {
435- display: grid;
436- grid-template-columns: 1fr 1fr;
437- }
438-
439- .site-nav a {
440- text-align: center;
441- min-height: var(--touch-target);
442- }
443-
444- /* Full width for commits link */
445- .site-nav a[href*="commits"],
446- .site-nav a[href*="logs"] {
447- grid-column: 1 / -1;
448- }
449-}
450-
451-/* ---- Commit List ---- */
452-.commit-list {
453- display: flex;
454- flex-direction: column;
455- gap: var(--space-4);
456-}
457-
458-.commit-row {
459- position: relative;
460- border-left: 2px solid transparent;
461- padding-left: var(--space-4);
462- transition: border-color var(--transition-fast),
463- background var(--transition-fast);
464-}
465-
466-.commit-row:hover {
467- border-left-color: var(--link-color);
468- background: rgba(139, 233, 253, 0.03);
469-}
470-
471-/* ---- Commit Graph ---- */
472-.commit-graph {
473- position: relative;
474- padding-left: 1.75rem;
475-}
476-
477-.commit-graph::before {
478- content: "";
479- position: absolute;
480- left: 0;
481- top: 0.5rem;
482- bottom: 0.5rem;
483- width: 2px;
484- background: var(--border);
485-}
486-
487-.commit-dot {
488- position: absolute;
489- left: -5px;
490- top: 0.25rem;
491- width: 12px;
492- height: 12px;
493- border-radius: 50%;
494- background: var(--link-color);
495- border: 2px solid var(--bg-color);
496- box-shadow: 0 0 0 1px var(--border);
497-}
498-
499-.commit-row:hover .commit-dot {
500- background: var(--hover);
501- transform: scale(1.1);
502- transition: transform var(--transition-fast);
503-}
504-
505-/* Hide graph on mobile */
506-@media (max-width: 600px) {
507- .commit-graph {
508- padding-left: 0;
509- }
510-
511- .commit-graph::before,
512- .commit-dot {
513- display: none;
514- }
515-}
516-
517-/* ---- Commit Content ---- */
518-.commit-header {
519- display: flex;
520- justify-content: space-between;
521- align-items: center;
522- gap: var(--space-3);
523- flex-wrap: wrap;
524-}
525-
526-.commit-hash {
527- font-family: var(--font-mono);
528- font-weight: var(--font-semibold);
529- font-size: 0.9rem;
530- color: var(--link-color);
531- letter-spacing: 0.02em;
532-}
533-
534-.commit-hash:hover {
535- color: var(--hover);
536-}
537-
538-.commit-message {
539- font-family: var(--font-body);
540- font-size: 1.05rem;
541- font-weight: var(--font-medium);
542- line-height: 1.5;
543- margin: var(--space-2) 0;
544- color: var(--text-color);
545-}
546-
547-.commit-meta {
548- font-size: var(--text-sm);
549- color: var(--grey-light);
550- font-weight: var(--font-medium);
551- display: flex;
552- align-items: center;
553- gap: var(--space-2);
554-}
555-
556-.commit-meta-separator {
557- opacity: 0.5;
558-}
559-
560-.commit-refs {
561- display: inline-flex;
562- gap: var(--space-1);
563-}
564-
565-.commit-ref {
566- font-family: var(--font-mono);
567- font-size: 0.8rem;
568- padding: 0.15rem var(--space-2);
569- border: 1px solid var(--link-color);
570- border-radius: 3px;
571- color: var(--link-color);
572- font-weight: var(--font-semibold);
573-}
574-
575-/* ---- Tree View ---- */
576-.tree-list {
577- border: 1px solid var(--border);
578- border-radius: 4px;
579- overflow: hidden;
580-}
581-
582-.tree-row {
583- display: flex;
584- align-items: center;
585- justify-content: space-between;
586- padding: var(--space-2) var(--space-3);
587- border-bottom: 1px solid rgba(98, 114, 164, 0.2);
588- transition: background var(--transition-fast);
589-}
590-
591-.tree-row:hover {
592- background: rgba(255, 255, 255, 0.03);
593-}
594-
595-.tree-row:last-child {
596- border-bottom: none;
597-}
598-
599-.tree-icon {
600- width: 16px;
601- height: 16px;
602- margin-right: var(--space-2);
603- opacity: 0.8;
604- transition: opacity var(--transition-fast);
605- flex-shrink: 0;
606-}
607-
608-.tree-row:hover .tree-icon {
609- opacity: 1;
610-}
611-
612-.tree-name {
613- font-family: var(--font-mono);
614- font-weight: var(--font-medium);
615- flex: 1;
616- display: flex;
617- align-items: center;
618-}
619-
620-.tree-name a {
621- color: var(--link-color);
622- text-decoration: none;
623-}
624-
625-.tree-name a:hover {
626- text-decoration: underline;
627- text-decoration-thickness: 2px;
628- text-underline-offset: 2px;
629-}
630-
631-.tree-commit {
632- font-size: var(--text-sm);
633- color: var(--grey-light);
634- flex: 1;
635- text-align: right;
636- margin-right: var(--space-4);
637- white-space: nowrap;
638- overflow: hidden;
639- text-overflow: ellipsis;
640-}
641-
642-.tree-commit a {
643- color: var(--grey-light);
644- text-decoration: none;
645-}
646-
647-.tree-commit a:hover {
648- color: var(--link-color);
649-}
650-
651-.tree-size {
652- font-family: var(--font-mono);
653- font-size: 0.8rem;
654- color: var(--grey-light);
655- min-width: 60px;
656- text-align: right;
657- flex-shrink: 0;
658-}
659-
660-.tree-meta-mobile {
661- display: none;
662- font-size: var(--text-sm);
663- color: var(--grey-light);
664- margin-top: var(--space-1);
665-}
666-
667-/* Tree View Mobile */
668-@media (max-width: 768px) {
669- .tree-row {
670- flex-direction: column;
671- align-items: flex-start;
672- padding: var(--space-3);
673- min-height: 60px;
674- }
675-
676- .tree-name {
677- font-size: 1.05rem;
678- font-weight: var(--font-semibold);
679- margin-bottom: var(--space-1);
680- }
681-
682- .tree-commit {
683- display: none;
684- }
685-
686- .tree-size {
687- display: none;
688- }
689-
690- .tree-meta-mobile {
691- display: block;
692- }
693-}
694-
695-/* ---- Breadcrumbs ---- */
696-.breadcrumbs {
697- font-family: var(--font-mono);
698- font-size: 0.95rem;
699- margin-bottom: var(--space-4);
700- display: flex;
701- align-items: center;
702- flex-wrap: wrap;
703- gap: var(--space-2);
704-}
705-
706-.breadcrumbs a {
707- color: var(--link-color);
708- text-decoration: none;
709- font-weight: var(--font-medium);
710-}
711-
712-.breadcrumbs a:hover {
713- text-decoration: underline;
714- text-decoration-thickness: 2px;
715-}
716-
717-.breadcrumbs .current {
718- font-weight: var(--font-bold);
719- color: var(--text-color);
720-}
721-
722-.breadcrumbs .separator {
723- opacity: 0.5;
724- color: var(--grey-light);
725-}
726-
727-/* ---- Diff View ---- */
728-.diff-file {
729- align-items: center;
730- height: 62px;
731- position: sticky;
732- top: 0;
733- left: 0;
734- background-color: var(--bg-color);
735- border-bottom: 1px solid var(--border);
736- padding: var(--space-2) var(--space-3);
737- font-family: var(--font-mono);
738- font-size: 0.9rem;
739-}
740-
741-.diff-file a {
742- color: var(--link-color);
743- font-weight: var(--font-semibold);
744-}
745-
746-.color-green {
747- color: #50fa7b;
748- font-weight: var(--font-semibold);
749-}
750-
751-.color-red {
752- color: #ff5555;
753- font-weight: var(--font-semibold);
754-}
755-
756-/* ---- Utility Classes ---- */
757-.border-b {
758- border-bottom: 1px solid var(--border);
759-}
760-
761-.border-b:last-child {
762- border-bottom: 0;
763-}
764-
765-.box {
766- margin: 1rem 0;
767- padding: var(--grid-height);
768- border: 1px solid var(--border);
769- border-radius: 4px;
770-}
771-
772-.white-space-bs {
773- white-space: break-spaces;
774-}
775-
776-.mb-0 {
777- margin-bottom: 0;
778-}
779-
780-/* ---- Section Headers ---- */
781-.section-title {
782- font-family: var(--font-display);
783- font-size: var(--text-xl);
784- font-weight: var(--font-bold);
785- letter-spacing: 0.05em;
786- text-transform: uppercase;
787- margin-bottom: var(--space-4);
788- color: var(--text-color);
789-}
790-
791-/* ---- Footer ---- */
792-.site-footer {
793- text-align: center;
794- padding-top: var(--space-4);
795- border-top: 1px solid var(--border);
796- margin-top: var(--space-6);
797- font-size: var(--text-sm);
798- color: var(--grey-light);
799-}
800-
801-.site-footer a {
802- color: var(--link-color);
803- font-weight: var(--font-medium);
804-}
805-
806-/* ---- Mobile Header ---- */
807-@media (max-width: 768px) {
808- .site-header {
809- padding: var(--space-4) 0;
810- }
811-
812- .repo-name {
813- font-size: var(--text-2xl);
814- }
815-
816- .header-content {
817- flex-direction: column;
818- gap: var(--space-4);
819- }
820-
821- .clone-cmd {
822- font-size: 0.75rem;
823- overflow-x: auto;
824- }
825-}
826-
827-/* ---- Definition Lists (Commit Details) ---- */
828-dl {
829- margin: var(--space-4) 0;
830-}
831-
832-dt {
833- font-family: var(--font-display);
834- font-weight: var(--font-semibold);
835- font-size: var(--text-sm);
836- text-transform: uppercase;
837- letter-spacing: 0.05em;
838- color: var(--grey-light);
839- margin-top: var(--space-3);
840-}
841-
842-dd {
843- margin-left: 0;
844- font-family: var(--font-body);
845- margin-top: var(--space-1);
846-}
847-
848-dd a {
849- font-family: var(--font-mono);
850- color: var(--link-color);
851-}
852-
853-/* ---- Links Enhancement ---- */
854-a {
855- transition: color var(--transition-fast),
856- background var(--transition-fast),
857- transform var(--transition-base),
858- box-shadow var(--transition-base);
859-}
860-
861-a:hover {
862- text-decoration-thickness: 2px;
863- text-underline-offset: 2px;
864-}
865-
866-/* ---- Existing responsive rules (preserve) ---- */
867-@media only screen and (max-width: 900px) {
868- .tree-commit {
869- display: none;
870- }
871-}
872-```
873-
874-**Step 2: Regenerate test site**
875-
876-Run: `make test-site`
877-Expected: CSS file copied successfully
878-
879-**Step 3: Take screenshot and verify styles applied**
880-
881-```bash
882-playwright-cli open http://localhost:8888
883-playwright-cli screenshot --filename=main-css-applied.png
884-```
885-
886-**Step 4: Commit**
887-
888-```bash
889-jj commit -m "design: add complete component styles to main.css"
890-```
891-
892----
893-
894-### Task 5: Update header.partial.tmpl with New Structure
895-
896-**Files:**
897-- Modify: `/home/btburke/projects/pgit/html/header.partial.tmpl`
898-
899-**Step 1: Rewrite template with new classes**
900-
901-```html
902-{{define "header"}}
903-<div class="header-content flex flex-col">
904- <h1 class="repo-name p-0">
905- {{if .SiteURLs.HomeURL}}
906- <a href="{{.SiteURLs.HomeURL}}">repos</a>
907- <span>/</span>
908- {{end}}
909- <span>{{.Repo.RepoName}}</span>
910- </h1>
911-
912- <nav class="site-nav">
913- <a href="{{.SiteURLs.SummaryURL}}">summary</a>
914- <a href="{{.SiteURLs.RefsURL}}">refs</a>
915- <span class="nav-current">{{.RevData.Name}}</span>
916- <a href="{{.RevData.TreeURL}}">code</a>
917- <a href="{{.RevData.LogURL}}">commits</a>
918- </nav>
919-
920- <div>
921- <div class="repo-desc">{{.Repo.Desc}}</div>
922- {{if .SiteURLs.CloneURL}}<pre class="clone-cmd mb-0">git clone {{.SiteURLs.CloneURL}}</pre>{{end}}
923- </div>
924-</div>
925-{{end}}
926-```
927-
928-**Step 2: Regenerate test site**
929-
930-Run: `make test-site`
931-Expected: No template errors
932-
933-**Step 3: Verify navigation renders as pills**
934-
935-Check that pipes are removed and each nav item is a separate element.
936-
937-**Step 4: Commit**
938-
939-```bash
940-jj commit -m "design: update header template with new navigation structure"
941-```
942-
943----
944-
945-### Task 6: Update log.page.tmpl with Commit Graph
946-
947-**Files:**
948-- Modify: `/home/btburke/projects/pgit/html/log.page.tmpl`
949-
950-**Step 1: Rewrite with commit graph and new classes**
951-
952-```html
953-{{template "base" .}}
954-
955-{{define "title"}}commits - {{.Repo.RepoName}}@{{.RevData.Name}}{{end}}
956-{{define "meta"}}{{end}}
957-
958-{{define "content"}}
959- <h2 class="section-title">{{.NumCommits}} commits</h2>
960-
961- <div class="commit-graph">
962- {{range .Logs}}
963- <div class="commit-row">
964- <div class="commit-dot"></div>
965-
966- <div class="commit-header">
967- <a href="{{.URL}}" class="commit-hash">{{.ShortID}}</a>
968-
969- <div class="commit-refs">
970- {{range .Refs}}
971- {{if .URL}}
972- <a href="{{.URL}}" class="commit-ref">{{.Refspec}}</a>
973- {{else}}
974- <span class="commit-ref">{{.Refspec}}</span>
975- {{end}}
976- {{end}}
977- </div>
978- </div>
979-
980- <div class="commit-message">
981- <pre class="m-0 white-space-bs">{{.Message}}</pre>
982- </div>
983-
984- <div class="commit-meta">
985- <span>{{.AuthorStr}}</span>
986- <span class="commit-meta-separator">·</span>
987- <span>{{.WhenStr}}</span>
988- </div>
989- </div>
990- {{end}}
991- </div>
992-{{end}}
993-```
994-
995-**Step 2: Regenerate test site**
996-
997-Run: `make test-site`
998-Expected: Template renders successfully
999-
1000-**Step 3: Verify commit graph appears**
1001-
1002-Check for vertical line and commit dots on desktop.
1003-
1004-**Step 4: Commit**
1005-
1006-```bash
1007-jj commit -m "design: add commit graph and enhanced commit list styling"
1008-```
1009-
1010----
1011-
1012-### Task 7: Update tree.page.tmpl with Mobile-Optimized Layout
1013-
1014-**Files:**
1015-- Modify: `/home/btburke/projects/pgit/html/tree.page.tmpl`
1016-
1017-**Step 1: Rewrite with enhanced tree styling and mobile meta**
1018-
1019-```html
1020-{{template "base" .}}
1021-
1022-{{define "title"}}files - {{.Repo.RepoName}}@{{.RevData.Name}}{{end}}
1023-{{define "meta"}}{{end}}
1024-
1025-{{define "content"}}
1026- <nav class="breadcrumbs">
1027- {{range .Tree.Crumbs}}
1028- {{if .IsLast}}
1029- <span class="current">{{.Text}}</span>
1030- {{else}}
1031- <a href="{{.URL}}">{{.Text}}</a>
1032- {{if not .IsLast}}<span class="separator">/</span>{{end}}
1033- {{end}}
1034- {{end}}
1035- </nav>
1036-
1037- <div class="tree-list">
1038- {{range .Tree.Items}}
1039- <div class="tree-row">
1040- <div class="tree-name">
1041- {{if .IsDir}}
1042- <svg class="tree-icon" xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="16" width="16" viewBox="0 0 512 512">
1043- <path d="M0 96C0 60.7 28.7 32 64 32H196.1c19.1 0 37.4 7.6 50.9 21.1L289.9 96H448c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM64 80c-8.8 0-16 7.2-16 16V416c0 8.8 7.2 16 16 16H448c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16H286.6c-10.6 0-20.8-4.2-28.3-11.7L213.1 87c-4.5-4.5-10.6-7-17-7H64z"/>
1044- </svg>
1045- {{else}}
1046- <svg class="tree-icon" xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="16" width="16" viewBox="0 0 384 512">
1047- <path d="M320 464c8.8 0 16-7.2 16-16V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320zM0 64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64z"/>
1048- </svg>
1049- {{end}}
1050-
1051- <a href="{{.URL}}">{{.Name}}</a>
1052- </div>
1053-
1054- {{if not $.Repo.HideTreeLastCommit}}
1055- <div class="tree-commit">
1056- <a href="{{.CommitURL}}" title="{{.Summary}}">{{.When}}</a>
1057- </div>
1058- {{end}}
1059-
1060- <div class="tree-size">
1061- {{if .IsDir}}
1062- {{else}}
1063- {{if .IsTextFile}}{{.NumLines}} L{{else}}{{.Size}}{{end}}
1064- {{end}}
1065- </div>
1066-
1067- <!-- Mobile-only meta -->
1068- {{if not $.Repo.HideTreeLastCommit}}
1069- <div class="tree-meta-mobile">
1070- {{.When}}
1071- </div>
1072- {{end}}
1073- </div>
1074- {{end}}
1075- </div>
1076-{{end}}
1077-```
1078-
1079-**Step 2: Regenerate test site**
1080-
1081-Run: `make test-site`
1082-Expected: Template renders successfully
1083-
1084-**Step 3: Test mobile view**
1085-
1086-Use Playwright to resize and verify mobile layout hides commit info properly.
1087-
1088-```bash
1089-playwright-cli open http://localhost:8888/tree/main/index.html
1090-playwright-cli resize 375 812
1091-playwright-cli screenshot --filename=tree-mobile.png
1092-```
1093-
1094-**Step 4: Commit**
1095-
1096-```bash
1097-jj commit -m "design: update tree view with mobile-optimized layout"
1098-```
1099-
1100----
1101-
1102-### Task 8: Update commit.page.tmpl with Enhanced Styles
1103-
1104-**Files:**
1105-- Modify: `/home/btburke/projects/pgit/html/commit.page.tmpl`
1106-
1107-**Step 1: Add classes to enhance commit detail page**
1108-
1109-```html
1110-{{template "base" .}}
1111-{{define "title"}}{{.Commit.Summary}} - {{.Repo.RepoName}}@{{.CommitID}}{{end}}
1112-{{define "meta"}}
1113-<link rel="stylesheet" href="{{.Repo.RootRelative}}syntax.css" />
1114-{{end}}
1115-
1116-{{define "content"}}
1117- <dl>
1118- <dt>commit</dt>
1119- <dd><a href="{{.CommitURL}}" class="commit-hash">{{.CommitID}}</a></dd>
1120-
1121- <dt>parent</dt>
1122- <dd><a href="{{.ParentURL}}" class="commit-hash">{{.Parent}}</a></dd>
1123-
1124- <dt>author</dt>
1125- <dd>{{.Commit.Author.Name}}</dd>
1126-
1127- <dt>date</dt>
1128- <dd>{{.Commit.Author.When}}</dd>
1129- </dl>
1130-
1131- <pre class="commit-message white-space-bs">{{.Commit.Message}}</pre>
1132-
1133- <div class="box mono">
1134- <div>
1135- <strong>{{.Diff.NumFiles}}</strong> files changed,
1136- <span class="color-green">+{{.Diff.TotalAdditions}}</span>,
1137- <span class="color-red">-{{.Diff.TotalDeletions}}</span>
1138- </div>
1139-
1140- <div class="mt">
1141- {{range .Diff.Files}}
1142- <div class="my-sm">
1143- <span>{{.FileType}}</span>
1144- <a href="#diff-{{.Name}}">{{.Name}}</a>
1145- </div>
1146- {{end}}
1147- </div>
1148- </div>
1149-
1150- {{range .Diff.Files}}
1151- <div id="diff-{{.Name}}" class="diff-file flex justify-between">
1152- <div>
1153- <span>{{.FileType}} {{if eq .FileType "R"}}{{.OldName}} => {{end}}</span>
1154- <a href="#diff-{{.Name}}">{{.Name}}</a>
1155- </div>
1156-
1157- <div>
1158- <span class="color-green">+{{.NumAdditions}}</span>,
1159- <span class="color-red">-{{.NumDeletions}}</span>
1160- </div>
1161- </div>
1162-
1163- {{.Content}}
1164- {{end}}
1165-{{end}}
1166-```
1167-
1168-**Step 2: Regenerate test site**
1169-
1170-Run: `make test-site`
1171-
1172-**Step 3: Commit**
1173-
1174-```bash
1175-jj commit -m "design: enhance commit detail page with typography classes"
1176-```
1177-
1178----
1179-
1180-### Task 9: Update refs.page.tmpl with Section Title
1181-
1182-**Files:**
1183-- Modify: `/home/btburke/projects/pgit/html/refs.page.tmpl`
1184-
1185-**Step 1: Add section title class**
1186-
1187-```html
1188-{{template "base" .}}
1189-
1190-{{define "title"}}refs - {{.Repo.RepoName}}{{end}}
1191-{{define "meta"}}{{end}}
1192-
1193-{{define "content"}}
1194- <h2 class="section-title">refs</h2>
1195-
1196- <ul class="tree-list">
1197- {{range .Refs}}
1198- {{if .URL}}
1199- <li class="tree-row"><a href="{{.URL}}">{{.Refspec}}</a></li>
1200- {{else}}
1201- <li class="tree-row">{{.Refspec}}</li>
1202- {{end}}
1203- {{end}}
1204- </ul>
1205-{{end}}
1206-```
1207-
1208-**Step 2: Regenerate and commit**
1209-
1210-Run: `make test-site`
1211-
1212-```bash
1213-jj commit -m "design: update refs page with section styling"
1214-```
1215-
1216----
1217-
1218-### Task 10: Update footer.partial.tmpl with Site Footer Class
1219-
1220-**Files:**
1221-- Modify: `/home/btburke/projects/pgit/html/footer.partial.tmpl`
1222-
1223-**Step 1: Add site-footer class**
1224-
1225-```html
1226-{{define "footer"}}
1227-<div class="site-footer">
1228- <div>
1229- built with <a href="https://pgit.pico.sh">pgit</a>
1230- </div>
1231-</div>
1232-{{end}}
1233-```
1234-
1235-**Step 2: Regenerate and commit**
1236-
1237-Run: `make test-site`
1238-
1239-```bash
1240-jj commit -m "design: add site-footer class to footer template"
1241-```
1242-
1243----
1244-
1245-### Task 11: Update file.page.tmpl with Breadcrumbs
1246-
1247-**Files:**
1248-- Modify: `/home/btburke/projects/pgit/html/file.page.tmpl`
1249-
1250-**Step 1: Add breadcrumbs class and section title**
1251-
1252-```html
1253-{{template "base" .}}
1254-{{define "title"}}{{.Item.Path}}@{{.RevData.Name}}{{end}}
1255-{{define "meta"}}
1256-<link rel="stylesheet" href="{{.Repo.RootRelative}}syntax.css" />
1257-{{end}}
1258-
1259-{{define "content"}}
1260- <nav class="breadcrumbs">
1261- {{range .Item.Crumbs}}
1262- <a href="{{.URL}}">{{.Text}}</a>
1263- {{if not .IsLast}}<span class="separator">/</span>{{end}}
1264- {{end}}
1265- </nav>
1266-
1267- {{if not .Repo.HideTreeLastCommit}}
1268- <div class="box">
1269- <div class="flex items-center justify-between">
1270- <div class="flex-1">
1271- <a href="{{.Item.CommitURL}}">{{.Item.Summary}}</a>
1272- </div>
1273- <div class="mono">
1274- <a href="{{.Item.CommitURL}}" class="commit-hash">{{.Item.CommitID}}</a>
1275- </div>
1276- </div>
1277-
1278- <div class="commit-meta mt">
1279- <span>{{.Item.Author.Name}}</span>
1280- <span class="commit-meta-separator">·</span>
1281- <span>{{.Item.When}}</span>
1282- </div>
1283- </div>
1284- {{end}}
1285-
1286- <h2 class="section-title">{{.Item.Name}}</h2>
1287-
1288- {{.Contents}}
1289-{{end}}
1290-```
1291-
1292-**Step 2: Regenerate and commit**
1293-
1294-Run: `make test-site`
1295-
1296-```bash
1297-jj commit -m "design: update file page with breadcrumbs and styling"
1298-```
1299-
1300----
1301-
1302-### Task 12: Final Testing and Screenshot Comparison
1303-
1304-**Files:** None (verification only)
1305-
1306-**Step 1: Regenerate complete test site**
1307-
1308-```bash
1309-make test-site
1310-```
1311-
1312-**Step 2: Start server and capture screenshots**
1313-
1314-```bash
1315-python3 -m http.server 8888 --directory /home/btburke/projects/pgit/testdata.site &
1316-```
1317-
1318-**Step 3: Capture desktop screenshots**
1319-
1320-```bash
1321-playwright-cli open http://localhost:8888
1322-playwright-cli screenshot --filename=final-desktop-home.png
1323-playwright-cli goto http://localhost:8888/logs/main/index.html
1324-playwright-cli screenshot --filename=final-desktop-commits.png
1325-playwright-cli goto http://localhost:8888/tree/main/index.html
1326-playwright-cli screenshot --filename=final-desktop-tree.png
1327-playwright-cli goto http://localhost:8888/commits/93ec21917415ae74afec3fab3e734145b75019fc.html
1328-playwright-cli screenshot --filename=final-desktop-commit.png
1329-```
1330-
1331-**Step 4: Capture mobile screenshots**
1332-
1333-```bash
1334-playwright-cli resize 375 812
1335-playwright-cli goto http://localhost:8888
1336-playwright-cli screenshot --filename=final-mobile-home.png
1337-playwright-cli goto http://localhost:8888/logs/main/index.html
1338-playwright-cli screenshot --filename=final-mobile-commits.png
1339-playwright-cli goto http://localhost:8888/tree/main/index.html
1340-playwright-cli screenshot --filename=final-mobile-tree.png
1341-```
1342-
1343-**Step 5: Verify all screenshots show:**
1344-- Google Fonts loaded (Space Grotesk, Inter, JetBrains Mono visible)
1345-- Navigation as pill buttons
1346-- Commit graph visible on desktop (vertical line with dots)
1347-- Tree view compact on desktop, stacked on mobile
1348-- Proper spacing and typography hierarchy
1349-- Hover states work (test manually)
1350-
1351-**Step 6: Final commit**
1352-
1353-```bash
1354-jj commit -m "design: complete visual enhancement implementation"
1355-```
1356-
1357----
1358-
1359-## Summary of Changes
1360-
1361-### Files Modified
1362-
1363-1. `/home/btburke/projects/pgit/static/vars.css` - Added design tokens
1364-2. `/home/btburke/projects/pgit/static/smol.css` - Updated typography base
1365-3. `/home/btburke/projects/pgit/static/main.css` - Complete component styles
1366-4. `/home/btburke/projects/pgit/html/base.layout.tmpl` - Added Google Fonts
1367-5. `/home/btburke/projects/pgit/html/header.partial.tmpl` - New nav structure
1368-6. `/home/btburke/projects/pgit/html/log.page.tmpl` - Commit graph
1369-7. `/home/btburke/projects/pgit/html/tree.page.tmpl` - Mobile tree view
1370-8. `/home/btburke/projects/pgit/html/commit.page.tmpl` - Enhanced styling
1371-9. `/home/btburke/projects/pgit/html/refs.page.tmpl` - Section styling
1372-10. `/home/btburke/projects/pgit/html/file.page.tmpl` - Breadcrumbs
1373-11. `/home/btburke/projects/pgit/html/footer.partial.tmpl` - Footer class
1374-
1375-### Key Features Implemented
1376-
1377-- ✅ Bold typography (Space Grotesk headers, Inter body, JetBrains Mono code)
1378-- ✅ Visual hierarchy with proper font weights and sizes
1379-- ✅ CSS-only pill navigation with hover effects
1380-- ✅ Mobile-optimized navigation (2-column grid, touch targets)
1381-- ✅ Simple commit graph (vertical line with dots)
1382-- ✅ Compact tree view on desktop
1383-- ✅ Mobile tree view (hidden commit/size info, larger touch targets)
1384-- ✅ Smooth transitions (150-200ms)
1385-- ✅ Accessible focus states
1386-- ✅ Respects color scheme from Chroma
1@@ -1,29 +0,0 @@
2-# High-Contrast Technical Design Upgrade
3-
4-## Goal
5-Improve the design of the Git hosting static site by applying a "High-Contrast Technical" aesthetic. This involves bold typography, strong visual hierarchy, denser spacing, and CSS-only interactive elements to make the interface more readable and visually appealing.
6-
7-## Architecture & Aesthetics
8-- **Typography:** Mix of a clean sans-serif for UI/menus and monospace for code/commits.
9-- **Visual Hierarchy:** Heavy font weights (e.g., 800) for primary information (commit messages, active states), muted colors (`var(--grey-light)`) for secondary metadata (author, date).
10-- **Density:** Tightly packed related information with generous whitespace between distinct blocks (e.g., between individual commits).
11-- **Interactivity:** Pure CSS hover states (color changes, borders) on menus and commit lists.
12-
13-## Components
14-
15-### Header and Navigation
16-- **Header (`header.partial.tmpl`):** Repository name in bold sans-serif.
17-- **Menu Layout:** Replace inline `|` separators with a flex container (`gap: 1rem`).
18-- **Links (`nav a`):** Styled as tabs. Default: muted (`var(--grey-light)`), bold. Hover: bright (`var(--text-color)`), crisp bottom border (using `border-bottom` or `::after`).
19-- **Active State (`nav span.font-bold`):** Matches hover style (bright text, bottom border).
20-
21-### Commit List (`log.page.tmpl`)
22-- **Typography:** Commit message (subject) is bold and larger. Metadata (author, date, short hash) is smaller (`var(--text-sm)`) and muted (`var(--grey-light)`).
23-- **Spacing:** Tight packing within a commit block, but larger margin (`margin-bottom: 1.5rem`) between commits.
24-- **Refs (`.Refspec`):** High-contrast pill shape (solid background/bright border).
25-- **Hover State:** Subtle background color change on the entire commit block (`div.group-2 > div:hover`).
26-
27-### Commit Detail (`commit.page.tmpl`)
28-- **Typography:** Main commit message treated as a major heading (large, bold, high contrast).
29-- **Metadata (`dl`):** Styled as a dense, two-column grid (`display: grid; grid-template-columns: max-content 1fr; gap: 0.5rem 1rem;`). Labels (`dt`) right-aligned and muted; values (`dd`) bold.
30-- **Diff Headers (`.diff-file`):** Enhanced sticky headers with a distinct, slightly darker background color and a bottom border.
1@@ -1,269 +0,0 @@
2-# High-Contrast Technical UI Upgrade Implementation Plan
3-
4-> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
5-
6-**Goal:** Implement a "High-Contrast Technical" aesthetic to improve typography, visual hierarchy, density, and CSS-only interactive elements across the Git hosting site templates.
7-
8-**Architecture:** We will modify the CSS (`static/main.css`, `static/smol.css`) and HTML templates (`html/header.partial.tmpl`, `html/log.page.tmpl`, `html/commit.page.tmpl`). We will rely purely on CSS for hover effects, spacing, and typography without adding any JavaScript.
9-
10-**Tech Stack:** Go HTML Templates, CSS
11-
12----
13-
14-### Task 1: Header and Navigation Menu Redesign
15-
16-**Files:**
17-- Modify: `html/header.partial.tmpl`
18-- Modify: `static/main.css`
19-
20-**Step 1: Update the Navigation HTML**
21-Remove the `|` separators from the `<nav>` element and structure it to easily support flexbox gaps.
22-
23-```html
24-<!-- html/header.partial.tmpl -->
25-<!-- REPLACE existing <nav> block with: -->
26-<nav class="flex gap items-center nav-menu">
27- <a href="{{.SiteURLs.SummaryURL}}">summary</a>
28- <a href="{{.SiteURLs.RefsURL}}">refs</a>
29- <span class="active">{{.RevData.Name}}</span>
30- <a href="{{.RevData.TreeURL}}">code</a>
31- <a href="{{.RevData.LogURL}}">commits</a>
32-</nav>
33-```
34-
35-**Step 2: Add CSS for the new Header/Nav**
36-Update `static/main.css` to add the new navigation styling.
37-
38-```css
39-/* static/main.css */
40-/* APPEND TO END OF FILE */
41-
42-/* --- High-Contrast UI Updates --- */
43-
44-/* Header & Nav */
45-.nav-menu {
46- gap: 1.5rem;
47- margin: 1rem 0;
48- border-bottom: 1px solid var(--border);
49- padding-bottom: 0.5rem;
50-}
51-
52-.nav-menu a, .nav-menu span.active {
53- color: var(--grey-light);
54- font-weight: 600;
55- text-transform: uppercase;
56- font-size: 0.9rem;
57- text-decoration: none;
58- padding-bottom: 0.4rem;
59- border-bottom: 2px solid transparent;
60- transition: all 0.2s ease;
61-}
62-
63-.nav-menu a:hover, .nav-menu span.active {
64- color: var(--text-color);
65- border-bottom: 2px solid var(--link-color);
66-}
67-```
68-
69-**Step 3: Render and Verify**
70-Run: `make test-site && npx playwright-cli open file:///home/btburke/projects/pgit/testdata.site/index.html`
71-Expected: The header menu is a flex row. No pipe separators. Links are grey but turn bright with a bottom border on hover.
72-
73-**Step 4: Commit**
74-```bash
75-jj commit -m "style: implement high-contrast header and navigation"
76-```
77-
78----
79-
80-### Task 2: Commit List (log.page.tmpl) Upgrade
81-
82-**Files:**
83-- Modify: `html/log.page.tmpl`
84-- Modify: `static/main.css`
85-
86-**Step 1: Update HTML Structure**
87-Refactor the loop inside `log.page.tmpl` to use semantic classes for the new design.
88-
89-```html
90-<!-- html/log.page.tmpl -->
91-<!-- REPLACE the content inside {{range .Logs}} with: -->
92-<div class="commit-row py">
93- <div class="flex justify-between items-start mb">
94- <div class="flex-1">
95- <pre class="m-0 white-space-bs font-bold text-md text-transform-none">{{.Message}}</pre>
96- <div class="flex items-center gap-xs text-sm font-grey-light mt-2">
97- <span class="font-bold">{{.AuthorStr}}</span>
98- <span> · </span>
99- <span>{{.WhenStr}}</span>
100- </div>
101- </div>
102-
103- <div class="flex flex-col items-end gap-xs">
104- <a href="{{.URL}}" class="mono text-sm font-bold commit-hash">{{.ShortID}}</a>
105- {{if .Refs}}
106- <div class="flex gap-xs flex-wrap justify-end mt-2">
107- {{range .Refs}}
108- <span class="ref-pill mono text-sm">
109- {{if .URL}}
110- <a href="{{.URL}}">{{.Refspec}}</a>
111- {{else}}
112- {{.Refspec}}
113- {{end}}
114- </span>
115- {{end}}
116- </div>
117- {{end}}
118- </div>
119- </div>
120-</div>
121-```
122-
123-**Step 2: Add CSS for Commit List**
124-Append the new styles to `static/main.css`.
125-
126-```css
127-/* static/main.css */
128-/* APPEND TO END OF FILE */
129-
130-/* Commit List */
131-.commit-row {
132- border-bottom: 1px solid var(--grey);
133- transition: background-color 0.2s ease;
134- padding: 1rem 0.5rem;
135- margin: 0 -0.5rem; /* pull out to allow hover background to extend */
136- border-radius: 4px;
137-}
138-
139-.commit-row:hover {
140- background-color: var(--pre);
141-}
142-
143-.commit-row:last-child {
144- border-bottom: none;
145-}
146-
147-.commit-hash {
148- background-color: var(--pre);
149- padding: 0.2rem 0.5rem;
150- border-radius: 4px;
151- border: 1px solid var(--grey);
152-}
153-
154-.ref-pill {
155- background-color: var(--link-color);
156- color: var(--bg-color);
157- padding: 0.1rem 0.4rem;
158- border-radius: 12px;
159- font-weight: bold;
160-}
161-.ref-pill a {
162- color: inherit;
163- text-decoration: none;
164-}
165-.ref-pill a:hover {
166- text-decoration: underline;
167-}
168-```
169-
170-**Step 3: Render and Verify**
171-Run: `make test-site && npx playwright-cli open file:///home/btburke/projects/pgit/testdata.site/commits/main.html`
172-Expected: Commit lists have generous spacing. Hovering over a row adds a subtle background. Hashes look like buttons. Refs look like solid pills. Messages are bold and larger than the author/date metadata.
173-
174-**Step 4: Commit**
175-```bash
176-jj commit -m "style: implement high-contrast commit list"
177-```
178-
179----
180-
181-### Task 3: Commit Detail (commit.page.tmpl) Upgrade
182-
183-**Files:**
184-- Modify: `html/commit.page.tmpl`
185-- Modify: `static/main.css`
186-
187-**Step 1: Update HTML Structure**
188-Convert the `<dl>` to use our new grid class and enhance the layout.
189-
190-```html
191-<!-- html/commit.page.tmpl -->
192-<!-- REPLACE the top section (above the diff) with: -->
193-<div class="mb-4">
194- <pre class="white-space-bs font-bold text-lg mb-4 text-transform-none">{{.Commit.Message}}</pre>
195-
196- <div class="metadata-grid text-sm mb-4">
197- <div class="meta-label">commit</div>
198- <div class="meta-value mono"><a href="{{.CommitURL}}">{{.CommitID}}</a></div>
199-
200- <div class="meta-label">parent</div>
201- <div class="meta-value mono"><a href="{{.ParentURL}}">{{.Parent}}</a></div>
202-
203- <div class="meta-label">author</div>
204- <div class="meta-value font-bold">{{.Commit.Author.Name}}</div>
205-
206- <div class="meta-label">date</div>
207- <div class="meta-value">{{.Commit.Author.When}}</div>
208- </div>
209-</div>
210-
211-<div class="box mono mb-4">
212-<!-- ... keep existing diff summary box content ... -->
213-```
214-
215-**Step 2: Add CSS for Commit Detail**
216-Append the new styles to `static/main.css`.
217-
218-```css
219-/* static/main.css */
220-/* APPEND TO END OF FILE */
221-
222-/* Commit Detail */
223-.metadata-grid {
224- display: grid;
225- grid-template-columns: max-content 1fr;
226- gap: 0.5rem 1.5rem;
227- align-items: center;
228- background-color: var(--pre);
229- padding: 1rem;
230- border-radius: 4px;
231- border: 1px solid var(--grey);
232-}
233-
234-.meta-label {
235- color: var(--grey-light);
236- text-align: right;
237- font-weight: 600;
238- text-transform: uppercase;
239- font-size: 0.8rem;
240-}
241-
242-.meta-value {
243- color: var(--text-color);
244-}
245-
246-/* Update existing .diff-file to be more distinct */
247-.diff-file {
248- align-items: center;
249- height: 48px; /* Slightly slimmer */
250- position: sticky;
251- top: 0;
252- left: 0;
253- background-color: var(--bg-color);
254- border-bottom: 2px solid var(--grey);
255- border-top: 1px solid var(--grey);
256- padding: 0 1rem;
257- margin: 2rem 0 0 0;
258- z-index: 10;
259- font-weight: bold;
260-}
261-```
262-
263-**Step 3: Render and Verify**
264-Run: `make test-site && npx playwright-cli open file:///home/btburke/projects/pgit/testdata.site/commits/93ec21917415ae74afec3fab3e734145b75019fc.html`
265-Expected: The commit message is large and bold. Metadata is in a neat, boxed grid. Diff file headers have a clear top/bottom border separating them from the code.
266-
267-**Step 4: Commit**
268-```bash
269-jj commit -m "style: implement high-contrast commit detail view"
270-```
1@@ -1,196 +0,0 @@
2-# Recent Commit Activity Indicator Plan
3-
4-> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
5-
6-**Goal:** Add a subtle, tight block to the summary page showing the most recent commit and a humanized relative date to indicate development activity.
7-
8-**Architecture:** Use `github.com/dustin/go-humanize` to format the relative time of the latest commit. Expose this via a new `HumanWhenStr` field on `CommitData`. Update the generator (`main.go`) to capture this data and pass it to the `SummaryPageData`. Finally, render it in `html/summary.page.tmpl` using a tight `.box-sm` layout.
9-
10-**Tech Stack:** Go, Go HTML Templates
11-
12----
13-
14-### Task 1: Implement `humanizeTime` Helper and Update Models
15-
16-**Files:**
17-- Modify: `main.go`
18-
19-**Step 1: Add `humanizeTime` function**
20-Add a new helper function to `main.go` (near `toPretty` or similar helpers) that formats the time. If older than a year, fallback to `Month Year`.
21-
22-```go
23-// in main.go
24-func humanizeTime(t time.Time) string {
25- if time.Since(t).Hours() > 365*24 {
26- return t.Format("Jan 2006")
27- }
28- return humanize.Time(t)
29-}
30-```
31-
32-**Step 2: Update `CommitData`**
33-Add `HumanWhenStr string` to `CommitData`.
34-
35-```go
36-// in main.go
37-type CommitData struct {
38- SummaryStr string
39- URL template.URL
40- WhenStr string
41- HumanWhenStr string // <-- NEW
42- AuthorStr string
43- ShortID string
44- ParentID string
45- Refs []*RefInfo
46- *git.Commit
47-}
48-```
49-
50-**Step 3: Update `SummaryPageData`**
51-Add `LastCommit *CommitData` to `SummaryPageData`.
52-
53-```go
54-// in main.go
55-type SummaryPageData struct {
56- *PageData
57- Readme template.HTML
58- LastCommit *CommitData // <-- NEW
59-}
60-```
61-
62-**Step 4: Build to Verify Syntax**
63-Run: `go build`
64-Expected: Clean build. No template or logical errors yet.
65-
66-**Step 5: Commit**
67-```bash
68-jj commit -m "feat: add humanize time helper and update models for recent commit indicator"
69-```
70-
71----
72-
73-### Task 2: Populate Data in Generator
74-
75-**Files:**
76-- Modify: `main.go`
77-
78-**Step 1: Update `writeRevision`**
79-In `main.go`'s `writeRevision` method (around line 966), `output.LastCommit = commit` is currently capturing the raw `*git.Commit`. Change `BranchOutput.LastCommit` type to `*CommitData`.
80-
81-First, update `BranchOutput`:
82-```go
83-// in main.go
84-type BranchOutput struct {
85- Readme string
86- LastCommit *CommitData // <-- CHANGED from *git.Commit
87-}
88-```
89-
90-Next, update the commit loop in `writeRevision` (around line 983) to populate the new field and capture the enriched struct:
91-
92-```go
93-// in main.go inside writeRevision loop
94- cd := &CommitData{
95- ParentID: parentID,
96- URL: c.getCommitURL(commit.ID.String()),
97- ShortID: getShortID(commit.ID.String()),
98- SummaryStr: commit.Summary(),
99- AuthorStr: commit.Author.Name,
100- WhenStr: commit.Author.When.Format(time.DateOnly),
101- HumanWhenStr: humanizeTime(commit.Author.When), // <-- NEW
102- Commit: commit,
103- Refs: tags,
104- }
105-
106- if i == 0 {
107- output.LastCommit = cd // <-- Captures the enriched CommitData
108- }
109- logs = append(logs, cd)
110-```
111-
112-**Step 2: Update `writeRootSummary` Method Signature**
113-Update `writeRootSummary` to accept the `LastCommit`.
114-
115-```go
116-// in main.go
117-func (c *Config) writeRootSummary(data *PageData, readme template.HTML, lastCommit *CommitData) { // <-- Add parameter
118- c.Logger.Info("writing root html", "repoPath", c.RepoPath)
119- c.writeHtml(&WriteData{
120- Filename: "index.html",
121- Template: "html/summary.page.tmpl",
122- Data: &SummaryPageData{
123- PageData: data,
124- Readme: readme,
125- LastCommit: lastCommit, // <-- Set it here
126- },
127- })
128-}
129-```
130-
131-**Step 3: Update `writeRootSummary` Invocation**
132-In `writeRepo()` (around line 738), pass `mainOutput.LastCommit`.
133-
134-```go
135-// in main.go
136- c.writeRootSummary(data, readmeHTML, mainOutput.LastCommit)
137-```
138-
139-**Step 4: Build to Verify Logic**
140-Run: `go build`
141-Expected: Clean build.
142-
143-**Step 5: Commit**
144-```bash
145-jj commit -m "feat: populate recent commit data for summary page"
146-```
147-
148----
149-
150-### Task 3: Render Activity Indicator in Template
151-
152-**Files:**
153-- Modify: `html/summary.page.tmpl`
154-
155-**Step 1: Update the Template**
156-Add the `.box-sm` block right below the `{{define "content"}}` directive, before the clone URL logic.
157-
158-```html
159-<!-- html/summary.page.tmpl -->
160-{{define "content"}}
161- {{if .LastCommit}}
162- <div class="box-sm flex justify-between items-center mb text-sm font-grey-light">
163- <div class="flex items-center gap-xs truncate">
164- <span class="font-bold">{{.LastCommit.AuthorStr}}</span>
165- <span> · </span>
166- <a href="{{.LastCommit.URL}}" class="link-alt-hover text-transform-none">{{.LastCommit.SummaryStr}}</a>
167- </div>
168- <div class="mono" title="{{.LastCommit.WhenStr}}">
169- {{.LastCommit.HumanWhenStr}}
170- </div>
171- </div>
172- {{end}}
173-
174- {{if .SiteURLs.CloneURL}}
175-...
176-```
177-
178-**Step 2: Add CSS Truncation Helper (if missing)**
179-Verify `static/main.css` or `static/smol.css` has a `.truncate` class. If not, add it to `static/main.css`:
180-
181-```css
182-/* in static/main.css */
183-.truncate {
184- overflow: hidden;
185- text-overflow: ellipsis;
186- white-space: nowrap;
187-}
188-```
189-
190-**Step 3: Render and Verify**
191-Run: `make test-site && npx playwright-cli open file:///home/btburke/projects/pgit/testdata.site/index.html`
192-Expected: A small box immediately above the clone URL block displaying the author, commit message, and relative date (e.g., "2 years ago" or "Oct 2024").
193-
194-**Step 4: Commit**
195-```bash
196-jj commit -m "feat: display recent commit activity indicator on summary page"
197-```
+6,
-1
1@@ -12,9 +12,14 @@
2 <nav class="nav-menu">
3 {{if eq .Active "summary"}}<span class="active">summary</span>{{else}}<a href="{{.SiteURLs.SummaryURL}}">summary</a>{{end}}
4 {{if eq .Active "refs"}}<span class="active">refs</span>{{else}}<a href="{{.SiteURLs.RefsURL}}">refs</a>{{end}}
5- <span class="font-bold">{{.RevData.Name}}</span>
6 {{if eq .Active "code"}}<span class="active">code</span>{{else}}<a href="{{.RevData.TreeURL}}">code</a>{{end}}
7 {{if eq .Active "commits"}}<span class="active">commits</span>{{else}}<a href="{{.RevData.LogURL}}">commits</a>{{end}}
8+ <details class="nav-menu__ref-selector">
9+ <summary>{{.RevData.Name}}</summary>
10+ <div class="ref-selector__dropdown">
11+ {{range .Refs}}{{if .URL}}<a href="{{.URL}}">{{.Refspec}}</a>{{end}}{{end}}
12+ </div>
13+ </details>
14 </nav>
15
16 {{if and (eq .Active "summary") .LastCommit}}
M
main.go
+3,
-0
1@@ -175,6 +175,7 @@ type PageData struct {
2 Repo *Config
3 SiteURLs *SiteURLs
4 RevData *RevData
5+ Refs []*RefInfo
6 }
7
8 type SummaryPageData struct {
9@@ -707,6 +708,7 @@ func (c *Config) writeRepo() *BranchOutput {
10 Repo: c,
11 RevData: revData,
12 SiteURLs: c.getURLs(),
13+ Refs: refInfoList,
14 }
15
16 if i == 0 {
17@@ -734,6 +736,7 @@ func (c *Config) writeRepo() *BranchOutput {
18 RevData: revData,
19 Repo: c,
20 SiteURLs: c.getURLs(),
21+ Refs: refInfoList,
22 }
23 c.writeRefs(data, refInfoList)
24 // Convert README markdown to HTML for summary page
+94,
-3
1@@ -324,6 +324,7 @@ sup {
2 margin: 1rem 0;
3 border-bottom: 1px solid var(--border);
4 padding-bottom: 0.5rem;
5+ flex-wrap: wrap;
6 }
7
8 .nav-menu a,
9@@ -353,6 +354,76 @@ sup {
10 border-bottom: 2px solid transparent;
11 }
12
13+/* Ref Selector Dropdown */
14+.nav-menu__ref-selector {
15+ margin-left: auto;
16+ position: relative;
17+}
18+
19+.nav-menu__ref-selector summary {
20+ color: var(--grey-light);
21+ font-weight: 600;
22+ text-transform: uppercase;
23+ font-size: 0.9rem;
24+ padding-bottom: 0.4rem;
25+ border-bottom: 2px solid transparent;
26+ cursor: pointer;
27+ list-style: none;
28+ display: flex;
29+ align-items: center;
30+ gap: 0.25rem;
31+}
32+
33+.nav-menu__ref-selector summary:hover {
34+ color: var(--text-color);
35+}
36+
37+.nav-menu__ref-selector summary::-webkit-details-marker {
38+ display: none;
39+}
40+
41+.nav-menu__ref-selector summary::after {
42+ content: "▼";
43+ font-size: 0.7rem;
44+}
45+
46+.nav-menu__ref-selector[open] summary::after {
47+ content: "▲";
48+}
49+
50+.ref-selector__dropdown {
51+ position: absolute;
52+ top: 100%;
53+ right: 0;
54+ min-width: 150px;
55+ background-color: var(--bg-color);
56+ border: 1px solid var(--border);
57+ border-radius: 4px;
58+ padding: 0.5rem 0;
59+ margin-top: 0.25rem;
60+ z-index: 100;
61+ max-height: 300px;
62+ overflow-y: auto;
63+}
64+
65+.ref-selector__dropdown a {
66+ display: block;
67+ padding: 0.25rem 1rem;
68+ color: var(--text-color);
69+ font-weight: 600;
70+ text-transform: uppercase;
71+ font-size: 0.9rem;
72+ text-decoration: none;
73+ border-bottom: none;
74+ padding-bottom: 0.25rem;
75+}
76+
77+.ref-selector__dropdown a:hover {
78+ background-color: var(--pre);
79+ color: var(--link-color);
80+ text-decoration: none;
81+}
82+
83 /* Last Commit Bar (summary page) */
84 .last-commit-bar {
85 display: flex;
86@@ -499,8 +570,7 @@ sup {
87 justify-content: space-between;
88 align-items: center;
89 gap: var(--line-height);
90- padding: var(--grid-height);
91- border-bottom: 1px solid var(--border);
92+ padding: 0 var(--grid-height);
93 }
94
95 .file-list__row:last-child {
96@@ -876,6 +946,11 @@ sup {
97 gap: 0.75rem;
98 }
99
100+ /* Hide ref selector on mobile */
101+ .nav-menu__ref-selector {
102+ display: none;
103+ }
104+
105 /* Commit list adjustments */
106 .commit-item__header {
107 flex-direction: column;
108@@ -941,7 +1016,14 @@ sup {
109 .last-commit-bar {
110 flex-direction: column;
111 align-items: flex-start;
112- gap: var(--grid-height);
113+ gap: 0;
114+ }
115+
116+ .last-commit-bar__info,
117+ .last-commit-bar__time {
118+ line-height: var(--line-height);
119+ margin: 0;
120+ padding: 0;
121 }
122
123 .last-commit-bar__info {
124@@ -951,10 +1033,19 @@ sup {
125
126 @media only screen and (max-width: 900px) {
127
128+ .file-list_row {
129+ padding: 0 var(--grid-height);
130+ padding-top: var(--grid-height);
131+ }
132+
133 /* Hide tree commit column on medium screens */
134 .file-list__commit {
135 display: none;
136 }
137+
138+ .file-list__size {
139+ display: none;
140+ }
141 }
142
143 /* Commit Message (in commit detail page) */
1@@ -0,0 +1,2 @@
2+x+)JMU042a040031Qrut�u��Mah~����a�
3+��o�����}�%��D�����.�c�pyY���k��@%���R5��]����XS������P�d�E�.�N�8�[5S�s�aF�3XQ5Q
+1,
-0
1@@ -0,0 +1 @@
2+1e12c021ffe53632ffd00c1c85752ad43e62f0ed
+1,
-1
1@@ -1 +1 @@
2-93ec21917415ae74afec3fab3e734145b75019fc
3+b51ecb50102b1b7b73ff2c7c684278d6c00b507a