When to use
You have a fragment of working code — anything from a Tailwind login form
to a Bootstrap modal — and you want a Malevich version that behaves
identically but follows the system. Use this for single-component or
single-screen-fragment refactors. For full-page rewrites or system-wide
migrations, plan a multi-step migration with the malevich-refactor
skill, not a single prompt invocation.
The prompt
Fill in the placeholders and send the text below.
You are working in the Malevich design system. Before answering, read:
llm-wiki/architecture.mdllm-wiki/glossary.mdllm-wiki/playbook/semantic-html.mdThen load the
malevich-refactorskill if you haven't already.I have the following code:
Source code:
{{code}}Source framework or system:
{{source_system}}Refactor this into Malevich. Follow these rules:
- Preserve behavior. Visual appearance may differ slightly to match Malevich tokens, but interactive behavior (focus, keyboard, form submission, dismissal) must be identical or better.
- Preserve identifiers. Keep IDs, data attributes, and identifier classes (
.checkout-form,.user-card). Only change visual class names.- Use existing components first. If the code is a button, produce a Malevich Button. Don't invent a new component because the source had custom styling.
- Standard HTML, no custom elements. Malevich components are semantic elements with BEM classes — no
<m-*>tags, no Shadow DOM (ADR-0004). Modals use the native<dialog>element.- One-to-one mapping where possible. A
<div class="modal">becomes a<dialog class="dialog">; don't restructure unnecessarily.- Identity vs presentation. Map a status/role to a BEM variant (
.alert.-warning); map a visual treatment or behavior to adata-{category}modifier (data-surface,data-effect,data-behavior), checked against the component's row inmodifiers/applicability.json.- No raw values. Every color, size, and spacing references a
var(--token)— semantic (tier-2) or component-specific (tier-3), never tier-1--palette-*/--scale-*. If a value has no clean equivalent, use the closest existing token and flag it.Output format:
- Inventory — UI elements found in the source and the Malevich component each maps to. Format:
<source identifier or description> → <Malevich component> (.<class>)- Refactored code — the rewritten markup, with CSS inside
@layer malevich.components.- Diff summary — three bullet lists: Visual changes, Structural changes, Behavioral changes. Keep them short — a long list means you've gone past refactor into rewrite.
- Open questions for me — anything you weren't sure about.
Do not rewrite the source from scratch. If you find yourself producing markup that no longer resembles the original, stop and ask whether a rewrite is what I want.
Variables
| Placeholder | What to fill in |
|---|---|
{{language}} |
The fence language: html, jsx, vue, astro. |
{{code}} |
The source code to refactor. Keep it focused — one screen region per invocation. |
{{source_system}} |
Where the code came from: Tailwind, Bootstrap 5, Material UI, vanilla, shadcn/ui, etc. Tells the agent which idioms to translate. |
Example input
Source: a Tailwind notification banner.
<div class="bg-yellow-100 border-l-4 border-yellow-500 p-4 flex items-start gap-3">
<svg class="w-5 h-5 text-yellow-700 flex-shrink-0"><!-- ... --></svg>
<div class="flex-1">
<h3 class="font-semibold text-yellow-900">Heads up</h3>
<p class="text-sm text-yellow-800">Your trial ends in 3 days.</p>
</div>
<button class="text-yellow-700 hover:text-yellow-900" aria-label="Dismiss">✕</button>
</div>
Source system: Tailwind.
Example output
Inventory:
outer container (banner) → Malevich Alert (display element) (.alert.-warning)
icon → icon-pack glyph (i.icon[data-icon])
title → Alert title (.alert__title)
body → Alert body (.alert__body)
dismiss affordance → dismissible behavior modifier (data-behavior)
Refactored code:
<aside class="alert -warning" data-behavior="dismissible">
<i class="alert__icon icon" data-icon="warning" aria-hidden="true"></i>
<div>
<p class="alert__title">Heads up</p>
<p class="alert__body">Your trial ends in 3 days.</p>
</div>
</aside>
No component CSS needed — the Alert element ships all required styles.
Status is the -warning variant. Dismissibility is the
data-behavior="dismissible" modifier; Alert's applicability row lists
dismissible, and the runtime wires the close affordance — so a separate
hand-rolled dismiss button is unnecessary.
Diff summary:
Visual changes:
- Yellow palette replaced with Malevich's
--color-warningfamily. Very close, not identical. - The Tailwind left bar maps to the Alert's default rail treatment — no extra work.
- Yellow palette replaced with Malevich's
Structural changes:
- Inline
flexlayout removed; Alert handles internal layout. - Heading became
.alert__title, paragraph.alert__body. - The hand-rolled
<button>✕is replaced by thedismissiblebehavior modifier (the runtime injects the close control).
- Inline
Behavioral changes:
- Dismissal now runs through the runtime instead of an inline handler.
Load
@malevich/componentsand callinit()once after mount; without the runtime the alert renders but isn't dismissible.
- Dismissal now runs through the runtime instead of an inline handler.
Load
Open questions for me:
- The original used
<h3>for the title; I used<p class="alert__title">to avoid injecting a heading level mid-flow. If this banner is a landmark that needs a heading, tell me the right level. - Should this be announced immediately by screen readers? If yes, swap
<aside>forrole="alert"— reserve that for urgent messages. - The icon uses the canonical pack name
warning. If your registered pack names it differently, tell me the pack.
Tips for a good refactor
- One region per prompt. Pasting a whole page produces a worse refactor than a single component.
- State the source system explicitly. "Tailwind" vs "Bootstrap" vs "shadcn" changes which idioms the agent translates.
- Don't strip the source. Comments, identifier classes, and data attributes give the agent signal. Leave them in.
- Re-run if the diff summary is long. A short list means a clean refactor; a long list means drift. Re-prompt with a smaller scope, or accept that this region needs a design review, not a refactor.
Pairs with
- Skill:
malevich-refactor— the procedural skill this prompt invokes. - Skill:
malevich-audit— run after the refactor to verify conformance. - Skill:
malevich-component-usage— the conventions the refactor produces.