@fugood/bricks-ctor 2.25.0-beta.12 → 2.25.0-beta.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 (27) hide show
  1. package/compile/index.ts +2 -0
  2. package/package.json +2 -2
  3. package/skills/bricks-design/SKILL.md +172 -45
  4. package/skills/bricks-design/references/architecture-truths.md +125 -0
  5. package/skills/bricks-design/references/avoiding-complexity.md +91 -0
  6. package/skills/bricks-design/references/design-critique.md +195 -0
  7. package/skills/bricks-design/references/design-languages.md +265 -0
  8. package/skills/bricks-design/references/performance.md +116 -0
  9. package/skills/bricks-design/references/presentation-and-slideshow.md +137 -0
  10. package/skills/bricks-design/references/translating-inputs.md +152 -0
  11. package/skills/bricks-design/references/variations-and-tweaks.md +124 -0
  12. package/skills/bricks-design/references/verification-toolchain.md +213 -0
  13. package/skills/bricks-design/references/when-the-brief-is-branded.md +284 -0
  14. package/skills/bricks-design/references/when-the-brief-is-vague.md +85 -0
  15. package/skills/bricks-design/references/workflow.md +134 -0
  16. package/skills/bricks-ux/SKILL.md +120 -0
  17. package/skills/bricks-ux/references/accessibility.md +162 -0
  18. package/skills/bricks-ux/references/flow-states.md +175 -0
  19. package/skills/bricks-ux/references/interaction-archetypes.md +189 -0
  20. package/skills/bricks-ux/references/monitoring-screens.md +153 -0
  21. package/skills/bricks-ux/references/pressable-composition.md +126 -0
  22. package/skills/bricks-ux/references/user-journey.md +168 -0
  23. package/skills/bricks-ux/references/ux-critique.md +256 -0
  24. package/tools/pull.ts +42 -2
  25. package/types/automation.ts +1 -0
  26. package/types/data-calc.ts +1 -0
  27. package/skills/bricks-design/LICENSE.txt +0 -180
@@ -0,0 +1,195 @@
1
+ # Design Critique — self-review before "done"
2
+
3
+ The Verification gate proves the design *runs*. Critique proves it's *good*. Both are required before declaring done; neither substitutes for the other.
4
+
5
+ This file gives the agent a structured self-review pass: five scoring dimensions with concrete rubrics, a per-deployment-shape focus chart, and an extended anti-slop top-10 with BRICKS-specific failure modes. Run the pass after the screenshots are captured and viewed (per [`verification-toolchain.md`](verification-toolchain.md)), and before declaring done to the user.
6
+
7
+ The point isn't to be self-critical for its own sake. The point is to catch the specific failure modes that consistently ship if not actively rooted out.
8
+
9
+ ## How to run the pass
10
+
11
+ 1. **Verify** — compile clean + screenshot every Canvas + read screenshots back (see `verification-toolchain.md`).
12
+ 2. **Score** — for each Canvas, rate the five dimensions below 0–10 against the rubrics.
13
+ 3. **Anti-slop sweep** — walk the top-10 list; flag every match.
14
+ 4. **Fix anything < 8** and any anti-slop matches; re-verify.
15
+ 5. **Declare done** — only when every Canvas scores ≥ 8 on every dimension and the anti-slop list is clean.
16
+
17
+ If a dimension cannot be scored ≥ 8 within the deployment's constraints, surface it as an accepted trade-off in the trade-off note rather than silently shipping a 6.
18
+
19
+ ## The five dimensions
20
+
21
+ ### 1. System commitment
22
+
23
+ *Does the work cite the declared system (the comment block at the top of the Subspace), and does deviation have rationale?*
24
+
25
+ | Score | Rubric |
26
+ |---|---|
27
+ | 9–10 | Every brick property points back to a Data token, an `ApplicationFont` entry, or the system block. Deviations carry a one-line comment explaining why. |
28
+ | 7–8 | Direction is correct; 1–2 hardcoded values that should be tokens, or 1–2 deviations without rationale. |
29
+ | 5–6 | Visible drift — a third type family slipped in, a fourth color appeared mid-flow, or a brick redrew an asset that exists in Media Flow. |
30
+ | 3–4 | The system block is decorative; the work doesn't follow it. |
31
+ | 1–2 | No system block, or the block contradicts the work. |
32
+
33
+ **Audit moves:**
34
+ - Open the system block. Pick five values from it (a color, a type size, a Standby duration, a margin, a Brick template). For each, check that the work uses it consistently.
35
+ - Pick five values *from* the work (a `backgroundColor` literal, a `fontSize`, a Standby easing, a hex code in a Rect, a brick template choice). For each, check that the value traces back to the system block or has rationale.
36
+ - If signature moves of the chosen design language (per [`design-languages.md`](design-languages.md)) are absent, score drops regardless of token-discipline. Swiss Editorial without numbered folios and hairline rules is not Swiss Editorial; it's "vaguely minimal."
37
+
38
+ ### 2. Visual hierarchy
39
+
40
+ *Does the user's eye flow where the designer intended? Is information findable in under 2 seconds?*
41
+
42
+ | Score | Rubric |
43
+ |---|---|
44
+ | 9–10 | Squint test passes — even at low resolution / low attention, primary / secondary / tertiary are unmistakable. Display:body scale ratio ≥ 2.5×. Three to four clear levels via size, weight, color, and space combined. |
45
+ | 7–8 | Hierarchy is clear with one or two muddy spots. |
46
+ | 5–6 | Title and body distinguished, but mid-levels collapse together; user has to read everything to find anything. |
47
+ | 3–4 | Information is uniform; no entry point. |
48
+ | 1–2 | The eye doesn't know where to land. |
49
+
50
+ **Audit moves:**
51
+ - The squint test. View the screenshot at 25% zoom or with eyes half-closed. The composition should still read.
52
+ - Measure the display:body scale ratio in grid units. < 2.5× = deduction.
53
+ - Count the levels distinguishable in the Canvas. < 3 = deduction; > 5 = different deduction (over-stratified).
54
+ - For the deployment's viewing distance, simulate the legibility floor (per the scale-floor table in `architecture-truths.md` Truth #6 + `performance.md`'s scale section). If body text won't read at that distance, hierarchy fails regardless of relative ratios.
55
+
56
+ ### 3. Craft execution
57
+
58
+ *Alignment. Spacing rhythm. Colour discipline. Typography count. Motion vocabulary consistency.*
59
+
60
+ | Score | Rubric |
61
+ |---|---|
62
+ | 9–10 | Grid stance matches the chosen language (lean / break / breathe) deliberately throughout. Every inter-Brick gap comes from the declared spacing scale. Colours limited to the system tokens (typically ≤ 4). Typography limited (typically ≤ 2 families). Standby Transitions use a consistent easing and timing vocabulary. |
63
+ | 7–8 | Mostly clean; 1–2 alignment slips or one off-scale spacing. |
64
+ | 5–6 | Visible inconsistency — colours creeping past the token set, mixed Standby easings, asymmetric margins without intent, ad-hoc gap values. |
65
+ | 3–4 | Grid stance unclear; multiple type families; arbitrary motion timings; spacing drift. |
66
+ | 1–2 | Looks like a draft. |
67
+
68
+ **Audit moves:**
69
+ - **Grid stance match.** Off-grid placements should serve the declared language (Brutalist break, Sagmeister theatrical, Risograph hand-placed). Off-grid that drifted in accidentally — flag and snap. A Swiss Editorial Canvas with a Brick at `(3.5, 11.2)` is a tell.
70
+ - **Spacing-scale adherence.** Open the style declaration block. Read the declared spacing scale (e.g., `2 / 4 / 8 / 16 gu`). Pick ten inter-Brick gaps across the Canvas — every one must come from that set. Gaps of 7 / 9 / 11 / 13 across siblings = arithmetic drift, the agent picked values ad-hoc instead of from the scale. Snap to the nearest scale value or update the scale (and re-check everywhere).
71
+ - List every distinct colour used in the Canvas. > 4 = deduction (excluding intentional photography palette spreads).
72
+ - List every distinct type family. > 2 = deduction.
73
+ - List every distinct Standby easing / duration combination. > 3 = deduction.
74
+
75
+ ### 4. Functional fit to deployment
76
+
77
+ *Does the design solve the deployment's actual constraints?*
78
+
79
+ This dimension overlaps with the companion `bricks-ux` skill — interaction / accessibility / flow-state correctness is critiqued in depth there (`bricks-ux/references/ux-critique.md`). What stays here is the visual-design contribution to functional fit: does the visual system *enable* the interaction layer to work, or does it actively disable it.
80
+
81
+ | Score | Rubric |
82
+ |---|---|
83
+ | 9–10 | Type meets legibility floor for viewing distance. Pressable Bricks are visually distinct from decorative. Contrast survives deployment conditions (sunlight / dim lobby / glare). Brand and asset choices accommodate languages in scope. Orientation respected. |
84
+ | 7–8 | One visual choice marginal — type at the floor instead of comfortably above; one asset that doesn't survive a locale; affordance distinction subtle but present. |
85
+ | 5–6 | One visual choice actively disables interaction — pressable tiles indistinguishable from decoration, body type below legibility floor for the distance, palette that fails contrast under deployment light. |
86
+ | 3–4 | Multiple visual-functional conflicts. |
87
+ | 1–2 | Visual design ignores deployment constraints entirely. |
88
+
89
+ **Audit moves:**
90
+ - Walk the deployment-context block (from Priority #0). For each visible item — what the user must read, find, press, distinguish — point to the visual choice that supports it.
91
+ - Squint test at 25% zoom: primary content readable, pressable elements visually distinct, severity tiers (if monitor) distinguishable.
92
+ - For interaction / accessibility / flow-state critique beyond the visual contribution, cross to `bricks-ux/references/ux-critique.md`. The two passes run in parallel; both block ship.
93
+
94
+ ### 5. Originality within direction
95
+
96
+ *Is this the chosen design language done at 80% commitment, or 30%?*
97
+
98
+ | Score | Rubric |
99
+ |---|---|
100
+ | 9–10 | The signature moves of the chosen language are present and confident. The work would be recognized by a designer familiar with the language. There's at least one move that's specific to *this* brief, not just templated language application. |
101
+ | 7–8 | Direction is recognizable; mostly templated execution; one or two moves feel rote. |
102
+ | 5–6 | Recognizable as "the kind of thing that gets called Swiss Editorial / Kenya Hara / etc." but generically — could be any brand. |
103
+ | 3–4 | Cliché-mode application of the language; works that any agent might produce given the same prompt. |
104
+ | 1–2 | The language is unrecognizable in the work. |
105
+
106
+ **Audit moves:**
107
+ - For the chosen direction, list its top 3–5 signature moves (from `design-languages.md` or your own knowledge of the language). For each, check whether the work executes it.
108
+ - Where signature moves are absent, the direction has been softened toward generic. Restore them.
109
+ - Look for the inverse — moves that *aren't* in the language but the work has imported anyway (a Field.io-style gradient on a Swiss Editorial piece, a Risograph spot color on a Kenya Hara piece). These are the dilutions that drop scores.
110
+
111
+ ## Deployment-shape focus
112
+
113
+ Different deployments weight the dimensions differently:
114
+
115
+ | Deployment shape | Strongest weight | Weaker weight |
116
+ |---|---|---|
117
+ | Glanceable signage (single canvas) | Visual hierarchy · Originality | Functional fit (low complexity) |
118
+ | Multi-canvas kiosk (transact / interact) | Functional fit · Craft execution | Originality (don't get cute with money or identity) |
119
+ | Reactive dashboard (monitor) | Visual hierarchy · Functional fit | Originality (data is the work) |
120
+ | Hospitality / lifestyle (dwell) | Originality · System commitment | Functional fit (low input complexity) |
121
+ | Wayfinding | Visual hierarchy · Functional fit (legibility floor) | Originality (recognition over flair) |
122
+ | Presentation / introduction loop | Originality · Visual hierarchy | Functional fit (no input) |
123
+
124
+ When focus weights diverge sharply, surface the trade-off in the trade-off note. A wayfinding screen that scores 10 on hierarchy and 6 on originality is *correct*; a wayfinding screen that scores 9 on originality and 6 on hierarchy is *wrong*.
125
+
126
+ ## Anti-slop top-10 (BRICKS-specific)
127
+
128
+ Walk this list every time. Each is a pattern that consistently slips into agent-produced work and consistently degrades it.
129
+
130
+ ### 1. Generic gradient backgrounds on a Rect
131
+ **Tell:** purple → pink → blue full-bleed on the boot Canvas. **Why bad:** it is the literal AI-generated-page tell; reviewers identify the work as machine-made instantly. **Fix:** use a single-color ground from the system tokens, or a reference-anchored gradient that's specific to the brand (declared as a Data token, used deliberately).
132
+
133
+ ### 2. Decorative left-border-accent on every Rect
134
+ **Tell:** every card-shaped Rect carries a 4-grid-unit left border in the accent color. **Why bad:** it is the AI-dashboard-card signature; once seen it cannot be un-seen and it dates the work to the AI-tool era. **Fix:** distinguish cards via background contrast, weight, or composition; or commit to a different card vocabulary that matches the chosen language.
135
+
136
+ ### 3. Emoji decoration in RichText
137
+ **Tell:** ✅, ⚡, 🚀, ✨ next to feature bullets or in headlines. **Why bad:** unless the brand actually uses emoji in its voice (rare, deliberate), this is decoration-as-substitute-for-design. **Fix:** real icon library (Lucide / Phosphor / Heroicons via `Icon` brick), or no icon at all.
138
+
139
+ ### 4. Sketch / SVG-drawn imitations of real assets
140
+ **Tell:** a `Sketch` brick that approximates a logo, a CSS-shape product silhouette, a SVG hero illustration. **Why bad:** AI-drawn imagery reads as AI-drawn imagery. A labeled placeholder is more honest. **Fix:** acquire the real asset via the [Media Flow protocol](when-the-brief-is-branded.md), generate one anchored on real brand reference, or accept a labeled placeholder.
141
+
142
+ ### 5. Fabricated stats / fake user counts
143
+ **Tell:** "10,000+ happy customers", "99.9% uptime", "trusted by Fortune 500" appearing without a source. **Why bad:** invented social proof is dishonest and reviewers usually catch it. **Fix:** request real numbers from the user or use a labeled placeholder ("[insert real metric]").
144
+
145
+ ### 6. Default sans system fonts when the brand has its own
146
+ **Tell:** Inter / Roboto / Helvetica / system-ui shipped despite the brand having a documented type stack. **Why bad:** it leaks "I didn't bother sourcing the brand font" across the entire surface area of the design. **Fix:** declare the brand fonts as `ApplicationFont` entries with the licensed files in Media Flow.
147
+
148
+ ### 7. Naive dark-mode by inverting Data values
149
+ **Tell:** the dark theme is "white background → black, black text → white" with no other adjustments. **Why bad:** a real dark theme rebalances saturation, contrast, accent intensity, and shadow. Inversion produces a theme that looks broken. **Fix:** if the brief wants dark mode, design it as a deliberate second theme — re-author the token Data, don't just toggle.
150
+
151
+ ### 8. Animation `loop` on every visible element
152
+ **Tell:** every brick on every canvas has a `runType: 'loop'` Animation attached. **Why bad:** continuous motion everywhere is visual noise that burns frame budget and dulls genuine attention-draws. **Fix:** reserve `loop` for true attention-draws (alarm pulse, recording dot, hero motion in Field.io); use Standby Transitions and shared-Brick auto-tween for everything else.
153
+
154
+ ### 9. Hover-state treatments imported to no-touch hardware
155
+ **Tell:** a brick's `pressable: 'enabled'` carries a press scale-down animation, but the deployment is a 75" no-touch signage panel. **Why bad:** the affordance promises something the hardware cannot deliver; the design reads as "ported from web." **Fix:** drop hover on no-touch; convert to a Switch driven by a non-pointer signal (sensor, timer, peripheral Generator) if the visual intent matters.
156
+
157
+ ### 10. AI-generated brand imagery without a real brand-reference anchor
158
+ **Tell:** a generated "brand-appropriate" hero image that nobody at the brand has ever seen, produced from a prompt like "modern tech product on a gradient." **Why bad:** generation without anchoring produces uncanny-valley assets that feel adjacent to the brand without being the brand. **Fix:** anchor every generation on at least one verified brand asset (logo, real photo, official color sample); apply 5-10-2-8; log generation metadata in `brand-spec.md`. (See [Media Flow protocol § Creating assets when missing](when-the-brief-is-branded.md#creating-assets-when-missing).)
159
+
160
+ ## Bonus failure modes (BRICKS-specific, less common)
161
+
162
+ - **Hardcoded English in a Subspace bound for multilingual deployment.** Every visible string should be a Data value, even when only one language is populated at first.
163
+ - **`persistData: true` on transient flow Data.** Resumes a half-complete flow after a watchdog reset and confuses the next user.
164
+ - **DataCalculation chains masquerading as orchestration.** See [`avoiding-complexity.md`](avoiding-complexity.md) — calc → calc → calc is the wrong primitive.
165
+ - **Subspace-as-tidiness.** A Subspace with a single instance and a leaky Props contract is a directory, not a module. See `architecture-truths.md` Truth #8.
166
+ - **Snap canvas transitions on routine navigation.** Reserved for emphasis only.
167
+ - **Inline brand binaries** (logo as base64 in a Brick prop, hero image embedded). Pollutes the Subspace and defeats Media Flow's offline + refresh model.
168
+ - **Pseudo-chrome contamination — page counters, progress bars, chapter numbers drawn into Canvas content.** A "Slide 3/12" Text Brick inside the design competes with the runtime's own transition affordances and reads as duplicated chrome. If the audience genuinely needs to know where they are, render it via a shared chrome Brick (so it auto-tweens with the rest of the chrome) — or drop it entirely. See [`presentation-and-slideshow.md`](presentation-and-slideshow.md).
169
+ - **Density-rhythm collapse — three or more consecutive Canvases at the same layout archetype.** Three "headline + bullet list" Canvases in a row reads as a single Canvas that didn't change. Alternate density across the sequence (full-bleed / two-column / pull-quote / data-figure / breather — see the rotation table in `presentation-and-slideshow.md`).
170
+ - **In-Canvas variation pickers — palette swatches, theme toggles, "choose your style" buttons left in production.** Same category as pseudo-chrome. The variation comparison surface is chat + source tree, not the Canvas. See [`variations-and-tweaks.md`](variations-and-tweaks.md).
171
+ - **Full-set unmount + remount per Canvas change.** Every Brick is Canvas-local; no shared ids; every transition is a hard cut even with Standby Transitions configured. This is what makes a sequence read as "narrated PowerPoint" instead of a designed flow. Pick 1–2 hero Bricks and share their ids across Canvases — see Truth #3.
172
+
173
+ ## First-viewer reaction rubric (for sequenced / narrative work)
174
+
175
+ For presentations, slideshows, intro decks, explainers — anything sequenced. Predict (or directly ask) the first reaction. The rubric is a separate axis from the 5 dimensions and only applies when the work is a sequence ≥ 3 Canvases.
176
+
177
+ - *"This is narrated PowerPoint."* — Redesign. Hero architecture missing or broken. Likely full-set unmount per Canvas change. Back to Pass 1.
178
+ - *"Things were just moving."* — Motion is present but hierarchy isn't. Heroes exist but compete with auxiliaries. Quiet down everything except the hero.
179
+ - *"I wanted to keep watching."* — Baseline good. Pacing works, hero continuity reads. Polish from here.
180
+ - *"I wanted to screenshot that frame."* — Memorable keyframe achieved. At least one Canvas is doing more than its job.
181
+
182
+ Aim for the third reaction overall and the fourth on at least one Canvas in any sequence of ≥ 5 Canvases. Anything ≤ first is a structural failure, not a polish issue.
183
+
184
+ ## Definition of "done" with critique applied
185
+
186
+ A design is done when:
187
+
188
+ 1. The Verification gate (compile + every-Canvas screenshot + screenshots reviewed) passes.
189
+ 2. Every Canvas scores ≥ 8 on every one of the five dimensions, or trade-offs are explicitly accepted with rationale.
190
+ 3. The anti-slop top-10 + bonus-failure-modes walk produces zero unaddressed matches.
191
+ 4. For sequenced / narrative work, the first-viewer rubric predicts ≥ "I wanted to keep watching."
192
+ 5. Reference comparisons (where applicable) have a written delta report.
193
+ 6. The trade-off note that ships alongside variations captures every accepted < 8.
194
+
195
+ If any item is unmet, the work is mid-iteration. Say so explicitly to the user; offer a precise list of what remains.
@@ -0,0 +1,265 @@
1
+ # Design Languages
2
+
3
+ A curated library of visual languages, each with concrete BRICKS-native execution notes. The library exists because *committing to a system* is what separates polished work from generic output — and an agent without anchors averages toward generic. These anchors give you something specific to commit to.
4
+
5
+ The library does not constrain you. Pick one, blend two, or invent a new one rooted in the same discipline. What it prevents is the no-commitment middle.
6
+
7
+ ## Two orthogonal axes
8
+
9
+ A picked direction is the combination of two independent choices:
10
+
11
+ - **Interaction archetype** — *what the user does* in front of the screen (glance / browse / interact / transact / monitor / dwell). Drives the Subspace structure: Canvas count, state-machine shape, dominant Bricks. See [`when-the-brief-is-vague.md`](when-the-brief-is-vague.md).
12
+ - **Visual language** — *what the design says*. Drives expression: type, color logic, motion vocabulary, signature moves, asset emphasis. This file.
13
+
14
+ A "browse + Kenya Hara emptiness" Subspace is profoundly different from a "browse + Brutalist web" Subspace, even though the user does the same thing. Advisor mode picks 3 candidates spanning both axes.
15
+
16
+ ## The commitment principle — fight your averaging instinct
17
+
18
+ When unsure, do *more* of what defines the chosen language, not less. A style executed at 30% reads as hesitant; at 80% it reads as deliberate.
19
+
20
+ - Swiss Editorial without numbered folios, hairline rules, and oversized headlines is just "generic minimal."
21
+ - Kenya Hara without 70%+ negative space is just "a bit sparse."
22
+ - Brutalist web with rounded corners and gradient accents is just "an unfinished page."
23
+
24
+ If you find yourself softening signature moves to "make it more accessible" — stop. The signature moves are the language. Soften them and you've abandoned the language for no destination.
25
+
26
+ ## How to use the library in Advisor mode
27
+
28
+ 1. **Pick 3 directions from different schools.** Not three minimalist variants. Spread across the schools below so the user sees a real choice.
29
+ 2. **For each direction, give:**
30
+ - One-sentence pitch.
31
+ - A flagship the user is likely to recognize (designer / firm / brand / institution).
32
+ - 3 vibe keywords.
33
+ - The interaction archetypes it fits.
34
+ - One sentence on what it would mean concretely for this brief.
35
+ 3. **Build a 3-cell preview** — three minimal Subspaces (one Canvas each) the user can render. Don't produce finished work; the preview is a chooser.
36
+ 4. **Once the user picks, drop out of Advisor mode** and continue the workflow rooted in that direction.
37
+
38
+ ## Style declaration ritual
39
+
40
+ After the direction is picked, write the committed system as a comment block at the top of the Subspace file. Every subsequent choice should cite this block. Adding a value not in the block requires updating the block first — that's what makes the system structural rather than aspirational.
41
+
42
+ ```ts
43
+ /**
44
+ * System: Swiss Editorial (Pentagram lineage)
45
+ * Archetype: glance
46
+ * Type: <Brand Sans> 4 / 8 / 16 gu · single family · weight contrast
47
+ * Color: ink #1A1A1A on cream #F5F0E6 · accent #FF3C00 (callouts only)
48
+ * Spacing: 2 / 4 / 8 / 16 gu (use only these for inter-Brick gaps)
49
+ * Grid stance: lean (strict alignment, generous margins 4–8 gu)
50
+ * Motion: ease-out 280ms entrance · ease-in 180ms exit · no loops
51
+ * Heroes: logo (id `brand-logo`) · folio (id `folio-num`)
52
+ * Asset emphasis: logo + 1 hero photograph per canvas · no decorative imagery
53
+ */
54
+ ```
55
+
56
+ The grid itself is given by the runtime (Truth #6). What the block commits to is the set of design decisions on top of the grid: type scale, palette, **spacing scale in grid units** (small enumeration so inter-Brick gaps stay consistent across many siblings), grid stance, motion vocabulary, and hero Brick ids. The comment is not for the runtime; it is for *you*, when you next look at the file and consider adding a third colour or a fourth gap value. The block's existence is what holds the line.
57
+
58
+ ---
59
+
60
+ ## School 1 · Structural modernism
61
+
62
+ ### 1. Swiss Editorial (Pentagram / Vignelli lineage)
63
+
64
+ - **Pitch:** Precision, authority, editorial gravity. Type, grid, hairline rule, restraint.
65
+ - **Flagships:** Pentagram, Vignelli's Unimark, MIT Press canon.
66
+ - **Keywords:** structural · monochrome · grid-disciplined · quiet.
67
+ - **Fits:** glance / browse / monitor.
68
+ - **BRICKS execution:**
69
+ - Bricks: large RichText for headlines, smaller Text for body, hairline `Rect` rules (1–2 grid units tall), numbered RichText folios in a corner, `Image` bricks at controlled scale.
70
+ - Heroes: brand wordmark or logo, numbered folio, masthead hairline rule — same id across Canvases.
71
+ - Theme tokens (Data): two grounds (cream + ink), one accent reserved for callouts; single sans family declared as `ApplicationFont`.
72
+ - Spacing scale: `2 / 4 / 8 / 16 gu`. Grid stance: **lean** (strict alignment, generous 4–8 gu margins, body columns at typeset widths).
73
+ - Density rhythm: dense type Canvases broken by wide-margin breathers every 3–4 Canvases.
74
+ - Motion: subtle vertical Standby on entrance (`ease-out` 280ms); shared headers across canvases via same-id Bricks; no `loop` animations.
75
+ - Asset emphasis: real photograph or none; never decorative imagery; logo at restrained scale.
76
+ - **Wrong for:** hospitality warmth, retail playfulness, ambient dwell loops.
77
+
78
+ ### 2. Bauhaus geometric (Müller-Brockmann / Karel Martens lineage)
79
+
80
+ - **Pitch:** Primary, architectural, confident. Geometry as the composition itself, not decoration.
81
+ - **Flagships:** Müller-Brockmann's Zurich Tonhalle posters, Paula Scher's Public Theater identity.
82
+ - **Keywords:** geometric · primary-color · flat · rhythmic.
83
+ - **Fits:** glance / dwell / monitor.
84
+ - **BRICKS execution:**
85
+ - Bricks: oversized `Rect` bricks as primary anchors (circles via `borderRadius`, squares, diagonals via `rotate`), `Text` bricks rotated 90° as composition elements, no photographic imagery.
86
+ - Heroes: one or two large geometric anchors (circle, square, diagonal bar) that re-position and re-scale across Canvases via shared id — the geometry is *the* narrative.
87
+ - Theme tokens: primary RGB or fluorescent accents (`#FF3C00`, `#0019FF`, `#F5E100`) on flat black or white; tri-color palette fixed in Data.
88
+ - Spacing scale: `1 / 3 / 6 / 12 gu`. Grid stance: **lean** (geometric anchors snapped hard to grid).
89
+ - Density rhythm: high-energy geometric Canvases alternating with declarative single-shape pause Canvases.
90
+ - Motion: bold sweep entrances (400–500ms), shared-Brick auto-tween of geometric anchors across canvases.
91
+ - Asset emphasis: logo, geometric forms, type-as-image; no scene photography.
92
+ - **Wrong for:** corporate finance, hospitality, hi-fi product UI.
93
+
94
+ ---
95
+
96
+ ## School 2 · Quiet minimalism
97
+
98
+ ### 3. Kenya Hara emptiness (MUJI / Shiseido editorial lineage)
99
+
100
+ - **Pitch:** Quiet, meditative, reverent, deliberately un-full.
101
+ - **Flagships:** MUJI art direction, Shiseido editorial, Hara's own book design.
102
+ - **Keywords:** generous-whitespace · monochrome · patient · reduced.
103
+ - **Fits:** dwell / glance.
104
+ - **BRICKS execution:**
105
+ - Bricks: a single hero `Image` (real photo, never redrawn), one small `RichText` caption, lots of empty Canvas; `Slideshow` rotation slow (12–24s per item).
106
+ - Heroes: the single hero `Image` shifts subtly in scale/position across Canvases (same id) — the photograph is the constant; everything else is breath.
107
+ - Theme tokens: warm-white ground (`#F8F4ED` or similar), single warm-charcoal ink (never pure black), no accent color.
108
+ - Spacing scale: `8 / 24 / 48 gu`. Grid stance: **breathe** (the grid is there but mostly unused; content islands placed with precision, 70–80% empty).
109
+ - Density rhythm: every Canvas is low-density. Variation is in framing (top-third / bottom-third / centered isolate), not density jumps.
110
+ - Motion: barely perceptible Standby (300–500ms delay, slow opacity easing); no `loop` animations.
111
+ - Asset emphasis: photography is the work — Media Flow asset must score 9–10 on the 5-10-2-8 craft dimension; one image carries the canvas.
112
+ - **Wrong for:** information-dense kiosks, transactional flows, dashboards.
113
+
114
+ ### 4. Dieter Rams industrial (Braun / Vitsœ / pre-2010 Apple)
115
+
116
+ - **Pitch:** Useful, honest, restrained, quietly confident.
117
+ - **Flagships:** Braun catalogs, pre-2010 Apple, Vitsœ.
118
+ - **Keywords:** functional · tactile · unobtrusive · long-lasting.
119
+ - **Fits:** glance / browse / monitor.
120
+ - **BRICKS execution:**
121
+ - Bricks: product `Image` as hero, sparse `RichText` specification blocks, hairline `Rect` grids separating spec columns.
122
+ - Heroes: the product photograph itself — re-framed and re-scaled across Canvases via shared id; spec callouts are auxiliary.
123
+ - Theme tokens: monochrome grey scale + one functional accent (used only where it means something — warning, primary action).
124
+ - Spacing scale: `2 / 4 / 8 gu`. Grid stance: **lean** (tight, even, predictable; nothing breaks rank).
125
+ - Density rhythm: even and measured across Canvases — no dramatic density jumps; pacing comes from Brick weight not layout shifts.
126
+ - Motion: minimal — Standby with linear easing, no spring, no `loop`.
127
+ - Asset emphasis: hero product photography first-class; spec icons as restrained line drawings.
128
+ - **Wrong for:** consumer entertainment, maximalist branding, hospitality warmth.
129
+
130
+ ---
131
+
132
+ ## School 3 · Editorial and narrative
133
+
134
+ ### 5. Magazine editorial (NY Magazine / Bloomberg Businessweek lineage)
135
+
136
+ - **Pitch:** Opinionated, layered, alive. Real editorial hierarchy.
137
+ - **Flagships:** New York Magazine, Bloomberg Businessweek, The California Sunday Magazine.
138
+ - **Keywords:** layered · photographic · type-driven · maximalist-typography.
139
+ - **Fits:** dwell / browse.
140
+ - **BRICKS execution:**
141
+ - Bricks: oversized `RichText` display headlines (a strong serif), second sans family for body, `Image` bricks anchored to text columns, pull-quote `Text` bricks at 2× body scale, color-blocked `Rect` sidebars.
142
+ - Heroes: masthead chrome (publication name + date), pull-quote container, hero photograph — all reposition across Canvases via shared id, giving the layered flip-through feel.
143
+ - Theme tokens: photograph-driven palette, accent values pulled from the hero images themselves and bound as Data; rich supporting neutrals.
144
+ - Spacing scale: `1 / 2 / 4 / 8 / 16 gu` (wider scale for editorial-style overlap and pull-quote breaks).
145
+ - Grid stance: **lean** with deliberate overlaps — content sits on the grid but layers cross gutter lines.
146
+ - Density rhythm: full-bleed portrait → text-heavy spread → pull-quote → image grid → breather — rotate hard, this language *needs* density variation.
147
+ - Motion: rich Standby with stagger (50–100ms increments per Brick); shared chrome animates across canvases.
148
+ - Asset emphasis: editorial-quality photography (full-bleed, scene, portrait); custom display serif as `ApplicationFont`.
149
+ - **Wrong for:** short-attention-span interfaces, transactional kiosks, dashboards.
150
+
151
+ ### 6. Risograph zine (indie print lineage)
152
+
153
+ - **Pitch:** Handmade, immediate, low-fidelity on purpose, warm.
154
+ - **Flagships:** Independent zines, Rough Trade posters, skate-culture print design.
155
+ - **Keywords:** risograph · two-color · textured · hand-placed.
156
+ - **Fits:** dwell / browse.
157
+ - **BRICKS execution:**
158
+ - Bricks: 2–3 spot-color `Rect` grounds, slightly off-grid `Image` bricks (deliberate), `Text` in a distinctive display, halftone overlays as low-opacity `Image` bricks (texture asset in Media Flow).
159
+ - Heroes: a distinctive display-type wordmark or a halftone-textured shape that re-stamps in different positions across Canvases — the hero feels stamped, not placed.
160
+ - Theme tokens: risograph palette (flo-pink, teal, navy, mustard) — saturated, slightly imperfect overprints.
161
+ - Spacing scale: deliberately irregular — `1 / 5 / 13 gu` (hand-placed feel; consistent within scale but not evenly stepped).
162
+ - Grid stance: **break** (Bricks deliberately off-grid by 1–2 units, slight rotations, content kissing edges).
163
+ - Density rhythm: chunky-and-busy alternating with stark single-image Canvases — the zine flip-through feel.
164
+ - Motion: hand-placed feel via tiny rotations on Standby (`rotate: 1–2deg` baseline); avoid the runtime's polished auto-tween for primary entries — use `ease-linear` or even snap on Standby for some elements.
165
+ - Asset emphasis: spot-color illustration, halftone texture, distinctive display type.
166
+ - **Wrong for:** enterprise, premium, anything trust-seeking.
167
+
168
+ ---
169
+
170
+ ## School 4 · Motion and the digital-native
171
+
172
+ ### 7. Field.io motion poetics
173
+
174
+ - **Pitch:** Alive, computational, mesmerizing. Motion is the medium.
175
+ - **Flagships:** Field.io, Active Theory, Universal Everything.
176
+ - **Keywords:** generative · motion-first · particle · light-as-material.
177
+ - **Fits:** dwell / monitor (high-end).
178
+ - **BRICKS execution:**
179
+ - Bricks: dominant `Video` / `VideoStreaming` / `Lottie` / `Rive` / `GenerativeMedia` full-bleed; `RichText` overlays at delicate sizes with semi-transparent backgrounds.
180
+ - Heroes: the brand reel / generative motion piece itself, full-bleed and persistent across Canvases — only the overlaid type changes; the motion is the throughline.
181
+ - Theme tokens: dark indigo to electric gradient ground, or pure monochrome with one light-based accent.
182
+ - Spacing scale: `2 / 8 / 24 gu` (delicate gaps for overlay type, large gaps for breathing room around full-bleed motion).
183
+ - Grid stance: **breathe** — motion is full-bleed; UI sits on the grid but quietly.
184
+ - Density rhythm: every Canvas is low-density overlay on full-bleed motion; variation is in *what the motion is doing* this Canvas, not in layout density.
185
+ - Motion: slow continuous motion via `Animation` `runType: 'loop'` — used sparingly, only on the hero. Cross-canvas transitions use shared-Brick auto-tween of full-bleed elements.
186
+ - Asset emphasis: brand reel video and animated logo Lottie/Rive are first-class — preloaded via Media Flow, hash-verified, offline-safe; the canvas is *driven* by these assets.
187
+ - **Wrong for:** content-heavy displays, purchase funnels, anything requiring careful reading.
188
+
189
+ ### 8. Brutalist web (Are.na / terminal lineage)
190
+
191
+ - **Pitch:** Raw, direct, anti-polish, confident.
192
+ - **Flagships:** Are.na, Bloomberg Terminal, deliberate "unstyled" indie sites.
193
+ - **Keywords:** unstyled · monospace · text-dense · system-typography.
194
+ - **Fits:** browse / monitor.
195
+ - **BRICKS execution:**
196
+ - Bricks: system-font `Text` and `RichText` only (or IBM Plex Mono / Times New Roman as `ApplicationFont`); dense `Items` lists with templated rows; hairline `Rect` borders only; no decorative imagery.
197
+ - Heroes: a single persistent navigation bar or "you are here" address-style label, same id across Canvases.
198
+ - Theme tokens: black on white, occasional single saturated accent, almost no gradients/shadows/rounded corners.
199
+ - Spacing scale: `1 / 2 / 4 gu` (tight, monospaced character cell rhythm).
200
+ - Grid stance: **lean** but ascetic — grid used as a literal table, no decorative breathing.
201
+ - Density rhythm: uniformly dense — variation is in content depth, not visual density. This language earns its weight by *refusing* the density-rotation principle.
202
+ - Motion: snap-cuts allowed and even welcome — but only as deliberate emphasis. Most transitions are shared-Brick auto-tween of typographic chrome.
203
+ - Asset emphasis: type. That's it.
204
+ - **Wrong for:** consumer retail, emotional storytelling, hospitality.
205
+
206
+ ---
207
+
208
+ ## School 5 · Expressive and experimental
209
+
210
+ ### 9. Sagmeister / experimental
211
+
212
+ - **Pitch:** Provocative, hand-made, emotional, attention-grabbing. The concept drives every choice.
213
+ - **Flagships:** Stefan Sagmeister, Paula Scher in expressive mode, Stefan Walz.
214
+ - **Keywords:** expressive · hand-craft · concept-driven · theatrical.
215
+ - **Fits:** dwell / glance (cultural / event contexts).
216
+ - **BRICKS execution:**
217
+ - Bricks: anything goes, but every choice serves the concept — `Sketch` for hand-drawn elements, sourced `Image` for hand-crafted typography photographs, `Text` bricks at extreme scale shifts via `rotate` and large grid frames.
218
+ - Heroes: the conceptual centerpiece (a hand-crafted word, a built-physical-object photograph) re-staged dramatically across Canvases — different angle, different scale, different distance — same id.
219
+ - Theme tokens: saturated, often clashing pairs used deliberately. No fear of "bad taste."
220
+ - Spacing scale: deliberately broken — `0 / 7 / 23 gu` (the irregularity is the point; siblings still share the same set so it doesn't read as drift).
221
+ - Grid stance: **break** — the grid is a foil to push against, not a rule.
222
+ - Density rhythm: extreme oscillation between maximalist Canvases and empty-pause Canvases.
223
+ - Motion: theatrical — long durations (600–1000ms), dramatic easing (`easeInOutBack`, `easeInOutElastic`), deliberate "broken" timings.
224
+ - Asset emphasis: hand-craft photography, custom or modified type, conceptual imagery.
225
+ - **Wrong for:** ongoing systems, B2B utility, any context demanding restraint.
226
+
227
+ ### 10. Y2K / futurist-retro
228
+
229
+ - **Pitch:** Optimistic, technological, nostalgic-for-futures-past.
230
+ - **Flagships:** Early-2000s tech branding, contemporary nostalgia revivals in fashion and music.
231
+ - **Keywords:** chrome · bubble · glossy · iridescent.
232
+ - **Fits:** dwell / interact (gaming / music / Gen Z contexts).
233
+ - **BRICKS execution:**
234
+ - Bricks: chrome-treatment `Image` bricks (sourced or brand-anchored generated); pixel/bitmap font as `ApplicationFont` (Departure Mono, VT323) for HUD overlays; scan-line overlay `Rect` bricks at low opacity.
235
+ - Heroes: HUD frame chrome (scan-line overlay, corner brackets, status readout strip) — persistent across Canvases via shared id, the chrome *is* the throughline; content swaps inside the HUD.
236
+ - Theme tokens: chrome / iridescence, acid green, electric blue, hot pink. Heavy gradients but in a meant-to-be-retro way (declared as Data tokens, never default web gradients).
237
+ - Spacing scale: `2 / 6 / 12 gu` (HUD-style regular intervals).
238
+ - Grid stance: **lean** — HUDs are precise; the chrome stays orthogonal even when content goes psychedelic.
239
+ - Density rhythm: HUD frame is constant; inner content alternates between data-readout dense and hero-render isolate.
240
+ - Motion: HUD-style entrances, cursor / scanner animations via `Animation`, pseudo-CRT glow via `Rect` shadow tokens.
241
+ - Asset emphasis: chrome 3D renders, retro-tech imagery, bubble lettering.
242
+ - **Wrong for:** trust-seeking finance, healthcare, enterprise.
243
+
244
+ ---
245
+
246
+ ## Combining language with archetype
247
+
248
+ The picked language constrains *expression*. The picked archetype constrains *structure*. They multiply, but with constraints:
249
+
250
+ | Archetype | Naturally fits | Resistant to |
251
+ |---|---|---|
252
+ | Glance | Swiss Editorial · Bauhaus · Kenya Hara · Brutalist web | Field.io (motion competes with glance) · Sagmeister (concept needs dwell) |
253
+ | Browse | Magazine editorial · Risograph · Brutalist web · Dieter Rams | Field.io · Y2K (too much motion noise) |
254
+ | Interact | Dieter Rams · Swiss Editorial · Brutalist web · Y2K (gaming) | Kenya Hara (precious quiet doesn't survive a tap) · Sagmeister (instability discourages decision) |
255
+ | Transact | Dieter Rams · Swiss Editorial | Field.io · Sagmeister · Y2K · Risograph (trust deficit) |
256
+ | Monitor | Swiss Editorial · Bauhaus · Brutalist web · Dieter Rams | Magazine editorial · Sagmeister (decoration distracts from data) |
257
+ | Dwell | Field.io · Magazine editorial · Kenya Hara · Sagmeister · Y2K | (any of the above can dwell; least natural is Brutalist web) |
258
+
259
+ When the user picks an awkward combination ("transact + Sagmeister"), surface the tension explicitly. Either talk them into the natural pairing, or commit hard to the awkward one as a deliberate brand statement — but don't middle-ground it into mush.
260
+
261
+ ## Adapting and inventing
262
+
263
+ The 10 directions are anchors. Real work often blends — "Kenya Hara emptiness with one Risograph spot-color accent for the call-to-action" is a legitimate combination if executed deliberately. What's not legitimate is blending three to dilute commitment.
264
+
265
+ When inventing a direction not in the library: write its system declaration block as if it were one of the entries above (pitch / flagship / keywords / fits / BRICKS execution / wrong-for). If you can't, the direction isn't real yet — keep working on it before committing.
@@ -0,0 +1,116 @@
1
+ # Performance
2
+
3
+ Second-order rules that keep a BRICKS Application fast on the actual hardware it deploys to (typically lower-spec than the developer's laptop) and resilient across watchdog reboots and offline windows.
4
+
5
+ ## Throttle at the Generator boundary
6
+
7
+ A high-frequency source (sensor publishing at 100 Hz, MQTT firehose, LLM token stream) written directly to Data will fire `update` / `valueChange` events on every write. Every bound Brick re-renders. Every dependent DataCalc re-runs. The canvas chokes.
8
+
9
+ **Throttle / aggregate inside the Generator**, not after.
10
+
11
+ - For sensor / MQTT: cap the published rate in the Generator (sample to 1–10 Hz, or only emit on Δ).
12
+ - For LLM streaming: write progressive deltas, but emit a `complete` event at the end and let downstream chains key off completion.
13
+ - For HTTP polling: respect a backoff; don't re-emit identical payloads.
14
+
15
+ If the source is upstream of you (a Generator template you can't modify), insert a buffering DataCalc that publishes to a downstream Data on a rate-limited schedule.
16
+
17
+ ## Bound Data history explicitly
18
+
19
+ Data is not a time-series store. If a design needs "the last N values" (a chart series, recent log lines, a conversation history), keep an explicitly bounded array.
20
+
21
+ - Use an `Iterator` Generator or a DataCalc that pushes new values and trims the head when length exceeds the cap.
22
+ - Pick the cap to fit the *visible* need, not "for safety" — 60 points for a 60-second chart, not 10 000.
23
+ - Unbounded arrays are a slow memory leak that watchdog will eventually paper over by killing the Application — and the user will see a reset they don't understand.
24
+
25
+ For longer-term history, push to a backend (Remote Data Bank, GraphQL, HTTP) via a separate Generator and treat the Data side as a recent-window cache.
26
+
27
+ ## `persistData: true` is for survival, not state
28
+
29
+ `Data.persistData: true` causes the Data value to be persisted across launcher restarts. This is the right knob for:
30
+
31
+ - Last-known-good content (the most recent fetched menu, the last cached weather payload).
32
+ - Idempotency keys generated at flow start.
33
+ - Locale preference and other long-lived configuration.
34
+
35
+ It is the *wrong* knob for transient flow state. A half-completed kiosk flow that survives a watchdog reset stuck in the middle is worse than a clean reset to Welcome. Default Path: keep flow Data ephemeral; reset on boot Canvas enter.
36
+
37
+ ## Boot Canvas must render in < 1 second using only cached/persisted Data
38
+
39
+ The boot Canvas is what the user sees on cold start, after a watchdog reset, after every fleet-managed reboot. It must:
40
+
41
+ - Render *something* immediately, with no Generator success required.
42
+ - Read from cached / persisted Data only — no synchronous network dependencies.
43
+ - Provide a self-recovery path (Cancel / Restart accessible from any deeper Canvas) so users stuck in a half-completed Subspace can always return.
44
+ - Reset all transient flow Data and Subspace state on entry.
45
+
46
+ **Failure mode:** boot Canvas waits for an HTTP fetch to render its content; user sees a blank screen on offline cold boot.
47
+
48
+ ## `renderOutOfViewport: false` for legitimate off-grid Bricks
49
+
50
+ By default the runtime auto-culls Bricks fully outside the grid. For Bricks that intentionally sit partly off-grid (overflow effects, anchored at origin) the in-viewport portion still renders.
51
+
52
+ If you have a Brick that is *entirely* off-grid for design reasons (a parked element that animates in via Switch / DynamicAnimation), set `renderOutOfViewport: false` to make the cull explicit and reduce per-frame cost on canvases with many such elements.
53
+
54
+ For Bricks that are off-grid only momentarily during a transition, leave the default — culling mid-tween causes flicker.
55
+
56
+ ## Brick count discipline
57
+
58
+ Every Brick on a Canvas costs render budget; off-screen-but-on-Canvas Bricks still cost something. Lists of 100 small text Bricks for a daily schedule will outrun a low-spec signage panel.
59
+
60
+ - Prefer **Items** Brick (virtualized) over hand-laid lists of repeating Bricks.
61
+ - Prefer **fewer-bigger** decorative Bricks over **many-tiny** ones for purely visual texture.
62
+ - Composite tiles often work better as a single Slideshow / Items frame than as N hand-positioned Brick groups per Canvas.
63
+
64
+ ## Offline-first wrap on every networked Generator
65
+
66
+ The standard wrap for any Generator that touches the network:
67
+
68
+ 1. **Cache layer** — read from local cache (DataBank, File Generator, persisted Data) before / instead of hitting network.
69
+ 2. **Fetch layer** — when network is up, fetch and update cache; emit `data updated` event.
70
+ 3. **Queue layer** — for writes (form submissions, payments), queue locally on offline; flush on reconnect with idempotency keys.
71
+ 4. **Status layer** — expose `network.online` and `data.lastSyncedAt` Data values for the UI to surface.
72
+
73
+ Default canvases read from the cache. Live fetches happen out-of-band; their results land in cache and trigger re-render via Data events.
74
+
75
+ **Failure mode:** a Generator that fetches synchronously on Canvas enter and renders blank on failure. Every networked Generator without this wrap is an outage waiting to ship.
76
+
77
+ ## Media in Media Flow is local-first — image/video/Lottie/Rive does NOT break offline
78
+
79
+ A common misread of "offline-first" is that media-rich designs (lots of images, video loops, Lottie / Rive animations, brand reels) are dangerous for offline deployments. **They are not.** Media bound through Media Flow is **preloaded** to the device at boot (or background-synced when Media Flow content updates) and served from local storage thereafter. Once cached, the media is available with no network at all — that is the whole point of Media Flow.
80
+
81
+ The mechanism:
82
+
83
+ - Each Media Flow asset is referenced from the Subspace by a Data of `kind: { type: 'media-resource-image' | 'media-resource-video' | 'lottie-file-uri' | 'rive-file-uri' | ... }` with a `preload: { type: 'url', hashType, hash }` block.
84
+ - The runtime's preload pass downloads every media asset referenced by the Application before letting the boot Canvas activate (or during a controlled progress state), and verifies integrity via the hash.
85
+ - Subsequent renders read from the local cache; the original URL is no longer needed.
86
+ - Cache survives watchdog restarts and reboots; `Application.runtimeCacheOptions` controls the policy.
87
+
88
+ Implications for design:
89
+
90
+ - **You can build heavy, image-rich, motion-heavy, video-driven Applications for fully-offline kiosks and signage.** The deployment doesn't lose anything by being offline; it loses something only if media isn't bound through Media Flow.
91
+ - **Brick templates that consume Media Flow assets — Image, Video, Slideshow, Lottie, Rive, GenerativeMedia source bricks — are offline-safe by default**, as long as their `source` (or equivalent) binds to a Media Flow Data with `preload` metadata, not to an arbitrary external URL referenced inline.
92
+ - **The offline-first wrap above is for Generators producing dynamic / runtime data** — current menu, train times, sensor readings, LLM responses, server-fed inventory. Not for design-time media. Don't conflate the two.
93
+ - **Do not** drop image / video / motion bricks "to be safe for offline". The result is generic, text-only design that loses the brand and the polish for no real gain.
94
+
95
+ The two failure modes to actually worry about:
96
+
97
+ 1. **Inline URLs that bypass Media Flow.** A Brick prop set to a literal `https://...` image URL is fetched at render time; offline = blank. Bind via Media Flow Data, not inline strings. (Truth #2 + the asset protocol enforce this structurally.)
98
+ 2. **Generators that fetch *content* synchronously**, even when the bricks displaying that content are bound through Media Flow. The content fetch is what fails, not the rendering. Wrap those Generators per the section above.
99
+
100
+ When unsure: ask "is this binary baked into the Application via Media Flow, or fetched at runtime from a server?" The first is offline-safe automatically; the second needs the wrap.
101
+
102
+ ## DataCalc trigger discipline
103
+
104
+ `triggerMode: 'auto'` reruns the calc on every input change. With multiple inputs and multiple downstream consumers, an `auto` calc can fire dozens of times per logical update.
105
+
106
+ - Use `auto` only when the calc is cheap and the consumers genuinely want every result.
107
+ - For expensive calcs (collection reductions, large object transforms), use `manual` and trigger explicitly via `PROPERTY_BANK_COMMAND` from the relevant event chain.
108
+ - Watch for circular dependencies: A's output is B's input is A's input. Auto mode will spin.
109
+
110
+ ## Animation budget
111
+
112
+ Standby Transitions are nearly free. Continuous `loop` animations are not.
113
+
114
+ - Reserve `runType: 'loop'` for genuine attention-draws: alarm pulse, recording-active indicator, "scan in progress" hint.
115
+ - A Canvas with 5+ looping animations on idle bricks burns frame budget for no design payoff.
116
+ - One orchestrated canvas-enter (staggered standby reveals) creates more delight than six scattered loops.