# 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
