@stylecrib/cli 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -9
- package/agents/MANIFEST.yml +136 -0
- package/agents/README.md +75 -0
- package/agents/art-director.md +168 -0
- package/agents/audacity-director.md +109 -0
- package/agents/brand-identity.md +179 -0
- package/agents/brand-precedent.md +119 -0
- package/agents/brief-enforcer.md +136 -0
- package/agents/component-qa.md +167 -0
- package/agents/cto.md +49 -0
- package/agents/design-director.md +184 -0
- package/agents/design-systems-engineer.md +162 -0
- package/agents/direction-curator.md +133 -0
- package/agents/homogeneity-detector.md +104 -0
- package/agents/logo-designer.md +240 -0
- package/agents/marketing-designer.md +156 -0
- package/agents/media-curator.md +165 -0
- package/agents/motion-engineer.md +270 -0
- package/agents/qa-conductor.md +143 -0
- package/agents/render-qa.md +133 -0
- package/agents/upgrade-simulator.md +123 -0
- package/agents/vp-architecture.md +49 -0
- package/agents/vp-engineering.md +49 -0
- package/dist/index.js +1606 -467
- package/package.json +12 -4
- package/themes/README.md +70 -0
- package/themes/acrylic-soft/THEME.md +142 -0
- package/themes/acrylic-soft/tokens.ts +180 -0
- package/themes/agency-creative/THEME.md +91 -0
- package/themes/agency-creative/tokens.ts +202 -0
- package/themes/agency-portfolio/THEME.md +109 -0
- package/themes/agency-portfolio/tokens.ts +159 -0
- package/themes/ai-startup/THEME.md +95 -0
- package/themes/ai-startup/tokens.ts +162 -0
- package/themes/airline-modern/THEME.md +104 -0
- package/themes/airline-modern/tokens.ts +179 -0
- package/themes/arc-stack/THEME.md +125 -0
- package/themes/arc-stack/tailwind.snippet.ts +17 -0
- package/themes/arc-stack/theme.yml +153 -0
- package/themes/arc-stack/tokens.ts +29 -0
- package/themes/architectural/THEME.md +102 -0
- package/themes/architectural/tokens.ts +159 -0
- package/themes/atelier-radiance/THEME.md +93 -0
- package/themes/atelier-radiance/tailwind.snippet.ts +15 -0
- package/themes/atelier-radiance/theme.yml +130 -0
- package/themes/atelier-radiance/tokens.ts +29 -0
- package/themes/automotive-ev/THEME.md +87 -0
- package/themes/automotive-ev/tokens.ts +183 -0
- package/themes/automotive-luxury/THEME.md +88 -0
- package/themes/automotive-luxury/tokens.ts +175 -0
- package/themes/baby-modern/THEME.md +79 -0
- package/themes/baby-modern/tokens.ts +184 -0
- package/themes/banking-gravity/THEME.md +171 -0
- package/themes/banking-gravity/tokens.ts +169 -0
- package/themes/beauty-clean/THEME.md +92 -0
- package/themes/beauty-clean/tokens.ts +176 -0
- package/themes/beauty-luxury/THEME.md +96 -0
- package/themes/beauty-luxury/tokens.ts +178 -0
- package/themes/bento-modular/BUILD_BRIEF.md +171 -0
- package/themes/bento-modular/THEME.md +80 -0
- package/themes/bento-modular/tailwind.snippet.ts +17 -0
- package/themes/bento-modular/theme.yml +83 -0
- package/themes/bento-modular/tokens.ts +27 -0
- package/themes/bookstore-indie/THEME.md +78 -0
- package/themes/bookstore-indie/tokens.ts +147 -0
- package/themes/brutalist/THEME.md +96 -0
- package/themes/brutalist/tokens.ts +151 -0
- package/themes/business-tiles/THEME.md +141 -0
- package/themes/business-tiles/tokens.ts +178 -0
- package/themes/cabana-poster/THEME.md +158 -0
- package/themes/cabana-poster/tailwind.snippet.ts +16 -0
- package/themes/cabana-poster/theme.yml +221 -0
- package/themes/cabana-poster/tokens.ts +34 -0
- package/themes/case-panel/THEME.md +126 -0
- package/themes/case-panel/tailwind.snippet.ts +15 -0
- package/themes/case-panel/theme.yml +153 -0
- package/themes/case-panel/tokens.ts +28 -0
- package/themes/cinematic-dark/THEME.md +97 -0
- package/themes/cinematic-dark/tokens.ts +195 -0
- package/themes/classic-car/THEME.md +86 -0
- package/themes/classic-car/tokens.ts +173 -0
- package/themes/cloud-friendly/THEME.md +152 -0
- package/themes/cloud-friendly/tokens.ts +181 -0
- package/themes/community-niche/THEME.md +102 -0
- package/themes/community-niche/tokens.ts +177 -0
- package/themes/corporate-grid/THEME.md +154 -0
- package/themes/corporate-grid/tokens.ts +182 -0
- package/themes/couture-luxury/THEME.md +85 -0
- package/themes/couture-luxury/tokens.ts +146 -0
- package/themes/creator-social/THEME.md +131 -0
- package/themes/creator-social/tokens.ts +249 -0
- package/themes/crypto-onchain/THEME.md +100 -0
- package/themes/crypto-onchain/tokens.ts +207 -0
- package/themes/cycling-brand/THEME.md +78 -0
- package/themes/cycling-brand/tokens.ts +185 -0
- package/themes/dating-friendly/THEME.md +102 -0
- package/themes/dating-friendly/tokens.ts +178 -0
- package/themes/dense-utility/THEME.md +85 -0
- package/themes/dense-utility/tokens.ts +155 -0
- package/themes/devtool-cli/THEME.md +100 -0
- package/themes/devtool-cli/tokens.ts +195 -0
- package/themes/devtool-docs/THEME.md +105 -0
- package/themes/devtool-docs/tokens.ts +177 -0
- package/themes/editorial/THEME.md +129 -0
- package/themes/editorial/tailwind.snippet.ts +15 -0
- package/themes/editorial/theme.yml +173 -0
- package/themes/editorial/tokens.ts +29 -0
- package/themes/education-formal/THEME.md +154 -0
- package/themes/education-formal/tailwind.snippet.ts +15 -0
- package/themes/education-formal/theme.yml +186 -0
- package/themes/education-formal/tokens.ts +29 -0
- package/themes/education-warm/THEME.md +91 -0
- package/themes/education-warm/tokens.ts +185 -0
- package/themes/ember-poster/README.md +79 -0
- package/themes/ember-poster/THEME.md +101 -0
- package/themes/ember-poster/package.json +34 -0
- package/themes/ember-poster/tailwind.snippet.ts +17 -0
- package/themes/ember-poster/theme.yml +109 -0
- package/themes/ember-poster/tokens.ts +27 -0
- package/themes/enterprise-cloud/THEME.md +139 -0
- package/themes/enterprise-cloud/tokens.ts +179 -0
- package/themes/enterprise-tech/THEME.md +167 -0
- package/themes/enterprise-tech/tailwind.snippet.ts +15 -0
- package/themes/enterprise-tech/theme.yml +202 -0
- package/themes/enterprise-tech/tokens.ts +29 -0
- package/themes/ev-charging/THEME.md +94 -0
- package/themes/ev-charging/tokens.ts +185 -0
- package/themes/farm-direct/THEME.md +92 -0
- package/themes/farm-direct/tokens.ts +180 -0
- package/themes/fintech-card/THEME.md +96 -0
- package/themes/fintech-card/tokens.ts +191 -0
- package/themes/fintech-trust/THEME.md +94 -0
- package/themes/fintech-trust/tokens.ts +192 -0
- package/themes/food-blog/THEME.md +98 -0
- package/themes/food-blog/tokens.ts +183 -0
- package/themes/forum-classic/THEME.md +100 -0
- package/themes/forum-classic/tokens.ts +168 -0
- package/themes/fresh-plate/THEME.md +144 -0
- package/themes/fresh-plate/tailwind.snippet.ts +16 -0
- package/themes/fresh-plate/theme.yml +189 -0
- package/themes/fresh-plate/tokens.ts +30 -0
- package/themes/furniture-modern/THEME.md +94 -0
- package/themes/furniture-modern/tokens.ts +176 -0
- package/themes/gaming-esports/THEME.md +146 -0
- package/themes/gaming-esports/tokens.ts +199 -0
- package/themes/gaming-streamer/THEME.md +139 -0
- package/themes/gaming-streamer/tokens.ts +201 -0
- package/themes/glassmorphic-modern/THEME.md +119 -0
- package/themes/glassmorphic-modern/tokens.ts +174 -0
- package/themes/government-civic/THEME.md +138 -0
- package/themes/government-civic/tokens.ts +164 -0
- package/themes/gym-chain/THEME.md +79 -0
- package/themes/gym-chain/tokens.ts +196 -0
- package/themes/healthcare-bright/THEME.md +95 -0
- package/themes/healthcare-bright/tokens.ts +184 -0
- package/themes/home-decor/THEME.md +94 -0
- package/themes/home-decor/tokens.ts +177 -0
- package/themes/hotel-boutique/THEME.md +110 -0
- package/themes/hotel-boutique/tokens.ts +179 -0
- package/themes/hyperminimal-mono/THEME.md +91 -0
- package/themes/hyperminimal-mono/tokens.ts +150 -0
- package/themes/indie-art-game/THEME.md +107 -0
- package/themes/indie-art-game/tokens.ts +216 -0
- package/themes/insurance-legacy/THEME.md +101 -0
- package/themes/insurance-legacy/tokens.ts +182 -0
- package/themes/insurance-modern/THEME.md +103 -0
- package/themes/insurance-modern/tokens.ts +192 -0
- package/themes/kaiju-reveal/THEME.md +97 -0
- package/themes/kaiju-reveal/tokens.ts +185 -0
- package/themes/kinetic-data/THEME.md +172 -0
- package/themes/kinetic-data/tailwind.snippet.ts +16 -0
- package/themes/kinetic-data/theme.yml +207 -0
- package/themes/kinetic-data/tokens.ts +30 -0
- package/themes/kinetic-headline/BUILD_BRIEF.md +156 -0
- package/themes/kinetic-headline/THEME.md +78 -0
- package/themes/kinetic-headline/tailwind.snippet.ts +16 -0
- package/themes/kinetic-headline/theme.yml +81 -0
- package/themes/kinetic-headline/tokens.ts +26 -0
- package/themes/law-firm/THEME.md +108 -0
- package/themes/law-firm/tokens.ts +158 -0
- package/themes/lawtech-modern/THEME.md +107 -0
- package/themes/lawtech-modern/tokens.ts +192 -0
- package/themes/linkedin-pro/THEME.md +102 -0
- package/themes/linkedin-pro/tokens.ts +174 -0
- package/themes/logistics-modern/THEME.md +94 -0
- package/themes/logistics-modern/tokens.ts +187 -0
- package/themes/magazine-glossy/THEME.md +74 -0
- package/themes/magazine-glossy/tokens.ts +158 -0
- package/themes/marker-mag/THEME.md +128 -0
- package/themes/marker-mag/tailwind.snippet.ts +15 -0
- package/themes/marker-mag/theme.yml +159 -0
- package/themes/marker-mag/tokens.ts +27 -0
- package/themes/marketplace-modern/THEME.md +135 -0
- package/themes/marketplace-modern/tokens.ts +186 -0
- package/themes/marketplace-vintage/THEME.md +110 -0
- package/themes/marketplace-vintage/tokens.ts +185 -0
- package/themes/maximalist/THEME.md +96 -0
- package/themes/maximalist/tokens.ts +168 -0
- package/themes/mid-century/THEME.md +109 -0
- package/themes/mid-century/tokens.ts +162 -0
- package/themes/motorcycle-brand/THEME.md +86 -0
- package/themes/motorcycle-brand/tokens.ts +174 -0
- package/themes/museum/THEME.md +83 -0
- package/themes/museum/tokens.ts +147 -0
- package/themes/music-streaming/THEME.md +101 -0
- package/themes/music-streaming/tokens.ts +187 -0
- package/themes/music-vinyl/THEME.md +98 -0
- package/themes/music-vinyl/tokens.ts +167 -0
- package/themes/nature-distilled/BUILD_BRIEF.md +158 -0
- package/themes/nature-distilled/THEME.md +81 -0
- package/themes/nature-distilled/tailwind.snippet.ts +16 -0
- package/themes/nature-distilled/theme.yml +91 -0
- package/themes/nature-distilled/tokens.ts +26 -0
- package/themes/news-tabloid/THEME.md +72 -0
- package/themes/news-tabloid/tokens.ts +158 -0
- package/themes/news-tech/THEME.md +75 -0
- package/themes/news-tech/tokens.ts +149 -0
- package/themes/newsletter/THEME.md +82 -0
- package/themes/newsletter/tokens.ts +138 -0
- package/themes/newspaper-classic/THEME.md +74 -0
- package/themes/newspaper-classic/tokens.ts +159 -0
- package/themes/nonprofit-arts/THEME.md +78 -0
- package/themes/nonprofit-arts/tokens.ts +157 -0
- package/themes/nonprofit-warm/THEME.md +105 -0
- package/themes/nonprofit-warm/tokens.ts +188 -0
- package/themes/outdoor-adventure/THEME.md +113 -0
- package/themes/outdoor-adventure/tokens.ts +181 -0
- package/themes/overland-broadside/THEME.md +119 -0
- package/themes/overland-broadside/tailwind.snippet.ts +17 -0
- package/themes/overland-broadside/theme.yml +138 -0
- package/themes/overland-broadside/tokens.ts +27 -0
- package/themes/performance-engineered/THEME.md +162 -0
- package/themes/performance-engineered/tailwind.snippet.ts +15 -0
- package/themes/performance-engineered/theme.yml +193 -0
- package/themes/performance-engineered/tokens.ts +29 -0
- package/themes/pet-food/THEME.md +78 -0
- package/themes/pet-food/tokens.ts +185 -0
- package/themes/pharma-clinical/THEME.md +164 -0
- package/themes/pharma-clinical/tailwind.snippet.ts +15 -0
- package/themes/pharma-clinical/theme.yml +201 -0
- package/themes/pharma-clinical/tokens.ts +29 -0
- package/themes/pill-editorial/THEME.md +125 -0
- package/themes/pill-editorial/tailwind.snippet.ts +15 -0
- package/themes/pill-editorial/theme.yml +168 -0
- package/themes/pill-editorial/tokens.ts +31 -0
- package/themes/podcast-warm/THEME.md +103 -0
- package/themes/podcast-warm/tokens.ts +192 -0
- package/themes/publisher-indie/THEME.md +78 -0
- package/themes/publisher-indie/tokens.ts +148 -0
- package/themes/raw-concrete/BUILD_BRIEF.md +157 -0
- package/themes/raw-concrete/THEME.md +76 -0
- package/themes/raw-concrete/tailwind.snippet.ts +16 -0
- package/themes/raw-concrete/theme.yml +88 -0
- package/themes/raw-concrete/tokens.ts +27 -0
- package/themes/realestate-luxury/THEME.md +94 -0
- package/themes/realestate-luxury/tokens.ts +169 -0
- package/themes/realestate-marketplace/THEME.md +106 -0
- package/themes/realestate-marketplace/tokens.ts +183 -0
- package/themes/restaurant-modern/THEME.md +109 -0
- package/themes/restaurant-modern/tokens.ts +172 -0
- package/themes/runway-fashion/THEME.md +99 -0
- package/themes/runway-fashion/tokens.ts +167 -0
- package/themes/saturday-morning/THEME.md +117 -0
- package/themes/saturday-morning/tokens.ts +281 -0
- package/themes/schema.ts +235 -0
- package/themes/signal-dark/BUILD_BRIEF.md +168 -0
- package/themes/signal-dark/THEME.md +107 -0
- package/themes/signal-dark/tokens.ts +181 -0
- package/themes/soft-modern/THEME.md +91 -0
- package/themes/soft-modern/tokens.ts +166 -0
- package/themes/solar-residential/THEME.md +92 -0
- package/themes/solar-residential/tokens.ts +176 -0
- package/themes/sports-league/THEME.md +180 -0
- package/themes/sports-league/tailwind.snippet.ts +15 -0
- package/themes/sports-league/theme.yml +213 -0
- package/themes/sports-league/tokens.ts +32 -0
- package/themes/stadium-sport/THEME.md +114 -0
- package/themes/stadium-sport/tokens.ts +187 -0
- package/themes/streetwear-hype/THEME.md +100 -0
- package/themes/streetwear-hype/tokens.ts +174 -0
- package/themes/studio-architect/THEME.md +108 -0
- package/themes/studio-architect/tokens.ts +162 -0
- package/themes/studio-photographer/THEME.md +88 -0
- package/themes/studio-photographer/tokens.ts +164 -0
- package/themes/team-kanban/THEME.md +167 -0
- package/themes/team-kanban/tailwind.snippet.ts +15 -0
- package/themes/team-kanban/theme.yml +209 -0
- package/themes/team-kanban/tokens.ts +35 -0
- package/themes/telehealth-modern/THEME.md +95 -0
- package/themes/telehealth-modern/tokens.ts +197 -0
- package/themes/tourism-board/THEME.md +111 -0
- package/themes/tourism-board/tokens.ts +173 -0
- package/themes/toys-modern/THEME.md +79 -0
- package/themes/toys-modern/tokens.ts +200 -0
- package/themes/travel-luxury/THEME.md +95 -0
- package/themes/travel-luxury/tokens.ts +162 -0
- package/themes/vacation-rental/THEME.md +105 -0
- package/themes/vacation-rental/tokens.ts +174 -0
- package/themes/vault-reel/THEME.md +134 -0
- package/themes/vault-reel/tailwind.snippet.ts +16 -0
- package/themes/vault-reel/theme.yml +167 -0
- package/themes/vault-reel/tokens.ts +30 -0
- package/themes/vet-modern/THEME.md +79 -0
- package/themes/vet-modern/tokens.ts +194 -0
- package/themes/web3-restraint/THEME.md +87 -0
- package/themes/web3-restraint/tokens.ts +154 -0
- package/themes/wellness-active/THEME.md +102 -0
- package/themes/wellness-active/tokens.ts +203 -0
- package/themes/wellness-spa/THEME.md +93 -0
- package/themes/wellness-spa/tokens.ts +173 -0
- package/themes/y2k-chrome/THEME.md +118 -0
- package/themes/y2k-chrome/tokens.ts +249 -0
- package/themes/yoga-studio/THEME.md +76 -0
- package/themes/yoga-studio/tokens.ts +163 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Design Direction — Music-Streaming
|
|
2
|
+
|
|
3
|
+
## Ethos
|
|
4
|
+
Spotify black canvas · Apple Music album-art hero · Tidal Hi-Fi audiophile blue · Bandcamp Daily editorial weight · SoundCloud waveform energy
|
|
5
|
+
|
|
6
|
+
## Feel
|
|
7
|
+
Near-black canvas that disappears behind oversized album art. Brand-green signal mark, geometric sans body, condensed numerals for runtimes and bitrates. Reads like lean-back playback — the artwork is the page, the chrome is a thin shell that gets out of the way. The page is the album cover, not the player UI.
|
|
8
|
+
|
|
9
|
+
## Reference brands
|
|
10
|
+
- **Spotify** → black canvas with green signal mark and Circular sans. The single-color play-button is the most-recognized affordance in the category.
|
|
11
|
+
- **Apple Music** → deep dark with SF Pro and album art as the hero element. The cover is the design.
|
|
12
|
+
- **Tidal Hi-Fi** → deep blue-black with audiophile blue accent and dense type. Hi-Res badges as tertiary chrome.
|
|
13
|
+
- **Bandcamp Daily** → editorial weight inside a dark player chrome. Long reads sit beside playable embeds.
|
|
14
|
+
- **SoundCloud** → waveform iconography and orange signal accent. The waveform is the timeline.
|
|
15
|
+
|
|
16
|
+
## Tokens
|
|
17
|
+
All tokens live in `src/index.css` as HSL triples. Every token's `from:` comment names its brand origin. Do not introduce numbered or generic tokens — if a new color is needed, name a brand it traces to.
|
|
18
|
+
|
|
19
|
+
Surface stack is **canvas-black** (background, HSL `0 0% 7%` — Spotify #121212 equivalent) → **card** at `0 0% 11%` (one stop above) → **popover** at `0 0% 14%` (two stops above). Depth comes from elevation, never from hue shift between tiers.
|
|
20
|
+
|
|
21
|
+
Brand tokens: `--signal-green` (the canonical play color), `--audiophile-blue` (Tidal Hi-Res accent), `--waveform-orange` (SoundCloud secondary), `--vinyl-cream` (Bandcamp editorial pop-in), `--canvas-black`, `--now-playing` (alias of signal-green). Primary is `--signal-green` — never use it for non-playback actions.
|
|
22
|
+
|
|
23
|
+
## Typography
|
|
24
|
+
- **Display:** Manrope (Spotify Circular substitute). Headings and album-title scale. Tracking `-0.02em` — tight, "Now Playing" feel.
|
|
25
|
+
- **Body:** Inter (Apple Music SF Pro substitute). Body base **15px** with **line-height 1.55** — denser than editorial, sized to Spotify track-row scale.
|
|
26
|
+
- **Mono:** JetBrains Mono. Runtimes, bitrates, BPM, sample rates — tabular numerics with `tnum` on.
|
|
27
|
+
|
|
28
|
+
H1 uses `clamp(2.5rem, 7vw, 5.5rem)`. Display headings often paired with adjacent oversized album-art at 1:1 aspect. Font features: `"ss01"`, `"ss02"`, `"tnum"`, `"cv11"`.
|
|
29
|
+
|
|
30
|
+
## Spacing
|
|
31
|
+
- **Container:** `max-w-7xl px-4 lg:px-8` — wide; album-art grids and playlist tables need it.
|
|
32
|
+
- **Section padding tiers:**
|
|
33
|
+
- Hero: `pt-16 pb-12 lg:pt-24 lg:pb-16` (the album-art is full-bleed; section padding stays modest)
|
|
34
|
+
- Default: `py-12 lg:py-20`
|
|
35
|
+
- Tight: `py-8 lg:py-12`
|
|
36
|
+
- **Allowed scale values:** 4 8 12 16 20 24 32 40 48 64 80 96 128. No arbitrary spacing.
|
|
37
|
+
|
|
38
|
+
## Color
|
|
39
|
+
No hex anywhere in component files. All color via tokens. Opacity via `/N` modifier on token. Pure black is forbidden — `--canvas-black` (`0 0% 7%`) replaces it; the slight lift off pure black is the entire reason the page feels warm rather than OLED-cold.
|
|
40
|
+
|
|
41
|
+
**Signal-green is reserved for playback affordances only.** Never use it for "Subscribe", "Sign up", or non-play CTAs — that ruins the play-button signal across the page. For non-playback hero actions, use foreground-color text-links or App Store badges.
|
|
42
|
+
|
|
43
|
+
## Radius
|
|
44
|
+
`--radius: 0.5rem`. Soft-square — Spotify card and Apple Music tile corner radius. Pills are allowed (`pillsAllowed: true`) for genre chips, filter tags, and the hero play button which is a full circle for icon buttons or a `rounded-full` pill for labeled play CTAs.
|
|
45
|
+
|
|
46
|
+
## Shadows
|
|
47
|
+
**Glow style.** Three utilities:
|
|
48
|
+
- `.art-lift` — soft black drop behind album-art tiles, lifts cover on hover
|
|
49
|
+
- `.now-playing-glow` — signal-green ring + soft glow on the active playback card (single instance per page)
|
|
50
|
+
- `.row-hover` — ghost inner stroke on track-row hover, 1px white at 6% opacity
|
|
51
|
+
|
|
52
|
+
No saturated colored shadows beyond the signal-green now-playing-glow.
|
|
53
|
+
|
|
54
|
+
## Motion
|
|
55
|
+
Five keyframes, all serve playback:
|
|
56
|
+
- `art-fade` (400ms) — album-art tile reveal as covers load; gentle scale-up from 0.98, no flash
|
|
57
|
+
- `equalizer` (1200ms infinite) — now-playing bar pulse, the canonical "this track is playing" indicator
|
|
58
|
+
- `play-pulse` (1800ms infinite) — primary play-button heartbeat ring on hero CTA, single instance per page
|
|
59
|
+
- `art-drift` (24000ms infinite) — blurred album-art backdrop drift behind hero, ambient
|
|
60
|
+
- `waveform-shimmer` (2400ms infinite) — SoundCloud-style waveform fill animation, used on the active scrubber bar only
|
|
61
|
+
|
|
62
|
+
Easing: `cubic-bezier(0.22, 1, 0.36, 1)`. `prefers-reduced-motion` is honored — every motion utility wrapped in a media query.
|
|
63
|
+
|
|
64
|
+
## Component patterns
|
|
65
|
+
- **Buttons:** primary play is a SOLID round signal-green circle with canvas-black play glyph — the iconic Spotify mark. Secondary controls (shuffle, repeat, queue) are ghost icon buttons in `--muted-foreground` that brighten to `--foreground` on hover. Text-link CTAs use foreground with underline-on-hover. **Never use green for non-playback actions.**
|
|
66
|
+
- **Cards:** album-art tile is the canonical card — a square cover image with title and artist text below, lifted by `.art-lift` on hover. Section cards use `bg-card`, 0.5rem radius, `p-4 lg:p-5`. No fill differentiation between cards on the same surface tier.
|
|
67
|
+
- **Inputs:** search is a `rounded-full` pill with `bg-input` and leading magnifier icon, no border. Focus shows 2px signal-green ring. Filter chips below are pills (`bg-secondary`, foreground text).
|
|
68
|
+
- **CTA links:** hero CTA is a solid signal-green pill with canvas-black label, optionally wrapped in `play-pulse`. Inline "Listen now" links are foreground-color underline-on-hover. App Store / Play Store badges for cross-platform.
|
|
69
|
+
|
|
70
|
+
## Recommended rich media
|
|
71
|
+
Music-streaming leans on **album artwork** as the primary visual asset — covers, not stock photography, not gradient illustration. The artwork is the design; everything else is chrome.
|
|
72
|
+
|
|
73
|
+
Lead media is **square album cover at 1:1 aspect, minimum 600×600 source** displayed at any size from a 64×64 row thumbnail to a full-bleed 1200×1200 hero. Behind the hero, a heavily blurred and saturated copy of the same album art often sits as a backdrop with `art-drift` animation — the Spotify "Now Playing" backdrop pattern. Never use generic music stock photos (headphones on a desk, vinyl in soft focus); those signal "this site doesn't have real catalog content".
|
|
74
|
+
|
|
75
|
+
**AI tool recommendations:** for placeholder album art when real catalog isn't available, **Midjourney** with prompts like *"square album cover artwork, [genre] aesthetic, minimal typographic mark, full bleed, 1:1"* — explicitly include "no text overlay" when you want clean covers. **Flux** for waveform overlays and abstract sound-art visualizations. Never generate "musicians performing" AI imagery — uncanny hands and instruments are a tell.
|
|
76
|
+
|
|
77
|
+
**Aspect ratios:** 1:1 square for covers (canonical). 16:9 only for video trailers and artist documentaries. 21:9 for full-bleed hero backdrops with blurred art. Never 4:5 (Instagram-portrait, off-feel for player chrome).
|
|
78
|
+
|
|
79
|
+
**Video:** muted-autoplay loops of waveform animation or abstract album-art motion are appropriate as ambient hero backdrops at ≤2 MB, H.265 or AV1. Always provide poster image. Music videos themselves are user-initiated only — never autoplay with sound.
|
|
80
|
+
|
|
81
|
+
**Waveform graphics:** SoundCloud-style horizontal waveforms are appropriate for scrubber/timeline UI. Use `.waveform-shimmer` on the played portion in `--signal-green`, unplayed portion in `--muted-foreground` at low opacity.
|
|
82
|
+
|
|
83
|
+
**Performance:** album-art thumbnails ≤30 KB AVIF at 600w; hero covers ≤120 KB at 1200w. Use blurhash placeholders during load — `art-fade` covers the transition. LCP under 2s with a single hero cover.
|
|
84
|
+
|
|
85
|
+
**Avoid:** stock musician/instrument photography, decorative SVG ornament, gradient backgrounds (soft-modern territory), glassmorphic player chrome (Apple-Music-style frosted glass is acceptable only as a sticky-bottom mini-player, never as full-page chrome), AI-generated "performing musicians" with uncanny hands or floating instruments.
|
|
86
|
+
|
|
87
|
+
**Accessibility:** album art always has alt-text in *"[Artist] — [Album]"* format. The `.now-playing-glow` element has `aria-live="polite"` with the current track. Equalizer animation has `aria-hidden="true"` — it's decorative, the now-playing text is the source of truth.
|
|
88
|
+
|
|
89
|
+
## Component families
|
|
90
|
+
None at install time. Family conventions emerge as the project grows; the Director appends them here as they're established. Expected first families: `TrackRow`, `AlbumTile`, `NowPlayingBar`, `PlaylistHeader`.
|
|
91
|
+
|
|
92
|
+
## Details
|
|
93
|
+
- **Selection:** `hsl(var(--signal-green) / 0.35)` background, foreground text.
|
|
94
|
+
- **Focus ring:** `2px solid hsl(var(--signal-green))`. Matches primary signal mark.
|
|
95
|
+
- **Scrollbar:** thin. Track-list virtualization expected for long playlists.
|
|
96
|
+
|
|
97
|
+
## Exceptions
|
|
98
|
+
None yet. When an intentional one-of-one violation lands, add it here with the reason. The Director's consistency pass lists all exceptions for human review.
|
|
99
|
+
|
|
100
|
+
## Revisions
|
|
101
|
+
- Initial direction, generated at install time.
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import type { Direction } from "../schema";
|
|
2
|
+
|
|
3
|
+
export const musicStreaming: Direction = {
|
|
4
|
+
name: "music-streaming",
|
|
5
|
+
ethos:
|
|
6
|
+
"Spotify black canvas · Apple Music album-art hero · Tidal Hi-Fi audiophile blue · Bandcamp Daily editorial weight · SoundCloud waveform energy",
|
|
7
|
+
references: [
|
|
8
|
+
{ brand: "Spotify", trait: "black canvas with green signal mark and Circular sans" },
|
|
9
|
+
{ brand: "Apple Music", trait: "deep dark with SF Pro and album art as the hero element" },
|
|
10
|
+
{ brand: "Tidal Hi-Fi", trait: "deep blue-black with audiophile blue accent and dense type" },
|
|
11
|
+
{ brand: "Bandcamp Daily", trait: "editorial weight inside a dark player chrome" },
|
|
12
|
+
{ brand: "SoundCloud", trait: "waveform iconography and orange signal accent" },
|
|
13
|
+
],
|
|
14
|
+
feel:
|
|
15
|
+
"Near-black canvas that disappears behind oversized album art. Brand-green signal mark, " +
|
|
16
|
+
"geometric sans body, condensed numerals for runtimes and bitrates. Reads like lean-back " +
|
|
17
|
+
"playback — the artwork is the page, the chrome is a thin shell that gets out of the way.",
|
|
18
|
+
|
|
19
|
+
fonts: {
|
|
20
|
+
display: {
|
|
21
|
+
family: "Manrope",
|
|
22
|
+
fallback: ["Inter", "system-ui", "-apple-system", "BlinkMacSystemFont", "sans-serif"],
|
|
23
|
+
from: "Spotify Circular substitute — geometric humanist sans, set tight at display sizes",
|
|
24
|
+
googleFont: "Manrope",
|
|
25
|
+
weights: [500, 700, 800],
|
|
26
|
+
},
|
|
27
|
+
body: {
|
|
28
|
+
family: "Inter",
|
|
29
|
+
fallback: ["system-ui", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "sans-serif"],
|
|
30
|
+
from: "Apple Music SF Pro substitute — neutral OS-feel body for track lists and metadata",
|
|
31
|
+
googleFont: "Inter",
|
|
32
|
+
weights: [400, 500, 600],
|
|
33
|
+
},
|
|
34
|
+
mono: {
|
|
35
|
+
family: "JetBrains Mono",
|
|
36
|
+
fallback: ["Berkeley Mono", "ui-monospace", "SFMono-Regular", "Consolas", "monospace"],
|
|
37
|
+
from: "Tidal Hi-Fi bitrate readouts and runtimes — tabular numerics for player metadata",
|
|
38
|
+
googleFont: "JetBrains+Mono",
|
|
39
|
+
weights: [400, 500],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
typography: {
|
|
44
|
+
headingTracking: "-0.02em", // album-title scale needs tight tracking — Spotify "Now Playing" feel
|
|
45
|
+
bodyTracking: "0",
|
|
46
|
+
fontFeatureSettings: '"ss01", "ss02", "tnum", "cv11"',
|
|
47
|
+
h1ScaleClamp: "clamp(2.5rem, 7vw, 5.5rem)", // big — album art adjacency
|
|
48
|
+
bodyBaseSize: "0.9375rem", // 15px — denser than editorial, Spotify-row scale
|
|
49
|
+
bodyLineHeight: "1.55",
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
colors: {
|
|
53
|
+
background: { hsl: "0 0% 7%", from: "Spotify black canvas — #121212 in HSL, a touch warmer than pure black" },
|
|
54
|
+
foreground: { hsl: "0 0% 98%", from: "Spotify near-white text — high contrast on the black canvas" },
|
|
55
|
+
card: { hsl: "0 0% 11%", from: "elevated player surface — Spotify card chrome, one stop above canvas" },
|
|
56
|
+
popover: { hsl: "0 0% 14%", from: "menu and tooltip surface — two stops above canvas" },
|
|
57
|
+
primary: { hsl: "141 73% 48%", from: "Spotify signal green — the canonical play-button mark" },
|
|
58
|
+
primaryForeground: { hsl: "0 0% 7%", from: "canvas-black on Spotify green for legibility on the play button" },
|
|
59
|
+
secondary: { hsl: "0 0% 16%", from: "row-hover surface — Spotify track-list hover chrome" },
|
|
60
|
+
secondaryForeground: { hsl: "0 0% 98%", from: "near-white on hover chrome" },
|
|
61
|
+
muted: { hsl: "0 0% 18%", from: "muted surface for inactive controls and divider panels" },
|
|
62
|
+
mutedForeground: { hsl: "0 0% 64%", from: "Spotify secondary text — metadata gray, runtime and artist subhead" },
|
|
63
|
+
accent: { hsl: "0 0% 20%", from: "active row chrome — Spotify selected-track background" },
|
|
64
|
+
accentForeground: { hsl: "0 0% 98%", from: "near-white on active row" },
|
|
65
|
+
border: { hsl: "0 0% 22%", from: "hairline divider between track rows — barely-there separator" },
|
|
66
|
+
input: { hsl: "0 0% 16%", from: "search and filter input surface — Spotify search bar chrome" },
|
|
67
|
+
ring: { hsl: "141 73% 48%", from: "Spotify green focus ring — matches primary signal mark" },
|
|
68
|
+
destructive: { hsl: "0 72% 51%", from: "remove-from-playlist red, distinct from any orange waveform accent" },
|
|
69
|
+
destructiveForeground: { hsl: "0 0% 98%", from: "near-white on destructive red" },
|
|
70
|
+
brand: {
|
|
71
|
+
"signal-green": { hsl: "141 73% 48%", from: "Spotify play-button green — the canonical playback signal" },
|
|
72
|
+
"audiophile-blue": { hsl: "210 100% 56%", from: "Tidal Hi-Fi blue — used on quality badges and now-playing accents" },
|
|
73
|
+
"waveform-orange": { hsl: "18 100% 56%", from: "SoundCloud waveform orange — secondary accent for upload/share affordances" },
|
|
74
|
+
"vinyl-cream": { hsl: "36 22% 88%", from: "Bandcamp Daily editorial cream — used inside dark cards for long-form blocks" },
|
|
75
|
+
"canvas-black": { hsl: "0 0% 7%", from: "= background; the Spotify canvas itself, also a semantic token" },
|
|
76
|
+
"now-playing": { hsl: "141 73% 48%", from: "= signal-green; the active-track indicator color across the player" },
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
spacing: {
|
|
81
|
+
base: 4,
|
|
82
|
+
scale: [4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 80, 96, 128], // medium-dense — track lists need to pack
|
|
83
|
+
containerMax: "max-w-7xl", // wide — album-art grids and playlist tables breathe at this width
|
|
84
|
+
containerPadding: "px-4 lg:px-8",
|
|
85
|
+
sectionPadding: {
|
|
86
|
+
hero: "pt-16 pb-12 lg:pt-24 lg:pb-16", // album-art hero is full-bleed; section padding stays modest
|
|
87
|
+
default: "py-12 lg:py-20",
|
|
88
|
+
tight: "py-8 lg:py-12",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
radius: {
|
|
93
|
+
base: "0.5rem", // soft-square — Spotify card and Apple Music tile corner
|
|
94
|
+
pillsAllowed: true, // tag chips and genre pills are common in playback UIs
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
shadows: {
|
|
98
|
+
style: "glow",
|
|
99
|
+
utilities: {
|
|
100
|
+
"art-lift":
|
|
101
|
+
"0 16px 40px hsl(0 0% 0% / 0.6), " +
|
|
102
|
+
"0 4px 12px hsl(0 0% 0% / 0.4)", // album-art tile lift — soft black drop behind covers
|
|
103
|
+
"now-playing-glow":
|
|
104
|
+
"0 0 0 1px hsl(var(--signal-green) / 0.4), " +
|
|
105
|
+
"0 0 24px hsl(var(--signal-green) / 0.25)", // green ring on the active playback card
|
|
106
|
+
"row-hover":
|
|
107
|
+
"inset 0 0 0 1px hsl(0 0% 100% / 0.06)", // ghost inner-stroke on track-row hover
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
motion: {
|
|
112
|
+
easing: "cubic-bezier(0.22, 1, 0.36, 1)",
|
|
113
|
+
durations: {
|
|
114
|
+
reveal: 400, // cover fade-in, play-button morph — quick, app-feel
|
|
115
|
+
loop: 1600, // equalizer-bar pulse — Spotify "now playing" indicator
|
|
116
|
+
ambient: 24000, // slow album-art ken-burns behind hero
|
|
117
|
+
},
|
|
118
|
+
keyframes: {
|
|
119
|
+
"art-fade": {
|
|
120
|
+
css:
|
|
121
|
+
"from { opacity: 0; transform: scale(0.98); }\n" +
|
|
122
|
+
"to { opacity: 1; transform: scale(1); }",
|
|
123
|
+
defaultDuration: 400,
|
|
124
|
+
iteration: "once",
|
|
125
|
+
purpose: "album-art tile reveal as covers load — gentle scale-up, no flash",
|
|
126
|
+
},
|
|
127
|
+
"equalizer": {
|
|
128
|
+
css:
|
|
129
|
+
"0%, 100% { transform: scaleY(0.3); }\n" +
|
|
130
|
+
"50% { transform: scaleY(1); }",
|
|
131
|
+
defaultDuration: 1200,
|
|
132
|
+
iteration: "infinite",
|
|
133
|
+
purpose: "now-playing equalizer bars — the canonical 'this track is playing' indicator",
|
|
134
|
+
},
|
|
135
|
+
"play-pulse": {
|
|
136
|
+
css:
|
|
137
|
+
"0%, 100% { box-shadow: 0 0 0 0 hsl(var(--signal-green) / 0.45); }\n" +
|
|
138
|
+
"50% { box-shadow: 0 0 0 14px hsl(var(--signal-green) / 0); }",
|
|
139
|
+
defaultDuration: 1800,
|
|
140
|
+
iteration: "infinite",
|
|
141
|
+
purpose: "primary play-button heartbeat ring on hero CTA — single instance per page",
|
|
142
|
+
},
|
|
143
|
+
"art-drift": {
|
|
144
|
+
css:
|
|
145
|
+
"0% { transform: scale(1.1) translate(0, 0); }\n" +
|
|
146
|
+
"100% { transform: scale(1.2) translate(-1%, -1%); }",
|
|
147
|
+
defaultDuration: 24000,
|
|
148
|
+
iteration: "infinite",
|
|
149
|
+
purpose: "blurred album-art backdrop drift behind hero — ambient, never on cover tiles themselves",
|
|
150
|
+
},
|
|
151
|
+
"waveform-shimmer": {
|
|
152
|
+
css:
|
|
153
|
+
"0% { background-position: -200% 0; }\n" +
|
|
154
|
+
"100% { background-position: 200% 0; }",
|
|
155
|
+
defaultDuration: 2400,
|
|
156
|
+
iteration: "infinite",
|
|
157
|
+
purpose: "SoundCloud-style waveform fill animation — used on the active scrubber bar only",
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
respectsReducedMotion: true,
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
density: "medium",
|
|
164
|
+
|
|
165
|
+
patterns: {
|
|
166
|
+
button:
|
|
167
|
+
"Primary play action is a SOLID round signal-green circle with the canvas-black play glyph — the iconic Spotify mark. " +
|
|
168
|
+
"Secondary controls (shuffle, repeat, queue) are ghost icon buttons in mutedForeground that brighten to foreground on hover. " +
|
|
169
|
+
"Text-link CTAs use foreground color with underline-on-hover. Never use green for non-playback actions — that color is reserved.",
|
|
170
|
+
card:
|
|
171
|
+
"Album-art tile is the canonical card — a square cover image with title and artist text below, lifted by .art-lift shadow on hover. " +
|
|
172
|
+
"Playlist/section cards use bg-card (one stop above canvas), 0.5rem radius, p-4 lg:p-5. No fill differentiation between cards on the same surface tier — depth comes from shadow lift on hover.",
|
|
173
|
+
input:
|
|
174
|
+
"Search uses a pill-shape (rounded-full) bg-input field with a leading icon, no border. " +
|
|
175
|
+
"Focus state shows a 2px signal-green ring. Filter chips below the search are pills (bg-secondary, foreground text).",
|
|
176
|
+
cta:
|
|
177
|
+
"Hero CTA is a solid signal-green pill with canvas-black label, optionally wrapped in play-pulse. " +
|
|
178
|
+
"Inline 'Listen now' or 'Open in app' links are foreground-color underline-on-hover. App Store / Play Store badges for cross-platform CTAs.",
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
details: {
|
|
182
|
+
selectionBg: "hsl(var(--signal-green) / 0.35)",
|
|
183
|
+
selectionFg: "hsl(var(--foreground))",
|
|
184
|
+
focusRing: "2px solid hsl(var(--signal-green))",
|
|
185
|
+
scrollbarStyle: "thin",
|
|
186
|
+
},
|
|
187
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Design Direction — Music-Vinyl
|
|
2
|
+
|
|
3
|
+
## Ethos
|
|
4
|
+
Resident Advisor clean white · Pitchfork deep-editorial serif · Bandcamp deep-cyan community · 4AD label restraint · Aphex Twin archive typewriter
|
|
5
|
+
|
|
6
|
+
## Feel
|
|
7
|
+
Warm paper canvas, deep-cyan link color, serif display set tight for review headlines. Long-read column with mono captions for catalog numbers and runtimes. Reads like a record-shop zine — vinyl-collector reverence, dense knowledge, no autoplay anywhere. The page is the review, not the player.
|
|
8
|
+
|
|
9
|
+
## Reference brands
|
|
10
|
+
- **Resident Advisor** → clean white canvas with DM Sans and dense review layout. Event listings as ledger rows.
|
|
11
|
+
- **Pitchfork** → deep editorial pace with Lora serif and restrained nav. The review is the product.
|
|
12
|
+
- **Bandcamp** → deep cyan link color and Lato body. Community-warm, artist-first commerce.
|
|
13
|
+
- **4AD label site** → deep cream paper with serif headlines and minimal chrome. Label as curator.
|
|
14
|
+
- **Aphex Twin archive** → typewriter mono with dense, obscure cataloguing. Catalog number as art.
|
|
15
|
+
|
|
16
|
+
## Tokens
|
|
17
|
+
All tokens live in `src/index.css` as HSL triples. Every token's `from:` comment names its brand origin. Do not introduce numbered or generic tokens — if a new color is needed, name a brand it traces to.
|
|
18
|
+
|
|
19
|
+
Surface stack is **label-cream** (background, HSL `38 28% 94%` — 4AD vinyl-sleeve inner) → **white card** (`0 0% 100%`) → **deeper cream** (secondary/muted/accent). Depth comes from hairline borders and the cream-on-white contrast, never from drop shadows.
|
|
20
|
+
|
|
21
|
+
Brand tokens: `--bandcamp-cyan` (primary, canonical link color), `--pitchfork-red` (Best New Music accolade only), `--label-cream`, `--vinyl-ink`, `--ra-blue` (Resident Advisor event chrome), `--archive-ochre` (catalog numerals). Primary is `--bandcamp-cyan` — used for all linkable affordances.
|
|
22
|
+
|
|
23
|
+
## Typography
|
|
24
|
+
- **Display:** Lora (Pitchfork review-headline serif). Contemporary book-serif, sits well at large sizes. Tracking `-0.02em` — fractional tightening at display scale.
|
|
25
|
+
- **Body:** DM Sans (Resident Advisor body). Geometric humanist sans, comfortable for dense review rows. Body base **17px** with **line-height 1.65**.
|
|
26
|
+
- **Mono:** JetBrains Mono. Catalog numbers, runtimes, BPM, pressing notes — the Aphex-Twin-archive typewriter feel.
|
|
27
|
+
|
|
28
|
+
H1 uses `clamp(2.5rem, 6.5vw, 5.5rem)`. Numbers always use `font-variant-numeric: tabular-nums`. Font features: `"ss01"`, `"calt"`, `"tnum"`.
|
|
29
|
+
|
|
30
|
+
## Spacing
|
|
31
|
+
- **Container:** `max-w-3xl px-5 lg:px-10` — 768px reading column for long-form reviews. The review is for *reading*; wider columns break flow.
|
|
32
|
+
- **Section padding tiers:**
|
|
33
|
+
- Hero: `pt-24 pb-16 lg:pt-36 lg:pb-24`
|
|
34
|
+
- Default: `py-16 lg:py-28`
|
|
35
|
+
- Tight: `py-10 lg:py-16`
|
|
36
|
+
- **Allowed scale values:** 4 6 8 12 16 20 24 32 40 48 64 96 128. No arbitrary spacing.
|
|
37
|
+
|
|
38
|
+
## Color
|
|
39
|
+
No hex anywhere in component files. All color via tokens. Opacity via `/N` modifier on token, not via new tokens. Pure white is reserved for `--card` only — the cream canvas is the default page surface. Pure black is forbidden — `--vinyl-ink` (warm brown-black) replaces it.
|
|
40
|
+
|
|
41
|
+
**Bandcamp cyan is the link color across the entire surface.** It is the only saturated color used at scale. Pitchfork-red is reserved for the "Best New Music" badge analog and review-score accolades — never as a CTA color. Archive-ochre is used on catalog numerals only, never on body text.
|
|
42
|
+
|
|
43
|
+
## Radius
|
|
44
|
+
`--radius: 0`. **Sharp corners only.** Pills are disallowed (`pillsAllowed: false`) — they read app-chrome, not zine. If a UI element needs softness, achieve it through whitespace and hairline borders, not corner rounding. This mirrors editorial — the print-zine convention.
|
|
45
|
+
|
|
46
|
+
## Shadows
|
|
47
|
+
**Minimal.** Two utilities:
|
|
48
|
+
- `.hairline-bottom` (1px border-bottom in `--border`) — ledger line between paragraphs and review-meta blocks
|
|
49
|
+
- `.review-rule` (inset top + bottom border, 1px each) — double-rule wrap for review-meta strips (byline, dateline, catalog meta)
|
|
50
|
+
|
|
51
|
+
No drop shadows. No glows. No depth.
|
|
52
|
+
|
|
53
|
+
## Motion
|
|
54
|
+
Three keyframes, all slow on purpose:
|
|
55
|
+
- `fade-rise` (1000ms once) — section entrance, no bounce, no flash, mirrors editorial
|
|
56
|
+
- `ink-bleed` (1400ms once) — review-headline reveal; letters resolve like ink settling on paper, used on h1 only
|
|
57
|
+
- `underline-grow` (400ms once) — Bandcamp-style link underline expansion on hover, left-anchored 1px line
|
|
58
|
+
|
|
59
|
+
Easing: `cubic-bezier(0.22, 1, 0.36, 1)`. `prefers-reduced-motion` is honored — every motion utility wrapped in a media query. **No looping or ambient animation** — the page does not perform.
|
|
60
|
+
|
|
61
|
+
## Component patterns
|
|
62
|
+
- **Buttons:** primary action is a text link in `--bandcamp-cyan` with `underline-grow` on hover — the canonical Bandcamp affordance. Solid-fill is reserved for the single "Buy / Add to library" hero action per review — `--vinyl-ink` bg + `--label-cream` label, sharp corners, mono uppercase. Tertiary actions are mono uppercase labels with hairline-bottom underline.
|
|
63
|
+
- **Cards:** review card uses `bg-card` (white) on cream page, hairline border on all four sides, sharp corners. Internal padding `p-6 lg:p-10`. Headline in Lora display serif, byline and catalog meta in mono. Album-art thumbnail sits as a square block at 1:1 aspect, no rounding, no shadow.
|
|
64
|
+
- **Inputs:** border-bottom only (1px `--border`), bg transparent. Label sits above in mono uppercase, tracking 0.06em. Focus shifts the underline to 2px `--ring` (cyan). Placeholder italic mutedForeground.
|
|
65
|
+
- **CTA links:** text-link with cyan color and underline-on-hover. Single hero "Buy on Bandcamp" / "Pre-order" button uses vinyl-ink fill + cream label, sharp corners, mono uppercase label. **Never gradient, never glow, never pill.**
|
|
66
|
+
|
|
67
|
+
## Recommended rich media
|
|
68
|
+
Music-vinyl leans on **square album covers** treated as printed objects on a zine page, and on **artist photography color-graded warm** like a record-store wall.
|
|
69
|
+
|
|
70
|
+
Lead media is **square album cover at 1:1 aspect, minimum 600×600**, displayed as a sharp-cornered block with hairline border. The cover sits *on* the page like a record on a shelf, not embedded in chrome. Artist photography uses **3:2 landscape**, color-graded to a warm Portra-400 or Cinestill-800T palette — slight golden highlights, deep shadows, never crushed black. Live-show shots are appropriate; in-studio is appropriate; press-headshot-style is not.
|
|
71
|
+
|
|
72
|
+
**AI tool recommendations:** **Midjourney** with prompts like *"medium-format film photograph, warm tungsten lighting, 35mm, Cinestill 800T grain"* for environmental artist shots; *"square album cover, [genre] aesthetic, hand-drawn typography, risograph print"* for placeholder catalog covers. Avoid Midjourney's default photorealistic shine — explicitly prompt for film grain. **Recraft** for the kind of stippled / line-art illustrations that sit in long-read reviews.
|
|
73
|
+
|
|
74
|
+
**Aspect ratios:** 1:1 square for album covers and label catalog imagery (canonical). 3:2 landscape for artist photography. 4:5 portrait for vertical artist shots. Never 16:9 (cinematic, off-feel). Never 1:1 for non-album content (Instagram-aesthetic).
|
|
75
|
+
|
|
76
|
+
**Video:** generally avoided. Vinyl-review readers are reading, not watching. If used, single hero with poster image and play button — never autoplay loop. Bandcamp-style audio embeds are appropriate: a thin player strip with album-art and play button, user-initiated only.
|
|
77
|
+
|
|
78
|
+
**Catalog numerals:** treat as the second-most-important typographic element after headlines. Always mono, often in `--archive-ochre`, often given their own meta strip with `.review-rule` framing. Aphex Twin archive aesthetic — the catalog number IS the design.
|
|
79
|
+
|
|
80
|
+
**Performance:** hero album cover ≤120 KB AVIF at 1200w; inline figures ≤80 KB. Long-read pages should LCP under 2s — if it slips, the hero is too large or the review needs a smaller cover-thumbnail variant.
|
|
81
|
+
|
|
82
|
+
**Avoid:** glossy product-photography album shots with reflections, lifestyle stock (headphones on coffee table), 3D rendered vinyl mockups with motion blur, animated GIFs, gradient backgrounds, glassmorphic anything, AI photos with uncanny hands or instruments, decorative SVG ornament beyond Bandcamp/4AD-style hand marks.
|
|
83
|
+
|
|
84
|
+
**Accessibility:** long-form alt-text on artist photography — describe environment and subject as if for a blind reader. Album covers use *"[Artist] — [Album], [Year]"* format. Catalog numbers in mono are decorative-meta, not pure decoration — read by screen readers as *"Catalog: XYZ-001"*.
|
|
85
|
+
|
|
86
|
+
## Component families
|
|
87
|
+
None at install time. Family conventions emerge as the project grows; the Director appends them here as they're established. Expected first families: `ReviewHeader`, `CatalogMeta`, `BuyStrip`, `EventRow`.
|
|
88
|
+
|
|
89
|
+
## Details
|
|
90
|
+
- **Selection:** `hsl(var(--bandcamp-cyan) / 0.22)` background, foreground text.
|
|
91
|
+
- **Focus ring:** `2px solid hsl(var(--ring))` (cyan). Thin and quiet — matches link underline weight.
|
|
92
|
+
- **Scrollbar:** thin.
|
|
93
|
+
|
|
94
|
+
## Exceptions
|
|
95
|
+
None yet. When an intentional one-of-one violation lands, add it here with the reason. The Director's consistency pass lists all exceptions for human review.
|
|
96
|
+
|
|
97
|
+
## Revisions
|
|
98
|
+
- Initial direction, generated at install time.
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import type { Direction } from "../schema";
|
|
2
|
+
|
|
3
|
+
export const musicVinyl: Direction = {
|
|
4
|
+
name: "music-vinyl",
|
|
5
|
+
ethos:
|
|
6
|
+
"Resident Advisor clean white · Pitchfork deep-editorial serif · Bandcamp deep-cyan community · 4AD label restraint · Aphex Twin archive typewriter",
|
|
7
|
+
references: [
|
|
8
|
+
{ brand: "Resident Advisor", trait: "clean white canvas with DM Sans and dense review layout" },
|
|
9
|
+
{ brand: "Pitchfork", trait: "deep editorial pace with Lora serif and restrained nav" },
|
|
10
|
+
{ brand: "Bandcamp", trait: "deep cyan link color and Lato body, warm community feel" },
|
|
11
|
+
{ brand: "4AD label site", trait: "deep cream paper with serif headlines and minimal chrome" },
|
|
12
|
+
{ brand: "Aphex Twin archive", trait: "typewriter mono with dense, obscure cataloguing" },
|
|
13
|
+
],
|
|
14
|
+
feel:
|
|
15
|
+
"Warm paper canvas, deep-cyan link color, serif display set tight for review headlines. " +
|
|
16
|
+
"Long-read column with mono captions for catalog numbers and runtimes. Reads like a record-shop " +
|
|
17
|
+
"zine — vinyl-collector reverence, dense knowledge, no autoplay anywhere.",
|
|
18
|
+
|
|
19
|
+
fonts: {
|
|
20
|
+
display: {
|
|
21
|
+
family: "Lora",
|
|
22
|
+
fallback: ["Iowan Old Style", "Apple Garamond", "Garamond", "Georgia", "serif"],
|
|
23
|
+
from: "Pitchfork review-headline serif — contemporary book-serif weight, sits well at large sizes",
|
|
24
|
+
googleFont: "Lora",
|
|
25
|
+
weights: [400, 500, 600, 700],
|
|
26
|
+
},
|
|
27
|
+
body: {
|
|
28
|
+
family: "DM Sans",
|
|
29
|
+
fallback: ["Lato", "Inter", "system-ui", "-apple-system", "sans-serif"],
|
|
30
|
+
from: "Resident Advisor body — geometric humanist sans, dense review-row-friendly",
|
|
31
|
+
googleFont: "DM+Sans",
|
|
32
|
+
weights: [400, 500, 700],
|
|
33
|
+
},
|
|
34
|
+
mono: {
|
|
35
|
+
family: "JetBrains Mono",
|
|
36
|
+
fallback: ["Courier Prime", "Berkeley Mono", "ui-monospace", "Consolas", "monospace"],
|
|
37
|
+
from: "Aphex Twin archive typewriter — catalog numbers, runtimes, BPM, pressing notes",
|
|
38
|
+
googleFont: "JetBrains+Mono",
|
|
39
|
+
weights: [400, 500],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
typography: {
|
|
44
|
+
headingTracking: "-0.02em", // Lora at display scale wants a fractional tightening
|
|
45
|
+
bodyTracking: "0",
|
|
46
|
+
fontFeatureSettings: '"ss01", "calt", "tnum"',
|
|
47
|
+
h1ScaleClamp: "clamp(2.5rem, 6.5vw, 5.5rem)", // review headline scale — Pitchfork lead
|
|
48
|
+
bodyBaseSize: "1.0625rem", // 17px — review prose comfort
|
|
49
|
+
bodyLineHeight: "1.65",
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
colors: {
|
|
53
|
+
background: { hsl: "38 28% 94%", from: "deep warm cream — 4AD label-site paper stock, vinyl-sleeve inner" },
|
|
54
|
+
foreground: { hsl: "30 15% 14%", from: "deep brown-ink — never pure black, sits warm against cream" },
|
|
55
|
+
card: { hsl: "0 0% 100%", from: "review card — pure white on cream, the way a printed review sits on a zine page" },
|
|
56
|
+
popover: { hsl: "0 0% 100%", from: "same as card; menus use the white plate, hairline border for depth" },
|
|
57
|
+
primary: { hsl: "192 80% 36%", from: "Bandcamp deep cyan — canonical link color across the community" },
|
|
58
|
+
primaryForeground: { hsl: "38 28% 94%", from: "cream paper on Bandcamp cyan" },
|
|
59
|
+
secondary: { hsl: "38 20% 88%", from: "deeper cream, sidebar panels and review meta-blocks" },
|
|
60
|
+
secondaryForeground: { hsl: "30 15% 14%", from: "brown-ink on deeper cream" },
|
|
61
|
+
muted: { hsl: "38 18% 90%", from: "muted cream — quote-block and pull-quote backgrounds" },
|
|
62
|
+
mutedForeground: { hsl: "30 12% 38%", from: "secondary review prose — byline, dateline, catalog meta" },
|
|
63
|
+
accent: { hsl: "38 22% 86%", from: "hover state for review-row chrome, fractional darken of cream" },
|
|
64
|
+
accentForeground: { hsl: "30 15% 14%", from: "brown-ink on hover cream" },
|
|
65
|
+
border: { hsl: "30 12% 78%", from: "Pitchfork hairline rule — column divider, between-section ledger line" },
|
|
66
|
+
input: { hsl: "30 12% 78%", from: "same as border — inputs share the hairline language" },
|
|
67
|
+
ring: { hsl: "192 80% 36%", from: "Bandcamp cyan focus ring — matches the link color" },
|
|
68
|
+
destructive: { hsl: "356 65% 42%", from: "review-pan red — used sparingly for low-score badges and remove actions" },
|
|
69
|
+
destructiveForeground: { hsl: "38 28% 94%", from: "cream on pan red" },
|
|
70
|
+
brand: {
|
|
71
|
+
"bandcamp-cyan": { hsl: "192 80% 36%", from: "= primary; the Bandcamp link color, the canonical signal mark" },
|
|
72
|
+
"pitchfork-red": { hsl: "0 70% 48%", from: "Pitchfork 'Best New Music' badge red — review-score accolade color" },
|
|
73
|
+
"label-cream": { hsl: "38 28% 94%", from: "= background; 4AD/indie-label paper stock, also a semantic token" },
|
|
74
|
+
"vinyl-ink": { hsl: "30 15% 14%", from: "= foreground; brown-black, also semantic for spine type and serial numbers" },
|
|
75
|
+
"ra-blue": { hsl: "215 75% 32%", from: "Resident Advisor deep navy — used on event-listing chrome and tertiary accents" },
|
|
76
|
+
"archive-ochre": { hsl: "36 70% 42%", from: "Aphex Twin archive ochre — catalog highlight, used on numerals only" },
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
spacing: {
|
|
81
|
+
base: 4,
|
|
82
|
+
scale: [4, 6, 8, 12, 16, 20, 24, 32, 40, 48, 64, 96, 128], // editorial-leaning but allows denser review rows
|
|
83
|
+
containerMax: "max-w-3xl", // 768px reading column for long-form reviews
|
|
84
|
+
containerPadding: "px-5 lg:px-10",
|
|
85
|
+
sectionPadding: {
|
|
86
|
+
hero: "pt-24 pb-16 lg:pt-36 lg:pb-24",
|
|
87
|
+
default: "py-16 lg:py-28",
|
|
88
|
+
tight: "py-10 lg:py-16",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
radius: {
|
|
93
|
+
base: "0", // sharp corners — print zine convention, mirrors editorial
|
|
94
|
+
pillsAllowed: false, // no pills; tags use sharp rect chips or underlined text
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
shadows: {
|
|
98
|
+
style: "minimal",
|
|
99
|
+
utilities: {
|
|
100
|
+
"hairline-bottom":
|
|
101
|
+
"0 1px 0 0 hsl(var(--border))", // ledger line — Pitchfork between-paragraph divider
|
|
102
|
+
"review-rule":
|
|
103
|
+
"inset 0 -1px 0 0 hsl(var(--border)), inset 0 1px 0 0 hsl(var(--border))", // double-rule for review-meta strips
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
motion: {
|
|
108
|
+
easing: "cubic-bezier(0.22, 1, 0.36, 1)",
|
|
109
|
+
durations: {
|
|
110
|
+
reveal: 1000, // slow on purpose — pages settle like a printed page being unfolded
|
|
111
|
+
loop: 4000,
|
|
112
|
+
ambient: 30000,
|
|
113
|
+
},
|
|
114
|
+
keyframes: {
|
|
115
|
+
"fade-rise": {
|
|
116
|
+
css:
|
|
117
|
+
"from { opacity: 0; transform: translateY(20px); }\n" +
|
|
118
|
+
"to { opacity: 1; transform: translateY(0); }",
|
|
119
|
+
defaultDuration: 1000,
|
|
120
|
+
iteration: "once",
|
|
121
|
+
purpose: "section entrance — slow, no bounce, no flash, mirrors editorial",
|
|
122
|
+
},
|
|
123
|
+
"ink-bleed": {
|
|
124
|
+
css:
|
|
125
|
+
"from { opacity: 0; filter: blur(2px); }\n" +
|
|
126
|
+
"to { opacity: 1; filter: blur(0); }",
|
|
127
|
+
defaultDuration: 1400,
|
|
128
|
+
iteration: "once",
|
|
129
|
+
purpose: "review-headline reveal — letters resolve like ink settling on paper, used on h1 only",
|
|
130
|
+
},
|
|
131
|
+
"underline-grow": {
|
|
132
|
+
css:
|
|
133
|
+
"from { background-size: 0 1px; }\n" +
|
|
134
|
+
"to { background-size: 100% 1px; }",
|
|
135
|
+
defaultDuration: 400,
|
|
136
|
+
iteration: "once",
|
|
137
|
+
purpose: "Bandcamp-style link underline expansion on hover — left-anchored 1px line",
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
respectsReducedMotion: true,
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
density: "medium",
|
|
144
|
+
|
|
145
|
+
patterns: {
|
|
146
|
+
button:
|
|
147
|
+
"Primary action is a text link in --bandcamp-cyan with an underline-grow on hover — the canonical Bandcamp affordance. " +
|
|
148
|
+
"Solid-fill is reserved for the single 'Buy / Add to library' hero action per review — vinyl-ink bg + cream label. " +
|
|
149
|
+
"Tertiary actions are mono uppercase labels with a hairline-bottom underline. Never a colored pill or rounded fill.",
|
|
150
|
+
card:
|
|
151
|
+
"Review card uses bg-card (white) on cream page, hairline border on all four sides, sharp corners. " +
|
|
152
|
+
"Internal padding p-6 lg:p-10. Headline in Lora display serif, byline and catalog meta in mono. " +
|
|
153
|
+
"Album-art thumbnail sits as a square block at 1:1 aspect, no rounding, no shadow.",
|
|
154
|
+
input:
|
|
155
|
+
"Border-bottom only (1px --border), bg transparent. Label sits above in mono uppercase, tracking 0.06em. " +
|
|
156
|
+
"Focus shifts the underline to 2px --ring (cyan). Placeholder is italic mutedForeground.",
|
|
157
|
+
cta:
|
|
158
|
+
"Text-link with cyan color and underline-on-hover. Single hero 'Buy on Bandcamp' / 'Pre-order' button uses vinyl-ink fill + cream label, sharp corners, mono uppercase label. Never gradient, never glow.",
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
details: {
|
|
162
|
+
selectionBg: "hsl(var(--bandcamp-cyan) / 0.22)",
|
|
163
|
+
selectionFg: "hsl(var(--foreground))",
|
|
164
|
+
focusRing: "2px solid hsl(var(--ring))",
|
|
165
|
+
scrollbarStyle: "thin",
|
|
166
|
+
},
|
|
167
|
+
};
|