Foundations
The panel uses warm greys, restrained typography and small corners. These choices come from shared tokens, not per-page styling. The tables below resolve values directly from packages/ui/src/styles/tokens.css at build time.
Colour architecture
Section titled “Colour architecture”Palette names describe a pigment: --cp-sandstone-*, --cp-deepslate-*, Signal, Amber, Ember and Ash. Semantic names describe a job: --cp-surface, --cp-fg, --cp-warning. Components use the semantic names, so they adapt to light and dark mode without choosing a second palette themselves.
Surfaces and text
Section titled “Surfaces and text”| Token / purpose | Light | Dark |
|---|---|---|
--cp-bgPage canvas | #f4f1ea | #171614 |
--cp-bg-subtleSecondary page area | #ece8de | #1e1c1a |
--cp-surfacePanels, inputs and dialogs | #fbfaf6 | #23211e |
--cp-surface-mutedQuiet fills, hover and selection | #ece8de | #2a2824 |
--cp-borderDividers and panel edges | #d9d3c7 | #37332e |
--cp-border-strongStronger boundaries | #b9b1a3 | #4f4a43 |
--cp-fgPrimary text | #1c1b18 | #ece8df |
--cp-fg-mutedDescriptions and secondary labels | #5f5a52 | #a8a197 |
--cp-consoleConsole background | #1a1917 | #0f0e0d |
--cp-console-fgConsole text | #ece8df | #e4e0d7 |
--cp-console-mutedConsole timestamps, system lines, hints | #9a9488 | #9a9488 |
Use bg for the page canvas, surface for a panel or control, and surface-muted for a quieter fill. Separate areas with spacing or a border before adding another background. fg-muted still carries readable information; it is not a disabled state.
The console has its own dark surface in both themes. Use console-fg with it rather than the page’s text colour, console-muted (5.8:1 on the surface) for timestamps, system lines, the prompt and placeholders, Signal green (brand) for commands you sent, and the status tokens for severity. Never reach for a palette colour such as neutral-500 or sky-300, or a white/10 border: those ignore the tokens and fall below the contrast floor.
Brand, interaction and status
Section titled “Brand, interaction and status”| Token / purpose | Light | Dark |
|---|---|---|
--cp-brandBrand mark and brand moments | #5bbf4a | #5bbf4a |
--cp-brand-textReadable brand text | #2f6b25 | #5bbf4a |
--cp-brand-buttonBrand button background | #2a5f21 | #5bbf4a |
--cp-brand-button-fgBrand button text | #ffffff | #10200a |
--cp-accentNeutral focus and interaction | #1c1b18 | #ece8df |
--cp-accent-fgText on the neutral accent | #fbfaf6 | #171614 |
--cp-successSuccess text and tinted states | #2f6b25 | #5bbf4a |
--cp-warningAttention text and tinted states | #8a5a00 | #e8b04a |
--cp-dangerError text and tinted states | #b8321f | #ef5a4f |
--cp-neutralNeutral status text | #5c636a | #9aa1a8 |
--cp-status-runningRunning dot or bar | #5bbf4a | #5bbf4a |
--cp-status-startingStarting or stopping dot | #e8b04a | #e8b04a |
--cp-status-crashedCrashed or error dot | #ef5a4f | #ef5a4f |
--cp-status-stoppedStopped or disconnected dot | #9aa1a8 | #9aa1a8 |
| Role | Use | Avoid |
|---|---|---|
| Brand | Logo, setup, update announcements and website calls to action | Making every panel action green |
| Accent | Neutral focus ring, selected choice, active tab and ordinary primary action | Using amber as an interaction accent |
| Status fill | Small dots and bars identifying a lifecycle state | Reusing a bright status fill for small text on a light surface |
| Status ink | success, warning, danger, neutral text and tinted feedback |
Decorative colour unrelated to the data |
Running and the brand share Signal green, but their roles remain distinct. A green running badge describes a server. A selected preset uses a neutral border even if it is the recommended option.
Status fills stay constant between themes. Text colours become darker in light mode for readability. See States and accessibility for the exact lifecycle mapping and contrast limits.
Typography
Section titled “Typography”Your server. Your hardware.
Everything you need to run your world.
[20:03:14 INFO]: Done (8.412s)!
What's new in CraftPanel
| Family | Weight | Role |
|---|---|---|
| Mona Sans | 500; 600 for the wordmark | Page, section, card and dialog headings |
| Inter | 400 body; 500 labels/buttons; occasional 600 emphasis | Default interface copy, descriptions and controls |
| Mona Sans Mono | 400–500 | Commands, logs, file paths, ports, versions, chart axes and technical labels |
| Geist Serif | 400 only | The “What’s new” heading and rare editorial brand copy |
Use tabular numerals for values that update or need comparison. The Stat primitive uses sans numerals with tabular-nums; technical strings and chart axes use Mono. Do not turn an entire form into monospace text.
Size hierarchy in the panel
Section titled “Size hierarchy in the panel”These sizes describe the shared helpers and common product patterns. They are not the website’s much larger hero scale.
| Use | Size / Tailwind | Typical implementation |
|---|---|---|
| Page title | 24 px / text-2xl |
PageHeader, server header |
| Primary reading | 20 px / text-xl |
Stat; performance cards use 30 px / text-3xl |
| Major local heading | 16 px / text-base |
Performance overview, tuning, dialog title |
| Section heading | 14 px / text-sm |
Section |
| Control text | 14 px, or 13 px compact | Button, Input, compact actions |
| Label / description | 13 px | Field, PageHeader descriptions, settings rows |
| Supporting text | 12 px / text-xs |
Help, badges, secondary metric context |
| Dense machine metadata | 10–11 px | Chart axes, keyboard hints and property keys; keep essential instructions larger |
DialogHeader currently uses 600 for its title; most headings use 500. Reuse the helper rather than overriding its weight on each screen. Nothing in the panel needs a weight above 600.
Tracking and font delivery
Section titled “Tracking and font delivery”| Token | Value | Application |
|---|---|---|
--cp-tracking-body |
−0.005 em | Inter body and UI copy |
--cp-tracking-heading |
−0.012 em | Headings; tracking-tight in the panel |
--cp-tracking-display |
−0.02 em | Large displays |
Code and monospace content reset tracking to zero. Geist Serif has one weight; font-synthesis-weight: none prevents fake bold. All four families are self-hosted. The panel loads its local font files through next/font/local and geist/font/serif; the website and docs use the shared font stylesheet.
Spacing and density
Section titled “Spacing and density”Use the 4 px spacing scale for the main layout. Small component details also use half steps, such as the 6 px gap inside a badge.
| Distance | Tailwind | Typical job |
|---|---|---|
| 4 px | gap-1, space-y-1 |
Label and short value |
| 8 px | gap-2, space-y-2 |
Field content, adjacent actions |
| 12 px | gap-3, p-3 |
Compact rows and small groups |
| 16 px | gap-4, p-4 |
Panel content, chart cards, console padding |
| 20–24 px | p-5, p-6, gap-5, gap-6 |
More spacious cards and dialogs |
| 32–40 px | space-y-8, space-y-10 |
Major page sections |
Keep descriptions attached to the setting or metric they explain. Use larger gaps between independent tasks than between a label and its control.
Corners, borders and elevation
Section titled “Corners, borders and elevation”| Token | Panel utility mapping |
|---|---|
--cp-radius-sm |
rounded-xs, rounded-sm |
--cp-radius |
rounded-md |
--cp-radius-lg |
rounded-lg, rounded-xl, rounded-2xl |
The radius names are mapped in apps/web/src/app/globals.css. rounded-xl therefore means 6 px, not Tailwind’s usual larger corner. Circular status dots, switches and avatars keep their circular shapes.
Major surfaces use thin borders and no decorative elevation. Dialogs, menus and tooltips use shadows to establish an overlay layer; existing primitives also include small control shadows. Do not add a large drop shadow to an ordinary panel. Solid dividers are the default; dashed outlines are reserved for patterns such as empty or drop areas.
Icons and the mark
Section titled “Icons and the mark”The panel uses Lucide React icons: usually 16 px in buttons and rows, 12 px in badges, and 14 px in compact contexts. Use currentColor through semantic classes. Keep icon meaning consistent: play for start, square for stop, rotate for restart, and a warning triangle for a problem. Give an icon-only action an accessible name.
The website’s pixel icons and isometric illustrations belong to its presentation language. They do not replace the panel’s Lucide controls.
The CraftPanel mark is an isometric block with a console prompt. Preserve its proportions and original colours. Only the top face changes with the theme: #c6cbc5 in light mode and #e6e8e3 in dark mode. Do not recolour the top face green or add effects around the mark.
The name itself is a wordmark: “Craft” in Mona Sans 600, “Panel” in Mona Sans 400 and a Signal green underscore, the cursor of the console prompt, after it. Use it wherever the product name is shown (sidebar, mobile header, website navigation, documentation header) and let it take its size from the surrounding font size. The cursor blinks three times on load and while hovered, and stands still for reduced motion. Show the block mark on its own (loading state, sign-in, favicons) and not next to the wordmark.