Files
AgentCompany/builtin-skills/frontend-design/design-dna/references/generation-guide.md
T
ZacharyZhang-NY e74dafcd36 Silence render-disposed spam, unbreak bundled skills, drop board wake
Three independently ugly bugs that all fed the same log flood:

* Electron's `WebFrameMain.send` writes every "Render frame was disposed"
  to stderr via `console.error`. When the worker fans a second
  agent-event past a reloading renderer, we produced thousands of
  identical lines and stalled the main loop on stderr I/O. Added a
  `mainFrame.detached` guard so the send is short-circuited before
  Electron's own catch block fires, and installed a targeted filter in
  `suppress-warnings.ts` (now actually imported from the entry point)
  so the specific `console.error("Error sending from webFrameMain:"…)`
  noise never reaches the terminal. Any other payload still surfaces.

* `dispatchAgentMessage` accepted the human-reader sentinel as a wake
  target when an agent replied to `__board__` — `wakeAgentIfPossible`
  then called `db.getAgent("__board__")`, threw, and the dispatcher
  kept repeating on every send. Strip `HUMAN_SENDER_ID` at
  `resolveMessageWakeTargets`, and keep a defense-in-depth guard in the
  heartbeat so a stray caller (future automation fan-out) cannot
  reintroduce the crash.

* Pi's skills loader rejects any SKILL.md whose frontmatter `name`
  diverges from its parent directory. The four bundled `my-writing-style`
  copies declared `name: writing-style-skill`, so every install emitted
  a warning and dropped the skill. They also lived as orphan gitlinks
  (mode 160000 without .gitmodules), and the global `*.md` gitignore
  hid every other SKILL.md from version control. Fixed the frontmatter
  to match the dir, converted the dangling submodules to plain trees,
  and allowlisted `builtin-skills/**/*.md` so a fresh clone carries the
  catalogue instead of silently losing it.
2026-04-20 08:13:48 -04:00

210 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Generation Guide
How to use a completed Design DNA JSON to generate designs in Phase 3. Covers all three dimensions.
## Priority Order
When generating a design from DNA JSON + content:
1. **Color & Typography** — define 80% of visual identity
2. **Spacing & Layout** — structural rhythm
3. **Shape & Elevation** — surface treatment
4. **Design Style qualitative fields** — mood, personality, composition approach
5. **Visual Effects** — special rendering layer (Canvas, WebGL, shaders, etc.)
6. **Motion & Interaction** — enhance after static layout and effects are solid
## Dimension 1: design_system → Code
### Tailwind CSS / Utility-First
```
color.primary.hex → --color-primary / bg-[hex]
typography.font_families → font-family config
spacing.scale → spacing config values
shape.border_radius → rounded-{sm|md|lg|full}
elevation.levels → shadow-{sm|md|lg}
```
### Plain CSS / CSS Variables
Generate a `:root` block with all design tokens:
```css
:root {
--color-primary: {color.primary.hex};
--color-secondary: {color.secondary.hex};
--color-accent: {color.accent.hex};
--font-heading: {typography.font_families.heading};
--font-body: {typography.font_families.body};
--radius-sm: {shape.border_radius.small};
--radius-md: {shape.border_radius.medium};
--radius-lg: {shape.border_radius.large};
--shadow-low: {elevation.levels.low};
--shadow-med: {elevation.levels.medium};
--shadow-high: {elevation.levels.high};
--ease: {motion.easing};
--duration-micro: {motion.duration_scale.micro};
--duration-normal: {motion.duration_scale.normal};
--duration-macro: {motion.duration_scale.macro};
/* ... map all tokens */
}
```
### Component Decisions
- `components.button_style` → button classes and variants
- `components.card_style` → card container treatment
- `components.navigation_pattern` → nav component choice
- `interaction_feel.hover_behavior` → :hover / :focus states
- `motion.easing` + `motion.duration_scale` → transition properties
## Dimension 2: design_style → Subjective Decisions
| DNA Field | Guides |
|---|---|
| aesthetic.mood | Overall emotional feeling — warm tones, cool precision, etc. |
| visual_language.whitespace_usage | padding/margin generosity |
| visual_language.contrast_level | How much elements pop vs. blend |
| composition.hierarchy_method | What tool to use for emphasis |
| composition.balance_type | Symmetric layout vs. dynamic asymmetry |
| imagery.graphic_elements | Decorative SVGs, gradients, patterns |
| brand_voice_in_ui.tone | Microcopy phrasing |
| interaction_feel.microinteraction_density | How many hover/click effects |
## Dimension 3: visual_effects → Special Rendering
### Technology Selection by Performance Tier
| Tier | Technologies | When to Use |
|---|---|---|
| **lightweight** | CSS animations, SVG SMIL, vanilla JS | `overview.performance_tier` = "lightweight" |
| **medium** | Canvas 2D, GSAP, Lottie, anime.js | `overview.performance_tier` = "medium" |
| **heavy** | Three.js, custom GLSL, Pixi.js, WebGL | `overview.performance_tier` = "heavy" |
### Implementation Patterns
#### Background Effects
```
"none" → skip
"gradient-animation" → CSS @keyframes on linear-gradient or conic-gradient
"noise-field" → Canvas 2D with Perlin/simplex noise
"mesh-gradient" → SVG <mesh> or canvas interpolation
"video-bg" → <video autoplay muted loop> with poster fallback
"generative-art" → Canvas 2D or WebGL generative algorithms
```
#### Particle Systems
When `particle_systems.enabled: true`:
- For `count` < 100 and no complex physics → vanilla JS + Canvas 2D
- For `count` >= 100 or complex interaction → consider Pixi.js or Three.js Points
- Map `interaction` ("mouse-repel", "mouse-attract") to pointer event handlers
- Use `requestAnimationFrame` loop; include destroy/cleanup on unmount
#### 3D Elements
When `3d_elements.enabled: true`:
- Default to Three.js unless DNA specifies otherwise
- Apply `lighting`, `camera`, `materials` from params
- Add `post_processing` effects via EffectComposer
- Handle resize with `ResizeObserver`
- Load via CDN: `https://cdn.jsdelivr.net/npm/three@latest/build/three.module.js`
#### Shader Effects
When `shader_effects.enabled: true`:
- Create vertex/fragment shaders based on `type`
- Pass `uniforms` from params (time, resolution, mouse position)
- For "noise-distortion": use noise functions matching `noise_type`
- Animate via `requestAnimationFrame` updating `u_time` uniform
#### Scroll Effects
- **Parallax**: Use `transform: translateY()` with scroll offset × layer speed
- **Scroll-triggered**: Use `IntersectionObserver` with `threshold` array
- **Scrub behavior**: If "scrubbed", animation progress = scroll progress. If "triggered", play once on enter.
#### Text Effects
```
"split-letter-animate" → Split text into <span> per char/word, stagger CSS animation
"typewriter" → CSS steps() or JS interval revealing chars
"glitch" → Layered clip-path + color offset animation
"gradient-fill" → background-clip: text with animated gradient
"3d-extrude" → text-shadow stack or WebGL text geometry
```
#### Cursor Effects
When `cursor_effects.enabled: true`:
- Hide default cursor: `cursor: none`
- Create custom cursor element following `pointermove`
- "magnetic-buttons": Apply transform pull on hover proximity
- "spotlight": Radial gradient mask following cursor
- "trail": Spawn fading elements on move
#### Glassmorphism / Neumorphism
```
"glass" → backdrop-filter: blur({blur_radius}); background: rgba(..., {transparency})
"neumorphic-light" → Dual box-shadow (light + dark offset) on light bg
"neumorphic-dark" → Dual box-shadow (inverted) on dark bg
"frosted-layers" → Stacked blur layers with varying opacity
```
#### Canvas Drawings
When `canvas_drawings.enabled: true`:
- Initialize canvas with `width/height` matching container
- Use `draw_method` to select rendering approach
- Animate with `requestAnimationFrame`
- Handle `responsiveness` via ResizeObserver
#### SVG Animations
When `svg_animations.enabled: true`:
- "path-draw": Animate `stroke-dashoffset` from path length to 0
- "morph-shapes": Interpolate `d` attribute between two paths
- "stroke-animation": Animate stroke properties (dasharray, width, color)
### Fallback Strategy
Always implement the fallback defined in `overview.fallback_strategy`:
```js
// Example: reduce to CSS on low-end devices
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const isLowEnd = navigator.hardwareConcurrency <= 2;
if (prefersReduced || isLowEnd) {
// Apply fallback: static CSS version, disable canvas/WebGL
}
```
## Output Format
Generate output as a single self-contained HTML file with inline CSS and JS (unless user specifies a framework). Include:
1. CSS custom properties block from `design_system` tokens
2. Component styles from `design_system.components` + `design_style`
3. Layout structure per `design_system.layout`
4. Content populated from user-provided content
5. Visual effects implemented per `visual_effects` specification
6. Animations/transitions if `design_system.motion.philosophy` is not "none"
7. Fallback handling for effects
For heavy effects requiring external libraries, load via CDN `<script>` tags:
```html
<!-- Three.js -->
<script type="importmap">{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@latest/build/three.module.js"}}</script>
<!-- GSAP -->
<script src="https://cdn.jsdelivr.net/npm/gsap@latest/dist/gsap.min.js"></script>
<!-- Lottie -->
<script src="https://cdn.jsdelivr.net/npm/lottie-web@latest/build/player/lottie.min.js"></script>
```
## Quality Checks
Before delivering, verify:
- [ ] Every color in output traces back to DNA palette
- [ ] Font families match DNA specification
- [ ] Spacing rhythm matches DNA scale
- [ ] Border radius matches DNA shape tokens
- [ ] Overall mood matches `design_style.aesthetic.mood`
- [ ] Component patterns match DNA `components` descriptions
- [ ] Contrast ratios meet WCAG AA minimum (4.5:1 body text, 3:1 large text)
- [ ] Visual effects match `visual_effects` specification (type, technology, params)
- [ ] Fallback strategy is implemented for effects
- [ ] `prefers-reduced-motion` is respected
- [ ] No effects render when their `enabled` flag is `false`
- [ ] Canvas/WebGL contexts are properly sized and handle resize
- [ ] Animation loops use `requestAnimationFrame` (no `setInterval`)