berd / ui
AGENTS.md1k starsChanged 3 months agoApache-2.0View on GitHub
Use the primitives in src/shared/ui/ as the default way to build interface elements. Prefer extending these components over recreating their styling in feature code. All buttons within a single surface zone must use the same size. Footer buttons in dialogs are the default Button size. Toolbar buttons are xs. Page-level actions are default. Never mix sizes within a footer, toolbar, or inline button group — if one button needs to be smaller, the whole group steps down together. The button…
We split this AGENTS.md into the rules it gives an agent
19 rules. About 0 are common, 9 are distinctive, and 10 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
10
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 3
Use the primitives in src/shared/ui/ as the default way to build interface elements.
- Distinctive: line 7
Prefer shared UI primitives over custom markup plus Tailwind classes.
- Distinctive: line 8
Prefer adding a variant or prop to a shared component over one-off styling in feature code.
- Very specific: line 9
Keep feature code focused on composition, state, and content.
- Distinctive: line 10
If a pattern appears in more than one place, extract or extend a shared primitive instead of copying class strings.
- Very specific: line 84
Use Button for clickable controls unless there is a strong reason not to.
- Very specific: line 85
Use variant and size before adding custom classes.
- Very specific: line 86
Use leftIcon and rightIcon for leading and trailing icons instead of manually placing icon children.
- Distinctive: line 87
Do not add spacing classes only to position button icons unless the design system cannot express the pattern yet.
- Very specific: line 91
Use Button for async action feedback too.
- Very specific: line 95
When combining async feedback with asChild, keep the visible label inside the slotted child so Button can swap it with loading, success, or …
- Very specific: line 110
Only give an icon its own explicit size-* class when intentionally overriding the design-system default.
- Very specific: line 127
Do not create wrapper buttons for back/save/delete.
- Very specific: line 145
When a trigger behaves like a button, use Button as the trigger surface.
- Distinctive: line 150
Avoid introducing custom colors, spacing, radii, or typography in feature code when existing tokens and shared variants cover the need.
- Distinctive: line 151
If a control needs a new visual treatment, add it to the shared component API first.
- Distinctive: line 152
Keep accessibility built in: semantic elements, labels for icon-only buttons, and consistent focus states.
- Distinctive: line 156
Before writing custom classes in a feature, ask:
- Distinctive: line 159
Should this become a shared variant or prop?
≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Shared UI Design System
Use the primitives in src/shared/ui/ as the default way to build interface elements. Prefer extending these components over recreating their styling in feature code.
Core Rules
- Prefer shared UI primitives over custom markup plus Tailwind classes.
- Prefer adding a variant or prop to a shared component over one-off styling in feature code.
- Keep feature code focused on composition, state, and content. Visual treatment should usually live in
src/shared/ui/. - If a pattern appears in more than one place, extract or extend a shared primitive instead of copying class strings.
Button sizing rule
All buttons within a single surface zone must use the same size.
Footer buttons in dialogs are the default Button size. Toolbar buttons are
xs. Page-level actions are default. Never mix sizes within a footer,
toolbar, or inline button group — if one button needs to be smaller, the
whole group steps down together.
The button system is a closed menu. Every button in the app is one of these named things — never a custom-styled Button.
The semantic menu (Button variants)
| Variant | Use when |
primary | The one main action (save, create, submit, confirm). Filled. |
outline | The paired secondary action next to a primary. Bordered. |
subtle | Soft-fill mid-weight action on background-colored surfaces. |
ghost | Quiet action in a row or toolbar. Invisible until hover. |
alert | Action inside a colored alert/banner; inherits currentColor. |
link | Inline text link that behaves as a button. Collapses to text. |
Two flags modify variants:
destructive— danger intent. Works onprimary(red fill),outline(red border/text),subtle(red tinted fill), andghost(red text + tint hover). Other variants ignore it and warn in dev.flush— ghost only. Inline geometry: no padding pill; rests atmuted-foregroundand raises the label on hover. For quiet actions that sit flush with surrounding content (list section actions, "show more").
Pick the emphasis first; if the action is dangerous, add destructive.
Chrome buttons (named wrappers)
Surface-specific recipes live in named components that compose Button. Use these instead of restyling Button for app chrome:
| Component | Base | Use when |
TopBarIconButton | ghost | Icon actions in the app top bar / window chrome. |
ComposerActionButton | subtle | Controls on the chat composer surface. |
PageHeaderButton | subtle | View-header actions in the app top strip. |
AgentTileButton | subtle | Actions floating over agent/persona tiles. |
GlassButton | subtle | Controls floating over media, canvases, artwork. |
JumpToLatestButton | primary | Floating back-to-live-edge pills over streams. |
DisclosureButton | ghost | "View more" / "View less" / "View all" affordances. Pick a surface. |
Each wrapper's recipe owns all of its interactive states; see the doc comment in its source for the full contract.
DisclosureButton takes a surface (default | sidebar | sidebarRow)
because how quiet the rest state can afford to be depends on what the button
sits on. default inherits the system ghost + flush states and is correct on
tinted raised surfaces like the chat user bubble; the sidebar* surfaces dim to
muted-foreground/75, which is only legible against the page background. Do not
use a sidebar* surface on a tinted surface.
The rule (audited in CI)
Feature code never puts color or interactive-state classes (bg-*,
text-foreground/text-muted-foreground/..., hover:*, active:*,
shadow-*, opacity-*) on a <Button>. Layout-only classes (ml-auto,
w-full, justify-start, shrink-0, truncation) are fine. If no variant,
flag, or wrapper fits, that is a design-system conversation — extend the
menu, don't restyle locally. pnpm design-system:audit enforces this and
fails on new violations.
General guidance
- Use
Buttonfor clickable controls unless there is a strong reason not to. - Use
variantandsizebefore adding custom classes. - Use
leftIconandrightIconfor leading and trailing icons instead of manually placing icon children. - Do not add spacing classes only to position button icons unless the design system cannot express the pattern yet.
- For icon-only actions, use the
icon-*sizes instead of text button sizes. - For active icon-only buttons, prefer native hover via
titleplusaria-label. - Reserve custom
Tooltipfor disabled controls or richer explanatory content. - Use
Buttonfor async action feedback too. Prefer itsfeedbackState,loadingLabel,successLabel,errorLabel,loadingVisual, andpreserveWidthprops over creating a separate async button wrapper or hand-placing spinners in feature code. - When combining async feedback with
asChild, keep the visible label inside the slotted child soButtoncan swap it with loading, success, or error feedback.
Ghost icon buttons
variant="ghost" has compound variants for all icon-* sizes that set hover:bg-transparent hover:text-foreground. This means ghost icon buttons have no background fill on hover — only a color change. Do not add hover:bg-accent/50 or similar hover background classes to ghost icon buttons; the compound variant already provides the correct behavior. Layout classes like mr-1, size-6, flex-shrink-0 are fine to add.
Icon Sizing
- Let
Buttonsize button icons by default. - Current button icon defaults are tied to button size:
xsandsmbuttons usesize-3icons.defaultbuttons usesize-3.5icons.lgbuttons usesize-4icons.- Only give an icon its own explicit
size-*class when intentionally overriding the design-system default. - Match icon visual weight to the text and control size. Small toolbar controls should not use oversized icons.
Dialogs
There is one modal surface: Dialog. Do not create new dialog chrome
components; compose the anatomy the use case needs.
DialogContentowns the glass surface, close button, and width via thesizeprop (md|lg|xl). Do not pass ad-hocmax-w-*classes.- Simple dialogs:
DialogHeader+ content +DialogFooter. Everything scrolls together. - Content-heavy dialogs (forms, pickers, lists): wrap the middle in
DialogBody. Its presence automatically pins the header and footer, moves padding to the zones, and gives the footer its top divider. UseDialogBody asChildwith a<form>child when the body is a single form. - All dialog actions live in
DialogFooterand useButtondirectly. Do not create wrapper buttons for back/save/delete. Back is just<Button variant="ghost" flush className="sm:mr-auto" />. Submit/save buttons use default Button size in the footer; if the body is a form, submit with<Button form={formId} type="submit">. - Semantic variants are the only other dialog components:
AlertDialog(interruptive, no light-dismiss),ConfirmDialog(yes/no preset), andCommandDialog(search-first palette). Never fork a new one for content density — density issize+DialogBody, not a new component. - Name feature dialogs
*Dialog, not*Modal. - List rows inside dialogs and settings use
RowButton(menuvariant for borderless option rows,fieldfor bordered input-like triggers) instead of raw<button>+ hand-rolled classes. Hover states come from the primitive (bg-muted); do not use washed-out one-offs likehover:bg-accent/30.
Menus And Selectors
- Compose menus from
DropdownMenu,DropdownMenuTrigger,DropdownMenuContent, and related shared primitives. - When a trigger behaves like a button, use
Buttonas the trigger surface. - Repeated trigger patterns like icon + label + chevron should be expressed through shared props or shared wrapper components.
Styling Boundaries
- Avoid introducing custom colors, spacing, radii, or typography in feature code when existing tokens and shared variants cover the need.
- If a control needs a new visual treatment, add it to the shared component API first.
- Keep accessibility built in: semantic elements, labels for icon-only buttons, and consistent focus states.
Good Heuristic
Before writing custom classes in a feature, ask:
- Can an existing shared component already do this?
- Should this become a shared variant or prop?
- Will another screen likely need the same pattern?
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 28,693 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository18 other files it gives its agents.
- AGENTS.mdAGENTS.md
- bb-cli/AGENTS.mdAGENTS.md
- distro/skills/berd-help/references/agents.mdAGENTS.md
- LAWS/AGENTS.mdAGENTS.md
- src/features/design-system/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- src/shared/ui/CLAUDE.mdCLAUDE.md
- assistive-uxSkill
- berdctl-new-commandSkill
- code-reviewSkill
- create-prSkill
- experimental-featuresSkill
- agent-builderSkill
- berd-helpSkill
- berd-monitorSkill
- berd-orchestratorSkill
- skill-builderSkill
- buzz-handoffSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

