--- name: detail-layout description: Use whenever building or editing a read-only detail / show page in the ERP project (entity detail screens, master-data detail, transaction detail, device/asset detail, contract-style detail with tabs). Governs LAYOUT ONLY — page vertical stack, identity/hero placement, section card stacking, key-value grids vs label/value rows, status metric blocks, summary multi-column blocks, workflow steppers, horizontal tabs for many data categories, embedded tables/lists, and action placement. Does not govern colors, fonts, border-radius, shadows, or other visual styling. Trigger this any time a detail page, detail section, FieldValue grid, detail tab, or related-list table on a detail page is added or restructured — including when the user says "build a detail page", "show entity data", or explicitly asks for tabs. --- # Detail Layout Layout rules for **read-only detail / show pages**, derived from this project's detail references: - [references/web-device-detail.png](references/web-device-detail.png) — desktop stacked section cards + key-value grid - [references/mobile-device-detail.png](references/mobile-device-detail.png) — narrow stacked cards + label/value rows - [references/web-contract-detail-tabs.png](references/web-contract-detail-tabs.png) — top summary + stepper + horizontal tabs for many categories These rules are about **structure and position**, not visual style (color, weight, radius, shadows belong to the design system / `@repo/ui`, not this skill). Every detail page decision should be made by walking the steps below, in order. ## Project chrome (do not rebuild) Detail routes already render inside `EnterpriseDetailPageProvider` → `ModulePageHeader` / `CorePageContainer`. That chrome owns: - Breadcrumbs - Page title (+ optional highlight key, e.g. code/id) - Status badge next to the title - Global page actions (Edit, Duplicate, Delete, lifecycle actions, Create) **Do not** re-implement those in the detail body. This skill governs the **children** of `EnterpriseDetailPageProvider` — the detail content below the module header. Optional **identity / hero** (§3) is an extra content block when the entity benefits from an avatar/image + display name stack; it is not a second page header. ## 1. Pick the page body mode Look at **how many distinct data categories** the entity has — that decides stacked vs tabbed body: | Detail type | Body mode | | --- | --- | | Few categories (≤3–4 section cards; e.g. Branch, User, simple master data) | **Stacked sections** — vertical stack of section cards under the header | | Many categories (>3–4 distinct groups) **or** the user explicitly asks for tabs | **Tabbed body** — keep a slim always-visible top (identity / summary / stepper), then a horizontal tab bar; each tab owns one category's content | | Narrow / mobile viewport | Same mode as desktop; only the **internal** key-value and status layouts collapse (§13) | Once a page picks stacked vs tabbed, stay consistent — don't mix an ad-hoc tab region with an ad-hoc long scroll of the same categories. **Force tabs when:** 1. The user prompt says to use tab(s), **or** 2. Showing every section at once would produce a long scroll of ≥4–5 independent category cards (e.g. Basic / Attachments / Milestone / Payment / Approvals / History). ## 2. Vertical structure of the detail page Top → bottom, never reorder: 1. **Module chrome** — already provided by `EnterpriseDetailPageProvider` (breadcrumbs, title, status, global actions). 2. **Identity / hero** (optional, §3) — only when an image/avatar + primary display name is part of the entity story. 3. **Summary block** (optional, §7) — high-level at-a-glance metadata / parties / key facts in a multi-column grid. Prefer this on tabbed pages so critical facts stay visible while tabs switch. 4. **Workflow stepper** (optional, §8) — only for entities with a linear lifecycle. 5. **Body** — either: - **Stacked:** section cards (§4) in category order, or - **Tabbed:** tab bar (§9) then the active tab panel (§10). Gap between these major bands uses the largest rhythm gap (§12). ## 3. Identity / hero (optional content block) Use when the entity has a meaningful visual (device photo, avatar, logo). Skip for plain master-data rows where the module header title is enough. ### Desktop / wide Single horizontal row inside one section surface: | Left | Middle (flex grow) | Right | | --- | --- | --- | | Leading media (fixed square/circle) | Title stack: primary name (+ id if not already in chrome), then one short subtitle/category line | Primary content action if it belongs to this block (usually omit — Edit lives in module chrome) | - Media left-aligned; title stack left-aligned next to media; any block-level action right-aligned on the same row. - Do not center the hero on wide layouts. ### Narrow / mobile Vertical centered stack: media → title → subtitle → optional full-width outline action. - Center alignment is correct on narrow widths only. - Primary action, if shown here, is full width under the subtitle — not beside the title. ## 4. Section cards (category containers) Every logical data group is its own section container (e.g. "Device Details", "Security & OS Details", "Documents"): - Sections **stack vertically** with consistent gap (§12) — never side-by-side category cards for independent groups. - Inside each section, top row is a **section header band**: - **Left:** section title (bold text only — no input). - **Right (optional):** section-scoped action (e.g. "Upload a document") — text/link or secondary control, right-aligned on the same baseline as the title. - Body of the section is one of: key-value grid (§5), key-value list (§5), status metric row/stack (§6), embedded table (§11), or a short summary + table combo (§10). - One section = one job. Don't dump unrelated fields into the same card. ## 5. Key-value fields Use `FieldValue` (or equivalent) for static metadata. Choose orientation by viewport / density: ### A. Label-above grid (default on desktop / wide) Matches the web device-detail reference and current `SimpleGrid` + `FieldValue` usage: - Multi-column grid, typically **3–5 columns** on wide (`md+`), **2** on `sm`, **1** on `base`. - Each cell is a vertical stack: **label on top**, **value underneath** (this is what `FieldValue` already does). - Fill left → right, top → bottom in reading order. - Prefer equal column tracks; a short leftover row leaves trailing cells empty — do not stretch the last field full width just to fill space. - Long free-text (address, notes) may span 2 columns or the full section width when the value would wrap awkwardly in a single track. ### B. Label-left / value-right rows (default on narrow / mobile) Matches the mobile device-detail reference: - One field per row: label left-aligned, value right-aligned. - Rows stack vertically inside the section; no multi-column grid on the narrow breakpoint. - Status-colored values and link values stay in the **value** slot (right side) — they do not move to a new row. **Do not** mix A and B inside the same section at the same breakpoint. Responsive collapse (§13) switches A → B on narrow widths. ## 6. Status / metric blocks Use when each item is a **named capability or check** with its own status (e.g. Antivirus / MDM / Encryption / OS), not a flat field list. ### Desktop / wide Horizontal row of equal sub-blocks inside the section: Each sub-block, top → bottom: 1. Icon + small category label (same row) 2. Primary value (software name / version) 3. Status badge / tag under the value ### Narrow / mobile Same sub-blocks, stacked vertically. Inside each sub-block: 1. Icon + small category label (top row) 2. Primary value on the next row, with status badge **on the same row to the right** of the value Don't use this pattern for ordinary scalar fields — those stay in §5. ## 7. Summary multi-column block (optional, top of body) Use on complex / tabbed details when several **at-a-glance groups** must stay visible above tabs (e.g. dates/value metadata | Party A | Party B): - Full-width band under identity (or under module chrome if no identity). - **2–3 equal columns** on wide; each column is a titled group of compact key-value rows (label then value on one line, or icon + label + value). - Columns are peer groups, not a key-value grid of unrelated fields — if fields aren't grouped into 2–3 stories, use a normal §5 section instead. - Collapses to a vertical stack of the same groups on narrow widths (§13). ## 8. Workflow stepper (optional) Only for entities with a **linear lifecycle** (Draft → Review → … → Active): - Full-width band under summary (or under identity / chrome). - Horizontal sequence left → right; completed → current → upcoming order must match domain order. - Label the band with a short section title above the stepper (e.g. "Status update"). - On narrow widths, keep sequence order; may scroll horizontally or show a compact current-step focus — never reorder stages. ## 9. Horizontal tabs (many-data body) When §1 selects tabbed body: - Tab bar sits **below** identity / summary / stepper and **above** the active panel — never above the module chrome, never below the first content card of a stacked page. - Tabs are a single horizontal list of category labels (Basic details, Attachments, Milestone, Payment, …). - One active tab at a time; switching tabs replaces the panel content — do not keep all tab panels mounted as a long scroll underneath. - Prefer **≤8–9** tabs; if more categories exist, merge related ones or keep rare ones behind a secondary entry inside a tab. - Tab labels are short nouns/phrases; order tabs by user-task frequency (overview / basics first, history last). - Use project `Tabs` from `@repo/ui/components` (see showcase forms demo for list/panel structure) — layout concern only: `Tabs.List` then `Tabs.Panel`s. ### What stays outside tabs Always-visible above the tab bar (when present): identity (§3), summary (§7), stepper (§8). Do **not** put the only copy of critical status / party / date facts exclusively inside a tab if the user needs them while browsing other tabs. ## 10. Tab panel content Each panel is laid out as if it were a small stacked detail of its own: 1. Optional **panel sub-header** — section title left; optional summary metrics split left/right on the same row (e.g. "Total invoice value" left, "Total estimated project value" right). 2. Optional **visual summary** (progress bar / distribution) full width under the sub-header — position only; styling is design-system. 3. One or more **section cards** (§4) and/or an **embedded table** (§11). Do not nest a second tab bar inside a panel. ## 11. Embedded tables / related lists For collections (documents, payment proofs, line history): - Table lives inside a section card (§4). - Section header band: title left, section action(s) right — filters and "Add …" sit on the **right of the header**, same row as the title (or immediately under the title row if filters + primary action don't fit). - Column headers above rows; text/id columns left-aligned; numeric columns right-aligned; status as an inline indicator in its cell; row actions in a fixed trailing column (ellipsis / menu) — same width every row. - Empty state stays inside the table/section body — don't relocate the section action. ## 12. Vertical rhythm Define three consistent gap sizes and use them the same way on every detail page: 1. **Label → value** (smallest): binds a field's label to its value (`FieldValue` gap). 2. **Field → next field / sub-block → next sub-block** (medium): separates peers inside a section. 3. **Section → section, and major band → next band** (largest): separates cards, summary, stepper, and tab bar from each other. Horizontal gaps inside grids match the medium rhythm. Don't invent a fourth gap tier per page. ## 13. Responsive collapse | Wide layout | Narrow collapse | | --- | --- | | Identity hero row (media \| title \| action) | Centered vertical stack (media → title → subtitle → full-width action) | | Key-value label-above grid (§5A) | Label-left / value-right rows (§5B) | | Status metric horizontal row (§6) | Stacked metric sub-blocks; badge beside value | | Summary 2–3 columns (§7) | Stacked column groups, same order | | Tab list | Horizontally scrollable tab list; panels still one-at-a-time | | Table | Horizontal scroll inside the section **or** stacked label/value per row — pick one strategy per table type and keep it project-wide | Never re-pair fields into different logical groups on collapse — only column count / orientation changes. ## 14. Action placement (position only) | Action scope | Position | | --- | --- | | Global entity actions (Edit, Delete, Activate, …) | Module header actions via `EnterpriseDetailPageProvider` — top-right of chrome | | Section-scoped action (Upload, Add record) | Right side of that section's header band (§4 / §11) | | Section filters | Right side of the table/section header, before or beside the section primary action | | Row action | Trailing column of that row only | Do not duplicate Edit in the body if the provider already exposes it, unless a mobile identity block needs a full-width local affordance (§3 narrow). ## 15. Checklist before finalizing any detail page - [ ] Did you choose stacked vs tabbed from category count / user request, per §1? - [ ] Is module chrome left to `EnterpriseDetailPageProvider` (no second breadcrumb/title/action bar)? - [ ] If tabbed: do identity / summary / stepper stay above the tab bar, per §9? - [ ] Is every category its own section card with title-left / action-right, per §4? - [ ] Are scalar fields using label-above grid on wide and label/value rows on narrow, per §5 / §13? - [ ] Are status/capability items using metric sub-blocks (§6), not mixed into a flat field grid? - [ ] Do related lists use header actions + table alignment rules, per §11? - [ ] Are global vs section vs row actions in the correct slots, per §14? - [ ] Does collapse preserve grouping and only change orientation/columns, per §13? ## Quick mapping to this codebase ```tsx // Stacked (few categories) — children of EnterpriseDetailPageProvider <> {/* optional identity */} {/* section: SimpleGrid + FieldValue */} {/* section: status metrics or table */} // Tabbed (many categories / user asked for tabs) <> {/* optional identity + summary + stepper */} {/* category tabs */} {/* section cards */} {/* summary row + table */} ``` Prefer existing primitives: `Paper` / section surfaces, `SimpleGrid`, `FieldValue`, `Tabs`, `StatusBadge`, table components from `@repo/ui` — this skill decides **where** they sit, not how they are themed.