Style guide
Every component the site has, rendered from the real templates with sample data, and the tokens read straight out of styles.css. If a thing is not on this page, the site does not have it yet. Use the theme switcher in the footer, or the Themes section below, to check the other schemes.
Tokens
Light value, then the dark override where one exists. Templates and rules use these names only.
Colors
| Token | Light | Dark |
|---|---|---|
--brand |
#110e08 | #000000 |
--brand-ink |
#ffffff | — |
--brand-ink-2 |
#dfe6f5 | — |
--brand-ink-muted |
#cdd7ee | — |
--brand-wash |
rgba(255, 255, 255, .12) | — |
--brand-wash-2 |
rgba(255, 255, 255, .16) | — |
--brand-line |
rgba(255, 255, 255, .4) | — |
--accent |
#ccff00 | #ccff00 |
--accent-2 |
#7ea800 | #7ea800 |
--ink-2 |
#35322d | #35322d |
--on-ink |
#ffffff | — |
--on-ink-muted |
rgba(255, 255, 255, .62) | — |
--on-ink-faint |
rgba(255, 255, 255, .14) | — |
--on-ink-line |
rgba(255, 255, 255, .4) | — |
--on-lime-muted |
rgba(17, 14, 8, .66) | — |
--accent-ink |
#110e08 | #110e08 |
--up |
#0a9d4f | #2fcf7a |
--down |
#c0392b | #ff6b5f |
--on-signal |
#ffffff | — |
--bg |
#ffffff | #110e08 |
--surface |
#ffffff | #1c180d |
--surface-2 |
#f1f3f4 | #35322d |
--text |
#110e08 | #f4f5f6 |
--link |
#110e08 | #ccff00 |
--muted |
#585e63 | #9aa1a7 |
--border |
#d7dadd | rgba(255, 255, 255, .13) |
--graph-node |
#2f4a9e | #7c9cf5 |
--graph-link |
#8a97ad | #5a6a85 |
Shadows
| Token | Light | Dark |
|---|---|---|
--shadow |
none | 0 1px 2px rgba(0, 0, 0, .3), 0 10px 30px rgba(0, 0, 0, .35) |
--shadow-sm |
none | 0 1px 2px rgba(0, 0, 0, .3) |
Sizes
| Token | Light | Dark |
|---|---|---|
--radius |
4px | — |
--radius-sm |
4px | — |
--radius-pill |
36px | — |
--maxw |
1080px | — |
Fonts
| Token | Light | Dark |
|---|---|---|
--font |
"Hanken Grotesk", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif | — |
--font-serif |
"Newsreader", Georgia, "Times New Roman", serif | — |
Type
Display, Newsreader 500
.displayPage head, 2.5rem serif
.page-head h1Heading two, card titles
h2 .card-titleThe lede: one sentence under a headline, muted, 1.08rem, max 60 characters wide.
.ledeBody text in Hanken Grotesk at 16px, line height 1.55. Numbers in tables use tabular figures 1,234.56 so columns line up.
bodyMuted text for labels and secondary lines.
.mutedSmall text, .85rem.
.smallInline code on a surface.
codeSymbol and name
.stock-symbol .stock-nameButtons
One primary action per screen. Buy is --up, Sell is --down; both also carry a word, never color alone.
Pills and range buttons
Price
Ticker (dashboard)
- Best ask
- $4.98
- Market cap
- $498,000
- Circulating
- 24,810 / 100,000
Quote block (stock page)
Direction
▲ up · ▼ down · ■ flat .up .down .flat, always with the glyph
Stat
Key / value list
- Previous close
- $4.95
- 52-week high
- $5.32 Feb 22, 2026
- First trade
- Jan 26, 2008
Identity
Douglas Dollars
Trader renews Jan 1, 2027
Tier badges
"Since DATE" joins the kicker once the engine exposes created_at (kmikeym-engine#18).
Tables
Order book
Bids (buyers)
| Price | Shares |
|---|---|
| $4.26 | 10 |
| $4.25 | 11 |
| $4.04 | 10 |
| and 1 more price level | |
Asks (sellers)
| Price | Shares |
|---|---|
| $4.98 | 48.25 |
| $4.99 | 2.03 |
| $5.20 | 4 |
| and 1 more price level | |
Trades
| When | Price | Shares |
|---|---|---|
| 2026-08-26 20:24:14 | $4.98 | 8.11 |
| 2026-08-26 01:50:19 | $4.95 | 0.95 |
| 2026-08-26 01:50:19 | $4.98 | 1.59 |
Empty state
| When | Price | Shares |
|---|---|---|
| No trades yet. | ||
Cards and grids
Card
Surface, radius, shadow from tokens.
Three up
.grid .grid-3, one column on phones.
Two up
.grid .grid-2 for book and tape.
Hero
The dashboard opener: headline plus lede on a brand surface.
Forms
Messages
Chart
Up
Down
Loading
Empty
Inline SVG from Support\Chart and the same drawing in app.js; no library. Colors follow --up, --down, --accent.
Bands (home page)
Paper band
Data in ink. Waffle, tape.
Themes
A theme is one file of token values under public/assets/themes/ and nothing else. <html data-theme> selects it; the choice is kept per browser. If a theme needs a template change, the component is wrong, not the theme.
- Default follows the system scheme (the Light and Dark columns in Tokens above).
- Light and Dark pin one scheme whatever the system says. Tests hold them identical to the two columns.
- Minimal: one typeface, black on white, no lime, no radius, no shadow, direction by glyph only. It restates every token, so it is the proof that the tokens are strict.
Rules
- Serif above 40 px only. Newsreader for the display sizes (
.display,.display-2, page heads at 2.5rem); everything smaller is Hanken. - Tokens only. No literal color, size or font name in a template or a rule. The test suite checks templates (must be zero) and ratchets the stylesheet (see Debt).
- Numbers are decimal strings from the engine. Format once in
Support\Format; never do money math in floats; never recompute a displayed number in JavaScript. - One primary action per screen. Buy and Sell carry their word as well as their color.
- Direction always has a glyph (▲ ▼ ■) so it survives a theme with no color.
- Works without JavaScript. JS is enhancement: the live ticker, the chart redraw, the nav. Every page must read and every form must submit with it off.
- Copy is in full kayfabe. Absurd things are written as plain product facts. No winks, no "it's a bit." The word is "shareholder", never "experiment". No em dashes anywhere.
- Phone first. Grids collapse at 760px, the book at 560px; check this page at 390px wide.
Debt: literal colors still in styles.css
2 outside the token blocks (baseline 2; the test fails if it grows). What is left is the two off-canvas nav scrims. Each one is a token waiting to be named.
| Line | Value |
|---|---|
| 138 | rgba(0, 0, 0, .35) |
| 147 | rgba(0, 0, 0, .5) |
Not built yet
Named in the plan (kmikeym-web#8), no component exists. When one is built it appears above by construction.
- Soft-cap meter with the payout sentence
- "Since DATE" on the identity block (needs
created_atfrom the engine) - Punch card for bounties