# SYSTEM.md



How I prefer agents to work, write code, and build UI. Read before starting. Each line is a strong default that stands alone, break one when it's clearly right, and say why.

## Workflow

- Scan the nearest AGENTS.md, this file, and the relevant code before writing.
- Write AGENTS.md for agents and a README for humans; keep both tight, well-sectioned, and built to swap, with the README especially short.
- Do exactly what's asked, smallest diff, and leave unrelated code and my changes alone.
- Minimum code that does the job. Simple, modular, root-cause fixes.
- Clear dead code and empty folders in the same change.
- Don't start dev servers; one is usually running.
- Don't push to remotes unless I ask.



## Code

- Native primitives and framework built-ins before libraries or custom code.
- One source of truth per concept. No magic numbers or hardcoded data.
- Thin, display-only components. Logic and data live outside them.
- Plain names a person would use, no jargon.
- Components get one-word names.
- Logged-in users get the app at the root URL, no /app or /dashboard prefix; move the marketing homepage to a path like /home.
- Never neglect SEO: meaningful titles, descriptions, OG and social images, semantic markup, and a sitemap.



## Color

- Tokens are the source of color, type, size, and spacing. No raw values in components.
- Prefer the framework's built-in scale (e.g. Tailwind's `rounded-2xl`, `p-4`, `max-h-screen`) over arbitrary values; reach for `[...]` only when nothing fits, and promote a genuinely shared value to a token.
- Default to a monochrome palette: neutrals on a single hue, lightness only, pushed toward near-black and near-white for real contrast, plus one accent with tints and shades when more range is needed. Choose the accent, and whether it leans light or dark, to fit the project.
- The accent is a spotlight, not a wash.
- Light and dark are both first-class, resolved per scheme through tokens. Verify both.
- Switching themes fires no transitions on elements.



## Typography

- Type scale is dramatic and tight: few token sizes with big jumps, display large and confident, body quiet, no arbitrary or timid in-between sizes.
- Few weights, high contrast: heavy display against regular body, with tracking that tightens as size grows.
- Define text styles once, applied by role, not inline.
- Render text with antialiased smoothing and legibility-optimized rendering.



## Copywriting

- Plain copy: value over features, no buzzwords, em or en dashes, or filler.
- Copy earns attention. Headlines and taglines are sharp and evocative, not a literal label of the obvious.
- Write declarative and second-person: short lines, no hedging or preamble, parallel and contrast pairs, landing on a concrete noun.
- Back claims with proof: concrete numbers and named customers, not adjectives.
- Show the product working through live or interactive demos, not static screenshots or stock imagery.



## Forms

- Inputs use the right type and inputmode (email, password, number).
- Inputs use at least 16px text so mobile doesn't zoom on focus.
- Autofocus the first input on desktop only.
- Spellcheck and autocomplete off unless the field genuinely benefits.
- Password managers off except on real credential fields.
- Input icons and affixes sit absolutely over the field with matching padding, not beside it, and focus the field on click.



## Components

- Component over raw element.
- Add a prop before forking.
- One wrapper per pattern (screen, section, card). Reuse its shape.
- One styling system, following native conventions.
- One icon set, referenced by name.
- Minimal element tree. Wrappers only when structural.
- Components keep their shape. Decorations are temporary, shape is permanent.



## Layout

- Layout structure owns positioning. Route every screen through a shared skeleton (header, body, pinned footer); never space pages by hand.
- Whitespace is extreme and structural: big, consistent air around and between sections, erring toward too much over cramped.
- Spacing reflects relationship. Related elements group tight; a subtitle hugs its title.
- Responsive by default at every size, no overflow or clipping.
- Finite choices wrap; sideways scroll is for continuous media.
- No layout shift. Reserve space for async content and media so nothing reflows.
- Columns of copy wrap to equal line counts; balance with wording, not fixed heights.
- Hit targets are padding, not margin, so a list of interactive items has no dead space. Grow padding instead of adding gaps.
- Buttons hug content and opt into full width explicitly.
- Peer controls in a row share height, shape, and treatment, plus equal width when side by side, so they read as one set.
- Align mathematically first, then correct by eye where it reads off. Line height can leave button text visually off-center, so nudge it; nudge icons and glyphs to look centered too.



## States

- Each screen stands alone, no half-states.
- Async surfaces have loading, empty, and error states.
- Use skeletons that mirror content over generic loaders.
- Empty states prompt the next action, like creating the first item.
- A missing value is a neutral placeholder, never a dropped line.
- Use tabular numbers for values that update.
- Disable a control while its action is in flight, so a submit can't fire twice.



## Interaction

- Interactive elements feedback on press, hover, and focus. Never snap or animate border color.
- Text stays unselectable on interactive surfaces.
- Cursors signal affordance: pointer on everything clickable including buttons, help on info and tooltips, text on text, not-allowed on disabled.
- Menus and dropdowns open on press, not click, so they feel instant.
- Keep system scrollbars out of the layout; hide them or use the overlay style, never build a custom scrollbar.
- Never leave a default browser outline or focus ring; replace it with an intentional focus style.
- Accessibility is part of done: labels on icon controls, visible focus, meaning beyond color.
- Details carry the brand. Style the overlooked states (text selection, caret, placeholder) to match.
- Floating surfaces share one style and animate in with a small move and fade.
- Motion is snappy (120 to 200ms), eases out, and comes from one shared source. Reuse named curves, never inline timings.
- Show feedback on the element itself, not a new one. Glow or shake a field, swap a label for a moment; use motion for soft failures and reserve error copy for what the user must read to act on.

