Craft, patterns & research that scale
We build interfaces that feel like a sharp colleague who knows your data inside out — not another generic admin tool. Work Sans. Tight tracking. Tokenized accents (default Minimal Neutral) with optional Spectrum / n2 Red / Dark modes. Frequency Field is brand atmosphere, not a control.
Two contexts share tokens but not always the same chrome: Playbook shell (this docs site) and Product UI demos (app patterns + client skins below). Don’t mix them when writing specs.
Load-bearing recipes already live across the site. Use these when adding pages so the playbook stays one system.
.site-nav in theme.css. Active section uses its accent token. Palette control (Spectrum · n2 Red · Minimal Neutral · Dark) via theme.js; default is Minimal Neutral.
.page-header — back link, display-size h1 in section accent, subline. Same language as homepage section titles (see Process, Marketing, Glossary).
Canonical shell component in theme.css:
.playbook-card + .playbook-card__bar (aria-hidden="true") + .playbook-card__bodystyle="--playbook-card-accent: var(--spectrum-…)".playbook-card--compact · .playbook-card--feature (homepage full-radius)Subcards stay border-only tiles (no bar). Product UI demos under demo-skin root stay separate — do not convert demos to playbook-card.
Uppercase tracking badge (EXISTING / COMING SOON / IA / RESEARCH) above section titles. Long pages use sticky “On this page” nav (this sidebar is the live example).
We use a small, consistent set of input primitives across flows, record editing, lists, and filters. Goal: speed and familiarity — not "yet another control". Prefer the real shared components (EditableParameter for attributes, the exact filter bar pattern) when possible.
When to use: Free-form data → text / multiline. Constrained choices → Select. Multiple flags → Checkbox group. Temporal → date. Discovery → icon-prefixed search InputBase + chips. Attributes in drawers → inline EditableParameter (click/pencil to edit, Enter/Esc to commit).
Screenshot from source + full live examples available in original N2 UX (using our tokens + patterns). See "FILTER / SEARCH", "TEXT", "SELECT" demos in source.
LIVE EXAMPLES — matching studio / flow / drawer implementations
Search shell and filter chips are 2rem (same as page CTAs). Theme radius — never pill. Selected = filled ink, not brand red. Counts follow the current search. Empty filter: Clear filters is the primary action.
Field text ~0.8125rem. Empty Select always shows the empty state in the field (product: shrink label + notched outline + renderValue). Never leave a floating label colliding with “— Unassigned —”.
Directly mirrors form step controls in FlowDetail.tsx and the Edit selected records drawer.
EditableParameter pattern (RecordDetailsDrawer / TabularDataPreview). Hover affordance on soft bg.
The form builder is the core of N2 Flow: define reusable forms by selecting fields from a table schema. Supports sections, role-based access, custom field types (range, tabular), and one-time use for schema fields.
When to use: For data collection flows where structure comes from existing tables. Use "click to add" from palette, drag to sections, set required/readOnly. Preview mode for validation. Publish to use in flows.
Permissions / Access matrix: /settings/users provides a dashboard with role assignment + domain/table access matrix (compact grid overview + per-user expandable inline selects for Owner/Editor/Read/None).
Combobox multi-select; matches form step roles.
Added in demo: —
Matches /admin/forms/* : palette left, sections right, one-time use for schema fields (FormBuilder.tsx).
n2flow uses a consistent list + focused detail pattern for flows (runs). Emphasis on current step ownership, progress visibility, and review actions. The admin blueprint is a flow template — do not say “data task” in nav or page titles.
When to use: For any multi-step data collection. List for overview + actions; detail for step execution with data review + comments.
| RUN | CURRENT STEP | STEP OWNER | PROGRESS | STATUS | ACTION |
|---|
Filter + sort + status chips + progress + action. Matches /flows (All Flows). Row title opens the run; More → Rename. Stalled is the exception, not the default (monochrome, not error red).
Start flow dialog: title “Start flow”; named Close; wizard shell min(70vh, 36rem); steps Choose template → Choose table → Upload file → Review & start; domain chips 2rem; deep-link ?newFlow=true&template=<id>.
Parser pane has two modes. Create (Parsers → /admin/parsers/:slug): heading Parser, field Parser name, primary Save. Review after Upload file on a run: heading This file, primary Continue / Use these mappings. Jump from Attach Parser: Open parser. Format is a property, not the noun. Do not say File importer or PDF parser. Do not title either mode Preview — Fields already owns that word.
List page header: H5 matches the left-nav label; description one line; secondary then primary PAGE 2rem CTAs.
Buttons — two heights only. PAGE 2rem (list-header CTAs, dialog footers, filter chrome). ROW 1.75rem (Remind + More in the same row). Never mix a PAGE text button with an unstyled kebab.
Select a run above to load step detail…
Click the step group to select. Path rows are full-width bordered list items with a Then: label — not badges sized by text. Body click selects the source; the chevron jumps to the target. Reject is dashed ink, not red. New paths default to manual (Auto progress off). Assignee is step-level, not per path.
Preview tab is a separate canvas: one dotted line per transition = all possible paths at design time. Click a node or port to edit that step on Template. Legend: dotted = all possible paths. One terminal Complete step; no outgoing Add path.
Chips and small tags are used heavily in All Flows and My Flows for status, filters, "Stalled" indicators, and lightweight metadata. They must be scannable at a glance, use consistent sizing, and avoid error-like colors for non-error states (e.g. stalled).
When to use: Status filter bar (interactive), row-level status, temporary "Stalled" / "Reminder sent" callouts, domain/duration badges.
Row status is monochrome (Stalled is not error red). All · 24 is a 2rem filter chip — different job from the 1rem row chips. Click a chip to select.
The org overview surface. Four phase cards (Ingest/Organize/Discover/Share) with live counts, contributor counts, plus the recent activity feed that surfaces cross-domain actions.
When to use: Landing view for most users. Cards link to the primary list for that phase. Activity is read-only scannable history.
We deliberately avoid heavy generic DataGrids. Our tables + filter bars + drawers keep the experience feeling like a material data tool.
When to use: Click row → record drawer. Checkboxes → Edit selected (write). Cmd/Ctrl+click → Compare (read). Do not say “batch edit” (collides with a materials batch/lot). Search/filter cluster always shown.
Table config → Fields: section Preview + label View + view name Default. Catalog Available fields + visible labels Filter fields and Fields from + value This table. Do not say Default View or All available fields. Do not leave the catalog search unlabeled.
Studio Tables list click always opens records. Pack walls (maxTables / maxRecords) belong on connect / import / seats — not on browse. Row click opens the record; kebab is More. Truncation: flex children minWidth: 0; dense tables tableLayout: fixed + cell ellipsis.
| ID | Name | Status |
|---|
Search shell and filter chips are 2rem (theme radius, never pill). Selection bar: N selected · Edit selected · Compare · Clear. Hide Edit selected and Add to Project without write permission (Viewer). Compare / export may remain. Click name to inline-edit. Primary actions stay in the page header. Leftover height: the page does not scroll — Layout is 100vh overflow hidden; the list or table fills leftover viewport (flex: 1; minHeight: 0; overflow: auto).
The deliberate hierarchy: Left nav → In-page tabs → Breadcrumbs → Drawers. Each has a live example below.
Filter-empty: Clear filters is primary; create/start is secondary. First-run empty keeps the create CTA primary.
Skeletons that match final layout.
Actionable recovery — never only “something went wrong”.
--n2-bg, --n2-surface, text/secondary/muted, --n2-border (theme.css)--spectrum-teal, --spectrum-violet-blue, --spectrum-violet, --spectrum-orange-warm--n2-red (#D70321) — playbook chrome only. Product filter selected fill is ink (T.ink), not brand red. Product default palette is Los Alamos.html.theme-dark.Product Theme settings: Density, Mode, and Palette are exclusive RadioGroups (hidden radio on each card). Engineer handoff is the theme contract with src/app/theme/ — token names are the API; do not extract an npm package until a second app consumes it. Copy JSON on Theme settings exports the live axes. Product default is Los Alamos. Palettes: Grayscale · Los Alamos · n2 demo · N2 Expanded · Spectrum. n2 demo and N2 Expanded share brand paper and red; Zoom stays n2 demo only. Pulse is not in the product left nav; Ask · ⌘K and the dataset rail remain. First-run: unbranded PasswordGate then branded LoginScreen. No SSO until it works. Do not print the demo access code on either screen. Type & motion: Work Sans, tight tracking. Theme transitions respect prefers-reduced-motion. Frequency Field is atmospheric brand texture (hero/overlays), not a form control. Progressive disclosure for complexity — summary first; depth on demand.
The structure and organization of content, data, and navigation across the platform. Defines how Schemas, Domains, Tables, Views, and Projects relate — and how users discover and navigate information.
Core n2 hierarchy with cross-cutting collections and discovery patterns. Click any node to open its glossary definition.
IA principle: clear hierarchy for findability + polyhierarchy for real user collections + facets/wayfinding for discovery and orientation.
Use research to reduce risk, not to decorate decks. Match the method to the decision: what people do vs what they say, and how many / how often vs why / how. (Framed with NN/g qualitative–quantitative practice.)
Answers: why, how, what mental models, where friction lives.
Answers: how many, how often, how large the effect, is A better than B.
Real tasks, realistic users, observe failure points. Prefer 5–8 per round, iterate (NN/g: small iterative tests beat one big study).
Open/closed sort for grouping; tree test for “can they find it?” Validates IA before we ship nav and domain labels.
Mental models, workflow, language of materials experts. Ask about last time they did the job — not abstract preferences.
Expert review against Nielsen’s heuristics + our tenets. Fast, cheap; not a substitute for users on novel flows.
Define success metrics first. Instrument funnels; A/B when traffic and risk warrant. Don’t ship based on vanity metrics.
Good for attitudes and satisfaction at scale; weak for inventing UI. Avoid leading questions; combine with behavior data.
Further depth (scripts, sample plans, templates) can land here later. Live UI demos sit under Components & Patterns.
Interactive demos already cover the core product patterns. Next: variants, contribution rules, and engineering handoff (props, states, a11y notes) so demos graduate into a shared system—not a second visual language.
See Components & Patterns →