257 lines
6.1 KiB
Markdown
257 lines
6.1 KiB
Markdown
# 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 |