Surfaces
The physics of a surface, in three rules: depth comes from borders and background steps, corners come from one fixed scale, and overflow never grows its own scrollbar.
Depth
The interface is flat. A surface is distinguished from its background by a 1px border and a background-color step, and by nothing else. Drop shadows and decorative outlines are banned in every UI component, with no exceptions.
- Border: 1px, a quiet neutral (the design site uses neutral-200), and constant: no state is allowed to change it.
- State is a background change: hover, selected, and active tint the surface. Borders and outlines never move, thicken, or recolor to signal state.
- Surface step: white content on a faintly tinted ground, or the reverse. One step, never a stack of tints.
- No decorative outlines: the CSS outline property is reserved for exactly one job, the keyboard focus indicator. Focus rings are never removed.
Draft 3
Reviewed today
B2Draft 3
Reviewed today
B2Draft 3
Reviewed today
B2Draft 3
Reviewed today
B2The one soft thing in the system is the brand art itself: gradient tiles may glow on dark gallery surfaces. That is art direction, not UI, and it never applies to components.
Radius
The system has exactly four corner radii: 6px, 12px, full, and the brand tile. There is no fifth.
6px · rounded-md
Small elements nested inside a card: nav links, code spans, table cells, mini chips.
Draft 3
Reviewed today
12px · rounded-xl
Cards, panels, figures, inputs. The workhorse container radius.
Full · rounded-full
Pills: buttons, chips, badges, level indicators. Anything one line tall.
The tile · 32/120
Reserved for brand art: the app-icon squircle at 26.7% of its side. Never for UI components.
- Nest downward: a 12px card contains 6px and full elements, never another 12px edge flush against its own.
- No sharp corners on interactive components, and no in-between values. 8px, 10px, and 16px do not exist here.
- The tile radius is art: it belongs to the squircle and its 3D render, and never to buttons, cards, or modals.
Scrolling
A page owns exactly one primary scroll context: the window's. Nested scroll regions are banned. When a region truly must overflow, it goes through the ScrollShadow container: each edge with more content fades out, and the region wears the system scrollbar.
- Never two vertical scrollbars. If a panel wants to scroll inside a scrolling page, the layout is wrong: shorten the panel, paginate it, or let the page grow.
- Content drives height. Multi-line fields auto-grow with their content (field-sizing: content) instead of fixing a height and scrolling inside it; panels and lists size to what they hold. Reaching for overflow-y-auto on an inner element means the layout should be restructured, not scrolled.
- Overflow goes through ScrollShadow. Where a bounded region is unavoidable (a picker, a chat transcript), it is a ScrollShadow container: a 40px mask fades each edge that has more content and vanishes at the ends, and the scrollbar is the system thumb. hideScrollBar is reserved for decorative rails: chip rows.
- Horizontal overflow is the one exception, for code blocks, wide tables, and chip rows. It scrolls sideways only and never traps vertical wheel input; chip rows use the horizontal ScrollShadow, scrollbar hidden the same way.
The scrollbar
The window, ScrollShadow regions, and horizontal code blocks wear one scrollbar skin, defined in globals.css:
- Track: transparent. The surface is the track; no fill, no border.
- Thumb: a 4px Lemon pill floating in a 10px gutter (rounded-full, inset by a transparent border), borderless like every other Lemon pill. No buttons, no corner square.
- States are fill steps only: Lemon resting, one step deeper on hover, two while dragging. The thumb never resizes, gains a border, or animates.
- One size token: the 10px gutter is
--scrollbar-size, and ScrollShadow's mask carves out the same strip, so the fade never covers the thumb. Firefox renders its thin native thumb in the same colors.
This list is taller than its box. It is the ScrollShadow component (imported from the app) wearing the system scrollbar; scroll it and watch the edges: the fade only exists where content continues.
- Draft 1 · first ideas
- Draft 2 · thesis sharpened
- Draft 3 · evidence added
- Draft 4 · paragraphs reordered
- Draft 5 · tenses fixed
- Draft 6 · conclusion rewritten
- Draft 7 · vocabulary upgraded
- Draft 8 · final read-through
- Draft 9 · submitted
Draft 1 · first ideas
Draft 2 · thesis sharpened
Draft 3 · evidence added
Draft 4 · paragraphs reordered
…continues below
…inside a scrolling page