Layout Contract
Overview
This page is the short list of rules a screen must satisfy before anything screen-specific is designed. The detail lives in the pages it points to; where they disagree with this page, this page wins.
Principles
-
Maximise screen real estate. Content uses the full width and height of the window. No maximum content width, no decorative bands, no element that repeats what another element already says.
-
One place for each thing. One title, one scope indicator, one record count, one set of paging controls, one filter band.
-
Lists are consistent with each other. Two list screens differ only in their columns, toggles and actions — never in typography, band order or control style.
-
State is shown, not inferred. A selected toggle carries a tick; a disabled control says why.
Vertical Stack
| Band | Contents | Specified by |
|---|---|---|
Breadcrumb |
Organisation › parent list › entity [status] date › screen [› child page]. Last crumb is the page’s
|
C01 rev 8 |
Tab strip |
Instance scope, with a leaf row only where a tab holds more than one sibling screen; or a tenant-scope section (see Section Tabs at Tenant Scope). |
C01 rev 8, rev 9 |
Command row |
Actions or the bulk bar, right-aligned, every button |
C09 rev 2 |
Content surface |
The screen body. For a list: filter band, table, pagination bar. |
Chrome above the content is at most two rows at instance scope and one at tenant scope, or two on a screen of a tenant-scope section.
Section Tabs at Tenant Scope
A sidebar row may anchor a section: several tenant-scope screens over the same data that share one tab strip. Numbers & Tags is the only section so far, with the tabs Stock status, Numbers, UNFIT and Activity.
-
The tab strip is the instance tab strip’s: the same component (
ap-tabsin link mode), the same underline treatment, rendered by the shell beneath the breadcrumb so it does not re-mount between tabs. -
The first tab is the landing, and the sidebar row leads to it. The row stays highlighted on every screen of the section, including child pages and detail pages.
-
The breadcrumb reads organisation › section › tab [› child page or detail]. A child page of the landing sits directly beneath the section crumb.
-
Commands that start a workflow are actions in the landing tab’s command row, and open child pages. They are not tabs and not sidebar rows.
-
Sections are declared in the navigation registry (
SECTIONSincore/nav/scoped-screen.ts), so a second section needs data, not code.
Content Surface
Everything a screen shows sits on a white, 1px-bordered, 8px-radius surface inside a 16px gutter.
A list has one surface; a dashboard or form may have several cards, each following the same treatment.
Nothing sits directly on the page background except the command row.
What a Screen Must Not Do
-
Render its own title, eyebrow or entity name beneath the chrome.
-
Render a scope chip or an "Active filters" label for a filter the route already pins.
-
Show the record count anywhere but the pagination bar.
-
Use a filled-versus-outline button as the only signal of a toggle’s state.
-
Introduce a second tab idiom: in-page tabs use the same underline treatment as the instance tab strip.
-
Type an icon as a Unicode glyph. Icons are drawn with
ap-icon; a glyph such as the circled-i has no rendering in several system fonts and shows as an empty box.