Skip to content
IdeaZen

Ledger

Web app

Dense, calm dashboards for data you read all day.

Best for: Analytics and admin dashboards, Finance and inventory tools, Internal tools with tables.

States

Every control is specified in every state, not just the default. Input borders use a 3:1 contrast colour so they stay visible.

Buttons

DefaultHoverFocusDisabled
SecondaryFocus
Default
Search invoices
Focus
acme
Error
name@

✕ Enter an email like name@example.com

Disabled
Not available

Colours

  • bg#F4F6F8
  • surface#FFFFFF
  • ink#0F1B2D
  • muted#5A6B80
  • line#D6DDE6
  • control#6B7C93
  • danger#B42318
  • accent#0E7C86

Type

  • Headings: IBM Plex Sans
  • Body: IBM Plex Sans
  • Mono: IBM Plex Mono

Compact. 4px spacing base, 32px table rows, 14px body text.

Principles

  • Information first: numbers and tables are the design. Chrome stays quiet.
  • One accent color (teal) marks the single most important action or value on a screen.
  • Separate regions with 1px lines and background steps, never shadows.
  • Right-align numbers, use the mono font for figures and IDs so columns line up.
  • Show state with text plus color (a label and a dot), never color alone.

Avoid

  • Gradients, glows and glassmorphism
  • Large rounded cards with soft shadows
  • Emoji or multicolour icons
  • Purple or blue-violet accents
  • Centered text blocks
  • Donut charts for anything with more than 4 slices

Components

Button
Primary: teal fill, white text, 32px tall, 4px radius. Secondary: 1px line border, ink text. No icons-only primary buttons.
Card
White surface on the grey page, 1px line border, 4px radius, 16px padding, no shadow. Title 14px semibold, optional muted caption.
Input
32px tall, 1px line border, 4px radius, teal 2px focus ring. Label above in 12px muted.
Table
32px rows, 1px line between rows, sticky header in muted 12px, numeric columns right-aligned in mono, row hover is a 4% ink tint.
Stat
Large mono number (24px), muted label beneath, small delta with an arrow and sign. Never a gauge or donut for a single number.
Navigation
Left sidebar 220px, text links with 16px icons, the active item has a 2px teal bar on its left edge.
Badge
Square-ish (2px radius), 12px text, tinted background plus a leading dot.

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: Ledger

Dense, calm dashboards for data you read all day.
Category: Web app. Best for: Analytics and admin dashboards; Finance and inventory tools; Internal tools with tables.

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
- Information first: numbers and tables are the design. Chrome stays quiet.
- One accent color (teal) marks the single most important action or value on a screen.
- Separate regions with 1px lines and background steps, never shadows.
- Right-align numbers, use the mono font for figures and IDs so columns line up.
- Show state with text plus color (a label and a dot), never color alone.

## Colour tokens
Define these once (CSS variables or Tailwind theme) and use only these. No raw hex values in components.

```css
:root {
  --bg: #F4F6F8;
  --surface: #FFFFFF;
  --ink: #0F1B2D;
  --muted: #5A6B80;
  --line: #D6DDE6;
  --control: #6B7C93;
  --danger: #B42318;
  --accent: #0E7C86;
  --accent-ink: #FFFFFF;
  --radius: 4px;
  --border-width: 1px;
  --shadow: none;
}
```

| Token | Value | Use |
|-------|-------|-----|
| bg | #F4F6F8 | page background |
| surface | #FFFFFF | panels, cards, inputs |
| ink | #0F1B2D | primary text |
| muted | #5A6B80 | secondary text, captions |
| line | #D6DDE6 | decorative dividers only (too faint for control borders) |
| control | #6B7C93 | borders of inputs, buttons and other controls (3:1 contrast) |
| danger | #B42318 | errors and destructive actions (4.5:1 on bg and surface) |
| accent | #0E7C86 | primary action, links, active state |
| accent-ink | #FFFFFF | text on accent |

## Typography
- Display / headings: IBM Plex Sans
- Body: IBM Plex 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: 4px
- Border: 1px solid line
- Shadow: none
- Density: Compact. 4px spacing base, 32px table rows, 14px body text.
- Type scale: 12 / 14 / 16 / 20 / 24 px. Body 14px, line height 1.5, headings semibold.
- Spacing scale: 4, 8, 12, 16, 24, 32, 48 px (use only these steps)

## Components
- **Button.** Primary: teal fill, white text, 32px tall, 4px radius. Secondary: 1px line border, ink text. No icons-only primary buttons.
- **Card.** White surface on the grey page, 1px line border, 4px radius, 16px padding, no shadow. Title 14px semibold, optional muted caption.
- **Input.** 32px tall, 1px line border, 4px radius, teal 2px focus ring. Label above in 12px muted.
- **Table.** 32px rows, 1px line between rows, sticky header in muted 12px, numeric columns right-aligned in mono, row hover is a 4% ink tint.
- **Stat.** Large mono number (24px), muted label beneath, small delta with an arrow and sign. Never a gauge or donut for a single number.
- **Navigation.** Left sidebar 220px, text links with 16px icons, the active item has a 2px teal bar on its left edge.
- **Badge.** Square-ish (2px radius), 12px text, tinted background plus a leading dot.

## Layout
- App shell: fixed 220px sidebar, 48px top bar, content max 1280px.
- 12-column grid with 16px gutters; stat row on top, then table or chart.
- Charts: one hue per chart plus grey; thin 1.5px lines; label directly on the line instead of a legend when possible.

## Motion
Almost none. 120ms colour transitions on hover. Skeleton rows while loading; no page animations.

## 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
- Gradients, glows and glassmorphism
- Large rounded cards with soft shadows
- Emoji or multicolour icons
- Purple or blue-violet accents
- Centered text blocks
- Donut charts for anything with more than 4 slices

More kits