Back to directory
dark · modern · minimal · saas · premium

Obsidian Rail.

A precision dark dev-tool surface. Near-black background, every divider a single 1px hairline at 8% white, Inter Display for headings and Geist Mono for IDs and timestamps with tabular-nums, a single electric mint accent reserved for active status pills and the primary CTA. Built for infrastructure dashboards, observability tools, and developer-platform marketing pages where the chrome itself reads as a precision instrument.

01 · Preview

The kitchen sink.

Obsidian.app
ProductPricingDocsAbout
Sign inGet started
dark · modern · minimal

Build with Obsidian Rail.

A complete design system, ready for your AI coding agent. Every primitive, token, and pattern below is generated straight from DESIGN.md — drop the file in your project and ship matching UI in minutes.

Start building →View on GitHub
Featured
Tokens that travel with your prompts.
Active users
12,840
Status
All systems operational
01 · Color

Palette

primary
#F5F6F7
secondary
#8B8E93
tertiary
#F5F6F7
neutral
#1A1C1E
surface
#0C0D0F
02 · Typography

Type scale

display
The quick brown fox
h1
A major section heading
h2
A subsection title
body
Body copy in the system's body font.
03 · Buttons

Buttons

PrimarySecondaryOutlineGhostText link →
Disabled
04 · Inputs

Form controls

Email
iris@studio.com
Password
••••••••••••
Bio
Designing for long-form publications. Based in Kyoto.
05 · Choices

Select & toggle

Plan
Starter
Free forever
Pro
$18 / month
Team
$48 / month
Toggles
Public profile
Require two-factor
Auto-accept invites
06 · Tags & badges

Labeling

NeutralAccentSolidWith dot
NEWBETAv2.0LIVE
07 · Cards

Cards

Feature
Editorial rigor

Prose-first token file — decisions live next to their reasoning.

Learn more →
Metric
24,810
▲ +12.4% vs last week
08 · Navigation

Tabs & breadcrumb

Overview
Analytics
Members
Workspace/Projects/Heritage System
09 · Spacing

Spacing scale

Fine micro-scale (1–5px) for pills, editorial scale (12–21px) for the grid.

1px
2px
5px
8px · base
10px
12px
14px
16px
18px
20px
21px
10 · Radius

Border radius scale

The system's own radius tokens — sm for chips and inputs, md for buttons, lg for cards, pill for fully-rounded CTAs.

sm
4px
md
6px
lg
8px
pill
9999px
11 · Elevation

Depth & elevation

00 · Flat
Elevation 00
01 · Low
Elevation 01
02 · Medium
Elevation 02
03 · High
Elevation 03
12 · Data

Charts

Weekly revenue
$48,210
M
T
W
T
F
S
S
Active sessions
2,184
02 · The file

DESIGN.md

markdown
1---
2name: "Obsidian Rail"
3description: "A precision dark dev-tool surface. Near-black background, every divider a single 1px hairline at 8% white, Inter Display for headings and Geist Mono for IDs and timestamps with tabular-nums, a single electric mint accent reserved for active status pills and the primary CTA. Built for infrastructure dashboards, observability tools, and developer-platform marketing pages where the chrome itself reads as a precision instrument."
4tags: [dark, modern, minimal, saas, premium]
5colors:
6 primary: "#f5f6f7"
7 secondary: "#8b8e93"
8 tertiary: "#f5f6f7"
9 neutral: "#1a1c1e"
10 surface: "#0c0d0f"
11typography:
12 display: Inter
13 body: Inter
14 mono: "Geist Mono"
15 scale:
16 hero: "4.25rem / 1.02 / 600 / -0.035em"
17 h1: "2.5rem / 1.12 / 600 / -0.025em"
18 h2: "1.5rem / 1.25 / 600 / -0.012em"
19 body: "0.9375rem / 1.6 / 400 / -0.005em"
20radius:
21 sm: 4px
22 md: 6px
23 lg: 8px
24 pill: 9999px
25shadows:
26 card: "rgba(0,0,0,0.20) 0 1px 2px"
27 button: none
28borders:
29 card: "1px solid rgba(245,246,247,0.08)"
30 divider: rgba(245,246,247,0.08)
31buttons:
32 primary:
33 background: #5fe3b1
34 color: #0c0d0f
35 border: none
36 shape: rounded
37 padding: 9px 18px
38 font: 600 / 0.8125rem
39 secondary:
40 background: #1a1c1e
41 color: #f5f6f7
42 border: 1px solid rgba(245,246,247,0.10)
43 shape: rounded
44 padding: 9px 18px
45 font: 500 / 0.8125rem
46 outline:
47 background: transparent
48 color: #f5f6f7
49 border: 1px solid rgba(245,246,247,0.14)
50 shape: rounded
51 padding: 9px 18px
52 font: 500 / 0.8125rem
53 ghost:
54 background: transparent
55 color: #8b8e93
56 border: none
57 shape: rounded
58 padding: 9px 14px
59 font: 500 / 0.8125rem
60charts:
61 variant: "thin-bars"
62 stroke_width: 1.25
63 fill_opacity: 0.06
64 gridlines: false
65 bar_gap: 3px
66 highlight: single
67 dot_marker: true
68fonts_url: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap"
69dependencies: ["lucide-react"]
70---
71
72# Obsidian Rail
73
74## AI Build Instructions
75
76> **Read this section before writing any code.** The rules below
77> are non-negotiable. Every value used in the UI must come from this
78> file's frontmatter — never substitute, approximate, or invent new
79> colors, fonts, radii, or shadows. If a value is missing, ask the
80> user before adding one.
81
82### 1 · Your role
83
84You are building UI for a project that has adopted **Obsidian Rail** as its
85design system. Treat `DESIGN.md` as the single source of truth.
86Your job is to translate the user's product requirements into
87components and pages that look like they were designed by the same
88person who authored this file.
89
90### 2 · Token compliance
91
92- Pull every color, font family, radius, shadow, and spacing value
93 from the frontmatter at the top of this file.
94- Use semantic roles (e.g. `primary`, `accent`, `muted`) — never
95 hard-code hex values that bypass the system.
96- When a token can be expressed as a CSS variable, declare it once
97 in your global stylesheet and reference it everywhere downstream.
98- The Google Fonts `<link>` is provided in the Typography section.
99 Add it to `<head>` before any component renders.
100
101### 3 · Component recipes
102
103Use these recipes verbatim when building the corresponding component.
104
105#### Buttons
106
107Four variants are defined. Pick one — never blend variants or invent a fifth.
108
109- **Primary** — rounded shape, bg `#5fe3b1`, text `#0c0d0f`, padding `9px 18px`, weight `600`.
110- **Secondary** — rounded shape, bg `#1a1c1e`, text `#f5f6f7`, border `1px solid rgba(245,246,247,0.10)`, padding `9px 18px`, weight `500`.
111- **Outline** — rounded shape, text `#f5f6f7`, border `1px solid rgba(245,246,247,0.14)`, padding `9px 18px`, weight `500`.
112- **Ghost** — rounded shape, text `#8b8e93`, padding `9px 14px`, weight `500`.
113
114Reach for **primary** as the single dominant CTA per screen.
115**Secondary** for the supporting action. **Outline** for tertiary
116actions in toolbars. **Ghost** for inline links and table actions.
117
118#### Cards
119
120- Background: `#0c0d0f`
121- Border: `1px solid rgba(245,246,247,0.08)`
122- Shadow: `rgba(0,0,0,0.20) 0 1px 2px`
123- Radius: `radius.lg` (`8px`)
124- Internal padding: `20px` for compact cards, `24–28px` for content cards.
125
126#### Tabs
127
128Variant: `underline`. Flat row of labels. Active tab gets a 2px underline in the accent color — no fill.
129
130#### Charts
131
132- Bar/line variant: `thin-bars`
133- No gridlines — let the bars/lines carry the data.
134- Highlight strategy: `single` — emphasize a single bar/point per chart.
135
136#### Typography pairings
137
138- **Display (`Inter`)** — h1, h2, hero headlines, brand wordmarks.
139- **Body (`Inter`)** — paragraphs, labels, button text, form inputs.
140- **Mono (`Geist Mono`)** — code, eyebrows, metadata, numerals in tables.
141
142### 4 · Hard constraints
143
144Never do any of the following without explicit instruction from the user:
145
146- Introduce a new color, font, radius, or shadow that isn't declared above.
147- Mix this system with another (e.g. don't paste in Material or Bootstrap defaults).
148- Use generic gradient defaults (purple→blue, peach→pink) — they break the system's voice.
149- Reach for emoji icons. Use a consistent icon library and size icons in line with body type.
150- Add motion that exceeds the system's restraint — keep transitions short (≤200ms) and subtle.
151
152### 5 · Before you finish — verify
153
154Run through this checklist for every screen you produce:
155
156- [ ] Every color used appears in the Colors table above.
157- [ ] Headlines use the display font; body copy uses the body font.
158- [ ] Buttons match one of the declared variants exactly (shape, padding, weight).
159- [ ] Border-radius values come from `radius.sm` / `radius.md` / `radius.lg` / `radius.pill`.
160- [ ] Cards and dividers use the declared border + shadow tokens.
161- [ ] No values were invented; if you needed something missing, you stopped and asked.
162
163---
164
165## 1. Atmosphere
166
167Obsidian Rail is a precision dark dev-tool surface. The page is near-black `#0c0d0f` — slightly warmer than true black, never blue. Cards lift to `#1a1c1e`, a 4% lightness step, edged with a single 1px hairline at 8% white. There are no shadows beyond a 1px lift; depth comes entirely from tonal-step + hairline. Headings run in Inter 600 at 68px, body in Inter 400 at 15px on a 1.6 leading. Every ID, timestamp, region, percentage, latency runs in Geist Mono with `font-variant-numeric: tabular-nums` — column-aligned to the millisecond. The single accent is electric mint `#5fe3b1` reserved for active status pills, the primary CTA, and the focus ring — never as a fill, never as a chart background.
168
169The discipline is in the hairline: every divider, every card edge, every table row separator is the same 1px at 8% white. Anything thicker reads as a brand-y SaaS card stack; anything dimmer disappears.
170
171**Signature moves**
172- Near-black warm `#0c0d0f` page → `#1a1c1e` card — single 4% tonal step, never two
173- Every divider, card edge, row separator: 1px at 8% white — one hairline value, system-wide
174- Geist Mono with tabular-nums on every ID, timestamp, region, percentage, latency
175- Mint `#5fe3b1` exclusively on active status pill + primary CTA + focus ring
176- Inter 600 at 68px for hero — calm authority, never display-serif drama
177- 15px body — dev consoles need density, not marketing spacing
178
179## 2. Palette
180
181### Surfaces
182- **Page** `#0c0d0f` — near-black, slight warm undertone
183- **Card** `#1a1c1e` — elevated surface, 4% tonal step
184- **Hairline** `rgba(245,246,247,0.08)` — every divider, every card edge
185
186### Ink
187- **Bone** `#f5f6f7` — primary text
188- **Bone 50** `#8b8e93` — secondary text, mono labels
189
190### Accent
191- **Mint** `#5fe3b1` — active status pill, primary CTA, focus ring, "operational" indicator
192- **Mint Soft** `rgba(95,227,177,0.12)` — focus ring background, hovered status pill
193
194### Status (semantic only — never UI accent)
195- Operational `#5fe3b1` (= mint, the accent doubles as healthy status)
196- Degraded `#e8b95f` — used only on degraded status badges
197- Down `#e87a5f` — used only on down status badges
198
199## 3. Typography
200
201| Role | Font | Size | Weight | Leading | Tracking |
202|------|------|------|--------|---------|----------|
203| Hero | Inter | 68px | 600 | 1.02 | -0.035em |
204| H1 | Inter | 40px | 600 | 1.12 | -0.025em |
205| H2 | Inter | 24px | 600 | 1.25 | -0.012em |
206| Body | Inter | 15px | 400 | 1.6 | -0.005em |
207| UI / Button | Inter | 13px | 500 | 1.4 | 0 |
208| ID / Region / Latency | Geist Mono | 13px | 500 | 1.0 | 0 tabular-nums |
209| Big Metric | Geist Mono | 28px | 600 | 1.0 | 0 tabular-nums |
210| Label | Geist Mono | 11px | 500 | 1.0 | 0.06em uppercase |
211| Timestamp | Geist Mono | 12px | 500 | 1.0 | 0 tabular-nums |
212
213Inter for prose; Geist Mono for every numeric or ID string. The tabular-nums variant is what makes a deploy-log column-align like a terminal.
214
215## 4. Buttons
216
217### Primary (Mint Compact)
218```css
219background: #5fe3b1;
220color: #0c0d0f;
221padding: 9px 18px;
222border-radius: 6px;
223font-weight: 600;
224```
225
226The mint button is the only saturated color on the page — its single appearance carries every primary action. Compact 9px vertical padding because dev tools live in toolbars.
227
228### Secondary (Card Lift)
229- `#1a1c1e` background, 1px hairline at 10% white, bone text — same compact shape
230
231### Outline & Ghost
232- Outline: transparent, 1px hairline at 14% white
233- Ghost: no border, bone-50, hover lifts to bone
234
235## 5. Cards
236
237```css
238background: #1a1c1e;
239border: 1px solid rgba(245,246,247,0.08);
240border-radius: 8px;
241box-shadow: rgba(0,0,0,0.20) 0 1px 2px;
242```
243
244The 4% tonal step is what separates the card from the page; the 1px hairline is the only edge treatment. No gradient borders, no glow, no inset highlight. The active card adds a 1px mint top hairline — the only place mint appears on a card edge.
245
246## 6. Charts
247
248Thin precise bars (3px wide, 3px gap). One bar in mint, others in 22% bone. Line charts at 1.25px bone with a 6% mint fill, ending in a mint dot marker. NO gridlines — the card edge frames the chart. Y-axis labels in Geist Mono uppercase 11px aligned right.
249
250## 7. Tabs
251
252Underline 1.5px in mint for the active state. Inactive tabs are bone-50 in Inter 500. Hover lifts to bone. Tabs sit on a 1px hairline baseline at 8% white.
253
254## 8. Spacing
255
256- Base 4px (table-row aware)
257- Scale: `4, 8, 12, 16, 20, 24, 32, 48, 64, 96`
258- Section padding: 64px desktop, 32px mobile — dev density
259
260## 9. Do's & don'ts
261
262✅ **Do**
263- Use the single 4% tonal step (page → card) and the single 1px hairline at 8% white system-wide
264- Use Geist Mono with tabular-nums on every ID, timestamp, region, percentage, latency
265- Reserve mint for active status pill + primary CTA + focus ring + "operational" indicator
266- Use 15px body — dev consoles need density, not marketing spacing
267
268❌ **Don't**
269- Use gradient borders, glows, or inset highlights — the hairline is the only chrome
270- Use a second UI accent — mint alone, plus muted status colors for degraded/down only
271- Use rounded-full pills for status — 6px capsule with mint or muted-amber/red text
272- Use shadows beyond the 1px lift — the tonal step IS the depth
273
274---
275
276## Tokens
277
278> Generated from the same source the live preview renders from.
279> Treat the values below as the contract — never substitute approximations.
280
281### Colors
282
283| Role | Value |
284|-----------|-------|
285| primary | `#f5f6f7` |
286| secondary | `#8b8e93` |
287| tertiary | `#f5f6f7` |
288| neutral | `#1a1c1e` |
289| surface | `#0c0d0f` |
290
291### Typography
292
293- **Display:** Inter
294- **Body:** Inter
295- **Mono:** Geist Mono
296
297| Role | size / leading / weight / tracking |
298|------|------------------------------------|
299| Hero | 4.25rem / 1.02 / 600 / -0.035em |
300| H1 | 2.5rem / 1.12 / 600 / -0.025em |
301| H2 | 1.5rem / 1.25 / 600 / -0.012em |
302| Body | 0.9375rem / 1.6 / 400 / -0.005em |
303
304### Radius
305
306- sm: `4px`
307- md: `6px`
308- lg: `8px`
309- pill: `9999px`
310
311### Shadows
312
313- **card:** `rgba(0,0,0,0.20) 0 1px 2px`
314- **button:** `none`
315
316### Borders
317
318- **card:** `1px solid rgba(245,246,247,0.08)`
319- **divider:** `rgba(245,246,247,0.08)`
320
321### Buttons
322
323Four variants, each fully tokenized. The preview renders from these exact values.
324
325#### Primary
326
327| Property | Value |
328|----------|-------|
329| shape | `rounded` |
330| background | `#5fe3b1` |
331| color | `#0c0d0f` |
332| border | `none` |
333| padding | `9px 18px` |
334| fontWeight | `600` |
335| fontSize | `0.8125rem` |
336
337#### Secondary
338
339| Property | Value |
340|----------|-------|
341| shape | `rounded` |
342| background | `#1a1c1e` |
343| color | `#f5f6f7` |
344| border | `1px solid rgba(245,246,247,0.10)` |
345| padding | `9px 18px` |
346| fontWeight | `500` |
347| fontSize | `0.8125rem` |
348
349#### Outline
350
351| Property | Value |
352|----------|-------|
353| shape | `rounded` |
354| background | `transparent` |
355| color | `#f5f6f7` |
356| border | `1px solid rgba(245,246,247,0.14)` |
357| padding | `9px 18px` |
358| fontWeight | `500` |
359| fontSize | `0.8125rem` |
360
361#### Ghost
362
363| Property | Value |
364|----------|-------|
365| shape | `rounded` |
366| background | `transparent` |
367| color | `#8b8e93` |
368| border | `none` |
369| padding | `9px 14px` |
370| fontWeight | `500` |
371| fontSize | `0.8125rem` |
372
373### Charts
374
375| Property | Value |
376|----------|-------|
377| variant | `thin-bars` |
378| strokeWidth | `1.25` |
379| fillOpacity | `0.06` |
380| gridlines | `false` |
381| barGap | `3px` |
382| highlight | `single` |
383| dotMarker | `true` |
384
03 · How to use it

Wire it into your agent.

markdown
# CLAUDE.md
Reference @DESIGN.md for all styling decisions. Apply tokens strictly — do not introduce colors, fonts, or radii outside the system. When in doubt, prefer the values declared in DESIGN.md frontmatter.
04 · Required setup

Three snippets.

Google Fonts link

html
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap" />

Install dependencies

bash
npm install lucide-react

Tailwind config

js
// tailwind.config.js
export default {
theme: {
extend: {
fontFamily: {
display: ['"Inter"', 'serif'],
sans: ['"Inter"', 'sans-serif'],
mono: ['"Geist Mono"', 'monospace'],
},
colors: {
primary: '#f5f6f7',
secondary: '#8b8e93',
accent: '#f5f6f7',
neutral: '#1a1c1e',
surface: '#0c0d0f',
},
borderRadius: {
sm: '4px',
md: '6px',
lg: '8px',
},
},
},
};
05 · Keep browsing

Try another system.