get-shit-pretty 0.7.3 → 0.8.2
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/bin/theme-css.js +331 -0
- package/gsp/agents/gsp-brand-coherence.md +7 -0
- package/gsp/hooks/hooks.json +1 -1
- package/gsp/skills/gsp-brand-brief/SKILL.md +50 -5
- package/gsp/skills/gsp-brand-guidelines/SKILL.md +51 -31
- package/gsp/skills/gsp-brand-guidelines/design-tokens.md +2 -0
- package/gsp/skills/gsp-brand-guidelines/guidelines-structure.md +167 -0
- package/gsp/skills/gsp-brand-guidelines/methodology/gsp-brand-coherence.md +86 -0
- package/gsp/skills/gsp-brand-guidelines/methodology/gsp-brand-engineer.md +13 -5
- package/gsp/skills/gsp-brand-guidelines/token-mapping.md +16 -319
- package/gsp/skills/gsp-brand-identity/SKILL.md +1 -1
- package/gsp/skills/gsp-brand-refine/SKILL.md +5 -6
- package/gsp/skills/gsp-brand-research/SKILL.md +1 -1
- package/gsp/skills/gsp-brand-strategy/SKILL.md +1 -1
- package/gsp/skills/gsp-design-system/SKILL.md +1 -1
- package/gsp/skills/gsp-doctor/SKILL.md +51 -3
- package/gsp/skills/gsp-progress/SKILL.md +1 -1
- package/gsp/skills/gsp-project-brief/SKILL.md +40 -6
- package/gsp/skills/gsp-project-build/SKILL.md +27 -31
- package/gsp/skills/gsp-project-build/flows/figma.md +50 -0
- package/gsp/skills/gsp-project-build/flows/revision.md +64 -0
- package/gsp/skills/gsp-project-build/methodology/gsp-project-builder.md +84 -1
- package/gsp/skills/gsp-project-build/shadcn-composition.md +217 -0
- package/gsp/skills/gsp-project-critique/SKILL.md +3 -1
- package/gsp/skills/gsp-project-design/SKILL.md +3 -2
- package/gsp/skills/gsp-project-design/methodology/gsp-project-designer.md +28 -21
- package/gsp/skills/gsp-project-research/SKILL.md +3 -1
- package/gsp/skills/gsp-project-review/SKILL.md +10 -1
- package/gsp/skills/gsp-scaffold/SKILL.md +67 -11
- package/gsp/skills/gsp-scaffold/shadcn-rules.md +433 -0
- package/gsp/skills/gsp-scaffold/shadcn-theming.md +310 -0
- package/gsp/skills/gsp-start/SKILL.md +18 -2
- package/gsp/skills/gsp-style/SKILL.md +1 -1
- package/gsp/skills/gsp-style/style-preset-schema.md +59 -14
- package/gsp/skills/gsp-style/styles/academia.yml +58 -8
- package/gsp/skills/gsp-style/styles/art-deco.yml +39 -7
- package/gsp/skills/gsp-style/styles/bauhaus.yml +39 -8
- package/gsp/skills/gsp-style/styles/bold-typography.yml +39 -8
- package/gsp/skills/gsp-style/styles/botanical.yml +39 -9
- package/gsp/skills/gsp-style/styles/claymorphism.yml +39 -9
- package/gsp/skills/gsp-style/styles/cyberpunk.yml +39 -7
- package/gsp/skills/gsp-style/styles/enterprise.yml +39 -10
- package/gsp/skills/gsp-style/styles/flat-design.yml +39 -9
- package/gsp/skills/gsp-style/styles/fluent.yml +39 -10
- package/gsp/skills/gsp-style/styles/glassmorphism.yml +39 -8
- package/gsp/skills/gsp-style/styles/humanist-literary.yml +39 -9
- package/gsp/skills/gsp-style/styles/industrial.yml +59 -9
- package/gsp/skills/gsp-style/styles/kinetic.yml +32 -7
- package/gsp/skills/gsp-style/styles/liquid-glass.yml +59 -9
- package/gsp/skills/gsp-style/styles/luxury.yml +59 -9
- package/gsp/skills/gsp-style/styles/material.yml +59 -9
- package/gsp/skills/gsp-style/styles/maximalism.yml +32 -6
- package/gsp/skills/gsp-style/styles/minimal-dark.yml +32 -7
- package/gsp/skills/gsp-style/styles/modern-dark.yml +32 -7
- package/gsp/skills/gsp-style/styles/monochrome.yml +59 -10
- package/gsp/skills/gsp-style/styles/neubrutalism.yml +59 -9
- package/gsp/skills/gsp-style/styles/neumorphism.yml +32 -7
- package/gsp/skills/gsp-style/styles/newsprint.yml +32 -7
- package/gsp/skills/gsp-style/styles/nothing.yml +44 -13
- package/gsp/skills/gsp-style/styles/organic.yml +42 -9
- package/gsp/skills/gsp-style/styles/playful-geometric.yml +43 -9
- package/gsp/skills/gsp-style/styles/professional.yml +41 -10
- package/gsp/skills/gsp-style/styles/retro.yml +42 -8
- package/gsp/skills/gsp-style/styles/saas.yml +42 -9
- package/gsp/skills/gsp-style/styles/sketch.yml +42 -9
- package/gsp/skills/gsp-style/styles/swiss-minimalist.yml +41 -10
- package/gsp/skills/gsp-style/styles/terminal.yml +42 -8
- package/gsp/skills/gsp-style/styles/vaporwave.yml +42 -7
- package/gsp/skills/gsp-style/styles/web3.yml +42 -9
- package/gsp/templates/branding/brief.md +9 -0
- package/gsp/templates/branding/config.json +1 -1
- package/gsp/templates/design-claude.md +6 -0
- package/gsp/templates/phases/design.md +0 -8
- package/gsp/templates/phases/patterns.md +2 -2
- package/gsp/templates/projects/config.json +6 -3
- package/gsp/templates/projects/state.md +1 -1
- package/gsp/templates/system/STACK.md +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# guidelines.html — Structure Spec
|
|
2
|
+
|
|
3
|
+
The `guidelines.html` is the visual conference of the entire brand pipeline — every phase of the branding diamond distilled into one self-rendering document:
|
|
4
|
+
|
|
5
|
+
- **Discover** → personas
|
|
6
|
+
- **Strategy** → positioning, voice
|
|
7
|
+
- **Identity** → color, typography, visual elements, logo
|
|
8
|
+
- **Patterns** → components, tokens
|
|
9
|
+
|
|
10
|
+
It uses the brand's own tokens, type, and primitives to render itself. One file, no build step, open in a browser. When someone opens this file, they should understand the brand completely — who it's for, what it stands for, and how it looks and speaks.
|
|
11
|
+
|
|
12
|
+
**Every element in this document must be derived from the brand pipeline outputs.** There are no defaults, no fallbacks, no generic treatments. If the brand is dark and editorial, the doc is dark and editorial. If the brand is warm and rounded, the doc is warm and rounded. The guidelines file is not a template being filled in — it is a brand artifact being built from the ground up using everything the pipeline produced.
|
|
13
|
+
|
|
14
|
+
## `:root` — shadcn-native token names
|
|
15
|
+
|
|
16
|
+
Use these exact CSS variable names so the file maps 1:1 with the shadcn token system. All values come from the brand's `.yml` tokens — use OKLCH values from palettes.json where available.
|
|
17
|
+
|
|
18
|
+
```css
|
|
19
|
+
:root {
|
|
20
|
+
/* shadcn core */
|
|
21
|
+
--background: ...; /* page background */
|
|
22
|
+
--foreground: ...; /* primary text */
|
|
23
|
+
--primary: ...; /* brand primary color */
|
|
24
|
+
--primary-foreground: ...; /* text on primary */
|
|
25
|
+
--secondary: ...; /* secondary surface */
|
|
26
|
+
--secondary-foreground: ...;
|
|
27
|
+
--muted: ...; /* muted surface */
|
|
28
|
+
--muted-foreground: ...; /* secondary text */
|
|
29
|
+
--accent: ...; /* accent color (the memorable one) */
|
|
30
|
+
--accent-foreground: ...;
|
|
31
|
+
--destructive: ...; /* error state */
|
|
32
|
+
--border: ...; /* border color */
|
|
33
|
+
--ring: ...; /* focus ring */
|
|
34
|
+
--radius: ...; /* base radius */
|
|
35
|
+
|
|
36
|
+
/* Brand-specific extensions */
|
|
37
|
+
--font-display: ...; /* heading/editorial font */
|
|
38
|
+
--font-body: ...; /* body/UI font */
|
|
39
|
+
--font-mono: ...; /* data/code font */
|
|
40
|
+
--ease: ...; /* brand easing curve */
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Primitive classes
|
|
45
|
+
|
|
46
|
+
Define only the primitives the brand actually uses. Their implementation is derived from the brand's identity — intensity.variance, visual_direction, effects vocabulary. Don't define a class that doesn't serve this brand.
|
|
47
|
+
|
|
48
|
+
```css
|
|
49
|
+
/* examples — implement only what fits the brand */
|
|
50
|
+
.frosted-glass /* glass surface — opacity/blur derived from brand intensity */
|
|
51
|
+
.frosted-glass-strong /* heavier glass — for hero overlays */
|
|
52
|
+
.grain /* noise texture — only if brand uses texture */
|
|
53
|
+
.glow /* ambient radial glow — only if brand uses glow */
|
|
54
|
+
.atmosphere /* full-bleed animated gradient — derived from brand palette */
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Layout primitives
|
|
58
|
+
|
|
59
|
+
```css
|
|
60
|
+
.container /* max-width wrapper, responsive padding */
|
|
61
|
+
section /* section spacing — density derived from brand intensity */
|
|
62
|
+
.section-label /* eyebrow label */
|
|
63
|
+
.section-heading /* large section heading */
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Sections
|
|
67
|
+
|
|
68
|
+
The template defines a baseline section order. Follow it. If the brand warrants additional sections beyond this list — imagery style, motion principles, iconography, spatial system, co-branding rules, etc. — add them where they fit. Number sections sequentially. Each section gets an `id` for sidebar navigation.
|
|
69
|
+
|
|
70
|
+
### Navigation — always
|
|
71
|
+
Fixed left sidebar. Table of contents linking to every section. Brand-derived styling — font, color, spacing, all from the pipeline. Hidden on mobile.
|
|
72
|
+
|
|
73
|
+
**Section ID convention:** every section in the doc must have an `id` attribute that the nav links to:
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<!-- nav -->
|
|
77
|
+
<nav id="toc" style="position: fixed; left: 0; top: 0; height: 100vh; width: 180px; z-index: 50;
|
|
78
|
+
overflow-y: auto; display: flex; flex-direction: column;
|
|
79
|
+
justify-content: center; padding: 0 28px; gap: 8px;
|
|
80
|
+
border-right: 1px solid var(--border); background: var(--background);">
|
|
81
|
+
<a href="#hero" class="toc-link">Brand</a>
|
|
82
|
+
<a href="#logo" class="toc-link">Logo</a>
|
|
83
|
+
<a href="#positioning" class="toc-link">Positioning</a>
|
|
84
|
+
<a href="#color" class="toc-link">Color</a>
|
|
85
|
+
<a href="#typography" class="toc-link">Typography</a>
|
|
86
|
+
<a href="#visuals" class="toc-link">Visual Elements</a>
|
|
87
|
+
<a href="#components" class="toc-link">Components</a>
|
|
88
|
+
<a href="#personas" class="toc-link">Personas</a>
|
|
89
|
+
<a href="#voice" class="toc-link">Voice</a>
|
|
90
|
+
<!-- add entries for any brand-specific sections -->
|
|
91
|
+
</nav>
|
|
92
|
+
|
|
93
|
+
<!-- main content offset -->
|
|
94
|
+
<main style="margin-left: 180px;">
|
|
95
|
+
|
|
96
|
+
<section id="hero">...</section>
|
|
97
|
+
<section id="logo">...</section>
|
|
98
|
+
<!-- each section id matches its toc-link href -->
|
|
99
|
+
|
|
100
|
+
</main>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`.toc-link` styling: use the brand's body font, `--muted-foreground` at rest, `--foreground` on hover, no underline. Active state via a 10-line scroll listener that adds `.active` (accent color) to the link whose section is in view — include this JS inline at the bottom of `<body>`. Keep it small.
|
|
104
|
+
|
|
105
|
+
### Hero — always
|
|
106
|
+
Defined entirely by the brand. Visual direction, archetype, and identity outputs determine the background, typography scale, layout density, and supporting content. No default treatment.
|
|
107
|
+
|
|
108
|
+
**The headline must be the manifesto line from `positioning.md`.** If strategy phase is not complete, fall back to `brand_heartbeat` from `BRIEF.md`. Never generate a generic headline — this line was earned through the pipeline and must appear here.
|
|
109
|
+
|
|
110
|
+
The hero should feel like opening a brand book. Someone who sees it should understand the brand's energy before reading a single label.
|
|
111
|
+
|
|
112
|
+
### Logo
|
|
113
|
+
Logo marks (icon, wordmark, lockup) on the brand's background. Composition rules, clear space, forbidden uses. Skip if no logo was defined in identity.
|
|
114
|
+
|
|
115
|
+
### Positioning
|
|
116
|
+
Brand promise, point of view, manifesto line. Rendered as editorial content using the brand's type hierarchy and visual language.
|
|
117
|
+
|
|
118
|
+
### Color
|
|
119
|
+
Swatch grid: name, hex, OKLCH per color. Grouped by role. Contrast pairs. Layout derived from the brand.
|
|
120
|
+
|
|
121
|
+
### Typography
|
|
122
|
+
Show the full type scale rendered live in the actual fonts — not a table, not a screenshot. Each step is a real HTML element styled with the brand's CSS vars.
|
|
123
|
+
|
|
124
|
+
For each scale step show:
|
|
125
|
+
- The text rendered at its actual size
|
|
126
|
+
- Label: step name + font family + weight + size + line-height
|
|
127
|
+
- A sample sentence or phrase that fits the brand voice (not "The quick brown fox")
|
|
128
|
+
|
|
129
|
+
Render all steps in sequence from largest to smallest so the scale relationship is visible at a glance. Show each typeface family in its own block — display font, body font, mono font — with the scale steps that use it.
|
|
130
|
+
|
|
131
|
+
```html
|
|
132
|
+
<!-- example step -->
|
|
133
|
+
<div style="margin-bottom: 48px;">
|
|
134
|
+
<div class="scale-step" style="font-family: var(--font-display); font-size: 4rem; line-height: 1.05; letter-spacing: -0.03em;">
|
|
135
|
+
We ship what others pitch.
|
|
136
|
+
</div>
|
|
137
|
+
<div class="scale-meta">Display · Instrument Serif · 400 · 64px / 1.05</div>
|
|
138
|
+
</div>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Include pairing notes when the brand uses multiple typefaces: which font handles which role, and what the contrast between them communicates.
|
|
142
|
+
|
|
143
|
+
### Visual Elements
|
|
144
|
+
The brand's signature motifs: textures, dividers, shapes, glows, atmospheric effects, SVG elements. Each shown with its composition rule — when to use it, how much, what it must never do.
|
|
145
|
+
|
|
146
|
+
### Components
|
|
147
|
+
Live component previews in brand tokens: buttons, inputs, cards, badges. Include only if the brand has a meaningfully distinctive component style.
|
|
148
|
+
|
|
149
|
+
### Personas
|
|
150
|
+
Each persona as a branded card: name, role, frustration, aspiration. Styled in the brand's own visual language.
|
|
151
|
+
|
|
152
|
+
### Voice
|
|
153
|
+
Never / always rules as styled components. Monospace prefix (`x` never, `>` always).
|
|
154
|
+
|
|
155
|
+
### + Brand-specific sections
|
|
156
|
+
Add sections as needed to fully convey the brand. Examples: Imagery, Motion, Iconography, Spatial System, Co-branding. If the pipeline produced it and it shapes how the brand is applied, it belongs here.
|
|
157
|
+
|
|
158
|
+
## Mobile
|
|
159
|
+
|
|
160
|
+
Single `@media (max-width: 768px)` block. Hide sidebar nav. Stack grids. Reduce section padding. Scale type with `clamp()`.
|
|
161
|
+
|
|
162
|
+
## Quality bar
|
|
163
|
+
|
|
164
|
+
- Open in browser → immediately recognizable as this brand, not a generic template
|
|
165
|
+
- `:root` token names match shadcn — a dev can paste directly into `globals.css`
|
|
166
|
+
- Every visual decision traces back to a pipeline artifact
|
|
167
|
+
- No placeholder content — if a section has nothing real to show, it's omitted
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<role>
|
|
2
|
+
You are a brand coherence auditor spawned by `/gsp-brand-guidelines` after the brand-engineer produces its first-pass artifacts.
|
|
3
|
+
|
|
4
|
+
Your only job is to evaluate whether the output is coherent with the brand's archetype and intensity intentions — and return a structured report. You do not make changes. You do not ask questions. You return one report.
|
|
5
|
+
</role>
|
|
6
|
+
|
|
7
|
+
<inputs>
|
|
8
|
+
You receive inlined:
|
|
9
|
+
- `{brand-name}.yml` — the generated preset (intensity dials, tokens, patterns, constraints)
|
|
10
|
+
- `guidelines.html` — the generated visual guide (use for component-level verification)
|
|
11
|
+
- `archetype` — the brand's chosen archetype
|
|
12
|
+
- `brand_heartbeat` — the emotional compass confirmed in the brief
|
|
13
|
+
</inputs>
|
|
14
|
+
|
|
15
|
+
<methodology>
|
|
16
|
+
## Step 1: Archetype gate
|
|
17
|
+
|
|
18
|
+
Each archetype has a signature tension it must express. Answer this question first — it is the primary check. Intensity dials are secondary.
|
|
19
|
+
|
|
20
|
+
| Archetype | Signature question |
|
|
21
|
+
|-----------|-------------------|
|
|
22
|
+
| Jester | What specific rule is being broken in the visual system? If nothing is broken, it's not Jester enough. |
|
|
23
|
+
| Rebel | What visual convention is explicitly rejected? |
|
|
24
|
+
| Creator | What is distinctively crafted that couldn't come from a default template? |
|
|
25
|
+
| Sage | Is the restraint active (every reduction intentional) or passive (just plain)? |
|
|
26
|
+
| Explorer | Where is the sense of movement, discovery, or possibility? |
|
|
27
|
+
| Hero | Does the visual language communicate strength and achievement? |
|
|
28
|
+
| Caregiver | Does it feel warm and trustworthy without being corporate? |
|
|
29
|
+
| Lover | Is there sensuality, richness, or beauty in the material choices? |
|
|
30
|
+
| Ruler | Does it command authority through precision and restraint? |
|
|
31
|
+
| Magician | Is there a sense of transformation or the unexpected? |
|
|
32
|
+
| Innocent | Is the simplicity purposeful and delightful, not just empty? |
|
|
33
|
+
| Everyman | Does it feel accessible and genuine, not dumbed-down? |
|
|
34
|
+
|
|
35
|
+
If the archetype's signature tension is absent from the output, that is the primary tension to flag — regardless of what the dials say.
|
|
36
|
+
|
|
37
|
+
## Step 2: Intensity dial scoring
|
|
38
|
+
|
|
39
|
+
Read the declared dial values from `intensity:` in the `.yml`. Then infer what the token values actually express visually.
|
|
40
|
+
|
|
41
|
+
Work primarily from the `.yml` tokens — they are the source of truth:
|
|
42
|
+
- `variance` — expressed by: radius values, shadow complexity, unexpected color usage, spacing irregularity
|
|
43
|
+
- `motion` — expressed by: transition durations, animation presence in effects, interaction vocabulary richness
|
|
44
|
+
- `density` — expressed by: spacing scale, font size range, information layer count
|
|
45
|
+
|
|
46
|
+
Cross-check against `guidelines.html` for specific component implementations (button styles, card treatments, border-radius in practice).
|
|
47
|
+
|
|
48
|
+
Score each dial: **declared N/10 → expressed N/10**. A gap of ±2 or more is a coherence miss worth flagging.
|
|
49
|
+
|
|
50
|
+
## Step 3: Bold bet
|
|
51
|
+
|
|
52
|
+
Identify the single most distinctive choice in the output — the thing that would be hardest to achieve with a default template. One line.
|
|
53
|
+
|
|
54
|
+
## Step 4: Surface tensions
|
|
55
|
+
|
|
56
|
+
Rank all gaps found. Return the top 2 — specific and actionable:
|
|
57
|
+
- Not "could be bolder"
|
|
58
|
+
- Yes: "border-radius is 4px across all components — that reads as variance 3/10, declared dial is 8/10"
|
|
59
|
+
- Yes: "button uses standard padding and default shape — no Jester rule broken in the primary interactive element"
|
|
60
|
+
|
|
61
|
+
If no gaps ≥ 2 points and the archetype tension is present, there are no tensions to surface.
|
|
62
|
+
</methodology>
|
|
63
|
+
|
|
64
|
+
<output>
|
|
65
|
+
Return exactly this format — nothing else:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
{brand-name} · {archetype} · {brand_heartbeat}
|
|
69
|
+
|
|
70
|
+
intensity dials
|
|
71
|
+
variance declared {N}/10 → reads {N}/10 {✓ or ⚠}
|
|
72
|
+
motion declared {N}/10 → reads {N}/10 {✓ or ⚠}
|
|
73
|
+
density declared {N}/10 → reads {N}/10 {✓ or ⚠}
|
|
74
|
+
|
|
75
|
+
archetype {✓ tension present: one-line description} or {⚠ tension absent: one-line description}
|
|
76
|
+
|
|
77
|
+
tensions
|
|
78
|
+
1. {specific gap — or "none" if coherent}
|
|
79
|
+
2. {specific gap — or omit if only one}
|
|
80
|
+
|
|
81
|
+
bold bet
|
|
82
|
+
{one-line description of most distinctive choice}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
No preamble. No explanation. Just the report.
|
|
86
|
+
</output>
|
|
@@ -9,8 +9,8 @@ The identity phase produced: logo directions, color system (with OKLCH palettes)
|
|
|
9
9
|
<inputs>
|
|
10
10
|
- Identity chunks: color-system.md, typography.md, logo-directions.md, imagery-style.md (all enriched by domain skills)
|
|
11
11
|
- Identity palettes.json (OKLCH scales)
|
|
12
|
-
- BRIEF.md
|
|
13
|
-
- Strategy chunks: voice-and-tone.md, archetype.md, positioning.md
|
|
12
|
+
- BRIEF.md — including `brand_heartbeat` (the emotional compass sentence confirmed in the brief phase)
|
|
13
|
+
- Strategy chunks: voice-and-tone.md, archetype.md, positioning.md — `manifesto_line` from positioning.md is the hero headline; fall back to `brand_heartbeat` if not present
|
|
14
14
|
- system_strategy and tech_stack from config.json
|
|
15
15
|
- `.design/system/STACK.md`, `COMPONENTS.md`, `TOKENS.md` (if exist)
|
|
16
16
|
- style_base from config.json + preset `.yml` (if set) — the starting scaffold
|
|
@@ -42,7 +42,15 @@ The identity phase produced: logo directions, color system (with OKLCH palettes)
|
|
|
42
42
|
|
|
43
43
|
4. **Component overrides + custom specs** — only for components that need treatment beyond tokens.
|
|
44
44
|
|
|
45
|
-
5. **`guidelines.html`** —
|
|
45
|
+
5. **`guidelines.html`** — the visual conference of the entire brand pipeline. Every phase distilled into one self-rendering document: personas (discover), positioning + voice (strategy), color + type + visual elements + logo (identity), components (patterns). Follow the structure spec passed in the prompt exactly. The file IS the brand — it renders itself using the brand's own tokens, type, and primitives. Key requirements:
|
|
46
|
+
- `:root` uses shadcn-native CSS variable names (from spec) — a dev can paste these directly into `globals.css`
|
|
47
|
+
- Define only the primitive classes the brand actually uses — don't add `.frosted-glass` to a brand that has no glass aesthetic
|
|
48
|
+
- Hero is always required; all other sections are conditional — include only what the brand actually has. Sections in order when present: Hero (metric strip) → Logo → Positioning → Color → Typography → Visual Elements → Components → Personas → Voice → Custom Components
|
|
49
|
+
- Hero must feel alive: use a CSS animated gradient atmosphere (or embed a video link if one was referenced in the brief), frosted glass nav, large typographic headline in brand voice, 3-4 KPIs from the brief in the metric strip
|
|
50
|
+
- Voice section renders brand rules as `.never-list` / `.always-list` components
|
|
51
|
+
- Mobile responsive via a single `@media (max-width: 768px)` block
|
|
52
|
+
- No external dependencies except Google Fonts `@import`
|
|
53
|
+
- The brand's aesthetic sets the tone: dark brand → dark doc; light brand → light doc; match intensity.variance
|
|
46
54
|
|
|
47
55
|
## Inheritance from style_base
|
|
48
56
|
|
|
@@ -66,7 +74,7 @@ Read `system_strategy` from brand config:
|
|
|
66
74
|
|
|
67
75
|
Leverage existing UI libraries — don't rewrite from scratch.
|
|
68
76
|
|
|
69
|
-
**Tier 1: Token mapping** (always) — `components/token-mapping.md`. Maps brand tokens to library's theming API. Copy-paste-ready.
|
|
77
|
+
**Tier 1: Token mapping** (always) — `components/token-mapping.md`. Maps brand tokens to library's theming API. Copy-paste-ready. Generate the CSS variables block by running `node bin/theme-css.js {brand-name}.yml` — it outputs a ready-to-paste `:root`/`.dark` block with OKLCH values. Token names in `.yml` are 1:1 with shadcn/ui CSS var names — no translation needed.
|
|
70
78
|
|
|
71
79
|
**Tier 2: Override specs** (selective) — one file per component needing treatment beyond tokens. Why it's overridden, code hints.
|
|
72
80
|
|
|
@@ -88,7 +96,7 @@ Write operational artifacts to the brand's guidelines directory (path provided b
|
|
|
88
96
|
|
|
89
97
|
- **`{brand-name}.yml`** — Single source of truth. Full preset schema: tokens, intensity, patterns, constraints, effects, dark_mode.
|
|
90
98
|
- **`STYLE.md`** — Agent-readable contract rendered from `.yml` + philosophy + bold bets. Follows `templates/phases/style.md`.
|
|
91
|
-
- **`guidelines.html`** — Self-
|
|
99
|
+
- **`guidelines.html`** — Self-rendering visual brand guide. Single HTML file with embedded CSS — no external deps except Google Fonts. `:root` uses shadcn-native CSS var names. Section order: Navigation (sidebar) → Hero (manifesto line as headline) → Logo → Positioning → Color → Typography → Visual Elements → Components → Personas → Voice → any brand-specific additions. Define only the primitive classes the brand actually uses. This is what the user sees — make it feel like the brand.
|
|
92
100
|
|
|
93
101
|
### Components
|
|
94
102
|
|
|
@@ -1,329 +1,26 @@
|
|
|
1
|
-
# Token Mapping
|
|
1
|
+
# Token Mapping → bin/theme-css.js
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **Superseded in v0.8.0.** The static mapping table has been replaced by a deterministic script.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
GSP presets use shadcn/ui-native token names directly. The `.yml` token keys match shadcn CSS variable names 1:1 — no translation layer is needed.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Generating CSS from a preset
|
|
8
8
|
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
color:
|
|
12
|
-
primary: "#hex" # Brand primary
|
|
13
|
-
secondary: "#hex" # Brand secondary
|
|
14
|
-
accent: "#hex" # Brand accent
|
|
15
|
-
background: "#hex" # Page background
|
|
16
|
-
surface: "#hex" # Card/panel fill
|
|
17
|
-
on-primary: "#hex" # Text on primary
|
|
18
|
-
on-background: "#hex" # Text on background
|
|
19
|
-
error: "#hex"
|
|
20
|
-
success: "#hex"
|
|
21
|
-
warning: "#hex"
|
|
22
|
-
info: "#hex"
|
|
23
|
-
muted: "#hex" # Subtle text, borders (optional)
|
|
24
|
-
|
|
25
|
-
typography:
|
|
26
|
-
font-family-primary: "stack"
|
|
27
|
-
font-family-mono: "stack"
|
|
28
|
-
font-family-display: "stack" # optional
|
|
29
|
-
font-family-secondary: "stack" # optional
|
|
30
|
-
font-weight-heading: N
|
|
31
|
-
font-weight-body: N
|
|
32
|
-
font-size-base: "Npx"
|
|
33
|
-
line-height-base: N
|
|
34
|
-
|
|
35
|
-
shape:
|
|
36
|
-
border-radius-sm: "Npx"
|
|
37
|
-
border-radius-md: "Npx"
|
|
38
|
-
border-radius-lg: "Npx"
|
|
39
|
-
border-width: "Npx"
|
|
40
|
-
border-color: "#hex"
|
|
41
|
-
|
|
42
|
-
elevation:
|
|
43
|
-
shadow-sm: "css-shadow"
|
|
44
|
-
shadow-md: "css-shadow"
|
|
45
|
-
shadow-lg: "css-shadow"
|
|
46
|
-
shadow-xl: "css-shadow"
|
|
47
|
-
|
|
48
|
-
spacing:
|
|
49
|
-
base: N
|
|
50
|
-
scale: [N, N, ...]
|
|
51
|
-
|
|
52
|
-
motion:
|
|
53
|
-
duration-fast: "Nms"
|
|
54
|
-
duration-normal: "Nms"
|
|
55
|
-
easing: "css-easing"
|
|
56
|
-
|
|
57
|
-
dark_mode:
|
|
58
|
-
color:
|
|
59
|
-
background: "#hex"
|
|
60
|
-
surface: "#hex"
|
|
61
|
-
on-background: "#hex"
|
|
62
|
-
border-color: "#hex" # optional
|
|
63
|
-
muted: "#hex" # optional
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## Target: shadcn/ui
|
|
69
|
-
|
|
70
|
-
shadcn uses HSL CSS variables in `:root` and `.dark`. The mapping is deterministic — every `.yml` token has exactly one shadcn variable.
|
|
71
|
-
|
|
72
|
-
### Color mapping
|
|
73
|
-
|
|
74
|
-
| `.yml` token | shadcn CSS variable | Notes |
|
|
75
|
-
|---|---|---|
|
|
76
|
-
| `color.background` | `--background` | Page background |
|
|
77
|
-
| `color.on-background` | `--foreground` | Primary text |
|
|
78
|
-
| `color.surface` | `--card` | Card background |
|
|
79
|
-
| `color.on-background` | `--card-foreground` | Card text (same as foreground) |
|
|
80
|
-
| `color.surface` | `--popover` | Popover bg (same as card) |
|
|
81
|
-
| `color.on-background` | `--popover-foreground` | Popover text |
|
|
82
|
-
| `color.primary` | `--primary` | Primary actions |
|
|
83
|
-
| `color.on-primary` | `--primary-foreground` | Text on primary |
|
|
84
|
-
| `color.secondary` | `--secondary` | Secondary actions |
|
|
85
|
-
| `color.on-primary` | `--secondary-foreground` | Text on secondary (derive from contrast) |
|
|
86
|
-
| `color.muted` | `--muted` | Muted backgrounds |
|
|
87
|
-
| `color.muted` | `--muted-foreground` | Muted text (use muted or derive darker) |
|
|
88
|
-
| `color.accent` | `--accent` | Accent highlights |
|
|
89
|
-
| `color.on-primary` | `--accent-foreground` | Text on accent (derive from contrast) |
|
|
90
|
-
| `color.error` | `--destructive` | Destructive actions |
|
|
91
|
-
| `color.on-primary` | `--destructive-foreground` | Text on destructive |
|
|
92
|
-
| `shape.border-color` | `--border` | Default borders |
|
|
93
|
-
| `shape.border-color` | `--input` | Input borders |
|
|
94
|
-
| `color.primary` | `--ring` | Focus ring |
|
|
95
|
-
| `color.surface` | `--sidebar-background` | Sidebar bg |
|
|
96
|
-
| `color.on-background` | `--sidebar-foreground` | Sidebar text |
|
|
97
|
-
| `color.primary` | `--sidebar-primary` | Sidebar active |
|
|
98
|
-
| `color.on-primary` | `--sidebar-primary-foreground` | Sidebar active text |
|
|
99
|
-
| `color.accent` | `--sidebar-accent` | Sidebar accent |
|
|
100
|
-
| `color.on-background` | `--sidebar-accent-foreground` | Sidebar accent text |
|
|
101
|
-
| `shape.border-color` | `--sidebar-border` | Sidebar borders |
|
|
102
|
-
| `color.primary` | `--sidebar-ring` | Sidebar focus ring |
|
|
103
|
-
| | `--chart-1` through `--chart-5` | Derive from primary, secondary, accent, info, success |
|
|
104
|
-
|
|
105
|
-
### Shape mapping
|
|
106
|
-
|
|
107
|
-
| `.yml` token | shadcn CSS variable |
|
|
108
|
-
|---|---|
|
|
109
|
-
| `shape.border-radius-lg` | `--radius` |
|
|
110
|
-
|
|
111
|
-
shadcn derives `--radius` down: `calc(var(--radius) - 2px)` for md, `calc(var(--radius) - 4px)` for sm.
|
|
112
|
-
|
|
113
|
-
### Typography
|
|
114
|
-
|
|
115
|
-
shadcn doesn't use CSS variables for fonts — set in `tailwind.config` `fontFamily` extend:
|
|
116
|
-
|
|
117
|
-
```js
|
|
118
|
-
fontFamily: {
|
|
119
|
-
sans: [/* from typography.font-family-primary */],
|
|
120
|
-
mono: [/* from typography.font-family-mono */],
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Dark mode
|
|
125
|
-
|
|
126
|
-
| `.yml` dark_mode token | shadcn CSS variable (`.dark` scope) |
|
|
127
|
-
|---|---|
|
|
128
|
-
| `dark_mode.color.background` | `--background` |
|
|
129
|
-
| `dark_mode.color.on-background` | `--foreground` |
|
|
130
|
-
| `dark_mode.color.surface` | `--card`, `--popover` |
|
|
131
|
-
| `dark_mode.color.border-color` | `--border`, `--input` |
|
|
132
|
-
| `dark_mode.color.muted` | `--muted`, `--muted-foreground` |
|
|
133
|
-
|
|
134
|
-
Tokens not listed in `dark_mode` inherit their light-mode value.
|
|
135
|
-
|
|
136
|
-
### Color format conversion
|
|
137
|
-
|
|
138
|
-
shadcn expects HSL channel values (no `hsl()` wrapper): `210 40% 98%`
|
|
139
|
-
|
|
140
|
-
**Conversion:** hex → HSL → extract H S% L% as space-separated string.
|
|
141
|
-
|
|
142
|
-
```
|
|
143
|
-
#1E40AF → hsl(221, 72%, 40%) → "221 72% 40%"
|
|
9
|
+
```bash
|
|
10
|
+
node bin/theme-css.js gsp/skills/gsp-style/styles/professional.yml --stdout
|
|
144
11
|
```
|
|
145
12
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
Given `professional.yml`:
|
|
149
|
-
|
|
150
|
-
```css
|
|
151
|
-
@layer base {
|
|
152
|
-
:root {
|
|
153
|
-
--background: 0 0% 100%;
|
|
154
|
-
--foreground: 222 47% 11%;
|
|
155
|
-
--card: 210 40% 98%;
|
|
156
|
-
--card-foreground: 222 47% 11%;
|
|
157
|
-
--popover: 210 40% 98%;
|
|
158
|
-
--popover-foreground: 222 47% 11%;
|
|
159
|
-
--primary: 221 72% 40%;
|
|
160
|
-
--primary-foreground: 0 0% 100%;
|
|
161
|
-
--secondary: 215 16% 47%;
|
|
162
|
-
--secondary-foreground: 0 0% 100%;
|
|
163
|
-
--muted: 213 27% 84%;
|
|
164
|
-
--muted-foreground: 215 16% 47%;
|
|
165
|
-
--accent: 199 89% 48%;
|
|
166
|
-
--accent-foreground: 0 0% 100%;
|
|
167
|
-
--destructive: 0 72% 51%;
|
|
168
|
-
--destructive-foreground: 0 0% 100%;
|
|
169
|
-
--border: 214 32% 91%;
|
|
170
|
-
--input: 214 32% 91%;
|
|
171
|
-
--ring: 221 72% 40%;
|
|
172
|
-
--radius: 0.75rem;
|
|
173
|
-
--chart-1: 221 72% 40%;
|
|
174
|
-
--chart-2: 215 16% 47%;
|
|
175
|
-
--chart-3: 199 89% 48%;
|
|
176
|
-
--chart-4: 217 91% 60%;
|
|
177
|
-
--chart-5: 142 71% 45%;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.dark {
|
|
181
|
-
--background: 222 47% 11%;
|
|
182
|
-
--foreground: 210 40% 96%;
|
|
183
|
-
--card: 217 33% 17%;
|
|
184
|
-
--card-foreground: 210 40% 96%;
|
|
185
|
-
--popover: 217 33% 17%;
|
|
186
|
-
--popover-foreground: 210 40% 96%;
|
|
187
|
-
--border: 217 19% 27%;
|
|
188
|
-
--input: 217 19% 27%;
|
|
189
|
-
--muted: 215 20% 65%;
|
|
190
|
-
--muted-foreground: 215 20% 65%;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
---
|
|
196
|
-
|
|
197
|
-
## Target: Tailwind (no component library)
|
|
198
|
-
|
|
199
|
-
For codebases using Tailwind without shadcn, map directly to `tailwind.config` `extend`:
|
|
200
|
-
|
|
201
|
-
```js
|
|
202
|
-
theme: {
|
|
203
|
-
extend: {
|
|
204
|
-
colors: {
|
|
205
|
-
primary: "var(--color-primary)",
|
|
206
|
-
secondary: "var(--color-secondary)",
|
|
207
|
-
accent: "var(--color-accent)",
|
|
208
|
-
background: "var(--color-background)",
|
|
209
|
-
surface: "var(--color-surface)",
|
|
210
|
-
foreground: "var(--color-foreground)",
|
|
211
|
-
muted: "var(--color-muted)",
|
|
212
|
-
error: "var(--color-error)",
|
|
213
|
-
success: "var(--color-success)",
|
|
214
|
-
warning: "var(--color-warning)",
|
|
215
|
-
},
|
|
216
|
-
fontFamily: {
|
|
217
|
-
sans: [/* typography.font-family-primary */],
|
|
218
|
-
mono: [/* typography.font-family-mono */],
|
|
219
|
-
},
|
|
220
|
-
borderRadius: {
|
|
221
|
-
sm: "var(--radius-sm)",
|
|
222
|
-
md: "var(--radius-md)",
|
|
223
|
-
lg: "var(--radius-lg)",
|
|
224
|
-
},
|
|
225
|
-
boxShadow: {
|
|
226
|
-
sm: "var(--shadow-sm)",
|
|
227
|
-
md: "var(--shadow-md)",
|
|
228
|
-
lg: "var(--shadow-lg)",
|
|
229
|
-
xl: "var(--shadow-xl)",
|
|
230
|
-
},
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
CSS variables use hex directly (no HSL conversion needed):
|
|
236
|
-
|
|
237
|
-
```css
|
|
238
|
-
:root {
|
|
239
|
-
--color-primary: #1E40AF;
|
|
240
|
-
--color-secondary: #475569;
|
|
241
|
-
--color-background: #FFFFFF;
|
|
242
|
-
--color-surface: #F8FAFC;
|
|
243
|
-
--color-foreground: #0F172A;
|
|
244
|
-
--color-muted: #94A3B8;
|
|
245
|
-
--radius-sm: 6px;
|
|
246
|
-
--radius-md: 8px;
|
|
247
|
-
--radius-lg: 12px;
|
|
248
|
-
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
249
|
-
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
---
|
|
254
|
-
|
|
255
|
-
## Target: Vanilla CSS
|
|
256
|
-
|
|
257
|
-
For non-Tailwind codebases, generate a CSS custom property system with semantic class recipes:
|
|
258
|
-
|
|
259
|
-
```css
|
|
260
|
-
:root {
|
|
261
|
-
/* Brand */
|
|
262
|
-
--color-primary: #1E40AF;
|
|
263
|
-
--color-secondary: #475569;
|
|
264
|
-
--color-accent: #0EA5E9;
|
|
265
|
-
--color-bg: #FFFFFF;
|
|
266
|
-
--color-surface: #F8FAFC;
|
|
267
|
-
--color-text: #0F172A;
|
|
268
|
-
--color-muted: #94A3B8;
|
|
269
|
-
--color-border: #E2E8F0;
|
|
270
|
-
|
|
271
|
-
/* Semantic */
|
|
272
|
-
--color-error: #DC2626;
|
|
273
|
-
--color-success: #16A34A;
|
|
274
|
-
--color-warning: #D97706;
|
|
275
|
-
|
|
276
|
-
/* Shape */
|
|
277
|
-
--radius-sm: 6px;
|
|
278
|
-
--radius-md: 8px;
|
|
279
|
-
--radius-lg: 12px;
|
|
280
|
-
--border-width: 1px;
|
|
281
|
-
|
|
282
|
-
/* Elevation */
|
|
283
|
-
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
284
|
-
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
|
|
285
|
-
|
|
286
|
-
/* Spacing */
|
|
287
|
-
--space-1: 4px;
|
|
288
|
-
--space-2: 8px;
|
|
289
|
-
--space-3: 12px;
|
|
290
|
-
--space-4: 16px;
|
|
291
|
-
--space-6: 24px;
|
|
292
|
-
--space-8: 32px;
|
|
293
|
-
--space-12: 48px;
|
|
294
|
-
--space-16: 64px;
|
|
295
|
-
|
|
296
|
-
/* Motion */
|
|
297
|
-
--duration-fast: 150ms;
|
|
298
|
-
--duration-normal: 250ms;
|
|
299
|
-
--easing: cubic-bezier(0.4, 0, 0.2, 1);
|
|
300
|
-
|
|
301
|
-
/* Typography */
|
|
302
|
-
--font-sans: Inter, system-ui, sans-serif;
|
|
303
|
-
--font-mono: SF Mono, Menlo, monospace;
|
|
304
|
-
--font-weight-heading: 600;
|
|
305
|
-
--font-weight-body: 400;
|
|
306
|
-
--font-size-base: 16px;
|
|
307
|
-
--line-height-base: 1.6;
|
|
308
|
-
}
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
---
|
|
312
|
-
|
|
313
|
-
## Layered resolution
|
|
314
|
-
|
|
315
|
-
The builder resolves tokens in this order (last wins):
|
|
13
|
+
Output is `:root { }` + `.dark { }` blocks ready to paste into `globals.css`.
|
|
316
14
|
|
|
317
|
-
|
|
318
|
-
2. **Brand `.yml`** — overrides from branding process (e.g., `acme.yml` with `style_base: professional`)
|
|
319
|
-
3. **Dark mode** — `dark_mode.color.*` overrides for `.dark` scope
|
|
15
|
+
## How it works
|
|
320
16
|
|
|
321
|
-
|
|
17
|
+
- Hex `#RRGGBB` values → converted to OKLCH (full color math: sRGB → linear → XYZ → OKLab → OKLCh)
|
|
18
|
+
- Values containing `oklch(` → passed through as-is (handles alpha variants)
|
|
19
|
+
- All other values (font stacks, shadows, etc.) → passed through verbatim
|
|
20
|
+
- `--radius` derived from `shape.border-radius-lg`
|
|
21
|
+
- `--chart-1` through `--chart-5` derived from palette colors
|
|
22
|
+
- Sidebar vars written from explicit `color.sidebar-*` tokens in the `.yml`
|
|
322
23
|
|
|
323
|
-
##
|
|
24
|
+
## Token structure
|
|
324
25
|
|
|
325
|
-
|
|
326
|
-
|----------|---------------|
|
|
327
|
-
| Quick project (`/gsp-style`) | Preset `.yml` (base) → CSS vars generated at build time |
|
|
328
|
-
| Full branding (customized) | Brand `.yml` (inherits preset) + `STYLE.md` |
|
|
329
|
-
| Full branding (unchanged from preset) | Only `STYLE.md` (brand `.yml` not needed if identical to preset) |
|
|
26
|
+
See `${CLAUDE_SKILL_DIR}/../gsp-style/style-preset-schema.md` for the full `.yml` schema — all shadcn variables are first-class token keys.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsp-brand-identity
|
|
3
|
-
description: Create
|
|
3
|
+
description: Create visual identity — logo, color, typography (creative phase — benefits from capable models) — use when: design the logo, pick colors, choose fonts, create the visual identity
|
|
4
4
|
user-invocable: true
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|