Tokens
Every shared value on the site. Components consume these instead of carrying one-off values — check here before introducing a new color, and never ship a hex that isn't on this list.
--canvas
--surface
--surface-soft
--ink
--muted
--line
--green
--green-strong
--green-soft
--control
--nav
- --canvas
#f0f2f5· dark#18191a— the app background. Surfaces sit on it, never beside it. - --surface
#ffffff· dark#242526— cards, panels, the drawer. - --surface-soft
#f7f8fa· dark#2f3031— quiet fills inside surfaces. - --ink
#14171a· dark#f2f3f5— primary text. - --muted
#65676b· dark#b0b3b8— secondary text and metadata. - --line
#e1e4e8· dark#3a3b3c— borders and dividers. - --green
#1a7f37in both themes — primary actions, the contact panel, the review FAB. Clears 4.5:1 with white text, so buttons and panels need no per-theme override. - --green-strong
#166534· dark#4cc38a— text links and anything green-on-canvas. Clears 4.5:1 in both themes. - --green-soft
#e6f4ea· dark#1c3325— tinted fills, e.g. secondary-button hover. - --control
#ffffff· dark#242526— control surfaces: the avatar ring, header buttons. - --nav
rgba(255,255,255,.94)· darkrgba(36,37,38,.95)— the dock background. - --header-core / --header-midHeader gradient stops —
rgba(240,242,245,.88)/.58, darkrgba(24,25,26,.9)/.62. - --shadow
0 2px 12px rgba(16,24,40,.08)· dark0 2px 14px rgba(0,0,0,.28)— the one elevation.
- TypeDM Sans, self-hosted as a variable WOFF2 (
assets/fonts/dm-sans.woff2, weights 400–700). Body is 16px / 1.5. There is no type scale — sizes are set per component, which is a smell to fix before it spreads. - Motion200–300ms budget, positional only. The pill glides on
.28s; drawer links stagger at 40ms; the copy confirmation holds 1.8s. Everything dies underprefers-reduced-motion. - Radius
999pxpills are reserved for identity and navigation. Content surfaces use 10–18px — pick from what exists before inventing a new one.