When to use
You have a brief that spans more than one component:
"A settings page: a left sidebar with sections, a main panel with a profile form (name, email, avatar upload), a danger zone with a delete button that confirms in a modal, and a sticky save bar at the bottom."
Use this when the work is a screen or flow, not a single piece. If
the brief is one component or one region, use component-from-brief
instead — it produces tighter output for small scopes.
The prompt
Fill in the placeholders and send the text below.
You are working in the Malevich design system. Read these files before answering:
llm-wiki/architecture.mdllm-wiki/glossary.mdllm-wiki/playbook/semantic-html.mdLoad the
malevich-component-usageskill.I want a Malevich-conformant screen for the following:
Brief:
{{brief}}Target framework:
{{framework}}Work in this order:
- Decompose. Break the screen into regions and name the component each maps to: sections (Hero, CTA, Site-header, Site-footer) and layouts (Block-, Split-, Grid-, Stack-layout) for structure, blocks for composites, elements for controls, overlays for anything that floats. Produce this map before any markup.
- Use existing components first. Reach for a new component only when no combination of existing ones fits — and if so, follow the
malevich-new-componentskill and call it out explicitly.- Compose top-down. Page → sections/layouts → blocks → elements. Respect composition direction (an element never wraps a block; overlays don't nest in overlays).
- Layout with tokens. Use
var(--space-gap-*)for gaps between regions andvar(--space-inset-*)for padding. No raw pixels, no tier-1 references.Constraints:
- Standard HTML elements with BEM classes — no custom elements, no
<m-*>tags (ADR-0004). Modals use native<dialog>.- Identity is a BEM short modifier (
.block.-variant); presentation and behavior aredata-{category}modifiers (data-surface,data-effect,data-behavior,data-rhythm), checked against each component's row inmodifiers/applicability.json.- Every value via
var(--token). Font tokens expand into five--font-<role>-*properties.- One accent action per region. State via attributes, not classes.
- Accessibility: landmark elements (
<header>,<nav>,<main>,<aside>,<footer>), real controls, visible focus.- If the screen needs interactive components (Dialog, Tabs, Tooltip) or any
data-behaviormodifier (sticky, dismissible…), note that the runtimeinit()must run once after mount.Output format:
- Region map — the decomposition (region → component → layer).
- HTML — the full screen markup, top to bottom.
- CSS — only the layout glue not already provided by components, inside
@layer malevich.componentsor a clearly-labelled page layer.- Runtime note — which components / behaviors need
init().- New components needed — anything you couldn't build from existing components, with a one-line justification each.
- Decisions / open questions.
If two readings of the brief diverge materially, ask before writing the whole screen.
Variables
| Placeholder | What to fill in |
|---|---|
{{brief}} |
The screen or flow description. The more you say about regions, hierarchy, and interactions, the better. |
{{framework}} |
vanilla HTML/CSS, Astro, React, Vue. Vanilla is the default. |
Tips for writing the brief
- Name the regions. "header, sidebar, main, save bar" gives the agent its decomposition for free.
- State the primary action per region. That fixes where
-accentgoes. - Call out anything that floats. Modals, tooltips, dropdowns are overlays and change the runtime needs.
- Don't specify spacing or color. Those come from the tokens.
Example input
A pricing page: a hero with a headline and subhead, a three-column pricing row (cards with a feature list and a CTA each, middle card highlighted), an FAQ section using disclosure rows, and a footer.
Example output (abridged)
Region map:
hero → Hero (section) .hero
pricing row → Grid-layout (section) .grid-layout
└ plan card → Card (block) ×3 .card (.-feature on middle)
└ CTA → Button (element) .button.-accent
faq → Stack-layout (section) .stack-layout
└ row → native <details>/<summary> .accordion__item
cta band → CTA (section) .cta
footer → Site-footer (section) .site-footer
HTML (abridged):
<main>
<section class="hero">
<h1 class="hero__title">Pricing that scales with you</h1>
<p class="hero__lead">Start free. Upgrade when it pays off.</p>
</section>
<section class="grid-layout" data-rhythm="regular">
<article class="card">…</article>
<article class="card -feature" data-surface="elevated">
<header class="card__header"><h3 class="card__title">Studio</h3></header>
<div class="card__body"><!-- feature list --></div>
<footer class="card__footer">
<button class="button -accent">Choose Studio</button>
</footer>
</article>
<article class="card">…</article>
</section>
<section class="stack-layout">
<details class="accordion__item">
<summary class="accordion__summary">Can I cancel anytime?</summary>
<div class="accordion__panel">Yes — no contract.</div>
</details>
</section>
<section class="cta">
<h2 class="cta__title">Ready to start?</h2>
<button class="button -accent">Create your canvas</button>
</section>
</main>
Runtime note: the disclosure rows use native <details>, so they
need no JS. Add init() if you swap them for the Accordion block's
collapsible behavior, or attach any other data-behavior modifier.
New components needed: none — the screen composes entirely from Hero,
Grid-layout, Card, Button, CTA, Site-footer, and native <details>.
Decisions / open questions:
- I highlighted the middle plan with
.card.-feature(identity) plusdata-surface="elevated"(presentation). If the highlighted plan differs, move the modifier. - I used a Grid-layout for the pricing row rather than a bespoke section.
If you want a pre-composed pricing section, that's a new Section
component — tell me and I'll follow
malevich-new-component.
Pairs with
- Prompt:
component-from-brief— when the scope is a single component, not a screen. - Skill:
malevich-component-usage— the conventions the screen follows. - Skill:
malevich-new-component— if the screen genuinely needs a new component.