Dossier
Pure grey, ruled with hairlines and split down one rail. Square panels, tracked caps labels, one bright cyan.
- Dark by default
- 35 colours · 14 type steps
- Inspired by ryplix.com
The same generated app in every design. Scroll inside the window to see the whole page.
What it is
Dossier reads like a case file on a dark screen. Panels are square on one pure grey ground, and 1px hairlines do all the separating, never shadows or gradients. One vertical rule runs the length of the page: labels and headings sit in a rail on its left, content sits on its right. Tracked caps labels, mono index numbers and tight Plus Jakarta Sans headings carry the structure. One bright cyan marks the main action, the lead figure and focus, and nothing else.
Maintained by @agentic-studio in the open registry.
Best for
It suits analytics consoles, compliance, security and operations tools, and research or agency case studies. It fits teams who want their product to read like evidence, not a pitch.
Trade-offs
- Dense on purpose. Body text is 14px and labels are 11px caps, so a long reading page should step its prose up to body-lg.
- The rail costs width. From 1024px section content sits right of a 22rem label column, so pricing grids and wide tables skip the rail and run full width.
- One colour, rationed. A second brand colour or a colourful illustration will fight the cyan, and in light the cyan fill is only 2.4:1 against the page, so its near-black label carries the button.
Tokens
Generated from this design’s design.yaml, and shipped as CSS variables plus a Tailwind theme. Templates may use these names and nothing else.
Colours
Every colour token in design.yaml, grouped the way the system documents them. These are the dark palette's values. The light palette uses the same names with its own values, and tokens.css ships both.
Brand and accent
accent
#2aabe2
accent-1
#2aabe2
accent-2
#e2e2e2
accent-3
#0d76a0
accent-4
#b7913b
accent-5
#8ad4f0
accent-6
#8a8a8a
accent-hover
#4fbcea
accent-soft
#1c2529
primary
#2aabe2
Surface
canvas
#1b1b1b
hairline
#333333
surface-card
#212121
surface-dark
#141414
surface-dark-elevated
#212121
surface-soft
#1b1b1b
surface-solid
#272727
surface-strong
#272727
Text
body
#c6c6c6
body-strong
#e2e2e2
ink
#f5f5f5
muted
#a8a8a8
muted-soft
#8a8a8a
on-accent
#141414
on-dark
#f5f5f5
on-primary
#141414
Semantic
error
#d87e77
success
#55a875
warning
#b7913b
Other
danger
#d87e77
danger-soft
#271c1b
error-soft
#271c1b
primary-hover
#4fbcea
success-soft
#19221c
warning-soft
#231e15
Type scale
Each token rendered at its real size, weight, line height and tracking. Specimens fall back to this site's typeface when the design's own face is not installed locally, so read the numbers, not the letterforms.
Ship faster
- Token
- display-xl
- Values
- 3.5rem · 56px · 600 · lh 1.04 · ls -0.035em
Ship faster
- Token
- display-lg
- Values
- 3rem · 48px · 600 · lh 1.06 · ls -0.033em
Ship faster
- Token
- display-md
- Values
- 2.625rem · 42px · 600 · lh 1.08 · ls -0.03em
Ship faster
- Token
- display-sm
- Values
- 1.875rem · 30px · 600 · lh 1.12 · ls -0.028em
Ship faster
- Token
- title-lg
- Values
- 1.5rem · 24px · 600 · lh 1.2 · ls -0.022em
Ship faster
- Token
- body-lg
- Values
- 1.0625rem · 17px · 400 · lh 1.55 · ls -0.004em
Ship faster
- Token
- title-md
- Values
- 1.0625rem · 17px · 600 · lh 1.35 · ls -0.012em
Ship faster
- Token
- title-sm
- Values
- 0.9375rem · 15px · 600 · lh 1.4 · ls -0.006em
Ship faster
- Token
- body-md
- Values
- 0.875rem · 14px · 400 · lh 1.6 · ls 0.005em
Ship faster
- Token
- body-sm
- Values
- 0.8125rem · 13px · 400 · lh 1.55 · ls 0.005em
Ship faster
- Token
- button
- Values
- 0.8125rem · 13px · 500 · lh 1 · ls 0.005em
Ship faster
- Token
- nav-link
- Values
- 0.8125rem · 13px · 500 · lh 1.4 · ls 0.005em
Ship faster
- Token
- caption
- Values
- 0.75rem · 12px · 500 · lh 1.45 · ls 0.01em
SHIP FASTER
- Token
- caption-uppercase
- Values
- 0.6875rem · 11px · 500 · lh 1.4 · ls 0.16em
Typefaces
The families the generated Tailwind theme points at. A licensed face is named here even when the substitute below is what actually renders.
- DisplayPlus Jakarta Sans, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
- BodyPlus Jakarta Sans, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
- MonoJetBrains Mono, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace
Spacing scale
Drawn at true size. These are the only gaps and paddings a generated repo is allowed to use.
- xxs0.25rem · 4px
- xs0.5rem · 8px
- sm0.75rem · 12px
- md1rem · 16px
- lg1.5rem · 24px
- xl2rem · 32px
- xxl3rem · 48px
- section4.5rem · 72px
Radius scale
Sample shapes at true corner radius. Buttons and inputs sit at the small end of this scale, feature cards at the large end.
- lg0 · 0px
- xl0 · 0px
- xs0.125rem · 2px
- sm0.25rem · 4px
- md0.5rem · 8px
- full9999px
- pill9999px
Elevation
Shadow tokens on a neutral card, at true blur and spread.
- insetinset 0 1px 0 rgb(255 255 255 / 0.2)
- lift0 0 #0000
- overlay0 24px 48px rgb(0 0 0 / 0.7)
- ring0 0 0 3px rgb(42 171 226 / 0.35)
- soft0 0 #0000
- xs0 0 #0000
DESIGN.md
Ships in your repo as DESIGN.md. The designer agent reads it before it may introduce a new visual pattern. This is the briefing, not a page about the briefing.
Dossier is a dark, square, flat design that reads like a case file. One pure grey ground, panels drawn with 1px hairlines, and from 1024px one vertical rule that files every section's label on its left and its content on its right. Plus Jakarta Sans sets the words, JetBrains Mono the numbers and indexes, and one bright cyan marks the main action. Light is the same file printed on grey paper.
Read this before you add a screen, a component or a colour. The tokens live in
src/app/globals.css, the faces in src/app/fonts.ts, the kit in
src/components/ui/.
At a glance
| Theme | Dark first: a #1b1b1b ground with #212121 cards. Light is a #f5f5f5 ground with white cards. |
| Type | Plus Jakarta Sans 600 headings with tight tracking, 14px body, 11px tracked caps labels, JetBrains Mono for numbers. |
| Colour | Pure greys plus one cyan (#2aabe2) with a near-black label, and #00688f wherever cyan is text in light. |
| Shape | Square panels (lg and xl are 0). 8px controls, 2px tags, true circles only for avatars, radios and dots. |
| Depth | Flat. Hairlines separate; only menus, dialogs, sheets and toasts carry a shadow. |
| Signature | The rail: one vertical rule at 25.5rem from header to footer, labels left, content right, under indexed caps eyebrows. |
Principles
- Separate with a 1px hairline or one step of fill, nothing else.
- Panels are square; only controls round.
- File every section on the rail: label left, content right.
- Spend cyan on one thing per view.
- Numbers, indexes, ids and keys go in mono; words never do.
Colour
Palette
| Token | Light | Dark | Role |
|---|---|---|---|
canvas (--background) | #f5f5f5 | #1b1b1b | The page floor |
surface-soft | #f5f5f5 | #1b1b1b | Section bands, sidebars, table heads |
surface-card (--muted) | #ffffff | #212121 | Tinted fills: inactive tabs, hover rows, code |
surface-strong | #e9e9e9 | #272727 | Pressed fills, progress tracks |
surface-solid (--popover) | #ffffff | #272727 | Menus, selects, toasts: always opaque |
card | #ffffff | #212121 | The card fill |
surface-dark | #1b1b1b | #141414 | The inverted panel |
hairline (--border) | #dcdcdc | #333333 | Every border and divider |
ink (--foreground) | #1b1b1b | #f5f5f5 | Headings and primary text |
body-strong | #2e2e2e | #e2e2e2 | Emphasised body text |
body | #4d4d4d | #c6c6c6 | Running text |
muted (--muted-foreground) | #646464 | #a8a8a8 | Secondary text, captions |
muted-soft | #8a8a8a | #8a8a8a | Placeholders, disabled text, icons at rest |
primary | #2aabe2 | #2aabe2 | The action colour |
accent (--accent-fill) | #00688f | #2aabe2 | The saturated accent: links, the accent badge |
accent-soft | #e6eff3 | #1c2529 | The tint an accent label sits on |
danger (--destructive) | #984540 | #d87e77 | Destructive actions and errors |
success, warning and error each come with a -soft tint for the back of a
badge or an alert: #0d6d3f, #795a00 and #984540 in light, #55a875, #b7913b and
#d87e77 in dark.
Dossier's own variables, read by the landing hooks and the kit:
--border-strong (#c4c4c4 light, #424242 dark), --bloom (rgb(42 171 226 /
0.3) light, rgb(42 171 226 / 0.35) dark).
How colour is used
- Every neutral is pure grey: a #1b1b1b ground, #212121 cards, #272727 raised surfaces, #333333 hairlines and #424242 for frames you touch.
- Cyan (#2aabe2) fills the primary button, checked controls, progress and the first stat cell, always with near-black #141414 text (7:1).
- Cyan as text uses text-accent: #2aabe2 on dark, #00688f on light, where the fill colour would fail.
- Status colours stay muted (green, ochre, brick red) and only appear as soft fills, status text and 2px rules.
- The CTA panel is #141414 in both modes and the dark card stays near-black; text on them uses on-dark, never text-muted in light.
Charts
accent-1 to accent-6 (also chart-1 to chart-6) are six series colours
ordered so neighbours stay distinguishable. Six series stay in the file's own
family: cyan, light grey, deep cyan, ochre, pale cyan and mid grey on dark; deep
cyan, ink, bright cyan, ochre, navy and grey on light. Lead with chart-1 and let
the greys carry the context. Assign them in order; never let colour be the only
way to tell two series apart.
Dark mode
The palette is declared twice in src/app/globals.css: light on :root, dark
under @media (prefers-color-scheme: dark) and again on .dark, where the
class wins in both directions. @theme inline points every utility at those
variables, so bg-canvas is one class that follows the mode.
src/lib/design.ts sets the theme a first visit opens in: dark here, because
Dossier is drawn in dark first. The theme menu in the header offers light, dark
and system and remembers the choice.
Type
Faces
- Plus Jakarta Sans (
font-display,font-body): headings and display type; running text and interface copy. - JetBrains Mono (
font-mono): code, ids and tabular labels.
Plus Jakarta Sans is a geometric sans with open counters that stays crisp at 600 with tight tracking and reads cleanly at 13px to 14px. JetBrains Mono has a tall x-height and even shapes, so 11px index numbers, ids and keys stay legible.
Every face loads through next/font/google in src/app/fonts.ts: downloaded at
build time and served from this app. Change a face there and here, together.
Scale
| Token | Size | Line | Tracking | Weight | Use |
|---|---|---|---|---|---|
text-display-xl | 56px | 1.04 | -0.035em | 600 | The hero headline, desktop |
text-display-lg | 48px | 1.06 | -0.033em | 600 | The hero headline, tablet |
text-display-md | 42px | 1.08 | -0.03em | 600 | Section headlines, the hero on phones |
text-display-sm | 30px | 1.12 | -0.028em | 600 | Section headlines on phones, big numbers |
text-title-lg | 24px | 1.2 | -0.022em | 600 | Page titles in the app |
text-title-md | 17px | 1.35 | -0.012em | 600 | Card titles |
text-title-sm | 15px | 1.4 | -0.006em | 600 | Small headings, table titles |
text-body-lg | 17px | 1.55 | -0.004em | 400 | Lead paragraphs |
text-body-md | 14px | 1.6 | 0.005em | 400 | Running text |
text-body-sm | 13px | 1.55 | 0.005em | 400 | Interface copy, table cells |
text-caption | 12px | 1.45 | 0.01em | 500 | Metadata, helper text |
text-caption-uppercase | 11px | 1.4 | 0.16em | 500 | Eyebrows above headings |
text-button | 13px | 1 | 0.005em | 500 | Buttons |
text-nav-link | 13px | 1.4 | 0.005em | 500 | Header and footer links |
Rules: one h1 per page. Display sizes are for marketing pages; the app tops
out at text-title-lg. Headings are Plus Jakarta Sans 600 with negative
tracking and stay small: the hero (56px at most) is the only big type, and every
landing section title is 30px. Labels are 11px caps at 0.12em to 0.16em. Mono
carries numbers and references only.
Space and layout
- Spacing tokens:
xxs4px,xs8px,sm12px,md16px,lg24px,xl32px,xxl48px,section72px (the gap between landing sections). - Content sits in
max-w-content(1280px) withpx-mdon phones andpx-lgfromsmup. Reading text stops atmax-w-measure(672px). - Compact: 13px interface type, 32, 40 and 44px controls, 16, 20 and 28px card padding, 72px sections.
- From 1024px every landing section sits on a 22rem label column, a 4rem gap and one rule centred in the gap, 25.5rem from the content edge.
- Pricing and wide tables skip the rail and run full width; below 1024px everything stacks on the left edge.
- The content column is 80rem and the reading measure 42rem.
Shape and depth
| Token | Value | Where |
|---|---|---|
rounded-xs | 2px | Badge, Breadcrumb, Checkbox, Kbd, Skeleton, Switch, Tooltip |
rounded-sm | 4px | Accordion, Dialog, DropdownMenu, Select, Sheet, Tabs, Toaster, the landing page |
rounded-md | 8px | Button, Input, Tabs, the landing page |
rounded-lg | 0 | AlertDialog, Alert, Card, Dialog, DropdownMenu, Popover, Select, Toaster, the landing page |
rounded-xl | 0 | The landing page |
rounded-pill | 9999px | The landing page |
rounded-full | 9999px | Avatar, RadioGroup |
Cards, dialogs, sheets, popovers, menus, alerts, toasts and pictures are square. Buttons and fields take 8px corners; badges, checkboxes, kbd and switches 2px. Three shadows are none: the overlay shadow floats menus and dialogs, a 1px white inset lights the top edge of cyan fills, and a 3px cyan halo marks focused fields.
Components
Every component lives in src/components/ui/ and is written against the tokens
above. Import from there; never restyle a kit component inline to make a
one-off.
| Component | In Dossier |
|---|---|
Button | 8px corners, Plus Jakarta Sans 500 at 13px, sentence case, and a 1px border on every variant (transparent where unseen) so sizes match. Primary is cyan with a near-black label and a 1px inset top highlight; secondary a card fill with a hairline; outline transparent with the input border; ghost body text with a faint ink tint on hover; danger a brick fill with the same highlight; link cyan text. Heights 32, 40 and 44px, icon buttons 36px square. Focus is a 2px cyan outline set 2px off the edge, and a pressed button moves down 1px. No pills, no outer shadows. |
Badge | A square tag, 2px corners and 20px tall, Plus Jakarta Sans 600 at 11px and always caps: 0.06em tracking, 0.14em with uppercase. Neutral is drawn with the input border and muted text; accent is the only solid badge (cyan with a near-black label); success, warning and danger use their soft fills and status text. |
Card | A square #212121 panel (white in light) with a hairline and no shadow. Soft is the ground with a hairline, strong a raised fill with no line, outline transparent, dark a near-black panel with on-dark text. Padding 16, 20 and 28px with 16px between parts. Title 17px 600, description 13px muted, and the footer sits under a hairline with its actions right. |
Input, Textarea, Select | 40px tall, 8px corners, a transparent fill on the input border, 14px ink text, placeholder in muted-soft. Hover lifts the line to muted-soft, focus turns it cyan with a 3px cyan halo, invalid turns it danger with a danger halo. The select chevron is muted-soft; its content is a square solid panel with the overlay shadow, an ink tint on the highlighted item and a cyan check. |
Checkbox, RadioGroup, Switch | Checkbox: a 16px square with 2px corners on the input border, cyan with a near-black check and an inset highlight when on. Radio: a true circle with an 8px cyan dot. Switch: a hardware toggle, a 2px-cornered track with a square thumb, grey on a raised track when off, cyan when on. All three take the 2px cyan focus outline. |
Tabs | Default is a 36px segmented strip with 8px corners in the input border, cells split by hairlines and the active cell on the raised fill in ink. Line tabs sit on a bottom hairline and mark the active one with a 2px cyan bar on the rule. |
Accordion | Rows split by hairlines. Triggers are 15px 600 ink with a muted-soft chevron that turns when open; answers are 14px body grey with right padding that clears the icon. |
Dialog, AlertDialog, Sheet | Square solid panels with a hairline and the overlay shadow over a surface-dark scrim at 70%, no blur. The dialog header sits over a hairline and the footer under one, actions right aligned; the alert dialog is narrower and rules only its footer. Sheets draw a hairline only on the edge that faces the page and rule their header and footer. Close buttons are 32px with 4px corners. |
DropdownMenu, Popover, Select content, Tooltip | Square solid panels with a hairline and the overlay shadow. Items are 13px with 4px corners and an ink tint on highlight; group labels are 11px caps; shortcuts are mono; checks and radio dots are cyan. Tooltips are tiny inverted ink tags with 2px corners and no arrow. |
Table | Caps heads (11px, 0.12em, 600, muted) at 36px over a hairline, no fill. Rows are 44px of 13px body text split by hairlines, with a faint ink tint on hover and a stronger one when selected. Figures are tabular; give numeric cells font-mono text-right. |
Alert | A square card panel with a hairline and a 2px left rule in the status colour; info uses cyan. The icon takes the status colour, the title is 13px 600 ink and the description 13px body grey. |
Avatar, Progress, Skeleton, Spinner, Separator, Kbd, Breadcrumb, Pagination, Field, Label, Toaster | Avatars are true circles on a raised fill with mono caps initials and a faint ink inner ring. Progress is a 4px square bar, cyan on a raised track. Skeletons pulse in a faint ink tint with 2px corners; the spinner is a 16px loader in the text colour. Separators are hairlines. Kbd is mono 11px with 2px corners on the input border. Breadcrumbs are 13px with muted-soft chevrons and the current page in ink 500. Pagination uses 36px boxes with the current page outlined. Labels are 11px caps in muted above their field and 13px sentence case beside a checkbox, radio or switch, with 6px field gaps. Toasts are square with a 2px status rule and a cyan info icon. |
The landing page
The landing page is the same in every design; the design decides how it looks.
Its sections carry data-slot hooks (listed at the top of
src/components/marketing/section-heading.tsx) that globals.css may style.
Dossier styles these:
site-header: the page ground with no blur, 56px tall, a hairline under it; it resets the section counter.brand-mark: an ink square with a mono initial, so the header's only cyan is its button.site-nav: from 1024px it opens on a left hairline at the rail, which drops on through the hero.hero-backdrop: no wash; from 1024px it draws the rail rule at 25.5rem down the whole hero.hero-eyebrow: a square caps tag in the stronger hairline with the arrow in its own cell; from 1024px it tops the rail.hero-title,hero-subtitle,hero-actions: left aligned; from 1024px the statement sits right of the rail.hero-note: a footnote under a short rule, filed at the foot of the rail.hero-visual,product-preview,showcase-visual: square, flat pictures on the ground in the stronger hairline, with four crop marks outside the corners from 640px.section: one top rule and no bottom rule; from 1024px each band draws the rail and files its heading left, its content right.section-eyebrow: a mono index in a hairline box (01, 02, 02.1), then the caps word in grey.section-title: 30px at every size, left aligned.logo-cloud,logo: the caption in the rail and the names as equal cells split by hairlines.feature-grid,feature-card,feature-icon: a ruled table of cells sharing 1px lines, a mono index top right, an outlined ink icon.steps,step,step-marker: ruled rows with a cyan mono number in a 3.5rem margin; no discs, no connector.stat-grid,stat: a ruled row of square cells; the first is solid cyan with its near-black label.testimonial: quotes become statements on file, one per ruled row.faq: ruled rows; the open question carries a 2px cyan tick on its left edge.cta-panel: a #141414 panel in both modes, square and flat, the title in its own rail and the buttons on the right.site-footer: the same ground, split on the rail, the link columns on the right.
Everything else is type, space and the kit.
Signed-in screens
The dashboard sidebar is the page ground cut off by one hairline, with the active item on a card fill in ink, under a 56px top bar; cards are square #212121 panels and KPI tiles read as ruled cells with caps labels and tabular values. Settings and sign-in use square cards with caps labels over drawn 40px fields and one full-width cyan submit.
Do and don't
Do
- Separate things with a 1px hairline or one step of fill.
- Keep panels square; round only controls (8px) and true circles.
- File each landing section on the rail from 1024px: label left, content right.
- Spend cyan on one thing per view: the main button, the lead figure, focus or a link.
- Put near-black on-primary text on every cyan fill.
- Set small labels in 11px caps at 0.12em to 0.16em.
- Set numbers, indexes, ids and keys in JetBrains Mono with tabular figures.
- Use text-accent for cyan text: #2aabe2 on dark, #00688f on light.
Don't
- Don't add gradients, glows or washes; the faint bloom under the two big calls to action is the only glow.
- Don't put a drop shadow on anything that does not float.
- Don't tint the greys or add a second accent.
- Don't use pills on buttons, badges, tabs, inputs or switches.
- Don't put white text on the cyan (2.6:1).
- Don't set body text under 13px or display text over 56px.
- Don't centre section headings or stack two rules.
- Don't use text-muted inside a dark card or on surface-dark in light; use on-dark at 70%.
Working in this design
Pasting from shadcn/ui. The token layer carries shadcn's variable names, so
most snippets render unmodified. Two utility names mean something else here:
bg-muted becomes bg-surface-card, and bg-accent / text-accent-foreground
(a hover surface upstream) become bg-surface-card / text-ink. Here muted
is a text colour and accent is the saturated accent.
Adding a token. Add it to all three palette blocks in globals.css (light,
the dark media query, .dark), map it in @theme inline, and document it in
the palette table above. Check contrast in both modes.
Adding a component. Check the kit first: most needs are a variant of
Button, Card or Badge, or a composition on the page. A new component gets
its own file in src/components/ui/, token classes only, a data-slot, and a
row in the Components table here. The designer subagent owns this.
Build a repo in Dossier
The builder opens with Dossier picked. Pick your batteries and the design is applied to every template before the zip is built.
