Attio Layout Decision Guide
One-page cheat sheet. Open this before building a new screen. Before editing an existing one.
If a pattern below conflicts with something in 03-layout.md or 04-components.md, this guide is the newer source of truth (it informs the rewrite of those chapters). For deeper pattern anatomy, see attio-layout-patterns.md. For tokens, see attio-design-language.md.
The three questions
Before building, answer these in order. Each has one right answer.
- What am I displaying? → Many items / one item / a form / a workbench / a dashboard / a canvas. Pick the archetype.
- How should it look? → Inside the archetype, which representation? (Table vs kanban; split vs drawer; flat vs card.)
- How do the pieces compose? → Page bar + content + (optional) right panel + (optional) action bar. In that exact order.
If you’re unsure on Q1, stop and re-read the list of archetypes in 03-layout.md. Picking the wrong archetype is the root cause of every nested-scroll, every 9-tab detail page, every “where does the Save button go” PR comment.
Decision tree 1 — “I’m displaying N items”
┌─ Is there a status pipeline? ──── YES ─→ KANBAN │ (open → in review → closed) │ ├─ Is time the primary axis? ────── YES ─→ CALENDAR │ (due dates, scheduled events) │Multiple items ──────┤ ├─ Is N < 20 AND each item ────── YES ─→ LIST │ has a picture/avatar as identity? (flat list, larger rows) │ └─ Otherwise ───────────────────────────→ TABLE (default; 95% of cases)Rules of thumb.
- Default to Table. Attio’s first-class view; most dense; most-scannable.
- Go to Kanban only when the status attribute is the reason the user is here. A list “that happens to have a status” is still a table.
- Go to List (flat rows, richer per-row cell) only when the item visual matters more than the attributes. Tools and agents with custom icons → list-or-cards call, see §cards-vs-flat below.
- Do not ship Gallery / Timeline / Map views unless a concrete user requirement forces it. Attio doesn’t have them; adding them multiplies maintenance.
Shipping multiple views? Rare. Most screens have one obviously-correct presentation — ship that and stop. A <ViewSwitcher> is only earned when all four of these are true:
- The screen is task-/flow-oriented — users triage, move items through stages, or work a queue (not “browse configuration”).
- Both representations are genuinely useful for the same user on the same data, not “one primary, one vanity.”
- The representations share the same query, filter, and sort state — switch is instant, not a refetch with different semantics.
- Users would realistically switch back and forth within a session, not pick once and forget.
If any of the four fails, pick the single best view and ship it. A settings-like list (agents registry, tools registry, versions) fails #1 — we know how to present it (a table), and nobody benefits from a kanban of their agents. Do not add a switcher.
Screens where the switcher does earn its keep: /review (inbox vs kanban by status), /agents/:id/tests (list vs kanban by pass/fail/pending), workflow run history (table vs pipeline view). These have real task/flow nature.
Settings is not a Detail-Split
The single most common misapplication: mechanically applying Attio’s 3a Split (main + right panel) to any screen that shows “one thing.” It’s wrong.
3a Split earns its keep only when the main area has genuine activity content — a timeline of emails/calls/notes/messages that scrolls down while the right panel holds static properties. If you’re writing configuration — name, description, model, prompt, variables, widget embed config, billing — the properties are the primary content. There’s nothing to put in the main area that isn’t just more properties.
For those, use Attio’s Settings archetype: <PageContent narrow> + flat <FormSection> groups + <Separator> between them. Full-width single column. No right panel. No card wrappers. See attio-design-language.md §3 “Settings / Configuration.”
| Screen type | Has genuine activity? | Archetype |
|---|---|---|
| Agent core settings (name, prompt, model, …) | No | Form (Attio Settings) |
| Agent variables | No | Form (Attio Settings) |
| Widget config | No | Form (Attio Settings) |
| Billing / security settings | No | Form (Attio Settings) |
| Knowledge-base doc viewer | No (doc is content, not timeline) | Workbench (list-nav + viewer) |
| Tool settings | No | Form with list-nav |
Conversation review (/review/:id) | Yes (the conversation is the timeline) | Detail 3a Split |
| CRM contact / company (future) | Yes (emails/calls/notes) | Detail 3a Split |
Decision tree 2 — “I’m displaying one item”
┌─ Are the item's properties first-class YES ─→ SPLIT │ alongside the tab content? (3a — main + right panel) │Single item ─────────┤ ├─ Is each tab itself a workbench/canvas YES ─→ TABBED FULL-PAGE │ (editor, chart, full-width dashboard)? (3b — no right panel) │ └─ Does the user's primary context stay YES ─→ DRAWER in the list (inbox, kanban triage)? (3c — overlay panel)
┌─ < 4 fields AND single-step commit? ────── YES ─→ MODAL (<Dialog>) │Form for one item ───┤ └─ Everything else ────────────────────────────────→ FORM PAGE (PageContent narrow + ActionBar)Rules.
- Split (3a) is the default record detail. Right panel for properties + metadata, main area for activity / timeline / tabs.
- Tabbed full-page (3b) is for content-heavy tabs. A workflow editor, a dense playground, a knowledge-base reader — each tab wants full width, so no right panel.
- Drawer (3c) is for peek-without-leaving. Deep-link via
?record=<id>, Esc closes, “Open full page” action promotes to 3a. - Never put a modal form with > 4 fields. Use
<Sheet>or a dedicated form page instead — same spec rule as before, unchanged. - Never nest a drawer inside a tabbed full-page. If the content is that deep, the archetype is wrong.
Decision tree 2.25 — “I’m running a multi-step task”
Wizards, imports, onboarding — any linear sequence the user starts and completes in one sitting. These deserve their own archetype (Focus View) rather than being crammed into a Dialog.
┌─ ≤ 1 field per step, ≤ 2 steps ─→ DIALOG │ (trivial flow, no distraction risk) (short form, keep in context) │Multi-step task ───────────┤ ├─ 3+ steps, sequential, must finish to ─→ FOCUS VIEW (3d) │ commit (import, onboarding, complex (full-screen takeover, no │ creation, destructive migration) sidebar, linear stepper) │ └─ Steps are revisitable / optional / ─→ FORM archetype with user dips in and out tabs or collapsible sections (not a wizard — a settings form)Focus View rules (from attio-layout-patterns.md §3d):
- Main-pane takeover, sidebar visible — the focus surface owns the main content area; the global nav stays addressable. Mount the route inside
AppLayout. ✕top-left — closes/aborts the flow, returns to parent page. Not “back.”- Two-row header — row 1 close + breadcrumb (
h-12); row 2 stepper (h-12). Stepper gets its own row to breathe. - Linear stepper — numbered steps connected by chevrons (
① ② ③). Future steps muted. No random-access. - No body tint —
bg-background, same as the rest of the app. Focus is established by structure (header + sidebar context + action bar), not surface color. - Centered, max-width content — never edge-to-edge.
- Sticky bottom action bar — Cancel / Previous / Next, full-width container with right-aligned cluster. Pass via the
actionsprop on<FocusLayout>. Floating-pill action clusters are forbidden. - No app-level actions at top — the flow owns the user’s attention until abort or complete.
“Wizard-in-a-Dialog” smell (same family as “Dialog that outgrew itself”):
Promote to Focus View when your <Dialog> has any of:
- A tab bar, stepper, or “Step 1 of 4” label inside the body.
- Content that changes shape across steps (drop zone → table → summary card).
- Back / Next buttons inside the DialogFooter.
showCloseButton={false}with a custom✕pinned to the corner.max-w-4xl+orh-[85vh]+.
The current /agents/:id/knowledge-base upload Dialog (KnowledgeBaseTab.tsx:675–771) has the first three — it’s a wizard crammed into a Dialog. Candidate for Focus View promotion once upload grows to include post-index verification steps.
Decision tree 2.5 — Dialog vs Drawer vs Page
Most common mistake after 3a-Split-overreach: picking the wrong overlay.
WHAT ARE YOU SHOWING / ASKING?│├─ Yes/no or a single-step commit (≤4 fields, no rich widgets)│ ├─ Confirmation → <ConfirmPopover> (routine) / <ConfirmDialog> (catastrophic)│ └─ Short form → <Dialog>│├─ Peek, read-only preview → Hover card popover (§6 in patterns doc)├─ Config side-task while staying in list → <Sheet> / drawer├─ Triage a collection, peek many records fast → <Sheet> / drawer (3c), URL-backed└─ Deep read/edit, shareable, >2 min attention → Dedicated pageWhat Attio actually does (captured from live app + help docs):
| Surface | Attio | Why |
|---|---|---|
| Click a record row (contact / deal / company) | Full page (3a Split) | Records have rich activity; page is the right size |
| Click a kanban card | Full page (3a Split) | Page-first for records |
| Hover entity name | Popover hover card | Peek only, never commits to layout shift |
| Delete confirmation | Dialog | Yes/no |
| ”Create new list” / “Invite teammate” | Dialog (1–3 fields) | Focused one-shot input |
| Edit view config / filter builder | Sheet | User keeps list context |
Attio is page-first for records, dialog-first for short commits, sheet-second for config side-tasks. It is not drawer-heavy like Linear or Notion.
When to reach for each
| Need | Use | Width / height caps |
|---|---|---|
| Yes/no confirm, reversible | <ConfirmPopover> | Anchored to trigger |
| Yes/no confirm, catastrophic | <ConfirmDialog> | Default Dialog sizing |
| Short form, 1–4 fields | <Dialog> | sm:max-w-md to sm:max-w-lg only |
| Read-only quick peek | Hover card (Popover) | 300–400px, auto-height |
| Config side-task (edit view, filter, attribute) | <Sheet> from right | 400px for narrow, 600px for wide |
| Record preview during triage | <Sheet> from right, ?id=<x> in URL | 500–600px, full viewport height |
| Record read/edit, shareable, long attention | Dedicated page (3a Split) | <PageContent> + <DetailPageBar> |
| Multi-step wizard (import, onboarding, complex create) | Focus View (3d) | Full viewport, sidebar hidden, max-width-constrained content |
Rules
- Never stack overlays. No drawer-inside-dialog, no dialog-over-drawer.
- URL-backed drawer (
?doc=<id>) beats unparameterized — Esc closes, browser back closes, link is shareable. - Drawer overlays, never pushes. Parent stays the same width.
- Page is the canonical form for any record deep-linked or worth >2 min of attention. Drawer is a shortcut for triage, not the destination.
The “Dialog that outgrew itself” smell
You’re in the wrong primitive when your <Dialog> acquires any two of these:
- Width escalation:
sm:max-w-2xl→max-w-4xl→max-w-6xl - Height hacks:
h-[85vh],max-h-[90vh], nestedoverflow-auto - Custom header replacing
<DialogHeader>(often withshowCloseButton={false}) - Tabs or split layout inside the body
Fix: promote to Sheet (triage context) or Page (shareable / long-attention).
Concrete example in nx-agent today: the KB doc preview at KnowledgeBaseTab.tsx:780–1124 hits all four. It’s a Dialog pretending to be a page.
Decision tree 3 — “I’m organizing subsections”
┌─ N ≤ 8, mutually exclusive, ─→ TABS │ user looks at one at a time (DetailPageBar tabs) │ ├─ User compares / edits across ─→ SPLIT PANEOrganizing subsections ────┤ two simultaneously (SplitContent) │ ├─ Reading top-to-bottom, each ─→ COLLAPSIBLE SECTIONS │ section optional (ContentSection collapsible) │ └─ Two/three equivalent views ─→ SUB-TOOLBAR of the same data (intra-tab switcher)Rules.
- Tabs break at 9. Our current agent detail has 9 — it’s already broken. Split the page into two detail URLs.
- Split pane (
<SplitContent>) is for comparison or cross-editing, not “I have a sidebar of links”. Navigation sidebars belong at the shell level, not inside content. - Collapsible sections are the Attio default for long-scroll pages (Record Details right panel, Settings, Dashboard). Use
<CollapsibleSection>(Plan 2 primitive) — state persists per-user in localStorage. - Sub-toolbar is an acceptable fourth tier inside a tab (spec exception). Keep it light — text segments, not a second tab row.
Decision tree 4 — Card vs flat
From attio-design-language.md L152–162, extended with nx-agent worked examples.
Use <Card> when… | Use flat <FormSection> / <PropertyList> / <Separator> when… |
|---|---|
| Dashboard metric tile (label + big number + trend) | Form field groups inside a settings page |
| Clickable entity preview (agent card, tool card, knowledge-base card in a grid) | Right-side property panel (<RightPanel> content) |
| Empty-state CTA (large centered “create your first agent” block) | Sequential form sections (name → description → permissions) |
| Danger zone (red-tinted card, always last) | Split-form property panel on the right |
| Widget on a workbench (chat panel card, recent-runs card) | Any “settings” sub-tab |
nx-agent worked examples.
| Case | Card or flat? | Why |
|---|---|---|
| Agents list — each agent as a tile on the home page | Card (<CardGrid columns={3}>) | Clickable entity preview |
| Agent settings form (name, description, system prompt) | Flat (<FormSection> + <Separator>) | Form field groups |
| Agent → Channels tab (one “card” per channel) | Card (<CardGrid>) | Clickable entity previews |
| Agent → Variables tab (key-value pairs) | Flat (<PropertyList>) | Key-value properties |
| Agent → Tools tab (sidebar list + right config) | Flat split (<SplitContent> + <PropertyList>) | Editing properties |
| Agent → Widget tab (form + preview iframe) | Flat (main) + Card (iframe preview) | Form is flat, the preview block is a card |
| Dashboard — usage metrics row | Card (<StatRow>, underlying metric cards) | KPI tiles |
| Dashboard — recent activity table | Flat (edge-to-edge <DataTable>) | Attio rule: tables don’t wrap |
| Review inbox (conversation list + preview) | Flat (<InboxList>) | Inbox archetype |
| Delete agent confirmation | <ConfirmDialog> (not a card) | Catastrophic confirm — dialog, not settings card |
| Danger zone on agent settings | Card (red-tinted) | The single “use card” exception in settings |
Per-screen mapping — nx-agent routes
Every route in the admin and chat apps, mapped to its archetype + Attio-aligned layout. Current column is what exists today; Target is what we should migrate to. Notes call out blockers or spec violations.
Admin app
| Route | Archetype | Current layout | Target layout (Attio-aligned) | Notes / blockers |
|---|---|---|---|---|
/agents | List | ListPageBar + <DataTable> (agents, status, actions) | Same — flat <DataTable> only, no view switcher. Agents is a registry, not a task/flow. Presentation is known. | DataTable default switches to variant="flat" (no border wrapper). |
/agents/:id | Detail (shell) | DetailPageBar with 9 tabs + <Outlet/> | Split into two detail pages — e.g. /agents/:id (core: Agent, Workflow, Knowledge Base, Tools, Variables) + /agents/:id/ops (Tests, Versions, Channels, Widget). Max 8 tabs per page. | Spec violation today (9 tabs). Reducing is a separate migration plan. |
/agents/:id (Agent tab) | Form (Attio Settings) | Single-column form | <PageContent narrow> + flat <FormSection> groups + <Separator> between them + <ActionBar> with Save/Cancel. Follows Attio’s Settings archetype (full-width single column, no right panel, no card wrappers). System prompt is a large <Textarea> inside its own FormSection. | Not a 3a Split — there’s no activity/timeline to put in the main area; properties are the content. Low-lift: current layout mostly works, just enforce flat FormSection + Separator and remove any card wrappers. Inline-edit (<PropertyList>) is optional and only if every field is independently savable. |
/agents/:id/workflow | Canvas (3b full-page) | Full viewport xyflow canvas + left panel + command palette | Keep. This is the archetype’s poster child. | Already Attio-aligned. |
/agents/:id/knowledge-base | List (tab) + Drawer (preview) | Table in the tab + Dialog at 90vh/6xl for preview containing nested split (left info panel + right content viewer, both with own overflow) | Tab: flat edge-to-edge <DataTable>. Doc preview: drawer (3c) opened from row click, URL-backed ?doc=<id>. Drawer body = flat <PropertyList> (metadata) + <CollapsibleSection> (RAG index status, replacing the inline muted-bg mini-card) + document viewer as main content + “Open full page” action. Transient progress/result banners become flat alerts, not cards. Filter chips replace the outline-button row. | P0 — multiple violations today: preview-in-Dialog (should be drawer or page), nested scrolls inside dialog, table border-wrapper, cards used as status banners, buttons-as-filters instead of chips, link-as-button for filename. Optional Plan N+1: /agents/:id/knowledge-base/:docId dedicated page for long-form doc reading, linked from the drawer’s “Open full page” action. |
/agents/:id/tools | Form (Attio Settings) with list nav | Split with select panel + config panel; nested scrolls | <SplitContent> left=tool list (selection only), right=flat settings for the selected tool: <FormSection> groups + <Separator> OR <PropertyList> with inline-edit if every field is independently savable. No <RightPanel> — the right side is the main content, not a property sidecar. | Nested-scroll violation today. Not a 3a Split. The “split” is list-for-nav + settings-for-content, not main-and-properties. |
/agents/:id/tests | Detail with sub-tabs | Sub-tabs (Test Suite List / Playground / History / Results), each with split layouts | Promote Playground to a full workbench page (3b). Suite list becomes a list with <HoverCardPreview> on suite name. History/Results earn a view switcher: default Table (latest runs), optional Kanban grouped by pass/fail/pending for active triage. | Multiple screens to split — own plan. Second screen that gets a view switcher. |
/agents/:id/widget | Form (Attio Settings) | Form + iframe preview + API key table | <PageContent narrow> + flat <FormSection> groups for widget config. Preview iframe is a single <Card> (self-contained widget, one of the valid card cases). API key table goes edge-to-edge flat below. No right panel — the config is the content. | Not a 3a Split. Follows Attio Settings: flat single-column, card only for the preview (genuine self-contained widget). |
/agents/:id/versions | List (inside detail) | Table of versions | Keep as table, edge-to-edge flat. No view switcher (audit log, not a flow). Row hover-card shows diff summary. | Low-lift. |
/agents/:id/channels | List (inside detail) | Channel cards + forms | Keep as <CardGrid> (channels are clickable entities). Add channel → opens drawer (3c) with channel settings. | Low-lift. |
/review | Inbox | Conversation list + preview (custom) | <InboxList> primitive (Plan 2). j/k keyboard navigation, e to archive, unread dot marker. View switcher earns its keep here — reviewers triage an inbox (default) but also want a kanban by review-status (pending / approved / rejected) when clearing a backlog. | New archetype. Deprecates the custom split. One of only 2–3 screens that get a view switcher. |
/review/:id | Detail (3a or 3c) | Call recording player + markup | Drawer (3c) when opened from /review; full page (3a split with <RightPanel> for metadata) when deep-linked. | Reuses drawer primitive from Plan 2. |
/tools | List | Tool registry with raw HTTP viewer | Table, edge-to-edge. No view switcher (registry, not a flow). Raw HTTP viewer opens in a drawer (3c), not inline. | Removes the current inline <pre> with overflow-auto. |
/settings/billing | Form | Form with payment fields | <PageContent narrow> + <FormSection> + <Separator> — flat settings layout. Danger zone = red-tinted card at the bottom. | Low-lift. |
/settings/security | List (security audit) | Audit log table | Edge-to-edge <DataTable>. No view switcher (audit log). Row hover-card preview shows audit detail. | Low-lift. |
Chat app
| Route | Archetype | Current layout | Target layout | Notes |
|---|---|---|---|---|
/bots | List (entity grid) | List of available agents (cards or list) | <CardGrid columns={3}> — agents are clickable entity previews. | Cards stay here — it’s an entity grid, not a dense collection. |
/chat/[botId]/[threadId] | Workbench | Header + message list + input bar | Keep. Chat is the canonical workbench. | No migration needed. |
/embed/[botId] | Exempt (iframe embed) | Minimal widget UI | Exempt from shell per spec. | No migration needed. |
/user/login | Exempt (auth) | Centered auth form | Exempt from shell per spec. | No migration needed. |
Focus View (3d) candidates in nx-agent
Not tied to a specific route — these are flows that currently don’t exist or are crammed into Dialogs:
| Flow | Today | Target |
|---|---|---|
| KB bulk upload + index verification | Dialog at KnowledgeBaseTab.tsx:675–771 — drop zone → pending list → upload. Already a 3-step wizard in Dialog shape. | Focus View (3d) if we add post-upload verification (review indexing status → confirm push to vector DB). Today’s 2-step flow can stay in Dialog; growing to 3+ means promote. |
| Agent creation wizard | Does not exist — creation is a quick-create dropdown or a simple form. | Focus View (3d) if we ever add a multi-step onboarding (choose template → configure model → connect tools → review → create). Until then, a dedicated /agents/new Form page is sufficient. |
| Agent cloning / templating | Does not exist. | Focus View (3d) if cloning grows beyond “pick source, click clone.” Single-step clone = Dialog. |
| Workspace onboarding | Does not exist. | Focus View (3d) when added — first-run experience, guided setup of first agent. |
| CSV / JSONL import for variables or knowledge | Not implemented. | Focus View (3d) when added — mirrors Attio’s /deals/import/new shape. |
Migration priority (blockers first)
- P0 — spec violations.
/agents/:id/knowledge-base,/agents/:id/toolsnested-scroll fixes. Need<RightPanel>+<PropertyList>from Plan 2. - P0 — 9-tab agent detail. Split into two detail pages.
- P1 — table wrappers. Flip
<DataTable>default tovariant="flat"and audit all callers (~14 pages). - P1 —
/reviewinbox. Replace custom split with<InboxList>. - P2 — view switcher (narrow). Only on
/review(inbox default, kanban for triage backlog) and/agents/:id/testshistory/results (table default, kanban by pass/fail for active triage). Do not add to/agents,/tools,/versions,/security— those are registries / audit logs with one obvious presentation. - P3 — hover-card previews. Add across admin tables.
- P3 — inline-edit everywhere. Add
<PropertyList>to remaining detail tabs once it’s battle-tested.
Red flags — signs you picked the wrong pattern
If you catch yourself writing any of these, go back and re-pick the archetype.
| Red flag | Real problem | Fix |
|---|---|---|
Two overflow-y-auto on the same page | Wrong archetype (you picked Split but the main area also wants to scroll its own sub-region) | Move the sub-scroll contents into <RightPanel> (which is the only allowed second scroll zone) OR switch to Tabbed full-page (3b) |
| 9+ tabs on a detail page | One page doing two jobs | Split into two detail URLs |
Table wrapped in <Card> or <div className="rounded-lg border"> | Non-Attio table chrome | Edge-to-edge. Remove wrapper. (Spec rewrite enforces this; Plan 2’s DataTable default = flat.) |
| Modal form with > 4 fields | Modal should’ve been a drawer or a form page | <Sheet> or <PageContent narrow> + <ActionBar> |
<Dialog> at 80–90vh containing a nested split / long content | Dialog is being used as a pseudo-page | Drawer (3c) for triage context, or dedicated detail page for long-form reading. Dialog is for confirmations + ≤4-field quick edits only. |
<Card> wrapping a progress bar, alert, or toast-like status banner | Banner is not a “content container” | Flat alert: role="status" or role="alert" div with icon + text, separated by spacing or <Separator>, not a card boundary |
<Dialog> containing a stepper, tab bar, or “Step 1 of 4” inside the body | Wizard crammed into a Dialog | Focus View (3d) — full-screen takeover with ✕ close, linear stepper, Next/Previous bottom-right. Dialog is for single-step commits. |
| Agent / resource creation as a multi-field modal form | ”Create” is not a confirmation, it’s a flow | Focus View for ≥3 steps or ≥6 fields; otherwise dedicated /new Form page. Dialog only for trivial “name it” creations. |
| Breadcrumb trail | Wrong navigation model | Back button in <DetailPageBar> — always goes to parent list |
| Primary button inside a section header | Wrong zone | Section actions are outline sm; primaries live in the page bar or action bar |
<Card> around a right-side property panel | Non-Attio pattern | Flat <PropertyList> with <CollapsibleSection> |
toast.success() after a click-triggered mutation | Wrong feedback surface | <ActionButton successText="…"> |
| Full-page loading spinner | Wrong loading state | <Skeleton> inside <PageContent> |
position: sticky inside content | Page bar is already fixed | Nothing else needs to stick |
| Gallery / timeline / map view for a record list | Over-reach beyond Attio | Use Table. If you genuinely need calendar, that’s fine — but stop before inventing a new view type. |
| Two primary buttons in the same neutral decision | Both should be outline | One primary max per zone |
<h1> inside content | Page-bar title covers this | Use <ListPageBar title> / <DetailPageBar title> |
Quick-reference decision card
Print this. Tape it next to your monitor.
ARCHETYPE → List | Detail | Form | Workbench | Dashboard | Canvas | FocusCOLLECTION → Table (default) | Kanban (pipeline) | Calendar (time) | List (<20, visual)DETAIL → Split (3a, properties first) | Tabbed (3b, content first) | Drawer (3c, list first) | Focus (3d, linear task)SUBSECTION → Tabs (≤8) | Split (compare) | Collapsible (scroll) | Sub-toolbar (equivalent views)CARD → KPI tile | Entity preview | Empty CTA | Danger zone. NOTHING ELSE.FLAT → Form, properties, settings, panels, split-form right side. EVERYTHING ELSE.SWITCHER → Only on task/flow screens (/review, /tests). Registries + audit logs = one view, no switch.OVERLAY → Dialog (≤4 fields, yes/no) | Sheet (triage / config side-task) | Page (shareable, long attention) | Focus (3+ step wizard) Attio = page-first for records, dialog-first for short commits, sheet-second for config, focus for wizards.See also
attio-design-language.md— tokens, 5 archetypes, card-vs-flat rule, spacing.attio-layout-patterns.md— deep pattern anatomy (right panel, inbox, hover card, slash menu, command palette, filter chips).../03-layout.md— in-spec layout rules (will be rewritten to align with this guide).../04-components.md— per-component rules (will be rewritten to align with this guide).../10-review-checklist.md— what reviewers check against.