brandspec 0.1.0

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/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "brandspec",
3
+ "version": "0.1.0",
4
+ "description": "Define Brand Identity as code. CLI for creating, validating, and generating brand tokens.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "bin": {
10
+ "brandspec": "./dist/cli.js"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "schema",
22
+ "workshop"
23
+ ],
24
+ "engines": {
25
+ "node": ">=18.0.0"
26
+ },
27
+ "scripts": {
28
+ "build": "tsup --config cli/tsup.config.ts",
29
+ "dev": "tsup --config cli/tsup.config.ts --watch",
30
+ "typecheck": "tsc -p cli/tsconfig.json --noEmit",
31
+ "test": "node --test cli/test/*.test.mjs",
32
+ "prepublishOnly": "npm run build && npm test"
33
+ },
34
+ "dependencies": {
35
+ "ajv": "^8.17.1",
36
+ "ajv-formats": "^3.0.1",
37
+ "js-yaml": "^4.1.0",
38
+ "jszip": "^3.10.1"
39
+ },
40
+ "devDependencies": {
41
+ "@types/js-yaml": "^4.0.9",
42
+ "@types/node": "^22.0.0",
43
+ "tsup": "^8.3.0",
44
+ "typescript": "^5.7.0"
45
+ },
46
+ "keywords": [
47
+ "brandspec",
48
+ "brand",
49
+ "identity",
50
+ "design-tokens",
51
+ "yaml",
52
+ "workshop",
53
+ "ai"
54
+ ],
55
+ "license": "MIT",
56
+ "homepage": "https://brandspec.dev",
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "https://github.com/brandspec/brandspec"
60
+ }
61
+ }
@@ -0,0 +1,219 @@
1
+ # Assets Specification
2
+
3
+ Machine-readable specification for the `assets` section of brand.yaml.
4
+
5
+ ## Structure
6
+
7
+ ```yaml
8
+ assets:
9
+ - file: "path/to/file.svg" # Required. Relative to brandspec/.
10
+ id: "logo-primary" # Recommended. Unique semantic identifier.
11
+ role: "logo" # Recommended. What the asset is.
12
+ variant: "primary" # Optional. Which variation.
13
+ context: "light-bg" # Optional. Usage context.
14
+ description: "Primary logo" # Optional. Human-readable description.
15
+ formats: [...] # Optional. Derived formats.
16
+ tags: [...] # Optional. Free-form tags.
17
+ ```
18
+
19
+ Only `file` is required. A minimal valid entry:
20
+
21
+ ```yaml
22
+ assets:
23
+ - file: logo.svg
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Fields
29
+
30
+ ### `file` (required)
31
+
32
+ Relative file path from `brandspec/` directory.
33
+
34
+ ### `id` (recommended)
35
+
36
+ Unique semantic identifier for programmatic access. Use `{role}-{variant}` pattern.
37
+
38
+ ### `role` (recommended)
39
+
40
+ What the asset is used for.
41
+
42
+ | Role | Description |
43
+ |------|-------------|
44
+ | `logo` | Main logo (may include wordmark) |
45
+ | `wordmark` | Text-only logo |
46
+ | `symbol` | Icon/symbol mark (no text) |
47
+ | `icon` | Small icon (app icon, etc.) |
48
+ | `favicon` | Browser favicon |
49
+ | `graphic` | General graphic asset |
50
+ | `pattern` | Repeating pattern/texture |
51
+ | `photo` | Photography |
52
+ | `illustration` | Illustrations |
53
+ | `video` | Video content |
54
+ | `audio` | Audio (sound logo, etc.) |
55
+ | `document` | Documents (guidelines PDF, etc.) |
56
+ | `font` | Font files |
57
+
58
+ Custom values are allowed.
59
+
60
+ ### `variant` (optional)
61
+
62
+ Which variation of the asset.
63
+
64
+ | Variant | Description |
65
+ |---------|-------------|
66
+ | `primary` | Main version |
67
+ | `secondary` | Alternative version |
68
+ | `monochrome` | Single color |
69
+ | `inverse` | Inverted (for dark backgrounds) |
70
+ | `simplified` | Simplified version (small sizes) |
71
+ | `vertical` | Vertical layout |
72
+ | `horizontal` | Horizontal layout |
73
+
74
+ Custom values are allowed.
75
+
76
+ ### `context` (optional)
77
+
78
+ Intended usage context.
79
+
80
+ | Context | Description |
81
+ |---------|-------------|
82
+ | `light-bg` | For light backgrounds |
83
+ | `dark-bg` | For dark backgrounds |
84
+ | `any` | Works on any background |
85
+ | `print` | For print use |
86
+ | `digital` | For digital/screen use |
87
+ | `social` | For social media |
88
+
89
+ ### `formats` (optional)
90
+
91
+ Derived formats (different sizes, file types):
92
+
93
+ ```yaml
94
+ formats:
95
+ - path: assets/logo-primary.png
96
+ width: 800
97
+ height: 200
98
+ - path: assets/logo-primary@2x.png
99
+ width: 1600
100
+ height: 400
101
+ ```
102
+
103
+ ### `tags` (optional)
104
+
105
+ Free-form tags for categorization:
106
+
107
+ ```yaml
108
+ tags: [header, official, print, marketing]
109
+ ```
110
+
111
+ ---
112
+
113
+ ## File Naming Convention
114
+
115
+ Pattern: `{role}-{variant}[-{context}].{ext}`
116
+
117
+ | Example | Role | Variant | Context |
118
+ |---------|------|---------|---------|
119
+ | `logo-primary.svg` | logo | primary | — |
120
+ | `logo-monochrome.svg` | logo | monochrome | — |
121
+ | `logo-inverse-dark-bg.svg` | logo | inverse | dark-bg |
122
+ | `favicon.ico` | favicon | — | — |
123
+ | `symbol-simplified.svg` | symbol | simplified | — |
124
+
125
+ ---
126
+
127
+ ## Directory Structure
128
+
129
+ ```
130
+ brandspec/
131
+ ├── brand.yaml
132
+ └── assets/
133
+ ├── logo-primary.svg
134
+ ├── logo-monochrome.svg
135
+ ├── logo-inverse.svg
136
+ ├── symbol.svg
137
+ ├── favicon.ico
138
+ └── icon-app.png
139
+ ```
140
+
141
+ Assets are stored in `brandspec/assets/` and referenced from `brand.yaml` with relative paths.
142
+
143
+ ---
144
+
145
+ ## Logo System Patterns
146
+
147
+ Brands use one of four fundamental logo system patterns. Each determines required assets.
148
+
149
+ ### Pattern A: Wordmark
150
+
151
+ Typography is the identity. Text-only or stylized text mark.
152
+
153
+ | Attribute | Detail |
154
+ |-----------|--------|
155
+ | Examples | Google, FedEx, Coca-Cola, Supreme, IBM |
156
+ | Best for | Strong names, text-centric brands |
157
+ | Required assets | `wordmark` (+ variants) |
158
+
159
+ ### Pattern B: Symbol + Wordmark (separated)
160
+
161
+ Independent symbol and wordmark, used separately or combined.
162
+
163
+ | Attribute | Detail |
164
+ |-----------|--------|
165
+ | Examples | Apple, Nike, Spotify, Slack, Airbnb |
166
+ | Best for | Apps needing an icon, long-term symbol recognition |
167
+ | Required assets | `symbol`, `wordmark` |
168
+ | Optional assets | `logo-horizontal`, `logo-vertical` (combined layouts) |
169
+
170
+ ### Pattern C: Combination Mark (integrated)
171
+
172
+ Symbol and text form a single inseparable unit.
173
+
174
+ | Attribute | Detail |
175
+ |-----------|--------|
176
+ | Examples | Adidas, Burger King, Lacoste |
177
+ | Best for | Early-stage brands, consistency priority |
178
+ | Required assets | `logo` (integrated unit) |
179
+ | Optional assets | `symbol` (extracted for favicon) |
180
+
181
+ ### Pattern D: Emblem
182
+
183
+ Text enclosed within or integral to a shape.
184
+
185
+ | Attribute | Detail |
186
+ |-----------|--------|
187
+ | Examples | Starbucks, BMW, NFL, university crests |
188
+ | Best for | Heritage, authority, luxury, institutional |
189
+ | Required assets | `logo` (full emblem) |
190
+ | Optional assets | `logo-simplified` (reduced detail for small sizes) |
191
+
192
+ ### Pattern Summary
193
+
194
+ > Shorthand names map to `role` + `variant` fields (e.g. `logo-simplified` = `role: logo, variant: simplified`).
195
+
196
+ ```yaml
197
+ logo_system_patterns:
198
+ wordmark:
199
+ required: [wordmark]
200
+ symbol_wordmark:
201
+ required: [symbol, wordmark]
202
+ optional: [logo-horizontal, logo-vertical]
203
+ combined:
204
+ required: [logo]
205
+ optional: [symbol]
206
+ emblem:
207
+ required: [logo]
208
+ optional: [logo-simplified]
209
+ ```
210
+
211
+ ### Recommended Variants (all patterns)
212
+
213
+ | Variant | Purpose | Priority |
214
+ |---------|---------|----------|
215
+ | `primary` | Standard use on light backgrounds | Required |
216
+ | `inverse` | Use on dark backgrounds | High |
217
+ | `monochrome` | Single-color constraints | High |
218
+ | `simplified` | Small sizes (favicon, 16–32px) | Medium |
219
+ | `vertical` / `horizontal` | Layout variants (Pattern B: symbol + wordmark combined) | Pattern B only |
@@ -0,0 +1,203 @@
1
+ # Core Specification
2
+
3
+ Machine-readable specification for the `core` section of brand.yaml.
4
+
5
+ Defines the brand's verbal identity: essence, personality, voice, and strategic statements.
6
+
7
+ ## Structure
8
+
9
+ ```yaml
10
+ core:
11
+ essence: "..." # Internal guiding principle. One sentence.
12
+ tagline: "..." # Public-facing copy. One line.
13
+ mission: "..." # Why the brand exists.
14
+ vision: "..." # What the brand aspires to become.
15
+ values: # Core beliefs that drive decisions.
16
+ - "..."
17
+ personality: # 3-5 adjectives describing the brand character.
18
+ - "..."
19
+ voice: # How the brand speaks.
20
+ tone:
21
+ - "..."
22
+ principles:
23
+ - "..."
24
+ ```
25
+
26
+ Only `meta.name` is required for a valid brandspec. All `core` fields are optional at the schema level.
27
+
28
+ ---
29
+
30
+ ## Fields
31
+
32
+ ### `essence` (recommended)
33
+
34
+ One sentence capturing the brand's internal guiding principle. Used as a north star for decisions, not shown to end users directly.
35
+
36
+ ```yaml
37
+ essence: "Make brand identity accessible to every builder"
38
+ ```
39
+
40
+ Rules:
41
+ - Single sentence, concise
42
+ - Internal-facing (guides decisions, not marketing copy)
43
+ - Distinct from `tagline` (which is public-facing)
44
+
45
+ ### `tagline` (recommended)
46
+
47
+ Public-facing copy that captures the brand promise. One line.
48
+
49
+ ```yaml
50
+ tagline: "Brand clarity, delivered"
51
+ ```
52
+
53
+ Rules:
54
+ - Short, memorable
55
+ - External-facing (marketing, website, social)
56
+ - Distinct from `essence` (which is internal)
57
+
58
+ ### `mission` (optional)
59
+
60
+ Why the brand exists. What it does and for whom.
61
+
62
+ ```yaml
63
+ mission: "To give every team a single source of truth for their brand identity"
64
+ ```
65
+
66
+ ### `vision` (optional)
67
+
68
+ What the brand aspires to become or achieve long-term.
69
+
70
+ ```yaml
71
+ vision: "A world where every product ships with a consistent, intentional brand"
72
+ ```
73
+
74
+ ### `values` (optional)
75
+
76
+ Array of strings. Core beliefs that drive brand decisions.
77
+
78
+ ```yaml
79
+ values:
80
+ - "Simplicity over complexity"
81
+ - "Openness by default"
82
+ - "Craft in every detail"
83
+ ```
84
+
85
+ ### `personality` (recommended)
86
+
87
+ Array of 3-5 adjectives describing the brand character. These inform voice, visual choices, and content tone.
88
+
89
+ ```yaml
90
+ personality:
91
+ - innovative
92
+ - approachable
93
+ - confident
94
+ - playful
95
+ ```
96
+
97
+ Rules:
98
+ - 3-5 adjectives
99
+ - Ordered by prominence (most defining trait first)
100
+ - Used as input for voice tone and visual direction
101
+
102
+ ### `voice` (optional)
103
+
104
+ Object defining how the brand speaks. Contains two sub-fields:
105
+
106
+ ```yaml
107
+ voice:
108
+ tone:
109
+ - friendly
110
+ - clear
111
+ - encouraging
112
+ principles:
113
+ - "Use active voice"
114
+ - "Keep sentences short"
115
+ - "Celebrate user wins"
116
+ ```
117
+
118
+ #### `voice.tone` (string[])
119
+
120
+ Adjectives describing the emotional quality of brand communication. Overlaps with `personality` but focuses specifically on written/spoken communication.
121
+
122
+ #### `voice.principles` (string[])
123
+
124
+ Actionable writing rules the brand follows. Each principle should be a concrete, checkable guideline.
125
+
126
+ > **Note:** The schema allows additional keys on `voice` for extensibility, but only `tone` and `principles` are standard. Linting may warn on unrecognized keys.
127
+
128
+ ---
129
+
130
+ ## Required vs Recommended
131
+
132
+ | Field | Level | Rationale |
133
+ |-------|-------|-----------|
134
+ | `essence` | Recommended | Core guiding principle — high value for brand consistency |
135
+ | `tagline` | Recommended | Public-facing identity — needed for most touchpoints |
136
+ | `personality` | Recommended | Drives voice and visual decisions across phases |
137
+ | `mission` | Optional | Useful but not needed for visual/verbal output |
138
+ | `vision` | Optional | Useful but not needed for visual/verbal output |
139
+ | `values` | Optional | Useful but not needed for visual/verbal output |
140
+ | `voice` | Optional | Can be derived from personality if not explicitly set |
141
+
142
+ The Workshop recommends defining at least `essence`, `tagline`, and `personality` during Phase 2 (Concept).
143
+
144
+ ---
145
+
146
+ ## Voice: What Goes Where
147
+
148
+ The `core.voice` object defines **tone** and **principles** only.
149
+
150
+ Do/Don't examples, specific copywriting rules, and detailed voice enforcement belong in the `guidelines` section as structured rules:
151
+
152
+ ```yaml
153
+ # core section — tone and principles
154
+ core:
155
+ voice:
156
+ tone: [friendly, clear]
157
+ principles:
158
+ - "Use active voice"
159
+ - "Keep sentences short"
160
+
161
+ # guidelines section — enforceable voice rules with examples
162
+ guidelines:
163
+ voice-examples:
164
+ content: |
165
+ ## Voice Examples
166
+ - Greeting: "Hey there!" (not "Dear user")
167
+ - Error: "Something went wrong" (not "Error 500")
168
+ rules:
169
+ - id: "voice-active"
170
+ description: "Copy uses active voice"
171
+ severity: warning
172
+ applies_to: voice
173
+ - id: "voice-no-jargon"
174
+ description: "No technical jargon in user-facing messages"
175
+ severity: warning
176
+ applies_to: voice
177
+ ```
178
+
179
+ This separation keeps `core` as a concise identity definition and `guidelines` as the enforceable rulebook.
180
+
181
+ ---
182
+
183
+ ## Extensions
184
+
185
+ For brand phrases, copy collections, or verbal identity elements that don't fit the standard `core` fields, use the top-level `extensions` section:
186
+
187
+ ```yaml
188
+ extensions:
189
+ copy:
190
+ key_phrase: "Build brands that last"
191
+ cta_primary: "Get started"
192
+ cta_secondary: "See examples"
193
+ naming:
194
+ rationale: "Evokes clarity, multiple facets, light/modern feel"
195
+ alternatives_considered:
196
+ - "BrandSync"
197
+ - "AssetHub"
198
+ ```
199
+
200
+ Rules:
201
+ - Use `extensions` for non-standard verbal identity content
202
+ - `extensions` is fully open (`additionalProperties: true`)
203
+ - Naming rationale belongs in `extensions.naming` or `_workshop/decisions.yml`, not in `core`
@@ -0,0 +1,110 @@
1
+ # Guidelines Specification
2
+
3
+ Machine-readable specification for the `guidelines` section of brand.yaml.
4
+
5
+ ## Structure
6
+
7
+ Each key under `guidelines` is a named guideline section containing free-form content and optional machine-readable rules:
8
+
9
+ ```yaml
10
+ guidelines:
11
+ logo-usage:
12
+ content: |
13
+ ## Logo Usage
14
+ Markdown content for human readers...
15
+ rules:
16
+ - id: "logo-min-size"
17
+ description: "Logo must meet minimum size requirements"
18
+ severity: error
19
+ applies_to: logo
20
+ criteria:
21
+ - "Digital usage: minimum 120px width"
22
+ - "Print usage: minimum 25mm width"
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Fields
28
+
29
+ ### `content` (recommended)
30
+
31
+ Free-form Markdown string. Human-readable guidelines for a specific topic.
32
+
33
+ Typical sections: logo usage, color usage, voice & tone examples.
34
+
35
+ ### `rules` (optional)
36
+
37
+ Array of structured, machine-readable rules for AI-driven brand linting.
38
+
39
+ Each rule:
40
+
41
+ ```yaml
42
+ - id: "rule-id" # Recommended. Unique rule identifier.
43
+ description: "..." # Required. What this rule enforces.
44
+ severity: error # Required. info | warning | error.
45
+ applies_to: "logo" # Optional. Target: logo, color, typography, voice.
46
+ criteria: # Optional. Specific checkable conditions.
47
+ - "Condition 1"
48
+ - "Condition 2"
49
+ ```
50
+
51
+ ### Severity Levels
52
+
53
+ | Level | Meaning | Action |
54
+ |-------|---------|--------|
55
+ | `info` | Advisory, best practice | No action required |
56
+ | `warning` | Should fix, non-critical | Review recommended |
57
+ | `error` | Must fix, violation | Requires resolution |
58
+
59
+ ---
60
+
61
+ ## Common Guideline Sections
62
+
63
+ ### `logo-usage`
64
+
65
+ Typical rules:
66
+
67
+ | Rule ID | Description | Severity |
68
+ |---------|-------------|----------|
69
+ | `logo-min-size` | Minimum size requirements (120px digital, 25mm print) | error |
70
+ | `logo-clear-space` | Clear space around logo | warning |
71
+ | `logo-no-rotation` | Logo must not be rotated | error |
72
+ | `logo-no-effects` | No shadows, gradients, or effects applied to logo | error |
73
+ | `logo-no-distortion` | Aspect ratio must match original | error |
74
+
75
+ ### `color-usage`
76
+
77
+ Typical rules:
78
+
79
+ | Rule ID | Description | Severity |
80
+ |---------|-------------|----------|
81
+ | `color-contrast-aa` | Text on brand colors meets WCAG AA (4.5:1 normal, 3:1 large) | error |
82
+ | `color-secondary-area` | Secondary color not used for large background areas (>30% viewport) | warning |
83
+
84
+ ### `voice-examples`
85
+
86
+ Typical rules:
87
+
88
+ | Rule ID | Description | Severity |
89
+ |---------|-------------|----------|
90
+ | `voice-active` | Copy uses active voice | warning |
91
+ | `voice-no-jargon` | No technical jargon in user-facing messages | warning |
92
+ | `voice-button-descriptive` | Button labels describe the action (not "Submit", "Click here") | error |
93
+
94
+ ---
95
+
96
+ ## Extensions and Core Sections
97
+
98
+ The `guidelines` key is for usage rules about the brand.
99
+
100
+ For brand-specific metadata that doesn't fit standard sections, use the top-level `extensions` section:
101
+
102
+ ```yaml
103
+ extensions:
104
+ social:
105
+ twitter: "@brand"
106
+ linkedin: "company/brand"
107
+ legal:
108
+ trademark: "Brand™"
109
+ copyright: "© 2026 Brand Inc."
110
+ ```