arkaos 5.3.0 → 5.5.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.
Files changed (57) hide show
  1. package/README.md +2 -2
  2. package/THE-ARKAOS-GUIDE.md +1 -1
  3. package/VERSION +1 -1
  4. package/arka/SKILL.md +1 -1
  5. package/config/skills-provenance.yaml +28 -0
  6. package/departments/brand/skills/colors/SKILL.md +3 -1
  7. package/departments/brand/skills/design-dna/SKILL.md +191 -0
  8. package/departments/brand/skills/design-dna/references/design-dna.LICENSE +21 -0
  9. package/departments/brand/skills/design-dna/references/generation-guide.md +209 -0
  10. package/departments/brand/skills/design-dna/references/schema.md +366 -0
  11. package/departments/brand/skills/design-system/SKILL.md +12 -3
  12. package/departments/dev/skills/canvas-generative/SKILL.md +362 -0
  13. package/departments/dev/skills/canvas-generative/references/algorithms.md +934 -0
  14. package/departments/dev/skills/canvas-generative/references/genjutsu.LICENSE +21 -0
  15. package/departments/dev/skills/css-native/SKILL.md +353 -0
  16. package/departments/dev/skills/css-native/references/genjutsu.LICENSE +21 -0
  17. package/departments/dev/skills/css-native/references/modern-css.md +465 -0
  18. package/departments/dev/skills/framer-motion/SKILL.md +223 -0
  19. package/departments/dev/skills/framer-motion/references/api.md +312 -0
  20. package/departments/dev/skills/framer-motion/references/genjutsu.LICENSE +21 -0
  21. package/harness/codex/AGENTS.md +1 -1
  22. package/harness/copilot/copilot-instructions.md +1 -1
  23. package/harness/cursor/rules/arkaos.mdc +2 -2
  24. package/harness/gemini/GEMINI.md +1 -1
  25. package/harness/opencode/AGENTS.md +1 -1
  26. package/harness/opencode/agents/arka-architect-gabriel.md +1 -1
  27. package/harness/opencode/agents/arka-brand-director-valentina.md +1 -1
  28. package/harness/opencode/agents/arka-cfo-helena.md +1 -1
  29. package/harness/opencode/agents/arka-chief-of-staff-afonso.md +1 -1
  30. package/harness/opencode/agents/arka-community-strategist-beatriz.md +1 -1
  31. package/harness/opencode/agents/arka-content-strategist-rafael.md +1 -1
  32. package/harness/opencode/agents/arka-conversion-strategist-ines.md +1 -1
  33. package/harness/opencode/agents/arka-coo-sofia.md +1 -1
  34. package/harness/opencode/agents/arka-copy-director-eduardo.md +1 -1
  35. package/harness/opencode/agents/arka-cqo-marta.md +1 -1
  36. package/harness/opencode/agents/arka-cto-marco.md +1 -1
  37. package/harness/opencode/agents/arka-design-ops-lead-iris.md +1 -1
  38. package/harness/opencode/agents/arka-ecom-director-ricardo.md +1 -1
  39. package/harness/opencode/agents/arka-knowledge-director-clara.md +1 -1
  40. package/harness/opencode/agents/arka-leadership-director-rodrigo.md +1 -1
  41. package/harness/opencode/agents/arka-marketing-director-luna.md +1 -1
  42. package/harness/opencode/agents/arka-ops-lead-daniel.md +1 -1
  43. package/harness/opencode/agents/arka-pm-director-carolina.md +1 -1
  44. package/harness/opencode/agents/arka-revops-lead-vicente.md +1 -1
  45. package/harness/opencode/agents/arka-saas-strategist-tiago.md +1 -1
  46. package/harness/opencode/agents/arka-sales-director-miguel.md +1 -1
  47. package/harness/opencode/agents/arka-strategy-director-tomas.md +1 -1
  48. package/harness/opencode/agents/arka-tech-director-francisca.md +1 -1
  49. package/harness/opencode/agents/arka-tech-lead-paulo.md +1 -1
  50. package/harness/opencode/agents/arka-video-producer-simao.md +1 -1
  51. package/harness/zed/.rules +1 -1
  52. package/knowledge/commands-registry.json +1 -1
  53. package/knowledge/skills-manifest.json +61 -1
  54. package/package.json +1 -1
  55. package/pyproject.toml +1 -1
  56. package/scripts/marketplace_gen.py +1 -1
  57. package/scripts/skills_catalog_gen.py +5 -5
@@ -0,0 +1,362 @@
1
+ ---
2
+ name: dev/canvas-generative
3
+ description: >
4
+ Algorithmic and generative art with Canvas 2D: DPR-aware setup, particle
5
+ systems with pooled allocation, noise fields, flow fields, fractals and
6
+ L-systems, double buffering — with reference implementations for the
7
+ core algorithms.
8
+ TRIGGER: "generative art", "arte generativa", "particles background",
9
+ "fundo de partículas", "noise field", "flow field", "canvas animation",
10
+ "fundo processual", "creative coding em canvas", "/dev canvas-generative".
11
+ SKIP: real-time 3D or shader work -> no dedicated skill yet, use the
12
+ frontend workflows; a pre-rendered 3D world scrubbed by scroll ->
13
+ dev/scroll-world; turning an existing video into a scroll site ->
14
+ dev/animated-website; charts and data graphics -> the dataviz skill.
15
+ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob]
16
+ metadata:
17
+ origin: community
18
+ source: https://github.com/AThevon/genjutsu
19
+ license: MIT
20
+ ---
21
+
22
+ <!-- arka:kb-first-prefix begin -->
23
+ > **KB-first:** query `mcp__obsidian__search_notes` (and
24
+ > `mcp__graphify__query_graph` when configured) and cite `[[wikilinks]]`
25
+ > or graph nodes — or declare the gap — BEFORE any external research.
26
+ > Full doctrine: `arka/SKILL.md` (KB-First Research).
27
+ <!-- arka:kb-first-prefix end -->
28
+
29
+ # Canvas Generative — `/dev canvas-generative`
30
+
31
+ > **Agent:** Diana (Frontend Dev) | **Framework:** Canvas 2D generative patterns (genjutsu)
32
+
33
+ > Algorithmic and generative art with Canvas 2D.
34
+ > Concise rules here. Deep-dive and reference implementations in `references/`.
35
+
36
+ ---
37
+
38
+ ## Canvas 2D Setup
39
+
40
+ ### DPR-Aware Sizing
41
+
42
+ Every canvas must be sharp on Retina/HiDPI displays. Set the buffer size to the physical pixel size, scale down with CSS.
43
+
44
+ ```js
45
+ function setupCanvas(canvas, width, height) {
46
+ const dpr = window.devicePixelRatio || 1;
47
+ canvas.width = width * dpr;
48
+ canvas.height = height * dpr;
49
+ canvas.style.width = `${width}px`;
50
+ canvas.style.height = `${height}px`;
51
+ const ctx = canvas.getContext('2d');
52
+ ctx.scale(dpr, dpr);
53
+ return ctx;
54
+ }
55
+ ```
56
+
57
+ ### Resize Handler
58
+
59
+ ```js
60
+ function handleResize(canvas, ctx, draw) {
61
+ const ro = new ResizeObserver(([entry]) => {
62
+ const { width, height } = entry.contentRect;
63
+ const dpr = window.devicePixelRatio || 1;
64
+ canvas.width = width * dpr;
65
+ canvas.height = height * dpr;
66
+ // setupCanvas pinned the CSS box inline; inline styles beat
67
+ // stylesheet rules, so skip this pair and the canvas stretches
68
+ // and blurs after any viewport change.
69
+ canvas.style.width = `${width}px`;
70
+ canvas.style.height = `${height}px`;
71
+ ctx.scale(dpr, dpr); // setting width reset the transform; rescale
72
+ draw(); // re-render after resize
73
+ });
74
+ ro.observe(canvas.parentElement);
75
+ return () => ro.disconnect();
76
+ }
77
+ ```
78
+
79
+ ### Animation Loop (RAF)
80
+
81
+ ```js
82
+ let animId;
83
+ let prevTime = 0;
84
+
85
+ function loop(time) {
86
+ const dt = Math.min((time - prevTime) / 1000, 0.1); // cap delta to avoid spiral of death
87
+ prevTime = time;
88
+
89
+ update(dt);
90
+ render(ctx);
91
+
92
+ animId = requestAnimationFrame(loop);
93
+ }
94
+
95
+ // Start
96
+ animId = requestAnimationFrame(loop);
97
+ // Stop
98
+ cancelAnimationFrame(animId);
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Noise
104
+
105
+ | Type | Characteristics | Best For |
106
+ |---|---|---|
107
+ | Perlin | Smooth, grid-aligned bias, cheaper | Terrain, clouds, gentle organic textures |
108
+ | Simplex | No grid artifacts, better gradients, slightly costlier | Flow fields, organic motion, seamless tiling |
109
+ | Worley (Cellular) | Distance-to-nearest-point, cell-like | Voronoi patterns, caustics, cracks, cell textures |
110
+
111
+ **Usage rules:**
112
+ - Always scale input coordinates (divide by a `noiseScale` factor) -- raw pixel coords produce visual noise
113
+ - Use octaves (fractal Brownian motion) for detail: sum multiple noise calls at increasing frequency and decreasing amplitude
114
+ - Seed your noise for reproducibility
115
+
116
+ ```js
117
+ // fBm pattern
118
+ function fbm(x, y, octaves = 4, lacunarity = 2, gain = 0.5) {
119
+ let value = 0, amplitude = 1, frequency = 1, maxAmp = 0;
120
+ for (let i = 0; i < octaves; i++) {
121
+ value += amplitude * noise2D(x * frequency, y * frequency);
122
+ maxAmp += amplitude;
123
+ amplitude *= gain;
124
+ frequency *= lacunarity;
125
+ }
126
+ return value / maxAmp; // normalize to [-1, 1]
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Particle Systems
133
+
134
+ ### Pool Pattern (No GC Pressure)
135
+
136
+ Pre-allocate a fixed array. Never `new` or `splice` at runtime.
137
+
138
+ ```js
139
+ const POOL_SIZE = 10000;
140
+ const particles = new Array(POOL_SIZE);
141
+ let aliveCount = 0;
142
+
143
+ // Init pool
144
+ for (let i = 0; i < POOL_SIZE; i++) {
145
+ particles[i] = { x: 0, y: 0, vx: 0, vy: 0, life: 0, maxLife: 0, active: false };
146
+ }
147
+
148
+ function spawn(x, y) {
149
+ if (aliveCount >= POOL_SIZE) return;
150
+ const p = particles[aliveCount++];
151
+ p.x = x; p.y = y;
152
+ p.vx = (Math.random() - 0.5) * 2;
153
+ p.vy = (Math.random() - 0.5) * 2;
154
+ p.life = 0; p.maxLife = 60 + Math.random() * 60;
155
+ p.active = true;
156
+ }
157
+
158
+ function update() {
159
+ for (let i = aliveCount - 1; i >= 0; i--) {
160
+ const p = particles[i];
161
+ p.x += p.vx; p.y += p.vy;
162
+ p.life++;
163
+ if (p.life >= p.maxLife) {
164
+ // Swap with last alive, shrink pool
165
+ particles[i] = particles[--aliveCount];
166
+ particles[aliveCount] = p;
167
+ p.active = false;
168
+ }
169
+ }
170
+ }
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Flow Fields
176
+
177
+ Grid of angle vectors that steer particles. The classic generative recipe.
178
+
179
+ 1. **Build grid:** Divide canvas into cells, compute an angle per cell (from noise)
180
+ 2. **Lookup:** Particle position maps to grid cell, retrieve angle
181
+ 3. **Steer:** Apply angle as velocity, accumulate over frames
182
+
183
+ ```js
184
+ const cols = Math.ceil(width / cellSize);
185
+ const rows = Math.ceil(height / cellSize);
186
+ const field = new Float32Array(cols * rows);
187
+
188
+ // Fill with noise-based angles
189
+ for (let y = 0; y < rows; y++) {
190
+ for (let x = 0; x < cols; x++) {
191
+ field[y * cols + x] = noise2D(x * 0.05, y * 0.05) * Math.PI * 2;
192
+ }
193
+ }
194
+
195
+ // Particle follow
196
+ function followField(p) {
197
+ const col = Math.floor(p.x / cellSize);
198
+ const row = Math.floor(p.y / cellSize);
199
+ if (col >= 0 && col < cols && row >= 0 && row < rows) {
200
+ const angle = field[row * cols + col];
201
+ p.vx += Math.cos(angle) * force;
202
+ p.vy += Math.sin(angle) * force;
203
+ }
204
+ // Damping to prevent runaway velocity
205
+ p.vx *= 0.98;
206
+ p.vy *= 0.98;
207
+ }
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Fractals & L-Systems
213
+
214
+ An L-system encodes recursive structure as string rewriting + turtle graphics.
215
+
216
+ | Component | Role |
217
+ |---|---|
218
+ | Axiom | Starting string (e.g. `"F"`) |
219
+ | Rules | Production rules (e.g. `"F" -> "F[+F]F[-F]F"`) |
220
+ | Angle | Turtle turn angle per `+`/`-` |
221
+ | Iterations | How many times to apply rules |
222
+
223
+ ```js
224
+ function lsystem(axiom, rules, iterations) {
225
+ let current = axiom;
226
+ for (let i = 0; i < iterations; i++) {
227
+ current = current.split('').map(c => rules[c] || c).join('');
228
+ }
229
+ return current;
230
+ }
231
+
232
+ function drawLSystem(ctx, commands, len, angle) {
233
+ const stack = [];
234
+ for (const c of commands) {
235
+ switch (c) {
236
+ case 'F': ctx.lineTo(ctx._x += Math.cos(ctx._a) * len, ctx._y += Math.sin(ctx._a) * len); break;
237
+ case '+': ctx._a += angle; break;
238
+ case '-': ctx._a -= angle; break;
239
+ case '[': stack.push({ x: ctx._x, y: ctx._y, a: ctx._a }); break;
240
+ case ']': { const s = stack.pop(); ctx._x = s.x; ctx._y = s.y; ctx._a = s.a; ctx.moveTo(s.x, s.y); } break;
241
+ }
242
+ }
243
+ }
244
+ ```
245
+
246
+ ---
247
+
248
+ ## Double Buffer Pattern
249
+
250
+ Render to an offscreen canvas, then blit to the visible one. Eliminates flicker and enables trail effects.
251
+
252
+ ```js
253
+ const offscreen = document.createElement('canvas');
254
+ offscreen.width = canvas.width;
255
+ offscreen.height = canvas.height;
256
+ const offCtx = offscreen.getContext('2d');
257
+
258
+ function render() {
259
+ // Draw to offscreen
260
+ offCtx.fillStyle = 'rgba(0, 0, 0, 0.05)'; // trail fade
261
+ offCtx.fillRect(0, 0, offscreen.width, offscreen.height);
262
+ drawParticles(offCtx);
263
+
264
+ // Blit to screen
265
+ ctx.drawImage(offscreen, 0, 0);
266
+ }
267
+ ```
268
+
269
+ ---
270
+
271
+ ## Do Not
272
+
273
+ ### 1. Never clearRect every frame for trail effects
274
+
275
+ Clearing destroys the trail. Use a semi-transparent fill instead.
276
+
277
+ ```js
278
+ // BAD -- kills trails
279
+ ctx.clearRect(0, 0, w, h);
280
+
281
+ // GOOD -- fades previous frame
282
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.02)';
283
+ ctx.fillRect(0, 0, w, h);
284
+ ```
285
+
286
+ ### 2. Never getImageData in the animation loop
287
+
288
+ `getImageData` reads back from GPU -- extremely slow. Avoid unless absolutely required (e.g. one-time color sampling).
289
+
290
+ ```js
291
+ // BAD -- 60fps GPU readback
292
+ function loop() {
293
+ const data = ctx.getImageData(0, 0, w, h); // blocks rendering pipeline
294
+ processPixels(data);
295
+ requestAnimationFrame(loop);
296
+ }
297
+
298
+ // GOOD -- sample once, cache
299
+ const colorMap = ctx.getImageData(0, 0, w, h);
300
+ function getColor(x, y) {
301
+ const i = (y * w + x) * 4;
302
+ return [colorMap.data[i], colorMap.data[i+1], colorMap.data[i+2]];
303
+ }
304
+ ```
305
+
306
+ ### 3. Always respect DPR for sharpness
307
+
308
+ A canvas without DPR scaling looks blurry on Retina displays. See setup section above.
309
+
310
+ ```js
311
+ // BAD
312
+ canvas.width = 800;
313
+ canvas.height = 600;
314
+
315
+ // GOOD
316
+ const dpr = window.devicePixelRatio || 1;
317
+ canvas.width = 800 * dpr;
318
+ canvas.height = 600 * dpr;
319
+ canvas.style.width = '800px';
320
+ canvas.style.height = '600px';
321
+ ctx.scale(dpr, dpr);
322
+ ```
323
+
324
+ ### 4. Never allocate in the hot loop
325
+
326
+ No `new`, no object spread, no array creation inside `update()` or `render()`. Pre-allocate everything.
327
+
328
+ ```js
329
+ // BAD
330
+ function update() {
331
+ particles.forEach(p => {
332
+ const force = { x: Math.cos(a), y: Math.sin(a) }; // new object every frame per particle
333
+ p.vx += force.x;
334
+ });
335
+ }
336
+
337
+ // GOOD
338
+ let fx = 0, fy = 0; // reuse
339
+ function update() {
340
+ for (let i = 0; i < aliveCount; i++) {
341
+ fx = Math.cos(a); fy = Math.sin(a);
342
+ particles[i].vx += fx;
343
+ }
344
+ }
345
+ ```
346
+
347
+ ---
348
+
349
+ ## Quick Reference: Loading Sub-skills
350
+
351
+ | Need | Load |
352
+ |---|---|
353
+ | Noise implementations, particle pool, flow field, L-system, attractors | `references/algorithms.md` |
354
+ | Timing and easing for animated transitions | the brand guidelines' Motion System (§06), reached via the source-of-truth table in `departments/brand/references/uiux-knowledge-and-tools.md` |
355
+ | 3D generative (shaders, GPU particles) | out of this skill's scope — Canvas 2D only; scope a WebGL approach with the frontend squad |
356
+
357
+ ## Output
358
+
359
+ A self-contained canvas module — DPR-aware setup, pooled particles or the
360
+ chosen algorithm, RAF loop with cleanup — dropped into the project's
361
+ component conventions, plus a one-line note of the algorithm and budget
362
+ chosen. Deep implementations stay in `references/algorithms.md`.