A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
1# Website Visual Improvement Plan
2
3## Goal
4Create a fun, personality-driven container registry that embraces its nautical theme while being clearly functional. Think GitHub's Octocat or DigitalOcean's Sammy - playful but professional.
5
6## Brand Identity (from seahorse logo)
7- **Primary Teal**: #4ECDC4 (body color) - the "ocean" feel
8- **Dark Teal**: #2E8B8B (mane/fins) - depth and contrast
9- **Mint Background**: #C8F0E7 - light, airy, underwater
10- **Coral Accent**: #FF6B6B (eye) - warmth, CTAs, highlights
11- **Nautical theme to embrace:**
12 - "Ship" containers (not just push)
13 - "Holds" for storage (like a ship's cargo hold)
14 - "Sailors" are users, "Captains" own holds
15 - Seahorse mascot as the friendly guide
16
17## Design Direction: Fun but Functional
18- Softer, more rounded corners
19- Playful color combinations (teal + coral)
20- Mascot appearances in empty states, loading, errors
21- Ocean-inspired subtle backgrounds (gradients, waves)
22- Friendly copy and microcopy throughout
23- Still clearly a container registry with all the technical info
24
25## Current State
26- Pure CSS with custom properties for theming
27- Basic card designs for repositories
28- Simple hero section with terminal mockup
29- Existing badges: Helm charts, multi-arch, attestations
30- Existing stats: stars, pull counts
31
32## Layout Wireframes
33
34### Current Homepage Layout
35```
36┌─────────────────────────────────────────────────────────────────┐
37│ [Logo] [Search] [Theme] [User] │ Navbar
38├─────────────────────────────────────────────────────────────────┤
39│ │
40│ ship containers on the open web. │ Hero
41│ ┌─────────────────────────┐ │
42│ │ $ docker login atcr.io │ │
43│ └─────────────────────────┘ │
44│ [Get Started] [Learn More] │
45│ │
46│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Benefits
47│ │ Docker │ │ Your Data │ │ Discover │ │
48│ └─────────────┘ └─────────────┘ └─────────────┘ │
49├─────────────────────────────────────────────────────────────────┤
50│ │
51│ Featured │
52│ ┌─────────────────────────────────────────────────────────────┐│
53│ │ [icon] user/repo ★ 12 ↓ 340 ││ WIDE cards
54│ │ Description text here... ││ (current)
55│ └─────────────────────────────────────────────────────────────┘│
56│ ┌─────────────────────────────────────────────────────────────┐│
57│ │ [icon] user/repo2 ★ 5 ↓ 120 ││
58│ └─────────────────────────────────────────────────────────────┘│
59│ │
60│ What's New │
61│ (similar wide cards) │
62└─────────────────────────────────────────────────────────────────┘
63```
64
65### Proposed Layout: Tile Grid
66```
67┌─────────────────────────────────────────────────────────────────┐
68│ [Logo] [Search] [Theme] [User] │
69├─────────────────────────────────────────────────────────────────┤
70│ │
71│ ship containers on the open web. │
72│ ┌─────────────────────────┐ │
73│ │ $ docker login atcr.io │ │
74│ └─────────────────────────┘ │
75│ [Get Started] [Learn More] │
76│ │
77│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
78│ │ Docker │ │ Your Data │ │ Discover │ │
79│ └────────────┘ └────────────┘ └────────────┘ │
80├─────────────────────────────────────────────────────────────────┤
81│ │
82│ Featured [View All] │
83│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐│
84│ │ [icon] │ │ [icon] │ │ [icon] ││ 3 columns
85│ │ user/repo │ │ user/repo2 │ │ user/repo3 ││ ~300px each
86│ │ Description... │ │ Description... │ │ Description... ││
87│ │ ────────────────││ │ ────────────────││ │ ────────────────│││
88│ │ ★ 12 ↓ 340 │ │ ★ 5 ↓ 120 │ │ ★ 8 ↓ 89 ││
89│ └──────────────────┘ └──────────────────┘ └──────────────────┘│
90│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐│
91│ │ ... │ │ ... │ │ ... ││
92│ └──────────────────┘ └──────────────────┘ └──────────────────┘│
93│ │
94├─────────────────────────────────────────────────────────────────┤
95│ │
96│ What's New │
97│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐│
98│ │ ... │ │ ... │ │ ... ││ Same tile
99│ └──────────────────┘ └──────────────────┘ └──────────────────┘│ layout
100└─────────────────────────────────────────────────────────────────┘
101```
102
103### Unified Tile Card (Same for Featured & What's New)
104```
105┌─────────────────────────────┐
106│ ┌────┐ user/repo [Helm] │ Icon + name + type badge
107│ │icon│ :latest │ Tag (if applicable)
108│ └────┘ │
109│ │
110│ Description text that │ Description (2-3 lines max)
111│ wraps nicely here... │
112│ │
113│ sha256:abcdef12 │ Digest (truncated)
114│ ───────────────────────────│ Divider
115│ ★ 12 ↓ 340 1 day ago │ Stats + timestamp
116└─────────────────────────────┘
117
118Card anatomy:
119┌─────────────────────────────┐
120│ HEADER │ - Icon (48x48)
121│ - icon + name + badge │ - user/repo
122│ - tag (optional) │ - :tag or :latest
123├─────────────────────────────┤
124│ BODY │ - Description (clamp 2-3 lines)
125│ - description │ - sha256:abc... (monospace)
126│ - digest │
127├─────────────────────────────┤
128│ FOOTER │ - ★ star count
129│ - stats + time │ - ↓ pull count
130│ │ - "2 hours ago"
131└─────────────────────────────┘
132```
133
134### Both Sections Use Same Card (Different Sort)
135```
136Featured (by stars/curated): What's New (by last_push):
137┌─────────────────────────┐ ┌─────────────────────────┐
138│ user/repo │ │ user/repo │
139│ :latest │ │ :v1.2.3 │ ← latest tag
140│ Description... │ │ Description... │
141│ │ │ │
142│ sha256:abc123 │ │ sha256:def456 │ ← latest digest
143│ ───────────────────────│ │ ───────────────────────│
144│ ★ 12 ↓ 340 1 day ago │ │ ★ 5 ↓ 89 2 hrs ago │ ← last_push time
145└─────────────────────────┘ └─────────────────────────┘
146
147Same card component, different data source:
148- Featured: GetFeaturedRepos() (curated or by stars)
149- What's New: GetRecentlyUpdatedRepos() (ORDER BY last_push DESC)
150```
151
152### Card Dimensions Comparison
153```
154Current: █████████████████████████████████████████ (~800px+ wide)
155Proposed: ████████████ ████████████ ████████████ (~280-320px each)
156 Card 1 Card 2 Card 3
157```
158
159### Mobile Responsive Behavior
160```
161Desktop (>1024px): [Card] [Card] [Card] 3 columns
162Tablet (768-1024px): [Card] [Card] 2 columns
163Mobile (<768px): [Card] 1 column (full width)
164```
165
166### Playful Elements
167```
168Empty State (no repos):
169┌─────────────────────────────────────────┐
170│ │
171│ 🐴 (seahorse) │
172│ "Nothing here yet!" │
173│ │
174│ Ship your first container to get │
175│ started on your voyage. │
176│ │
177│ [Start Shipping] │
178└─────────────────────────────────────────┘
179
180Error/404:
181┌─────────────────────────────────────────┐
182│ │
183│ 🐴 (confused seahorse) │
184│ "Lost at sea!" │
185│ │
186│ We couldn't find that container. │
187│ Maybe it drifted away? │
188│ │
189│ [Back to Shore] │
190└─────────────────────────────────────────┘
191
192Hero with subtle ocean feel:
193┌─────────────────────────────────────────┐
194│ ≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋ │ Subtle wave pattern bg
195│ │
196│ ship containers on the │
197│ open web. 🐴 │ Mascot appears!
198│ │
199│ ┌─────────────────────┐ │
200│ │ $ docker login ... │ │
201│ └─────────────────────┘ │
202│ │
203│ ≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋≋ │
204└─────────────────────────────────────────┘
205```
206
207### Card with Personality
208```
209┌───────────────────────────────────┐
210│ ┌──────┐ │
211│ │ icon │ user/repo │
212│ │ │ :latest [⚓ Helm] │ Anchor icon for Helm
213│ └──────┘ │
214│ │
215│ A container that does amazing │
216│ things for your app... │
217│ │
218│ sha256:abcdef12 │
219│ ─────────────────────────────────│
220│ ★ 12 ↓ 340 1 day ago │
221│ │
222│ 🐴 Shipped by alice.bsky.social │ Playful "shipped by" line
223└───────────────────────────────────┘
224
225(optional: "Shipped by" could be subtle or only on hover)
226```
227
228## Design Improvements
229
230### 1. Enhanced Card Design (Priority: High)
231**Files:** `pkg/appview/public/css/style.css`, `pkg/appview/templates/components/repo-card.html`
232
233- Add subtle gradient backgrounds on hover
234- Improve shadow depth (layered shadows for modern look)
235- Add smooth transitions (transform, box-shadow)
236- Better icon styling with ring/border accent
237- Enhanced badge visibility with better contrast
238- Add "Updated X ago" timestamp to cards
239- Improve stat icon/count alignment and spacing
240
241### 2. Hero Section Polish (Priority: High)
242**Files:** `pkg/appview/public/css/style.css`, `pkg/appview/templates/pages/home.html`
243
244- Add subtle background pattern or gradient mesh
245- Improve terminal mockup styling (better shadows, glow effect)
246- Enhance benefit cards with icons and better spacing
247- Add visual separation between hero and content
248- Improve CTA button styling with better hover states
249
250### 3. Typography & Spacing (Priority: High)
251**Files:** `pkg/appview/public/css/style.css`
252
253- Increase visual hierarchy with better font weights
254- Add more breathing room (padding/margins)
255- Improve heading styles with subtle underlines or accents
256- Better link styling with hover states
257- Add letter-spacing to badges for readability
258
259### 4. Badge System Enhancement (Priority: Medium)
260**Files:** `pkg/appview/public/css/style.css`, templates
261
262- Create unified badge design language
263- Add subtle icons inside badges (already using Lucide)
264- Improve color coding: Helm (blue), Attestation (green), Multi-arch (purple)
265- Add "Official" or "Verified" badge styling (for future use)
266- Better hover states on interactive badges
267
268### 5. Featured Section Improvements (Priority: Medium)
269**Files:** `pkg/appview/templates/pages/home.html`, `pkg/appview/public/css/style.css`
270
271- Add section header with subtle styling
272- Improve grid responsiveness
273- Add "View All" link styling
274- Better visual distinction from "What's New" section
275
276### 6. Navigation Polish (Priority: Medium)
277**Files:** `pkg/appview/public/css/style.css`, nav templates
278
279- Improve search bar visibility and styling
280- Better user menu dropdown aesthetics
281- Add subtle border or shadow to navbar
282- Improve mobile responsiveness
283
284### 7. Loading & Empty States (Priority: Low)
285**Files:** `pkg/appview/public/css/style.css`
286
287- Add skeleton loading animations
288- Improve empty state illustrations/styling
289- Better transition when content loads
290
291### 8. Micro-interactions (Priority: Low)
292**Files:** `pkg/appview/public/css/style.css`, `pkg/appview/public/js/app.js`
293
294- Add subtle hover animations throughout
295- Improve button press feedback
296- Star button animation on click
297- Copy button success animation
298
299## Implementation Order
300
3011. **Phase 1: Core Card Styling**
302 - Update `.featured-card` with modern shadows and transitions
303 - Enhance badge styling in `style.css`
304 - Add hover effects and transforms
305
3062. **Phase 2: Hero & Featured Section**
307 - Improve hero section gradient/background
308 - Polish benefit cards
309 - Add section separators
310
3113. **Phase 3: Typography & Spacing**
312 - Update font weights and sizes
313 - Improve padding throughout
314 - Better visual rhythm
315
3164. **Phase 4: Navigation & Polish**
317 - Navbar improvements
318 - Loading states
319 - Final micro-interactions
320
321## Key CSS Changes
322
323### Tile Grid Layout
324```css
325.featured-grid {
326 display: grid;
327 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
328 gap: 1.5rem;
329}
330
331/* Already exists but updating min-width */
332.featured-card {
333 min-height: 200px;
334 display: flex;
335 flex-direction: column;
336 justify-content: space-between;
337}
338```
339
340### Enhanced Shadow System (Multi-layer for depth)
341```css
342--shadow-card: 0 1px 3px rgba(0,0,0,0.08), 0 4px 12px rgba(0,0,0,0.05);
343--shadow-card-hover: 0 8px 25px rgba(78,205,196,0.15), 0 4px 12px rgba(0,0,0,0.1);
344--shadow-nav: 0 2px 8px rgba(0,0,0,0.1);
345```
346
347### Card Design Enhancement
348```css
349.featured-card {
350 transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
351 border: 1px solid var(--border);
352}
353.featured-card:hover {
354 transform: translateY(-4px);
355 box-shadow: var(--shadow-card-hover);
356 border-color: var(--primary); /* teal accent on hover */
357}
358```
359
360### Icon Container Styling
361```css
362.featured-icon-placeholder {
363 background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
364 box-shadow: 0 2px 8px rgba(78,205,196,0.3);
365}
366```
367
368### Badge System (Consistent, Accessible)
369```css
370.badge-helm {
371 background: #0d6cbf;
372 color: #fff;
373}
374.badge-multi {
375 background: #7c3aed;
376 color: #fff;
377}
378.badge-attestation {
379 background: #059669;
380 color: #fff;
381}
382/* All badges: */
383font-weight: 600;
384letter-spacing: 0.02em;
385text-transform: uppercase;
386font-size: 0.7rem;
387padding: 0.25rem 0.5rem;
388border-radius: 4px;
389```
390
391### Hero Section Enhancement
392```css
393.hero-section {
394 background:
395 linear-gradient(135deg, var(--hero-bg-start) 0%, var(--hero-bg-end) 50%, rgba(78,205,196,0.1) 100%),
396 url('/static/wave-pattern.svg'); /* subtle wave pattern */
397 background-size: cover, 100% 50px;
398 background-position: center, bottom;
399 background-repeat: no-repeat, repeat-x;
400}
401.benefit-card {
402 border: 1px solid transparent;
403 border-radius: 12px; /* softer corners */
404 transition: all 0.2s ease;
405}
406.benefit-card:hover {
407 border-color: var(--primary);
408 transform: translateY(-4px);
409}
410```
411
412### Playful Border Radius (Softer Feel)
413```css
414:root {
415 --radius-sm: 6px; /* was 4px */
416 --radius-md: 12px; /* was 8px */
417 --radius-lg: 16px; /* new */
418}
419
420.featured-card { border-radius: var(--radius-md); }
421.benefit-card { border-radius: var(--radius-md); }
422.btn { border-radius: var(--radius-sm); }
423.hero-terminal { border-radius: var(--radius-lg); }
424```
425
426### Fun Empty States
427```css
428.empty-state {
429 text-align: center;
430 padding: 3rem;
431}
432.empty-state-mascot {
433 width: 120px;
434 height: auto;
435 margin-bottom: 1.5rem;
436 animation: float 3s ease-in-out infinite;
437}
438@keyframes float {
439 0%, 100% { transform: translateY(0); }
440 50% { transform: translateY(-10px); }
441}
442.empty-state-title {
443 font-size: 1.5rem;
444 font-weight: 600;
445 color: var(--fg);
446}
447.empty-state-text {
448 color: var(--secondary);
449 margin-bottom: 1.5rem;
450}
451```
452
453### Typography Refinements
454```css
455.featured-title {
456 font-weight: 600;
457 letter-spacing: -0.01em;
458}
459.featured-description {
460 line-height: 1.5;
461 opacity: 0.85;
462}
463```
464
465## Data Model Change
466
467**Current "What's New":** Shows individual pushes (each tag push is a separate card)
468
469**Proposed "What's New":** Shows repos ordered by last update time (same as Featured, different sort)
470
471**Tracking:** `repository_stats` table already has `last_push` timestamp!
472```sql
473SELECT * FROM repository_stats ORDER BY last_push DESC LIMIT 9;
474```
475
476**Unified Card Data:**
477| Field | Source |
478|-------|--------|
479| Handle, Repository | users + manifests |
480| Tag | Latest tag from `tags` table |
481| Digest | From latest tag or manifest |
482| Description, IconURL | repo_pages or annotations |
483| StarCount, PullCount | stars count + repository_stats |
484| LastUpdated | `repository_stats.last_push` |
485| ArtifactType | manifests.artifact_type |
486
487## Files to Modify
488
489| File | Changes |
490|------|---------|
491| `pkg/appview/public/css/style.css` | Rounded corners, shadows, hover, badges, ocean theme |
492| `pkg/appview/public/wave-pattern.svg` | NEW: Subtle wave pattern for hero background |
493| `pkg/appview/templates/components/repo-card.html` | Add Tag, Digest, LastUpdated fields |
494| `pkg/appview/templates/components/empty-state.html` | NEW: Reusable fun empty state with mascot |
495| `pkg/appview/templates/pages/home.html` | Both sections use repo-card grid |
496| `pkg/appview/templates/pages/404.html` | Fun "Lost at sea" error page |
497| `pkg/appview/db/queries.go` | New `GetRecentlyUpdatedRepos()` query; add fields to `RepoCardData` |
498| `pkg/appview/handlers/home.go` | Replace `GetRecentPushes` with `GetRecentlyUpdatedRepos` |
499| `pkg/appview/templates/partials/push-list.html` | Delete or repurpose (no longer needed) |
500
501## Dependencies
502
503**Mascot Art Needed:**
504- `seahorse-empty.svg` - Friendly pose for "nothing here yet" empty states
505- `seahorse-confused.svg` - Lost/confused pose for 404 errors
506- `seahorse-waving.svg` (optional) - For hero section accent
507
508**Can proceed without art:**
509- CSS changes (colors, shadows, rounded corners, gradients)
510- Card layout and grid changes
511- Data layer changes (queries, handlers)
512- Wave pattern background (simple SVG)
513
514**Blocked until art is ready:**
515- Empty state component with mascot
516- 404 page redesign with mascot
517- Hero mascot integration (optional)
518
519## Implementation Phases
520
521### Phase 1: CSS & Layout (No art needed)
5221. Update border-radius variables (softer corners)
5232. New shadow system
5243. Card hover effects with teal accent
5254. Tile grid layout (`minmax(280px, 1fr)`)
5265. Wave pattern SVG for hero background
527
528### Phase 2: Card Component & Data
5291. Update `repo-card.html` with new structure
5302. Add `Digest`, `Tag`, `CreatedAt` fields
5313. Update queries for latest manifest info
5324. Replace push list with card grid
533
534### Phase 3: Hero & Section Polish
5351. Hero gradient + wave pattern
5362. Benefit card improvements
5373. Section headers and spacing
5384. Mobile responsive breakpoints
539
540### Phase 4: Mascot Integration (BLOCKED - needs art)
5411. Empty state component with mascot
5422. 404 page with confused seahorse
5433. Hero mascot (optional)
544
545### Phase 5: Testing
5461. Dark mode verification
5472. Mobile responsive check
5483. All functionality works (stars, links, copy)
549
550## Verification
551
5521. **Visual check on homepage** - cards have depth and polish
5532. **Hover states** - smooth transitions on cards, buttons, badges
5543. **Dark mode** - all changes work in both themes
5554. **Mobile** - responsive at all breakpoints
5565. **Functionality** - stars, search, navigation all work
5576. **Performance** - no jank from CSS transitions
5587. **Accessibility** - badge text readable (contrast check)