All documents

The dashboard structure

Every screen in every 8020 app is the same five boxes in the same order with the same gaps. This is the document to read before building a screen, and registry/examples/dashboard-screen.tsx is that structure as code (pnpm dlx shadcn@latest add @8020iq/dashboard-screen).

Every number below was measured, not chosen — see 14-measurements.md, which is generated by driving a browser.

The skeleton

Screen                     page box        padding 24 (32 at lg)
  PageHeader               the one <h1>, actions on the title's line
  section                  a titled group  gap 16
    Eyebrow                the label — type marks a section, never a rule
    grid                   tiles           gap 16
  section                  the data        gap 12
    toolbar (flex-wrap)    filters         gap 8
    Panel                  the frame       1px border · 8px radius · ZERO padding
      Table fill           owns the scroll

The two rhythms, and picking wrong is the common mistake

<Screen><Screen fill>
It is
a scrolling document
a viewport application
Gap between blocks
40 px
24 px
Padding
24 · 24 · 80 · 24
24 all round
Who scrolls
the page
ONE child — a table, a map, a list

Use fill the moment a table with a sticky header is on the screen. Without a sized chain — Screen fillPanel min-h-0 flex-1Table fill — the document becomes the scroll port and a correct sticky header looks broken.

The gaps, and what each one means

GapWhereWhy that value
40 px
between blocks on a scrolling page
Two unrelated things
24 px
between blocks on a fill page
Same, tightened because the viewport is fixed
16 px
inside a section: label → content, and between tiles
One thing and its parts
12 px
data section: toolbar → Panel
The toolbar BELONGS to the table; it is not its own block
8 px
between controls in the toolbar, and icon → label
Peers in a row

If you find yourself wanting a value between these, the question is usually whether two things are one group or two.

The grids

GridClassesFor
KPI row
grid grid-cols-2 gap-4 md:grid-cols-4
Four figures that qualify the screen
Catalogue
grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-6
A set of many peers (eighteen permit types)
Tiles / cards
grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3
The hub's tools

Two on a phone, always. Nothing in between these three.

Borders and surfaces — there is one of each

  • 1 px, --border (#E8E4DE light, white 8% dark). That is the only border weight on a resting surface. --border-strong exists for a table outline and for hover, not as a second default.
  • 8 px radius on every container (card, panel, tile, alert), 6 px on every control, 16 px only where a card is a big clickable object (rounded-[var(--radius-card)]).
  • No shadow on a resting surface. A card is a line, not a lift. Elevation is reserved for things that actually float (19-elevation-and-depth.md).
  • Card fill is --card (#F5F3EF on cream, titanium on charcoal). Never pure white on cream.

What not to do

  • No card inside a card. If a panel needs sections, they are separated by a 1 px rule, not by nested boxes.
  • No padding on a Panel that holds a table. The table's own 20 px cell padding is the padding; two paddings put the sticky header below a strip of card.
  • No second <h1>. PageHeader is the only one; a section is an Eyebrow.
  • No overflow on the Panel around a table. The Table owns both axes; a second scroller gives position: sticky two ancestors to resolve against.
  • No coloured section headers, no coloured left borders, no tinted "info" boxes. A section is marked with type; emphasis is the bracket Callout.
  • No full-width primary buttons and no more than one primary per screen.
  • No figure without a qualifier line. A stat tile has a label above and a sentence below; a number alone is not a fact.

The screen's furniture is not the screen's business

The rail, the header, the breadcrumb and the account menu come from SiteShell (05-sidebar-and-shell.md). A screen renders a Screen and nothing above it — that is what makes every tool wear the same frame without any tool knowing how the frame is built.