stillmade-sdk 0.1.12 → 0.1.14

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/AGENTS.md CHANGED
@@ -6,7 +6,7 @@ This folder is the StillMade Block SDK. Read this file before writing code; it i
6
6
 
7
7
  Do not tell the user a Block is ready, done or working until `node packages/block-cli/cli.js gate .` passes after your last edit, and report the exact status it prints. In this folder Claude Code (`.claude/settings.json`) and Cursor (`.cursor/hooks.json`) run the gate when you finish a turn and send any failures back to you, but only in a session started in this folder: if you downloaded the SDK during the current session, run the gate yourself. Other agents must also run it themselves. If you cannot fix a failure, say plainly that the Block is not ready and list the failing checks.
8
8
 
9
- Contract `stillmade.block-builder@1.5.3`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
9
+ Contract `stillmade.block-builder@1.5.4`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
10
10
 
11
11
  ## Source of truth
12
12
 
@@ -54,7 +54,7 @@ Give the Block a short, plain name of 40 characters or fewer that says what it d
54
54
 
55
55
  ## Interface
56
56
 
57
- If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction genuinely needs one. Build custom views from the Block kit the host injects (`block-kit.css`): the result in `sm-stage`, picks as pictures in `sm-choices`, one `sm-primary` naming the action (Write, Generate; never "Run") and no price (StillMade's run button adds it), extras in a closed `sm-more`; a look the person names wins. Fit one laptop screen without scrolling: label beside control, status in a few words, files as tiles, rare tools as icons, (i) on unclear controls. Drop words nobody needs; put helpful ones in a closed `sm-hint`. Expose the capability, not the implementation: sensible defaults, previews, progress, clear errors, visible outputs. Do not show raw JSON, internal IDs, filesystem details, provider terminology or developer settings unless the Block is itself a developer tool. When a person chooses among options they need to hear or see (voices, music, sounds, fonts, looks, colors, templates or images), let them preview each option before choosing: a sample to play or a thumbnail, from the Block's own files or the host's free samples, never a paid generation. Leave previews out only when the builder states there is nothing to preview. Choices StillMade owns, such as voices and models in the run review, already show their samples. Follow the host appearance (Light, Dark and White) and one elastic layout: stacked on a 320px phone with no sideways scroll (result first, action pinned), and from 860px the controls left (≤380px), the result filling the right.
57
+ If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction genuinely needs one. Build custom views from the Block kit the host injects (`block-kit.css`): the result in `sm-stage`, picks as pictures in `sm-choices`, one `sm-primary` naming the action (Write, Generate; never "Run") and no price (StillMade's run button adds it), extras in a closed `sm-more`; a look the person names wins. Fit one laptop screen without scrolling: label beside control, status in a few words, files as tiles, rare tools as icons, (i) on unclear controls. Drop words nobody needs; put helpful ones in a closed `sm-hint`. Expose the capability, not the implementation: sensible defaults, previews, progress, clear errors, visible outputs. Do not show raw JSON, internal IDs, filesystem details, provider terminology or developer settings unless the Block is itself a developer tool. When a person chooses among options they need to hear or see (voices, music, sounds, fonts, looks, colors, templates or images), let them preview each option before choosing: a sample to play or a thumbnail, from the Block's own files or the host's free samples, never a paid generation. Leave previews out only when the builder states there is nothing to preview. Choices StillMade owns, such as voices and models in the run review, already show their samples. Follow the host appearance (Light, Dark and White) and one elastic layout: stacked on a 320px phone with no sideways scroll (result first, action pinned), and from 860px the controls left (≤380px), the result filling the right. Short settings sit side by side (`sm-settings`; three or four short options as one `data-segmented` row); many items are one line each (`sm-list`) that open in place; input files are small tiles (`sm-gallery data-size="small"`); on a phone chip rows scroll sideways and long lists show three. Compacting moves controls, never deletes them.
58
58
 
59
59
  ## Shared editing
60
60
 
@@ -57,13 +57,16 @@ piece in Light, Dark and White.
57
57
  | `sm-block` | The one workspace. `data-layout="split"` puts the stage beside the controls on wide screens. |
58
58
  | `sm-stage` | The thing being made: preview, media or result. `data-ratio="16:9"`, `"9:16"` or `"1:1"`. |
59
59
  | `sm-empty` | An empty stage: a glyph, at most five words, one action. |
60
- | `sm-choices` | Picks shown as pictures (`img`, `.sm-swatch`, `.sm-glyph`) and one or two words. `data-compact` for short text chips. Give the `fieldset` an `id` and `data-stillmade-share` so teammates see the same pick. |
60
+ | `sm-choices` | Picks shown as pictures (`img`, `.sm-swatch`, `.sm-glyph`) and one or two words. `data-compact` for short text chips, `data-segmented` for one connected row of three or four short options. Chips and segments scroll sideways on a phone. Give the `fieldset` an `id` and `data-stillmade-share` so teammates see the same pick. |
61
61
  | `sm-field`, `sm-fields` | A short label above one control; a responsive group of them. |
62
+ | `sm-settings` | Short settings side by side, each label above its control. |
63
+ | `sm-list` | Many items, one line each: a thumbnail, one line of text, a short fact. An item that opens in place is an `li` holding a `details`. `data-peek` shows three on a phone, with a last `li.sm-list-more` button that sets `data-open`. |
64
+ | `sm-clamp` | Long text that shows five lines on a phone until it gets `data-open`. |
62
65
  | `sm-actions` | One `sm-primary`, then `sm-quiet` buttons and `sm-icon` buttons (each with `aria-label` and `title`). |
63
66
  | `sm-status` | Live state beside the action: `data-state="loading"`, `"success"`, `"waiting"` or `"error"`. |
64
67
  | `sm-more` | A closed `<details>` for secondary settings. |
65
68
  | `sm-hint` | A closed `<details>` info toggle for an explanation that might help. |
66
- | `sm-gallery` | A grid of results or media. |
69
+ | `sm-gallery` | A grid of results or media. `data-size="small"` for input files: more tiles per row as the screen widens. |
67
70
  | `sm-glyph` | A small icon in `currentColor`: `play`, `pause`, `plus`, `close`, `check`, `chevron`, `upload`, `image`, `video`, `audio`, `text`, `spark`, `info`, `warning`, `spinner`. Works in standard views, which cannot use SVG. |
68
71
 
69
72
  **Function first.** When the person building a Block does not ask for a look,
@@ -148,6 +151,20 @@ exception, never unrelated technical UI.
148
151
  fields. Before there is a result, the stage previews what will be made
149
152
  from the inputs given so far, not an empty box. `data-layout="stack"`
150
153
  keeps one column.
154
+ 17. Settings sit side by side, next to what they change. Short settings are
155
+ an `sm-settings` grid, and three or four short options (Low / Med /
156
+ High, 16:9 / 9:16 / 1:1) are one `data-segmented` row, not big tiles.
157
+ 18. Lists fill the width at a small size. Input files are `sm-gallery
158
+ data-size="small"` tiles; many items (shots, scenes, rows) are an
159
+ `sm-list`, one line each with a thumbnail, one line of text and a short
160
+ fact, and tapping an item opens all of its fields in place. Extra width
161
+ means more items per row, never bigger cards.
162
+ 19. On a phone, chip and segment rows scroll sideways instead of wrapping,
163
+ long lists show their first three and "N more" (`sm-list data-peek`),
164
+ and long text shows five lines until tapped (`sm-clamp`).
165
+ 20. Nothing is lost when a Block gets smaller. Every control stays on the
166
+ screen, behind an (i), in `sm-more`, or inside the item it belongs to.
167
+ Compacting moves controls; it never deletes them.
151
168
 
152
169
  ## 4. What StillMade checks
153
170
 
package/PASTE_TO_LLM.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  <!-- builder-contract:start (generated by npm run build:sdk; do not edit) -->
4
4
 
5
- ## Block builder contract (stillmade.block-builder@1.5.3)
5
+ ## Block builder contract (stillmade.block-builder@1.5.4)
6
6
 
7
- Contract `stillmade.block-builder@1.5.3`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
7
+ Contract `stillmade.block-builder@1.5.4`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
8
8
 
9
9
  ### Source of truth
10
10
 
@@ -52,7 +52,7 @@ Give the Block a short, plain name of 40 characters or fewer that says what it d
52
52
 
53
53
  ### Interface
54
54
 
55
- If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction genuinely needs one. Build custom views from the Block kit the host injects (`block-kit.css`): the result in `sm-stage`, picks as pictures in `sm-choices`, one `sm-primary` naming the action (Write, Generate; never "Run") and no price (StillMade's run button adds it), extras in a closed `sm-more`; a look the person names wins. Fit one laptop screen without scrolling: label beside control, status in a few words, files as tiles, rare tools as icons, (i) on unclear controls. Drop words nobody needs; put helpful ones in a closed `sm-hint`. Expose the capability, not the implementation: sensible defaults, previews, progress, clear errors, visible outputs. Do not show raw JSON, internal IDs, filesystem details, provider terminology or developer settings unless the Block is itself a developer tool. When a person chooses among options they need to hear or see (voices, music, sounds, fonts, looks, colors, templates or images), let them preview each option before choosing: a sample to play or a thumbnail, from the Block's own files or the host's free samples, never a paid generation. Leave previews out only when the builder states there is nothing to preview. Choices StillMade owns, such as voices and models in the run review, already show their samples. Follow the host appearance (Light, Dark and White) and one elastic layout: stacked on a 320px phone with no sideways scroll (result first, action pinned), and from 860px the controls left (≤380px), the result filling the right.
55
+ If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction genuinely needs one. Build custom views from the Block kit the host injects (`block-kit.css`): the result in `sm-stage`, picks as pictures in `sm-choices`, one `sm-primary` naming the action (Write, Generate; never "Run") and no price (StillMade's run button adds it), extras in a closed `sm-more`; a look the person names wins. Fit one laptop screen without scrolling: label beside control, status in a few words, files as tiles, rare tools as icons, (i) on unclear controls. Drop words nobody needs; put helpful ones in a closed `sm-hint`. Expose the capability, not the implementation: sensible defaults, previews, progress, clear errors, visible outputs. Do not show raw JSON, internal IDs, filesystem details, provider terminology or developer settings unless the Block is itself a developer tool. When a person chooses among options they need to hear or see (voices, music, sounds, fonts, looks, colors, templates or images), let them preview each option before choosing: a sample to play or a thumbnail, from the Block's own files or the host's free samples, never a paid generation. Leave previews out only when the builder states there is nothing to preview. Choices StillMade owns, such as voices and models in the run review, already show their samples. Follow the host appearance (Light, Dark and White) and one elastic layout: stacked on a 320px phone with no sideways scroll (result first, action pinned), and from 860px the controls left (≤380px), the result filling the right. Short settings sit side by side (`sm-settings`; three or four short options as one `data-segmented` row); many items are one line each (`sm-list`) that open in place; input files are small tiles (`sm-gallery data-size="small"`); on a phone chip rows scroll sideways and long lists show three. Compacting moves controls, never deletes them.
56
56
 
57
57
  ### Shared editing
58
58
 
@@ -210,7 +210,7 @@ Optional custom view interfaces are supported, but generated manifest.ui control
210
210
 
211
211
  *When:* StillMade's builder adds this section when the person asks for an interface, preview or controls, or refines a Block that has one.
212
212
 
213
- A custom interface is the optional package-level view:{html,css?,themedCss?,javascript?}; when refining, preserve and refine base.view. Design it by StillMade's interface principles, in order: Function first: unless the person asks for a design direction, build from the Block kit (`sm-block`, `sm-stage`, `sm-choices`, `sm-actions`, `sm-more`) and ship little or no CSS of your own. A direction the person names wins over the kit. Show the thing being made: the preview, media or result gets the largest area (`sm-stage`). Never a JSON dump, source editor, manifest or diagnostic panel unless the task is about source. One obvious next action (`sm-primary`); peers are quiet buttons or named icons. Seven or fewer choices in view. The action button names what it does ("Write", "Generate image", "Make video"), never "Run", "Run step", "Submit" or "Review cost". Show no credit numbers: StillMade puts the price beside the verb on its own run button ("Write · 1 credit"), with a chip for the model, quality or count when they can change. Pressing it runs at that price; a confirmation appears only when the server price is higher. Pictures over words: choices people see or hear are thumbnails, swatches, samples or glyphs (`sm-choices`), not word lists. Icons carry an accessible name and tooltip; never emoji. Words only when needed. Drop what nobody needs to finish the task (intros, "how it works", restating the Block name). Words that might help start collapsed (`sm-hint`, `sm-more`). Errors, spending approvals, stale inputs and destructive steps stay visible, in few words. Strong defaults; secondary settings go in `sm-more`, closed. Compact: the whole Block fits one laptop screen without scrolling. A short setting is one row, its label beside the control; no card around a single control. Status is a dot or a few words ("No narration yet"), never a paragraph; the reason sits behind an `sm-hint`. Files are tiles: a saved file is a thumbnail or chip and adding one is a + tile. Never the bare browser file picker, and no size limits in view until a file is too big. Rare tools (update, schedule, history, reload) are named icon buttons beside the action, never sections under the work. An (i) beside anything a newcomer could misread: a setting, status or number whose effect is not obvious from its label gets a closed `sm-hint` with one or two sentences. Give every input that needs one a `description`; StillMade shows it as that (i). Obvious controls get none. One workspace: no cards inside cards, no second title, step counter or Back/Next bar; the host owns navigation. Status sits beside the action it describes (`sm-status`), in a few words. Keep the page in normal scroll flow; no sticky media or control strips unless the editing task needs them. Use the width: from 860px wide the kit puts the controls on the left at a reading width (300–380px) and the result (`sm-stage`) fills the right, in its real shape; under that everything stacks with the result first and the action within reach. Extra width goes to the result, never to wider text fields. Before there is a result, the stage previews what will be made from the inputs. `data-layout="stack"` opts out. Text scene descriptions are planning notes, never a storyboard or an approved frame. Its DOM controller is separate from manifest runtime code. The view may also declare appearance:"original" or "host". For an imported design, preserve its colors with appearance:"original" and view.css; no themed replacement is required. Preserve base.view.appearance when refining unless the user requests a change. Omitted/host appearance retains the existing Light, Dark and White requirement: supply semantic colors in view.css or a complete replacement view.themedCss. An original-style view may optionally supply valid themedCss for a StillMade appearance preview. Use StillMade variables (--bg,--fg,--fg-muted,--border-tok,--r-3) only when opting into host styling; do not redefine host tokens in the themed variant. Appearance never relaxes sandbox constraints: no CSS escapes/filters/blending, imports/url(), or element.style mutations in JS. Use classes for UI state; media pixels retain their colors. Both CSS fields have the same 32 KiB limit; all existing shared-state, security and permission checks still apply. Declare elements in html, bind with document.getElementById/querySelector and addEventListener; use literal property access, array methods, textContent, input.value, button.disabled and canvas. Initial values: StillMade.onInput(values=>{...}); await StillMade.run(inputBindings) returns validated output bindings from the isolated package runtime; catch errors and show results. No computation in the DOM controller; put it in code/recipe. Disable the action button while pending.
213
+ A custom interface is the optional package-level view:{html,css?,themedCss?,javascript?}; when refining, preserve and refine base.view. Design it by StillMade's interface principles, in order: Function first: unless the person asks for a design direction, build from the Block kit (`sm-block`, `sm-stage`, `sm-choices`, `sm-actions`, `sm-more`) and ship little or no CSS of your own. A direction the person names wins over the kit. Show the thing being made: the preview, media or result gets the largest area (`sm-stage`). Never a JSON dump, source editor, manifest or diagnostic panel unless the task is about source. One obvious next action (`sm-primary`); peers are quiet buttons or named icons. Seven or fewer choices in view. The action button names what it does ("Write", "Generate image", "Make video"), never "Run", "Run step", "Submit" or "Review cost". Show no credit numbers: StillMade puts the price beside the verb on its own run button ("Write · 1 credit"), with a chip for the model, quality or count when they can change. Pressing it runs at that price; a confirmation appears only when the server price is higher. Pictures over words: choices people see or hear are thumbnails, swatches, samples or glyphs (`sm-choices`), not word lists. Icons carry an accessible name and tooltip; never emoji. Words only when needed. Drop what nobody needs to finish the task (intros, "how it works", restating the Block name). Words that might help start collapsed (`sm-hint`, `sm-more`). Errors, spending approvals, stale inputs and destructive steps stay visible, in few words. Strong defaults; secondary settings go in `sm-more`, closed. Compact: the whole Block fits one laptop screen without scrolling. A short setting is one row, its label beside the control; no card around a single control. Status is a dot or a few words ("No narration yet"), never a paragraph; the reason sits behind an `sm-hint`. Files are tiles: a saved file is a thumbnail or chip and adding one is a + tile. Never the bare browser file picker, and no size limits in view until a file is too big. Rare tools (update, schedule, history, reload) are named icon buttons beside the action, never sections under the work. An (i) beside anything a newcomer could misread: a setting, status or number whose effect is not obvious from its label gets a closed `sm-hint` with one or two sentences. Give every input that needs one a `description`; StillMade shows it as that (i). Obvious controls get none. One workspace: no cards inside cards, no second title, step counter or Back/Next bar; the host owns navigation. Status sits beside the action it describes (`sm-status`), in a few words. Keep the page in normal scroll flow; no sticky media or control strips unless the editing task needs them. Use the width: from 860px wide the kit puts the controls on the left at a reading width (300–380px) and the result (`sm-stage`) fills the right, in its real shape; under that everything stacks with the result first and the action within reach. Extra width goes to the result, never to wider text fields. Before there is a result, the stage previews what will be made from the inputs. `data-layout="stack"` opts out. Settings sit side by side (`sm-settings`), next to what they change. Three or four short options are one segmented row (`data-segmented`), not a row of big tiles. Lists fill the width at a small size: input files are small tiles (`sm-gallery data-size="small"`), many items are one line each (`sm-list`): a thumbnail, one line of text, a short fact. Tapping an item opens all of its fields in place. Extra width means more items per row, never bigger cards. On a phone chip and segment rows scroll sideways instead of wrapping; long lists show their first three with "N more" (`data-peek`) and long text five lines until tapped (`sm-clamp`). Nothing is lost when a Block gets smaller: every control stays on the screen, behind an (i), in `sm-more`, or inside the item it belongs to. Compacting moves controls; it never deletes them. Text scene descriptions are planning notes, never a storyboard or an approved frame. Its DOM controller is separate from manifest runtime code. The view may also declare appearance:"original" or "host". For an imported design, preserve its colors with appearance:"original" and view.css; no themed replacement is required. Preserve base.view.appearance when refining unless the user requests a change. Omitted/host appearance retains the existing Light, Dark and White requirement: supply semantic colors in view.css or a complete replacement view.themedCss. An original-style view may optionally supply valid themedCss for a StillMade appearance preview. Use StillMade variables (--bg,--fg,--fg-muted,--border-tok,--r-3) only when opting into host styling; do not redefine host tokens in the themed variant. Appearance never relaxes sandbox constraints: no CSS escapes/filters/blending, imports/url(), or element.style mutations in JS. Use classes for UI state; media pixels retain their colors. Both CSS fields have the same 32 KiB limit; all existing shared-state, security and permission checks still apply. Declare elements in html, bind with document.getElementById/querySelector and addEventListener; use literal property access, array methods, textContent, input.value, button.disabled and canvas. Initial values: StillMade.onInput(values=>{...}); await StillMade.run(inputBindings) returns validated output bindings from the isolated package runtime; catch errors and show results. No computation in the DOM controller; put it in code/recipe. Disable the action button while pending.
214
214
  Standard custom view code (no `view.config.json` frame runtime) is checked before it runs. These rules come straight from the validator; frame views run in their own sandbox and may build the page with ordinary DOM calls such as `createElement`:
215
215
 
216
216
  - **HTML elements:** only `div`, `section`, `article`, `header`, `footer`, `main`, `aside`, `nav`, `h1`, `h2`, `h3`, `h4`, `p`, `span`, `strong`, `em`, `i`, `small`, `br`, `hr`, `label`, `input`, `textarea`, `button`, `select`, `option`, `optgroup`, `fieldset`, `legend`, `output`, `progress`, `meter`, `ul`, `ol`, `li`, `dl`, `dt`, `dd`, `figure`, `figcaption`, `img`, `video`, `audio`, `source`, `canvas`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th`, `td`, `pre`, `code`, `details`, `summary`. No scripts, iframes, SVG, forms, comments or inline event attributes; media URLs must be `data:` or `blob:`.
package/SDK.md CHANGED
@@ -182,7 +182,7 @@ The archive needs Node.js 22 or later and nothing else; its runtime is bundled,
182
182
 
183
183
  ## Block builder contract
184
184
 
185
- Contract `stillmade.block-builder@1.5.3`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
185
+ Contract `stillmade.block-builder@1.5.4`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
186
186
 
187
187
  ### Source of truth
188
188
 
@@ -230,7 +230,7 @@ Give the Block a short, plain name of 40 characters or fewer that says what it d
230
230
 
231
231
  ### Interface
232
232
 
233
- If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction genuinely needs one. Build custom views from the Block kit the host injects (`block-kit.css`): the result in `sm-stage`, picks as pictures in `sm-choices`, one `sm-primary` naming the action (Write, Generate; never "Run") and no price (StillMade's run button adds it), extras in a closed `sm-more`; a look the person names wins. Fit one laptop screen without scrolling: label beside control, status in a few words, files as tiles, rare tools as icons, (i) on unclear controls. Drop words nobody needs; put helpful ones in a closed `sm-hint`. Expose the capability, not the implementation: sensible defaults, previews, progress, clear errors, visible outputs. Do not show raw JSON, internal IDs, filesystem details, provider terminology or developer settings unless the Block is itself a developer tool. When a person chooses among options they need to hear or see (voices, music, sounds, fonts, looks, colors, templates or images), let them preview each option before choosing: a sample to play or a thumbnail, from the Block's own files or the host's free samples, never a paid generation. Leave previews out only when the builder states there is nothing to preview. Choices StillMade owns, such as voices and models in the run review, already show their samples. Follow the host appearance (Light, Dark and White) and one elastic layout: stacked on a 320px phone with no sideways scroll (result first, action pinned), and from 860px the controls left (≤380px), the result filling the right.
233
+ If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction genuinely needs one. Build custom views from the Block kit the host injects (`block-kit.css`): the result in `sm-stage`, picks as pictures in `sm-choices`, one `sm-primary` naming the action (Write, Generate; never "Run") and no price (StillMade's run button adds it), extras in a closed `sm-more`; a look the person names wins. Fit one laptop screen without scrolling: label beside control, status in a few words, files as tiles, rare tools as icons, (i) on unclear controls. Drop words nobody needs; put helpful ones in a closed `sm-hint`. Expose the capability, not the implementation: sensible defaults, previews, progress, clear errors, visible outputs. Do not show raw JSON, internal IDs, filesystem details, provider terminology or developer settings unless the Block is itself a developer tool. When a person chooses among options they need to hear or see (voices, music, sounds, fonts, looks, colors, templates or images), let them preview each option before choosing: a sample to play or a thumbnail, from the Block's own files or the host's free samples, never a paid generation. Leave previews out only when the builder states there is nothing to preview. Choices StillMade owns, such as voices and models in the run review, already show their samples. Follow the host appearance (Light, Dark and White) and one elastic layout: stacked on a 320px phone with no sideways scroll (result first, action pinned), and from 860px the controls left (≤380px), the result filling the right. Short settings sit side by side (`sm-settings`; three or four short options as one `data-segmented` row); many items are one line each (`sm-list`) that open in place; input files are small tiles (`sm-gallery data-size="small"`); on a phone chip rows scroll sideways and long lists show three. Compacting moves controls, never deletes them.
234
234
 
235
235
  ### Shared editing
236
236
 
@@ -7224,9 +7224,9 @@ Ask the assistant to return source files or one `.stillmade.json` package. Run t
7224
7224
 
7225
7225
  <!-- builder-contract:start (generated by npm run build:sdk; do not edit) -->
7226
7226
 
7227
- ### Block builder contract (stillmade.block-builder@1.5.3)
7227
+ ### Block builder contract (stillmade.block-builder@1.5.4)
7228
7228
 
7229
- Contract `stillmade.block-builder@1.5.3`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
7229
+ Contract `stillmade.block-builder@1.5.4`. Humans, coding agents, imported source, GitHub repositories and generated code all adapt to the Block platform; anything that becomes a StillMade Block obeys this contract.
7230
7230
 
7231
7231
  ### Source of truth
7232
7232
 
@@ -7274,7 +7274,7 @@ Give the Block a short, plain name of 40 characters or fewer that says what it d
7274
7274
 
7275
7275
  ### Interface
7276
7276
 
7277
- If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction genuinely needs one. Build custom views from the Block kit the host injects (`block-kit.css`): the result in `sm-stage`, picks as pictures in `sm-choices`, one `sm-primary` naming the action (Write, Generate; never "Run") and no price (StillMade's run button adds it), extras in a closed `sm-more`; a look the person names wins. Fit one laptop screen without scrolling: label beside control, status in a few words, files as tiles, rare tools as icons, (i) on unclear controls. Drop words nobody needs; put helpful ones in a closed `sm-hint`. Expose the capability, not the implementation: sensible defaults, previews, progress, clear errors, visible outputs. Do not show raw JSON, internal IDs, filesystem details, provider terminology or developer settings unless the Block is itself a developer tool. When a person chooses among options they need to hear or see (voices, music, sounds, fonts, looks, colors, templates or images), let them preview each option before choosing: a sample to play or a thumbnail, from the Block's own files or the host's free samples, never a paid generation. Leave previews out only when the builder states there is nothing to preview. Choices StillMade owns, such as voices and models in the run review, already show their samples. Follow the host appearance (Light, Dark and White) and one elastic layout: stacked on a 320px phone with no sideways scroll (result first, action pinned), and from 860px the controls left (≤380px), the result filling the right.
7277
+ If the capability needs UI, use the Block UI SDK: generated `manifest.ui` controls first; a sandboxed custom view (`view.html`/`view.css`/`view.js`) only when the core interaction genuinely needs one. Build custom views from the Block kit the host injects (`block-kit.css`): the result in `sm-stage`, picks as pictures in `sm-choices`, one `sm-primary` naming the action (Write, Generate; never "Run") and no price (StillMade's run button adds it), extras in a closed `sm-more`; a look the person names wins. Fit one laptop screen without scrolling: label beside control, status in a few words, files as tiles, rare tools as icons, (i) on unclear controls. Drop words nobody needs; put helpful ones in a closed `sm-hint`. Expose the capability, not the implementation: sensible defaults, previews, progress, clear errors, visible outputs. Do not show raw JSON, internal IDs, filesystem details, provider terminology or developer settings unless the Block is itself a developer tool. When a person chooses among options they need to hear or see (voices, music, sounds, fonts, looks, colors, templates or images), let them preview each option before choosing: a sample to play or a thumbnail, from the Block's own files or the host's free samples, never a paid generation. Leave previews out only when the builder states there is nothing to preview. Choices StillMade owns, such as voices and models in the run review, already show their samples. Follow the host appearance (Light, Dark and White) and one elastic layout: stacked on a 320px phone with no sideways scroll (result first, action pinned), and from 860px the controls left (≤380px), the result filling the right. Short settings sit side by side (`sm-settings`; three or four short options as one `data-segmented` row); many items are one line each (`sm-list`) that open in place; input files are small tiles (`sm-gallery data-size="small"`); on a phone chip rows scroll sideways and long lists show three. Compacting moves controls, never deletes them.
7278
7278
 
7279
7279
  ### Shared editing
7280
7280
 
@@ -7432,7 +7432,7 @@ Optional custom view interfaces are supported, but generated manifest.ui control
7432
7432
 
7433
7433
  *When:* StillMade's builder adds this section when the person asks for an interface, preview or controls, or refines a Block that has one.
7434
7434
 
7435
- A custom interface is the optional package-level view:{html,css?,themedCss?,javascript?}; when refining, preserve and refine base.view. Design it by StillMade's interface principles, in order: Function first: unless the person asks for a design direction, build from the Block kit (`sm-block`, `sm-stage`, `sm-choices`, `sm-actions`, `sm-more`) and ship little or no CSS of your own. A direction the person names wins over the kit. Show the thing being made: the preview, media or result gets the largest area (`sm-stage`). Never a JSON dump, source editor, manifest or diagnostic panel unless the task is about source. One obvious next action (`sm-primary`); peers are quiet buttons or named icons. Seven or fewer choices in view. The action button names what it does ("Write", "Generate image", "Make video"), never "Run", "Run step", "Submit" or "Review cost". Show no credit numbers: StillMade puts the price beside the verb on its own run button ("Write · 1 credit"), with a chip for the model, quality or count when they can change. Pressing it runs at that price; a confirmation appears only when the server price is higher. Pictures over words: choices people see or hear are thumbnails, swatches, samples or glyphs (`sm-choices`), not word lists. Icons carry an accessible name and tooltip; never emoji. Words only when needed. Drop what nobody needs to finish the task (intros, "how it works", restating the Block name). Words that might help start collapsed (`sm-hint`, `sm-more`). Errors, spending approvals, stale inputs and destructive steps stay visible, in few words. Strong defaults; secondary settings go in `sm-more`, closed. Compact: the whole Block fits one laptop screen without scrolling. A short setting is one row, its label beside the control; no card around a single control. Status is a dot or a few words ("No narration yet"), never a paragraph; the reason sits behind an `sm-hint`. Files are tiles: a saved file is a thumbnail or chip and adding one is a + tile. Never the bare browser file picker, and no size limits in view until a file is too big. Rare tools (update, schedule, history, reload) are named icon buttons beside the action, never sections under the work. An (i) beside anything a newcomer could misread: a setting, status or number whose effect is not obvious from its label gets a closed `sm-hint` with one or two sentences. Give every input that needs one a `description`; StillMade shows it as that (i). Obvious controls get none. One workspace: no cards inside cards, no second title, step counter or Back/Next bar; the host owns navigation. Status sits beside the action it describes (`sm-status`), in a few words. Keep the page in normal scroll flow; no sticky media or control strips unless the editing task needs them. Use the width: from 860px wide the kit puts the controls on the left at a reading width (300–380px) and the result (`sm-stage`) fills the right, in its real shape; under that everything stacks with the result first and the action within reach. Extra width goes to the result, never to wider text fields. Before there is a result, the stage previews what will be made from the inputs. `data-layout="stack"` opts out. Text scene descriptions are planning notes, never a storyboard or an approved frame. Its DOM controller is separate from manifest runtime code. The view may also declare appearance:"original" or "host". For an imported design, preserve its colors with appearance:"original" and view.css; no themed replacement is required. Preserve base.view.appearance when refining unless the user requests a change. Omitted/host appearance retains the existing Light, Dark and White requirement: supply semantic colors in view.css or a complete replacement view.themedCss. An original-style view may optionally supply valid themedCss for a StillMade appearance preview. Use StillMade variables (--bg,--fg,--fg-muted,--border-tok,--r-3) only when opting into host styling; do not redefine host tokens in the themed variant. Appearance never relaxes sandbox constraints: no CSS escapes/filters/blending, imports/url(), or element.style mutations in JS. Use classes for UI state; media pixels retain their colors. Both CSS fields have the same 32 KiB limit; all existing shared-state, security and permission checks still apply. Declare elements in html, bind with document.getElementById/querySelector and addEventListener; use literal property access, array methods, textContent, input.value, button.disabled and canvas. Initial values: StillMade.onInput(values=>{...}); await StillMade.run(inputBindings) returns validated output bindings from the isolated package runtime; catch errors and show results. No computation in the DOM controller; put it in code/recipe. Disable the action button while pending.
7435
+ A custom interface is the optional package-level view:{html,css?,themedCss?,javascript?}; when refining, preserve and refine base.view. Design it by StillMade's interface principles, in order: Function first: unless the person asks for a design direction, build from the Block kit (`sm-block`, `sm-stage`, `sm-choices`, `sm-actions`, `sm-more`) and ship little or no CSS of your own. A direction the person names wins over the kit. Show the thing being made: the preview, media or result gets the largest area (`sm-stage`). Never a JSON dump, source editor, manifest or diagnostic panel unless the task is about source. One obvious next action (`sm-primary`); peers are quiet buttons or named icons. Seven or fewer choices in view. The action button names what it does ("Write", "Generate image", "Make video"), never "Run", "Run step", "Submit" or "Review cost". Show no credit numbers: StillMade puts the price beside the verb on its own run button ("Write · 1 credit"), with a chip for the model, quality or count when they can change. Pressing it runs at that price; a confirmation appears only when the server price is higher. Pictures over words: choices people see or hear are thumbnails, swatches, samples or glyphs (`sm-choices`), not word lists. Icons carry an accessible name and tooltip; never emoji. Words only when needed. Drop what nobody needs to finish the task (intros, "how it works", restating the Block name). Words that might help start collapsed (`sm-hint`, `sm-more`). Errors, spending approvals, stale inputs and destructive steps stay visible, in few words. Strong defaults; secondary settings go in `sm-more`, closed. Compact: the whole Block fits one laptop screen without scrolling. A short setting is one row, its label beside the control; no card around a single control. Status is a dot or a few words ("No narration yet"), never a paragraph; the reason sits behind an `sm-hint`. Files are tiles: a saved file is a thumbnail or chip and adding one is a + tile. Never the bare browser file picker, and no size limits in view until a file is too big. Rare tools (update, schedule, history, reload) are named icon buttons beside the action, never sections under the work. An (i) beside anything a newcomer could misread: a setting, status or number whose effect is not obvious from its label gets a closed `sm-hint` with one or two sentences. Give every input that needs one a `description`; StillMade shows it as that (i). Obvious controls get none. One workspace: no cards inside cards, no second title, step counter or Back/Next bar; the host owns navigation. Status sits beside the action it describes (`sm-status`), in a few words. Keep the page in normal scroll flow; no sticky media or control strips unless the editing task needs them. Use the width: from 860px wide the kit puts the controls on the left at a reading width (300–380px) and the result (`sm-stage`) fills the right, in its real shape; under that everything stacks with the result first and the action within reach. Extra width goes to the result, never to wider text fields. Before there is a result, the stage previews what will be made from the inputs. `data-layout="stack"` opts out. Settings sit side by side (`sm-settings`), next to what they change. Three or four short options are one segmented row (`data-segmented`), not a row of big tiles. Lists fill the width at a small size: input files are small tiles (`sm-gallery data-size="small"`), many items are one line each (`sm-list`): a thumbnail, one line of text, a short fact. Tapping an item opens all of its fields in place. Extra width means more items per row, never bigger cards. On a phone chip and segment rows scroll sideways instead of wrapping; long lists show their first three with "N more" (`data-peek`) and long text five lines until tapped (`sm-clamp`). Nothing is lost when a Block gets smaller: every control stays on the screen, behind an (i), in `sm-more`, or inside the item it belongs to. Compacting moves controls; it never deletes them. Text scene descriptions are planning notes, never a storyboard or an approved frame. Its DOM controller is separate from manifest runtime code. The view may also declare appearance:"original" or "host". For an imported design, preserve its colors with appearance:"original" and view.css; no themed replacement is required. Preserve base.view.appearance when refining unless the user requests a change. Omitted/host appearance retains the existing Light, Dark and White requirement: supply semantic colors in view.css or a complete replacement view.themedCss. An original-style view may optionally supply valid themedCss for a StillMade appearance preview. Use StillMade variables (--bg,--fg,--fg-muted,--border-tok,--r-3) only when opting into host styling; do not redefine host tokens in the themed variant. Appearance never relaxes sandbox constraints: no CSS escapes/filters/blending, imports/url(), or element.style mutations in JS. Use classes for UI state; media pixels retain their colors. Both CSS fields have the same 32 KiB limit; all existing shared-state, security and permission checks still apply. Declare elements in html, bind with document.getElementById/querySelector and addEventListener; use literal property access, array methods, textContent, input.value, button.disabled and canvas. Initial values: StillMade.onInput(values=>{...}); await StillMade.run(inputBindings) returns validated output bindings from the isolated package runtime; catch errors and show results. No computation in the DOM controller; put it in code/recipe. Disable the action button while pending.
7436
7436
  Standard custom view code (no `view.config.json` frame runtime) is checked before it runs. These rules come straight from the validator; frame views run in their own sandbox and may build the page with ordinary DOM calls such as `createElement`:
7437
7437
 
7438
7438
  - **HTML elements:** only `div`, `section`, `article`, `header`, `footer`, `main`, `aside`, `nav`, `h1`, `h2`, `h3`, `h4`, `p`, `span`, `strong`, `em`, `i`, `small`, `br`, `hr`, `label`, `input`, `textarea`, `button`, `select`, `option`, `optgroup`, `fieldset`, `legend`, `output`, `progress`, `meter`, `ul`, `ol`, `li`, `dl`, `dt`, `dd`, `figure`, `figcaption`, `img`, `video`, `audio`, `source`, `canvas`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th`, `td`, `pre`, `code`, `details`, `summary`. No scripts, iframes, SVG, forms, comments or inline event attributes; media URLs must be `data:` or `blob:`.
@@ -9554,13 +9554,16 @@ piece in Light, Dark and White.
9554
9554
  | `sm-block` | The one workspace. `data-layout="split"` puts the stage beside the controls on wide screens. |
9555
9555
  | `sm-stage` | The thing being made: preview, media or result. `data-ratio="16:9"`, `"9:16"` or `"1:1"`. |
9556
9556
  | `sm-empty` | An empty stage: a glyph, at most five words, one action. |
9557
- | `sm-choices` | Picks shown as pictures (`img`, `.sm-swatch`, `.sm-glyph`) and one or two words. `data-compact` for short text chips. Give the `fieldset` an `id` and `data-stillmade-share` so teammates see the same pick. |
9557
+ | `sm-choices` | Picks shown as pictures (`img`, `.sm-swatch`, `.sm-glyph`) and one or two words. `data-compact` for short text chips, `data-segmented` for one connected row of three or four short options. Chips and segments scroll sideways on a phone. Give the `fieldset` an `id` and `data-stillmade-share` so teammates see the same pick. |
9558
9558
  | `sm-field`, `sm-fields` | A short label above one control; a responsive group of them. |
9559
+ | `sm-settings` | Short settings side by side, each label above its control. |
9560
+ | `sm-list` | Many items, one line each: a thumbnail, one line of text, a short fact. An item that opens in place is an `li` holding a `details`. `data-peek` shows three on a phone, with a last `li.sm-list-more` button that sets `data-open`. |
9561
+ | `sm-clamp` | Long text that shows five lines on a phone until it gets `data-open`. |
9559
9562
  | `sm-actions` | One `sm-primary`, then `sm-quiet` buttons and `sm-icon` buttons (each with `aria-label` and `title`). |
9560
9563
  | `sm-status` | Live state beside the action: `data-state="loading"`, `"success"`, `"waiting"` or `"error"`. |
9561
9564
  | `sm-more` | A closed `<details>` for secondary settings. |
9562
9565
  | `sm-hint` | A closed `<details>` info toggle for an explanation that might help. |
9563
- | `sm-gallery` | A grid of results or media. |
9566
+ | `sm-gallery` | A grid of results or media. `data-size="small"` for input files: more tiles per row as the screen widens. |
9564
9567
  | `sm-glyph` | A small icon in `currentColor`: `play`, `pause`, `plus`, `close`, `check`, `chevron`, `upload`, `image`, `video`, `audio`, `text`, `spark`, `info`, `warning`, `spinner`. Works in standard views, which cannot use SVG. |
9565
9568
 
9566
9569
  **Function first.** When the person building a Block does not ask for a look,
@@ -9645,6 +9648,20 @@ exception, never unrelated technical UI.
9645
9648
  fields. Before there is a result, the stage previews what will be made
9646
9649
  from the inputs given so far, not an empty box. `data-layout="stack"`
9647
9650
  keeps one column.
9651
+ 17. Settings sit side by side, next to what they change. Short settings are
9652
+ an `sm-settings` grid, and three or four short options (Low / Med /
9653
+ High, 16:9 / 9:16 / 1:1) are one `data-segmented` row, not big tiles.
9654
+ 18. Lists fill the width at a small size. Input files are `sm-gallery
9655
+ data-size="small"` tiles; many items (shots, scenes, rows) are an
9656
+ `sm-list`, one line each with a thumbnail, one line of text and a short
9657
+ fact, and tapping an item opens all of its fields in place. Extra width
9658
+ means more items per row, never bigger cards.
9659
+ 19. On a phone, chip and segment rows scroll sideways instead of wrapping,
9660
+ long lists show their first three and "N more" (`sm-list data-peek`),
9661
+ and long text shows five lines until tapped (`sm-clamp`).
9662
+ 20. Nothing is lost when a Block gets smaller. Every control stays on the
9663
+ screen, behind an (i), in `sm-more`, or inside the item it belongs to.
9664
+ Compacting moves controls; it never deletes them.
9648
9665
 
9649
9666
  ### 4. What StillMade checks
9650
9667
 
@@ -12191,6 +12208,8 @@ The latest version of each Block bundled with the SDK, generated from the packag
12191
12208
  | `sm.motion-graphics` 2.0.0 | Motion graphics | editor-extension | `timeline` timeline (timeline) · primary; `projectTimeline` timeline (timeline) · project context only; `plan` json (motion_graphics_plan) | `timeline` timeline (timeline) · primary; `edit` workspace-edit (editor_workspace_edit) |
12192
12209
  | `sm.new-items` 1.0.0 | Only new items | task | `items` object (external_data) · primary; `id_field` text (item_id_field) | `item` object (external_data) · primary; `waiting` integer (pending_item_count) |
12193
12210
  | `sm.panel-strip` 2.4.1 | Image Panels | workspace | `panels` panel-document (image_panel_document) · project context only · primary; `transcript` transcript (timed_transcript) · project context only; `script` script (narration_script) · project context only; `narrationScript` script (narration_script); `narrationTiming` transcript (timed_transcript); `blueprint` bible (production_blueprint) · project context only; `updatedPanels` panel-document (image_panel_document); `commit` boolean (apply_changes); `generatedImage` image (image); `targetPanelId` text (panel_id); `attachGeneratedImage` boolean (boolean); `action` text (host_action); `stockQuery` text (stock_query); `generatedImages` image[] (image_list) | `panels` panel-document (image_panel_document) · primary; `edit` workspace-edit (workspace_edit); `stockAction` approval (portable_media_action); `qualityAction` approval (portable_media_action); `renderAction` approval (portable_media_action); `stockAsset` asset (licensed_asset); `stockImage` image (licensed_stock_image); `qualityReport` metadata (quality_report); `generationPlan` metadata (generation_plan); `generateAction` approval (portable_media_action); `generatedImage` image (generated_image); `batchGenerateAction` approval (portable_media_action); `generatedImages` image[] (generated_image_list) |
12211
+ | `sm.photo-notes` 1.0.0 | Photo notes | task | `photos` image[] (photo_set) · primary | `notes` text (photo_notes) · primary |
12212
+ | `sm.pick-photos` 1.0.0 | Pick best photos | task | `photos` image[] (image) · primary; `keep` integer (photo_keep_count); `instruction` text (photo_selection_instruction); `notes` json (photo_notes) | `photos` image[] (image) · primary; `reasons` text (plain_text) |
12194
12213
  | `sm.pipeline` 2.2.5 | Canvas | workspace | `canvas` pipeline (canvas_document) · project context only · primary; `assets` asset[] (project_assets) · project context only; `versions` metadata[] (asset_versions) · project context only; `updatedCanvas` pipeline (canvas_document); `commit` boolean (canvas_commit_intent); `generatedImage` image (generated_image_version); `addGeneratedImage` boolean (attach_generated_image); `generatedImageTitle` text (generated_image_title); `generatedVideo` video (generated_video_version); `addGeneratedVideo` boolean (attach_generated_video); `generatedVideoTitle` text (generated_video_title); `generatedAudio` audio (generated_audio_version); `addGeneratedAudio` boolean (attach_generated_audio); `generatedAudioTitle` text (generated_audio_title); `connectionProposal` json (context_connection_proposal); `applyContextConnections` boolean (context_connection_intent) | `canvas` pipeline (canvas_document) · primary; `edit` workspace-edit (canvas_edit_proposal) |
12195
12214
  | `sm.quality-audit` 1.0.2 | Quality review plan | task | `assets` asset[] (saved_asset_versions) · project context only · primary | `plan` metadata (visual_quality_review_plan) · primary |
12196
12215
  | `sm.research` 2.0.2 | Research | task | `input` text (research_question) · primary; `sourceTitle` text (source_title); `sourceUrl` text (source_url); `sourceNotes` text (source_notes) | `output` research (research_dossier) · primary |
@@ -12307,7 +12326,7 @@ Optional custom view interfaces are supported, but generated manifest.ui control
12307
12326
 
12308
12327
  *When:* StillMade's builder adds this section when the person asks for an interface, preview or controls, or refines a Block that has one.
12309
12328
 
12310
- A custom interface is the optional package-level view:{html,css?,themedCss?,javascript?}; when refining, preserve and refine base.view. Design it by StillMade's interface principles, in order: Function first: unless the person asks for a design direction, build from the Block kit (`sm-block`, `sm-stage`, `sm-choices`, `sm-actions`, `sm-more`) and ship little or no CSS of your own. A direction the person names wins over the kit. Show the thing being made: the preview, media or result gets the largest area (`sm-stage`). Never a JSON dump, source editor, manifest or diagnostic panel unless the task is about source. One obvious next action (`sm-primary`); peers are quiet buttons or named icons. Seven or fewer choices in view. The action button names what it does ("Write", "Generate image", "Make video"), never "Run", "Run step", "Submit" or "Review cost". Show no credit numbers: StillMade puts the price beside the verb on its own run button ("Write · 1 credit"), with a chip for the model, quality or count when they can change. Pressing it runs at that price; a confirmation appears only when the server price is higher. Pictures over words: choices people see or hear are thumbnails, swatches, samples or glyphs (`sm-choices`), not word lists. Icons carry an accessible name and tooltip; never emoji. Words only when needed. Drop what nobody needs to finish the task (intros, "how it works", restating the Block name). Words that might help start collapsed (`sm-hint`, `sm-more`). Errors, spending approvals, stale inputs and destructive steps stay visible, in few words. Strong defaults; secondary settings go in `sm-more`, closed. Compact: the whole Block fits one laptop screen without scrolling. A short setting is one row, its label beside the control; no card around a single control. Status is a dot or a few words ("No narration yet"), never a paragraph; the reason sits behind an `sm-hint`. Files are tiles: a saved file is a thumbnail or chip and adding one is a + tile. Never the bare browser file picker, and no size limits in view until a file is too big. Rare tools (update, schedule, history, reload) are named icon buttons beside the action, never sections under the work. An (i) beside anything a newcomer could misread: a setting, status or number whose effect is not obvious from its label gets a closed `sm-hint` with one or two sentences. Give every input that needs one a `description`; StillMade shows it as that (i). Obvious controls get none. One workspace: no cards inside cards, no second title, step counter or Back/Next bar; the host owns navigation. Status sits beside the action it describes (`sm-status`), in a few words. Keep the page in normal scroll flow; no sticky media or control strips unless the editing task needs them. Use the width: from 860px wide the kit puts the controls on the left at a reading width (300–380px) and the result (`sm-stage`) fills the right, in its real shape; under that everything stacks with the result first and the action within reach. Extra width goes to the result, never to wider text fields. Before there is a result, the stage previews what will be made from the inputs. `data-layout="stack"` opts out. Text scene descriptions are planning notes, never a storyboard or an approved frame. Its DOM controller is separate from manifest runtime code. The view may also declare appearance:"original" or "host". For an imported design, preserve its colors with appearance:"original" and view.css; no themed replacement is required. Preserve base.view.appearance when refining unless the user requests a change. Omitted/host appearance retains the existing Light, Dark and White requirement: supply semantic colors in view.css or a complete replacement view.themedCss. An original-style view may optionally supply valid themedCss for a StillMade appearance preview. Use StillMade variables (--bg,--fg,--fg-muted,--border-tok,--r-3) only when opting into host styling; do not redefine host tokens in the themed variant. Appearance never relaxes sandbox constraints: no CSS escapes/filters/blending, imports/url(), or element.style mutations in JS. Use classes for UI state; media pixels retain their colors. Both CSS fields have the same 32 KiB limit; all existing shared-state, security and permission checks still apply. Declare elements in html, bind with document.getElementById/querySelector and addEventListener; use literal property access, array methods, textContent, input.value, button.disabled and canvas. Initial values: StillMade.onInput(values=>{...}); await StillMade.run(inputBindings) returns validated output bindings from the isolated package runtime; catch errors and show results. No computation in the DOM controller; put it in code/recipe. Disable the action button while pending.
12329
+ A custom interface is the optional package-level view:{html,css?,themedCss?,javascript?}; when refining, preserve and refine base.view. Design it by StillMade's interface principles, in order: Function first: unless the person asks for a design direction, build from the Block kit (`sm-block`, `sm-stage`, `sm-choices`, `sm-actions`, `sm-more`) and ship little or no CSS of your own. A direction the person names wins over the kit. Show the thing being made: the preview, media or result gets the largest area (`sm-stage`). Never a JSON dump, source editor, manifest or diagnostic panel unless the task is about source. One obvious next action (`sm-primary`); peers are quiet buttons or named icons. Seven or fewer choices in view. The action button names what it does ("Write", "Generate image", "Make video"), never "Run", "Run step", "Submit" or "Review cost". Show no credit numbers: StillMade puts the price beside the verb on its own run button ("Write · 1 credit"), with a chip for the model, quality or count when they can change. Pressing it runs at that price; a confirmation appears only when the server price is higher. Pictures over words: choices people see or hear are thumbnails, swatches, samples or glyphs (`sm-choices`), not word lists. Icons carry an accessible name and tooltip; never emoji. Words only when needed. Drop what nobody needs to finish the task (intros, "how it works", restating the Block name). Words that might help start collapsed (`sm-hint`, `sm-more`). Errors, spending approvals, stale inputs and destructive steps stay visible, in few words. Strong defaults; secondary settings go in `sm-more`, closed. Compact: the whole Block fits one laptop screen without scrolling. A short setting is one row, its label beside the control; no card around a single control. Status is a dot or a few words ("No narration yet"), never a paragraph; the reason sits behind an `sm-hint`. Files are tiles: a saved file is a thumbnail or chip and adding one is a + tile. Never the bare browser file picker, and no size limits in view until a file is too big. Rare tools (update, schedule, history, reload) are named icon buttons beside the action, never sections under the work. An (i) beside anything a newcomer could misread: a setting, status or number whose effect is not obvious from its label gets a closed `sm-hint` with one or two sentences. Give every input that needs one a `description`; StillMade shows it as that (i). Obvious controls get none. One workspace: no cards inside cards, no second title, step counter or Back/Next bar; the host owns navigation. Status sits beside the action it describes (`sm-status`), in a few words. Keep the page in normal scroll flow; no sticky media or control strips unless the editing task needs them. Use the width: from 860px wide the kit puts the controls on the left at a reading width (300–380px) and the result (`sm-stage`) fills the right, in its real shape; under that everything stacks with the result first and the action within reach. Extra width goes to the result, never to wider text fields. Before there is a result, the stage previews what will be made from the inputs. `data-layout="stack"` opts out. Settings sit side by side (`sm-settings`), next to what they change. Three or four short options are one segmented row (`data-segmented`), not a row of big tiles. Lists fill the width at a small size: input files are small tiles (`sm-gallery data-size="small"`), many items are one line each (`sm-list`): a thumbnail, one line of text, a short fact. Tapping an item opens all of its fields in place. Extra width means more items per row, never bigger cards. On a phone chip and segment rows scroll sideways instead of wrapping; long lists show their first three with "N more" (`data-peek`) and long text five lines until tapped (`sm-clamp`). Nothing is lost when a Block gets smaller: every control stays on the screen, behind an (i), in `sm-more`, or inside the item it belongs to. Compacting moves controls; it never deletes them. Text scene descriptions are planning notes, never a storyboard or an approved frame. Its DOM controller is separate from manifest runtime code. The view may also declare appearance:"original" or "host". For an imported design, preserve its colors with appearance:"original" and view.css; no themed replacement is required. Preserve base.view.appearance when refining unless the user requests a change. Omitted/host appearance retains the existing Light, Dark and White requirement: supply semantic colors in view.css or a complete replacement view.themedCss. An original-style view may optionally supply valid themedCss for a StillMade appearance preview. Use StillMade variables (--bg,--fg,--fg-muted,--border-tok,--r-3) only when opting into host styling; do not redefine host tokens in the themed variant. Appearance never relaxes sandbox constraints: no CSS escapes/filters/blending, imports/url(), or element.style mutations in JS. Use classes for UI state; media pixels retain their colors. Both CSS fields have the same 32 KiB limit; all existing shared-state, security and permission checks still apply. Declare elements in html, bind with document.getElementById/querySelector and addEventListener; use literal property access, array methods, textContent, input.value, button.disabled and canvas. Initial values: StillMade.onInput(values=>{...}); await StillMade.run(inputBindings) returns validated output bindings from the isolated package runtime; catch errors and show results. No computation in the DOM controller; put it in code/recipe. Disable the action button while pending.
12311
12330
  Standard custom view code (no `view.config.json` frame runtime) is checked before it runs. These rules come straight from the validator; frame views run in their own sandbox and may build the page with ordinary DOM calls such as `createElement`:
12312
12331
 
12313
12332
  - **HTML elements:** only `div`, `section`, `article`, `header`, `footer`, `main`, `aside`, `nav`, `h1`, `h2`, `h3`, `h4`, `p`, `span`, `strong`, `em`, `i`, `small`, `br`, `hr`, `label`, `input`, `textarea`, `button`, `select`, `option`, `optgroup`, `fieldset`, `legend`, `output`, `progress`, `meter`, `ul`, `ol`, `li`, `dl`, `dt`, `dd`, `figure`, `figcaption`, `img`, `video`, `audio`, `source`, `canvas`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th`, `td`, `pre`, `code`, `details`, `summary`. No scripts, iframes, SVG, forms, comments or inline event attributes; media URLs must be `data:` or `blob:`.
package/UI_AESTHETIC.md CHANGED
@@ -224,6 +224,16 @@ before/after examples from an Image Panels project (Voiceover 1,210 px to about
224
224
  the right side previews what will be made from the inputs. Under 860 px it is
225
225
  one elastic column, result first, with the action pinned to the bottom on a
226
226
  phone. Mockup: `docs/ui-review/wide-step-layout.html`.
227
+ - Settings sit side by side next to what they change (a grid of short
228
+ segmented controls, not rows of big tiles). Lists fill the width at a small
229
+ size: photos are small tiles, shots are one line each and open in place.
230
+ On a phone, choice rows scroll sideways, long lists show the first few and
231
+ "6 more", long text shows five lines. Kit: `sm-settings`,
232
+ `sm-choices[data-segmented]`, `sm-gallery[data-size="small"]`, `sm-list`,
233
+ `sm-clamp`.
234
+ - Nothing is lost when a screen gets smaller: every control stays, behind an
235
+ (i), in a one-tap menu, or inside the item it belongs to. The dealership
236
+ Steps with every control accounted for: `docs/ui-review/wide-steps.html`.
227
237
  - Mockups: `docs/ui-review/compact-principles.html`.
228
238
 
229
239
  ## Icon preference
@@ -0,0 +1,180 @@
1
+ // Generated by scripts/build-owned-blocks.mjs. Edit the owned source files.
2
+ export default {
3
+ "manifest": {
4
+ "schemaVersion": 1,
5
+ "sdkVersion": "0.1.0",
6
+ "id": "sm.photo-notes",
7
+ "version": "1.0.0",
8
+ "name": "Photo notes",
9
+ "description": "Rate up to four owned photos for sharpness, light, people and faces through StillMade's approved vision capability, one line per photo.",
10
+ "kind": "task",
11
+ "runtime": "capability",
12
+ "entry": "src/capability.json",
13
+ "license": "MIT",
14
+ "provenance": {
15
+ "notice": "Original source (authorship declared by the packager)\nLicense: MIT\nChanges: Original implementation declared by the packager; no reused repository or dependency code.\nFiles: LICENSE, src/capability.json\n\nMIT License\n\nCopyright (c) 2026 StillMade contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n",
16
+ "portableSources": [
17
+ {
18
+ "kind": "original",
19
+ "license": "MIT",
20
+ "paths": [
21
+ "LICENSE",
22
+ "src/capability.json"
23
+ ],
24
+ "evidence": [
25
+ "upstream/0/LICENSE",
26
+ "upstream/0/src/capability.json"
27
+ ],
28
+ "changes": "Original implementation declared by the packager; no reused repository or dependency code."
29
+ }
30
+ ]
31
+ },
32
+ "inputs": {
33
+ "photos": {
34
+ "type": "image[]",
35
+ "primary": true,
36
+ "description": "One to four persistent photos from the user's StillMade library.",
37
+ "semantic": "photo_set",
38
+ "required": true
39
+ }
40
+ },
41
+ "outputs": {
42
+ "notes": {
43
+ "type": "text",
44
+ "primary": true,
45
+ "description": "One line per photo, in order: sharpness, light, people, faces, smiles, closed eyes, tags and a short description.",
46
+ "semantic": "photo_notes"
47
+ }
48
+ },
49
+ "permissions": {
50
+ "project": [],
51
+ "capabilities": [
52
+ "image.describe"
53
+ ],
54
+ "network": [],
55
+ "filesystem": [],
56
+ "secrets": []
57
+ },
58
+ "ui": [
59
+ {
60
+ "port": "photos",
61
+ "control": "asset"
62
+ }
63
+ ],
64
+ "platforms": {
65
+ "phone": {
66
+ "supported": true
67
+ },
68
+ "browser": {
69
+ "supported": true
70
+ },
71
+ "desktop": {
72
+ "supported": true
73
+ }
74
+ }
75
+ },
76
+ "capability": {
77
+ "schemaVersion": 1,
78
+ "operation": "image.describe",
79
+ "image": {
80
+ "$input": "photos"
81
+ },
82
+ "instruction": "Rate each supplied photo, in the order given, so a person can choose the best photos for a video. Return exactly one line per photo and nothing else, in this format:\nPhoto 1 | sharp 8 | light 7 | people 2 | faces clear yes | smiling yes | eyes closed no | tags: beach, family, sunset | Two people laughing on a beach at sunset.\nsharp is focus and blur from 0 (unusable) to 10 (crisp). light is exposure and color from 0 (too dark or blown out) to 10 (well lit). people is how many people are clearly visible. faces clear is yes when at least one face is visible and in focus. smiling is yes when a visible person smiles or laughs. eyes closed is yes when the main person blinks. tags are up to six plain lowercase words for the subject, setting, occasion and mood. End with one short plain sentence describing only what is visible. Never identify a real person by name, never guess age, ethnicity, health or other sensitive traits, and never invent anything outside the frame.",
83
+ "maxTokens": 700,
84
+ "output": "notes"
85
+ },
86
+ "tests": [
87
+ {
88
+ "name": "One blue photo",
89
+ "input": {
90
+ "photos": [
91
+ {
92
+ "width": 1,
93
+ "height": 1,
94
+ "data": [
95
+ 20,
96
+ 80,
97
+ 200,
98
+ 255
99
+ ]
100
+ }
101
+ ]
102
+ },
103
+ "expectations": {
104
+ "notes": {
105
+ "kind": "text",
106
+ "minLength": 20,
107
+ "maxLength": 32768,
108
+ "includes": [
109
+ "Photo 1"
110
+ ]
111
+ }
112
+ }
113
+ },
114
+ {
115
+ "name": "Two plain photos",
116
+ "input": {
117
+ "photos": [
118
+ {
119
+ "width": 1,
120
+ "height": 1,
121
+ "data": [
122
+ 128,
123
+ 128,
124
+ 128,
125
+ 255
126
+ ]
127
+ },
128
+ {
129
+ "width": 1,
130
+ "height": 1,
131
+ "data": [
132
+ 240,
133
+ 200,
134
+ 40,
135
+ 255
136
+ ]
137
+ }
138
+ ]
139
+ },
140
+ "expectations": {
141
+ "notes": {
142
+ "kind": "text",
143
+ "minLength": 40,
144
+ "maxLength": 32768,
145
+ "includes": [
146
+ "Photo 1",
147
+ "Photo 2"
148
+ ]
149
+ }
150
+ }
151
+ }
152
+ ],
153
+ "portable": {
154
+ "format": "stillmade-block/1",
155
+ "dependencies": [],
156
+ "sources": [
157
+ {
158
+ "kind": "original",
159
+ "license": "MIT",
160
+ "paths": [
161
+ "LICENSE",
162
+ "src/capability.json"
163
+ ],
164
+ "evidence": [
165
+ "upstream/0/LICENSE",
166
+ "upstream/0/src/capability.json"
167
+ ],
168
+ "changes": "Original implementation declared by the packager; no reused repository or dependency code."
169
+ }
170
+ ],
171
+ "files": {
172
+ "upstream/0/LICENSE": "MIT License\n\nCopyright (c) 2026 StillMade contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n",
173
+ "upstream/0/src/capability.json": "{\n \"schemaVersion\": 1,\n \"operation\": \"image.describe\",\n \"image\": {\n \"$input\": \"photos\"\n },\n \"instruction\": \"Rate each supplied photo, in the order given, so a person can choose the best photos for a video. Return exactly one line per photo and nothing else, in this format:\\nPhoto 1 | sharp 8 | light 7 | people 2 | faces clear yes | smiling yes | eyes closed no | tags: beach, family, sunset | Two people laughing on a beach at sunset.\\nsharp is focus and blur from 0 (unusable) to 10 (crisp). light is exposure and color from 0 (too dark or blown out) to 10 (well lit). people is how many people are clearly visible. faces clear is yes when at least one face is visible and in focus. smiling is yes when a visible person smiles or laughs. eyes closed is yes when the main person blinks. tags are up to six plain lowercase words for the subject, setting, occasion and mood. End with one short plain sentence describing only what is visible. Never identify a real person by name, never guess age, ethnicity, health or other sensitive traits, and never invent anything outside the frame.\",\n \"maxTokens\": 700,\n \"output\": \"notes\"\n}"
174
+ },
175
+ "lineage": {
176
+ "parents": [],
177
+ "changes": "Packaged original Block source for StillMade."
178
+ }
179
+ }
180
+ };