Best for: Notes, docs and journaling apps, Learning and study tools, Content and publishing tools.
Components
- Button
- Primary: raspberry fill, white text, 40px tall, 2px radius. Secondary: text with an underline on hover. Keep labels as verbs ("Save note").
- Card
- Avoid cards. List items are separated by a 1px line and 16px vertical padding. Where a panel is needed: white surface, 1px line.
- Input
- Borderless on the page background with a 1px bottom line that turns raspberry on focus. Large (18px) for titles.
- Editor
- Single column, 68ch, serif title at 36px, body 18px. Floating toolbar appears on text selection only.
- Navigation
- Slim left list of documents (260px) in 15px sans; the active document is bold with a raspberry 2px left rule. Top bar holds only search and the account.
- Tag
- Plain muted text with a leading "#". No filled pills.
The DESIGN.md file
Put this in your project (for example docs/DESIGN.md) and tell your AI tool: "Follow docs/DESIGN.md for all UI." Or paste it into a chat builder along with your project description.
# DESIGN.md: Marginalia
A reading-and-writing app that feels like a well-set page.
Category: Web app. Best for: Notes, docs and journaling apps; Learning and study tools; Content and publishing tools.
Follow this file for every screen and component. If something is not covered, choose the option closest to these principles. Do not substitute your own default style.
## Principles
- The text is the interface. Give it room and a comfortable measure (60 to 70 characters).
- Serif headings give the app a voice; the sans body keeps controls clear.
- Raspberry is used sparingly: links, the active item and one primary action.
- Prefer underlines and spacing to boxes. Few borders, no shadows.
- Writing surfaces are distraction-free: hide controls until they are needed.
## Colour tokens
Define these once (CSS variables or Tailwind theme) and use only these. No raw hex values in components.
```css
:root {
--bg: #F6F6F3;
--surface: #FFFFFF;
--ink: #1F1F1F;
--muted: #6B6B66;
--line: #E1E0DA;
--control: #85847D;
--danger: #A8260F;
--accent: #C2255C;
--accent-ink: #FFFFFF;
--radius: 2px;
--border-width: 1px;
--shadow: none;
}
```
| Token | Value | Use |
|-------|-------|-----|
| bg | #F6F6F3 | page background |
| surface | #FFFFFF | panels, cards, inputs |
| ink | #1F1F1F | primary text |
| muted | #6B6B66 | secondary text, captions |
| line | #E1E0DA | decorative dividers only (too faint for control borders) |
| control | #85847D | borders of inputs, buttons and other controls (3:1 contrast) |
| danger | #A8260F | errors and destructive actions (4.5:1 on bg and surface) |
| accent | #C2255C | primary action, links, active state |
| accent-ink | #FFFFFF | text on accent |
## Typography
- Display / headings: Newsreader
- Body: DM Sans
- Mono: IBM Plex Mono
- Load them from Google Fonts or the framework's font loader. Keep body text at 16px or larger on mobile.
- Left-align text. Keep paragraphs under 70 characters wide.
## Shape and spacing
- Corner radius: 2px
- Border: 1px solid line
- Shadow: none
- Density: Roomy. 8px spacing base, 18px body text with 1.65 line height, content column 68ch.
- Type scale: 15 / 17 / 20 / 26 / 36 / 48 px. Body 17 to 18px, line height 1.65, titles in the serif.
- Spacing scale: 4, 8, 16, 24, 32, 48, 96 px (use only these steps)
## Components
- **Button.** Primary: raspberry fill, white text, 40px tall, 2px radius. Secondary: text with an underline on hover. Keep labels as verbs ("Save note").
- **Card.** Avoid cards. List items are separated by a 1px line and 16px vertical padding. Where a panel is needed: white surface, 1px line.
- **Input.** Borderless on the page background with a 1px bottom line that turns raspberry on focus. Large (18px) for titles.
- **Editor.** Single column, 68ch, serif title at 36px, body 18px. Floating toolbar appears on text selection only.
- **Navigation.** Slim left list of documents (260px) in 15px sans; the active document is bold with a raspberry 2px left rule. Top bar holds only search and the account.
- **Tag.** Plain muted text with a leading "#". No filled pills.
## Layout
- Two columns: document list (260px) and the page (centered, 68ch max).
- Generous top margin (96px) above the document title.
- Settings and secondary views open as full pages, not modals.
## Motion
Subtle. 150ms fades when switching documents. Respect reduced motion.
## Interaction states
Every interactive element needs all of these, not just the default:
- **Hover:** primary buttons darken about 8%; secondary buttons and rows get a subtle background tint. Hover is never the only way to reveal an action (touch has no hover).
- **Focus:** a visible 2px outline in the accent colour with a 2px offset. Never remove the outline without replacing it.
- **Active / pressed:** move 1px down or darken further, so the click feels acknowledged.
- **Disabled:** 45% opacity, not-allowed cursor, aria-disabled. If the reason is not obvious, say why next to the control.
- **Loading:** keep the button width, show a spinner, disable repeat clicks, and keep the label ("Saving...").
- **Selected / current:** differs by more than colour (weight, underline, check mark or bar).
- **Error:** danger colour plus an icon and text, never colour alone.
## Forms and validation
- Every field has a visible label above it. Never use a placeholder as the only label.
- Use the control border colour (3:1 contrast) for input and button borders, not the faint line colour.
- Use the right input type and autocomplete attribute; inputs are at least 16px on mobile so iOS does not zoom.
- Mark optional fields, not required ones. Keep forms as short as possible.
- Validate when the user leaves a field and again on submit; do not show errors while they are still typing.
- Put the error message under the field: say what went wrong and how to fix it ("Enter an email like name@example.com"). On submit with errors, move focus to the first invalid field.
- Never clear what the user typed after an error.
## Feedback and system status
- Acknowledge every action within 100ms (pressed state, spinner or optimistic update).
- Loads longer than about 300ms show a skeleton shaped like the content; longer than 10 seconds show progress or a way to cancel.
- Confirm non-critical actions with a toast (role="status", visible at least 5 seconds). Errors stay on screen until dismissed.
- Destructive actions ask for confirmation or offer Undo. Name the thing being deleted in the dialog.
- Empty states say what will appear here and offer one clear action. Error states say what happened and what to do next.
## Navigation and structure
- The user can always tell where they are: current item marked with aria-current and a non-colour cue.
- At most 7 top-level destinations. Keep navigation in the same place on every page.
- Links look like links. Buttons do things; links go places.
- The browser Back button works and URLs reflect state (filters, tabs, steps) so pages can be shared and reloaded.
- One primary action per screen.
## Responsive behaviour
- Design mobile first. Breakpoints: 480, 768, 1024, 1280 px. Single column below 768px.
- No horizontal scrolling at 320px width. Tables scroll inside their own container or collapse to stacked rows.
- Touch targets at least 44 by 44px with 8px between them. Dense desktop UIs may use smaller controls only for a fine pointer; enlarge them under `@media (pointer: coarse)`.
- Support zoom to 200% and user font-size changes; use rem for type and spacing where possible.
## Content and tone
- Sentence case. Buttons start with a verb that says what happens ("Save note", not "Submit"). Keep names consistent across screens.
- Plain language, no jargon, no filler. Do not blame the user in errors.
## Accessibility
- Text contrast at least 4.5:1; large text and interface borders at least 3:1.
- Use semantic HTML (button, a, nav, main, label, table). Every control is reachable and operable by keyboard in a logical order.
- Do not rely on colour alone to convey meaning. Give images alt text and icon-only buttons an accessible name.
- Respect prefers-reduced-motion. Set the page language.
## Avoid
- Card grids for lists of documents
- Filled colourful tags
- Drop shadows and heavy borders
- Cream backgrounds with terracotta accents (a common default)
- Sans-serif for large titles
- Toolbars that are always visible