stillmade-sdk 0.1.19 → 0.1.21
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 +1 -1
- package/INTERFACE_DESIGN.md +11 -2
- package/PASTE_TO_LLM.md +5 -1
- package/SDK.md +21 -4
- package/package.json +1 -1
- package/packages/block-sdk/builder-contract.js +1 -1
- package/packages/block-sdk/view-design.js +70 -2
- package/packages/design-system/block-kit.css +15 -6
package/AGENTS.md
CHANGED
|
@@ -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. 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.
|
|
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, each label beside its control (`sm-field`, `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
|
|
package/INTERFACE_DESIGN.md
CHANGED
|
@@ -58,8 +58,8 @@ piece in Light, Dark and White.
|
|
|
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
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
|
-
| `sm-field`, `sm-fields` |
|
|
62
|
-
| `sm-settings` | Short settings side by side, each label
|
|
61
|
+
| `sm-field`, `sm-fields` | One short setting on one row, its label beside the control; a responsive group of them. On a phone the control wraps under its label only when both do not fit. A textarea, picture choices, file tiles or a list keep the label above. |
|
|
62
|
+
| `sm-settings` | Short settings side by side, each label beside its control; a narrow cell wraps the control under its label. |
|
|
63
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
64
|
| `sm-clamp` | Long text that shows five lines on a phone until it gets `data-open`. |
|
|
65
65
|
| `sm-actions` | One `sm-primary`, then `sm-quiet` buttons and `sm-icon` buttons (each with `aria-label` and `title`). |
|
|
@@ -175,6 +175,15 @@ exception, never unrelated technical UI.
|
|
|
175
175
|
ungrouped options, more than one `h1`, a visible paragraph over twenty words,
|
|
176
176
|
a word dropdown for something people see or hear, a bare browser file
|
|
177
177
|
picker, and a size limit printed in view.
|
|
178
|
+
- Admission warns about the compact rules it can see in the source: a short
|
|
179
|
+
input or select whose label sits above it outside `sm-field` / `sm-settings`
|
|
180
|
+
(a `<br>` between them, or a label made `display: block`); a heading,
|
|
181
|
+
legend or `<details>` summary titled Update, Schedule, History, Reload or
|
|
182
|
+
Versions, which should be an icon button beside the action; and more than
|
|
183
|
+
eight visible top-level rows besides the stage. The row count is an estimate:
|
|
184
|
+
a static check cannot measure height. StillMade's builder preview measures the
|
|
185
|
+
real one and says when the view is taller than one laptop screen (720px) at
|
|
186
|
+
the Desktop size.
|
|
178
187
|
- Admission also warns, and `stillmade-block ready` fails the "UI works" check
|
|
179
188
|
(DOD-15), when a button says "Run", "Run step" or "Submit", when the
|
|
180
189
|
interface shows a credit price, or when it has a page heading
|
package/PASTE_TO_LLM.md
CHANGED
|
@@ -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. 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.
|
|
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, each label beside its control (`sm-field`, `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
|
|
|
@@ -200,6 +200,10 @@ For Editor changes return a primary output {type:"timeline-edit"} and declare "t
|
|
|
200
200
|
|
|
201
201
|
Write the description in third-grade language: one short sentence, ideally 8–14 words and never more than 20. Use common words and say what the person can make or do. Start with an action. Leave out technical terms such as typed ports, scoped context, artifacts, pipeline, runtime, and handoff. Do not list every feature, repeat the name, add marketing claims, or say this Block lets you. Keep essential limits and describe only what the code actually does. For example: Cut clips, add sound and text, then save your video. Apply these No AI Slop editing rules to the description prose only; keep the required response format, code, and identifiers intact. Write for a person choosing a Block or Project Type. Use familiar words, direct verbs, and details supported by the saved code. Preserve useful limits and clear existing sentences. Use “version” or “saved version” instead of “release”; use “Public”, “Private” and “Draft” for visibility and readiness. Call release notes “What changed”. Check each sentence: could it describe almost any app? If so, replace it with a specific supported action or remove it. Never invent examples, numbers, features, reviews, or results to sound more specific. Cut hype, vague benefits, dramatic reveals, fake expert claims, rhetorical questions, introductions that delay the point, and closing lines that repeat the paragraph. Avoid phrases such as game changer, cutting-edge, unlock your potential, seamless, powerful solution, leverage, empower, streamline, and elevate. Say what the person can do. State the useful fact directly instead of using not-X-but-Y contrasts. Use complete sentences, with no decorative dashes, emoji, or emphasis. Keep names consistent; do not cycle through synonyms for a Block. Avoid repeated sentence shapes and forcing every listing into an identical template. Use search terms only where they describe the real task. Do not repeat keywords or stretch the copy to hit a word or sentence count. Before returning the copy, reread it for factual accuracy, simple language, specific detail, natural rhythm, and filler. Fix any failures silently and return only the requested output.
|
|
202
202
|
|
|
203
|
+
### Compact interface
|
|
204
|
+
|
|
205
|
+
Every Block interface, generated or custom, follows StillMade's compact rules: 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. 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. 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. StillMade draws generated manifest.ui controls this way itself (label beside control, files as tiles, the result filling the right on wide screens); you supply at most four inputs that matter in view, sensible defaults, and a short `description` on every input whose effect is not obvious from its name, which StillMade shows as its (i).
|
|
206
|
+
|
|
203
207
|
### Generated controls first
|
|
204
208
|
|
|
205
209
|
*When:* StillMade's builder adds this section when the person did not ask for a custom interface.
|
package/SDK.md
CHANGED
|
@@ -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. 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.
|
|
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, each label beside its control (`sm-field`, `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
|
|
|
@@ -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. 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.
|
|
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, each label beside its control (`sm-field`, `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
|
|
|
@@ -7422,6 +7422,10 @@ For Editor changes return a primary output {type:"timeline-edit"} and declare "t
|
|
|
7422
7422
|
|
|
7423
7423
|
Write the description in third-grade language: one short sentence, ideally 8–14 words and never more than 20. Use common words and say what the person can make or do. Start with an action. Leave out technical terms such as typed ports, scoped context, artifacts, pipeline, runtime, and handoff. Do not list every feature, repeat the name, add marketing claims, or say this Block lets you. Keep essential limits and describe only what the code actually does. For example: Cut clips, add sound and text, then save your video. Apply these No AI Slop editing rules to the description prose only; keep the required response format, code, and identifiers intact. Write for a person choosing a Block or Project Type. Use familiar words, direct verbs, and details supported by the saved code. Preserve useful limits and clear existing sentences. Use “version” or “saved version” instead of “release”; use “Public”, “Private” and “Draft” for visibility and readiness. Call release notes “What changed”. Check each sentence: could it describe almost any app? If so, replace it with a specific supported action or remove it. Never invent examples, numbers, features, reviews, or results to sound more specific. Cut hype, vague benefits, dramatic reveals, fake expert claims, rhetorical questions, introductions that delay the point, and closing lines that repeat the paragraph. Avoid phrases such as game changer, cutting-edge, unlock your potential, seamless, powerful solution, leverage, empower, streamline, and elevate. Say what the person can do. State the useful fact directly instead of using not-X-but-Y contrasts. Use complete sentences, with no decorative dashes, emoji, or emphasis. Keep names consistent; do not cycle through synonyms for a Block. Avoid repeated sentence shapes and forcing every listing into an identical template. Use search terms only where they describe the real task. Do not repeat keywords or stretch the copy to hit a word or sentence count. Before returning the copy, reread it for factual accuracy, simple language, specific detail, natural rhythm, and filler. Fix any failures silently and return only the requested output.
|
|
7424
7424
|
|
|
7425
|
+
### Compact interface
|
|
7426
|
+
|
|
7427
|
+
Every Block interface, generated or custom, follows StillMade's compact rules: 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. 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. 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. StillMade draws generated manifest.ui controls this way itself (label beside control, files as tiles, the result filling the right on wide screens); you supply at most four inputs that matter in view, sensible defaults, and a short `description` on every input whose effect is not obvious from its name, which StillMade shows as its (i).
|
|
7428
|
+
|
|
7425
7429
|
### Generated controls first
|
|
7426
7430
|
|
|
7427
7431
|
*When:* StillMade's builder adds this section when the person did not ask for a custom interface.
|
|
@@ -9555,8 +9559,8 @@ piece in Light, Dark and White.
|
|
|
9555
9559
|
| `sm-stage` | The thing being made: preview, media or result. `data-ratio="16:9"`, `"9:16"` or `"1:1"`. |
|
|
9556
9560
|
| `sm-empty` | An empty stage: a glyph, at most five words, one action. |
|
|
9557
9561
|
| `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
|
-
| `sm-field`, `sm-fields` |
|
|
9559
|
-
| `sm-settings` | Short settings side by side, each label
|
|
9562
|
+
| `sm-field`, `sm-fields` | One short setting on one row, its label beside the control; a responsive group of them. On a phone the control wraps under its label only when both do not fit. A textarea, picture choices, file tiles or a list keep the label above. |
|
|
9563
|
+
| `sm-settings` | Short settings side by side, each label beside its control; a narrow cell wraps the control under its label. |
|
|
9560
9564
|
| `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
9565
|
| `sm-clamp` | Long text that shows five lines on a phone until it gets `data-open`. |
|
|
9562
9566
|
| `sm-actions` | One `sm-primary`, then `sm-quiet` buttons and `sm-icon` buttons (each with `aria-label` and `title`). |
|
|
@@ -9672,6 +9676,15 @@ exception, never unrelated technical UI.
|
|
|
9672
9676
|
ungrouped options, more than one `h1`, a visible paragraph over twenty words,
|
|
9673
9677
|
a word dropdown for something people see or hear, a bare browser file
|
|
9674
9678
|
picker, and a size limit printed in view.
|
|
9679
|
+
- Admission warns about the compact rules it can see in the source: a short
|
|
9680
|
+
input or select whose label sits above it outside `sm-field` / `sm-settings`
|
|
9681
|
+
(a `<br>` between them, or a label made `display: block`); a heading,
|
|
9682
|
+
legend or `<details>` summary titled Update, Schedule, History, Reload or
|
|
9683
|
+
Versions, which should be an icon button beside the action; and more than
|
|
9684
|
+
eight visible top-level rows besides the stage. The row count is an estimate:
|
|
9685
|
+
a static check cannot measure height. StillMade's builder preview measures the
|
|
9686
|
+
real one and says when the view is taller than one laptop screen (720px) at
|
|
9687
|
+
the Desktop size.
|
|
9675
9688
|
- Admission also warns, and `stillmade-block ready` fails the "UI works" check
|
|
9676
9689
|
(DOD-15), when a button says "Run", "Run step" or "Submit", when the
|
|
9677
9690
|
interface shows a credit price, or when it has a page heading
|
|
@@ -12327,6 +12340,10 @@ For Editor changes return a primary output {type:"timeline-edit"} and declare "t
|
|
|
12327
12340
|
|
|
12328
12341
|
Write the description in third-grade language: one short sentence, ideally 8–14 words and never more than 20. Use common words and say what the person can make or do. Start with an action. Leave out technical terms such as typed ports, scoped context, artifacts, pipeline, runtime, and handoff. Do not list every feature, repeat the name, add marketing claims, or say this Block lets you. Keep essential limits and describe only what the code actually does. For example: Cut clips, add sound and text, then save your video. Apply these No AI Slop editing rules to the description prose only; keep the required response format, code, and identifiers intact. Write for a person choosing a Block or Project Type. Use familiar words, direct verbs, and details supported by the saved code. Preserve useful limits and clear existing sentences. Use “version” or “saved version” instead of “release”; use “Public”, “Private” and “Draft” for visibility and readiness. Call release notes “What changed”. Check each sentence: could it describe almost any app? If so, replace it with a specific supported action or remove it. Never invent examples, numbers, features, reviews, or results to sound more specific. Cut hype, vague benefits, dramatic reveals, fake expert claims, rhetorical questions, introductions that delay the point, and closing lines that repeat the paragraph. Avoid phrases such as game changer, cutting-edge, unlock your potential, seamless, powerful solution, leverage, empower, streamline, and elevate. Say what the person can do. State the useful fact directly instead of using not-X-but-Y contrasts. Use complete sentences, with no decorative dashes, emoji, or emphasis. Keep names consistent; do not cycle through synonyms for a Block. Avoid repeated sentence shapes and forcing every listing into an identical template. Use search terms only where they describe the real task. Do not repeat keywords or stretch the copy to hit a word or sentence count. Before returning the copy, reread it for factual accuracy, simple language, specific detail, natural rhythm, and filler. Fix any failures silently and return only the requested output.
|
|
12329
12342
|
|
|
12343
|
+
### Compact interface
|
|
12344
|
+
|
|
12345
|
+
Every Block interface, generated or custom, follows StillMade's compact rules: 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. 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. 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. StillMade draws generated manifest.ui controls this way itself (label beside control, files as tiles, the result filling the right on wide screens); you supply at most four inputs that matter in view, sensible defaults, and a short `description` on every input whose effect is not obvious from its name, which StillMade shows as its (i).
|
|
12346
|
+
|
|
12330
12347
|
### Generated controls first
|
|
12331
12348
|
|
|
12332
12349
|
*When:* StillMade's builder adds this section when the person did not ask for a custom interface.
|
package/package.json
CHANGED
|
@@ -57,7 +57,7 @@ const SECTIONS=Object.freeze([
|
|
|
57
57
|
`Give the Block a short, plain name of ${BLOCK_NAME_MAX_LENGTH} characters or fewer that says what it does ("Captioned Clip", not "Captioned Business Clip Generator With Review"). The name appears in step bars, Project Type cards and pickers, so put the detail in the description instead. New releases with a longer name do not pass readiness.`),
|
|
58
58
|
rule('ui','block',
|
|
59
59
|
'Prefer `manifest.ui`; custom views use the Block kit (`sm-*` classes) unless a look is named. Pictures over words: preview each option before choosing; cut needless words, fold the rest; the start button names the action (never "Run") and shows no price (StillMade adds it); fit one screen unscrolled and a 320px phone.',
|
|
60
|
-
'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.'),
|
|
60
|
+
'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, each label beside its control (`sm-field`, `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.'),
|
|
61
61
|
rule('multiplayer','block',
|
|
62
62
|
'Custom views share edits: `StillMade.onShared`, publish every editable field (`data-stillmade-share`, `bindShared`, `updateShared`), respect `canEdit`, never re-run on remote updates.',
|
|
63
63
|
'Projects are multiplayer. A custom view subscribes through `StillMade.onShared(callback)` and publishes every editable field: give static controls a unique `id` and `data-stillmade-share="field"` (the host owns their synchronization), use `StillMade.bindShared(field, elementId)` for controls created dynamically, and `StillMade.updateShared(values, before, options)` for structured values; private variables and DOM values are not shared. Mark a truly device-only control (playback, hover, device selection) with `data-stillmade-local`. Observe shared outputs as well as state, honor `canEdit` in every mutating callback (read-only participants cannot write), never run, click or call a paid integration in response to a remote update, and preserve conflicting drafts. Shared background work uses `sharedWork` with the `work.shared` permission.'),
|
|
@@ -12,8 +12,8 @@ export const BLOCK_KIT_CLASSES=Object.freeze({
|
|
|
12
12
|
'sm-stage':'The thing being made: preview, media or result. The biggest area; data-ratio="16:9|9:16|1:1".',
|
|
13
13
|
'sm-empty':'What an empty stage shows: an .sm-glyph, at most five words and one action.',
|
|
14
14
|
'sm-choices':'A fieldset of radio labels shown as pictures (img, .sm-swatch or .sm-glyph) and one or two words; replaces word dropdowns. data-compact for short text chips, data-segmented for one connected row (Low / Med / High). On a phone chips and segments scroll sideways.',
|
|
15
|
-
'sm-field':'
|
|
16
|
-
'sm-settings':'Short settings side by side, each label
|
|
15
|
+
'sm-field':'One short setting on one row, its label beside the control; on a phone the control wraps under the label only when both do not fit. A textarea, picture choices, file tiles or a list keep the label above. Group several in .sm-fields.',
|
|
16
|
+
'sm-settings':'Short settings side by side, each label beside its control (a narrow cell wraps the control under its label); .sm-choices[data-segmented] inside for three or four short options.',
|
|
17
17
|
'sm-list':'Many items one line each (thumbnail, one line of text, a short fact); an item opens in place with <details>. data-peek shows three on a phone.',
|
|
18
18
|
'sm-clamp':'Long text that shows five lines on a phone until opened (data-open).',
|
|
19
19
|
'sm-actions':'The action row: one .sm-primary, optional .sm-quiet buttons and .sm-icon buttons (aria-label and title required).',
|
|
@@ -48,6 +48,9 @@ export const BLOCK_INTERFACE_PRINCIPLES=Object.freeze([
|
|
|
48
48
|
'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.',
|
|
49
49
|
'Text scene descriptions are planning notes, never a storyboard or an approved frame.',
|
|
50
50
|
]);
|
|
51
|
+
// The compact layout rules (October 18–19, 2026), for every Block interface,
|
|
52
|
+
// generated or custom. StillMade's in-app builders and the SDK guide both read them.
|
|
53
|
+
export const COMPACT_INTERFACE_RULES=Object.freeze(BLOCK_INTERFACE_PRINCIPLES.filter(rule=>/^(?:Compact:|Status is|Files are tiles|An \(i\)|Use the width)/.test(rule)));
|
|
51
54
|
// Compatibility names for existing consumers.
|
|
52
55
|
export const INTERFACE_DESIGN_CONVENTIONS=BLOCK_INTERFACE_PRINCIPLES;
|
|
53
56
|
export const INTERFACE_DESIGN_PRINCIPLES=BLOCK_INTERFACE_PRINCIPLES;
|
|
@@ -71,6 +74,66 @@ function bareFilePicker(html){
|
|
|
71
74
|
return false;
|
|
72
75
|
}
|
|
73
76
|
const words=text=>text.replace(/<[^>]*>/g,' ').trim().split(/\s+/).filter(Boolean).length;
|
|
77
|
+
const SHORT_CONTROL=/^<(?:select\b|input\b(?![^>]*\btype\s*=\s*["']?(?:file|hidden|checkbox|radio|range|submit|button|image|reset)\b))/;
|
|
78
|
+
const ROW_CLASSES=/\bsm-(?:field|fields|settings|label|row|choices)\b/;
|
|
79
|
+
const afterBreak=text=>text.replace(/^<br\s*\/?>\s*/,'');
|
|
80
|
+
// A short control (a text-like input or a select) whose label sits above it outside the kit's
|
|
81
|
+
// one-row fields: a <br> between them, a label styled display:block right before the control,
|
|
82
|
+
// or the Block's CSS making every label a block. Conservative: a label inside or just after
|
|
83
|
+
// sm-field / sm-settings markup is skipped. One forward scan; every search is bounded.
|
|
84
|
+
function stackedLabel(html,css){
|
|
85
|
+
const lower=html.toLowerCase();
|
|
86
|
+
let blockLabels=false;
|
|
87
|
+
for(const rule of String(css||'').toLowerCase().split('}')){
|
|
88
|
+
const open=rule.indexOf('{');if(open===-1)continue;
|
|
89
|
+
if(rule.slice(0,open).split(',').some(selector=>/(?:^|\s)label$/.test(selector.trim()))&&/display\s*:\s*block\b/.test(rule.slice(open)))blockLabels=true;
|
|
90
|
+
}
|
|
91
|
+
for(let at=lower.indexOf('<label');at!==-1;at=lower.indexOf('<label',at+6)){
|
|
92
|
+
if(ROW_CLASSES.test(lower.slice(Math.max(0,at-240),at)))continue;
|
|
93
|
+
const tagEnd=lower.indexOf('>',at);if(tagEnd===-1)return false;
|
|
94
|
+
const close=lower.slice(tagEnd,tagEnd+400).indexOf('</label>');if(close===-1)continue;
|
|
95
|
+
const tag=lower.slice(at,tagEnd),inner=lower.slice(tagEnd+1,tagEnd+close),after=lower.slice(tagEnd+close+8,tagEnd+close+408).trimStart();
|
|
96
|
+
const brInside=inner.indexOf('<br');
|
|
97
|
+
if(brInside!==-1&&SHORT_CONTROL.test(afterBreak(inner.slice(brInside))))return true;
|
|
98
|
+
if(/^<br\b/.test(after)&&SHORT_CONTROL.test(afterBreak(after)))return true;
|
|
99
|
+
if((blockLabels||/\bstyle\s*=\s*["'][^"']*display\s*:\s*block/.test(tag))&&SHORT_CONTROL.test(after))return true;
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
// Rare tools named as their own section: a heading, legend or <details> summary titled
|
|
104
|
+
// Update / Schedule / History / Reload / Versions.
|
|
105
|
+
const RARE_TOOL=/^(?:update|updates|schedule|scheduling|history|reload|versions?|version history|run history|past runs|check for updates)$/i;
|
|
106
|
+
function rareToolSection(html){
|
|
107
|
+
const lower=html.toLowerCase();
|
|
108
|
+
for(let at=lower.indexOf('<');at!==-1;at=lower.indexOf('<',at+1)){
|
|
109
|
+
const name=/^<(h[1-6]|summary|legend)\b/.exec(lower.slice(at,at+9));if(!name)continue;
|
|
110
|
+
const near=lower.slice(at,at+300),open=near.indexOf('>'),close=near.indexOf('</'+name[1]);
|
|
111
|
+
if(open===-1||close<open)continue;
|
|
112
|
+
const text=html.slice(at+open+1,at+close).replace(/<[^<>]*>/g,' ').replace(/\s+/g,' ').trim();
|
|
113
|
+
if(RARE_TOOL.test(text))return text;
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
// A static proxy for "fits one laptop screen": the visible top-level rows of the sm-block
|
|
118
|
+
// (or the <main>) besides the stage. It cannot measure height; StillMade's builder preview measures the real one.
|
|
119
|
+
const VOID_TAGS=new Set(['area','base','br','col','embed','hr','img','input','link','meta','param','source','track','wbr']);
|
|
120
|
+
export const COMPACT_ROW_LIMIT=8;
|
|
121
|
+
function topLevelRows(html){
|
|
122
|
+
const lower=html.toLowerCase(),found=/\bclass\s*=\s*["'][^"'<>]*\bsm-block\b/.exec(lower)||/<main\b/.exec(lower);
|
|
123
|
+
if(!found)return 0;
|
|
124
|
+
let depth=0,rows=0;
|
|
125
|
+
for(let at=lower.lastIndexOf('<',found.index);at!==-1;at=lower.indexOf('<',at+1)){
|
|
126
|
+
const end=lower.indexOf('>',at);if(end===-1)break;
|
|
127
|
+
const tag=/^<(\/?)([a-z][a-z0-9-]*)/.exec(lower.slice(at,Math.min(end+1,at+40)));
|
|
128
|
+
if(!tag)continue;
|
|
129
|
+
const [,closing,name]=tag;
|
|
130
|
+
if(closing){if(--depth<=0)break;continue;}
|
|
131
|
+
// Hidden parts, dialogs and live status lines (often empty) are not rows.
|
|
132
|
+
if(depth===1&&!['script','style','template','dialog'].includes(name)&&!/\bsm-stage\b|\shidden\b|\saria-live\b|\srole\s*=\s*["']?status\b/.test(lower.slice(at,end)))rows++;
|
|
133
|
+
if(!VOID_TAGS.has(name)&&lower[end-1]!=='/')depth++;
|
|
134
|
+
}
|
|
135
|
+
return rows;
|
|
136
|
+
}
|
|
74
137
|
|
|
75
138
|
export function reviewViewDesign(view){
|
|
76
139
|
if(!view)return {passed:true,issues:[],warnings:[],principles:BLOCK_INTERFACE_PRINCIPLES};
|
|
@@ -89,6 +152,11 @@ export function reviewViewDesign(view){
|
|
|
89
152
|
// Compact: a bare browser file picker and printed size limits each take rows nobody needs.
|
|
90
153
|
if(bareFilePicker(primary))warnings.push('A bare file picker is in view. Show files as tiles: a + tile (a label around a hidden file input) and a thumbnail or chip for each saved file.');
|
|
91
154
|
if(/\bup to \d+\s*(?:mb|gb|kb)\b/i.test(primary.replace(/<[^<>]*>/g,' ')))warnings.push('A size limit is printed in view. Say it only when a file is too big.');
|
|
155
|
+
if(stackedLabel(primary,view.css))warnings.push('A short setting has its label above the control. Put the label beside it: <div class="sm-field"><label for="x">Label</label><input id="x"></div>, or several side by side in .sm-settings.');
|
|
156
|
+
const rareTool=rareToolSection(html);
|
|
157
|
+
if(rareTool)warnings.push(`"${rareTool.slice(0,40)}" is its own section. Rare tools (update, schedule, history, reload) are named icon buttons beside the action (.sm-icon in .sm-actions), never sections under the work.`);
|
|
158
|
+
const rows=topLevelRows(primary);
|
|
159
|
+
if(rows>COMPACT_ROW_LIMIT)warnings.push(`The workspace has ${rows} visible rows besides the stage and may not fit one laptop screen (an estimate: this check counts rows and cannot measure height). Put short settings side by side in .sm-settings and secondary ones in a closed .sm-more.`);
|
|
92
160
|
warnings.push(...blockKitProblems(view).map(problem=>problem.message));
|
|
93
161
|
return {passed:issues.length===0,issues,warnings,principles:BLOCK_INTERFACE_PRINCIPLES};
|
|
94
162
|
}
|
|
@@ -79,16 +79,23 @@
|
|
|
79
79
|
:where(.sm-actions) > :where(.sm-primary){flex:1 1 100%}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
/* ---------- Fields: a short
|
|
82
|
+
/* ---------- Fields: a short setting is one row, its label beside the control ----------
|
|
83
|
+
Long inputs (a textarea, picture choices, file tiles, a list) keep their label above. */
|
|
83
84
|
:where(.sm-field){display:grid;gap:6px;min-width:0}
|
|
84
85
|
:where(.sm-field) > :where(label,.sm-label){display:flex;align-items:center;gap:var(--s-1,4px);font-size:var(--fs-body-s,.875rem);color:var(--fg-muted);min-height:24px}
|
|
85
86
|
:where(.sm-field) :where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),select,textarea){width:100%;min-height:var(--touch-target,44px);padding:10px 12px;border:1px solid var(--border-tok);border-radius:var(--r-3,8px);background:var(--bg-elev-1);color:var(--fg);font:inherit}
|
|
86
87
|
:where(.sm-field) :where(textarea){min-height:96px;resize:vertical}
|
|
87
88
|
:where(.sm-fields){display:grid;gap:var(--s-4,16px);grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr))}
|
|
88
|
-
/* Compact
|
|
89
|
+
/* Compact (October 19, 2026): a short field is one row at every width. On a phone or in a
|
|
90
|
+
narrow cell the label takes its own width and the control the rest; when the two do not
|
|
91
|
+
fit, the control wraps under its label. */
|
|
92
|
+
:where(.sm-field:not(:has(textarea,.sm-choices,.sm-gallery,.sm-list))){display:flex;flex-wrap:wrap;align-items:center;gap:6px var(--s-2,8px)}
|
|
93
|
+
:where(.sm-field:not(:has(textarea,.sm-choices,.sm-gallery,.sm-list))) > :where(label,.sm-label){flex:0 1 auto}
|
|
94
|
+
:where(.sm-field:not(:has(textarea,.sm-choices,.sm-gallery,.sm-list))) > :where(:not(label,.sm-label)){flex:1 1 var(--sm-control,10rem);min-width:0}
|
|
95
|
+
/* Wider than a phone, short fields line up: one label column, the controls beside it. */
|
|
89
96
|
@container (min-width:520px){
|
|
90
97
|
/* Picture choices, file tiles and lists keep the full width: their label sits above, and they need the row. */
|
|
91
|
-
:where(.sm-field:not(:has(textarea,.sm-choices,.sm-gallery,.sm-list))){grid-template-columns:minmax(5rem,9rem) minmax(0,1fr);align-items:center;gap:var(--s-2,8px)}
|
|
98
|
+
:where(.sm-field:not(:has(textarea,.sm-choices,.sm-gallery,.sm-list))){display:grid;grid-template-columns:minmax(5rem,9rem) minmax(0,1fr);align-items:center;gap:var(--s-2,8px)}
|
|
92
99
|
:where(.sm-field) :where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),select){min-height:36px;padding:6px 10px}
|
|
93
100
|
:where(.sm-fields){gap:var(--s-2,8px) var(--s-4,16px)}
|
|
94
101
|
}
|
|
@@ -123,9 +130,11 @@
|
|
|
123
130
|
:where(.sm-choices[data-segmented]) > :where(label:last-of-type){border-start-end-radius:var(--r-pill,999px);border-end-end-radius:var(--r-pill,999px)}
|
|
124
131
|
:where(.sm-choices[data-segmented]) > :where(label:has(input:checked)){position:relative;z-index:1;background:var(--bg-elev-2)}
|
|
125
132
|
:where(.sm-choices[data-segmented]) :where(.sm-glyph){--sm-glyph-size:16px;margin:0}
|
|
126
|
-
/* Settings side by side: a grid of short settings, each label
|
|
133
|
+
/* Settings side by side: a grid of short settings, each label beside its control. A cell
|
|
134
|
+
too narrow for both wraps the control under its label; long inputs keep the label above. */
|
|
127
135
|
:where(.sm-settings){display:grid;gap:var(--s-3,12px) var(--s-4,16px);grid-template-columns:repeat(auto-fill,minmax(min(100%,11rem),1fr));align-items:start;min-width:0}
|
|
128
136
|
:where(.sm-settings) > :where(.sm-field){grid-template-columns:minmax(0,1fr);gap:4px}
|
|
137
|
+
:where(.sm-settings) > :where(.sm-field:not(:has(textarea,.sm-choices,.sm-gallery,.sm-list))){--sm-control:6rem;display:flex;flex-wrap:wrap;align-items:center;gap:4px var(--s-2,8px)}
|
|
129
138
|
:where(.sm-settings) > :where(.sm-choices) > :where(legend),:where(.sm-settings) :where(.sm-label){font-size:var(--fs-caption,.8125rem)}
|
|
130
139
|
/* On a phone, a row of chips or segments scrolls sideways instead of wrapping. */
|
|
131
140
|
@container (max-width:519px){
|
|
@@ -189,7 +198,7 @@
|
|
|
189
198
|
:where(.sm-more) > :where(summary):hover{color:var(--fg)}
|
|
190
199
|
:where(.sm-more) > :where(:not(summary)){margin-top:var(--s-2,8px)}
|
|
191
200
|
:where(.sm-more[open]){padding-bottom:var(--s-3,12px)}
|
|
192
|
-
/* The popup
|
|
201
|
+
/* The popup opens under its label row (.sm-label) and is never wider than the view, so it stays on a narrow screen even when the label sits beside its control. */
|
|
193
202
|
:where(.sm-label){position:relative}
|
|
194
203
|
:where(.sm-hint){display:inline-block;vertical-align:middle}
|
|
195
204
|
:where(:not(.sm-label)) > :where(.sm-hint){position:relative}
|
|
@@ -198,7 +207,7 @@
|
|
|
198
207
|
:where(.sm-hint) > :where(summary)::-webkit-details-marker{display:none}
|
|
199
208
|
:where(.sm-hint) > :where(summary)::before{content:"i";display:grid;place-items:center;width:15px;height:15px;border:1.5px solid currentColor;border-radius:50%;font:600 10px/1 var(--font-body);font-style:normal}
|
|
200
209
|
:where(.sm-hint) > :where(summary):hover,:where(.sm-hint[open]) > :where(summary){color:var(--fg)}
|
|
201
|
-
:where(.sm-hint) > :where(:not(summary)){position:absolute;z-index:5;inset-inline-start:0;top:100%;width:max-content;max-width:min(280px,
|
|
210
|
+
:where(.sm-hint) > :where(:not(summary)){position:absolute;z-index:5;inset-inline-start:0;top:100%;width:max-content;max-width:min(280px,calc(100cqi - 32px));margin:4px 0 0;padding:10px 12px;border:1px solid var(--border-tok);border-radius:var(--r-3,8px);background:var(--bg-elev-2);color:var(--fg);font-size:var(--fs-body-s,.875rem);line-height:1.45;box-shadow:var(--shadow-1)}
|
|
202
211
|
/* Outside a label row there is no safe anchor, so the explanation opens in the flow instead. */
|
|
203
212
|
:where(:not(.sm-label)) > :where(.sm-hint[open]){display:block}
|
|
204
213
|
:where(:not(.sm-label)) > :where(.sm-hint) > :where(:not(summary)){position:static;width:auto;max-width:60ch}
|