dreative 0.5.0 → 0.5.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/README.md +49 -27
- package/dist/cli/audit.js +206 -0
- package/dist/cli/audit.test.js +79 -0
- package/dist/cli/docsCheck.js +163 -0
- package/dist/cli/docsCheck.test.js +8 -0
- package/dist/cli/index.js +81 -8
- package/dist/server/preview.js +73 -73
- package/dist/server/store.js +11 -0
- package/dist/shared/artifacts.js +162 -0
- package/dist/shared/design.js +42 -22
- package/dist/shared/ruleSystem.js +130 -0
- package/dist/shared/ruleSystem.test.js +187 -0
- package/dist/shared/skillSystem.js +173 -0
- package/dist/shared/skillSystem.test.js +110 -0
- package/dist/ui/assets/{index--vztc_MR.js → index-CKwmbx2j.js} +13 -13
- package/dist/ui/index.html +12 -12
- package/package.json +5 -3
- package/skill/dreative/DESIGN.md +290 -95
- package/skill/dreative/PLAN.md +462 -71
- package/skill/dreative/SKILL.md +230 -126
- package/skill/dreative/frameworks/nextjs.md +13 -0
- package/skill/dreative/frameworks/react-vite.md +12 -0
- package/skill/dreative/frameworks/styling.md +14 -0
- package/skill/dreative/frameworks/sveltekit.md +10 -0
- package/skill/dreative/frameworks/vue-nuxt.md +12 -0
- package/skill/dreative/recipes/3d-recipes.md +44 -0
- package/skill/dreative/recipes/cinematic-recipes.md +19 -0
- package/skill/dreative/recipes/immersive-recipes.md +18 -0
- package/skill/dreative/recipes/media-recipes.md +60 -0
- package/skill/dreative/recipes/motion-recipes.md +44 -0
- package/skill/dreative/references/ARTIFACTS.md +180 -0
- package/skill/dreative/references/REFLEX_FONTS.json +44 -0
- package/skill/dreative/references/RULES.json +186 -0
- package/skill/dreative/references/SKILL_CONTRACT.md +30 -0
- package/skill/dreative/references/TIERS.md +42 -0
- package/skill/dreative/schemas/plan.schema.json +241 -0
- package/skill/dreative/schemas/verify.schema.json +61 -0
- package/skill/dreative/skills/3d.md +94 -157
- package/skill/dreative/skills/cinematic.md +56 -232
- package/skill/dreative/skills/experimental.md +111 -0
- package/skill/dreative/skills/immersive.md +61 -223
- package/skill/dreative/skills/interaction.md +9 -1
- package/skill/dreative/skills/media.md +135 -216
- package/skill/dreative/skills/mobile.md +128 -117
- package/skill/dreative/skills/motion.md +89 -229
- package/skill/dreative/skills/refined.md +116 -102
- package/skill/dreative/skills/ux.md +155 -144
- package/dist/server/ai.js +0 -177
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://dreative.local/schemas/plan.schema.json",
|
|
4
|
+
"title": "Dreative Multi-Page Direct Design Plan",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["version", "request", "createdAt", "tier", "depth", "skills", "skillPolicy", "designRead", "pages", "preservationManifest", "decisionLedger"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"version": { "const": 2 },
|
|
10
|
+
"doctrineVersion": { "const": 2 },
|
|
11
|
+
"request": { "type": "string", "minLength": 1 },
|
|
12
|
+
"createdAt": { "type": "string", "format": "date-time" },
|
|
13
|
+
"tier": { "enum": ["solid", "premium", "expressive", "award"] },
|
|
14
|
+
"depth": { "enum": ["restyle", "relayout", "restructure", "reimagine"] },
|
|
15
|
+
"skills": { "$ref": "#/$defs/skillList" },
|
|
16
|
+
"skillPolicy": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"additionalProperties": false,
|
|
19
|
+
"required": ["mode", "global", "routingApproved", "userAssignments"],
|
|
20
|
+
"properties": {
|
|
21
|
+
"mode": { "const": "hybrid" },
|
|
22
|
+
"global": { "$ref": "#/$defs/skillList" },
|
|
23
|
+
"routingApproved": { "const": true },
|
|
24
|
+
"userAssignments": {
|
|
25
|
+
"type": "array",
|
|
26
|
+
"items": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"required": ["pageId", "skills"],
|
|
30
|
+
"properties": {
|
|
31
|
+
"pageId": { "type": "string", "minLength": 1 },
|
|
32
|
+
"skills": { "$ref": "#/$defs/treatmentList" }
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"designRead": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"additionalProperties": false,
|
|
41
|
+
"required": ["register", "concept", "signature"],
|
|
42
|
+
"properties": {
|
|
43
|
+
"register": { "type": "string", "minLength": 1 },
|
|
44
|
+
"concept": { "type": "string", "minLength": 1 },
|
|
45
|
+
"signature": { "type": "string", "minLength": 1 }
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"implementationStartedAt": { "type": "string", "format": "date-time" },
|
|
49
|
+
"ruleExceptions": { "type": "array", "items": { "$ref": "#/$defs/ruleException" } },
|
|
50
|
+
"creativeStrategy": { "$ref": "#/$defs/creativeStrategy" },
|
|
51
|
+
"fontDecision": { "$ref": "#/$defs/fontDecision" },
|
|
52
|
+
"experimentalPlan": { "$ref": "#/$defs/experimentalPlan" },
|
|
53
|
+
"conceptExploration": { "$ref": "#/$defs/conceptExploration" },
|
|
54
|
+
"recipeAccess": { "type": "array", "items": { "$ref": "#/$defs/recipeAccess" } },
|
|
55
|
+
"pages": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/page" } },
|
|
56
|
+
"preservationManifest": { "type": "string", "minLength": 1 },
|
|
57
|
+
"decisionLedger": { "type": "string", "minLength": 1 }
|
|
58
|
+
},
|
|
59
|
+
"$defs": {
|
|
60
|
+
"skill": { "enum": ["ux", "mobile", "refined", "motion", "interaction", "media", "3d", "immersive", "cinematic", "experimental"] },
|
|
61
|
+
"skillList": {
|
|
62
|
+
"type": "array",
|
|
63
|
+
"uniqueItems": true,
|
|
64
|
+
"allOf": [{ "contains": { "const": "ux" } }, { "contains": { "const": "mobile" } }],
|
|
65
|
+
"items": { "$ref": "#/$defs/skill" }
|
|
66
|
+
},
|
|
67
|
+
"treatmentList": {
|
|
68
|
+
"type": "array",
|
|
69
|
+
"uniqueItems": true,
|
|
70
|
+
"items": { "$ref": "#/$defs/skill" }
|
|
71
|
+
},
|
|
72
|
+
"status": { "enum": ["planned", "shipped", "fallback", "cut"] },
|
|
73
|
+
"ruleException": {
|
|
74
|
+
"type": "object",
|
|
75
|
+
"additionalProperties": false,
|
|
76
|
+
"required": ["ruleId", "decision", "declaredAt", "reason", "alternative", "successCriteria", "evidenceIds"],
|
|
77
|
+
"properties": {
|
|
78
|
+
"ruleId": { "type": "string", "minLength": 1 },
|
|
79
|
+
"decision": { "const": "substituted" },
|
|
80
|
+
"declaredAt": { "type": "string", "format": "date-time" },
|
|
81
|
+
"reason": { "type": "string", "minLength": 20 },
|
|
82
|
+
"alternative": { "type": "string", "minLength": 30 },
|
|
83
|
+
"successCriteria": { "type": "array", "minItems": 2, "items": { "type": "string", "minLength": 12 } },
|
|
84
|
+
"evidenceIds": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } }
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"creativeStrategy": {
|
|
88
|
+
"oneOf": [
|
|
89
|
+
{
|
|
90
|
+
"type": "object",
|
|
91
|
+
"additionalProperties": false,
|
|
92
|
+
"required": ["path", "mechanisms", "drivers"],
|
|
93
|
+
"properties": {
|
|
94
|
+
"path": { "const": "diversity" },
|
|
95
|
+
"mechanisms": { "type": "array", "minItems": 4, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
|
|
96
|
+
"drivers": { "type": "array", "minItems": 3, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } }
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"type": "object",
|
|
101
|
+
"additionalProperties": false,
|
|
102
|
+
"required": ["path", "signatureMechanism", "states", "secondaryMechanisms", "drivers"],
|
|
103
|
+
"properties": {
|
|
104
|
+
"path": { "const": "development" },
|
|
105
|
+
"signatureMechanism": { "type": "string", "minLength": 1 },
|
|
106
|
+
"states": { "type": "array", "minItems": 3, "uniqueItems": true, "items": { "type": "string", "minLength": 12 } },
|
|
107
|
+
"secondaryMechanisms": { "type": "array", "minItems": 2, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
|
|
108
|
+
"drivers": { "type": "array", "minItems": 2, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } }
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
"fontDecision": {
|
|
114
|
+
"type": "object",
|
|
115
|
+
"additionalProperties": false,
|
|
116
|
+
"required": ["selected", "candidates", "recentDisplayFonts"],
|
|
117
|
+
"properties": {
|
|
118
|
+
"selected": { "type": "string", "minLength": 1 },
|
|
119
|
+
"candidates": {
|
|
120
|
+
"type": "array",
|
|
121
|
+
"minItems": 3,
|
|
122
|
+
"items": {
|
|
123
|
+
"type": "object",
|
|
124
|
+
"additionalProperties": false,
|
|
125
|
+
"required": ["name", "reflex", "rationale"],
|
|
126
|
+
"properties": {
|
|
127
|
+
"name": { "type": "string", "minLength": 1 },
|
|
128
|
+
"reflex": { "type": "boolean" },
|
|
129
|
+
"rationale": { "type": "string", "minLength": 12 }
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"recentDisplayFonts": { "type": "array", "maxItems": 3, "items": { "type": "string" } },
|
|
134
|
+
"reasonKinds": {
|
|
135
|
+
"type": "array",
|
|
136
|
+
"uniqueItems": true,
|
|
137
|
+
"items": {
|
|
138
|
+
"enum": ["existing-brand", "design-system-metrics", "product-register", "supplied-reference", "language-coverage", "variable-font-capability", "performance", "physical-editorial-historical-reference"]
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"justification": { "type": "string", "minLength": 20 },
|
|
142
|
+
"repeatJustification": { "type": "string", "minLength": 20 }
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
"experimentalPlan": {
|
|
146
|
+
"type": "object",
|
|
147
|
+
"additionalProperties": false,
|
|
148
|
+
"required": ["majorSectionIds", "candidates"],
|
|
149
|
+
"properties": {
|
|
150
|
+
"majorSectionIds": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
|
|
151
|
+
"candidates": {
|
|
152
|
+
"type": "array",
|
|
153
|
+
"items": {
|
|
154
|
+
"type": "object",
|
|
155
|
+
"additionalProperties": false,
|
|
156
|
+
"required": ["id", "sectionId", "idea", "selected"],
|
|
157
|
+
"properties": {
|
|
158
|
+
"id": { "type": "string", "minLength": 1 },
|
|
159
|
+
"sectionId": { "type": "string", "minLength": 1 },
|
|
160
|
+
"idea": { "type": "string", "minLength": 20 },
|
|
161
|
+
"selected": { "type": "boolean" }
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"conceptExploration": {
|
|
168
|
+
"type": "object",
|
|
169
|
+
"additionalProperties": false,
|
|
170
|
+
"required": ["recordedAt", "concepts"],
|
|
171
|
+
"properties": {
|
|
172
|
+
"recordedAt": { "type": "string", "format": "date-time" },
|
|
173
|
+
"concepts": {
|
|
174
|
+
"type": "array",
|
|
175
|
+
"minItems": 3,
|
|
176
|
+
"items": {
|
|
177
|
+
"type": "object",
|
|
178
|
+
"additionalProperties": false,
|
|
179
|
+
"required": ["name", "concept", "brandConnection"],
|
|
180
|
+
"properties": {
|
|
181
|
+
"name": { "type": "string", "minLength": 1 },
|
|
182
|
+
"concept": { "type": "string", "minLength": 20 },
|
|
183
|
+
"brandConnection": { "type": "string", "minLength": 20 }
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"recipeAccess": {
|
|
190
|
+
"type": "object",
|
|
191
|
+
"additionalProperties": false,
|
|
192
|
+
"required": ["file", "loadedAt", "purpose"],
|
|
193
|
+
"properties": {
|
|
194
|
+
"file": { "type": "string", "minLength": 1 },
|
|
195
|
+
"loadedAt": { "type": "string", "format": "date-time" },
|
|
196
|
+
"purpose": { "enum": ["feasibility", "implementation", "performance", "fallback", "concept-repair"] }
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
"asset": {
|
|
200
|
+
"type": "object",
|
|
201
|
+
"additionalProperties": false,
|
|
202
|
+
"required": ["id", "path", "purpose", "status"],
|
|
203
|
+
"properties": {
|
|
204
|
+
"id": { "type": "string", "minLength": 1 },
|
|
205
|
+
"path": { "type": "string", "minLength": 1 },
|
|
206
|
+
"purpose": { "type": "string", "minLength": 1 },
|
|
207
|
+
"status": { "$ref": "#/$defs/status" },
|
|
208
|
+
"reason": { "type": "string", "minLength": 1 }
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
"section": {
|
|
212
|
+
"type": "object",
|
|
213
|
+
"additionalProperties": false,
|
|
214
|
+
"required": ["id", "name", "layoutFamily", "skills", "interactions", "mobile", "fallback", "verification", "assets", "status"],
|
|
215
|
+
"properties": {
|
|
216
|
+
"id": { "type": "string", "minLength": 1 },
|
|
217
|
+
"name": { "type": "string", "minLength": 1 },
|
|
218
|
+
"layoutFamily": { "type": "string", "minLength": 1 },
|
|
219
|
+
"skills": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/skill" } },
|
|
220
|
+
"interactions": { "type": "array", "items": { "type": "string" } },
|
|
221
|
+
"mobile": { "type": "string", "minLength": 1 },
|
|
222
|
+
"fallback": { "type": "string", "minLength": 1 },
|
|
223
|
+
"verification": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } },
|
|
224
|
+
"assets": { "type": "array", "items": { "$ref": "#/$defs/asset" } },
|
|
225
|
+
"status": { "$ref": "#/$defs/status" },
|
|
226
|
+
"reason": { "type": "string", "minLength": 1 }
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
"page": {
|
|
230
|
+
"type": "object",
|
|
231
|
+
"additionalProperties": false,
|
|
232
|
+
"required": ["id", "name", "skills", "sections"],
|
|
233
|
+
"properties": {
|
|
234
|
+
"id": { "type": "string", "minLength": 1 },
|
|
235
|
+
"name": { "type": "string", "minLength": 1 },
|
|
236
|
+
"skills": { "$ref": "#/$defs/skillList" },
|
|
237
|
+
"sections": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/section" } }
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://dreative.local/schemas/verify.schema.json",
|
|
4
|
+
"title": "Dreative Verification Report",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["version", "generatedAt", "evidence"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"version": { "const": 1 },
|
|
10
|
+
"generatedAt": { "type": "string", "format": "date-time" },
|
|
11
|
+
"evidence": {
|
|
12
|
+
"type": "array",
|
|
13
|
+
"items": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"additionalProperties": false,
|
|
16
|
+
"required": ["id", "criterion", "status", "evidence", "proof"],
|
|
17
|
+
"properties": {
|
|
18
|
+
"id": { "type": "string", "minLength": 1 },
|
|
19
|
+
"criterion": { "type": "string", "minLength": 1 },
|
|
20
|
+
"status": { "enum": ["pass", "fail", "not-applicable"] },
|
|
21
|
+
"evidence": { "type": "string", "minLength": 1 },
|
|
22
|
+
"proof": {
|
|
23
|
+
"type": "object",
|
|
24
|
+
"additionalProperties": false,
|
|
25
|
+
"required": ["timestamp"],
|
|
26
|
+
"properties": {
|
|
27
|
+
"timestamp": { "type": "string", "format": "date-time" },
|
|
28
|
+
"artifactPath": { "type": "string", "minLength": 1 },
|
|
29
|
+
"viewport": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"additionalProperties": false,
|
|
32
|
+
"required": ["width", "height"],
|
|
33
|
+
"properties": {
|
|
34
|
+
"width": { "type": "number", "exclusiveMinimum": 0 },
|
|
35
|
+
"height": { "type": "number", "exclusiveMinimum": 0 },
|
|
36
|
+
"dpr": { "type": "number", "exclusiveMinimum": 0 }
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"command": { "type": "string", "minLength": 1 },
|
|
40
|
+
"exitCode": { "type": "integer" },
|
|
41
|
+
"consoleErrorCount": { "type": "integer", "minimum": 0 },
|
|
42
|
+
"testedUrl": { "type": "string", "minLength": 1 },
|
|
43
|
+
"averageFps": { "type": "number", "exclusiveMinimum": 0 },
|
|
44
|
+
"maxFrameTimeMs": { "type": "number", "minimum": 0 },
|
|
45
|
+
"playwrightTestId": { "type": "string", "minLength": 1 }
|
|
46
|
+
},
|
|
47
|
+
"anyOf": [
|
|
48
|
+
{ "required": ["artifactPath"] },
|
|
49
|
+
{ "required": ["command", "exitCode"] },
|
|
50
|
+
{ "required": ["consoleErrorCount"] },
|
|
51
|
+
{ "required": ["testedUrl"] },
|
|
52
|
+
{ "required": ["averageFps"] },
|
|
53
|
+
{ "required": ["maxFrameTimeMs"] },
|
|
54
|
+
{ "required": ["playwrightTestId"] }
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -1,157 +1,94 @@
|
|
|
1
|
-
# Dreative Specialist Skill — 3D, WebGL & Shaders
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
the DOM (a11y/layout/fallback, `opacity: 0` never `display:none`) while
|
|
96
|
-
textured planes copy their `getBoundingClientRect()` per rAF (lerped).
|
|
97
|
-
One scene owns ALL planes — never a canvas per image.
|
|
98
|
-
- **Video textures**: `new THREE.VideoTexture(videoEl)` with the element
|
|
99
|
-
`muted playsinline` and playing; `texture.colorSpace = SRGBColorSpace`;
|
|
100
|
-
generated seamless loops (media.md §1) make the best texture sources —
|
|
101
|
-
a pre-rendered loop as a texture often beats a live sim for cost.
|
|
102
|
-
- Effects on media planes: hover ripple/lens (damped `uMouse` + radial UV
|
|
103
|
-
displacement), velocity stretch + RGB split (clamped, damped decay),
|
|
104
|
-
noise-mask dissolves between textures (§4), subtle vertex curvature for
|
|
105
|
-
the floating-paper look.
|
|
106
|
-
- Failure path is wired, not theoretical: WebGL missing/lost or
|
|
107
|
-
reduced-motion → un-hide the DOM media (`opacity: 1`). Verify it fires.
|
|
108
|
-
|
|
109
|
-
## 5. Particles and points
|
|
110
|
-
|
|
111
|
-
Points/instancing, never meshes-per-particle: `<Points>` + `BufferAttribute`
|
|
112
|
-
positions animated in a shader (`uTime` in the vertex shader), or
|
|
113
|
-
`<Instances>`/`InstancedMesh` for repeated geometry (≤ ~10k instances). Counts:
|
|
114
|
-
2-5k points desktop, halve on mobile. Particle color from the page palette at 1-2
|
|
115
|
-
hues; size attenuation on; additive blending only on dark surfaces.
|
|
116
|
-
|
|
117
|
-
## 6. Scroll- and layout-integration
|
|
118
|
-
|
|
119
|
-
- Canvas placement: either a bounded block IN the layout (preferred — it composes
|
|
120
|
-
with the grid) or a full-bleed fixed background with content scrolling over.
|
|
121
|
-
Full-page persistent canvases with DOM scrolled on top: use drei
|
|
122
|
-
`ScrollControls` + `<Scroll html>` so 3D and DOM share one scroll.
|
|
123
|
-
- Scroll-linked 3D: map scroll progress (Motion `useScroll` / ScrollTrigger /
|
|
124
|
-
drei `useScroll`) to camera position along a path or object rotation — damped
|
|
125
|
-
(`damp3`, `dampE`), never raw-set per frame.
|
|
126
|
-
- DOM/3D registration (labels pinned to model parts): drei `<Html transform
|
|
127
|
-
occlude>`; keep text as real DOM for accessibility, never texture-baked type.
|
|
128
|
-
- The block's `data-dreative-id` goes on the wrapper div around the Canvas.
|
|
129
|
-
|
|
130
|
-
## 7. Performance & fallbacks (ship-blockers)
|
|
131
|
-
|
|
132
|
-
- `<Canvas dpr={[1, 2]}>` (cap device pixel ratio), `frameloop="demand"` +
|
|
133
|
-
`invalidate()` for static-until-interacted scenes; pause the loop when the
|
|
134
|
-
canvas leaves the viewport (IntersectionObserver) and on `document.hidden`.
|
|
135
|
-
- One `useFrame` per concern; no allocations inside it (reuse vectors created
|
|
136
|
-
outside). Dispose on unmount (R3F handles it; imperative three must
|
|
137
|
-
`dispose()` geometries/materials/textures).
|
|
138
|
-
- Mobile: halve particle counts, drop post-processing, consider a poster image
|
|
139
|
-
below 768px — a janky 3D hero is worse than none.
|
|
140
|
-
- `prefers-reduced-motion`: stop idle rotation/particle drift; render one static
|
|
141
|
-
well-lit frame (`frameloop="demand"` makes this free).
|
|
142
|
-
- WebGL unavailable/context-lost → the poster fallback, never a blank block.
|
|
143
|
-
- Keyboard/screen-reader: canvas gets `role="img"` + `aria-label`; any 3D-driven
|
|
144
|
-
interaction has a DOM equivalent.
|
|
145
|
-
|
|
146
|
-
## 8. Recipes
|
|
147
|
-
|
|
148
|
-
- **Product hero**: GLB + `Environment` + key light + `ContactShadows`, `Float`
|
|
149
|
-
idle, damped mouse parallax, scroll scrubs a 90° orbit. Poster until loaded.
|
|
150
|
-
- **Gradient-mesh hero background**: one plane, fbm + domain-warp fragment shader
|
|
151
|
-
mixing 3 palette colors, `uTime` 0.08, `uMouse` warps locally. ~120 lines, no
|
|
152
|
-
model, no lighting — the best effort/impact ratio in this file.
|
|
153
|
-
- **Point-cloud globe**: sphere-distributed points, shader-animated shimmer,
|
|
154
|
-
arcs as `TubeGeometry`/fat lines between coords, slow idle rotation, drag to
|
|
155
|
-
spin (damped).
|
|
156
|
-
- **Scroll story**: `ScrollControls pages={4}` + camera on a `CatmullRomCurve3`
|
|
157
|
-
path, DOM copy in `<Scroll html>`, one damped lookAt target per section.
|
|
1
|
+
# Dreative Specialist Skill — 3D, WebGL & Shaders
|
|
2
|
+
|
|
3
|
+
## Contract
|
|
4
|
+
|
|
5
|
+
Follow `../references/SKILL_CONTRACT.md`. Dependencies: `ux`, `mobile`; add
|
|
6
|
+
`motion` when scroll/time drives the scene. Deliver a named spatial purpose,
|
|
7
|
+
asset/material source, staged berth, budgets, semantic/poster fallback, and
|
|
8
|
+
runtime evidence.
|
|
9
|
+
|
|
10
|
+
Load for real spatial subjects, WebGL, three.js/R3F, shaders, particles, globes,
|
|
11
|
+
or a plan-defined dimensional signature. 3D is expensive in bytes, battery, and
|
|
12
|
+
attention; it must serve the subject or concept.
|
|
13
|
+
|
|
14
|
+
## 0. Explore before recipes
|
|
15
|
+
|
|
16
|
+
Record three original brand-native spatial concepts before opening
|
|
17
|
+
`../recipes/3d-recipes.md`. Begin with subject, spatial purpose, recurrence,
|
|
18
|
+
interaction, and berth—not a primitive or shader technique.
|
|
19
|
+
|
|
20
|
+
## 1. Hard gates
|
|
21
|
+
|
|
22
|
+
- **No coded organic subjects (`3d.noCodedOrganic`).** Food, plants, fabric,
|
|
23
|
+
skin, liquid, wood, or other richly textured real objects never ship as crude
|
|
24
|
+
primitives. Use a real GLB, photoreal cutout, sourced photo, or cut the object.
|
|
25
|
+
- WebGL/context loss/loading/low power/mobile/reduced motion always has a real
|
|
26
|
+
poster or DOM fallback (`effects.runtimeFallback`, `motion.reducedMotion`).
|
|
27
|
+
- Canvas and traveling objects never cover content or controls; pointer events
|
|
28
|
+
and keyboard paths remain intact (`spatial.noOcclusion`, `ux.functional`).
|
|
29
|
+
- Text remains semantic DOM, not texture-baked. Content is visible without 3D.
|
|
30
|
+
- Models/textures/materials named as shipped assets exist and are tracked.
|
|
31
|
+
- Verification proves a live context/draw, interaction, performance, and
|
|
32
|
+
fallback behavior with structured evidence.
|
|
33
|
+
|
|
34
|
+
## 2. Award spatial signature
|
|
35
|
+
|
|
36
|
+
`award.spatialSignature` requires one unmistakable dimensional or spatial
|
|
37
|
+
signature with depth, recurrence, input response, and visual dominance on
|
|
38
|
+
desktop and mobile.
|
|
39
|
+
|
|
40
|
+
The proven default is:
|
|
41
|
+
|
|
42
|
+
1. a recognizable real GLB; or
|
|
43
|
+
2. a photoreal transparent cutout billboard staged with parallax, restrained
|
|
44
|
+
rotation, contact shadow, rim light, and—when useful—multiple angles.
|
|
45
|
+
|
|
46
|
+
This default exists because dogfood coded/shader hero objects repeatedly read as
|
|
47
|
+
generic demos. Valid registered alternatives include spatial typography,
|
|
48
|
+
layered photographic depth, a persistent interactive scene instrument, or a
|
|
49
|
+
data-driven spatial structure that meets declared observable criteria.
|
|
50
|
+
|
|
51
|
+
A generic orb, blob, sphere, torus, or untextured coded form remains invalid as
|
|
52
|
+
a signature. `3d.signatureRecognizable` permits a brand-native abstract
|
|
53
|
+
instrument only when it has a nameable function, material identity, recurrence,
|
|
54
|
+
and input response; ambient decoration does not qualify.
|
|
55
|
+
|
|
56
|
+
## 3. Staging and material
|
|
57
|
+
|
|
58
|
+
Every object gets a planned berth: section/lane, space reserved by type/layout,
|
|
59
|
+
crop, light direction, shadow/ground, travel states, and hidden states when no
|
|
60
|
+
safe berth exists. It never floats over other imagery unless genuinely
|
|
61
|
+
composited with matched light and cast/contact shadow.
|
|
62
|
+
|
|
63
|
+
Realism comes from material and light, not geometry count:
|
|
64
|
+
|
|
65
|
+
- environment/IBL plus one coherent key direction;
|
|
66
|
+
- deliberate exposure/color management;
|
|
67
|
+
- contact/cast shadow or defensible weightlessness;
|
|
68
|
+
- texture/normal/roughness or a custom procedural shader for visible coded
|
|
69
|
+
geometry;
|
|
70
|
+
- camera FOV/framing appropriate to the subject;
|
|
71
|
+
- damped input and subtle idle behavior.
|
|
72
|
+
|
|
73
|
+
## 4. Architecture
|
|
74
|
+
|
|
75
|
+
React uses R3F + drei unless the existing stack strongly dictates otherwise;
|
|
76
|
+
one simple shader plane may use OGL/three.js. Lazy-load the whole spatial bundle
|
|
77
|
+
outside the critical path. One scene owns related planes/objects. Reuse vectors
|
|
78
|
+
and buffers; avoid allocations in render loops.
|
|
79
|
+
|
|
80
|
+
Models use optimized GLB/glTF with measured bytes/triangles and a poster during
|
|
81
|
+
load. Particles use points/instancing, not mesh-per-particle. DOM-synced media
|
|
82
|
+
planes keep semantic source media for layout and fallback.
|
|
83
|
+
|
|
84
|
+
## 5. Performance and verification
|
|
85
|
+
|
|
86
|
+
- Cap DPR and complexity; pause off-screen/hidden work.
|
|
87
|
+
- Mobile reduces particles/post effects or uses a purpose-designed poster.
|
|
88
|
+
- Reduced motion renders a stable, intentional frame.
|
|
89
|
+
- Dispose imperative resources and test route transitions/context restoration.
|
|
90
|
+
- Record transferred weight, frame-time/FPS sample, context/draw evidence,
|
|
91
|
+
object/material identity, desktop/mobile screenshots, input response, and
|
|
92
|
+
poster/context-loss fallback.
|
|
93
|
+
|
|
94
|
+
Recipe reference: `../recipes/3d-recipes.md`, after concept exploration only.
|