Night Shift
Web appDarkA dark, keyboard-first look for tools developers live in.
Best for: Developer tools and CLIs with a web UI, API dashboards and log viewers, Command-palette driven apps.
deploy production⌘D
deploy staging⌘⇧D
view logs⌘L
rollback last release⌘Z
12:04:11 api GET /v1/jobs 200 18ms
12:04:12 api POST /v1/jobs 201 42ms
12:04:14 worker retry 2/5 job_8f2a
12:04:15 api GET /v1/jobs 200 16ms
Services
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
✕ Enter an email like name@example.com
Colours
- bg#0C1118
- surface#141B25
- ink#DCE6F2
- muted#8393A7
- line#243041
- control#5F7189
- danger#FF7B72
- accent#FFB020
Type
- Headings: Geist
- Body: Geist
- Mono: Geist Mono
Compact-medium. 4px spacing base, 36px rows, 14px text, mono for anything the user might copy.
Principles
- Keyboard first: every action has a shortcut, shown in the UI as a small key chip.
- Dark slate surfaces with amber as the only accent; never use pure black or pure white.
- Mono type for code, commands, IDs and timestamps; sans for everything else.
- Depth comes from surface steps (bg, surface, raised) and 1px lines, not shadows.
- Status uses colour plus a text label: green, amber, red kept low-saturation.
Avoid
- Neon glows and gradients
- Pure black (#000) or pure white (#fff)
- Acid-green terminal clichés
- Rounded pill buttons
- Icons without labels or tooltips
- Light-mode-only previews
Components
- Button
- Primary: amber fill, dark text, 32px, 6px radius. Secondary: surface fill with line border. Show the shortcut in a key chip at the right of the label.
- Card
- Surface background, 1px line border, 6px radius, 16px padding. Header row with mono title.
- Input
- Dark surface, 1px line border, amber 2px focus ring, mono text for code fields.
- CommandPalette
- Centered 560px panel, search input on top, results with the matched letters in amber, keys on the right. Opens with Cmd/Ctrl+K.
- CodeBlock
- Raised surface, mono 13px, copy button top right, line numbers in muted.
- Navigation
- Thin left rail with icons and tooltips, or a top tab row. Active item gets an amber underline.
- Badge
- Mono 12px, 1px border in the status colour, transparent fill.
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: Night Shift
A dark, keyboard-first look for tools developers live in.
Category: Web app. Best for: Developer tools and CLIs with a web UI; API dashboards and log viewers; Command-palette driven apps.
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
- Keyboard first: every action has a shortcut, shown in the UI as a small key chip.
- Dark slate surfaces with amber as the only accent; never use pure black or pure white.
- Mono type for code, commands, IDs and timestamps; sans for everything else.
- Depth comes from surface steps (bg, surface, raised) and 1px lines, not shadows.
- Status uses colour plus a text label: green, amber, red kept low-saturation.
## Colour tokens
Define these once (CSS variables or Tailwind theme) and use only these. No raw hex values in components.
```css
:root {
--bg: #0C1118;
--surface: #141B25;
--ink: #DCE6F2;
--muted: #8393A7;
--line: #243041;
--control: #5F7189;
--danger: #FF7B72;
--accent: #FFB020;
--accent-ink: #1A1200;
--radius: 6px;
--border-width: 1px;
--shadow: none;
}
```
| Token | Value | Use |
|-------|-------|-----|
| bg | #0C1118 | page background |
| surface | #141B25 | panels, cards, inputs |
| ink | #DCE6F2 | primary text |
| muted | #8393A7 | secondary text, captions |
| line | #243041 | decorative dividers only (too faint for control borders) |
| control | #5F7189 | borders of inputs, buttons and other controls (3:1 contrast) |
| danger | #FF7B72 | errors and destructive actions (4.5:1 on bg and surface) |
| accent | #FFB020 | primary action, links, active state |
| accent-ink | #1A1200 | text on accent |
## Typography
- Display / headings: Geist
- Body: Geist
- Mono: Geist 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: 6px
- Border: 1px solid line
- Shadow: none
- Density: Compact-medium. 4px spacing base, 36px rows, 14px text, mono for anything the user might copy.
- Type scale: 12 / 13 / 14 / 16 / 20 / 28 px. Body 14px, code 13px, line height 1.5.
- Spacing scale: 4, 8, 12, 16, 24, 32 px (use only these steps)
## Components
- **Button.** Primary: amber fill, dark text, 32px, 6px radius. Secondary: surface fill with line border. Show the shortcut in a key chip at the right of the label.
- **Card.** Surface background, 1px line border, 6px radius, 16px padding. Header row with mono title.
- **Input.** Dark surface, 1px line border, amber 2px focus ring, mono text for code fields.
- **CommandPalette.** Centered 560px panel, search input on top, results with the matched letters in amber, keys on the right. Opens with Cmd/Ctrl+K.
- **CodeBlock.** Raised surface, mono 13px, copy button top right, line numbers in muted.
- **Navigation.** Thin left rail with icons and tooltips, or a top tab row. Active item gets an amber underline.
- **Badge.** Mono 12px, 1px border in the status colour, transparent fill.
## Layout
- Full-bleed app, no max width for log and table views; 720px max for forms.
- Split panes where useful (list left, detail right), resizable.
- Sticky headers on long tables and logs.
## Motion
Instant. Only a 100ms fade for the command palette. No decorative animation.
## 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
- Neon glows and gradients
- Pure black (#000) or pure white (#fff)
- Acid-green terminal clichés
- Rounded pill buttons
- Icons without labels or tooltips
- Light-mode-only previews
More kits
- Ledger · Web app
- Marginalia · Web app
- Launchpad · Landing page