Meridian — layout.md
Spatial system for application + cinema. Influences ranked in
influences.md.
Primary absorb: Fluent 2 layout (4px grid, proximity, breakpoints) + Cursor inverted-L chrome + Polaris task density.
1. Laws
- 4px base unit — all pads, gaps, and control heights snap to multiples of 4 (Fluent spacing ramp).
- Proximity = meaning — space groups related information; prefer space over extra dividers (Fluent, Polaris).
- Density follows task — indexes dense; detail/forms breathe; marketing stages use theater, not app density.
- Chrome is quiet — inverted-L (sidebar + top bar) recedes; content owns hierarchy (Linear, Cursor app).
- One layout vocabulary — never fork components per surface; remap via
data-surface. - Stroke before shadow — pane separation = 1px
border-border/edge(Fluent stroke). - Control ≠ layer radius — controls
rounded-lg; panelsrounded-2xl; shellsrounded-3xl.
2. Spacing ramp (Fluent → Meridian)
| Fluent token | px | Meridian use |
|---|---|---|
| size20 | 2 | Icon optical adjust only |
| size40 | 4 | Micro gap inside controls |
| size80 | 8 | Compact chrome padding (px-2) |
| size120 | 12 | Default control inline gap |
| size160 | 16 | Card compact pad step |
| size200 | 20 | Application --surface-pad default |
| size240 | 24 | Section rhythm |
| size320 | 32 | Pane gutters / control default height |
| size400 | 40 | Row height / marketing CTA |
CSS knobs (app/globals.css):
--surface-pad
--surface-gap
--control-h*
--row-h*
Rule: if you need a one-off p-[13px], stop — pick the nearest ramp step.
3. Application shell (Cursor + Linear)
Canonical anatomy:
┌──────────────────────────────────────────────────────────┐
│ topbar h-8…h-11 search · filters · kbd │
├────────────┬─────────────────────────────┬───────────────┤
│ sidebar │ main content │ optional rail │
│ w-40…14rem │ index | detail | editor │ AI / meta │
│ quiet nav │ scroll: one port │ object-bound │
├────────────┴─────────────────────────────┴───────────────┤
│ status h-6 mono │
└──────────────────────────────────────────────────────────┘
| Region | Width / height | Surface | Notes |
|---|---|---|---|
| Sidebar | 10–14rem | bg-muted/15–20 + border-r | Labels/icons aligned (Linear) |
| Topbar | h-8 app / h-11 site | hairline bottom | No brand fill |
| Main | minmax(0,1fr) | bg-background | Single scroll owner |
| Agent rail | 16–18rem | bg-muted/10–15 | Only when object selected |
| Status | h-6 | mono 10px | Density proof |
Proofs: components/surfaces/workbench.tsx, composer-shell.tsx.
Alignment checklist (Linear discipline)
- Icon + label share one vertical centerline in sidebar rows
- Tab labels share baseline with toolbar controls
- Table cells: ID mono left, title truncate, meta right
- Avoid “icon soup” — one leading icon max per row
4. Grid & breakpoints
Fluent size classes (Layout):
| Class | Range | Meridian behavior |
|---|---|---|
| small | <479 | Stack; hide side rails; 44px touch |
| medium | <639 | Compact stack |
| large | <1023 | Optional sidebar collapse |
| x-large | ≥1024 | Full inverted-L |
| xx-large+ | ≥1366 | Wider main; keep measure for reading |
Techniques (Fluent): reposition · resize · reflow · show/hide · re-architect.
Meridian default: responsive one layout (not adaptive forks), with progressive disclosure of rails.
Column guidance
| Context | Columns | Gutter |
|---|---|---|
| App workbench | Fluid 2–3 regions | 0 (stroke dividers) |
| Docs / reading | Manuscript (1 col) | — · max 65ch |
| Marketing film | Full-bleed stage | Edge-to-edge media |
| Theme showcase | 12-col mental model | 16–24px |
5. Surface matrix (layout implications)
data-surface | Pad | Gap | Control | Row | Scroll |
|---|---|---|---|---|---|
application | 20 | 12 | 32 | 40 | One main port |
desktop | 12 | 8 | 28 | 32 | Instant; no nested ports |
marketing | 24 | 20 | 36–40 | — | Stage svh; no nested demo scroll |
mobile | 16 | 12 | 44 | 52 | Safe areas; bottom chrome |
6. Pane composition patterns
Index + detail (Polaris density)
[ filters h-8 ]
[ table rows h-8…h-10 ]
└ selected → opens rail OR navigates detail
Composer (Cursor)
[ explorer | tabs + editor | agent ]
Marketing stage
[ theater svh ]
copy (one idea)
ProductFrame → app proof (rounded-2xl edge)
7. Shape on layout edges
| Element | Radius | Source |
|---|---|---|
| Nav item, input, button | rounded-lg | Fluent Large control |
| Card, workbench shell, popover | rounded-2xl | Fluent layer |
| Modal / hero shell | rounded-3xl | Marketing shell |
| Badge / pill / CTA pill | rounded-full | Fluent pill form |
| Screen-edge chrome | square OK | Fluent: skip radius at screen edge |
8. Dividers
Prefer space → then 1px stroke → then elevation.
Never double: thick border + heavy shadow + loud background.
| Separator | Token |
|---|---|
| Pane split | border-border |
| Inset card | edge |
| Floated overlay | depth-soft / depth-raised |
9. Reading layouts
| Lane | Measure | Type |
|---|---|---|
typeset typeset-docs | ≤65ch | Docs / help |
typeset typeset-reading | ≤65ch | Essays |
typeset typeset-chat | ≤56ch | Agent messages |
| Never | >80ch | — |
Demo bands under prose: reading-demo-break / DocsDemoSection — not full-bleed text-sm paragraphs.
10. Anti-patterns
| Ban | Why |
|---|---|
Nested overflow-auto demos | Steal scroll (cinema laws) |
| Inset hero media cards | Breaks full-bleed subject |
| Dashboard soup in first marketing viewport | Violates one-idea frame |
| Cards wrapping every label | Chrome noise (Linear) |
Arbitrary gap-[0.85rem] | Off Fluent 4px ramp |
rounded-md / rounded-xl in app chrome | Outside closed radii |
11. Implementation map
| Concern | Code |
|---|---|
| Surface density | [data-surface] in globals.css |
| Radius intent | radiusFor in lib/design/grammar.ts |
| Shells | components/surfaces/* |
| Cinema stages | components/cinematic/* |
| Platform chrome | components/chrome/platform-header.tsx |
| Contract chrome | components/chrome/contract-frame.tsx |
12. Agent checklist
- Spacing on 4px ramp
- Correct
data-surface - Control vs layer radius
- Single scroll owner in demos
- Sidebar/topbar quiet; brand only on selected/CTA
-
npm run check:design