summer-apps-design skill carry the rules, so agents get them right without being told.
Load the kit
--se-*), the Geist font and every <summer-*> component, and follows Studio’s light or dark theme. The stylesheet alone is /summer-ui/v1/ui.css. summerUI.toast(text) shows a toast in the app.
The full catalog, with every attribute, property, method, event and a copyable example per component, is summer_app_guide section kit, and /summer-ui/v1/catalog.json on the app host. Copy its examples instead of inventing markup.
Components
Rules for every component
hiddenhides any kit component.- A JSON attribute is also a property of the same name:
select.options = [...],table.rows = [...]. - Setting
.valuefrom code never emitschange. Only the person’s input does, so updating a control while you render never loops. - Clear
loadingonce the data is shown, also when the data is empty. - Number inputs have no
minormax. Check the range in the form’ssubmithandler and set the field’serror. - Tables have no buttons per row. For a one-click row action, use
summer-listrow actions, or clickable rows that open a dialog. - A chart with several
ykeys draws grouped bars side by side, not stacked. Negative values hang below zero.
The rules in short
- One line says what the tool does and where its data goes. One primary button finishes the task.
- Tokens only: no hex colours. Geist only; weights 400, 500 and 600; numbers tabular and right-aligned.
- No frame around the whole app, no cards inside cards, no badge on every row, no native audio, video, select or range controls.
- Design the loading, empty and error states.
- When a teammate or an agent changes something, flash that row briefly instead of showing a toast.
- Check light and dark, at phone and desktop widths.
summer_app_screenshotwithwidth: 390andtheme: "dark"shows both.
summer-apps-design skill and in summer_app_guide (section design).
Layout apps
For a quick decision UI, an agent can publish a layout instead of code: one JSON object of kit nodes that Summer draws inside the sandbox. No code runs.{ type, id?, props, children? }. Unknown props are errors. Inputs, buttons and forms need an id. Limits: 200 KB, 200 nodes, depth 8.
Node types: page, stack, grid, tabs, card, form, heading, text, notice, stat, table, chart, image, audio, video, model3d, asset, choice-group, list, button, slider, select, toggle, text-input. There is no dialog in a layout; build a code app for edit flows.
Button and form actions:
{ "type": "send", "name": "sound.picked" }: an event your agent reads withsummer_app_events. Its payload holdsvalues, every input’s current value byid.{ "type": "open", "path": "/studio/..." }: moves the Studio tab.{ "type": "generate", "method": "generate.image", "args": { "prompt": { "$input": "prompt" } } }: a paid generation for the person using the app.
summer_app_guide (section layout) has every prop.
