F FieldInsight Developer guide preview · build.html
Search… 🔔
Back to Prototypes
FieldInsight · Developer Reference

The Developer Style Guide.

The canonical style guide for every Open Claw prototype — locked from the Purchase Order page rebuild (proto-multi-supplier-po). Orange · purple · blue button hierarchy, document-page patterns, tables, chrome, and widgets. Copy-paste the snippets; demos render in the actual styles they teach.

Prefer plain text? Same content as styling-guide.md — paste into any AI context, drop into a repo, or read offline.

Prototype style guide — pending Lead Engineer sign-off (Vadim). Once approved, every Open Claw prototype maps onto this page. Reference implementation: fi-supplier-po · tokens in poButtonTokens.ts · per-button map in affordance-style-guide.md.
1

Structure

Every FieldInsight page is the same three parts: a dark purple top bar with global controls, a dark purple left sidebar with module nav, and a cream content area where the work happens. Container max-width is 1180 px. Page shapes (list, detail, dashboard) are inherent in the product — this guide focuses on style and affordance, not wireframes.

Page skeleton

Three CSS Grid areas: top bar (48 px row), sidebar (220 px column), everything else. Sidebar collapses at < 900 px.

HTML code
<div class="app"> <header class="app-top"> ... </header> // 48px, fixed <aside class="app-sidebar"> ... </aside> // 220px, sticky <main class="app-content"> <a class="crumb" href="/parent">Back</a> <h1 class="page-title">Your page</h1> <p class="page-lead">One-line intro.</p> // page content here </main> </div>
CSS code
.app { display: grid; grid-template-columns: 220px 1fr; grid-template-rows: 48px 1fr; min-height: 100vh; } .app-top { grid-column: 1 / -1; } .app-content { padding: 32px 36px 64px; max-width: 1180px; }

Spacing rhythm

UsePxWhen
Page padding (X)36Side gutters in .app-content
Page padding (top)32From top bar to first heading
Section gap52Between top-level sections
Subsection gap28Between h3 groups inside a section
Component gap14Between buttons in a row, cards in a grid
Tight gap8Inside a button (icon ↔ label), chip clusters
2

Text formatting

Two font families, both from Google Fonts. Bricolage Grotesque for display (page titles, section heads, big numerals). Plus Jakarta Sans for everything else. JetBrains Mono only for code, IDs, URLs.

Font stack

CSS code
--fi-font-display: 'Bricolage Grotesque', system-ui, sans-serif; --fi-font-body: 'Plus Jakarta Sans', system-ui, sans-serif; --fi-font-mono: 'JetBrains Mono', ui-monospace, monospace; // Google Fonts import (paste once into <head>) <link href="https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,600;12..96,700&family=Plus+Jakarta+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">

Type scale all sizes in px

Page title — Bricolage 32 / 700 / -0.025em

Section heading — Bricolage 22 / 700

Subsection — Bricolage 17 / 600

Body — Plus Jakarta Sans 14 / 400. The default. Use for everything except headings, code, and small captions.

Body soft — 13 / 400, var(--fi-text-soft). For supporting text inside cards.

Caption / Eyebrow — 11.5 / 700 / 0.12em tracking

// inline code — JetBrains 12.5
RoleFontSizeWeightTrackingColor token
Page title (H1)Display32700-0.025em--fi-text
Section (H2)Display22700-0.02em--fi-text
Subsection (H3)Display17600-0.01em--fi-text
BodyBody14400--fi-text
Body softBody13400--fi-text-soft
Caption / eyebrowBody11.57000.12em UPPERCASE--fi-text-muted
Button labelBody12–13700varies
Code / IDsMono12–12.5500--fi-text

Text colours

TokenHexUse
--fi-text#1A1230Primary body text, headings, table cells
--fi-text-soft#4A3D6BSupporting text, descriptions, sub-labels
--fi-text-muted#6F6489Captions, table headers, breadcrumbs, "last updated"
--fi-primary#FF6A13Links, focus states, dates that need emphasis
Dates always use var(--fi-primary). "Today", selected days, active month chips, and date input focus rings render in the primary colour — never an accent. This makes date state instantly recognisable across every palette.
3

Buttons & hierarchy PO prototype · green · orange · purple · blue

The PO page defines the canonical button stack for every Open Claw prototype. Four action colours on document pagesgreen (lifecycle hero: Submit · Approve · Finalise), orange (attention / confirm), purple (workflow event), blue (working tools). Green is the one permitted filled-button exception on white document pages — not a free pass for every verb. At most two filled buttons per visible region — typically one green lifecycle hero + one purple workflow event.

Chrome vs content. The left sidebar is dark purple (--fi-chrome-bg · #39006B); active nav uses orange (--fi-primary). Lifecycle buttons on the white document use status green (#1E7A3A) so navigation never competes with the hero action. Orange on buttons = attention moments (Confirm goods received) and general app CTAs (+ Book Job) — not the default lifecycle fill.

The seven levels map to poButtonTokens.ts

LevelClass / tokenSizeColourUse on document pages
L1 Lifecycle heropo-btn-status-green · BTN_STATUS_GREEN32 px Status green #1E7A3A · hover #166030Approve · Submit · Finalise — ONE per region
L1 Attentionpo-btn-attention · BTN_STATUS_ORANGE32 px Orange #FF6A13Confirm goods received (hold banner)
L2 Workflowpo-btn-purple · BTN_PURPLE28 px Purple #6C5AC4 · hover #513FADReconcile Supplier Invoice · Create Credit
L3 Standardpo-btn-standard · BTN_STANDARD28 px Blue tintClose · + Find Bill · Receive all · Approve & Email · companions
L3b Ghost docpo-btn-ghost-doc · BTN_GHOST_DOC28 pxWhite + blue borderPreview · Download · Email · Copy · Create job ▾ · Export to Xero
L4 Inline linkpo-btn-link · LINK_BLUEtext#2563EB+ Add from library · + Add line item
L5 Destructivepo-btn-danger · BTN_GHOST_DANGER28 pxRed ghostDelete (Draft only, far right)

Live stack — all levels

L1 Lifecycle (green) + L2 Workflow + L3 Standard (footer lifecycle row)
L2 Workflow + L3 Standard (Bills section, expanded)
L3b Ghost doc tools (footer row 1 — icon + label, identical weight)
L4 Inline links + L1 Attention
Import zones — Attach (blue) vs AI (purple + sparkle)
Attach file
Drag files here · not imported into the document
AI Import
Drag files here · AI imports line items to the document

Per-region button map every control on the PO page

RegionButtonLevel
Footer lifecycleSubmit · Approve · FinaliseL1 Lifecycle hero (green)
Approve & Email · Receive allL3 Standard (blue)
CloseL3 Standard — left-isolated
Preview · Download · Email · CopyL3b Ghost doc
Create job ▾ · Export to XeroL3b Ghost doc
DeleteL5 Destructive — far right, Draft only
Bills (expanded)Reconcile Supplier InvoiceL2 Workflow (purple)
+ Find Bill · + Generate Bill from PO · + Generate Blank BillL3 Standard
Create CreditL2 Workflow (purple)
Use CreditL3 Standard
Credit NotesCreate Credit · Use CreditL2 + L3
Line items+ Add from library · + Add line itemL4 Inline link
Import preview modalAuto-create codes & add to POL1 Hero
Add as-is · All new → service · CancelL3 Standard · muted · text
Hold bannerConfirm goods receivedL1 Attention (orange)
Import zonesAttach Choose file · AI Choose fileL3 Standard · L2 Workflow + sparkle

Click-? hints every workflow button

Workflow buttons carry a hover-revealed ? glyph (see Bills demo above). Click opens a dialog: Description (business meaning) + Example (real PO data). One dictionary per page (FOOTER_BTN_INFO). Hover-only tooltips are banned on workflow verbs. Labels are verb-led: "Reconcile Supplier Invoice" not "Supplier Invoice Received".

The wall of buttons anti-pattern

✕ Don't — 12 equal purple fills (legacy production PO)
✓ Do — one green lifecycle hero, purple workflow, blue/ghost for the rest

Do

  • One green L1 lifecycle hero per visible region (Submit · Approve · Finalise).
  • Orange for attention confirmations — not the default lifecycle fill.
  • Purple for workflow events that aren't the lifecycle verb.
  • Blue tint for companions and mid-page tools; ghost-doc for footer utilities.
  • Click-? on every workflow button — no hover-only tooltips.
  • Map onto poButtonTokens.ts — never invent per-repo colours.

Don't

  • Multiple green fills in one region — green is ONE lifecycle hero only; not every verb.
  • Three or more filled buttons in one row — budget is max 2 fills per region.
  • Duplicate affordances (+ File when Attach zone exists; View/Edit when chevron exists).
  • Deep purple #39006B on workflow buttons — that's AI-only (§7).
4

Tables

The default data table pattern: white card on cream surface, uppercase-tracking header row, subtle hover, status pills in the right-side column. Use for any list-of-things page (jobs, customers, invoices, assets).

Data table

Job # Customer Type Scheduled Status Actions
JOB-14517 ACME Heating & Cooling HVAC service Mon 1 Jun, 09:00 Scheduled
JOB-14516 Bayside Apartments Coil replacement Tue 2 Jun, 13:00 Draft
JOB-14515 Hutton St Body Corp Quarterly PPM Fri 29 May, 11:30 Complete
JOB-14514 Trade Tools AU Switchboard fault Wed 27 May, 08:00 Overdue
HTML code
<table class="data-table"> <thead> <tr><th>Job #</th><th>Customer</th><th>Type</th><th>Scheduled</th><th>Status</th></tr> </thead> <tbody> <tr> <td><code class="inline">JOB-14517</code></td> <td>ACME Heating &amp; Cooling</td> <td>HVAC service</td> <td>Mon 1 Jun, 09:00</td> <td><span class="pill scheduled">Scheduled</span></td> </tr> // ...more rows... </tbody> </table>

Status pill semantics

PillMeaningBackgroundText
DraftUnfinished record--fi-surface-2--fi-text-muted
ScheduledCommitted, futureinfo tint--fi-info
CompleteDone, no action neededsuccess tint--fi-success
OverdueNeeds attentiondanger tint--fi-danger

Do

  • Action column right-aligned, with tertiary-tier Open → per row.
  • IDs in mono font (JOB-14517) for scannability.
  • Status as a pill, never a free-text word.
  • Hover state on rows for affordance — links to the detail page.

Don't

  • Striped rows (zebra). The hover state is enough.
  • Heavy borders between every cell — only between rows.
  • Put primary-tier buttons inside row actions. Use tertiary.
  • Wrap status text in a coloured div — use the pill class so the shape is consistent.
5

Chrome & in-page controls

Five surfaces wrap every page: top bar, primary sidebar, secondary mini-nav, page header, and the breadcrumb. Each one contains multiple sub-components — documented below as cards so a developer can drop just the piece they need into a screen.

5.1 Top bar 48 px · dark purple · global

One bar with five sub-components, left to right: brand, trial banner, spacer, action cluster (search + clock-in/log-time + icon buttons). The bar at the very top of this page is the live render — these cards isolate each piece so you can copy just one.

Brand chip .brand

Wordmark + filled orange mark square. Always the leftmost element. Click returns to the default landing page (usually /schedule).

F FieldInsight
HTML code
<a href="/" class="brand"> <span class="mark">F</span> FieldInsight </a>

Trial / system banner .trial-banner

Inline status line in the top bar — trial countdown, "demo data", deploy-state warnings, the "Switch to live" toggle. Always inline (never a separate row) so the chrome stays one bar. The CTA at the end uses --fi-primary so it pops against the dark purple chrome.

Trial account (1096 days left). Upgrade now
HTML code
<span class="cmp-trial"> Trial account (1096 days left). <a href="/billing">Upgrade now</a> </span>

Search mini-app .cmp-search

A pill that combines a scope chip (Jobs / Customers / Invoices / etc.) with a text input and an orange go button. Scope chip is its own dropdown — picks which entity the query searches. Open shortcut: ⌘ K. Submit returns the user to the matching list view, pre-filtered.

Jobs ▾ Search… 🔍
HTML code
<form class="cmp-search"> <button type="button" class="cmp-search-filter">Jobs ▾</button> <input type="search" class="cmp-search-input" placeholder="Search…"> <button type="submit" class="cmp-search-go">🔍</button> </form>

Clock-in / Log-time cluster soft-action

Two soft-action buttons (per Section 3). Low-emphasis CTAs that don't compete with the page's primary orange action. Used for time tracking — the user clocks in once at the start of a shift; Log time records discretionary entries to a job.

HTML code
<button class="btn btn-soft">Clock in</button> <button class="btn btn-soft">Log time</button>

Top-bar icon cluster .top-icon ×N

Right-edge cluster of square icon buttons: notifications, mobile-app pairing, settings, chat. All are icon tier (26 × 26 px) so they line up vertically with the soft-action cluster's height. A red dot indicates unread / attention state.

🔔 📱 💬
HTML code
<button class="top-icon" title="Notifications"> 🔔 <span class="unread-dot"></span> </button> <button class="top-icon" title="Mobile app">📱</button> <button class="top-icon" title="Settings">⚙</button> <button class="top-icon" title="Support chat">💬</button>

5.2 Left primary sidebar 220 px expanded · 56 px collapsed

The module nav. Profile chip pinned at top, 14 module links below, Help anchored at the bottom. Collapses to an icons-only 56 px rail on narrower viewports (or on user preference) — every label hides, the active accent stays. Active state uses --fi-chrome-active (orange · --fi-primary) with a white left border — dark purple chrome, orange wayfinding. Lifecycle green stays on document buttons only (§3).

Profile / account chip .cmp-profile

Pinned to the top of the sidebar (above the module list). Three lines: user name + role chip · profile sub-label · company name. Click opens the user menu. Read-only in the collapsed state — only the avatar dot shows.

Paul D Tyrrell Profile Company Demo
HTML code
<a href="/me" class="cmp-profile"> <span class="cmp-profile-name">Paul D Tyrrell</span> <span class="cmp-profile-role">Profile</span> <span class="cmp-profile-co">Company Demo</span> </a>

Module nav · 14 items .app-sidebar a

Schedule · To-do · Accounts · Projects · Jobs · Map · Timesheets · Reports · Inventory · Sales · Assets · Safety · Library · Help. Each link is icon + label. Help is anchored to the bottom of the column so it's always one click away.

HTML code
<aside class="app-sidebar"> <a href="/me" class="cmp-profile"> ... </a> <a href="/schedule" class="active"> <span class="icon">📅</span>Schedule </a> <a href="/todo"><span class="icon">◉</span>To-do</a> // 12 more module links... <a href="/help" class="sidebar-bottom"> <span class="icon">?</span>Help </a> </aside>

Collapsed state 56 px icons-only

User-toggleable. When collapsed, the sidebar shrinks to 56 px showing only icons; labels appear as tooltips on hover. The active accent stays visible (the orange/green left border) so the user always knows where they are. Use this on narrow viewports (< 1100 px) by default; full state above that.

5.3 Secondary mini-nav 36 px · vertical icon strip

A thin vertical strip between the primary sidebar and the content area. Each icon toggles a side panel for the active module (mini-calendar picker on Schedule, unscheduled-jobs list on Schedule, customer-quick-pick on Accounts). One module owns its mini-nav — when you change module, the strip's icons change with it.

Module-specific side-panel toggles

Each icon button opens / closes a corresponding side panel. Active panel = highlighted icon (orange fill). At most one panel open at a time — clicking a second icon swaps the panel content.

📅 👤 ↑ active icon toggles its side panel open
HTML code
<nav class="cmp-mininav" aria-label="Schedule side panels"> <button class="cmp-mininav-btn active" title="Calendar picker"> 📅 </button> <button class="cmp-mininav-btn" title="Unscheduled jobs"> ◧ </button> <button class="cmp-mininav-btn" title="Technician filter"> 👤 </button> </nav>

5.4 Page header in-content · per-page controls

The action row that sits at the top of every page's content area, beneath any breadcrumb. Contains everything that scopes / acts-on the data shown below: period switcher, time stepper, primary CTA, quick actions, filter bar. Order is consistent left-to-right so users learn it once and recognise it on every page.

Period switcher + stepper .cmp-period

Two controls living side by side. The switcher (Month / Week / Day) and Rotate set the granularity of the schedule view. The stepper (◀ May ▶) walks backward/forward through periods at the chosen granularity. "Today" is marked with the primary-orange dot per the date-contrast rule.

Month Rotate May
HTML code
<div class="cmp-period"> <button class="period-select">Month</button> <button class="period-rotate">Rotate</button> <div class="period-step"> <button class="step-btn" aria-label="Previous month">◀</button> <span class="step-label">May</span> <button class="step-btn" aria-label="Next month">▶</button> </div> </div>

Primary CTA + quick actions + Add ⚡ 📍

The hero action for the page — + Add Job on Schedule, + Add Account on Accounts, etc. Always orange-filled primary tier per Section 3. Quick-action icons sit next to it — page-specific shortcuts like auto-allocate (⚡) and pin-to-map (📍). They're icon tier with a tooltip, no label.

HTML code
<div class="page-actions"> <button class="btn btn-primary">+ Add Job</button> <button class="btn btn-icon" title="Auto-allocate">⚡</button> <button class="btn btn-icon" title="Pin on map">📍</button> </div>

Filter bar + Add Filter · Search

Lives on the next row down (below the period/CTA row). + Add Filter is an outlined secondary-tier button that opens a filter chooser modal. Search is the primary-fill secondary-tier button that applies the current filter set and refreshes the data below. Once filters are applied they appear as chips between these two buttons.

HTML code
<div class="cmp-filter"> <button class="btn btn-outline">+ Add Filter</button> // applied filters render as chips here, before the Search button <button class="btn btn-secondary">Search</button> </div>

5.5 Breadcrumbs above the page title

Single-line back link above the page title. Use .crumb with a back-arrow prefix. For nested detail pages, list parent module → list view → detail.

7

AI styling addendum

This page is the master style guide. AI pattern rules live here in Section 7 — not in a separate app.

AI surfaces — canonical rules (Section 7)

Any feature where AI does work (parsing, matching, suggesting, drafting) marks the moment with the canonical Two-Star sparkle in #39006B. Three placements only: inline icon · circular badge (max one per page) · pill CTA. Approved labels: Ask AI, Re-read, Re-generate, Scan bill, Post to Xero →. Everything else on the page uses the tokens in Sections 1–6.

Full pattern spec (SVGs, CSS, provenance rules): workspace ai-styling-pattern.md.

6

Document pages & widgets PO patterns · proto-multi-supplier-po v1.28

The PO detail page went through ~10 UX iterations — chevron disclosure, masthead card, banner removal, purple softening. These are the patterns that survived. They apply to any document page: PO, quote, invoice, bill, credit note.

6.1 Chevron disclosure the only collapse pattern

One rotating chevron (▸ / ▾) at the left of the section title. The whole header row is the click targetcursor: pointer, soft hover tint. A count chip follows the title; state persists per user in localStorage. Never ship View / Edit or Expand / Collapse button pairs — the chevron replaces them.

Collapsed — header still answers "do I need to open this?"
Line Items 4 lines · $661.17 inc GST · 0 of 4 received
Expanded — chevron rotates, action row sits one fixed gap below
Bills 1 bill · Total billed: $643.50 / $661.17 PO value
HTML code
<!-- whole row clickable · chevron left · count chip · inline facts --> <div class="disclosure-head" role="button" aria-expanded="false"> <span class="disclosure-chevron">▸</span> <h3>Line Items</h3> <span class="count-chip has-data">4 lines</span> <span class="disclosure-summary">· <strong>$661.17</strong> inc GST · 0 of 4 received</span> </div>

6.2 The masthead card document identity is never loose text

Every document page opens with one identity card: uppercase eyebrow (document type), the counterpart name as headline, a fact grid (date · delivery · reference), and an "Edit details" disclosure that expands the edit form in place. The document number, status pill, and template selector stay in the page header above — the masthead owns who and when.

Purchase Order
Reece Plumbing
Edit details ▾
PO Date
11 Jun 2026
Delivery
18 Jun 2026
Reference
JOB-14517

6.3 Line table Supplier Code + Internal Code

#Supplier CodeInternal CodeDescriptionQtyLine Total
1CLI264/3SMgryQSW-SVCService call-out1$185.00
2L&CCLCM20-M20FIT-2020mm compression fitting4$48.60

PO shows both codes: purple Supplier Code (what the supplier picks/packs) + orange Internal Code (your inventory). Header band #F0F0F2; supplier column purple #6a1b9a; internal column orange. Fully-received rows tint #f1f8e9 (status only — not a button colour).

6.4 Rules that survived the iterations

RuleDetail
Rich collapsed summariesMoney and key values bold; progress coloured by state (success green when complete, muted otherwise). If there's nothing worth saying, say nothing — don't pad.
Uniform section rhythmOne divider component between sections, same margin everywhere (≈10 px). Title-row → action-row gap is one fixed value in every section — per-section drift is visible at a glance.
Inline affordance beats bannersIf the fix is available inline (highlighted picker cell in the exact problem row), do not also show an alert banner counting the problems. One affordance per problem.
Screen vs print split.print-only for letterhead / address band; .no-print for chevrons, chips, action rows. On beforeprint, expand collapsed sections the document needs; restore on afterprint.
Verb-led labelsButtons say what happens next, not what already happened — "Reconcile Supplier Invoice" (opens reconciliation) replaced "Supplier Invoice Received".

6.5 Workflow palette recap green · orange · purple · blue — see §3

Green lifecycle hero (Approve/Submit/Finalise, one per region) → orange attention (Confirm goods received) → purple workflow (Reconcile Supplier Invoice) → blue tools (everything else). Bright green #22C55E is status pips and chips only — not a button fill. Deep purple #39006B on chrome is navigation; on buttons it is AI-only (§7).

6.6 Click-? hints apply-tooltip-pattern

Workflow buttons (section action rows, lifecycle footer, dialog primaries) carry a hover-revealed ? glyph at the top-right corner; clicking it opens a dialog with Description (business meaning, leads with why) and Example (this customer's real data shape — real PO numbers, suppliers, dollar values). Hover tooltips disappear before users can read them and never work on touch. One shared dictionary per page (e.g. FOOTER_BTN_INFO) is the single source of truth — no key, no ship. Reference: InfoableButton, proto-multi-supplier-po v1.27.20 (12 workflow buttons documented); canonical doc: apply-tooltip-pattern.md.

CSS code
/* screen vs print — same DOM, two renders */ .print-only { display: none; } @media print { .print-only { display: block !important; } .no-print { display: none !important; } }
Reference build. proto-multi-supplier-po v1.28 — full button hierarchy, chevron disclosure, masthead card, dual code columns, click-? hints. Per-button map: affordance-style-guide.md · tokens: poButtonTokens.ts.
8

Explicit by design NAB · NAT · NAS

Where possible, make information discoverable and clear. Users should never have to guess what a control does, or open Settings to learn state that belongs on the page they are already on. Explicit, never implicit behaviour. These three rules sit above button tiers and colour — they explain why we resist clutter.

The NAB · NAT · NAS test. Before adding any new interactive control, ask: can the user already see or reach this from what's on screen? If yes — don't add another button, setting, or toggle. Prefer inline facts, disclosure headers, row affordances, and labelled zones over mystery chrome.

The three rules

RuleStands forMeansInstead of…Do…
NAB Not Another Button One entry point per action class — never duplicate the same verb in a second control. A + File button when an Attach zone exists · View/Edit pair when a chevron discloses · Select items when the grip column selects Use the zone, chevron, row click, inline link, or existing footer tool
NAT Not Another Toggle Don't hide behaviour behind an unlabelled or mystery switch — state and consequence must be readable at a glance. A nameless ON/OFF pill · toggle that changes data with no inline label · "enable advanced mode" with no explanation on the page Label the toggle (what it controls + current state) · or show read-only state inline and edit in place
NAS Not Another Setting Don't bury information in Settings (or a modal three clicks away) when it belongs where the user is working. Visible/required flags only in System Fields admin · document status you can't see until you expand a menu · pricing rules hidden in a config screen the PO author never opens Surface the fact on the page — count chips, disclosure summaries, masthead fields, column headers, click-? hints

Discoverable by default explicit, never implicit

A collapsed section header should still answer "do I need to open this?" — chevron + title + count chip + inline facts (see §6.1). A document masthead should show who, when, and reference without opening Edit (see §6.2). A workflow button should explain why via click-?, not a hover tooltip that vanishes (see §3 · §6.6). If the user has to hunt, you have violated NAS. If they have to guess what a switch does, you have violated NAT. If two controls do the same job, you have violated NAB.

PO page examples NAB · NAT · NAS in practice

Do — explicit & discoverable

  • NAB: Attach-file zone is the only file entry — no separate + File button.
  • NAB: Chevron disclosure replaces View / Edit / Expand / Collapse button pairs.
  • NAS: Collapsed Bills header shows 1 bill · Total billed $643.50 / $661.17 PO value — no need to open Settings or guess.
  • NAS: Line Items header shows line count, total inc GST, and received count while collapsed.
  • NAT: Settings toggles (Profile P) are labelled Visible / Required — never a mystery switch on a document page.
  • Explicit: Every workflow verb gets click-? with Description + Example — business meaning, not data shape alone.

Don't — implicit & cluttered

  • NAB: Attach zone and a + File button — two entry points, same action.
  • NAB: Grip column for row select and a Select items toolbar button.
  • NAB: Twelve equal footer buttons — every action looks primary; nothing is discoverable by hierarchy (see §3 wall-of-buttons).
  • NAS: Bill reconciliation status only visible after expanding three sections — user can't triage from the page chrome.
  • NAT: Unlabelled toggle that changes line behaviour with no inline explanation.
  • Implicit: Hover-only tooltips on workflow verbs — disappear before the user reads them; fail on touch.
HTML code
<!-- NAB: one attach entry — no + File button --> <div class="attach-zone" role="button" tabindex="0"> <strong>Attach file</strong> <span class="attach-hint">Drag files here</span> <button class="btn btn-standard" type="button">Choose file</button> </div> <!-- NAS: collapsed header still answers "do I need to open this?" --> <div class="disclosure-head" role="button" aria-expanded="false"> <span class="disclosure-chevron">▸</span> <h3>Bills</h3> <span class="count-chip">1 bill</span> <span class="disclosure-summary">· Total billed: <strong>$643.50</strong> / $661.17 PO value</span> </div> <!-- NAT: labelled toggle — never a mystery switch --> <label class="toggle-row"> <span class="toggle-label">Visible on mobile forms</span> <span class="toggle-state">On</span> <input type="checkbox" role="switch" checked /> </label>
Related rules. NAB · NAT · NAS complement §3 (filled-button budget, one lifecycle hero), §6 (chevron disclosure, masthead card, inline summaries), and apply-tooltip-pattern.md (click-? for explicit workflow meaning). When in doubt: make it visible, label it, or collapse it with facts — never add another control.