@symbo.ls/mcp 1.0.10 → 1.0.13

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.
Files changed (46) hide show
  1. package/README.md +1 -0
  2. package/package.json +5 -2
  3. package/symbols_mcp/skills/AUDIT.md +148 -174
  4. package/symbols_mcp/skills/BRAND_IDENTITY.md +75 -0
  5. package/symbols_mcp/skills/COMPONENTS.md +266 -0
  6. package/symbols_mcp/skills/COOKBOOK.md +850 -0
  7. package/symbols_mcp/skills/DEFAULT_COMPONENTS.md +3491 -1637
  8. package/symbols_mcp/skills/DEFAULT_LIBRARY.md +301 -0
  9. package/symbols_mcp/skills/DESIGN_CRITIQUE.md +70 -59
  10. package/symbols_mcp/skills/DESIGN_DIRECTION.md +109 -175
  11. package/symbols_mcp/skills/DESIGN_SYSTEM.md +722 -0
  12. package/symbols_mcp/skills/DESIGN_SYSTEM_ARCHITECT.md +65 -57
  13. package/symbols_mcp/skills/DESIGN_TO_CODE.md +83 -64
  14. package/symbols_mcp/skills/DESIGN_TREND.md +62 -50
  15. package/symbols_mcp/skills/FIGMA_MATCHING.md +69 -58
  16. package/symbols_mcp/skills/LEARNINGS.md +374 -0
  17. package/symbols_mcp/skills/MARKETING_ASSETS.md +71 -59
  18. package/symbols_mcp/skills/MIGRATION.md +561 -0
  19. package/symbols_mcp/skills/PATTERNS.md +536 -0
  20. package/symbols_mcp/skills/PRESENTATION.md +78 -0
  21. package/symbols_mcp/skills/PROJECT_STRUCTURE.md +398 -0
  22. package/symbols_mcp/skills/RULES.md +519 -0
  23. package/symbols_mcp/skills/RUNNING_APPS.md +476 -0
  24. package/symbols_mcp/skills/SEO-METADATA.md +64 -9
  25. package/symbols_mcp/skills/SNIPPETS.md +598 -0
  26. package/symbols_mcp/skills/SSR-BRENDER.md +99 -0
  27. package/symbols_mcp/skills/SYNTAX.md +835 -0
  28. package/symbols_mcp/skills/ACCESSIBILITY.md +0 -471
  29. package/symbols_mcp/skills/ACCESSIBILITY_AUDITORY.md +0 -70
  30. package/symbols_mcp/skills/AGENT_INSTRUCTIONS.md +0 -265
  31. package/symbols_mcp/skills/BRAND_INDENTITY.md +0 -69
  32. package/symbols_mcp/skills/BUILT_IN_COMPONENTS.md +0 -304
  33. package/symbols_mcp/skills/CLAUDE.md +0 -2158
  34. package/symbols_mcp/skills/CLI_QUICK_START.md +0 -205
  35. package/symbols_mcp/skills/DEFAULT_DESIGN_SYSTEM.md +0 -496
  36. package/symbols_mcp/skills/DESIGN_SYSTEM_CONFIG.md +0 -487
  37. package/symbols_mcp/skills/DESIGN_SYSTEM_IN_PROPS.md +0 -136
  38. package/symbols_mcp/skills/DOMQL_v2-v3_MIGRATION.md +0 -236
  39. package/symbols_mcp/skills/MIGRATE_TO_SYMBOLS.md +0 -634
  40. package/symbols_mcp/skills/OPTIMIZATIONS_FOR_AGENT.md +0 -253
  41. package/symbols_mcp/skills/PROJECT_SETUP.md +0 -217
  42. package/symbols_mcp/skills/QUICKSTART.md +0 -79
  43. package/symbols_mcp/skills/REMOTE_PREVIEW.md +0 -144
  44. package/symbols_mcp/skills/SYMBOLS_LOCAL_INSTRUCTIONS.md +0 -1405
  45. package/symbols_mcp/skills/THE_PRESENTATION.md +0 -69
  46. package/symbols_mcp/skills/UI_UX_PATTERNS.md +0 -68
@@ -0,0 +1,374 @@
1
+ # Symbols / DOMQL Runtime — Internal Rules & Gotchas
2
+
3
+ These are mandatory technical rules for the DOMQL/Symbols runtime. Violating any of them causes silent bugs, missed renders, or incorrect DOM output.
4
+
5
+ ---
6
+
7
+ ## CSS-in-Props Resolution Order
8
+
9
+ Every property on an element is resolved top-down through this pipeline. The first match wins:
10
+
11
+ | Priority | Source | Behavior |
12
+ |----------|--------|----------|
13
+ | 1 (highest) | `element.classlist[key]` | Component-level class definitions |
14
+ | 2 | `CSS_PROPS_REGISTRY[key]` | Theme-aware processors (color, border, shadow, hide, etc.) — resolves design tokens |
15
+ | 3 | `DEFAULT_CSS_PROPERTIES_LIST.includes(key)` | Raw CSS pass-through — no theme resolution |
16
+ | 4 (lowest) | Everything else | Returned as non-CSS props (`rest`) |
17
+
18
+ **Why this matters:** Only properties routed through `CSS_PROPS_REGISTRY` (priority 2) resolve theme tokens. Shorthand properties like `borderColor` resolve themes, but directional variants (`borderTopColor`) require explicit registry entries or they pass through raw.
19
+
20
+ ---
21
+
22
+ ## CSS Override Precedence
23
+
24
+ `props` block CSS CANNOT override base component-level CSS. You must override at the same declaration level.
25
+
26
+ ```js
27
+ // WRONG — props can't override component-level color
28
+ export const MyLink = {
29
+ extends: 'Link',
30
+ props: { color: 'primary' }, // Ignored — Link's component-level color wins
31
+ }
32
+
33
+ // CORRECT — override at the same level
34
+ export const MyLink = {
35
+ extends: 'Link',
36
+ color: 'primary', // Overrides at component level
37
+ }
38
+ ```
39
+
40
+ This same rule applies to sub-component overrides in nested children.
41
+
42
+ ---
43
+
44
+ ## Event Handler Signatures
45
+
46
+ There are exactly two signatures. Using the wrong one shifts all parameters silently.
47
+
48
+ | Event type | Signature | Examples |
49
+ |------------|-----------|----------|
50
+ | Lifecycle events | `(element, state)` | `onInit`, `onRender`, `onUpdate` |
51
+ | DOM events | `(event, element, state)` | `onClick`, `onInput`, `onKeydown` |
52
+
53
+ **Common bug:** Writing `(event, el, s)` in a lifecycle handler. The first arg is actually the element, so `s` becomes `undefined`.
54
+
55
+ ```js
56
+ // CORRECT
57
+ onInit: (el, s) => {}
58
+ onClick: (event, el, s) => {}
59
+ ```
60
+
61
+ ---
62
+
63
+ ## HTML Attributes Are Automatic
64
+
65
+ Do NOT use `attr: {}` for standard HTML attributes. DOMQL's `attrs-in-props` module auto-detects valid attributes for each tag using a database of 600+ attributes.
66
+
67
+ During element creation, `applyPropsAsAttrs()` calls `filterAttributesByTagName(tag, props, cssPropsRegistry)`. If a property is a valid HTML attribute for that tag AND is not in the CSS properties registry, it automatically becomes `setAttribute()`.
68
+
69
+ ```js
70
+ // CORRECT — type, disabled, placeholder all auto-detected
71
+ export const MyButton = { tag: 'button', type: 'submit', disabled: true }
72
+ export const MyInput = { tag: 'input', type: 'email', placeholder: 'Enter email' }
73
+ ```
74
+
75
+ **Use `attr: {}` ONLY for:**
76
+ - Custom/non-standard attributes not in the HTML spec
77
+ - `data-*` attributes
78
+ - ARIA attributes beyond auto-detected ones
79
+ - Forcing a property to be an attribute when it would otherwise be interpreted as CSS
80
+
81
+ ```js
82
+ export const MyElement = {
83
+ attr: {
84
+ 'data-testid': 'my-element',
85
+ 'aria-describedby': 'tooltip-1',
86
+ },
87
+ }
88
+ ```
89
+
90
+ ---
91
+
92
+ ## Property Classification (Three Paths)
93
+
94
+ Every property on a DOMQL element takes exactly one of three paths:
95
+
96
+ | Path | What matches | Handling |
97
+ |------|-------------|----------|
98
+ | 1. REGISTRY | `attr`, `style`, `text`, `html`, `data`, `classlist`, `state`, `scope`, `fetch`, `deps`, `extends`, `children`, `content`, `childExtends`, `childExtendsRecursive`, `props`, `if`, `define`, `tag`, `on`, `component`, `context`, `query`, `variables` | Built-in DOMQL properties handled by mixins |
99
+ | 2. CSS | 300+ registered CSS properties (`display`, `flexDirection`, `margin`, `padding`, `color`, `background`, `border`, `opacity`, `transform`, `transition`, etc.) | Processed by `css-in-props` via Emotion; theme-aware processors handle tokens |
100
+ | 3. HTML attribute | Valid HTML attribute for the element's tag AND not a CSS property | Auto-applied as DOM attribute via `setAttribute()` |
101
+
102
+ Anything matching none of the three paths stays as a component-level property in DOMQL's internal element tree.
103
+
104
+ ---
105
+
106
+ ## Component Key Auto-Extending
107
+
108
+ A child key that matches a registered component name automatically extends that component. No explicit `extends` is needed.
109
+
110
+ ```js
111
+ export const MyPage = {
112
+ Hgroup: { gap: '0' }, // auto-extends registered Hgroup
113
+ Avatar: { boxSize: 'C' }, // auto-extends registered Avatar
114
+ Button: { text: 'Click' }, // auto-extends registered Button
115
+ }
116
+ ```
117
+
118
+ Use explicit `extends` only when:
119
+ - The key casing differs from the component name
120
+ - You want to extend a different component than the key name suggests
121
+
122
+ ---
123
+
124
+ ## Conditional Props Pattern
125
+
126
+ Use `isActive` boolean with `.isActive` / `!isActive` blocks. Do NOT use dynamic props spread.
127
+
128
+ ```js
129
+ // CORRECT — conditional style blocks
130
+ export const NavItem = {
131
+ isActive: (el, s) => s.root.currentPath === s.path,
132
+ padding: 'Z A',
133
+ opacity: '.6',
134
+
135
+ '.isActive': {
136
+ opacity: '1',
137
+ fontWeight: '700',
138
+ borderBottom: '2px solid',
139
+ borderBottomColor: 'primary',
140
+ },
141
+
142
+ '!isActive': {
143
+ ':hover': { opacity: '.8' },
144
+ },
145
+ }
146
+
147
+ // WRONG — dynamic props spread
148
+ export const NavItem = {
149
+ props: (el, s) => ({
150
+ opacity: s.root.currentPath === s.path ? '1' : '.6',
151
+ fontWeight: s.root.currentPath === s.path ? '700' : '400',
152
+ }),
153
+ }
154
+ ```
155
+
156
+ Default styles go at component level; active overrides go in `.isActive`. Inactive overrides go in `!isActive`.
157
+
158
+ ---
159
+
160
+ ## state.root.update() with onlyUpdate
161
+
162
+ To limit re-rendering to a specific component subtree, pass `onlyUpdate` as the second argument:
163
+
164
+ ```js
165
+ onClick: (e, el, s) => {
166
+ s.root.update(
167
+ { activeModal: 'settings' },
168
+ { onlyUpdate: 'ModalCard' } // Only re-render ModalCard subtree
169
+ )
170
+ }
171
+ ```
172
+
173
+ **Why:** Without `onlyUpdate`, the entire component tree re-renders on root state change. Use this for performance.
174
+
175
+ ---
176
+
177
+ ## SPA Navigation — preventDefault Required
178
+
179
+ When using `tag: 'a'` with `attr: { href: '/' }` AND an `onClick` handler, both the handler and the browser's default navigation fire. Always call `e.preventDefault()`.
180
+
181
+ ```js
182
+ export const NavLink = {
183
+ extends: 'Link',
184
+ onClick: (e, el) => {
185
+ e.preventDefault()
186
+ el.router('/', el.getRoot())
187
+ },
188
+ }
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Emotion CSS Class Cleanup
194
+
195
+ When toggling CSS-in-props values (like `hide`, `opacity`), stale Emotion class names can persist on the DOM. Key facts:
196
+
197
+ | Scenario | What happens |
198
+ |----------|-------------|
199
+ | `hide: true` | Generates a class with `display: none !important` |
200
+ | `hide` becomes falsy | No class is generated — the old class must be removed |
201
+ | Class name format | `smbls-{hash}-{label}` (content-hashed) |
202
+
203
+ The framework handles cleanup internally, but be aware of this when debugging class-related issues.
204
+
205
+ ---
206
+
207
+ ## Forced Reflow for Transitions
208
+
209
+ `state.root.update()` applies all Emotion classes in one JS execution block — the browser never paints the intermediate state. To make CSS transitions work, force a reflow with `node.offsetHeight`:
210
+
211
+ ```js
212
+ el.node.style.opacity = '0'
213
+ el.node.offsetHeight // Force reflow — browser paints the 0 state
214
+ el.node.style.opacity = '' // Let Emotion class transition take over
215
+ ```
216
+
217
+ Do NOT use `requestAnimationFrame` (unreliable timing) or `transitionend` (may not fire if element starts hidden).
218
+
219
+ ---
220
+
221
+ ## Update Cascade Path
222
+
223
+ This is the exact render cycle triggered by `state.update()`. Use it to debug state/render issues:
224
+
225
+ ```
226
+ state.update()
227
+ -> applyElementUpdate
228
+ -> element.update({}, { updateByState: true })
229
+ -> for (param in element): update children recursively
230
+ -> update content element explicitly (bypasses REGISTRY skip)
231
+ -> triggerEventOn('beforeClassAssign')
232
+ -> Box.onBeforeClassAssign
233
+ -> useCssInProps(props, element) -> ref.__class
234
+ -> transformEmotionClass -> ref.__classNames
235
+ -> clean stale classNames
236
+ -> applyClassListOnNode -> node.setAttribute('class', ...)
237
+ ```
238
+
239
+ ---
240
+
241
+ ## state.replace() vs state.update()
242
+
243
+ | Method | Behavior | Use when |
244
+ |--------|----------|----------|
245
+ | `state.update()` | Merges new values into existing state, triggers re-render | Updating individual properties |
246
+ | `state.replace()` | Replaces the entire state object | Replacing arrays or resetting state entirely |
247
+
248
+ ```js
249
+ // Arrays: use replace to ensure proper re-render
250
+ onClick: (e, el, s) => s.replace({
251
+ items: [...s.items, 'New Item']
252
+ })
253
+
254
+ // Simple values: use update
255
+ onClick: (e, el, s) => s.update({
256
+ count: s.count + 1
257
+ })
258
+ ```
259
+
260
+ ---
261
+
262
+ ## scope for Local Instance Data
263
+
264
+ `scope` holds data that does NOT trigger re-renders. Use it for timers, refs, caches, and any mutable data that should not cause UI updates.
265
+
266
+ ```js
267
+ export const Timer = {
268
+ state: { seconds: 0 },
269
+ scope: {},
270
+ onRender: (el, s) => {
271
+ el.scope.interval = setInterval(() => {
272
+ s.update({ seconds: s.seconds + 1 })
273
+ }, 1000)
274
+ },
275
+ Button: {
276
+ text: 'Stop',
277
+ onClick: (e, el) => clearInterval(el.scope.interval),
278
+ },
279
+ }
280
+ ```
281
+
282
+ `scope` is accessible from anywhere in the component tree via `el.scope`.
283
+
284
+ ---
285
+
286
+ ## Template Strings
287
+
288
+ Use `{{ key }}` syntax for simple state-to-text binding without a function. It resolves from the element's local state.
289
+
290
+ ```js
291
+ export const Greeting = {
292
+ state: { name: 'World' },
293
+ P: { text: 'Hello, {{ name }}!' }, // Simple binding
294
+ P_2: { text: (el, s) => `Score: ${s.score}` }, // Complex binding
295
+ }
296
+ ```
297
+
298
+ Use function syntax instead when you need: computed values, parent/root state access, or complex expressions.
299
+
300
+ ---
301
+
302
+ ## External Dependencies
303
+
304
+ External libraries must be declared in BOTH `package.json` AND `symbols/dependencies.js`:
305
+
306
+ ```js
307
+ // symbols/dependencies.js
308
+ import lottie from 'lottie-web'
309
+ import Prism from 'prismjs'
310
+
311
+ export default { lottie, Prism }
312
+ ```
313
+
314
+ Access in components via `el.context.dependencies.lottie`. Missing the `dependencies.js` export means the library is installed but invisible to components.
315
+
316
+ ---
317
+
318
+ ## Symbols Module Architecture
319
+
320
+ ### Core Runtime
321
+
322
+ | Package | Purpose |
323
+ |---------|---------|
324
+ | `@domql/element` | Core element system — create, update, render, destroy, and all mixins (attr, style, text, html, data, classList, state, scope) |
325
+ | `@domql/state` | Reactive state management — update, replace, toggle, parent/root state access |
326
+ | `@domql/utils` | Shared utilities — propertizeElement, object manipulation, element creation helpers |
327
+ | `domql` | Main DOMQL library entry point (bundles element, state, utils) |
328
+
329
+ ### Styling & Attributes
330
+
331
+ | Package | Purpose |
332
+ |---------|---------|
333
+ | `css-in-props` | CSS-in-props system with 300+ CSS property registry and Emotion-based styling. Handles theme-aware processors for colors, spacing, borders, shadows |
334
+ | `attrs-in-props` | HTML attribute validation and filtering by tag name. Database of 600+ valid HTML attributes per tag — ensures only valid attrs become DOM attributes |
335
+ | `scratch` | CSS framework and methodology (Phi-notation spacing system) |
336
+
337
+ ### UI Components
338
+
339
+ | Package | Purpose |
340
+ |---------|---------|
341
+ | `@symbo.ls/uikit` | Pre-built UI components: Button, Input, Select, Dialog, Avatar, Icon, Range, Dropdown, Notification, Link, Tooltip — all built on DOMQL atoms |
342
+
343
+ ### Build & Tooling
344
+
345
+ | Package | Purpose |
346
+ |---------|---------|
347
+ | `smbls` | Main Symbols package — runtime entry point |
348
+ | `cli` | CLI for project management (`smbls start`, `smbls build`, `smbls create`) |
349
+ | `runner` | Build runner and toolchain (Parcel integration) |
350
+ | `create` / `create-smbls` | Project scaffolding and creation |
351
+ | `frank` | Bidirectional transformation between Symbols project JSON and filesystem formats |
352
+ | `preview` | Development preview server |
353
+
354
+ ### Data & Sync
355
+
356
+ | Package | Purpose |
357
+ |---------|---------|
358
+ | `state` | State management package |
359
+ | `sync` | Real-time bidirectional sync with Express/Socket.io |
360
+ | `icons` | Icon system and icon set management |
361
+ | `default-config` | Default configuration for new projects |
362
+
363
+ ### Element REGISTRY — All Built-in Properties
364
+
365
+ These properties are handled internally by DOMQL. They are NOT passed to DOM or CSS:
366
+
367
+ ```
368
+ attr, style, text, html, data, classlist, state, scope, fetch, deps,
369
+ extends, children, content, childExtends, childExtendsRecursive,
370
+ props, if, define, tag, query, on, component, context, variables,
371
+ __name, __ref, __hash, __text, key, parent, node
372
+ ```
373
+
374
+ Any property NOT in this registry, NOT a CSS property, and NOT a valid HTML attribute for the tag stays as a component-level property in DOMQL's internal element tree.
@@ -1,66 +1,78 @@
1
- The Marketing Asset Factory
2
-
3
- You are a Creative Director at a top-tier marketing agency working on a campaign for [PRODUCT/SERVICE].
4
-
5
- Campaign objective: [AWARENESS/CONVERSION/RETENTION]
6
- Target audience: [DEMOGRAPHICS + PSYCHOGRAPHICS]
7
- Campaign theme: [CORE MESSAGE/HOOK]
8
- Tone: [PROFESSIONAL/PLAYFUL/URGENT/LUXURY/MINIMAL]
9
-
10
- Generate a complete marketing asset library:
11
-
12
- 1. DIGITAL ADVERTISING (15 assets)
13
- • Google Ads:
14
- - 5 headlines (30 characters max)
15
- - 5 descriptions (90 characters max)
16
- - Display ad concepts (300x250, 728x90, 160x600) with visual descriptions
17
-
18
- • Facebook/Instagram Ads:
19
- - 3 feed ad concepts (visual + copy)
20
- - 3 story ad concepts (9:16 format)
21
- - 3 reel/TikTok script concepts (15-30 seconds)
22
-
23
- 2. EMAIL MARKETING (8 assets)
24
- • Subject lines (10 options, A/B test variations)
25
- • Preview text (10 options)
26
- • Full email templates:
27
- - Welcome series (3 emails)
28
- - Promotional email (1)
29
- - Nurture sequence (3 emails)
30
- - Re-engagement (1)
31
-
32
- 3. LANDING PAGE COPY (5 assets)
33
- • Hero section (headline, subheadline, CTA)
34
- • Feature sections (3 variations)
35
- • Social proof section (testimonial framework)
36
- • FAQ section (8 questions + answers)
37
- • Pricing page (if applicable)
38
-
39
- 4. SOCIAL MEDIA CONTENT (12 assets)
40
- • LinkedIn posts (4)
41
- • Twitter/X threads (2)
42
- • Instagram captions (3)
43
- • TikTok/Short-form scripts (3)
44
-
45
- 5. SALES ENABLEMENT (7 assets)
46
- • One-pager content structure
47
- • Sales deck outline (10 slides)
48
- • Case study template
49
- • Battlecard (competitor comparison)
50
- • Product demo script
51
- • Objection handling guide (10 common objections)
52
- • Proposal template
53
-
54
- 6. CONTENT MARKETING (5 assets)
55
- • Blog post outlines (3)
56
- • Whitepaper structure
57
- • Webinar script outline
1
+ # Marketing Asset Factory
58
2
 
59
- For each asset provide:
3
+ You are a Creative Director at a top-tier marketing agency. Generate a complete marketing asset library.
4
+
5
+ ## Inputs
6
+
7
+ - Product/Service: [PRODUCT/SERVICE]
8
+ - Campaign objective: [AWARENESS/CONVERSION/RETENTION]
9
+ - Target audience: [DEMOGRAPHICS + PSYCHOGRAPHICS]
10
+ - Campaign theme: [CORE MESSAGE/HOOK]
11
+ - Tone: [PROFESSIONAL/PLAYFUL/URGENT/LUXURY/MINIMAL]
12
+
13
+ ## Deliverables
14
+
15
+ ### 1. Digital Ads (15 assets)
16
+
17
+ **Google Ads**:
18
+ - 5 headlines (30 characters max)
19
+ - 5 descriptions (90 characters max)
20
+ - Display ad concepts (300x250, 728x90, 160x600) with visual descriptions
21
+
22
+ **Facebook/Instagram Ads**:
23
+ - 3 feed ad concepts (visual + copy)
24
+ - 3 story ad concepts (9:16 format)
25
+ - 3 reel/TikTok script concepts (15-30 seconds)
26
+
27
+ ### 2. Email Marketing (8 assets)
28
+
29
+ - Subject lines (10 options with A/B test variations)
30
+ - Preview text (10 options)
31
+ - Full email templates:
32
+ - Welcome series (3 emails)
33
+ - Promotional email (1)
34
+ - Nurture sequence (3 emails)
35
+ - Re-engagement (1)
36
+
37
+ ### 3. Landing Pages (5 assets)
60
38
 
61
- - The exact copy/content
39
+ - Hero section (headline, subheadline, CTA)
40
+ - Feature sections (3 variations)
41
+ - Social proof section (testimonial framework)
42
+ - FAQ section (8 questions + answers)
43
+ - Pricing page (if applicable)
44
+
45
+ ### 4. Social Media (12 assets)
46
+
47
+ - LinkedIn posts (4)
48
+ - Twitter/X threads (2)
49
+ - Instagram captions (3)
50
+ - TikTok/Short-form scripts (3)
51
+
52
+ ### 5. Sales Enablement (7 assets)
53
+
54
+ - One-pager content structure
55
+ - Sales deck outline (10 slides)
56
+ - Case study template
57
+ - Battlecard (competitor comparison)
58
+ - Product demo script
59
+ - Objection handling guide (10 common objections)
60
+ - Proposal template
61
+
62
+ ### 6. Content Marketing (5 assets)
63
+
64
+ - Blog post outlines (3)
65
+ - Whitepaper structure
66
+ - Webinar script outline
67
+
68
+ ## Per-Asset Requirements
69
+
70
+ For each asset provide:
71
+ - Exact copy/content
62
72
  - Visual direction (colors, imagery, composition)
63
73
  - CTA and next step
64
74
  - A/B testing recommendations
65
75
 
76
+ ## Instructions
77
+
66
78
  Maintain brand consistency across all 47+ assets with unified messaging hierarchy.