that initial commit
This commit is contained in:
289
docs/decisions/ADR-003-frontend-technology.md
Normal file
289
docs/decisions/ADR-003-frontend-technology.md
Normal file
@@ -0,0 +1,289 @@
|
||||
# ADR-003: Front-end Technology Stack
|
||||
|
||||
## Status
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
StarPunk requires a front-end for:
|
||||
1. Public interface (homepage, note permalinks) - Server-side rendered
|
||||
2. Admin interface (note creation/editing) - Requires some interactivity
|
||||
3. Progressive enhancement principle - Core functionality must work without JavaScript
|
||||
|
||||
The front-end must be minimal, elegant, and align with the "no client-side complexity" principle stated in CLAUDE.MD.
|
||||
|
||||
## Decision
|
||||
|
||||
### Public Interface: Server-Side Rendered HTML
|
||||
- **Template Engine**: Jinja2 (included with Flask)
|
||||
- **CSS**: Custom CSS (no framework)
|
||||
- **JavaScript**: None required for V1
|
||||
- **Build Tools**: None required
|
||||
|
||||
### Admin Interface: Enhanced Server-Side Rendering
|
||||
- **Template Engine**: Jinja2 (included with Flask)
|
||||
- **CSS**: Custom CSS (shared with public interface)
|
||||
- **JavaScript**: Minimal vanilla JavaScript for markdown preview only
|
||||
- **Build Tools**: None required
|
||||
|
||||
### Asset Management
|
||||
- **CSS**: Single stylesheet served statically
|
||||
- **JavaScript**: Single optional file for markdown preview
|
||||
- **No bundler**: Direct file serving
|
||||
- **No transpilation**: Modern browsers only (ES6+)
|
||||
|
||||
## Rationale
|
||||
|
||||
### Server-Side Rendering (SSR)
|
||||
**Simplicity Score: 10/10**
|
||||
- Zero build process
|
||||
- No JavaScript framework complexity
|
||||
- Direct Flask template rendering
|
||||
- Familiar Jinja2 syntax
|
||||
|
||||
**Fitness Score: 10/10**
|
||||
- Perfect for content-first site
|
||||
- Faster initial page load
|
||||
- Better SEO (though not critical for single-user)
|
||||
- Works without JavaScript
|
||||
- Easier to implement microformats
|
||||
|
||||
**Maintenance Score: 10/10**
|
||||
- Jinja2 is stable and mature
|
||||
- No framework version updates
|
||||
- No npm dependency hell
|
||||
- Templates are simple HTML
|
||||
|
||||
### No CSS Framework
|
||||
**Simplicity Score: 10/10**
|
||||
- Custom CSS is ~200 lines for entire site
|
||||
- No unused classes or styles
|
||||
- Full control over appearance
|
||||
- No framework learning curve
|
||||
|
||||
**Fitness Score: 9/10**
|
||||
- StarPunk needs minimal, elegant design
|
||||
- Single theme, no customization needed
|
||||
- Mobile-responsive can be achieved with simple media queries
|
||||
- No complex components needed
|
||||
|
||||
### Minimal JavaScript Approach
|
||||
**Simplicity Score: 9/10**
|
||||
- Vanilla JavaScript only (no React/Vue/Svelte)
|
||||
- Single purpose: markdown preview in admin
|
||||
- Optional progressive enhancement
|
||||
- No build step required
|
||||
|
||||
**Fitness Score: 10/10**
|
||||
- Markdown preview improves UX but isn't required
|
||||
- All functionality works without JavaScript
|
||||
- Can use fetch API for preview without library
|
||||
- Modern browser features are sufficient
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
- Zero build time
|
||||
- No node_modules directory
|
||||
- Instant development setup
|
||||
- Fast page loads
|
||||
- Works with JavaScript disabled
|
||||
- Easy to understand and modify
|
||||
- Microformats implementation is straightforward
|
||||
- Complete control over HTML output
|
||||
|
||||
### Negative
|
||||
- No TypeScript type checking
|
||||
- No hot module replacement (but Flask auto-reload works)
|
||||
- Manual CSS organization required
|
||||
- Must write responsive CSS manually
|
||||
|
||||
### Mitigation
|
||||
- Keep JavaScript minimal and well-commented
|
||||
- Organize CSS with clear sections
|
||||
- Use CSS custom properties for theming
|
||||
- Test manually in multiple browsers
|
||||
- Validate HTML with W3C validator
|
||||
|
||||
## Frontend File Structure
|
||||
|
||||
```
|
||||
static/
|
||||
├── css/
|
||||
│ └── style.css # Single stylesheet for entire site
|
||||
└── js/
|
||||
└── preview.js # Optional markdown preview (admin only)
|
||||
|
||||
templates/
|
||||
├── base.html # Base template with HTML structure
|
||||
├── index.html # Homepage (note list)
|
||||
├── note.html # Single note permalink
|
||||
└── admin/
|
||||
├── base.html # Admin base template
|
||||
├── dashboard.html # Admin dashboard
|
||||
├── new.html # Create new note
|
||||
└── edit.html # Edit existing note
|
||||
```
|
||||
|
||||
## CSS Architecture
|
||||
|
||||
### Custom CSS Properties (Variables)
|
||||
```css
|
||||
:root {
|
||||
--color-text: #333;
|
||||
--color-bg: #fff;
|
||||
--color-link: #0066cc;
|
||||
--color-border: #ddd;
|
||||
--font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
--font-mono: 'SF Mono', Monaco, monospace;
|
||||
--spacing-unit: 1rem;
|
||||
--max-width: 42rem;
|
||||
}
|
||||
```
|
||||
|
||||
### Mobile-First Responsive Design
|
||||
```css
|
||||
/* Base: Mobile styles */
|
||||
body { padding: 1rem; }
|
||||
|
||||
/* Tablet and up */
|
||||
@media (min-width: 768px) {
|
||||
body { padding: 2rem; }
|
||||
}
|
||||
```
|
||||
|
||||
## JavaScript Architecture
|
||||
|
||||
### Markdown Preview Implementation
|
||||
```javascript
|
||||
// static/js/preview.js
|
||||
// Simple markdown preview using marked.js CDN (no build step)
|
||||
// Progressive enhancement - form works without this
|
||||
```
|
||||
|
||||
**Decision**: Use marked.js from CDN for client-side preview
|
||||
- **Justification**: Same library as server-side (consistency)
|
||||
- **Simplicity**: No bundling required
|
||||
- **Reliability**: CDN delivers cached version
|
||||
- **Alternative**: No preview (acceptable fallback)
|
||||
|
||||
## Template Organization
|
||||
|
||||
### Jinja2 Template Strategy
|
||||
- **Inheritance**: Use base templates for common structure
|
||||
- **Blocks**: Define clear content blocks for overriding
|
||||
- **Macros**: Create reusable microformat snippets
|
||||
- **Filters**: Use Jinja2 filters for date formatting
|
||||
|
||||
### Example Base Template Structure
|
||||
```jinja2
|
||||
{# templates/base.html #}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}{{ site.title }}{% endblock %}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||
<link rel="alternate" type="application/rss+xml" href="{{ url_for('feed') }}">
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
{% block content %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## Microformats Integration
|
||||
|
||||
Server-side rendering makes microformats implementation straightforward:
|
||||
|
||||
```jinja2
|
||||
{# Macro for h-entry note rendering #}
|
||||
{% macro render_note(note) %}
|
||||
<article class="h-entry">
|
||||
<div class="e-content">
|
||||
{{ note.content_html | safe }}
|
||||
</div>
|
||||
<footer>
|
||||
<a class="u-url" href="{{ url_for('note', slug=note.slug) }}">
|
||||
<time class="dt-published" datetime="{{ note.created_at.isoformat() }}">
|
||||
{{ note.created_at.strftime('%B %d, %Y') }}
|
||||
</time>
|
||||
</a>
|
||||
</footer>
|
||||
</article>
|
||||
{% endmacro %}
|
||||
```
|
||||
|
||||
## Build and Development Workflow
|
||||
|
||||
### Development
|
||||
1. Run Flask development server: `flask run`
|
||||
2. Edit templates/CSS/JS directly
|
||||
3. Browser auto-refresh on template changes
|
||||
4. No build step required
|
||||
|
||||
### Production
|
||||
1. Copy static files to production
|
||||
2. Templates are rendered on-demand
|
||||
3. Optionally enable Flask caching for rendered HTML
|
||||
4. Serve static assets with nginx/Apache (optional)
|
||||
|
||||
## Browser Support
|
||||
- Modern browsers (Chrome 90+, Firefox 88+, Safari 14+, Edge 90+)
|
||||
- Mobile browsers (iOS Safari 14+, Chrome Android 90+)
|
||||
- Progressive enhancement ensures basic functionality on older browsers
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
### React/Vue/Svelte (Rejected)
|
||||
- **Simplicity**: 2/10 - Requires build tools, npm, bundlers
|
||||
- **Fitness**: 3/10 - Massive overkill for content site
|
||||
- **Maintenance**: 5/10 - Constant framework updates
|
||||
- **Verdict**: Violates "no client-side complexity" principle
|
||||
|
||||
### htmx (Considered)
|
||||
- **Simplicity**: 8/10 - Single JavaScript file, declarative
|
||||
- **Fitness**: 6/10 - Useful for dynamic updates, but not needed in V1
|
||||
- **Maintenance**: 8/10 - Stable, minimal dependencies
|
||||
- **Verdict**: Interesting for V2, but V1 doesn't need dynamic updates
|
||||
|
||||
### Alpine.js (Considered)
|
||||
- **Simplicity**: 8/10 - Lightweight, declarative
|
||||
- **Fitness**: 5/10 - Good for small interactions, but we barely need any
|
||||
- **Maintenance**: 8/10 - Well maintained
|
||||
- **Verdict**: Too much for the minimal JS we need
|
||||
|
||||
### Tailwind CSS (Rejected)
|
||||
- **Simplicity**: 4/10 - Requires build process, large configuration
|
||||
- **Fitness**: 3/10 - Utility-first doesn't fit minimal design needs
|
||||
- **Maintenance**: 7/10 - Well maintained but heavy
|
||||
- **Verdict**: Build process violates simplicity; custom CSS is sufficient
|
||||
|
||||
### Bootstrap/Bulma (Rejected)
|
||||
- **Simplicity**: 5/10 - Large framework with many unused features
|
||||
- **Fitness**: 3/10 - Component-heavy, we need minimal custom design
|
||||
- **Maintenance**: 9/10 - Very stable
|
||||
- **Verdict**: Too much CSS for what we need
|
||||
|
||||
### PicoCSS/Water.css (Considered)
|
||||
- **Simplicity**: 9/10 - Classless CSS, just include and go
|
||||
- **Fitness**: 7/10 - Good starting point but may not match design vision
|
||||
- **Maintenance**: 8/10 - Maintained, simple
|
||||
- **Verdict**: Close consideration, but custom CSS gives full control
|
||||
|
||||
## Standards Compliance
|
||||
- Semantic HTML5 elements
|
||||
- Valid HTML (W3C validator)
|
||||
- Accessible forms and navigation
|
||||
- Proper heading hierarchy
|
||||
- ARIA labels where needed
|
||||
- Mobile-responsive (viewport meta tag)
|
||||
- Progressive enhancement (works without JS)
|
||||
|
||||
## References
|
||||
- Jinja2 Documentation: https://jinja.palletsprojects.com/
|
||||
- MDN Web Docs: https://developer.mozilla.org/
|
||||
- Microformats2: http://microformats.org/wiki/h-entry
|
||||
- Progressive Enhancement: https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement
|
||||
- Semantic HTML: https://developer.mozilla.org/en-US/docs/Glossary/Semantics
|
||||
Reference in New Issue
Block a user