chore: remove impeccable
This commit is contained in:
@@ -1,105 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"generatedAt": "2026-05-05T00:00:00Z",
|
||||
"title": "Design System: MAL",
|
||||
"extensions": {
|
||||
"colorMeta": {
|
||||
"background": { "role": "neutral", "displayName": "Void Black", "canonical": "#080808" },
|
||||
"background-sidebar": { "role": "neutral", "displayName": "Deep Charcoal", "canonical": "#0f0f0f" },
|
||||
"background-header": { "role": "neutral", "displayName": "Elevated Black", "canonical": "#141414" },
|
||||
"background-surface": { "role": "neutral", "displayName": "Surface Gray", "canonical": "#202020" },
|
||||
"background-button": { "role": "neutral", "displayName": "Button Dark", "canonical": "#1a1a1a" },
|
||||
"background-button-hover": { "role": "neutral", "displayName": "Button Hover", "canonical": "#252525" },
|
||||
"foreground-muted": { "role": "neutral", "displayName": "Muted Gray", "canonical": "#6a6b70" },
|
||||
"foreground": { "role": "neutral", "displayName": "Off White", "canonical": "#f8f9fa" },
|
||||
"accent": { "role": "primary", "displayName": "Soft Violet", "canonical": "#9f7aea" },
|
||||
"danger": { "role": "accent", "displayName": "Red Alert", "canonical": "#dc2626" }
|
||||
},
|
||||
"typographyMeta": {
|
||||
"body": { "displayName": "Body", "purpose": "Standard text, descriptions" },
|
||||
"title": { "displayName": "Title", "purpose": "Page headings" },
|
||||
"label": { "displayName": "Label", "purpose": "Navigation, buttons, form labels" }
|
||||
},
|
||||
"shadows": [],
|
||||
"motion": [
|
||||
{ "name": "ease-default", "value": "cubic-bezier(0.4, 0, 0.2, 1)", "purpose": "Default transition easing" }
|
||||
],
|
||||
"breakpoints": []
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"name": "Primary Button",
|
||||
"kind": "button",
|
||||
"refersTo": "button-primary",
|
||||
"description": "Main action button with purple background",
|
||||
"html": "<button class=\"ds-btn-primary\">Action</button>",
|
||||
"css": ".ds-btn-primary { background: #9f7aea; color: #080808; padding: 8px 16px; border: none; font-weight: 500; transition: background 0.2s; } .ds-btn-primary:hover { background: #b79ef5; }"
|
||||
},
|
||||
{
|
||||
"name": "Secondary Button",
|
||||
"kind": "button",
|
||||
"refersTo": "button-secondary",
|
||||
"description": "Secondary action with dark background",
|
||||
"html": "<button class=\"ds-btn-secondary\">Action</button>",
|
||||
"css": ".ds-btn-secondary { background: rgba(255,255,255,0.05); color: #f8f9fa; padding: 8px 16px; border: none; transition: background 0.2s; } .ds-btn-secondary:hover { background: rgba(255,255,255,0.1); }"
|
||||
},
|
||||
{
|
||||
"name": "Anime Card",
|
||||
"kind": "card",
|
||||
"refersTo": "card-anime",
|
||||
"description": "Anime poster card with hover reveal",
|
||||
"html": "<div class=\"ds-card\"><img src=\"\" alt=\"Anime\"><div class=\"ds-card-overlay\"><span>Title</span></div></div>",
|
||||
"css": ".ds-card { position: relative; aspect-ratio: 2/3; background: rgba(255,255,255,0.05); overflow: hidden; } .ds-card img { width: 100%; height: 100%; object-fit: cover; } .ds-card-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.8); opacity: 0; padding: 12px; transition: opacity 0.3s; display: flex; flex-direction: column; } .ds-card:hover .ds-card-overlay { opacity: 1; }"
|
||||
},
|
||||
{
|
||||
"name": "Navigation Item",
|
||||
"kind": "nav",
|
||||
"refersTo": "nav-item",
|
||||
"description": "Sidebar navigation link with active indicator",
|
||||
"html": "<a class=\"ds-nav-item\" href=\"/\">Home</a>",
|
||||
"css": ".ds-nav-item { display: flex; align-items: center; padding: 12px 28px; color: #6a6b70; text-decoration: none; transition: color 0.2s, background 0.2s; position: relative; } .ds-nav-item:hover { background: rgba(255,255,255,0.05); } .ds-nav-item.active { color: #9f7aea; } .ds-nav-item.active::before { content: ''; position: absolute; left: 0; top: 50%; transform: translateY(-50%); height: 32px; width: 2px; background: #9f7aea; }"
|
||||
},
|
||||
{
|
||||
"name": "Dropdown Menu",
|
||||
"kind": "custom",
|
||||
"refersTo": "dropdown",
|
||||
"description": "Custom dropdown with dark background",
|
||||
"html": "<div class=\"ds-dropdown\"><button>Menu</button><div class=\"ds-dropdown-content\"><button>Option</button></div></div>",
|
||||
"css": ".ds-dropdown { position: relative; } .ds-dropdown-content { position: absolute; top: 100%; right: 0; background: #1a1a1a; box-shadow: 0 8px 24px rgba(0,0,0,0.4); padding: 4px 0; display: none; min-width: 160px; } .ds-dropdown-content button { display: block; width: 100%; padding: 10px 20px; text-align: left; background: none; border: none; color: #f8f9fa; } .ds-dropdown-content button:hover { background: rgba(255,255,255,0.1); }"
|
||||
}
|
||||
],
|
||||
"narrative": {
|
||||
"northStar": "The Personal Theater",
|
||||
"overview": "A dark, intimate interface for watching anime. Built for long viewing sessions in low-light environments. The aesthetic rejects the loud, gamified look of mainstream anime trackers. No flashy animations, no glassmorphism, no gradient text.",
|
||||
"keyCharacteristics": [
|
||||
"Dark by default; light mode secondary",
|
||||
"Minimal chrome; content first",
|
||||
"Purple accent ≤10% of any screen",
|
||||
"No rounded corners",
|
||||
"DM Sans system fonts"
|
||||
],
|
||||
"rules": [
|
||||
{ "name": "The One Accent Rule", "body": "Purple appears on ≤10% of any given screen. Its rarity is the point.", "section": "colors" },
|
||||
{ "name": "The Weight Contrast Rule", "body": "Headings use font-semibold (600), body uses font-normal (400). Avoid flat weight hierarchies.", "section": "typography" },
|
||||
{ "name": "The Flat-By-Default Rule", "body": "Surfaces are flat at rest. No shadows. Depth conveyed through tonal layering.", "section": "elevation" }
|
||||
],
|
||||
"dos": [
|
||||
"Do use accent purple for primary actions and active states only",
|
||||
"Do keep interfaces dark by default",
|
||||
"Do use weight contrast for hierarchy",
|
||||
"Do reveal detail on hover",
|
||||
"Do include back buttons on detail pages"
|
||||
],
|
||||
"donts": [
|
||||
"Don't use rounded corners anywhere",
|
||||
"Don't use color to differentiate toast types",
|
||||
"Don't use gradient text",
|
||||
"Don't use glassmorphism",
|
||||
"Don't use hero metric layouts",
|
||||
"Don't use identical card grids with no variation",
|
||||
"Don't use modals as first thought",
|
||||
"Don't use side-stripe borders",
|
||||
"Don't use green accent—violet is the one and only"
|
||||
]
|
||||
}
|
||||
}
|
||||
155
DESIGN.md
155
DESIGN.md
@@ -1,155 +0,0 @@
|
||||
---
|
||||
name: MAL
|
||||
description: Personal anime streaming & watchlist service
|
||||
colors:
|
||||
background: "#080808"
|
||||
background-sidebar: "#0f0f0f"
|
||||
background-header: "#141414"
|
||||
background-surface: "#202020"
|
||||
background-button: "#1a1a1a"
|
||||
background-button-hover: "#252525"
|
||||
foreground-muted: "#6a6b70"
|
||||
foreground: "#f8f9fa"
|
||||
accent: "#9f7aea"
|
||||
danger: "#dc2626"
|
||||
typography:
|
||||
body:
|
||||
fontFamily: "'DM Sans', 'Segoe UI', system-ui, sans-serif"
|
||||
fontSize: "14px"
|
||||
fontWeight: 400
|
||||
lineHeight: 1.5
|
||||
rounded:
|
||||
default: "6px"
|
||||
spacing:
|
||||
sm: "0.25rem"
|
||||
md: "0.5rem"
|
||||
lg: "1rem"
|
||||
xl: "1.5rem"
|
||||
2xl: "2rem"
|
||||
components:
|
||||
button-primary:
|
||||
backgroundColor: "{colors.accent}"
|
||||
textColor: "#080808"
|
||||
padding: "8px 16px"
|
||||
button-secondary:
|
||||
backgroundColor: "{colors.background-button}"
|
||||
textColor: "{colors.foreground}"
|
||||
padding: "8px 16px"
|
||||
button-secondary-hover:
|
||||
backgroundColor: "{colors.background-button-hover}"
|
||||
---
|
||||
|
||||
# Design System: MAL
|
||||
|
||||
## 1. Overview
|
||||
|
||||
**Creative North Star: "The Personal Theater"**
|
||||
|
||||
A dark, intimate interface for watching anime. Built for long viewing sessions in low-light environments—think late-night streaming on a personal server. The aesthetic rejects the loud, gamified look of mainstream anime trackers. No flashy animations, no glassmorphism, no gradient text. Just content and controls.
|
||||
|
||||
**Key Characteristics:**
|
||||
- Dark by default; light mode exists but is secondary
|
||||
- Minimal chrome; the anime artwork carries the visual weight
|
||||
- Purple accent used sparingly (<10% of any screen)
|
||||
- No rounded corners; sharp edges throughout
|
||||
- System fonts (DM Sans) for reliability across devices
|
||||
|
||||
## 2. Colors
|
||||
|
||||
The palette is intentionally restrained. Dark surfaces dominate to reduce eye strain during long sessions.
|
||||
|
||||
### Primary
|
||||
- **Accent Purple** (`#9f7aea`): Navigation highlights, active states, primary actions. Used on active sidebar items, hover states on important buttons, current episode indicators.
|
||||
|
||||
### Neutral
|
||||
- **Background** (`#080808`): Main page background. Deep black with a hint of warmth.
|
||||
- **Background Sidebar** (`#0f0f0f`): Slightly elevated surface for navigation panel.
|
||||
- **Background Header** (`#141414`): Sticky header surface, slightly brighter than page.
|
||||
- **Background Surface** (`#202020`): Cards, dropdowns, search inputs.
|
||||
- **Background Button** (`#1a1a1a`): Default button state, form fields.
|
||||
- **Background Button Hover** (`#252525`): Button hover state.
|
||||
- **Foreground Muted** (`#6a6b70`): Secondary text, icons, placeholders.
|
||||
- **Foreground** (`#f8f9fa`): Primary text, headings.
|
||||
|
||||
### Named Rules
|
||||
**The One Accent Rule.** Purple appears on ≤10% of any given screen. Its rarity is the point. Navigation highlights use a subtle left border; primary buttons use the accent background.
|
||||
|
||||
## 3. Typography
|
||||
|
||||
**Body Font:** DM Sans (with Segoe UI, system-ui fallbacks)
|
||||
|
||||
**Character:** Clean, legible, unremarkable. The typeface should be invisible—content first.
|
||||
|
||||
### Hierarchy
|
||||
- **Title** (`600`, `20px`): Page headings.
|
||||
- **Body** (`400`, `14px`): Standard text, descriptions.
|
||||
- **Label** (`500`, `14px`, `0.025em`): Navigation items, buttons, form labels.
|
||||
- **Small** (`400`, `12px`): Metadata, episode numbers, timestamps.
|
||||
|
||||
### Named Rules
|
||||
**The Weight Contrast Rule.** Headings use `font-semibold` (600), body uses `font-normal` (400). Avoid flat weight hierarchies.
|
||||
|
||||
## 4. Elevation
|
||||
|
||||
**Flat by default.** No shadows at rest. Depth is conveyed through tonal layering—different background colors rather than shadow layers.
|
||||
|
||||
- **Hover state:** Background shifts from `#1a1a1a` to `#252525`.
|
||||
- **Active states:** Subtle accent tint (`bg-accent/20`) or accent left border.
|
||||
- **No shadows.** The interface is intentionally flat.
|
||||
|
||||
### Shadow Vocabulary
|
||||
None used. If shadows are needed for overlays (modals, dropdowns), use `box-shadow: 0 8px 24px rgba(0,0,0,0.4)`.
|
||||
|
||||
## 5. Components
|
||||
|
||||
### Buttons
|
||||
- **Shape:** No rounded corners (sharp edges).
|
||||
- **Primary:** Purple background (`bg-accent`), dark text. Used for the most important action on each screen.
|
||||
- **Secondary:** Dark background (`bg-white/5`), light text. Used for prev/next episode, filters.
|
||||
- **Hover:** Background shifts lighter (`bg-white/10`). Transition duration 200ms.
|
||||
|
||||
### Cards / Anime Grid
|
||||
- **Corner Style:** No radius. Square corners.
|
||||
- **Background:** None at rest. Dark image placeholder (`bg-white/5`) behind anime poster.
|
||||
- **Hover:** Overlay appears (`bg-black/80`) revealing title, synopsis, and watchlist button.
|
||||
- **Internal Padding:** 12px (main content), 8px (card hover overlay).
|
||||
|
||||
### Navigation (Sidebar)
|
||||
- **Style:** Fixed width (256px), collapsible to icons only.
|
||||
- **Default:** Text in `foreground-muted` (`#6a6b70`), no background.
|
||||
- **Hover:** `bg-white/5`.
|
||||
- **Active:** Left accent border (`w-0.5 bg-accent`), accent text color. Subtle glow (`shadow-[0_0_8px_rgba(159,122,234,0.6)]`).
|
||||
|
||||
### Dropdowns
|
||||
- **Background:** `#1a1a1a` with shadow.
|
||||
- **No radius.** Sharp corners.
|
||||
- **Items:** 12px vertical padding, hover `bg-white/10`.
|
||||
|
||||
### Input Fields
|
||||
- **Style:** `bg-white/5`, `border-transparent`, 8px vertical padding.
|
||||
- **Focus:** Border shifts to accent color (`focus:border-accent`).
|
||||
|
||||
### Toast Notifications
|
||||
- **Style:** Monochromatic, no color coding by type.
|
||||
- **Background:** `bg-white/10` with `border-white/20`.
|
||||
- **No rounded corners.**
|
||||
|
||||
## 6. Do's and Don'ts
|
||||
|
||||
### Do:
|
||||
- **Do** use accent purple for primary actions and active states only.
|
||||
- **Do** keep interfaces dark by default—lighter backgrounds are for special emphasis only.
|
||||
- **Do** use weight contrast (semibold headings, normal body) for hierarchy.
|
||||
- **Do** reveal detail on hover (anime cards, navigation).
|
||||
- **Do** include back buttons on detail pages.
|
||||
|
||||
### Don't:
|
||||
- **Don't** use rounded corners anywhere.
|
||||
- **Don't** use color to differentiate toast types—all toasts look the same.
|
||||
- **Don't** use gradient text.
|
||||
- **Don't** use glassmorphism (blur backgrounds, transparency effects).
|
||||
- **Don't** use hero metric layouts (big number + small label).
|
||||
- **Don't** use identical card grids with no visual variation.
|
||||
- **Don't** use modals as a first thought—inline and progressive disclosure preferred.
|
||||
- **Don't** use side-stripe borders (colored left/right borders on cards).
|
||||
- **Don't** use the green accent—violet is the one and only accent.
|
||||
257
DESIGN_SYSTEM.md
257
DESIGN_SYSTEM.md
@@ -1,257 +0,0 @@
|
||||
# MAL Design System
|
||||
|
||||
## Overview
|
||||
|
||||
This design system is for the MAL anime streaming service. It provides reusable components, design tokens, and patterns for building consistent UI.
|
||||
|
||||
## Design Tokens
|
||||
|
||||
### Colors
|
||||
|
||||
| Token | Value | Usage |
|
||||
|-------|-------|-------|
|
||||
| `--color-background` | `#080808` | Main page background |
|
||||
| `--color-background-sidebar` | `#0f0f0f` | Sidebar background |
|
||||
| `--color-background-header` | `#141414` | Sticky header |
|
||||
| `--color-background-surface` | `#202020` | Cards, dropdowns |
|
||||
| `--color-background-button` | `#1a1a1a` | Button default state |
|
||||
| `--color-background-button-hover` | `#252525` | Button hover state |
|
||||
| `--color-foreground-muted` | `#6a6b70` | Secondary text, icons |
|
||||
| `--color-foreground` | `#f8f9fa` | Primary text |
|
||||
| `--color-accent` | `#9f7aea` | Primary accent (violet) |
|
||||
| `--color-danger` | `#dc2626` | Error states, delete actions |
|
||||
|
||||
### Typography
|
||||
|
||||
| Role | Font | Size | Weight |
|
||||
|------|------|------|--------|
|
||||
| Title | DM Sans | 20px | 600 |
|
||||
| Body | DM Sans | 14px | 400 |
|
||||
| Label | DM Sans | 14px | 500 |
|
||||
| Small | DM Sans | 12px | 400 |
|
||||
|
||||
### Spacing
|
||||
|
||||
| Token | Value |
|
||||
|-------|-------|
|
||||
| `--space-1` | 0.25rem |
|
||||
| `--space-2` | 0.5rem |
|
||||
| `--space-3` | 0.75rem |
|
||||
| `--space-4` | 1rem |
|
||||
| `--space-5` | 1.25rem |
|
||||
| `--space-6` | 1.5rem |
|
||||
| `--space-8` | 2rem |
|
||||
|
||||
## Components
|
||||
|
||||
### 1. Anime Card (`anime_card.gohtml`)
|
||||
|
||||
A poster card with hover reveal.
|
||||
|
||||
**Usage:**
|
||||
```gohtml
|
||||
{{template "anime_card" dict "Anime" . "WithActions" true "IsWatchlist" false}}
|
||||
```
|
||||
|
||||
**Props:**
|
||||
- `Anime` - Anime data object
|
||||
- `WithActions` - Show hover overlay with actions (bool)
|
||||
- `IsWatchlist` - Show in-watchlist state (bool)
|
||||
- `Compact` - Hide metadata below (bool)
|
||||
- `HideTitle` - Hide title below image (bool)
|
||||
- `HasTopBadge` - Adjust overlay padding for badge (bool)
|
||||
|
||||
**States:**
|
||||
- Default: Image with subtle dark placeholder
|
||||
- Hover: Black overlay (80%) reveals title, synopsis, watchlist button
|
||||
|
||||
### 2. Navigation (`navigation.gohtml`)
|
||||
|
||||
Sidebar navigation with active indicator.
|
||||
|
||||
**Usage:**
|
||||
```gohtml
|
||||
{{template "navigation" dict "CurrentPath" .CurrentPath}}
|
||||
```
|
||||
|
||||
**Props:**
|
||||
- `CurrentPath` - Current page path for active state
|
||||
|
||||
**Items:**
|
||||
- Home (`/`)
|
||||
- Browse (`/browse`)
|
||||
- Discover (`/discover`)
|
||||
- Watchlist (`/watchlist`)
|
||||
|
||||
**States:**
|
||||
- Default: Muted gray text
|
||||
- Hover: `bg-white/5`
|
||||
- Active: Accent text + left border (`w-0.5 bg-accent`) + subtle glow
|
||||
|
||||
### 3. Dropdown (`dropdown.gohtml`)
|
||||
|
||||
Custom dropdown using `<ui-dropdown>` web component.
|
||||
|
||||
**Usage:**
|
||||
```gohtml
|
||||
<ui-dropdown class="relative block" data-align="left" data-width="w-48">
|
||||
<div data-trigger>
|
||||
<button>Trigger</button>
|
||||
</div>
|
||||
<div data-content class="hidden absolute ...">
|
||||
<button>Option 1</button>
|
||||
<button>Option 2</button>
|
||||
</div>
|
||||
</ui-dropdown>
|
||||
```
|
||||
|
||||
**Attributes:**
|
||||
- `data-align` - `left` or `right` alignment
|
||||
- `data-width` - Width (Tailwind class)
|
||||
|
||||
**Styling:**
|
||||
- Background: `#1a1a1a`
|
||||
- No border radius
|
||||
- Items: 10px vertical padding, hover `bg-white/10`
|
||||
|
||||
### 4. Filter Bar (`filter_bar.gohtml`)
|
||||
|
||||
Search and filter controls for browse page.
|
||||
|
||||
**Usage:**
|
||||
```gohtml
|
||||
{{template "filter_bar" .}}
|
||||
```
|
||||
|
||||
**Controls:**
|
||||
- Search input (text)
|
||||
- Genre dropdown (multi-select)
|
||||
- Status dropdown (airing, complete, upcoming)
|
||||
- Type dropdown (tv, movie, ova, special, ona)
|
||||
- Sort dropdown + order toggle
|
||||
|
||||
### 5. Header (`header.gohtml`)
|
||||
|
||||
Sticky header with logo, search, and user menu.
|
||||
|
||||
**Usage:**
|
||||
```gohtml
|
||||
{{template "header" .}}
|
||||
```
|
||||
|
||||
**Sections:**
|
||||
- Left: Mobile menu toggle, sidebar toggle, logo
|
||||
- Center: Search input (desktop only)
|
||||
- Right: User avatar dropdown
|
||||
|
||||
### 6. Watchlist Actions (`watchlist_actions.gohtml`)
|
||||
|
||||
Watchlist toggle button.
|
||||
|
||||
**Usage:**
|
||||
```gohtml
|
||||
{{template "watchlist_actions" dict "MalID" 123 "IsWatchlist" true}}
|
||||
```
|
||||
|
||||
**Props:**
|
||||
- `MalID` - Anime MAL ID
|
||||
- `IsWatchlist` - Current state
|
||||
|
||||
**States:**
|
||||
- Not in watchlist: Outline icon, accent on hover
|
||||
- In watchlist: Filled icon (`fill: currentColor`)
|
||||
|
||||
### 7. Video Player (`video_player.gohtml`)
|
||||
|
||||
Video player container for episodes.
|
||||
|
||||
**Usage:**
|
||||
```gohtml
|
||||
{{template "video_player" dict "WatchData" .WatchData "TotalEpisodes" .Anime.Episodes}}
|
||||
```
|
||||
|
||||
**Props:**
|
||||
- `WatchData` - Video source data
|
||||
- `TotalEpisodes` - Total episode count
|
||||
|
||||
### 8. Continue Watching (`continue_watching.gohtml`)
|
||||
|
||||
Horizontal row for continue watching section.
|
||||
|
||||
**Usage:**
|
||||
```gohtml
|
||||
{{template "continue_watching" .ContinueWatching}}
|
||||
```
|
||||
|
||||
**Props:**
|
||||
- Array of anime with watch progress
|
||||
|
||||
## Patterns
|
||||
|
||||
### Button Variants
|
||||
|
||||
**Primary:**
|
||||
```html
|
||||
<button class="bg-accent text-black px-4 py-2">Action</button>
|
||||
```
|
||||
|
||||
**Secondary:**
|
||||
```html
|
||||
<button class="bg-white/5 text-neutral-300 px-4 py-2 hover:bg-white/10">Action</button>
|
||||
```
|
||||
|
||||
**Danger:**
|
||||
```html
|
||||
<button class="bg-red-500/10 text-red-400 px-4 py-2 hover:bg-red-500/20">Delete</button>
|
||||
```
|
||||
|
||||
### Empty State
|
||||
|
||||
```html
|
||||
<div class="flex flex-col items-center justify-center gap-4 py-24">
|
||||
<svg class="h-16 w-16 opacity-30">...</svg>
|
||||
<p class="text-neutral-300 font-medium">Title</p>
|
||||
<p class="text-neutral-500 text-sm">Description</p>
|
||||
<div class="flex gap-3 mt-2">
|
||||
<a class="bg-accent/20 text-accent px-5 py-2.5">Action</a>
|
||||
<a class="bg-white/10 text-neutral-200 px-5 py-2.5">Secondary</a>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Card Grid
|
||||
|
||||
```html
|
||||
<div class="grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4 2xl:grid-cols-6">
|
||||
<!-- Cards -->
|
||||
</div>
|
||||
```
|
||||
|
||||
### Episode List Item
|
||||
|
||||
```html
|
||||
<a class="flex items-center gap-3 px-3 py-2 hover:bg-white/5 border-l-2 {{if .Filler}}border-l-yellow-500{{end}} {{if .Recap}}border-l-blue-500{{end}} {{if $isCurrent}}bg-accent/20{{end}}">
|
||||
<span class="w-10 shrink-0 text-xs font-medium text-neutral-500">EP{{.MalID}}</span>
|
||||
<span class="truncate text-sm text-neutral-300">{{.Title}}</span>
|
||||
</a>
|
||||
```
|
||||
|
||||
## Migration Guide
|
||||
|
||||
### Adding a New Component
|
||||
|
||||
1. Create template in `templates/components/`
|
||||
2. Document props and usage in this file
|
||||
3. Add to component index above
|
||||
|
||||
### Updating Existing Components
|
||||
|
||||
1. Make changes in `templates/components/`
|
||||
2. Update this documentation
|
||||
3. Test across all usage sites
|
||||
|
||||
### Design Token Changes
|
||||
|
||||
1. Update in `static/style.css`
|
||||
2. Update YAML frontmatter in `DESIGN.md`
|
||||
3. Update this token reference
|
||||
33
PRODUCT.md
33
PRODUCT.md
@@ -1,33 +0,0 @@
|
||||
# MAL - Anime Streaming & Watchlist Service
|
||||
|
||||
## Product Purpose
|
||||
Personal anime streaming service with watchlist management for me and my friends. Simple, functional, easy to navigate.
|
||||
|
||||
## Users
|
||||
- **Primary**: Me (owner)
|
||||
- **Secondary**: Close friends with access
|
||||
- Technical comfort: Medium - comfortable with self-hosted services
|
||||
|
||||
## Brand Tone
|
||||
- **Practical**: No fluff, just works
|
||||
- **Clean**: Minimal aesthetic, functional over decorative
|
||||
- **Personal**: Built for us, not for distribution
|
||||
|
||||
## Design Principles
|
||||
1. **Easy to maneuver** - Clear navigation, predictable patterns
|
||||
2. **Content-first** - Anime artwork and details take precedence
|
||||
3. **Fast interactions** - HTMX for snappy partial updates
|
||||
4. **Dark theme default** - Easy on eyes for long viewing sessions
|
||||
|
||||
## Anti-References
|
||||
- No anime list sites (MyAnimeList, AniList clones)
|
||||
- No generic SaaS dashboards
|
||||
- No "AI slop" aesthetics - gradient text, glassmorphism, hero metrics
|
||||
|
||||
## Register
|
||||
**Product** - Design serves the utility, not the reverse.
|
||||
|
||||
## Technical Stack
|
||||
- Go backend (HTMX for interactivity)
|
||||
- Tailwind CSS
|
||||
- No JavaScript framework - vanilla JS only
|
||||
Reference in New Issue
Block a user