Easy to get wrong
Uppercase. There is no uppercase text.
Headings, labels, buttons and metadata are sentence case. A page header's metadata is a quiet caption that never repeats the kind the breadcrumbs give ("Term", "Data product") or a count shown on a tab.
Cards. Do not put cards inside a panel or lay out a grid of identical icon cards.
Use a table, a list with thin rules or a single panel.
Repeated state. Show each piece of state once.
Where there is a search bar, its tokens are the one summary of active filters, and the facet sidebar shows only its checkboxes (hide-applied). Do not echo the whole query back in the result count ("23 results" is enough). In step-by-step flows, the stepper names the step and shows what each finished step chose, so the step does not repeat its own name as a heading and the side summary only says what is still to come ("First run 10:00 UTC today"). Finished steps are quiet ticks; only the current step carries weight.
Two editors for one value. Give each value one editor.
Search is one bar: free text and conditions as tokens, with the facets editing the same query. The query builder opens in place of the bar and writes back to it, so only one is on screen at a time.
Page actions. The More menu is for occasional or destructive actions.
If people come to a page to do something, make it a visible button. Do not repeat sidebar destinations as header buttons, and keep "create" actions on the page that owns them. Each action appears once per screen: not in the header and again in a section, the blade or the More menu. Home is for getting back to work: recent items, things that need you, and the setup checklist on a new instance. A personal toggle such as Subscribe is a quiet icon button that shows its state (a filled bell when on), so it doesn't compete with the primary. Places to go (the source's own docs, a runbook) sit in a visible Links row under the header as small outlined buttons with the link's own icon (a provider logo, or a symbol for anything else) and an arrow showing they open a new tab. They stay out of More, and More leaves out anything already on screen (such as Copy MRN beside the MRN's own copy button).
Lists that grow. Design every list for hundreds of items: pagination, a search box, and dropdown filters (owner, tag).
Filter pills only suit a short, fixed set of about six. A personal section such as "Your teams" shows five at most with Show all, and searching collapses everything into one ranked list. Tables fill the space they are given: no dead space beside a table and no clipped columns. Only scroll sideways when the columns truly cannot fit.
Creating things. A modal dialog is for a short decision or confirmation.
Creating something opens in place and uses the finished page's sections, names and order, but leaves out what the system assigns: no MRN, caption, refresh status or other details until the thing exists. Ask for as little as possible, starting with what people came to write (the name), and fill in what you can (the owner as you). Do not put a helper field such as "paste a link" first; it does not fit every case and slows down the common one. Optional groups start as one "+ Add" button each and expand in place, so there's no wall of empty fields. Validate when a field is left and on submit, not while typing; a duplicate links to the existing record. Offer the better path once, as a quiet line next to the field it depends on ("Google Drive has a plugin that keeps assets like this up to date" under Where it lives), as a hint rather than a gate or a step. A "Create another" checkbox is not a second primary action. Options that add work or cost (a schedule, notifications) start off, and fields that depend on a switch appear only when it is on.
Picking many things. Show what is already chosen separately from search results, and give each result its own Link or Remove button that acts at once, with Undo in a toast.
Never mix chosen and unchosen items in one checklist with "untick to remove". Show results with their logo and type, not their MRN.
Previews and side panels. A preview answers, in order: what is it, can I trust it, who do I ask, what does it mean, where does it flow.
Lead with the logo, name and an "At a glance" list of the facts that decide whether someone can use it (type, freshness, personal data, popularity, size). Give each section one question to answer, with a plain heading ("Who to ask", "What it means", "Where it flows"). Fold identifiers and timestamps into a collapsible "More details" section, and put the next steps ("Open", "Query") in the footer, not a text link. Leave out histories that belong on the full page, such as a 30-run strip.
Row actions. A table row shows one visible button: the action that row needs most (Rotate key on an expiring key, Revoke on an active one).
Everything else goes in a More menu at the end of the row. Two or three buttons side by side crowd the row and get cut off when space is tight.
Rules and automations. Anything that runs on its own (asset rules, data product rules, saved searches) reads as "Matches, then Adds or Does, then Applied to", in plain words first ("Tagged pii", "From Kafka") with the exact query second.
Show what it adds by name, not as a count ("PII handling runbook", not "1 link"), keep its on/off switch visible where it is listed, and show one page per rule rather than splitting it across tabs. When a list mixes things people added and things rules brought in, group them by how they got there ("Added manually", then "From rules" under each rule) instead of a "How added" column; only the manual ones have Remove.
Schemas. Show a schema as an outline, not a grid of columns.
Each field is two lines: name, type in everyday words ("Text", "Money (GBP)", "One of 3 values: WEB, IOS, ANDROID") and markers (Key, PII, Certified), then its description with glossary terms. Mark only exceptions ("Optional", "Edited", "92% filled"). Nesting becomes a tree only where it exists, top level open. Exact types, statistics, allowed values, who can see the field and its path live in a field panel opened by selecting it. Offer Structure, JSON and YAML views with Copy, showing the original Avro or JSON Schema when known.
Runs and traces. Show agent and pipeline runs as a list on the left and the selected run on the right, read as a story.
A run is named by what it was asked ("Where is my order?"), with when, how long and how many steps as a caption, and a pill only when it failed. Each step reads in plain words ("Ran a query on orders → 5 rows") with a thin timing bar on the run's own clock. A refused or failed step is marked with its reason and the rule behind it. Raw inputs (SQL, arguments) fold away under "Show query", and tokens, model and IDs sit in More details. Never lead with function-call syntax or token counts.
Search and filters. Conditions are neutral tokens in plain words inside the search bar ("Type is Table", "Provider is Snowflake or BigQuery").
Click any part to change it, with a picker that fits the field. Several values of one field read as "is X or Y" instead of a separate OR. Typing @ completes field, operator and value, and facets add and remove the same tokens. "Show as text" reveals the raw query in place, and a query the tokens cannot show opens as text, never a dead end. Avoid row-by-row builders with a joiner on every row. For anything more, "Build query" opens the query builder in place of the bar: groups with an All, Any or None switch and a plain hint ("Every condition must match"), rows that read as a sentence ("Where … and …") in the same columns at every level, nested up to three deep with a rule rather than a box, a live result count, and Apply or Cancel. A query the tokens cannot show offers Build query, so nothing is ever stuck as text. Offer only the operators the query engine accepts for each field: a glossary term "is" or "matches" a pattern; type, kind, provider and name take is, is not, contains and matches; metadata takes everything, including comparisons and "between" for numbers. Wildcards read as "matches" ("Name matches orders_*"). Any metadata key can be typed as a field.
Key and value pairs. Free-form metadata is rows of key, value and remove, with Add field.
Pasting key: value lines splits them into rows, dotted keys mean nesting, and "Edit as JSON" is there for deeper structures.
First use. Before something is in use, hide panels that can only say "nothing yet".
The welcome and the setup checklist may sit on the faint contour field; panels join as they gain something to show.
Stay in the interface. Setup flows do not hand people code to copy (CLI commands, SQL grants) unless that code is the task.
Say what is needed in a sentence and link to the docs for the exact commands; keep actions such as Test connection as buttons.
Timelines. A horizontal timeline is one straight line with a dot per step, the step's name and time under its dot, and the time between steps as a quiet caption on the line.
No end ticks or drawing marks.
Global search. The search in the top bar opens the command palette (⌘K or Ctrl+K), never a separate search page or an inline dropdown.
It mixes pages, commands and live catalog results, shows recent items before anything is typed, and every typed query ends with "Search the catalog for …", which opens Discover with that query. People can always get from the palette to every result, including when nothing matched.